instar 1.3.371 → 1.3.373

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.
@@ -542,6 +542,122 @@ if [[ "$STATE_SESSION" != "$HOOK_SESSION" ]]; then
542
542
  record_session_id "$HOOK_SESSION"
543
543
  fi
544
544
 
545
+ # ── IDLE_BACKOFF — consecutive quick stops back off before re-injecting the frame ──
546
+ # Every block-decision below re-feeds the FULL frame + context to the model. When the
547
+ # session is idle/holding (nothing actionable), stops arrive back-to-back (~4s apart)
548
+ # and the loop re-injects thousands of tokens ~15×/min, all night — the 2026-06-06
549
+ # rapid-idle-refire waste. Backoff: measure the agent's ACTIVE time since the last
550
+ # re-injection (gap = stop arrival − last resume; slept time never counts toward the
551
+ # gap, so a long sleep can't masquerade as productive work). gap < QUICK_SECS ⇒ an
552
+ # idle cycle ⇒ the consecutive counter rises ⇒ tiered sleep (3+ quick stops → T1 30s,
553
+ # 6+ → T2 120s, 10+ → T3 300s) BEFORE the next re-injection. Any real work makes the
554
+ # gap long and resets the counter to zero — productive loops never wait at all.
555
+ # RESPONSIVENESS: the sleep polls every POLL_SECS and breaks EARLY on (a) a new
556
+ # inbound message for this topic, (b) the emergency-stop flag, (c) the state file
557
+ # vanishing (stop/stop-all) — a user message cuts the wait to ≤POLL_SECS.
558
+ # SAFETY (fail-toward-noise, never toward strand): the total sleep self-clamps to a
559
+ # third of THIS hook's own registered Stop timeout, read live from settings.json —
560
+ # a host-killed Stop hook fails OPEN and strands the loop, which is categorically
561
+ # worse than refire noise. Unreadable/missing timeout ⇒ conservative 20s cap; codex
562
+ # registrations (.codex/hooks.json, different timeout semantics) ⇒ same 20s cap.
563
+ BACKOFF_STATE="${STATE_FILE%.md}.backoff.json"
564
+ BACKOFF_SLEPT=0
565
+ if [[ "${INSTAR_HOOK_BACKOFF_DISABLE:-0}" != "1" ]]; then
566
+ BK_QUICK_SECS="${INSTAR_HOOK_BACKOFF_QUICK_SECS:-120}"
567
+ BK_T1="${INSTAR_HOOK_BACKOFF_T1:-30}"
568
+ BK_T2="${INSTAR_HOOK_BACKOFF_T2:-120}"
569
+ BK_T3="${INSTAR_HOOK_BACKOFF_T3:-300}"
570
+ BK_POLL="${INSTAR_HOOK_BACKOFF_POLL_SECS:-5}"
571
+
572
+ # Self-clamp: never sleep past a third of the registered hook timeout.
573
+ BK_MAX="${INSTAR_HOOK_BACKOFF_MAX_SLEEP:-}"
574
+ if [[ -z "$BK_MAX" ]]; then
575
+ if [[ "$IS_CODEX" == "1" ]]; then
576
+ BK_MAX=20
577
+ else
578
+ BK_REG_TIMEOUT=$(python3 -c "
579
+ import json
580
+ try:
581
+ s = json.load(open('.claude/settings.json'))
582
+ for grp in (s.get('hooks', {}).get('Stop') or []):
583
+ for h in (grp.get('hooks') or []):
584
+ if 'autonomous-stop-hook.sh' in (h.get('command') or ''):
585
+ t = h.get('timeout')
586
+ print(int(t) if isinstance(t, (int, float)) and t > 0 else '')
587
+ raise SystemExit
588
+ except SystemExit:
589
+ pass
590
+ except Exception:
591
+ pass
592
+ " 2>/dev/null || echo "")
593
+ if [[ "$BK_REG_TIMEOUT" =~ ^[0-9]+$ ]] && [[ $BK_REG_TIMEOUT -ge 60 ]]; then
594
+ BK_MAX=$(( BK_REG_TIMEOUT / 3 ))
595
+ else
596
+ BK_MAX=20
597
+ fi
598
+ fi
599
+ fi
600
+
601
+ # Read sidecar (per-topic). A new run (different started_at) resets the counter.
602
+ BK_PREV_RESUMED=$(jq -r '.lastResumedAt // 0' "$BACKOFF_STATE" 2>/dev/null || echo 0)
603
+ BK_PREV_QUICK=$(jq -r '.quickStops // 0' "$BACKOFF_STATE" 2>/dev/null || echo 0)
604
+ BK_PREV_RUN=$(jq -r '.runStartedAt // ""' "$BACKOFF_STATE" 2>/dev/null || echo "")
605
+ [[ "$BK_PREV_RESUMED" =~ ^[0-9]+$ ]] || BK_PREV_RESUMED=0
606
+ [[ "$BK_PREV_QUICK" =~ ^[0-9]+$ ]] || BK_PREV_QUICK=0
607
+ if [[ "$BK_PREV_RUN" != "$STARTED_AT" ]]; then
608
+ BK_PREV_RESUMED=0; BK_PREV_QUICK=0
609
+ fi
610
+
611
+ BK_NOW=$(date +%s)
612
+ BK_GAP=-1
613
+ BK_QUICK=0
614
+ if [[ $BK_PREV_RESUMED -gt 0 ]]; then
615
+ BK_GAP=$(( BK_NOW - BK_PREV_RESUMED ))
616
+ if [[ $BK_GAP -lt $BK_QUICK_SECS ]]; then
617
+ BK_QUICK=$(( BK_PREV_QUICK + 1 ))
618
+ fi
619
+ fi
620
+
621
+ BK_SLEEP=0
622
+ if [[ $BK_QUICK -ge 10 ]]; then BK_SLEEP=$BK_T3
623
+ elif [[ $BK_QUICK -ge 6 ]]; then BK_SLEEP=$BK_T2
624
+ elif [[ $BK_QUICK -ge 3 ]]; then BK_SLEEP=$BK_T1
625
+ fi
626
+ [[ $BK_SLEEP -gt $BK_MAX ]] && BK_SLEEP=$BK_MAX
627
+
628
+ if [[ $BK_SLEEP -gt 0 ]]; then
629
+ bk_inbound_latest() { ls -t .instar/telegram-inbound/msg-"${REPORT_TOPIC:-none}"-* 2>/dev/null | head -1; }
630
+ BK_MARK_IN=$(bk_inbound_latest)
631
+ while [[ $BACKOFF_SLEPT -lt $BK_SLEEP ]]; do
632
+ BK_CHUNK=$(( BK_SLEEP - BACKOFF_SLEPT ))
633
+ [[ $BK_CHUNK -gt $BK_POLL ]] && BK_CHUNK=$BK_POLL
634
+ sleep "$BK_CHUNK"
635
+ BACKOFF_SLEPT=$(( BACKOFF_SLEPT + BK_CHUNK ))
636
+ [[ -f ".instar/autonomous-emergency-stop" ]] && break
637
+ [[ ! -f "$STATE_FILE" ]] && break
638
+ [[ "$(bk_inbound_latest)" != "$BK_MARK_IN" ]] && break
639
+ done
640
+ echo "[autonomous] idle backoff: quickStops=$BK_QUICK gap=${BK_GAP}s slept=${BACKOFF_SLEPT}s (cap=${BK_MAX}s)" >&2
641
+
642
+ # Re-check terminal conditions that may have arrived during the sleep.
643
+ if [[ ! -f "$STATE_FILE" ]]; then
644
+ rm -f "$BACKOFF_STATE" 2>/dev/null || true
645
+ echo "[autonomous] state file removed during idle backoff — allowing exit" >&2
646
+ exit 0
647
+ fi
648
+ if [[ -f ".instar/autonomous-emergency-stop" ]]; then
649
+ emit "🛑 Autonomous mode: Emergency stop detected (during idle backoff)."
650
+ notify_terminal_stop "🛑 My autonomous run on \"$(goal_snippet)\" was stopped (emergency stop)."
651
+ rm -f "$STATE_FILE" "$BACKOFF_STATE" 2>/dev/null || true
652
+ exit 0
653
+ fi
654
+ fi
655
+
656
+ BK_RESUMED=$(date +%s)
657
+ printf '{"runStartedAt":"%s","lastResumedAt":%s,"quickStops":%s,"lastSleepSecs":%s}\n' \
658
+ "$STARTED_AT" "$BK_RESUMED" "$BK_QUICK" "$BACKOFF_SLEPT" > "$BACKOFF_STATE" 2>/dev/null || true
659
+ fi
660
+
545
661
  # ── Continue the job: increment iteration, feed the task back. ────────
546
662
  NEXT_ITERATION=$((ITERATION + 1))
547
663
 
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA6SH,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAuxDD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA4iTtE;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDzE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuD5E"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA6SH,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAuxDD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAwpTtE;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDzE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuD5E"}
@@ -2367,6 +2367,13 @@ export async function startServer(options) {
2367
2367
  // same explicit replication gate; undefined = dark (verb answers
2368
2368
  // 'disabled', merge layer returns own rows only).
2369
2369
  let commitmentReplicaStore;
2370
+ // P1.5b owner-routed mutation (§3.4): the owner-side replay window, the
2371
+ // forwarder-side durable intent queue, and the route-facing forward fn.
2372
+ // All undefined while dark.
2373
+ let commitmentOpKeyWindow;
2374
+ let pendingMutationLedger;
2375
+ let _commitmentReFire;
2376
+ let forwardCommitmentMutate;
2370
2377
  {
2371
2378
  const cjCfg = config.multiMachine?.coherenceJournal;
2372
2379
  const cjEnabled = cjCfg?.enabled ?? !!config.developmentAgent;
@@ -9957,6 +9964,23 @@ export async function startServer(options) {
9957
9964
  return { ok: false, reason: 'working-set disabled' };
9958
9965
  return workingSetPullServer.handle(cmd);
9959
9966
  },
9967
+ // COMMITMENTS-COHERENCE-SPEC §3.4 — owner-side apply for the
9968
+ // owner-routed mutation. opKey window first (replay returns the
9969
+ // recorded verdict, applies nothing); the UNCHANGED state machine
9970
+ // re-validates; the opKey records AFTER the store write (§4.5 —
9971
+ // a crash between resolves as idempotent-noop on the re-fire).
9972
+ 'commitment-mutate': async (cmd) => {
9973
+ const c = cmd;
9974
+ if (!commitmentOpKeyWindow || !commitmentTracker)
9975
+ return { ok: false, reason: 'commitment-mutate disabled' };
9976
+ const mutMod = await import('../core/CommitmentMutation.js');
9977
+ const replay = commitmentOpKeyWindow.check(c.payload.opKey);
9978
+ if (replay)
9979
+ return { verdict: replay.verdict, ...(replay.status ? { status: replay.status } : {}), replayed: true };
9980
+ const outcome = await mutMod.applyOwnerMutation(commitmentTracker, c.payload);
9981
+ commitmentOpKeyWindow.record(c.payload.opKey, outcome);
9982
+ return outcome;
9983
+ },
9960
9984
  // COMMITMENTS-COHERENCE-SPEC §3.2 — serve OWN commitment records
9961
9985
  // as seq-windowed delta pages. Registered always (lockstep with
9962
9986
  // the union+RBAC edits); answers 'disabled' until the replication
@@ -10243,7 +10267,81 @@ export async function startServer(options) {
10243
10267
  stateDir: config.stateDir,
10244
10268
  logger: (m) => console.log(pc.dim(` [commitments-sync] ${m}`)),
10245
10269
  });
10246
- console.log(pc.dim(' [commitments-sync] replica store wired (serve + receive + advert)'));
10270
+ // P1.5b: opKey window + pending-mutation ledger + forward fn.
10271
+ const mutMod = await import('../core/CommitmentMutation.js');
10272
+ const csCfg2 = config.multiMachine?.coherenceJournal?.commitments;
10273
+ commitmentOpKeyWindow = new mutMod.OpKeyWindow({
10274
+ stateDir: config.stateDir,
10275
+ ttlDays: csCfg2?.opKeyTtlDays,
10276
+ });
10277
+ pendingMutationLedger = new mutMod.PendingMutationLedger({
10278
+ stateDir: config.stateDir,
10279
+ ttlDays: csCfg2?.pendingMutationTtlDays,
10280
+ maxPerCommitment: csCfg2?.maxPendingOpsPerCommitment,
10281
+ maxPerOwner: csCfg2?.maxPendingOpsPerOwner,
10282
+ onExpired: (rec) => {
10283
+ void telegram?.createAttentionItem({
10284
+ id: `CMT-MUT-EXPIRED-${rec.payload.opKey}`,
10285
+ title: `A queued commitment ${rec.payload.op} was never applied`,
10286
+ summary: `The ${rec.payload.op} for ${rec.payload.origin}::${rec.payload.id} stayed queued for the full retention window (${rec.attempts} attempts) — its home machine never returned. Re-issue it once that machine is back.`,
10287
+ category: 'agent-health',
10288
+ priority: 'NORMAL',
10289
+ lane: 'agent-health',
10290
+ sourceContext: 'commitments-coherence',
10291
+ }).catch(() => { });
10292
+ },
10293
+ logger: (m) => console.log(pc.dim(` [commitment-mutate] ${m}`)),
10294
+ });
10295
+ const sendMutate = async (ownerMachineId, payload) => {
10296
+ const url = peerUrl(ownerMachineId);
10297
+ const queue = async (reason) => {
10298
+ await pendingMutationLedger.enqueue(payload);
10299
+ return { kind: 'queued', reason };
10300
+ };
10301
+ if (!url)
10302
+ return queue('owner unreachable (no known URL)');
10303
+ try {
10304
+ const res = await meshClient.send({ machineId: ownerMachineId, url }, { type: 'commitment-mutate', payload }, 0);
10305
+ if (res.ok && res.result && typeof res.result === 'object' && 'verdict' in res.result) {
10306
+ await pendingMutationLedger.clear(payload.opKey);
10307
+ return { kind: 'verdict', outcome: res.result };
10308
+ }
10309
+ if (!res.ok && (res.status === 501 || res.status === 403)) {
10310
+ // Mutating-verb mixed-version honesty (§3.4): an old
10311
+ // owner queues durably + the caller answers honestly.
10312
+ return queue(`owner runs an older version (HTTP ${res.status}) — applies after it updates`);
10313
+ }
10314
+ return queue(`owner answered unexpectedly (HTTP ${res.status})`);
10315
+ }
10316
+ catch (e) {
10317
+ // Timeout/transport = AMBIGUOUS (B24): queue with the SAME
10318
+ // opKey — if the owner did apply, the re-fire returns the
10319
+ // recorded verdict (idempotent-noop), never a double-apply.
10320
+ return queue(`owner unreachable (${e instanceof Error ? e.message : String(e)}) — queued, confirming on its return`);
10321
+ }
10322
+ };
10323
+ forwardCommitmentMutate = sendMutate;
10324
+ // Re-fire on the owner's return: ride the SAME presence seam
10325
+ // the working-set drain uses; sequential, fresh envelopes.
10326
+ const reFireForOwner = async (ownerMachineId) => {
10327
+ if (!pendingMutationLedger)
10328
+ return;
10329
+ const pending = await pendingMutationLedger.pendingForOwner(ownerMachineId);
10330
+ for (const rec of pending) {
10331
+ const r = await sendMutate(ownerMachineId, rec.payload);
10332
+ if (r.kind === 'verdict')
10333
+ continue; // cleared inside sendMutate
10334
+ await pendingMutationLedger.recordAttempt(rec.payload.opKey);
10335
+ }
10336
+ };
10337
+ _commitmentReFire = reFireForOwner;
10338
+ // TTL sweep rides the working-set 10-min timer cadence.
10339
+ const cmtSweepTimer = setInterval(() => {
10340
+ void pendingMutationLedger?.sweepExpired().catch(() => { });
10341
+ }, 600_000);
10342
+ if (typeof cmtSweepTimer.unref === 'function')
10343
+ cmtSweepTimer.unref();
10344
+ console.log(pc.dim(' [commitments-sync] replica store wired (serve + receive + advert + owner-routed mutation)'));
10247
10345
  }
