instar 1.3.911 → 1.3.913

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 (54) hide show
  1. package/README.md +1 -1
  2. package/dist/commands/server.d.ts.map +1 -1
  3. package/dist/commands/server.js +79 -2
  4. package/dist/commands/server.js.map +1 -1
  5. package/dist/config/ConfigDefaults.d.ts.map +1 -1
  6. package/dist/config/ConfigDefaults.js +7 -0
  7. package/dist/config/ConfigDefaults.js.map +1 -1
  8. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  9. package/dist/core/PostUpdateMigrator.js +11 -0
  10. package/dist/core/PostUpdateMigrator.js.map +1 -1
  11. package/dist/core/WriteDomainRegistry.d.ts.map +1 -1
  12. package/dist/core/WriteDomainRegistry.js +9 -0
  13. package/dist/core/WriteDomainRegistry.js.map +1 -1
  14. package/dist/core/machineCoherenceManifest.d.ts.map +1 -1
  15. package/dist/core/machineCoherenceManifest.js +15 -0
  16. package/dist/core/machineCoherenceManifest.js.map +1 -1
  17. package/dist/core/sessionPoolPromotionActivation.d.ts +42 -0
  18. package/dist/core/sessionPoolPromotionActivation.d.ts.map +1 -0
  19. package/dist/core/sessionPoolPromotionActivation.js +61 -0
  20. package/dist/core/sessionPoolPromotionActivation.js.map +1 -0
  21. package/dist/core/types.d.ts +10 -0
  22. package/dist/core/types.d.ts.map +1 -1
  23. package/dist/core/types.js.map +1 -1
  24. package/dist/monitoring/PresenceProxy.d.ts +4 -0
  25. package/dist/monitoring/PresenceProxy.d.ts.map +1 -1
  26. package/dist/monitoring/PresenceProxy.js +43 -3
  27. package/dist/monitoring/PresenceProxy.js.map +1 -1
  28. package/dist/monitoring/SessionRecovery.d.ts +17 -1
  29. package/dist/monitoring/SessionRecovery.d.ts.map +1 -1
  30. package/dist/monitoring/SessionRecovery.js +103 -16
  31. package/dist/monitoring/SessionRecovery.js.map +1 -1
  32. package/dist/monitoring/guardManifest.d.ts.map +1 -1
  33. package/dist/monitoring/guardManifest.js +1 -0
  34. package/dist/monitoring/guardManifest.js.map +1 -1
  35. package/dist/scaffold/templates.d.ts.map +1 -1
  36. package/dist/scaffold/templates.js +1 -0
  37. package/dist/scaffold/templates.js.map +1 -1
  38. package/dist/server/AgentServer.d.ts +2 -0
  39. package/dist/server/AgentServer.d.ts.map +1 -1
  40. package/dist/server/AgentServer.js +1 -0
  41. package/dist/server/AgentServer.js.map +1 -1
  42. package/dist/server/CapabilityIndex.js +1 -1
  43. package/dist/server/CapabilityIndex.js.map +1 -1
  44. package/dist/server/routes.d.ts +2 -0
  45. package/dist/server/routes.d.ts.map +1 -1
  46. package/dist/server/routes.js +28 -0
  47. package/dist/server/routes.js.map +1 -1
  48. package/package.json +1 -1
  49. package/src/data/builtin-manifest.json +64 -64
  50. package/src/scaffold/templates.ts +1 -0
  51. package/upgrades/1.3.912.md +33 -0
  52. package/upgrades/1.3.913.md +30 -0
  53. package/upgrades/side-effects/context-wall-recovery-robustness.md +62 -0
  54. package/upgrades/side-effects/session-pool-promotion-activation.md +52 -0
