instar 1.3.1590 → 1.3.1592
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 +6 -0
- package/dashboard/console/machines-model.js +15 -0
- package/dashboard/console/machines.js +3 -2
- package/dashboard/console/promises.js +3 -1
- 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.1591.md +27 -0
- package/upgrades/1.3.1592.md +22 -0
- package/upgrades/side-effects/console-decide-origin.eli16.md +12 -0
- package/upgrades/side-effects/console-decide-origin.md +24 -0
- package/upgrades/side-effects/machine-self-maintenance-watch-only.md +104 -0
|
@@ -992,6 +992,12 @@ button.run-mark:focus-visible { outline: 2px solid var(--accent); outline-offset
|
|
|
992
992
|
/* A column flex box squeezes its children to fit; history items must keep their own height
|
|
993
993
|
and let the box scroll (tool lines clip their overflow, so without this they shrink to 0). */
|
|
994
994
|
.sess-history > * { flex-shrink: 0; }
|
|
995
|
+
/* Long tool lines never wrap, so their min-content width is the whole line: without these
|
|
996
|
+
the open session (and the page's grid column) grew to fit it, wider than a phone. */
|
|
997
|
+
.main, .sess-view, .sess-open, .sess-term-wrap, .sess-composer { min-width: 0; }
|
|
998
|
+
.sess-input { min-width: 0; width: 100%; }
|
|
999
|
+
/* History has no live stream to return to: never float "Back to live" over it. */
|
|
1000
|
+
.sess-history:not([hidden]) ~ .sess-resume { display: none; }
|
|
995
1001
|
.sess-history-note { margin: 0; text-align: center; font-size: 13px; color: var(--text-muted); }
|
|
996
1002
|
.sess-h { max-width: 92%; }
|
|
997
1003
|
.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); }
|
|
@@ -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
|
);
|
|
@@ -143,7 +143,9 @@ function openPromise(r, { post, chatId, names, refresh }) {
|
|
|
143
143
|
else if (fallback) fallback.querySelector('p').textContent = 'Copying is unavailable here. Select this question and paste it in the conversation:';
|
|
144
144
|
} : undefined }));
|
|
145
145
|
}
|
|
146
|
-
|
|
146
|
+
// Always name the machine that holds it: the same promise id can exist on several
|
|
147
|
+
// machines (ids are per machine), and a bare id is refused as ambiguous.
|
|
148
|
+
const q = r.origin ? `?origin=${encodeURIComponent(r.origin)}` : '';
|
|
147
149
|
const id = encodeURIComponent(c.id);
|
|
148
150
|
const result = async (path, body) => {
|
|
149
151
|
const x = await post(`/commitments/${id}/${path}${q}`, body);
|
|
@@ -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":"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"}
|
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
|