10248
10346
  catch (e) { /* @silent-fallback-ok: commitments-sync construction failure degrades to local-only commitments — never blocks boot (COMMITMENTS-COHERENCE-SPEC §4) */
10249
10347
  commitmentReplicaStore = undefined;
@@ -10489,6 +10587,13 @@ export async function startServer(options) {
10489
10587
  return undefined;
10490
10588
  return nested[machineId] ?? Object.values(nested)[0];
10491
10589
  };
10590
+ // Returning-peer hook (one compact dep keeps the wiring-test window
10591
+ // intact): working-set pending-pull drain (§3.4) + queued
10592
+ // commitment-mutate re-fire (P1.5b §3.4). Both no-op while dark.
10593
+ const onPeerBack = (machineId) => {
10594
+ workingSetPullCoordinator?.onPeerRecorded(machineId);
10595
+ void _commitmentReFire?.(machineId).catch(() => { });
10596
+ };
10492
10597
  const peerPresencePuller = new presenceMod.PeerPresencePuller({
10493
10598
  selfMachineId: meshSelfId,
10494
10599
  listPeers: () => meshIdMgr
@@ -10497,7 +10602,7 @@ export async function startServer(options) {
10497
10602
  .map((m) => ({ machineId: m.machineId, url: peerUrl(m.machineId) })),
10498
10603
  recordHeartbeat: (obs) => { machinePoolRegistry?.recordHeartbeat(obs); },
10499
10604
  log: (line) => console.log(pc.dim(` [peer-presence] ${line}`)),
10500
- onPeerRecorded: (machineId) => workingSetPullCoordinator?.onPeerRecorded(machineId), // working-set re-arm (§3.4); no-op when dark
10605
+ onPeerRecorded: (m) => onPeerBack(m), // ws re-arm + queued-commitment re-fire; no-op when dark
10501
10606
  fetchPeerCapacity: async (machineId, url) => {
10502
10607
  const res = await meshClient.send({ machineId, url }, { type: 'session-status' }, 0);
10503
10608
  if (res.ok && res.result && typeof res.result === 'object') {
@@ -10791,7 +10896,7 @@ export async function startServer(options) {
10791
10896
  catch (err) {
10792
10897
  console.log(pc.dim(` [session-pool] rollout gate not wired: ${err instanceof Error ? err.message : String(err)}`));
10793
10898
  }
10794
- const server = new AgentServer({ config, sessionManager, state, scheduler, telegram, relationships, feedback, feedbackAnomalyDetector, dispatches, updateChecker, autoUpdater, autoDispatcher, quotaTracker, quotaManager, publisher, viewer, tunnel, evolution, watchdog, topicMemory, triageNurse, projectMapper, coherenceGate: scopeVerifier, contextHierarchy, canonicalState, operationGate, sentinel, adaptiveTrust, memoryMonitor, orphanReaper, coherenceMonitor, commitmentTracker, semanticMemory, activitySentinel, rateLimitSentinel, releaseReadinessSentinel: releaseReadinessSentinel ?? undefined, messageRouter, summarySentinel, spawnManager, systemReviewer, capabilityMapper, selfKnowledgeTree, coverageAuditor, topicResumeMap: _topicResumeMap ?? undefined, sessionRefresh: _sessionRefresh ?? undefined, autonomyManager, trustElevationTracker, autonomousEvolution, coordinator: coordinator.enabled ? coordinator : undefined, localSigningKeyPem, leaseTransport, 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, whatsappBusinessBackend, messageBridge, hookEventReceiver, worktreeMonitor, subagentTracker, instructionsVerifier, handshakeManager: threadlineHandshake, threadlineRouter, conversationStore, warrantsReplyGate, collaborationSurfacer, threadResumeMap, topicLinkageHandler: topicLinkageHandler ?? undefined, threadlineRelayClient, threadlineReplyWaiters, listenerManager: listenerManager ?? undefined, responseReviewGate, messagingToneGate, outboundDedupGate, telemetryHeartbeat, pasteManager, featureRegistry, discoveryEvaluator, completionEvaluator, unifiedTrust, liveConfig, sharedStateLedger, ledgerSessionRegistry, worktreeManager, oidcEnrolledRepos: parallelDevConfig?.oidcEnrolledRepos, initiativeTracker, projectRoundRunner, projectDriftChecker, machineHeartbeat, machinePoolRegistry, meshRpcDispatcher, workingSetPullCoordinator, commitmentReplicaStore, sessionOwnershipRegistry, topicPinStore: _topicPinStore ?? undefined, secretSync: _secretSyncHandle ?? undefined, meshSelfId: _meshSelfId ?? undefined, resolveRouterUrl: _resolveRouterUrl ?? undefined, resolvePeerUrls: _resolvePeerUrls ?? undefined, sessionPoolE2EResultStore, proxyCoordinator, topicIntentStore, topicIntentArcCheck, usherSignalStore, intelligence: sharedIntelligence ?? undefined, telegramBridgeConfig, telegramBridge: telegramBridge ?? undefined, threadlineObservability, briefDeps, workingMemory, taskFlowRegistry, threadlineFlowBridge, sessionReaper, agentWorktreeReaper, mcpProcessReaper, geminiLoopRunner, sleepController, agentActivityState, reapLog, sleepWakeDetector, unjustifiedStopGate, stopGateDb, stopNotifier });
10899
+ const server = new AgentServer({ config, sessionManager, state, scheduler, telegram, relationships, feedback, feedbackAnomalyDetector, dispatches, updateChecker, autoUpdater, autoDispatcher, quotaTracker, quotaManager, publisher, viewer, tunnel, evolution, watchdog, topicMemory, triageNurse, projectMapper, coherenceGate: scopeVerifier, contextHierarchy, canonicalState, operationGate, sentinel, adaptiveTrust, memoryMonitor, orphanReaper, coherenceMonitor, commitmentTracker, semanticMemory, activitySentinel, rateLimitSentinel, releaseReadinessSentinel: releaseReadinessSentinel ?? undefined, messageRouter, summarySentinel, spawnManager, systemReviewer, capabilityMapper, selfKnowledgeTree, coverageAuditor, topicResumeMap: _topicResumeMap ?? undefined, sessionRefresh: _sessionRefresh ?? undefined, autonomyManager, trustElevationTracker, autonomousEvolution, coordinator: coordinator.enabled ? coordinator : undefined, localSigningKeyPem, leaseTransport, 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, whatsappBusinessBackend, messageBridge, hookEventReceiver, worktreeMonitor, subagentTracker, instructionsVerifier, handshakeManager: threadlineHandshake, threadlineRouter, conversationStore, warrantsReplyGate, collaborationSurfacer, threadResumeMap, topicLinkageHandler: topicLinkageHandler ?? undefined, threadlineRelayClient, threadlineReplyWaiters, listenerManager: listenerManager ?? undefined, responseReviewGate, messagingToneGate, outboundDedupGate, telemetryHeartbeat, pasteManager, featureRegistry, discoveryEvaluator, completionEvaluator, unifiedTrust, liveConfig, sharedStateLedger, ledgerSessionRegistry, worktreeManager, oidcEnrolledRepos: parallelDevConfig?.oidcEnrolledRepos, initiativeTracker, projectRoundRunner, projectDriftChecker, machineHeartbeat, machinePoolRegistry, meshRpcDispatcher, workingSetPullCoordinator, commitmentReplicaStore, forwardCommitmentMutate, sessionOwnershipRegistry, topicPinStore: _topicPinStore ?? undefined, secretSync: _secretSyncHandle ?? undefined, meshSelfId: _meshSelfId ?? undefined, resolveRouterUrl: _resolveRouterUrl ?? undefined, resolvePeerUrls: _resolvePeerUrls ?? undefined, sessionPoolE2EResultStore, proxyCoordinator, topicIntentStore, topicIntentArcCheck, usherSignalStore, intelligence: sharedIntelligence ?? undefined, telegramBridgeConfig, telegramBridge: telegramBridge ?? undefined, threadlineObservability, briefDeps, workingMemory, taskFlowRegistry, threadlineFlowBridge, sessionReaper, agentWorktreeReaper, mcpProcessReaper, geminiLoopRunner, sleepController, agentActivityState, reapLog, sleepWakeDetector, unjustifiedStopGate, stopGateDb, stopNotifier });
10795
10900
  // Boot-recovery (tunnel-failure-resilience spec Part 6): if the agent
10796
10901
  // died mid-relay-episode, the persisted tunnel.json carries
10797
10902
  // rotationPending=true. Rotate the dashboard PIN + authToken BEFORE