instar 1.3.1581 → 1.3.1583

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 (102) hide show
  1. package/dist/commands/server.d.ts.map +1 -1
  2. package/dist/commands/server.js +165 -5
  3. package/dist/commands/server.js.map +1 -1
  4. package/dist/core/AppConversationService.d.ts +15 -0
  5. package/dist/core/AppConversationService.d.ts.map +1 -1
  6. package/dist/core/AppConversationService.js +20 -0
  7. package/dist/core/AppConversationService.js.map +1 -1
  8. package/dist/core/AppConversationStore.d.ts +21 -3
  9. package/dist/core/AppConversationStore.d.ts.map +1 -1
  10. package/dist/core/AppConversationStore.js +35 -5
  11. package/dist/core/AppConversationStore.js.map +1 -1
  12. package/dist/core/AppConversationsReplicatedStore.js +1 -1
  13. package/dist/core/AppConversationsReplicatedStore.js.map +1 -1
  14. package/dist/core/AppRecordSignatures.d.ts +102 -0
  15. package/dist/core/AppRecordSignatures.d.ts.map +1 -0
  16. package/dist/core/AppRecordSignatures.js +247 -0
  17. package/dist/core/AppRecordSignatures.js.map +1 -0
  18. package/dist/core/CoherenceJournal.d.ts +1 -1
  19. package/dist/core/CoherenceJournal.d.ts.map +1 -1
  20. package/dist/core/CoherenceJournal.js +10 -2
  21. package/dist/core/CoherenceJournal.js.map +1 -1
  22. package/dist/core/MobileDeviceKeyLedger.d.ts +93 -0
  23. package/dist/core/MobileDeviceKeyLedger.d.ts.map +1 -0
  24. package/dist/core/MobileDeviceKeyLedger.js +323 -0
  25. package/dist/core/MobileDeviceKeyLedger.js.map +1 -0
  26. package/dist/core/MobileDeviceKeyLedgerReplicatedStore.d.ts +19 -0
  27. package/dist/core/MobileDeviceKeyLedgerReplicatedStore.d.ts.map +1 -0
  28. package/dist/core/MobileDeviceKeyLedgerReplicatedStore.js +53 -0
  29. package/dist/core/MobileDeviceKeyLedgerReplicatedStore.js.map +1 -0
  30. package/dist/core/MobileDeviceKeys.d.ts +9 -2
  31. package/dist/core/MobileDeviceKeys.d.ts.map +1 -1
  32. package/dist/core/MobileDeviceKeys.js +8 -4
  33. package/dist/core/MobileDeviceKeys.js.map +1 -1
  34. package/dist/core/PostUpdateMigrator.d.ts +3 -0
  35. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  36. package/dist/core/PostUpdateMigrator.js +32 -2
  37. package/dist/core/PostUpdateMigrator.js.map +1 -1
  38. package/dist/core/ReplicatedStoreReconcilerWiring.d.ts.map +1 -1
  39. package/dist/core/ReplicatedStoreReconcilerWiring.js +1 -0
  40. package/dist/core/ReplicatedStoreReconcilerWiring.js.map +1 -1
  41. package/dist/core/devGatedFeatures.js +1 -1
  42. package/dist/core/devGatedFeatures.js.map +1 -1
  43. package/dist/core/peerHomebaseAwareness.d.ts +4 -0
  44. package/dist/core/peerHomebaseAwareness.d.ts.map +1 -1
  45. package/dist/core/peerHomebaseAwareness.js +24 -7
  46. package/dist/core/peerHomebaseAwareness.js.map +1 -1
  47. package/dist/data/standards-guard-index.json +1 -1
  48. package/dist/data/standards-guard-index.meta.json +2 -2
  49. package/dist/data/standards-registry.meta.json +1 -1
  50. package/dist/server/AgentServer.d.ts +1 -0
  51. package/dist/server/AgentServer.d.ts.map +1 -1
  52. package/dist/server/AgentServer.js +32 -0
  53. package/dist/server/AgentServer.js.map +1 -1
  54. package/dist/server/CapabilityIndex.js +1 -1
  55. package/dist/server/CapabilityIndex.js.map +1 -1
  56. package/dist/server/mobileConversationRoutes.d.ts +22 -9
  57. package/dist/server/mobileConversationRoutes.d.ts.map +1 -1
  58. package/dist/server/mobileConversationRoutes.js +99 -25
  59. package/dist/server/mobileConversationRoutes.js.map +1 -1
  60. package/dist/server/mobilePairingRoutes.d.ts +10 -1
  61. package/dist/server/mobilePairingRoutes.d.ts.map +1 -1
  62. package/dist/server/mobilePairingRoutes.js +105 -6
  63. package/dist/server/mobilePairingRoutes.js.map +1 -1
  64. package/dist/server/routes.d.ts +2 -0
  65. package/dist/server/routes.d.ts.map +1 -1
  66. package/dist/server/routes.js +35 -4
  67. package/dist/server/routes.js.map +1 -1
  68. package/dist/threadline/PeerUserMeantJudge.d.ts +135 -0
  69. package/dist/threadline/PeerUserMeantJudge.d.ts.map +1 -0
  70. package/dist/threadline/PeerUserMeantJudge.js +394 -0
  71. package/dist/threadline/PeerUserMeantJudge.js.map +1 -0
  72. package/dist/threadline/ThreadlineEndpoints.d.ts +17 -0
  73. package/dist/threadline/ThreadlineEndpoints.d.ts.map +1 -1
  74. package/dist/threadline/ThreadlineEndpoints.js +21 -0
  75. package/dist/threadline/ThreadlineEndpoints.js.map +1 -1
  76. package/dist/threadline/ThreadlineRouter.d.ts +24 -0
  77. package/dist/threadline/ThreadlineRouter.d.ts.map +1 -1
  78. package/dist/threadline/ThreadlineRouter.js +45 -1
  79. package/dist/threadline/ThreadlineRouter.js.map +1 -1
  80. package/dist/threadline/TopicLinkageHandler.d.ts +35 -0
  81. package/dist/threadline/TopicLinkageHandler.d.ts.map +1 -1
  82. package/dist/threadline/TopicLinkageHandler.js +95 -35
  83. package/dist/threadline/TopicLinkageHandler.js.map +1 -1
  84. package/dist/threadline/peerHomebase.d.ts +65 -0
  85. package/dist/threadline/peerHomebase.d.ts.map +1 -1
  86. package/dist/threadline/peerHomebase.js +43 -0
  87. package/dist/threadline/peerHomebase.js.map +1 -1
  88. package/dist/threadline/peerHomebaseRelay.d.ts +94 -0
  89. package/dist/threadline/peerHomebaseRelay.d.ts.map +1 -0
  90. package/dist/threadline/peerHomebaseRelay.js +220 -0
  91. package/dist/threadline/peerHomebaseRelay.js.map +1 -0
  92. package/package.json +1 -1
  93. package/src/data/builtin-manifest.json +64 -64
  94. package/src/data/standards-guard-index.json +1 -1
  95. package/src/data/standards-guard-index.meta.json +2 -2
  96. package/src/data/standards-registry.meta.json +1 -1
  97. package/src/data/state-coherence-registry.json +17 -0
  98. package/upgrades/1.3.1582.md +26 -0
  99. package/upgrades/1.3.1583.md +42 -0
  100. package/upgrades/side-effects/mobile-native-conversations-inc2.md +142 -0
  101. package/upgrades/side-effects/peer-homebase-per-message.md +149 -0
  102. package/upgrades/side-effects/peer-homebase-routing.md +143 -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';
