instar 1.3.1641 → 1.3.1643

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.
Files changed (53) hide show
  1. package/dashboard/console/development-model.js +33 -5
  2. package/dashboard/console/development.js +33 -15
  3. package/dashboard/console/ui.js +3 -2
  4. package/dist/commands/server.d.ts.map +1 -1
  5. package/dist/commands/server.js +41 -1
  6. package/dist/commands/server.js.map +1 -1
  7. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  8. package/dist/core/PostUpdateMigrator.js +4 -3
  9. package/dist/core/PostUpdateMigrator.js.map +1 -1
  10. package/dist/data/standards-guard-index.json +14 -2
  11. package/dist/data/standards-guard-index.meta.json +3 -3
  12. package/dist/data/standards-registry.md +5 -5
  13. package/dist/data/standards-registry.meta.json +2 -2
  14. package/dist/monitoring/GuardLatchStore.d.ts +44 -3
  15. package/dist/monitoring/GuardLatchStore.d.ts.map +1 -1
  16. package/dist/monitoring/GuardLatchStore.js +68 -7
  17. package/dist/monitoring/GuardLatchStore.js.map +1 -1
  18. package/dist/monitoring/agentStopRelease.d.ts +170 -0
  19. package/dist/monitoring/agentStopRelease.d.ts.map +1 -0
  20. package/dist/monitoring/agentStopRelease.js +451 -0
  21. package/dist/monitoring/agentStopRelease.js.map +1 -0
  22. package/dist/monitoring/greenPrAutomergeWiring.d.ts +5 -0
  23. package/dist/monitoring/greenPrAutomergeWiring.d.ts.map +1 -1
  24. package/dist/monitoring/greenPrAutomergeWiring.js +47 -0
  25. package/dist/monitoring/greenPrAutomergeWiring.js.map +1 -1
  26. package/dist/native/InstarWedgeCanary.app/Contents/MacOS/InstarWedgeCanary +0 -0
  27. package/dist/native/instar-desktop-host +0 -0
  28. package/dist/server/AgentServer.d.ts +1 -0
  29. package/dist/server/AgentServer.d.ts.map +1 -1
  30. package/dist/server/AgentServer.js +1 -0
  31. package/dist/server/AgentServer.js.map +1 -1
  32. package/dist/server/CapabilityIndex.d.ts.map +1 -1
  33. package/dist/server/CapabilityIndex.js +2 -1
  34. package/dist/server/CapabilityIndex.js.map +1 -1
  35. package/dist/server/routes.d.ts +2 -0
  36. package/dist/server/routes.d.ts.map +1 -1
  37. package/dist/server/routes.js +122 -3
  38. package/dist/server/routes.js.map +1 -1
  39. package/dist/server/stopGate.js +1 -1
  40. package/dist/server/stopGate.js.map +1 -1
  41. package/package.json +1 -1
  42. package/src/data/builtin-manifest.json +64 -64
  43. package/src/data/standards-guard-index.json +14 -2
  44. package/src/data/standards-guard-index.meta.json +3 -3
  45. package/src/data/standards-registry.md +5 -5
  46. package/src/data/standards-registry.meta.json +2 -2
  47. package/upgrades/1.3.1642.md +23 -0
  48. package/upgrades/1.3.1643.md +30 -0
  49. package/upgrades/side-effects/agent-stop-release.md +77 -0
  50. package/upgrades/side-effects/console-development-stopped-lead.eli16.md +11 -0
  51. package/upgrades/side-effects/console-development-stopped-lead.md +55 -0
  52. package/upgrades/side-effects/message-origin-all-platforms-constitution.eli16.md +7 -0
  53. package/upgrades/side-effects/message-origin-all-platforms-constitution.md +22 -0
@@ -24,6 +24,7 @@ export const WATCHER_CADENCE_MS = 600000; // GreenPrAutoMerger
24
24
  export const VERIFY_MINUTES = 45; // a full local verify takes about this long
25
25
  export const ARMED_OVERDUE_MS = 24 * 3600000; // the watcher's own armed-confirm ceiling
26
26
  export const STALL_TICKS = 6; // readiness ticks in a row with no usable answer (about 3 h)
27
+ export const DEV_FOLDS = ['shipping', 'feedback', 'pace'];
27
28
  export const PACE_WINDOWS = [7, 14, 30];
28
29
  export const PACE_PEOPLE = [{ key: 'team', label: 'Everyone' }, { key: 'codey', label: 'Codey' }, { key: 'echo', label: 'Echo' }, { key: 'other', label: 'Others' }];
