instar 1.3.1580 → 1.3.1582

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 (74) hide show
  1. package/dist/commands/server.d.ts.map +1 -1
  2. package/dist/commands/server.js +68 -4
  3. package/dist/commands/server.js.map +1 -1
  4. package/dist/core/MobileDeviceKeys.d.ts +6 -0
  5. package/dist/core/MobileDeviceKeys.d.ts.map +1 -1
  6. package/dist/core/MobileDeviceKeys.js +1 -1
  7. package/dist/core/MobileDeviceKeys.js.map +1 -1
  8. package/dist/core/MobileOwnNames.d.ts +137 -0
  9. package/dist/core/MobileOwnNames.d.ts.map +1 -0
  10. package/dist/core/MobileOwnNames.js +481 -0
  11. package/dist/core/MobileOwnNames.js.map +1 -0
  12. package/dist/core/PostUpdateMigrator.d.ts +5 -0
  13. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  14. package/dist/core/PostUpdateMigrator.js +31 -1
  15. package/dist/core/PostUpdateMigrator.js.map +1 -1
  16. package/dist/core/devGatedFeatures.d.ts.map +1 -1
  17. package/dist/core/devGatedFeatures.js +6 -0
  18. package/dist/core/devGatedFeatures.js.map +1 -1
  19. package/dist/core/peerHomebaseAwareness.d.ts +2 -0
  20. package/dist/core/peerHomebaseAwareness.d.ts.map +1 -1
  21. package/dist/core/peerHomebaseAwareness.js +12 -7
  22. package/dist/core/peerHomebaseAwareness.js.map +1 -1
  23. package/dist/core/types.d.ts +9 -0
  24. package/dist/core/types.d.ts.map +1 -1
  25. package/dist/core/types.js.map +1 -1
  26. package/dist/data/standards-guard-index.json +1 -1
  27. package/dist/data/standards-guard-index.meta.json +2 -2
  28. package/dist/data/standards-registry.meta.json +1 -1
  29. package/dist/scaffold/templates.d.ts.map +1 -1
  30. package/dist/scaffold/templates.js +2 -1
  31. package/dist/scaffold/templates.js.map +1 -1
  32. package/dist/server/AgentServer.d.ts +11 -0
  33. package/dist/server/AgentServer.d.ts.map +1 -1
  34. package/dist/server/AgentServer.js +13 -1
  35. package/dist/server/AgentServer.js.map +1 -1
  36. package/dist/server/mobilePairingRoutes.d.ts +17 -0
  37. package/dist/server/mobilePairingRoutes.d.ts.map +1 -1
  38. package/dist/server/mobilePairingRoutes.js +116 -15
  39. package/dist/server/mobilePairingRoutes.js.map +1 -1
  40. package/dist/server/routes.d.ts +4 -0
  41. package/dist/server/routes.d.ts.map +1 -1
  42. package/dist/server/routes.js +29 -2
  43. package/dist/server/routes.js.map +1 -1
  44. package/dist/threadline/ThreadlineEndpoints.d.ts +16 -0
  45. package/dist/threadline/ThreadlineEndpoints.d.ts.map +1 -1
  46. package/dist/threadline/ThreadlineEndpoints.js +19 -0
  47. package/dist/threadline/ThreadlineEndpoints.js.map +1 -1
  48. package/dist/threadline/ThreadlineRouter.d.ts +16 -0
  49. package/dist/threadline/ThreadlineRouter.d.ts.map +1 -1
  50. package/dist/threadline/ThreadlineRouter.js +30 -1
  51. package/dist/threadline/ThreadlineRouter.js.map +1 -1
  52. package/dist/threadline/TopicLinkageHandler.d.ts +14 -0
  53. package/dist/threadline/TopicLinkageHandler.d.ts.map +1 -1
  54. package/dist/threadline/TopicLinkageHandler.js +55 -21
  55. package/dist/threadline/TopicLinkageHandler.js.map +1 -1
  56. package/dist/threadline/peerHomebase.d.ts +65 -0
  57. package/dist/threadline/peerHomebase.d.ts.map +1 -1
  58. package/dist/threadline/peerHomebase.js +43 -0
  59. package/dist/threadline/peerHomebase.js.map +1 -1
  60. package/dist/threadline/peerHomebaseRelay.d.ts +66 -0
  61. package/dist/threadline/peerHomebaseRelay.d.ts.map +1 -0
  62. package/dist/threadline/peerHomebaseRelay.js +112 -0
  63. package/dist/threadline/peerHomebaseRelay.js.map +1 -0
  64. package/package.json +1 -1
  65. package/src/data/builtin-manifest.json +64 -64
  66. package/src/data/standards-guard-index.json +1 -1
  67. package/src/data/standards-guard-index.meta.json +2 -2
  68. package/src/data/standards-registry.meta.json +1 -1
  69. package/src/scaffold/templates.ts +2 -1
  70. package/upgrades/1.3.1581.md +22 -0
  71. package/upgrades/1.3.1582.md +26 -0
  72. package/upgrades/side-effects/mobile-multi-route-inc1.md +120 -0
  73. package/upgrades/side-effects/peer-homebase-routing.md +143 -0
  74. package/upgrades/side-effects/test-loopback-bind.md +50 -0