package/README.md CHANGED
@@ -141,7 +141,7 @@ We didn't just claim it works. We ran controlled experiments — same model, sam
141
141
  | **Coherence Gate** | LLM-powered response review. PEL + gate reviewer + 9 specialist reviewers catch quality issues before delivery | [→](https://instar.sh/features/coherence-gate/) |
142
142
  | **Intent Alignment** | Decision journaling, drift detection, organizational constraints | [→](https://instar.sh/features/intent/) |
143
143
  | **EXO 3.0 Alignment** | MTP protocol refusal/endorsement tests (`IntentTestHarness`, `OrgIntentIdentityLayer`), agent-readiness scoring (`AgentReadinessScorer`), agent digital passports (`AgentPassport`), learning-velocity metrics (`LearningVelocityScorer`) | [→](https://instar.sh/features/exo3/) |
144
- | **Multi-Machine** | Ed25519/X25519 crypto identity, encrypted sync, automatic failover | [→](https://instar.sh/features/multi-machine/) |
144
+ | **Multi-Machine** | Ed25519/X25519 crypto identity, encrypted sync, automatic failover, and evidence-gated session-pool promotion (`POST /session-pool/promote`) | [→](https://instar.sh/features/multi-machine/) |
145
145
  | **Serendipity Protocol** | Sub-agents capture out-of-scope discoveries without breaking focus. HMAC-signed, secret-scanned | [→](https://instar.sh/features/serendipity/) |
146
146
  | **Threadline Protocol** | Agent-to-agent conversations with canonical identity, three-layer trust model, authorization policy, Ed25519 invitations, Sybil protection, MoltBridge network discovery, rich agent profiles (auto-compiled from agent data with human review gate), discovery waterfall, message security, tamper-proof audit logging, framework-agnostic interop, persistent listener daemon (always-on relay connection, pipe-mode sessions, sub-30s cross-machine failover), eleven MCP tools (seven core + four registry-conditional). 80 modules, roughly 3,800 test cases across 74 dedicated test files plus 125 cross-cutting | [→](https://instar.sh/features/threadline/) |
147
147
  | **A2A Delivery Health** | Durable agent-to-agent delivery tracking (`threadline/A2ADeliveryTracker`) so a message between agents never silently dies out — a reply on the thread is the acknowledgement, and `GET /threadline/peers/health` answers "is my channel to this peer alive?" as a lookup, not a guess. The `monitoring/A2ARedeliverySentinel` adds active recovery: re-send unacknowledged messages with backoff, then one aggregated escalation per dark peer. Recording-only; never gates a send | [→](https://instar.sh/features/a2a-delivery-health/) |
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA2EH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAU3D,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AA0BjG,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AA8H7D,OAAO,KAAK,EAAW,oBAAoB,EAAe,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACjG,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAgFtD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC1C,OAAO,CAUT;AAyID,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA4qDD;;;;;;;;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,CAwtBN;AAgmBD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAgupBtE;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;AA4EH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAU3D,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AA0BjG,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AA8H7D,OAAO,KAAK,EAAW,oBAAoB,EAAe,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACjG,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAgFtD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC1C,OAAO,CAUT;AAyID,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA+rDD;;;;;;;;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,CAwtBN;AAgmBD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAuypBtE;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"}
@@ -45,6 +45,7 @@ import { configureHostSpawnSemaphore } from '../core/hostSpawnSemaphore.js';
45
45
  import { SpawningTopicsRegistry } from '../core/SpawningTopicsRegistry.js';
46
46
  import { planCredentialIdentityRepair } from '../core/CredentialIdentityRepairPlan.js';
47
47
  import { TopicReachabilityVerifier } from '../monitoring/TopicReachabilityVerifier.js';
48
+ import { probeTranscript } from '../monitoring/transcriptProber.js';
48
49
  import { SingleInstanceLock, installReleaseHandlers } from '../core/SingleInstanceLock.js';
49
50
  import { resolveDevAgentGate, resolveStateSyncStores } from '../core/devAgentGate.js';
50
51
  import { resolveAntiThrashKnobs, readingValidity } from '../core/SwapAntiThrash.js';
@@ -485,6 +486,10 @@ let _spawningTopicsRegistryRef = null;
485
486
  // Module-level reference for session resume mapping.
486
487
  // Set once in startServer() and used by spawnSessionForTopic/respawnSessionForTopic.
487
488
  let _topicResumeMap = null;
489
+ // Context-wall recovery latch. These late-bound seams let every Telegram/Slack
490
+ // spawn chokepoint fail fresh while SessionRecovery owns a durable latch.
491
+ let _contextExhaustionFreshRequired = null;
492
+ let _clearContextExhaustionFreshRequired = null;
488
493
  // ── Multi-Machine Session Pool (§L4) activation refs ──────────────────────
489
494
  // The SessionRouter is constructed in startServer()'s mesh block, but the inbound
490
495
  // dispatch handler that consults it is defined ABOVE startServer — so the router is
@@ -523,6 +528,9 @@ let _missingLoginSession = null;
523
528
  // runner is dark (dev-gated) — the route 503s. Constructed inside the rollout-gate
524
529
  // boot block next to the E2E result store + StageAdvancer.
525
530
  let _sessionPoolFailoverRunnerDriver = null;
531
+ // Promotion activation is separate from the always-live demotion reconciler.
532
+ // Null while promotionModel is off; backs the manual route and auto-climb tick.
533
+ let _sessionPoolPromotionActivation = null;
526
534
  // The store the unconditional boot sweep opened when the queue will run this
527
535
  // boot — adopted by the engine construction (one open handle, single-writer).
528
536
  let _sweptInboundStore = null;
@@ -1095,6 +1103,11 @@ spawnOpts) {
1095
1103
  // TopicResumeMap is authoritative — it saved the UUID for this specific topic at kill time
1096
1104
  // or via the refresh heartbeat. Skip LLM validation (which was failing due to JSONL sampling
1097
1105
  // issues and is redundant for an authoritative source).
1106
+ const contextWallForcesFresh = _contextExhaustionFreshRequired?.(topicId) === true;
1107
+ if (contextWallForcesFresh) {
1108
+ _topicResumeMap?.remove(topicId);
1109
+ console.log(`[spawnSessionForTopic] Context-exhaustion latch active for topic ${topicId} — forcing fresh spawn`);
1110
+ }
1098
1111
  let resumeSessionId = _topicResumeMap?.get(topicId) ?? undefined;
1099
1112
  if (resumeSessionId) {
1100
1113
  console.log(`[spawnSessionForTopic] Found resume UUID for topic ${topicId}: ${resumeSessionId} (source: TopicResumeMap — trusted)`);
@@ -1216,6 +1229,9 @@ spawnOpts) {
1216
1229
  }
1217
1230
  }, 8000);
1218
1231
  }
1232
+ if (contextWallForcesFresh) {
1233
+ _clearContextExhaustionFreshRequired?.(topicId);
1234
+ }
1219
1235
  return newSessionName;
1220
1236
  }
1221
1237
  /**
@@ -7823,7 +7839,15 @@ export async function startServer(options) {
7823
7839
  }
7824
7840
  // Check resume map for session continuity (keyed on routing key, so a
7825
7841
  // thread resumes its OWN session and not the channel-root one).
7826
- const resumeInfo = slackAdapter.getChannelResume(routingKey);
7842
+ const contextWallForcesFresh = conversationId !== null
7843
+ && _contextExhaustionFreshRequired?.(conversationId) === true;
7844
+ if (contextWallForcesFresh) {
7845
+ slackAdapter.removeChannelResume(routingKey);
7846
+ console.log(`[slack→session] Context-exhaustion latch active for conversation ${conversationId} — forcing fresh spawn`);
7847
+ }
7848
+ const resumeInfo = contextWallForcesFresh
7849
+ ? null
7850
+ : slackAdapter.getChannelResume(routingKey);
7827
7851
  const resumeSessionId = resumeInfo?.uuid ?? undefined;
7828
7852
  if (resumeInfo) {
7829
7853
  slackAdapter.removeChannelResume(routingKey);
@@ -7910,6 +7934,9 @@ export async function startServer(options) {
7910
7934
  slackAdapter.registerChannelSession(routingKey, newSessionName, isThreadSession ? `${channelId} (thread ${replyThreadTs})` : undefined);
7911
7935
  slackAdapter.trackMessageInjection(channelId, newSessionName, message.content);
7912
7936
  console.log(`[slack→session] ${resumeSessionId ? 'Resumed' : 'Spawned'} "${newSessionName}" for ${isThreadSession ? `thread ${routingKey}` : `channel ${channelId}`}`);
7937
+ if (contextWallForcesFresh && conversationId !== null) {
7938
+ _clearContextExhaustionFreshRequired?.(conversationId);
7939
+ }
7913
7940
  }
7914
7941
  }
7915
7942
  catch (err) {
@@ -10301,6 +10328,18 @@ export async function startServer(options) {
10301
10328
  },
10302
10329
  // P1/P2 cross-check dep — see SessionRecovery.killForRecovery().
10303
10330
  hasActiveProcesses: (name) => sessionManager.hasActiveProcesses(name),
10331
+ probeTranscript: (name) => {
10332
+ const session = sessionManager.listRunningSessions()
10333
+ .find((candidate) => candidate.tmuxSession === name);
10334
+ if (!session?.claudeSessionId) {
10335
+ return { resolved: false, path: '', size: 0, mtime: 0 };
10336
+ }
10337
+ return probeTranscript({
10338
+ framework: session.framework ?? 'claude-code',
10339
+ sessionId: session.claudeSessionId,
10340
+ projectDir: session.cwd ?? config.sessions.projectDir,
10341
+ });
10342
+ },
10304
10343
  respawnSession: async (topicId, _sessionName, recoveryPrompt) => {
10305
10344
  // Check Slack first (synthetic IDs are negative)
10306
10345
  const slackChId = slackProxyChannelMap.get(topicId);
@@ -10568,6 +10607,10 @@ export async function startServer(options) {
10568
10607
  // Clean up after 60 seconds — by then the kill and respawn are done
10569
10608
  setTimeout(() => contextExhaustionKills.delete(sessionName), 60_000);
10570
10609
  });
10610
+ _contextExhaustionFreshRequired = (topicId) => sessionRecovery?.hasContextWedgedSeen(topicId) === true;
10611
+ _clearContextExhaustionFreshRequired = (topicId) => {
10612
+ sessionRecovery?.clearContextWedgedSeen(topicId);
10613
+ };
10571
10614
  console.log(pc.green(' Session Recovery enabled (mechanical fast-path)'));
10572
10615
  }
10573
10616
  // SessionMonitor — proactive session health monitoring
@@ -12976,6 +13019,9 @@ export async function startServer(options) {
12976
13019
  return { recovered: result.recovered };
12977
13020
  }
12978
13021
  : undefined,
13022
+ hasContextExhaustionLatch: sessionRecovery
13023
+ ? (topicId) => sessionRecovery.hasContextWedgedSeen(topicId)
13024
+ : undefined,
12979
13025
  // Shared per-topic mutex — coordinates with PromiseBeacon.
12980
13026
  acquireProxyMutex: (topicId, holder) => proxyCoordinator.tryAcquire(topicId, holder),
12981
13027
  releaseProxyMutex: (topicId, holder) => proxyCoordinator.release(topicId, holder),
@@ -22626,6 +22672,37 @@ export async function startServer(options) {
22626
22672
  writeStageConfig: (s) => liveConfig.set(guardMod.STAGE_CONFIG_PATH, s, { stageWriteToken: guardMod.STAGE_WRITE_TOKEN }),
22627
22673
  audit: (event, detail) => console.log(pc.dim(` [stage-advancer] ${event} ${JSON.stringify(detail)}`)),
22628
22674
  });
22675
+ // ── Promotion activation ────────────────────────────────────────────────
22676
+ // Default `off` constructs nothing and schedules nothing. Both live models
22677
+ // reuse the same driver + StageAdvancer gate. The manual route remains a
22678
+ // one-step lever in both `operator` and `auto-climb`; only auto-climb gets
22679
+ // a timer. The independent ceiling defaults to dark, so selecting a model
22680
+ // alone grants no promotion authority.
22681
+ const promotionMod = await import('../core/sessionPoolPromotionActivation.js');
22682
+ const rolloutMod = await import('../core/SessionPoolRolloutDriver.js');
22683
+ const promotionCfg = promotionMod.resolveSessionPoolPromotionConfig(config.multiMachine?.sessionPool);
22684
+ if (promotionCfg.model !== 'off') {
22685
+ const rolloutDriver = new rolloutMod.SessionPoolRolloutDriver({
22686
+ advancer: stageAdvancer,
22687
+ enabled: () => true,
22688
+ targetCeiling: () => promotionCfg.ceiling,
22689
+ audit: (event, detail) => console.log(pc.dim(` [session-pool-promotion] ${event} ${JSON.stringify(detail)}`)),
22690
+ });
22691
+ _sessionPoolPromotionActivation = new promotionMod.SessionPoolPromotionActivation(promotionCfg, rolloutDriver);
22692
+ if (promotionCfg.model === 'auto-climb') {
22693
+ const promotionTimer = setInterval(() => {
22694
+ try {
22695
+ _sessionPoolPromotionActivation?.autoTick();
22696
+ }
22697
+ catch (err) {
22698
+ console.warn('[session-pool-promotion] auto-climb tick failed; no stage was promoted:', err instanceof Error ? err.message : String(err));
22699
+ }
22700
+ }, promotionCfg.tickMs);
22701
+ if (promotionTimer.unref)
22702
+ promotionTimer.unref();
22703
+ }
22704
+ console.log(pc.green(` SessionPool promotion activation: ${promotionCfg.model} (ceiling ${promotionCfg.ceiling}; cadence ${promotionCfg.tickMs}ms)`));
22705
+ }
22629
22706
  // ── SessionPoolFailoverRunner (§Rollout, Track H) — the in-agent PRODUCER of
22630
22707
  // a real failover-E2E green so a DEPLOYED dev agent can promote its own
22631
22708
  // sessionPool stage instead of sitting at 'shadow' forever. Dev-gated dark
@@ -23125,7 +23202,7 @@ export async function startServer(options) {
23125
23202
  const server = new AgentServer({ config, sessionManager, llmQueue: sharedLlmQueue, state, scheduler, telegram, relationships, feedback, feedbackAnomalyDetector, dispatches, updateChecker, autoUpdater, autoDispatcher, quotaTracker, quotaManager, publisher, viewer, tunnel, evolution, watchdog, topicMemory, triageNurse, projectMapper, cartographer: cartographer ?? undefined, coherenceGate: scopeVerifier, contextHierarchy, canonicalState, operationGate, sentinel, adaptiveTrust, memoryMonitor, orphanReaper, coherenceMonitor, commitmentTracker, subscriptionPool, accountFollowMePeerViews: async () => { const nickById = new Map((_listPoolMachines?.() ?? []).map((m) => [m.machineId, m.nickname ?? m.machineId])); let peers = (_resolvePeerUrls?.() ?? []).map((p) => ({ machineId: p.machineId, nickname: nickById.get(p.machineId) ?? p.machineId, url: p.url })); if (peers.length === 0) {
23126
23203
  peers = (_listPoolMachines?.() ?? []).filter((m) => m.machineId !== _meshSelfId && !!m.lastKnownUrl).map((m) => ({ machineId: m.machineId, nickname: m.nickname ?? m.machineId, url: m.lastKnownUrl }));
23127
23204
  } if (peers.length === 0)
23128
- 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, 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, conversationFollowThrough, whatsappBusinessBackend, messageBridge, hookEventReceiver, worktreeMonitor, subagentTracker, instructionsVerifier, handshakeManager: threadlineHandshake, threadlineRouter, conversationStore, threadLog, threadMessageRecorder, warrantsReplyGate, collaborationSurfacer, threadResumeMap, topicLinkageHandler: topicLinkageHandler ?? undefined, threadlineRelayClient, threadlineReplyWaiters, listenerManager: listenerManager ?? undefined, a2aDeliveryTracker: a2aDeliveryTracker ?? undefined, 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, meshRpcDispatcher, deliverA2aToMachine: _deliverA2aToMachine ?? undefined, workingSetPullCoordinator, workingSetArtifactManager, orchestratorPoller, commitmentReplicaStore, preferenceReplicaStore, replicatedRecordEmitter, conflictStore, rollbackUnmerge, droppedOriginRegistry, preferencesUnionReader, forwardCommitmentMutate, sessionOwnershipRegistry, sendDrain: _sendDrain ?? undefined, 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, guardRegistry, listPoolMachines: _listPoolMachines ?? undefined, deliverMandateToMachine: _deliverMandateToMachine ?? undefined, 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, geminiLoopRunner, sleepController, agentActivityState, reapLog, resumeQueue, resumeDrainer, autonomousLivenessReconciler, enforcedTerminationStatus: () => enforcedTerminationWatchdog?.guardStatus() ?? null, prHandLease: prHandLease ?? undefined, operatorStopRecorder: recordOperatorStop, sleepWakeDetector, unjustifiedStopGate, stopGateDb, stopNotifier, liveTestGate, liveTestGateMode, liveTestRunnerCtx }); // Resolve the late-bound topic-operator getter (increment 2e): routing was
23205
+ 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, 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, conversationFollowThrough, whatsappBusinessBackend, messageBridge, hookEventReceiver, worktreeMonitor, subagentTracker, instructionsVerifier, handshakeManager: threadlineHandshake, threadlineRouter, conversationStore, threadLog, threadMessageRecorder, warrantsReplyGate, collaborationSurfacer, threadResumeMap, topicLinkageHandler: topicLinkageHandler ?? undefined, threadlineRelayClient, threadlineReplyWaiters, listenerManager: listenerManager ?? undefined, a2aDeliveryTracker: a2aDeliveryTracker ?? undefined, 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, conflictStore, rollbackUnmerge, droppedOriginRegistry, preferencesUnionReader, forwardCommitmentMutate, sessionOwnershipRegistry, sendDrain: _sendDrain ?? undefined, 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, guardRegistry, listPoolMachines: _listPoolMachines ?? undefined, deliverMandateToMachine: _deliverMandateToMachine ?? undefined, 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, geminiLoopRunner, sleepController, agentActivityState, reapLog, resumeQueue, resumeDrainer, autonomousLivenessReconciler, enforcedTerminationStatus: () => enforcedTerminationWatchdog?.guardStatus() ?? null, prHandLease: prHandLease ?? undefined, operatorStopRecorder: recordOperatorStop, sleepWakeDetector, unjustifiedStopGate, stopGateDb, stopNotifier, liveTestGate, liveTestGateMode, liveTestRunnerCtx }); // Resolve the late-bound topic-operator getter (increment 2e): routing was
23129
23206
  if (_stateSyncStoresResolved?.classReview?.enabled && replicatedPeerStreamReader) {
23130
23207
  const { CLASS_REVIEW_STORE_KEY, classReviewFromOriginRecord } = await import('../core/ClassReviewReplicatedStore.js');
23131
23208
  const reader = replicatedPeerStreamReader;