@@ -4728,6 +4731,10 @@ export async function startServer(options) {
4728
4731
  // are on (no separate switch: for a native conversation the store is the only copy).
4729
4732
  const { APP_CONVERSATIONS_KIND_REGISTRATION } = await import('../core/AppConversationsReplicatedStore.js');
4730
4733
  replicatedKindRegistry.register(APP_CONVERSATIONS_KIND_REGISTRATION);
4734
+ // mobile-native-conversations §4.8 — the `mobileDeviceKeyLedger` kind (inert registration; on
4735
+ // whenever native app conversations are on, so a signed record can be checked on any machine).
4736
+ const { DEVICE_KEY_LEDGER_KIND_REGISTRATION } = await import('../core/MobileDeviceKeyLedgerReplicatedStore.js');
4737
+ replicatedKindRegistry.register(DEVICE_KEY_LEDGER_KIND_REGISTRATION);
4731
4738
  // WS2.3 (ws23-relationships-userregistry-security) — register the SECOND concrete
4732
4739
  // replicated kind, `relationship-record`, onto the registry: the FIRST PII kind.
4733
4740
  // Dual-registry's dynamic half (the static half is CoherenceJournal.JOURNAL_KINDS,
@@ -4913,6 +4920,15 @@ export async function startServer(options) {
4913
4920
  _appConversationService?.ingestReplicated(entries.map((e) => appEventFromReplicatedData(e.data)));
4914
4921
  }).catch(() => { });