29
30
  export const PACE_METRICS = [
@@ -78,6 +79,8 @@ export function watcherLine(w, now = Date.now()) {
78
79
  if (w.invariantOk === false) return { text: 'Merge watcher: its safety invariant failed; it will not arm anything until that clears.', tone: 'bad' };
79
80
  if (w.breaker && w.breaker.open) return { text: 'Merge watcher paused itself after repeated failures.', tone: 'bad' };
80
81
  const gate = w.gate || {};
82
+ const stops = Array.isArray(gate.rollbackStops) ? gate.rollbackStops : [];
83
+ if (stops.length && stops.every((s) => s && s.class === 'agent')) return { text: 'Auto-merging is stopped by the agent for its own reason. It releases this itself when its condition is met; you can also turn it back on below.', tone: 'attn', stopped: true };
81
84
  if (Array.isArray(gate.rollback) && gate.rollback.length) return { text: 'Auto-merging is stopped (you or the agent rolled it back). Turn it back on below.', tone: 'attn', stopped: true };
82
85
  if (!w.lastTickAt) return { text: 'Merge watcher has not checked yet.', tone: 'unknown' };
83
86
  const age = now - w.lastTickAt;
@@ -183,12 +186,34 @@ export function buildShipping({ watcher, verify, release } = {}, now = Date.now(
183
186
  }
184
187
  const armedPrs = w && Array.isArray(w.armed) ? w.armed.map((a) => a.pr) : [];
185
188
  return {
186
- state: 'ok', headline, tone, tiles, rows, watcher: wl, release: releaseLine(release, now),
189
+ state: 'ok', headline, tone: wl && wl.stopped && tone !== 'bad' ? 'attn' : tone, tiles, rows, moving, watcher: wl, release: releaseLine(release, now),
187
190
  partial: !w || !v, armedPrs, stopped: Boolean(wl && wl.stopped), rollbackLatches: (w && w.gate && Array.isArray(w.gate.rollback)) ? w.gate.rollback : [],
188
- line: !w ? 'Shipping: can’t tell' : `Shipping: ${moving === 0 ? 'nothing on the way' : `${moving} on the way`}${needs ? `, ${needs} need${needs === 1 ? 's' : ''} you` : ''}${stuck ? `, ${needs ? '' : ''}${stuck} stuck` : ''}`,
191
+ line: !w ? 'Shipping: can’t tell' : `Shipping: ${wl && wl.stopped ? 'auto-merge stopped, ' : ''}${moving === 0 ? 'nothing on the way' : `${moving} on the way`}${needs ? `, ${needs} need${needs === 1 ? 's' : ''} you` : ''}${stuck ? `, ${needs ? '' : ''}${stuck} stuck` : ''}`,
189
192
  repoKnown: Boolean(repo),
190
193
  };
191
194
  }
195
+ /**
196
+ * The lead card while auto-merging is stopped, or null when it is not. It is the first
197
+ * thing on the page because the stop is invisible otherwise: nothing merges, and the
198
+ * Shipping fold that used to be its only sign is often closed.
199
+ */
200
+ export function stoppedLead(shipping) {
201
+ if (!shipping || !shipping.stopped) return null;
202
+ const n = shipping.moving || 0;
203
+ return {
204
+ title: 'Automatic merging is stopped',
205
+ detail: `No pull request merges on its own until it is back on.${n ? ` ${plural(n, 'pull request is', 'pull requests are')} on the way.` : ''}`,
206
+ why: shipping.watcher.text,
207
+ button: 'Turn auto-merge back on',
208
+ };
209
+ }
210
+
211
+ /** The section a `?s=` link names, from the location hash; null for none or an unknown one. */
212
+ export function foldFromHash(hash) {
213
+ const s = new URLSearchParams(String(hash || '').split('?')[1] || '').get('s');
214
+ return DEV_FOLDS.includes(s) ? s : null;
215
+ }
216
+
192
217
  function ordinal(n) { return n === 1 ? '1st' : n === 2 ? '2nd' : n === 3 ? '3rd' : `${n}th`; }
193
218
 
194
219
  /** Words for the hold result (never a blanket "held": the server says whether an armed merge was disarmed). */
@@ -545,11 +570,14 @@ export function commitResultWords(status, data) {
545
570
  // ── The combined page ────────────────────────────────────────────────────────
546
571
  /** The page headline: the worst state first, coverage stated. */
547
572
  export function developmentHeadline({ shipping, feedback, pace } = {}) {
573
+ const stopped = Boolean(shipping && shipping.stopped);
574
+ const needs = shipping && shipping.rows ? shipping.rows.filter((r) => r.group === 'needs') : [];
548
575
  if (feedback && feedback.todos && feedback.todos.length) {
549
- const n = feedback.todos.length + (shipping && shipping.rows ? shipping.rows.filter((r) => r.group === 'needs').length : 0);
550
- return { text: n === 1 ? 'One thing needs you.' : `${n} things need you.`, tone: 'attn', sub: feedback.todos[0].sentence };
576
+ const n = feedback.todos.length + needs.length + (stopped ? 1 : 0);
577
+ return { text: n === 1 ? 'One thing needs you.' : `${n} things need you.`, tone: 'attn', sub: stopped ? 'Automatic merging is stopped.' : feedback.todos[0].sentence };
551
578
  }
552
- const needs = shipping && shipping.rows ? shipping.rows.filter((r) => r.group === 'needs') : [];
579
+ // Stopped is never "Nothing here needs you": it comes before every calmer reading below.
580
+ if (stopped) return { text: needs.length ? `${needs.length + 1} things need you.` : 'Automatic merging is stopped.', tone: 'attn', sub: needs.length ? 'Automatic merging is stopped.' : shipping.line };
553
581
  if (needs.length) return { text: needs.length === 1 ? 'One pull request needs your approval on GitHub.' : `${needs.length} pull requests need your approval on GitHub.`, tone: 'attn', sub: shipping.line };
554
582
  if (feedback && feedback.state === 'cant-tell') return { text: 'Can’t tell whether anything needs you.', tone: 'muted', sub: feedback.headline };
555
583
  const stuck = shipping && shipping.rows ? shipping.rows.filter((r) => r.group === 'stuck').length : 0;
@@ -10,7 +10,7 @@
10
10
  // server requires it. Every value reaches the DOM through textContent.
11
11
 
12
12
  import {
13
- buildShipping, buildPace, buildFeedback, developmentHeadline, maintainerMode, authorityCard, holdWords, verifyWords, rollbackWords,
13
+ buildShipping, buildPace, buildFeedback, developmentHeadline, stoppedLead, foldFromHash, maintainerMode, authorityCard, holdWords, verifyWords, rollbackWords,
14
14
  readinessAuthorityRequest, triageAuthorityRequest, commitRequest, authorityResultWords, commitResultWords, newDecisionRef, PACE_METRICS, DEV_TOOLS_KEY,
15
15
  } from './development-model.js';
16
16
  import { el, setKids, pageHead, section, sheet, closeSheet, story, details, note, cantTell, askPin } from './ui.js';
@@ -19,8 +19,8 @@ import { legacyHref } from './nav-model.js';
19
19
  const EYEBROW = 'Work · Development';
20
20
  const TIMEOUT_MS = 5000;
21
21
  const PROBE_FRESH_MS = 5 * 60000;
22
- // The open fold, the Pace controls and any limits the operator typed, kept across refreshes (F9: a poll never rebuilds typed input).
23
- const view = { open: null, days: 14, person: 'team', metric: 'merges', day: null, envelope: { readiness: null, triage: null } };
22
+ // The open fold, a link's section still to scroll to, the Pace controls and any limits the operator typed, kept across refreshes (F9: a poll never rebuilds typed input).
23
+ const view = { open: null, scrollTo: null, days: 14, person: 'team', metric: 'merges', day: null, envelope: { readiness: null, triage: null } };
24
24
  let last = null;
25
25
  let probe = null; // { at, promise } — the maintainer-mode reads, once per page load
26
26
 
@@ -90,9 +90,13 @@ export function groupExtras(g, { get }) {
90
90
 
91
91
  // ── the page ─────────────────────────────────────────────────────────────────
92
92
  export async function renderDevelopment(main, ctx) {
93
- if (!main.querySelector('.dev-page')) setKids(main, el('section', { class: 'hero page-hero' }, el('div', { class: 'eyebrow', text: EYEBROW }), el('h1', { class: 'page-title skeleton', text: 'Loading development' })));
94
- const want = new URLSearchParams((location.hash.split('?')[1] || '')).get('s');
95
- if (want && !view.open) view.open = want;
93
+ // Each navigation gets a new <main>, so no page yet means someone just arrived: a `?s=` link wins over the
94
+ // remembered fold then. A 30-second refresh keeps the page, so it never overrides what the operator opened or closed.
95
+ if (!main.querySelector('.dev-page')) {
96
+ setKids(main, el('section', { class: 'hero page-hero' }, el('div', { class: 'eyebrow', text: EYEBROW }), el('h1', { class: 'page-title skeleton', text: 'Loading development' })));
97
+ const want = foldFromHash(location.hash);
98
+ if (want) { view.open = want; view.scrollTo = want; }
99
+ }
96
100
  const [watcher, verify, release, readiness, triageSummary, triageProposal, execute, queue, drain, pace] = await Promise.all([
97
101
  read('/green-pr-automerge'), read('/local-verify'), read('/release-readiness'),
98
102
  read('/feedback-factory/readiness-authorities/proposal'), read('/feedback-factory/triage/summary'), read('/feedback-factory/triage/authority/proposal'),
@@ -117,13 +121,14 @@ function paint() {
117
121
  const todos = feedback.todos;
118
122
  const first = todos[0] || null;
119
123
  const lead = first ? todoCard(first, deps, true) : null;
124
+ const stopped = stoppedCard(shipping, deps);
120
125
  const moreLine = todos.length > 1 ? el('button', { class: 'link-btn older-line', type: 'button', text: `${todos.length - 1} more ${todos.length === 2 ? 'thing needs' : 'things need'} you ›`, onclick: () => openMore(todos.slice(1), deps) }) : null;
121
126
 
122
127
  // First arrival opens the section with the worst news (Shipping otherwise); 'none' is the operator's own collapse.
123
128
  if (!view.open) view.open = feedback.tone === 'attn' || feedback.state === 'cant-tell' ? 'feedback' : 'shipping';
124
129
  setKids(main, el('div', { class: 'dev-page' },
125
130
  pageHead({ eyebrow: EYEBROW, headline: h.text, sub: h.sub, tone: h.tone }),
126
- lead, moreLine,
131
+ stopped, lead, moreLine,
127
132
  el('div', { class: 'page-sections' },
128
133
  fold({ id: 'shipping', title: 'Shipping', line: shipping.line, tone: shipping.tone, body: () => shippingBody(shipping, deps) }),
129
134
  fold({ id: 'feedback', title: 'Feedback', line: feedback.line, tone: feedback.tone, body: () => feedbackBody(feedback, deps) }),
@@ -131,8 +136,12 @@ function paint() {
131
136
  ),
132
137
  el('p', { class: 'foot-note' }, el('a', { href: legacyHref('pr-pipeline'), text: 'Legacy PR pipeline' }), document.createTextNode(' · '), el('a', { href: legacyHref('feedback-drain'), text: 'feedback drain' }), document.createTextNode(' · '), el('a', { href: legacyHref('throughput'), text: 'throughput' })),
133
138
  ));
134
- const sec = main.querySelector(`#sec-${view.open}`);
135
- if (sec && new URLSearchParams((location.hash.split('?')[1] || '')).get('s') === view.open) sec.scrollIntoView({ block: 'start' });
139
+ // Once per arrival: a refresh or a fold tap must not pull the page back to the linked section.
140
+ if (view.scrollTo) {
141
+ const sec = main.querySelector(`#sec-${view.scrollTo}`);
142
+ view.scrollTo = null;
143
+ if (sec) sec.scrollIntoView({ block: 'start' });
144
+ }
136
145
  }
137
146
 
138
147
  /** One of the three sections: a one-line summary that opens in place; one open at a time. */
@@ -159,6 +168,17 @@ function toneLine(l, extra) {
159
168
  function block(title, ...kids) { return el('section', { class: 'sheet-block' }, el('h3', { class: 'eyebrow', text: title }), ...kids); }
160
169
  function sub(title, ...kids) { return el('div', { class: 'dev-sub' }, el('h3', { class: 'eyebrow sub-label', text: title }), ...kids); }
161
170
 
171
+ /** The one way back on: the lead card and the Shipping fold both use it. */
172
+ function backOnButton(s, deps, primary = false) {
173
+ return el('button', { class: primary ? 'btn-primary btn-inline' : 'btn-quiet', type: 'button', text: 'Turn auto-merge back on', onclick: () => enableAutoMerge(s, deps) });
174
+ }
175
+ /** Auto-merging is stopped: the first thing on the page, whichever fold is open. */
176
+ function stoppedCard(s, deps) {
177
+ const c = stoppedLead(s);
178
+ if (!c) return null;
179
+ return el('div', { class: 'need-card stopped-lead' }, el('span', { class: 'need-title', text: c.title }), el('span', { class: 'need-sub', text: c.detail }), el('span', { class: 'need-sub', text: c.why }), backOnButton(s, deps, true));
180
+ }
181
+
162
182
  // ── to-dos (Feedback approvals and links) ────────────────────────────────────
163
183
  function todoCard(todo, deps, lead = false) {
164
184
  if (todo.kind === 'link') {
@@ -263,11 +283,8 @@ function shippingBody(s, deps) {
263
283
  const rows = s.rows.map((r) => ({ ...r, sub: r.sub, end: r.end }));
264
284
  const list = section({ id: 'prs', title: 'Pull requests', rows, empty: s.headline, onRow: (r) => openPr(r, s, deps) });
265
285
  const foot = el('div', { class: 'sheet-actions dev-foot' });
266
- if (s.stopped) {
267
- const back = el('button', { class: 'btn-quiet', type: 'button', text: 'Turn auto-merge back on' });
268
- back.addEventListener('click', () => enableAutoMerge(s, deps));
269
- foot.append(back);
270
- } else {
286
+ if (s.stopped) foot.append(backOnButton(s, deps));
287
+ else {
271
288
  const stop = el('button', { class: 'btn-quiet btn-danger-outline', type: 'button', text: 'Stop auto-merging' });
272
289
  stop.addEventListener('click', () => stopAutoMerge(s, deps));
273
290
  foot.append(stop);
@@ -279,7 +296,8 @@ function shippingBody(s, deps) {
279
296
  release, toneLine(s.watcher),
280
297
  s.partial ? note('Partial: one of Shipping’s sources did not answer; its tile says why. The others are real.') : null,
281
298
  s.repoKnown ? null : note('GitHub links are off: the repository name comes from the Pace read, which did not answer.'),
282
- list, foot,
299
+ // While stopped the way back on sits above the list, not under a long list of pull requests.
300
+ s.stopped ? [foot, list] : [list, foot],
283
301
  ];
284
302
  }
285
303
 
@@ -14,7 +14,8 @@ export function el(tag, attrs = {}, ...kids) {
14
14
  else if (k.startsWith('on') && typeof v === 'function') n.addEventListener(k.slice(2), v);
15
15
  else n.setAttribute(k, v === true ? '' : String(v));
16
16
  }
17
- for (const kid of kids.flat()) if (kid != null && kid !== false) n.append(kid);
17
+ // Any depth: an array left inside the kids would otherwise be stringified into the page ("[object HTMLParagraphElement]").
18
+ for (const kid of kids.flat(Infinity)) if (kid != null && kid !== false) n.append(kid);
18
19
  return n;
19
20
  }
20
21
 
@@ -204,7 +205,7 @@ export function actionButton({ label, kind = 'primary', confirm, reason, run, do
204
205
  }
205
206
 
206
207
  /** replaceChildren that skips null/false (a bare null would render as the text "null"). */
207
- export function setKids(node, ...kids) { node.replaceChildren(...kids.flat().filter((k) => k != null && k !== false)); }
208
+ export function setKids(node, ...kids) { node.replaceChildren(...kids.flat(Infinity).filter((k) => k != null && k !== false)); }
208
209
 
209
210
  // ── PIN sheet (00-patterns.md §4: one look, per-action adapters) ───────────
210
211
  // adapter 'session': POST /dashboard/unlock → operator-session token, held in page
@@ -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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"}
@@ -22178,6 +22178,7 @@ export async function startServer(options) {
22178
22178
  // session death; the dual-latch gate is read every tick.
22179
22179
  let greenPrAutoMerger = null;
22180
22180
  let guardLatchStore = null;
22181
+ let agentStopSurfacer = null;
22181
22182
  {
22182
22183
  const gpCfg = config.monitoring?.greenPrAutoMerge;
22183
22184
  if (gpCfg?.enabled) {
@@ -22224,6 +22225,42 @@ export async function startServer(options) {
22224
22225
  };
22225
22226
  guardLatchStore = wiring.buildGuardLatchStore(wiringOpts);
22226
22227
  const deps = wiring.buildGreenPrDeps(wiringOpts, guardLatchStore);
22228
+ // green-pr-agent-stop-release: its own pass and own state file, apart from the
22229
+ // watcher's tick, so a stop cannot be orphaned and a slow read cannot stall a tick.
22230
+ {
22231
+ const latchesForStops = guardLatchStore;
22232
+ const { AgentStopSurfacer } = await import('../monitoring/agentStopRelease.js');
22233
+ agentStopSurfacer = new AgentStopSurfacer({
22234
+ stateDir: config.stateDir,
22235
+ listRollbackStops: () => latchesForStops.rollbackStops(),
22236
+ facts: wiring.buildAgentStopFacts(wiringOpts),
22237
+ runningVersion: () => ProcessIntegrity.getInstance()?.runningVersion ?? config.version ?? null,
22238
+ commitments: commitmentTracker,
22239
+ raiseAttention: telegram ? (item) => telegram.upsertAttentionItem(item) : undefined,
22240
+ closeAttention: telegram ? (id, resolution) => { telegram.clearAttentionCondition({ id }, resolution); } : undefined,
22241
+ wakeTopic: telegram
22242
+ ? async (topicId, brief) => {
22243
+ const live = telegram.getSessionForTopic(topicId);
22244
+ if (live && sessionManager.isSessionAlive(live)) {
22245
+ sessionManager.injectTelegramMessage(live, topicId, brief);
22246
+ return;
22247
+ }
22248
+ // A topic a peer owns gets no second session here. Refusing leaves the wake
22249
+ // to retry in an hour, with the Attention item as the floor.
22250
+ if (_claimOwnershipForAutonomousSpawn?.(topicId) === 'owned-elsewhere')
22251
+ throw new Error('topic is owned by another machine');
22252
+ if (live) {
22253
+ await respawnSessionForTopic(sessionManager, telegram, live, topicId, brief, topicMemory);
22254
+ return;
22255
+ }
22256
+ // Keep the topic's own name; registering a made-up one would retitle it.
22257
+ const name = (await telegram.resolveTopicName(topicId)) ?? `topic-${topicId}`;
22258
+ telegram.registerTopicSession(topicId, await spawnSessionForTopic(sessionManager, telegram, name, topicId, brief, topicMemory), name);
22259
+ }
22260
+ : undefined,
22261
+ logger: (m) => console.warn(m),
22262
+ });
22263
+ }
22227
22264
  const { GreenPrAutoMerger } = await import('../monitoring/GreenPrAutoMerger.js');
22228
22265
  greenPrAutoMerger = new GreenPrAutoMerger(deps, {
22229
22266
  ...gpCfg,
@@ -29588,7 +29625,7 @@ export async function startServer(options) {
29588
29625
  const server = new AgentServer({ config, ecosystemLedger: _ecosystemLedger ?? undefined, singleInstanceLock, agentIdentity: _agentIdentityDeps, terminateSessionAuthority: terminateWithAuthority, subscriptionEmailBinding: credentialLocationLedger, subscriptionEmailBarrier, subscriptionIdentityOracle, sessionManager, llmQueue: sharedLlmQueue, state, scheduler, telegram, telegramOrigin: telegramOriginBoot?.runtime, relationships, feedback, feedbackAnomalyDetector, dispatches, updateChecker, autoUpdater, autoDispatcher, quotaTracker, quotaManager, publisher, viewer, jobAnomalySendAutomationReply: sendAutomationReply, tunnel, evolution, watchdog, topicMemory, triageNurse, projectMapper, cartographerRoots: cartographerRoots ?? undefined, coherenceGate: scopeVerifier, contextHierarchy, canonicalState, operationGate, sentinel, adaptiveTrust, memoryMonitor, orphanReaper, coherenceMonitor, commitmentTracker, subscriptionPool, accountFollowMePeerViews: async () => { const nickById = new Map((_listPoolMachines?.() ?? []).map((m) => [m.machineId, verifiedEntityName(m.machineId, m.nickname) ?? ''])); let peers = (_resolvePeerUrls?.() ?? []).map((p) => ({ machineId: p.machineId, nickname: nickById.get(p.machineId) ?? '', url: p.url })); if (peers.length === 0) {
29589
29626
  peers = (_listPoolMachines?.() ?? []).filter((m) => m.machineId !== _meshSelfId && !!m.lastKnownUrl).map((m) => ({ machineId: m.machineId, nickname: verifiedEntityName(m.machineId, m.nickname) ?? '', url: m.lastKnownUrl }));
29590
29627
  } if (peers.length === 0)
29591
- return []; const { fetchPeerSubscriptionViews } = await import('../core/fetchPeerSubscriptionViews.js'); return fetchPeerSubscriptionViews({ peers: () => peers, fetchImpl: fetch, authToken: config.authToken ?? '' }); }, quotaPoller, quotaAwareScheduler: _quotaAwareScheduler ?? undefined, proactiveSwapMonitor: _proactiveSwapMonitor ?? undefined, inUseAccountResolver, enrollmentWizard, accountFollowMeRevocation, credentialRepointing, semanticMemory, activitySentinel, rateLimitSentinel, releaseReadinessSentinel: releaseReadinessSentinel ?? undefined, greenPrAutoMerger: greenPrAutoMerger ?? undefined, localVerify: localVerifyService ?? undefined, localVerifyStatus: localVerifyStatus ?? undefined, guardLatchStore: guardLatchStore ?? undefined, messageRouter, summarySentinel, spawnManager, systemReviewer, capabilityMapper, selfKnowledgeTree, coverageAuditor, topicResumeMap: _topicResumeMap ?? undefined, topicProfile: _topicProfileCtx ?? undefined, sessionRefresh: _sessionRefresh ?? undefined, autonomyManager, trustElevationTracker, autonomousEvolution, coordinator: coordinator.enabled ? coordinator : undefined, meshBindActive: coordinator.managers.identityManager.hasIdentity() && config.multiMachine?.meshTransport?.enabled !== false, localSigningKeyPem, leaseTransport, peerEndpointRecorder, getSelfMeshEndpoints, onLeasePullRequest: () => leaseCoordinatorRef?.currentLease() ?? null, liveTailReceiver, handoffWireTransport, onHandoffBegin, onHandoffInitiate: handoffInitiate, handoffInProgress: handoffSentinelInProgress, messageLedger, currentInboundByTopic, replyMarkerTransport, onReplyMarker: messageLedger ? (marker) => { const m = marker; messageLedger.applyRemoteReplyMarker(m.dedupeKey, { platform: m.platform, replyIdempotencyKey: m.replyIdempotencyKey, epoch: m.epoch, topic: m.topic ?? null }); } : undefined, whatsapp: whatsappAdapter, slack: slackAdapter, imessage: imessageAdapter, conversationRegistry, conversationBindAuth, appConversations: _appConversationService ?? undefined, slackInboundDispatch: () => _slackInboundDispatch, conversationFollowThrough, whatsappBusinessBackend, messageBridge, hookEventReceiver, worktreeMonitor, subagentTracker, instructionsVerifier, handshakeManager: threadlineHandshake, threadlineRouter, conversationStore, threadLog, threadMessageRecorder, warrantsReplyGate, collaborationSurfacer, peerHomebaseRelay, threadResumeMap, topicLinkageHandler: topicLinkageHandler ?? undefined, threadlineRelayClient, pairingInvites: threadlinePairingInvites, getLastRelayEvent: threadlineGetLastRelayEvent, a2aRelayForward: _a2aRelayForwardCtx ?? undefined, threadlineReplyWaiters, threadlineMcpHttp, listenerManager: listenerManager ?? undefined, a2aDeliveryTracker: a2aDeliveryTracker ?? undefined, relayVerdictCounters: threadlineRelayClient ? (() => ({ ...threadlineRelayClient.relayVerdictCounters, expiredMismatchIgnored: a2aDeliveryTracker?.expiredMismatchIgnored ?? 0 })) : undefined, inboundIdLedger: _inboundIdLedger ?? undefined, inboundIdLedgerDaemonDeferred: () => _inboundIdLedgerDaemonDeferred, responseReviewGate, reviewCanaryBattery, messagingToneGate, outboundDedupGate, telemetryHeartbeat, pasteManager, featureRegistry, discoveryEvaluator, completionEvaluator, unifiedTrust, liveConfig, sharedStateLedger, ledgerSessionRegistry, worktreeManager, oidcEnrolledRepos: parallelDevConfig?.oidcEnrolledRepos, initiativeTracker, projectRoundRunner, projectDriftChecker, machineHeartbeat, machinePoolRegistry, ropeHealthMonitor, writeAdmission: writeAdmission ?? undefined, getInboundQueue: () => _inboundQueue, getMachineCoherence: () => _machineCoherenceSentinel, getSingleMachineFailoverGap: () => _singleMachineFailoverGap, getMissingLoginSession: () => _missingLoginSession, getSessionPoolFailoverRunner: () => _sessionPoolFailoverRunnerDriver?.status() ?? null, sessionPoolPromotionActivation: _sessionPoolPromotionActivation, meshRpcDispatcher, deliverA2aToMachine: _deliverA2aToMachine ?? undefined, workingSetPullCoordinator, workingSetArtifactManager, orchestratorPoller, commitmentReplicaStore, preferenceReplicaStore, replicatedRecordEmitter, replicatedStoreReconciler, conflictStore, rollbackUnmerge, droppedOriginRegistry, preferencesUnionReader, jevMemoryPicker, forwardCommitmentMutate, sessionOwnershipRegistry, sendDrain: _sendDrain ?? undefined, claimTopicOwnershipOnSpawn: (topicId) => _claimOwnershipForAutonomousSpawn ? _claimOwnershipForAutonomousSpawn(topicId) : 'unwired', topicPinStore: _topicPinStore ?? undefined, topicPinSkewQuarantine: _topicPinSkewQuarantine ?? undefined, topicPinFoldView: _topicPinFoldView ?? undefined, ownershipReconciler: _ownershipReconciler ?? undefined, staleOwnerEngine: _staleOwnerEngine ?? undefined, duplicateReconciler: _duplicateReconciler ?? undefined, ownerDarkLadder: _ownerDarkLadder ?? undefined, spawnAdmission: _spawnAdmission ?? undefined, judgmentProvenance: _judgmentProvenance ?? undefined, leaseHandback: _leaseHandbackCtx ?? undefined, streamTicketStore: _streamTicketStore ?? undefined, poolStreamAllowRemoteInput: config.dashboard?.poolStream?.allowRemoteInput ?? false, poolStreamConnector: _poolStreamConnector ?? undefined, secretSync: _secretSyncHandle ?? undefined, meshSelfId: _meshSelfId ?? undefined, resolveRouterUrl: _resolveRouterUrl ?? undefined, resolvePeerUrls: _resolvePeerUrls ?? undefined, recordRopeResult: _recordRopeResult ?? undefined, guardRegistry, listPoolMachines: _listPoolMachines ?? undefined, deliverMandateToMachine: _deliverMandateToMachine ?? undefined, passkeyRevokeOutbox: _passkeyRevokeOutbox ? () => _passkeyRevokeOutbox : undefined, passkeyPeerOnline: _passkeyPeerOnline, passkeyPoolReader: _passkeyPoolReader ? () => _passkeyPoolReader : undefined, passkeyProofBrowser: async (profileDir) => { const { ChromeCdpReloginBrowser } = await import('../core/ChromeCdpReloginBrowser.js'); return new ChromeCdpReloginBrowser({ userDataDir: profileDir, passkeyMode: true, headless: true, launchTimeoutMs: 30_000, operationTimeoutMs: 20_000 }); }, poolLink: _poolLink ?? undefined, poolPollCache: _poolPollCache ?? undefined, sessionPoolE2EResultStore, proxyCoordinator, topicIntentStore, topicIntentArcCheck, usherSignalStore, intelligence: sharedIntelligence ?? undefined, telegramBridgeConfig, telegramBridge: telegramBridge ?? undefined, threadlineObservability, briefDeps, workingMemory, taskFlowRegistry, threadlineFlowBridge, sessionReaper, agentWorktreeReaper, externalHogSentinel, orphanedWorkSentinel, mcpProcessReaper, codexArmSessionSweeper, geminiLoopRunner, sleepController, agentActivityState, reapLog, resumeQueue, resumeDrainer, autonomousLivenessReconciler, enforcedTerminationStatus: () => enforcedTerminationWatchdog?.guardStatus() ?? null, prHandLease: prHandLease ?? undefined, standDownRegistry: _standDownRegistry ?? undefined, standDownAudit: _standDownAudit ?? undefined, operatorStopRecorder: recordOperatorStop, sleepWakeDetector, unjustifiedStopGate, stopGateDb, stopNotifier, liveTestGate, liveTestGateMode, liveTestRunnerCtx }); // Resolve the late-bound topic-operator getter (increment 2e): routing was
29628
+ return []; const { fetchPeerSubscriptionViews } = await import('../core/fetchPeerSubscriptionViews.js'); return fetchPeerSubscriptionViews({ peers: () => peers, fetchImpl: fetch, authToken: config.authToken ?? '' }); }, quotaPoller, quotaAwareScheduler: _quotaAwareScheduler ?? undefined, proactiveSwapMonitor: _proactiveSwapMonitor ?? undefined, inUseAccountResolver, enrollmentWizard, accountFollowMeRevocation, credentialRepointing, semanticMemory, activitySentinel, rateLimitSentinel, releaseReadinessSentinel: releaseReadinessSentinel ?? undefined, greenPrAutoMerger: greenPrAutoMerger ?? undefined, localVerify: localVerifyService ?? undefined, localVerifyStatus: localVerifyStatus ?? undefined, guardLatchStore: guardLatchStore ?? undefined, agentStopSurfacer: agentStopSurfacer ?? undefined, messageRouter, summarySentinel, spawnManager, systemReviewer, capabilityMapper, selfKnowledgeTree, coverageAuditor, topicResumeMap: _topicResumeMap ?? undefined, topicProfile: _topicProfileCtx ?? undefined, sessionRefresh: _sessionRefresh ?? undefined, autonomyManager, trustElevationTracker, autonomousEvolution, coordinator: coordinator.enabled ? coordinator : undefined, meshBindActive: coordinator.managers.identityManager.hasIdentity() && config.multiMachine?.meshTransport?.enabled !== false, localSigningKeyPem, leaseTransport, peerEndpointRecorder, getSelfMeshEndpoints, onLeasePullRequest: () => leaseCoordinatorRef?.currentLease() ?? null, liveTailReceiver, handoffWireTransport, onHandoffBegin, onHandoffInitiate: handoffInitiate, handoffInProgress: handoffSentinelInProgress, messageLedger, currentInboundByTopic, replyMarkerTransport, onReplyMarker: messageLedger ? (marker) => { const m = marker; messageLedger.applyRemoteReplyMarker(m.dedupeKey, { platform: m.platform, replyIdempotencyKey: m.replyIdempotencyKey, epoch: m.epoch, topic: m.topic ?? null }); } : undefined, whatsapp: whatsappAdapter, slack: slackAdapter, imessage: imessageAdapter, conversationRegistry, conversationBindAuth, appConversations: _appConversationService ?? undefined, slackInboundDispatch: () => _slackInboundDispatch, conversationFollowThrough, whatsappBusinessBackend, messageBridge, hookEventReceiver, worktreeMonitor, subagentTracker, instructionsVerifier, handshakeManager: threadlineHandshake, threadlineRouter, conversationStore, threadLog, threadMessageRecorder, warrantsReplyGate, collaborationSurfacer, peerHomebaseRelay, threadResumeMap, topicLinkageHandler: topicLinkageHandler ?? undefined, threadlineRelayClient, pairingInvites: threadlinePairingInvites, getLastRelayEvent: threadlineGetLastRelayEvent, a2aRelayForward: _a2aRelayForwardCtx ?? undefined, threadlineReplyWaiters, threadlineMcpHttp, listenerManager: listenerManager ?? undefined, a2aDeliveryTracker: a2aDeliveryTracker ?? undefined, relayVerdictCounters: threadlineRelayClient ? (() => ({ ...threadlineRelayClient.relayVerdictCounters, expiredMismatchIgnored: a2aDeliveryTracker?.expiredMismatchIgnored ?? 0 })) : undefined, inboundIdLedger: _inboundIdLedger ?? undefined, inboundIdLedgerDaemonDeferred: () => _inboundIdLedgerDaemonDeferred, responseReviewGate, reviewCanaryBattery, messagingToneGate, outboundDedupGate, telemetryHeartbeat, pasteManager, featureRegistry, discoveryEvaluator, completionEvaluator, unifiedTrust, liveConfig, sharedStateLedger, ledgerSessionRegistry, worktreeManager, oidcEnrolledRepos: parallelDevConfig?.oidcEnrolledRepos, initiativeTracker, projectRoundRunner, projectDriftChecker, machineHeartbeat, machinePoolRegistry, ropeHealthMonitor, writeAdmission: writeAdmission ?? undefined, getInboundQueue: () => _inboundQueue, getMachineCoherence: () => _machineCoherenceSentinel, getSingleMachineFailoverGap: () => _singleMachineFailoverGap, getMissingLoginSession: () => _missingLoginSession, getSessionPoolFailoverRunner: () => _sessionPoolFailoverRunnerDriver?.status() ?? null, sessionPoolPromotionActivation: _sessionPoolPromotionActivation, meshRpcDispatcher, deliverA2aToMachine: _deliverA2aToMachine ?? undefined, workingSetPullCoordinator, workingSetArtifactManager, orchestratorPoller, commitmentReplicaStore, preferenceReplicaStore, replicatedRecordEmitter, replicatedStoreReconciler, conflictStore, rollbackUnmerge, droppedOriginRegistry, preferencesUnionReader, jevMemoryPicker, forwardCommitmentMutate, sessionOwnershipRegistry, sendDrain: _sendDrain ?? undefined, claimTopicOwnershipOnSpawn: (topicId) => _claimOwnershipForAutonomousSpawn ? _claimOwnershipForAutonomousSpawn(topicId) : 'unwired', topicPinStore: _topicPinStore ?? undefined, topicPinSkewQuarantine: _topicPinSkewQuarantine ?? undefined, topicPinFoldView: _topicPinFoldView ?? undefined, ownershipReconciler: _ownershipReconciler ?? undefined, staleOwnerEngine: _staleOwnerEngine ?? undefined, duplicateReconciler: _duplicateReconciler ?? undefined, ownerDarkLadder: _ownerDarkLadder ?? undefined, spawnAdmission: _spawnAdmission ?? undefined, judgmentProvenance: _judgmentProvenance ?? undefined, leaseHandback: _leaseHandbackCtx ?? undefined, streamTicketStore: _streamTicketStore ?? undefined, poolStreamAllowRemoteInput: config.dashboard?.poolStream?.allowRemoteInput ?? false, poolStreamConnector: _poolStreamConnector ?? undefined, secretSync: _secretSyncHandle ?? undefined, meshSelfId: _meshSelfId ?? undefined, resolveRouterUrl: _resolveRouterUrl ?? undefined, resolvePeerUrls: _resolvePeerUrls ?? undefined, recordRopeResult: _recordRopeResult ?? undefined, guardRegistry, listPoolMachines: _listPoolMachines ?? undefined, deliverMandateToMachine: _deliverMandateToMachine ?? undefined, passkeyRevokeOutbox: _passkeyRevokeOutbox ? () => _passkeyRevokeOutbox : undefined, passkeyPeerOnline: _passkeyPeerOnline, passkeyPoolReader: _passkeyPoolReader ? () => _passkeyPoolReader : undefined, passkeyProofBrowser: async (profileDir) => { const { ChromeCdpReloginBrowser } = await import('../core/ChromeCdpReloginBrowser.js'); return new ChromeCdpReloginBrowser({ userDataDir: profileDir, passkeyMode: true, headless: true, launchTimeoutMs: 30_000, operationTimeoutMs: 20_000 }); }, poolLink: _poolLink ?? undefined, poolPollCache: _poolPollCache ?? undefined, sessionPoolE2EResultStore, proxyCoordinator, topicIntentStore, topicIntentArcCheck, usherSignalStore, intelligence: sharedIntelligence ?? undefined, telegramBridgeConfig, telegramBridge: telegramBridge ?? undefined, threadlineObservability, briefDeps, workingMemory, taskFlowRegistry, threadlineFlowBridge, sessionReaper, agentWorktreeReaper, externalHogSentinel, orphanedWorkSentinel, mcpProcessReaper, codexArmSessionSweeper, geminiLoopRunner, sleepController, agentActivityState, reapLog, resumeQueue, resumeDrainer, autonomousLivenessReconciler, enforcedTerminationStatus: () => enforcedTerminationWatchdog?.guardStatus() ?? null, prHandLease: prHandLease ?? undefined, standDownRegistry: _standDownRegistry ?? undefined, standDownAudit: _standDownAudit ?? undefined, operatorStopRecorder: recordOperatorStop, sleepWakeDetector, unjustifiedStopGate, stopGateDb, stopNotifier, liveTestGate, liveTestGateMode, liveTestRunnerCtx }); // Resolve the late-bound topic-operator getter (increment 2e): routing was
29592
29629
  const readIdentityProjectionPeerRows = async () => {
29593
29630
  const peers = _resolvePeerUrls?.() ?? [];
29594
29631
  const extra = config.multiMachine?.peerUrlAllowlist;
@@ -30547,6 +30584,9 @@ export async function startServer(options) {
30547
30584
  // no per-session write admission.
30548
30585
  sessionManager.startMonitoring();
30549
30586
  await server.start();
30587
+ // After listen: a stop's condition usually turns met across a restart onto the
30588
+ // fixed version, and the wake brief sends a session straight to a route.
30589
+ agentStopSurfacer?.start();
30550
30590
  // #1425 regression containment: only begin the cooperative witness-index +
30551
30591
  // parity scans AFTER the HTTP server is listening. Until publication the
30552
30592
  // reader serves the legacy witness path, never a partial candidate index.