instar 1.3.1589 → 1.3.1591
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dashboard/console/console.css +4 -1
- package/dashboard/console/machines-model.js +15 -0
- package/dashboard/console/machines.js +3 -2
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +76 -0
- package/dist/commands/server.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts +7 -0
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +27 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/SessionManager.d.ts +1 -1
- package/dist/core/SessionManager.d.ts.map +1 -1
- package/dist/core/SessionManager.js.map +1 -1
- package/dist/core/devGatedFeatures.d.ts.map +1 -1
- package/dist/core/devGatedFeatures.js +6 -0
- package/dist/core/devGatedFeatures.js.map +1 -1
- package/dist/core/types.d.ts +13 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/data/standards-guard-index.json +1 -1
- package/dist/data/standards-guard-index.meta.json +2 -2
- package/dist/data/standards-registry.meta.json +1 -1
- package/dist/monitoring/guardManifest.d.ts.map +1 -1
- package/dist/monitoring/guardManifest.js +10 -0
- package/dist/monitoring/guardManifest.js.map +1 -1
- package/dist/monitoring/machineMaintenance/DrainRehearsal.d.ts +134 -0
- package/dist/monitoring/machineMaintenance/DrainRehearsal.d.ts.map +1 -0
- package/dist/monitoring/machineMaintenance/DrainRehearsal.js +509 -0
- package/dist/monitoring/machineMaintenance/DrainRehearsal.js.map +1 -0
- package/dist/monitoring/machineMaintenance/HostMaintenanceStore.d.ts +80 -0
- package/dist/monitoring/machineMaintenance/HostMaintenanceStore.d.ts.map +1 -0
- package/dist/monitoring/machineMaintenance/HostMaintenanceStore.js +160 -0
- package/dist/monitoring/machineMaintenance/HostMaintenanceStore.js.map +1 -0
- package/dist/monitoring/machineMaintenance/WorkYieldRegistry.d.ts +69 -0
- package/dist/monitoring/machineMaintenance/WorkYieldRegistry.d.ts.map +1 -0
- package/dist/monitoring/machineMaintenance/WorkYieldRegistry.js +120 -0
- package/dist/monitoring/machineMaintenance/WorkYieldRegistry.js.map +1 -0
- package/dist/monitoring/machineMaintenance/planner.d.ts +88 -0
- package/dist/monitoring/machineMaintenance/planner.d.ts.map +1 -0
- package/dist/monitoring/machineMaintenance/planner.js +154 -0
- package/dist/monitoring/machineMaintenance/planner.js.map +1 -0
- package/dist/monitoring/machineMaintenance/readings.d.ts +90 -0
- package/dist/monitoring/machineMaintenance/readings.d.ts.map +1 -0
- package/dist/monitoring/machineMaintenance/readings.js +161 -0
- package/dist/monitoring/machineMaintenance/readings.js.map +1 -0
- package/dist/native/instar-desktop-host +0 -0
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +3 -1
- package/dist/scaffold/templates.js.map +1 -1
- package/dist/scheduler/JobScheduler.d.ts +2 -0
- package/dist/scheduler/JobScheduler.d.ts.map +1 -1
- package/dist/scheduler/JobScheduler.js +4 -0
- package/dist/scheduler/JobScheduler.js.map +1 -1
- package/dist/server/CapabilityIndex.d.ts.map +1 -1
- package/dist/server/CapabilityIndex.js +9 -0
- package/dist/server/CapabilityIndex.js.map +1 -1
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +13 -0
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +65 -65
- package/src/data/standards-guard-index.json +1 -1
- package/src/data/standards-guard-index.meta.json +2 -2
- package/src/data/standards-registry.meta.json +1 -1
- package/src/data/state-coherence-registry.json +19 -0
- package/src/scaffold/templates.ts +3 -1
- package/upgrades/1.3.1590.md +20 -0
- package/upgrades/1.3.1591.md +27 -0
- package/upgrades/side-effects/console-history-shrink-fix.eli16.md +11 -0
- package/upgrades/side-effects/console-history-shrink-fix.md +16 -0
- package/upgrades/side-effects/machine-self-maintenance-watch-only.md +104 -0
|
@@ -989,6 +989,9 @@ button.run-mark:focus-visible { outline: 2px solid var(--accent); outline-offset
|
|
|
989
989
|
.sess-tab[aria-pressed="true"] { border-color: var(--accent); color: var(--accent); background: var(--accent-wash); }
|
|
990
990
|
.sess-history { flex: 1; min-width: 0; min-height: 320px; height: 52dvh; overflow-y: auto; padding: var(--s-3); background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--r-md); display: flex; flex-direction: column; gap: var(--s-3); }
|
|
991
991
|
.sess-history[hidden], .sess-term[hidden] { display: none; }
|
|
992
|
+
/* A column flex box squeezes its children to fit; history items must keep their own height
|
|
993
|
+
and let the box scroll (tool lines clip their overflow, so without this they shrink to 0). */
|
|
994
|
+
.sess-history > * { flex-shrink: 0; }
|
|
992
995
|
.sess-history-note { margin: 0; text-align: center; font-size: 13px; color: var(--text-muted); }
|
|
993
996
|
.sess-h { max-width: 92%; }
|
|
994
997
|
.sess-h-user { align-self: flex-end; background: var(--accent-wash); border: 1px solid var(--hairline); border-radius: var(--r-md); padding: var(--s-2) var(--s-3); }
|
|
@@ -1025,7 +1028,7 @@ button.run-mark:focus-visible { outline: 2px solid var(--accent); outline-offset
|
|
|
1025
1028
|
.app:has(> .preview-banner) { --preview-h: 37px; }
|
|
1026
1029
|
.sessions-page.has-open .sess-open { height: 100%; min-height: 0; }
|
|
1027
1030
|
.sessions-page.has-open .sess-term-wrap { min-height: 0; }
|
|
1028
|
-
.sessions-page.has-open .sess-term { height: auto; min-height: 0; }
|
|
1031
|
+
.sessions-page.has-open .sess-term, .sessions-page.has-open .sess-history { height: auto; min-height: 0; }
|
|
1029
1032
|
.sessions-page.has-open .sess-composer { position: static; padding-bottom: 0; }
|
|
1030
1033
|
}
|
|
1031
1034
|
.sess-default-box:empty { display: none; }
|
|
@@ -133,3 +133,18 @@ export function usageOf(res, sessionNames = {}) {
|
|
|
133
133
|
].filter(Boolean),
|
|
134
134
|
};
|
|
135
135
|
}
|
|
136
|
+
|
|
137
|
+
/** One line for this machine's care status. Watch-only, so it never implies a restart will happen. */
|
|
138
|
+
export function machineCareLine(r) {
|
|
139
|
+
if (!r || !r.ok || !r.data) return null;
|
|
140
|
+
const d = r.data;
|
|
141
|
+
const uptime = typeof d.uptimeDays === 'number' ? `Up ${d.uptimeDays} days` : 'Uptime unread';
|
|
142
|
+
const held = (Array.isArray(d.safetyHolds) ? d.safetyHolds : []).filter((h) => h.active).map((h) => h.label);
|
|
143
|
+
const night = d.lastRehearsal;
|
|
144
|
+
const last = !night ? 'No practice run yet'
|
|
145
|
+
: night.outcome === 'would-restart' ? 'Last practice run: would have restarted'
|
|
146
|
+
: night.outcome === 'would-roll' ? 'Last practice run: would have waited a night'
|
|
147
|
+
: night.outcome === 'would-hold' ? 'Last practice run: would have been held'
|
|
148
|
+
: 'Last practice run: outcome unknown';
|
|
149
|
+
return [`Restart care is watching only, nothing restarts.`, uptime, last, held.length ? `Holding now: ${held.join(', ')}` : null].filter(Boolean).join(' · ');
|
|
150
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Reads only; the one frequent write is Rename (bearer). Identity reviews stay in
|
|
3
3
|
// the legacy tab until their PIN sheet is rebuilt (the plan's first cut).
|
|
4
4
|
|
|
5
|
-
import { buildMachinesPage, ropesFor, healthOf, usageOf } from './machines-model.js';
|
|
5
|
+
import { buildMachinesPage, ropesFor, healthOf, usageOf, machineCareLine } from './machines-model.js';
|
|
6
6
|
import { el, setKids, pageHead, sheet, closeSheet, story, note, cantTell } from './ui.js';
|
|
7
7
|
import { legacyHref } from './nav-model.js';
|
|
8
8
|
|
|
@@ -11,7 +11,7 @@ const STATE_DOT = { ok: 'dot live', attn: 'dot attn', bad: 'dot bad', stale: 'do
|
|
|
11
11
|
export async function renderMachines(main, ctx) {
|
|
12
12
|
const { get } = ctx;
|
|
13
13
|
if (!main.querySelector('.machine-cards')) setKids(main, el('section', { class: 'hero page-hero' }, el('div', { class: 'eyebrow', text: 'Capacity · Machines' }), el('h1', { class: 'page-title skeleton', text: 'Loading machines' })));
|
|
14
|
-
const [pool, health, guards, sessions] = await Promise.all([get('/pool'), get('/health'), get('/guards'), get('/sessions?scope=pool', 8000)]);
|
|
14
|
+
const [pool, health, guards, sessions, care] = await Promise.all([get('/pool'), get('/health'), get('/guards'), get('/sessions?scope=pool', 8000), get('/machine-maintenance')]);
|
|
15
15
|
const live = sessions.ok && Array.isArray(sessions.data && sessions.data.sessions) ? sessions.data.sessions.filter((s) => s.status === 'running' || s.status === 'starting') : [];
|
|
16
16
|
const byMachine = {};
|
|
17
17
|
const names = {};
|
|
@@ -38,6 +38,7 @@ export async function renderMachines(main, ctx) {
|
|
|
38
38
|
setKids(main,
|
|
39
39
|
pageHead({ eyebrow: 'Capacity · Machines', headline: page.headline, sub: page.sub, tone: page.tone, facts: page.facts }),
|
|
40
40
|
!sessions.ok ? note(`Couldn't count sessions: ${sessions.reason}.`) : null,
|
|
41
|
+
machineCareLine(care) ? note(machineCareLine(care)) : null,
|
|
41
42
|
cards,
|
|
42
43
|
legacyLink(),
|
|
43
44
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAuHA,OAAO,EAAE,cAAc,EAAwD,MAAM,2BAA2B,CAAC;AAgBjH,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AA6BjG,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AA6J7D,OAAO,KAAK,EAAW,oBAAoB,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACjG,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AA4GtD,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC1C,OAAO,CAUT;AA0ID,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA0DD,+EAA+E;AAC/E,wBAAgB,qCAAqC,CACnD,SAAS,EAAE,IAAI,CAAC,OAAO,2BAA2B,EAAE,cAAc,EAAE,QAAQ,CAAC,GAAG,IAAI,EACpF,OAAO,EAAE,MAAM,GACd,IAAI,CAEN;AAukBD,wBAAsB,oBAAoB,CACxC,cAAc,EAAE,cAAc,EAC9B,QAAQ,EAAE,eAAe,EACzB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,aAAa,CAAC,EAAE,MAAM,EACtB,WAAW,CAAC,EAAE,WAAW,EACzB,WAAW,CAAC,EAAE,WAAW,EACzB,kBAAkB,CAAC,EAAE,MAAM;AAC3B;;qCAEqC;AACrC,WAAW,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE;AACzD;;wEAEwE;AACxE,SAAS,CAAC,EAAE;IACV,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;;sEAGkE;IAClE,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,GACA,OAAO,CAAC,MAAM,CAAC,CAiZjB;AA0xBD;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,YAAY,EACpB,YAAY,EAAE,oBAAoB,GAAG,IAAI,GACxC;IACD,YAAY,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IAC3C,QAAQ,EAAE,MAAM,CAAC;CAClB,CAqBA;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,eAAe,EACzB,cAAc,EAAE,cAAc,EAC9B,YAAY,CAAC,EAAE,YAAY,EAC3B,WAAW,CAAC,EAAE,WAAW,EACzB,WAAW,CAAC,EAAE,WAAW,EACzB,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,EAGvE,UAAU,CAAC,EAAE,MAAM,OAAO,8BAA8B,EAAE,WAAW,GAAG,IAAI,EAK5E,qBAAqB,CAAC,EAAE,MAAM,OAAO,gCAAgC,EAAE,kBAAkB,GAAG,IAAI,EAKhG,mBAAmB,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,EAQrD,oBAAoB,CAAC,EAAE,MAAM;IAC3B,YAAY,EAAE,OAAO,kBAAkB,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACrE,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IAC3C,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,IAAI,GACP,IAAI,CAo4BN;AA+pBD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAg41BtE;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuDzE;AA+BD,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAkE5E"}
|
package/dist/commands/server.js
CHANGED
|
@@ -22755,6 +22755,82 @@ export async function startServer(options) {
|
|
|
22755
22755
|
console.log(pc.dim(` [work-admission] self-help notice failed: ${err instanceof Error ? err.message : String(err)}`));
|
|
22756
22756
|
}
|
|
22757
22757
|
}
|
|
22758
|
+
// ── Machine self-maintenance, watch-only (docs/specs/machine-self-maintenance.md) ──
|
|
22759
|
+
// Every dep below is a read: this build cannot restart a machine or stop work.
|
|
22760
|
+
// A throwaway agent never runs it, whatever the gate says.
|
|
22761
|
+
try {
|
|
22762
|
+
const mmEnabled = () => resolveDevAgentGate(liveConfig.get('machineMaintenance.enabled', undefined), config);
|
|
22763
|
+
const projectDir = path.dirname(config.stateDir);
|
|
22764
|
+
const { classifyLocation, readThrowawayRecord } = await import('../core/ThrowawayAgentGuard.js');
|
|
22765
|
+
const throwaway = classifyLocation({ projectDir, record: readThrowawayRecord(projectDir) }).throwaway;
|
|
22766
|
+
if (mmEnabled() && !throwaway) {
|
|
22767
|
+
const { DrainRehearsal, readHostCensus, setActiveDrainRehearsal } = await import('../monitoring/machineMaintenance/DrainRehearsal.js');
|
|
22768
|
+
const { HostMaintenanceStore } = await import('../monitoring/machineMaintenance/HostMaintenanceStore.js');
|
|
22769
|
+
const { normalizeSettings } = await import('../monitoring/machineMaintenance/planner.js');
|
|
22770
|
+
const { makeReadOnlyRunner, readMachineSignals } = await import('../monitoring/machineMaintenance/readings.js');
|
|
22771
|
+
const { activeAutonomousJobs } = await import('../core/AutonomousSessions.js');
|
|
22772
|
+
const { getHostTestRunnerSemaphore } = await import('../core/hostTestRunnerSemaphore.js');
|
|
22773
|
+
const { IDLE_PROMPT_PATTERNS } = await import('../core/SessionManager.js');
|
|
22774
|
+
const atBoundary = async (tmux) => {
|
|
22775
|
+
// Async, so a slow pane cannot hold the event loop. tmux returns the whole
|
|
22776
|
+
// pane plus history here, and only the bottom says what the session is doing.
|
|
22777
|
+
const output = await sessionManager.captureOutputAsync(tmux, 12);
|
|
22778
|
+
if (output === null)
|
|
22779
|
+
return null;
|
|
22780
|
+
const tail = output.trimEnd().split('\n').slice(-12).join('\n');
|
|
22781
|
+
// Claude Code shows its prompt box while working too, so the working marker decides first.
|
|
22782
|
+
if (/esc to interrupt/i.test(tail))
|
|
22783
|
+
return false;
|
|
22784
|
+
return IDLE_PROMPT_PATTERNS.some((p) => tail.includes(p));
|
|
22785
|
+
};
|
|
22786
|
+
const rehearsal = new DrainRehearsal({
|
|
22787
|
+
agentName: config.projectName,
|
|
22788
|
+
version: startupVersion,
|
|
22789
|
+
stateDir: config.stateDir,
|
|
22790
|
+
logPath: path.join(config.stateDir, '..', 'logs', 'machine-drain.jsonl'),
|
|
22791
|
+
store: new HostMaintenanceStore(),
|
|
22792
|
+
enabled: mmEnabled,
|
|
22793
|
+
settings: () => normalizeSettings(liveConfig.get('machineMaintenance', undefined)),
|
|
22794
|
+
readSignals: () => readMachineSignals(makeReadOnlyRunner(config.sessions.tmuxPath)),
|
|
22795
|
+
census: async ({ readBoundaries }) => {
|
|
22796
|
+
const limiter = getHostTestRunnerSemaphore().status();
|
|
22797
|
+
const snapshot = localVerifyService?.snapshot();
|
|
22798
|
+
const sessions = [];
|
|
22799
|
+
for (const s of sessionManager.getCachedRunningSessions().sessions) {
|
|
22800
|
+
sessions.push({
|
|
22801
|
+
name: s.name, tmuxSession: s.tmuxSession, topicId: s.telegramTopicId, jobSlug: s.jobSlug,
|
|
22802
|
+
slackRoutingKey: _slackAdapter?.getChannelForSession(s.tmuxSession) ?? undefined,
|
|
22803
|
+
atBoundary: readBoundaries ? await atBoundary(s.tmuxSession) : null,
|
|
22804
|
+
});
|
|
22805
|
+
}
|
|
22806
|
+
return {
|
|
22807
|
+
sessions,
|
|
22808
|
+
autonomousRuns: activeAutonomousJobs(config.stateDir).map((j) => ({ topic: j.topic ?? 'legacy' })),
|
|
22809
|
+
localVerifyRunning: snapshot?.inFlight ? [snapshot.inFlight] : [],
|
|
22810
|
+
localVerifyQueued: (snapshot?.queue ?? []).map((e) => ({ pr: e.pr, headSha: e.headSha })),
|
|
22811
|
+
testRuns: [
|
|
22812
|
+
...limiter.liveHolders.map((h) => ({ pid: h.pid, acquiredAt: h.acquiredAt, lane: 'suite' })),
|
|
22813
|
+
...limiter.targetedHolders.map((h) => ({ pid: h.pid, acquiredAt: h.acquiredAt, lane: 'targeted' })),
|
|
22814
|
+
],
|
|
22815
|
+
scriptRuns: scheduler?.getActiveScriptRunIds() ?? [],
|
|
22816
|
+
};
|
|
22817
|
+
},
|
|
22818
|
+
resumeQueue: () => {
|
|
22819
|
+
const q = resumeQueue?.snapshot();
|
|
22820
|
+
return q ? { disabled: q.disabled, paused: q.paused, dryRun: q.dryRun, entries: q.entries.length } : null;
|
|
22821
|
+
},
|
|
22822
|
+
coResidentAgents: () => readHostCensus(path.join(os.homedir(), '.instar', 'registry.json'), Date.now()),
|
|
22823
|
+
holdsLease: () => (coordinator.enabled ? coordinator.holdsLease() : null),
|
|
22824
|
+
ownUser: os.userInfo().username,
|
|
22825
|
+
log: (line) => console.log(pc.yellow(` [machine-maintenance] ${line}`)),
|
|
22826
|
+
});
|
|
22827
|
+
setActiveDrainRehearsal(rehearsal);
|
|
22828
|
+
rehearsal.start();
|
|
22829
|
+
}
|
|
22830
|
+
}
|
|
22831
|
+
catch (err) {
|
|
22832
|
+
console.warn(` [machine-maintenance] not started: ${err instanceof Error ? err.message : err}`);
|
|
22833
|
+
}
|
|
22758
22834
|
// ── Overload admission (trustworthy-machine-load Part C) ──
|
|
22759
22835
|
// Each machine protects its own resources: closed to new AUTOMATIC work while
|
|
22760
22836
|
// its own load verdict is saturated/impaired, one host-wide recovery slot for an
|