4915
4922
  }
4923
+ // Device-key ledger rows: each lands only when it verifies under the pinned key of the machine it names.
4924
+ if (kind === 'mobile-device-key-ledger-row' && _appConversationService?.deps.keyLedger) {
4925
+ const ledger = _appConversationService.deps.keyLedger;
4926
+ for (const e of entries) {
4927
+ const r = ledger.ingestReplicated(e.data);
4928
+ if (r === 'bad-signature' || r === 'unverifiable')
4929
+ console.warn(` [device-key-ledger] a replicated row was not accepted (${r})`);
4930
+ }
4931
+ }
4916
4932
  });
4917
4933
  // Author-side HLC clock — persisted under the journal dir (atomic temp+rename)
4918
4934
  // so the merge total order survives restarts (§3.5). node = this machine's id.
@@ -5020,7 +5036,7 @@ export async function startServer(options) {
5020
5036
  const _stateSyncStoresResolved = (() => {
5021
5037
  let s = _stateSyncStoresBase ?? {};
5022
5038
  if (_appNativeOn)
5023
- s = { ...s, appConversations: { enabled: true } };
5039
+ s = { ...s, appConversations: { enabled: true }, mobileDeviceKeyLedger: { enabled: true } };
5024
5040
  if (_accountFollowMeEnabled)
5025
5041
  s = { ...s, subscriptionAccountMeta: { enabled: true } };
5026
5042
  if (_pinReplicateEnabled)
@@ -8585,7 +8601,24 @@ export async function startServer(options) {
8585
8601
  console.warn(` [app-conversations] reply relay: ${[...r.errors, ...r.degraded].join('; ')}`);
8586
8602
  }
8587
8603
  let appDispatch = null;
8604
+ // Signed records (§4.6): this machine's identity signer, the signing-key history lookup and
8605
+ // the device-key ledger. No identity ⇒ messages are still stored and delivered, read `unknown`.
8606
+ const [sigMod, ledgerMod, ledgerReplMod] = await Promise.all([
8607
+ import('../core/AppRecordSignatures.js'), import('../core/MobileDeviceKeyLedger.js'), import('../core/MobileDeviceKeyLedgerReplicatedStore.js'),
8608
+ ]);
8609
+ const appSigner = sigMod.loadMachineSigner(config.stateDir);
8610
+ const appKeyLookup = sigMod.identityKeyLookup(config.stateDir);
8611
+ if (!appSigner)
8612
+ console.warn(' [app-conversations] this machine has no identity key: app messages will read "couldn\'t check"');
8613
+ const appKeyLedger = appSigner ? new ledgerMod.MobileDeviceKeyLedger({
8614
+ stateDir: config.stateDir, signer: appSigner, keyLookup: appKeyLookup,
8615
+ reportDegradation: (what, detail) => degradationReporter.report({
8616
+ feature: what, primary: 'check signed app messages against the device-key ledger', fallback: 'messages read "couldn\'t check"',
8617
+ reason: detail, impact: 'Signed app messages cannot be checked on this machine.',
8618
+ }),
8619
+ }) : null;
8588
8620
  const appSvc = new AppConversationService({
8621
+ signer: appSigner, keyLookup: appKeyLookup, keyLedger: appKeyLedger,
8589
8622
  stateDir: config.stateDir,
8590
8623
  machineId: () => _meshSelfId ?? os.hostname(),
8591
8624
  registry: conversationRegistry,
@@ -8632,6 +8665,27 @@ export async function startServer(options) {
8632
8665
  const emitter = replicatedRecordEmitter;
8633
8666
  appSvc.store.setReplicationHook((ev) => emitter.emit(replMod.APP_CONVERSATIONS_STORE_KEY, replMod.deriveAppConversationRecordKey(ev.conversationKey, ev.eventId), replMod.buildAppConversationRecordData(ev)));
8634
8667
  }
8668
+ if (replicatedRecordEmitter && appKeyLedger) {
8669
+ const emitter = replicatedRecordEmitter;
8670
+ appKeyLedger.setReplicationHook((row) => emitter.emit(ledgerReplMod.DEVICE_KEY_LEDGER_STORE_KEY, ledgerReplMod.deriveDeviceKeyLedgerRecordKey(row), ledgerReplMod.buildDeviceKeyLedgerRecordData(row)));
8671
+ }
8672
+ if (replicatedPeerStreamReader && cjOwnMachineId && appKeyLedger) {
8673
+ try {
8674
+ const reader = replicatedPeerStreamReader;
8675
+ let landed = 0;
8676
+ for (const rk of reader.listRecordKeys(ledgerReplMod.DEVICE_KEY_LEDGER_STORE_KEY)) {
8677
+ for (const r of reader.loadOriginRecords(ledgerReplMod.DEVICE_KEY_LEDGER_STORE_KEY, rk)) {
8678
+ if (r.origin !== cjOwnMachineId && appKeyLedger.ingestReplicated(r.data) === 'accepted')
8679
+ landed++;
8680
+ }
8681
+ }
8682
+ if (landed > 0)
8683
+ console.log(pc.dim(` [device-key-ledger] landed ${landed} replicated row(s) at boot`));
8684
+ }
8685
+ catch (err) {
8686
+ console.warn(` [device-key-ledger] boot replication read failed: ${err instanceof Error ? err.message : String(err)}`);
8687
+ }
8688
+ }
8635
8689
  if (replicatedPeerStreamReader && cjOwnMachineId) {
8636
8690
  try {
8637
8691
  const reader = replicatedPeerStreamReader;
@@ -17288,6 +17342,55 @@ export async function startServer(options) {
17288
17342
  const collaborationSurfacer = telegram
17289
17343
  ? new CollaborationSurfacer({ telegram, stateDir: config.stateDir })
17290
17344
  : undefined;
17345
+ // peer-conversation-homebase-topic §2.6 (operator rule 2026-10-31): a peer's message meant
17346
+ // for the user is posted to the peer's own topic. One resolver for every delivery point;
17347
+ // the trust manager is built further down (Threadline bootstrap), so its read is late-bound
17348
+ // and resolves to the existing routing until then.
17349
+ let _peerProfileFor = null;
17350
+ const peerUserTopic = makePeerUserTopicResolver({
17351
+ enabled: () => _peerHomebaseEnabledForRouting(config),
17352
+ profileFor: (peer) => _peerProfileFor?.(peer) ?? null,
17353
+ conversationFor: (threadId) => conversationStore.get(threadId) ?? null,
17354
+ });
17355
+ // §2.7: "meant for the user?" is judged PER MESSAGE (Jev first, then the Codex fast tier,
17356
+ // then the shared provider — so a Claude-only agent still judges; no verdict posts). Read
17357
+ // live: `threadline.peerHomebase.perMessageClassification: false` restores first-only.
17358
+ let peerUserMeantJudge = null;
17359
+ try {
17360
+ const { buildPeerUserMeantJudge } = await import('../threadline/PeerUserMeantJudge.js');
17361
+ const { getFeatureMetricsRecorder } = await import('../core/CircuitBreakingIntelligenceProvider.js');
17362
+ const { SecretStore } = await import('../core/SecretStore.js');
17363
+ let userMeantCodex = null;
17364
+ try {
17365
+ const { LlmCircuitBreaker } = await import('../core/LlmCircuitBreaker.js');
17366
+ const { buildIntelligenceProvider: buildUserMeantReferee } = await import('../core/intelligenceProviderFactory.js');
17367
+ userMeantCodex = buildUserMeantReferee({ framework: 'codex-cli', breaker: new LlmCircuitBreaker() });
17368
+ }
17369
+ catch { /* @silent-fallback-ok — no Codex CLI; the shared provider is the next referee */ }
17370
+ peerUserMeantJudge = buildPeerUserMeantJudge({
17371
+ readPeerHomebaseBlock: () => liveConfig.get('threadline.peerHomebase', undefined),
17372
+ readSecret: (name) => new SecretStore({ stateDir: config.stateDir, forceFileKey: config.secrets?.forceFileKey }).get(name),
17373
+ referees: () => [
17374
+ ...(userMeantCodex ? [{ name: 'codex', provider: userMeantCodex }] : []),
17375
+ ...(sharedIntelligence ? [{ name: 'shared', provider: sharedIntelligence }] : []),
17376
+ ],
17377
+ stateDir: config.stateDir,
17378
+ metrics: { record: (r) => getFeatureMetricsRecorder()?.record(r) },
17379
+ });
17380
+ console.log(pc.dim(` Peer user-meant judge: constructed (referees: ${[userMeantCodex ? 'codex' : null, sharedIntelligence ? 'shared' : null].filter(Boolean).join(', ') || 'none'})`));
17381
+ }
17382
+ catch (err) {
17383
+ console.log(pc.yellow(` Peer user-meant judge: not constructed (${err?.message ?? 'unknown'}) — first-only rule applies`));
17384
+ }
17385
+ const peerHomebaseRelay = telegram
17386
+ ? new PeerHomebaseRelay({
17387
+ resolve: peerUserTopic,
17388
+ salienceGate: new (await import('../threadline/SalienceGate.js')).SalienceGate(),
17389
+ userMeantJudge: peerUserMeantJudge,
17390
+ sendToTopic: (topicId, text) => withThreadlineForwardedAuthor(telegramOriginBoot?.runtime.service, 'inbound', topicId, text, () => telegram.sendToTopic(topicId, text)),
17391
+ log: (m) => console.log(m),
17392
+ })
17393
+ : undefined;
17291
17394
  // CMT-567: one shared BriefDeps for the "open this" LLM topic-name + summary.
17292
17395
  // Built once here (all three inputs in scope) and threaded to BOTH getHubDeps
17293
17396
  // closures AND the AgentServer ctx, so the HTTP route + the structural
@@ -17902,6 +18005,12 @@ export async function startServer(options) {
17902
18005
  _a2aRelayForwardCtx = a2aRelayForwardCtx;
17903
18006
  const a2aRelayForwardEnabled = () => a2aRelayForwardMod.resolveRelayForwardEnabled(liveConfig.get('threadline.relayForward.enabled', undefined), config);
17904
18007
  const salienceGate = new SalienceGate(); // fallback-only for v1; spec §5.4
18008
+ // §2.6: tell a spawned thread session which topic to use for the user.
18009
+ threadlineRouter.setPeerUserTopicResolver((q) => peerUserTopic({ threadId: q.threadId, peers: q.peers }), {
18010
+ // §2.7: only where the relay has actually taken this thread under per-message judging.
18011
+ serverPostsUserMeant: (threadId) => peerHomebaseRelay?.postsUserMeantFor(threadId) === true
18012
+ && conversationStore.get(threadId)?.boundTopicId == null,
18013
+ });
17905
18014
  let topicLinkageHandler = null;
17906
18015
  if (commitmentTracker) {
17907
18016
  topicLinkageHandler = new TopicLinkageHandler({
@@ -17956,6 +18065,21 @@ export async function startServer(options) {
17956
18065
  selfMachineId: () => _meshSelfId,
17957
18066
  selfMachineName: () => _meshSelfId ? (verifiedEntityName(_meshSelfId, _listPoolMachines?.().find((m) => m.machineId === _meshSelfId)?.nickname) ?? 'this machine') : 'this machine',
17958
18067
  topicOwnerOf: (topicId) => sessionOwnershipRegistry?.ownerOf(String(topicId)) ?? null,
18068
+ // §2.6: a user-facing post about this reply goes to the peer's own topic (the operator's
18069
+ // binding still wins); the reply itself is still handed to the originating session.
18070
+ resolveUserTopic: (q) => {
18071
+ const r = peerUserTopic({ threadId: q.threadId, peers: q.peers, existingTopicId: q.originTopicId });
18072
+ return r.topicId;
18073
+ },
18074
+ // §2.7: a reply redirected to the homebase is judged per message (null when switched off).
18075
+ judgeUserMeant: async (q) => {
18076
+ if (!peerUserMeantJudge || !peerUserMeantJudge.enabled())
18077
+ return null;
18078
+ const v = await peerUserMeantJudge.judge({ threadId: q.threadId, peer: q.peers[0] ?? '', senderName: q.senderName, text: q.text, deadlineMs: q.deadlineMs });
18079
+ if (v.firstOnly)
18080
+ return null; // the judge's budget is spent: the SalienceGate (first-only) decides
18081
+ return { verdict: v.userMeant ? 'user-visible' : 'agent-internal', reason: `per-message: ${v.decidedBy}/${v.reason}` };
18082
+ },
17959
18083
  onRemoteReplyEvent: (event) => {
17960
18084
  if (event === 'ask')
17961
18085
  a2aRelayForwardCtx.counters.replyAsks++;
@@ -18458,6 +18582,8 @@ export async function startServer(options) {
18458
18582
  const { PeerHomebaseBackfill } = await import('../threadline/peerHomebaseBackfill.js');
18459
18583
  const { peerHomebaseEnabled, displayNameCollides } = await import('../threadline/peerHomebase.js');
18460
18584
  const asPeer = (p) => p && p.fingerprint && p.pairingState === 'mutual-verified' ? { fingerprint: p.fingerprint, name: p.agent } : null;
18585
+ // §2.6: the routing resolver reads the same trust store.
18586
+ _peerProfileFor = (fp) => tm.getProfileByFingerprint(fp);
18461
18587
  _peerHomebaseBackfill = new PeerHomebaseBackfill({
18462
18588
  enabled: () => peerHomebaseEnabled(config),
18463
18589
  holdsLease: () => !state.readOnly,
@@ -18474,6 +18600,19 @@ export async function startServer(options) {
18474
18600
  record: (fp, topicId) => tm.setHomebaseTopic(fp, topicId),
18475
18601
  log: (m) => console.log(m),
18476
18602
  });
18603
+ // §2.1 on BOTH sides of an invite pairing: the inviter ('finishing', its person tapped
18604
+ // Finish) and the acceptor ('finish-received', the inviter's signed finish arrived) each
18605
+ // create their homebase the moment the pairing is mutual-verified — before the first
18606
+ // message, which previously reached the acceptor before its topic existed. 'paired' is a
18607
+ // late backstop; ensureFor is idempotent, lease-holder-only, and never throws.
18608
+ const hbBackfill = _peerHomebaseBackfill;
18609
+ threadline.pairingInvites?.events.on('notice', (n) => {
18610
+ if (!n || typeof n.peerFp !== 'string')
18611
+ return;
18612
+ if (n.kind === 'finishing' || n.kind === 'finish-received' || n.kind === 'paired') {
18613
+ void hbBackfill.ensureFor(n.peerFp).catch(() => { });
18614
+ }
18615
+ });
18477
18616
  }
18478
18617
  // Secure A2A Verified Pairing §3.8 (FD11) — SEND-SIDE: attach the journal-backed
18479
18618
  // emitter to the trust manager's pairing-replication hooks so a local markMutualVerified
@@ -18753,15 +18892,36 @@ export async function startServer(options) {
18753
18892
  // a peer reaching out cold. Topic-bound conversations are surfaced by
18754
18893
  // TopicLinkageHandler instead, so we skip them here. Best-effort,
18755
18894
  // non-blocking; never breaks the inbound path.
18756
- if (collaborationSurfacer) {
18757
- const hasParentTopic = conversationStore.get(gateThreadId)?.boundTopicId != null;
18758
- void collaborationSurfacer.surface({
18895
+ const hasParentTopic = conversationStore.get(gateThreadId)?.boundTopicId != null;
18896
+ // §2.6 (operator rule 2026-10-31): a peer with its own topic gets its user-meant
18897
+ // messages posted THERE by the server — never left to whichever topic a session
18898
+ // picks. Topic-bound conversations are TopicLinkageHandler's (it applies the same
18899
+ // rule), so only an unbound one is relayed here. The silent-hub first-contact post
18900
+ // is replaced by the homebase post for such a peer.
18901
+ // When the relay does not post (agent-internal, rate-limited, send failed) the
18902
+ // existing hub surface still runs, so no message is left with no topic at all.
18903
+ const hubSurface = () => {
18904
+ // No bare early exit here: the ACT-091 audit pins every exit after the ack stage.
18905
+ void collaborationSurfacer?.surface({
18759
18906
  threadId: gateThreadId,
18760
18907
  senderName,
18761
18908
  text: textContent,
18762
18909
  hasParentTopic,
18763
18910
  warrants: !decision.suppress,
18764
18911
  });
18912
+ };
18913
+ if (peerHomebaseRelay && !hasParentTopic) {
18914
+ void peerHomebaseRelay.relayInbound({
18915
+ threadId: gateThreadId,
18916
+ peers: [senderFingerprint],
18917
+ senderName,
18918
+ text: textContent,
18919
+ messageType: typeof msgType === 'string' ? msgType : null,
18920
+ }).then((r) => { if (!r.posted)
18921
+ hubSurface(); }, () => hubSurface());
18922
+ }
18923
+ else {
18924
+ hubSurface();
18765
18925
  }
18766
18926
  }
18767
18927
  catch (gateErr) {
@@ -29068,7 +29228,7 @@ export async function startServer(options) {
29068
29228
  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
29229
  peers = (_listPoolMachines?.() ?? []).filter((m) => m.machineId !== _meshSelfId && !!m.lastKnownUrl).map((m) => ({ machineId: m.machineId, nickname: verifiedEntityName(m.machineId, m.nickname) ?? '', url: m.lastKnownUrl }));
29070
29230
  } 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
29231
+ 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
29232
  const readIdentityProjectionPeerRows = async () => {
29073
29233
  const peers = _resolvePeerUrls?.() ?? [];
29074
29234
  const extra = config.multiMachine?.peerUrlAllowlist;