@@ -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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"}
@@ -277,6 +277,9 @@ function liveInjectOutcomeFromObservation(r) {
277
277
  import { createThreadlineTopicRespawn } from '../threadline/topicRespawnHook.js';
278
278
  import { WarrantsReplyGate, evaluateAndRecordInbound } from '../threadline/WarrantsReplyGate.js';
279
279
  import { CollaborationSurfacer } from '../threadline/CollaborationSurfacer.js';
280
+ import { PeerHomebaseRelay } from '../threadline/peerHomebaseRelay.js';
281
+ import { withThreadlineForwardedAuthor } from '../threadline/TelegramOriginAttribution.js';
282
+ import { makePeerUserTopicResolver, peerHomebaseEnabled as _peerHomebaseEnabledForRouting } from '../threadline/peerHomebase.js';
280
283
  import { ListenerSessionManager } from '../threadline/ListenerSessionManager.js';
281
284
  import { SystemReviewer } from '../monitoring/SystemReviewer.js';
282
285
  import { createSessionProbes } from '../monitoring/probes/SessionProbe.js';
@@ -17288,6 +17291,24 @@ export async function startServer(options) {
17288
17291
  const collaborationSurfacer = telegram
17289
17292
  ? new CollaborationSurfacer({ telegram, stateDir: config.stateDir })
17290
17293
  : undefined;
17294
+ // peer-conversation-homebase-topic §2.6 (operator rule 2026-10-31): a peer's message meant
17295
+ // for the user is posted to the peer's own topic. One resolver for every delivery point;
17296
+ // the trust manager is built further down (Threadline bootstrap), so its read is late-bound
17297
+ // and resolves to the existing routing until then.
17298
+ let _peerProfileFor = null;
17299
+ const peerUserTopic = makePeerUserTopicResolver({
17300
+ enabled: () => _peerHomebaseEnabledForRouting(config),
17301
+ profileFor: (peer) => _peerProfileFor?.(peer) ?? null,
17302
+ conversationFor: (threadId) => conversationStore.get(threadId) ?? null,
17303
+ });
17304
+ const peerHomebaseRelay = telegram
17305
+ ? new PeerHomebaseRelay({
17306
+ resolve: peerUserTopic,
17307
+ salienceGate: new (await import('../threadline/SalienceGate.js')).SalienceGate(),
17308
+ sendToTopic: (topicId, text) => withThreadlineForwardedAuthor(telegramOriginBoot?.runtime.service, 'inbound', topicId, text, () => telegram.sendToTopic(topicId, text)),
17309
+ log: (m) => console.log(m),
17310
+ })
17311
+ : undefined;
17291
17312
  // CMT-567: one shared BriefDeps for the "open this" LLM topic-name + summary.
17292
17313
  // Built once here (all three inputs in scope) and threaded to BOTH getHubDeps
17293
17314
  // closures AND the AgentServer ctx, so the HTTP route + the structural
@@ -17902,6 +17923,8 @@ export async function startServer(options) {
17902
17923
  _a2aRelayForwardCtx = a2aRelayForwardCtx;
17903
17924
  const a2aRelayForwardEnabled = () => a2aRelayForwardMod.resolveRelayForwardEnabled(liveConfig.get('threadline.relayForward.enabled', undefined), config);
17904
17925
  const salienceGate = new SalienceGate(); // fallback-only for v1; spec §5.4
17926
+ // §2.6: tell a spawned thread session which topic to use for the user.
17927
+ threadlineRouter.setPeerUserTopicResolver((q) => peerUserTopic({ threadId: q.threadId, peers: q.peers }));
17905
17928
  let topicLinkageHandler = null;
17906
17929
  if (commitmentTracker) {
17907
17930
  topicLinkageHandler = new TopicLinkageHandler({
@@ -17956,6 +17979,12 @@ export async function startServer(options) {
17956
17979
  selfMachineId: () => _meshSelfId,
17957
17980
  selfMachineName: () => _meshSelfId ? (verifiedEntityName(_meshSelfId, _listPoolMachines?.().find((m) => m.machineId === _meshSelfId)?.nickname) ?? 'this machine') : 'this machine',
17958
17981
  topicOwnerOf: (topicId) => sessionOwnershipRegistry?.ownerOf(String(topicId)) ?? null,
17982
+ // §2.6: a user-facing post about this reply goes to the peer's own topic (the operator's
17983
+ // binding still wins); the reply itself is still handed to the originating session.
17984
+ resolveUserTopic: (q) => {
17985
+ const r = peerUserTopic({ threadId: q.threadId, peers: q.peers, existingTopicId: q.originTopicId });
17986
+ return r.topicId;
17987
+ },
17959
17988
  onRemoteReplyEvent: (event) => {
17960
17989
  if (event === 'ask')
17961
17990
  a2aRelayForwardCtx.counters.replyAsks++;
@@ -18458,6 +18487,8 @@ export async function startServer(options) {
18458
18487
  const { PeerHomebaseBackfill } = await import('../threadline/peerHomebaseBackfill.js');
18459
18488
  const { peerHomebaseEnabled, displayNameCollides } = await import('../threadline/peerHomebase.js');
18460
18489
  const asPeer = (p) => p && p.fingerprint && p.pairingState === 'mutual-verified' ? { fingerprint: p.fingerprint, name: p.agent } : null;
18490
+ // §2.6: the routing resolver reads the same trust store.
18491
+ _peerProfileFor = (fp) => tm.getProfileByFingerprint(fp);
18461
18492
  _peerHomebaseBackfill = new PeerHomebaseBackfill({
18462
18493
  enabled: () => peerHomebaseEnabled(config),
18463
18494
  holdsLease: () => !state.readOnly,
@@ -18474,6 +18505,19 @@ export async function startServer(options) {
18474
18505
  record: (fp, topicId) => tm.setHomebaseTopic(fp, topicId),
18475
18506
  log: (m) => console.log(m),
18476
18507
  });
18508
+ // §2.1 on BOTH sides of an invite pairing: the inviter ('finishing', its person tapped
18509
+ // Finish) and the acceptor ('finish-received', the inviter's signed finish arrived) each
18510
+ // create their homebase the moment the pairing is mutual-verified — before the first
18511
+ // message, which previously reached the acceptor before its topic existed. 'paired' is a
18512
+ // late backstop; ensureFor is idempotent, lease-holder-only, and never throws.
18513
+ const hbBackfill = _peerHomebaseBackfill;
18514
+ threadline.pairingInvites?.events.on('notice', (n) => {
18515
+ if (!n || typeof n.peerFp !== 'string')
18516
+ return;
18517
+ if (n.kind === 'finishing' || n.kind === 'finish-received' || n.kind === 'paired') {
18518
+ void hbBackfill.ensureFor(n.peerFp).catch(() => { });
18519
+ }
18520
+ });
18477
18521
  }
18478
18522
  // Secure A2A Verified Pairing §3.8 (FD11) — SEND-SIDE: attach the journal-backed
18479
18523
  // emitter to the trust manager's pairing-replication hooks so a local markMutualVerified
@@ -18753,15 +18797,35 @@ export async function startServer(options) {
18753
18797
  // a peer reaching out cold. Topic-bound conversations are surfaced by
18754
18798
  // TopicLinkageHandler instead, so we skip them here. Best-effort,
18755
18799
  // non-blocking; never breaks the inbound path.
18756
- if (collaborationSurfacer) {
18757
- const hasParentTopic = conversationStore.get(gateThreadId)?.boundTopicId != null;
18758
- void collaborationSurfacer.surface({
18800
+ const hasParentTopic = conversationStore.get(gateThreadId)?.boundTopicId != null;
18801
+ // §2.6 (operator rule 2026-10-31): a peer with its own topic gets its user-meant
18802
+ // messages posted THERE by the server — never left to whichever topic a session
18803
+ // picks. Topic-bound conversations are TopicLinkageHandler's (it applies the same
18804
+ // rule), so only an unbound one is relayed here. The silent-hub first-contact post
18805
+ // is replaced by the homebase post for such a peer.
18806
+ // When the relay does not post (agent-internal, rate-limited, send failed) the
18807
+ // existing hub surface still runs, so no message is left with no topic at all.
18808
+ const hubSurface = () => {
18809
+ // No bare early exit here: the ACT-091 audit pins every exit after the ack stage.
18810
+ void collaborationSurfacer?.surface({
18759
18811
  threadId: gateThreadId,
18760
18812
  senderName,
18761
18813
  text: textContent,
18762
18814
  hasParentTopic,
18763
18815
  warrants: !decision.suppress,
18764
18816
  });
18817
+ };
18818
+ if (peerHomebaseRelay && !hasParentTopic) {
18819
+ void peerHomebaseRelay.relayInbound({
18820
+ threadId: gateThreadId,
18821
+ peers: [senderFingerprint],
18822
+ senderName,
18823
+ text: textContent,
18824
+ }).then((r) => { if (!r.posted)
18825
+ hubSurface(); }, () => hubSurface());
18826
+ }
18827
+ else {
18828
+ hubSurface();
18765
18829
  }
18766
18830
  }
18767
18831
  catch (gateErr) {
@@ -29068,7 +29132,7 @@ export async function startServer(options) {
29068
29132
  const server = new AgentServer({ config, 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) {
29069
29133
  peers = (_listPoolMachines?.() ?? []).filter((m) => m.machineId !== _meshSelfId && !!m.lastKnownUrl).map((m) => ({ machineId: m.machineId, nickname: verifiedEntityName(m.machineId, m.nickname) ?? '', url: m.lastKnownUrl }));
29070
29134
  } if (peers.length === 0)
29071
- 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, conversationFollowThrough, whatsappBusinessBackend, messageBridge, hookEventReceiver, worktreeMonitor, subagentTracker, instructionsVerifier, handshakeManager: threadlineHandshake, threadlineRouter, conversationStore, threadLog, threadMessageRecorder, warrantsReplyGate, collaborationSurfacer, 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, 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
29135
+ 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, 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, 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
29072
29136
  const readIdentityProjectionPeerRows = async () => {
29073
29137
  const peers = _resolvePeerUrls?.() ?? [];
29074
29138
  const extra = config.multiMachine?.peerUrlAllowlist;