@cello-protocol/daemon 0.0.53 → 0.0.54

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 (173) hide show
  1. package/dist/agent-handlers.d.ts +57 -0
  2. package/dist/agent-handlers.d.ts.map +1 -0
  3. package/dist/agent-handlers.js +360 -0
  4. package/dist/agent-handlers.js.map +1 -0
  5. package/dist/agent-id-migration.d.ts.map +1 -1
  6. package/dist/agent-id-migration.js +1 -0
  7. package/dist/agent-id-migration.js.map +1 -1
  8. package/dist/agent-loader.d.ts +3 -4
  9. package/dist/agent-loader.d.ts.map +1 -1
  10. package/dist/agent-loader.js +3 -4
  11. package/dist/agent-loader.js.map +1 -1
  12. package/dist/cbor-blob-migration.d.ts +8 -0
  13. package/dist/cbor-blob-migration.d.ts.map +1 -0
  14. package/dist/cbor-blob-migration.js +115 -0
  15. package/dist/cbor-blob-migration.js.map +1 -0
  16. package/dist/close-session-handler.d.ts +41 -0
  17. package/dist/close-session-handler.d.ts.map +1 -0
  18. package/dist/close-session-handler.js +399 -0
  19. package/dist/close-session-handler.js.map +1 -0
  20. package/dist/consortium-bootstrap.d.ts +83 -0
  21. package/dist/consortium-bootstrap.d.ts.map +1 -0
  22. package/dist/consortium-bootstrap.js +120 -0
  23. package/dist/consortium-bootstrap.js.map +1 -0
  24. package/dist/contact-handlers.d.ts +56 -0
  25. package/dist/contact-handlers.d.ts.map +1 -0
  26. package/dist/contact-handlers.js +303 -0
  27. package/dist/contact-handlers.js.map +1 -0
  28. package/dist/content-park-client.d.ts.map +1 -1
  29. package/dist/content-park-client.js +7 -7
  30. package/dist/content-park-client.js.map +1 -1
  31. package/dist/content-park.d.ts +15 -0
  32. package/dist/content-park.d.ts.map +1 -0
  33. package/dist/content-park.js +227 -0
  34. package/dist/content-park.js.map +1 -0
  35. package/dist/daemon.d.ts +0 -11
  36. package/dist/daemon.d.ts.map +1 -1
  37. package/dist/daemon.js +407 -4552
  38. package/dist/daemon.js.map +1 -1
  39. package/dist/db-identity-store.d.ts +31 -35
  40. package/dist/db-identity-store.d.ts.map +1 -1
  41. package/dist/db-identity-store.js +62 -66
  42. package/dist/db-identity-store.js.map +1 -1
  43. package/dist/directory-bootstrap.d.ts +27 -31
  44. package/dist/directory-bootstrap.d.ts.map +1 -1
  45. package/dist/directory-bootstrap.js +18 -21
  46. package/dist/directory-bootstrap.js.map +1 -1
  47. package/dist/frame-values.d.ts +3 -0
  48. package/dist/frame-values.d.ts.map +1 -0
  49. package/dist/frame-values.js +73 -0
  50. package/dist/frame-values.js.map +1 -0
  51. package/dist/identity-migration.d.ts +8 -8
  52. package/dist/identity-migration.d.ts.map +1 -1
  53. package/dist/identity-migration.js +30 -31
  54. package/dist/identity-migration.js.map +1 -1
  55. package/dist/inbound-seal-request.d.ts +17 -0
  56. package/dist/inbound-seal-request.d.ts.map +1 -0
  57. package/dist/inbound-seal-request.js +155 -0
  58. package/dist/inbound-seal-request.js.map +1 -0
  59. package/dist/inbound-sessions.d.ts +54 -0
  60. package/dist/inbound-sessions.d.ts.map +1 -0
  61. package/dist/inbound-sessions.js +603 -0
  62. package/dist/inbound-sessions.js.map +1 -0
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js +8 -10
  65. package/dist/index.js.map +1 -1
  66. package/dist/initiate-session-handler.d.ts +22 -0
  67. package/dist/initiate-session-handler.d.ts.map +1 -0
  68. package/dist/initiate-session-handler.js +150 -0
  69. package/dist/initiate-session-handler.js.map +1 -0
  70. package/dist/network-directory-node.d.ts +6 -6
  71. package/dist/network-directory-node.d.ts.map +1 -1
  72. package/dist/network-directory-node.js +29 -28
  73. package/dist/network-directory-node.js.map +1 -1
  74. package/dist/notification-handlers.d.ts +32 -0
  75. package/dist/notification-handlers.d.ts.map +1 -0
  76. package/dist/notification-handlers.js +73 -0
  77. package/dist/notification-handlers.js.map +1 -0
  78. package/dist/outbound-sessions.d.ts +54 -0
  79. package/dist/outbound-sessions.d.ts.map +1 -0
  80. package/dist/outbound-sessions.js +429 -0
  81. package/dist/outbound-sessions.js.map +1 -0
  82. package/dist/park-envelope.d.ts.map +1 -1
  83. package/dist/park-envelope.js +3 -2
  84. package/dist/park-envelope.js.map +1 -1
  85. package/dist/register-handler.d.ts +35 -0
  86. package/dist/register-handler.d.ts.map +1 -0
  87. package/dist/register-handler.js +179 -0
  88. package/dist/register-handler.js.map +1 -0
  89. package/dist/registration-manager.d.ts.map +1 -1
  90. package/dist/registration-manager.js +3 -6
  91. package/dist/registration-manager.js.map +1 -1
  92. package/dist/relay-receipt-store.d.ts.map +1 -1
  93. package/dist/relay-receipt-store.js +1 -2
  94. package/dist/relay-receipt-store.js.map +1 -1
  95. package/dist/retry-queue.d.ts +18 -60
  96. package/dist/retry-queue.d.ts.map +1 -1
  97. package/dist/retry-queue.js +46 -97
  98. package/dist/retry-queue.js.map +1 -1
  99. package/dist/seal-coordinator.d.ts +47 -0
  100. package/dist/seal-coordinator.d.ts.map +1 -0
  101. package/dist/seal-coordinator.js +551 -0
  102. package/dist/seal-coordinator.js.map +1 -0
  103. package/dist/seal-flows.d.ts +50 -0
  104. package/dist/seal-flows.d.ts.map +1 -0
  105. package/dist/seal-flows.js +454 -0
  106. package/dist/seal-flows.js.map +1 -0
  107. package/dist/seal-frontier-verify.d.ts +9 -9
  108. package/dist/seal-frontier-verify.d.ts.map +1 -1
  109. package/dist/seal-frontier-verify.js +11 -12
  110. package/dist/seal-frontier-verify.js.map +1 -1
  111. package/dist/seal-leaf.d.ts +58 -0
  112. package/dist/seal-leaf.d.ts.map +1 -0
  113. package/dist/seal-leaf.js +111 -0
  114. package/dist/seal-leaf.js.map +1 -0
  115. package/dist/seal-receipt-upgrade.d.ts +1 -1
  116. package/dist/seal-receipt-upgrade.js +1 -1
  117. package/dist/seal-upgrade.d.ts +10 -10
  118. package/dist/seal-upgrade.d.ts.map +1 -1
  119. package/dist/seal-upgrade.js +23 -24
  120. package/dist/seal-upgrade.js.map +1 -1
  121. package/dist/session-assignment-parser.d.ts +16 -19
  122. package/dist/session-assignment-parser.d.ts.map +1 -1
  123. package/dist/session-assignment-parser.js +30 -29
  124. package/dist/session-assignment-parser.js.map +1 -1
  125. package/dist/session-ceremony.d.ts +3 -6
  126. package/dist/session-ceremony.d.ts.map +1 -1
  127. package/dist/session-ceremony.js +7 -9
  128. package/dist/session-ceremony.js.map +1 -1
  129. package/dist/session-content-handlers.d.ts +25 -0
  130. package/dist/session-content-handlers.d.ts.map +1 -0
  131. package/dist/session-content-handlers.js +436 -0
  132. package/dist/session-content-handlers.js.map +1 -0
  133. package/dist/session-name.d.ts +35 -0
  134. package/dist/session-name.d.ts.map +1 -0
  135. package/dist/session-name.js +60 -0
  136. package/dist/session-name.js.map +1 -0
  137. package/dist/session-node-manager.d.ts +26 -62
  138. package/dist/session-node-manager.d.ts.map +1 -1
  139. package/dist/session-node-manager.js +115 -92
  140. package/dist/session-node-manager.js.map +1 -1
  141. package/dist/session-read-handlers.d.ts +38 -0
  142. package/dist/session-read-handlers.d.ts.map +1 -0
  143. package/dist/session-read-handlers.js +233 -0
  144. package/dist/session-read-handlers.js.map +1 -0
  145. package/dist/session-relay-client.d.ts +8 -8
  146. package/dist/session-relay-client.d.ts.map +1 -1
  147. package/dist/session-relay-client.js +44 -46
  148. package/dist/session-relay-client.js.map +1 -1
  149. package/dist/session-tree.d.ts +11 -23
  150. package/dist/session-tree.d.ts.map +1 -1
  151. package/dist/session-tree.js +14 -26
  152. package/dist/session-tree.js.map +1 -1
  153. package/dist/signaling-connect.d.ts +2 -5
  154. package/dist/signaling-connect.d.ts.map +1 -1
  155. package/dist/signaling-connect.js +7 -12
  156. package/dist/signaling-connect.js.map +1 -1
  157. package/dist/sqlcipher-db.d.ts +18 -19
  158. package/dist/sqlcipher-db.d.ts.map +1 -1
  159. package/dist/sqlcipher-db.js +30 -30
  160. package/dist/sqlcipher-db.js.map +1 -1
  161. package/dist/telegram-doorbell.d.ts +38 -0
  162. package/dist/telegram-doorbell.d.ts.map +1 -0
  163. package/dist/telegram-doorbell.js +139 -0
  164. package/dist/telegram-doorbell.js.map +1 -0
  165. package/dist/types.d.ts +86 -79
  166. package/dist/types.d.ts.map +1 -1
  167. package/dist/types.js +0 -1
  168. package/dist/types.js.map +1 -1
  169. package/dist/vocabulary.d.ts +30 -30
  170. package/dist/vocabulary.d.ts.map +1 -1
  171. package/dist/vocabulary.js +41 -49
  172. package/dist/vocabulary.js.map +1 -1
  173. package/package.json +5 -5
@@ -0,0 +1,603 @@
1
+ /**
2
+ * Seam 2: inbound session establishment — the counterparty side.
3
+ *
4
+ * When agent A initiates a session, the directory FROST-signs a SessionAssignment and pushes it to
5
+ * B. This is everything B does with it: verify it, wait for B's standing receiver, accept the
6
+ * session, and park the event on a per-agent queue that a waiting cello_await_session drains.
7
+ *
8
+ * The accept path is SERIALIZED through one chain (inboundAcceptChain) on purpose — two assignments
9
+ * racing into acceptSession would both try to consume the single standing receiver.
10
+ *
11
+ * Everything here is keyed by (agentName, sessionId), NEVER sessionId alone: two of the operator's
12
+ * agents can hold both ends of the same session on one daemon (DOD-LOOP-1), and keying by session
13
+ * alone would let one agent's inbound event resolve the other's waiter.
14
+ */
15
+ import { randomUUID } from "node:crypto";
16
+ import { frameValueToHex } from "./frame-values.js";
17
+ import { computeGenesisPrevRoot } from "@cello-protocol/protocol-types";
18
+ import { hash as cryptoHash } from "@cello-protocol/crypto";
19
+ import { DbIdentityStore } from "./db-identity-store.js";
20
+ import { extractOfferedMoniker } from "./session-assignment-parser.js";
21
+ /** How long an un-accepted inbound session request stays claimable. */
22
+ export const INBOUND_SESSION_TTL_MS = 24 * 60 * 60 * 1000;
23
+ export function createInboundSessions(deps) {
24
+ const { logger, sessionNodeManager, agents, getConnState, resolveCurrentAgent, NO_CURRENT_AGENT_RESPONSE, getKeyProvider, sharedSignaling, handleInboundSealInterruptedRequest, reapDeadHalfOpenSessions, sendAwayResponse, dispatchSessionStateChangedWithTelegram, sendTelegramDoorbell, } = deps;
25
+ // ─── Seam 2: inbound session establishment (counterparty side) ─────────────
26
+ //
27
+ // When agent A initiates a session, the directory FROST-signs a SessionAssignment
28
+ // and PUSHES it to the counterparty B over B's directory signaling stream (an
29
+ // unsolicited `session_assignment` frame). The daemon turns that frame into a live
30
+ // inbound session: it resolves which local agent is participant_b, calls
31
+ // SessionNodeManager.acceptSession (which hands off the standing receiver node bound
32
+ // to A's session peer id), and enqueues an inbound session event that a blocked
33
+ // cello_await_session call returns. This is the inbound mirror of cello_initiate_session.
34
+ // MONIKER-2 AC2b: the initiator's validated offered name. Session-scoped display material ONLY
35
+ // (spec: promotion to a stored pet name needs an explicit operator action). In-memory by design —
36
+ // a restart degrades the label to fingerprint, never worse.
37
+ //
38
+ // DOD-MONIKER-6 (spec §10): keyed by (agentName, sessionIdHex), NEVER sessionIdHex alone. A box
39
+ // is written by the RECEIVING side and holds the CALLER's name, so it is meaningful only to the
40
+ // agent it was written for. Keyed by session id alone, a daemon hosting both participants hands
41
+ // the initiator the box filled in for her counterparty — she is told she messaged herself — and
42
+ // either agent's state change or request expiry silently drops the other's name.
43
+ const offeredMonikers = new Map();
44
+ const offerKey = (agentName, sessionIdHex) => `${agentName}:${sessionIdHex}`;
45
+ // Expired requests move HERE (from inboundSessionQueues) rather than vanishing — visible via
46
+ // cello_check_notifications so the operator can see what they missed, not just silence.
47
+ const expiredSessionRequests = new Map();
48
+ // A blocked cello_await_session waiter. connectionId is carried so the disconnect
49
+ // hook can evict waiters belonging to a dead connection (otherwise enqueue would hand
50
+ // an inbound event to a closed connection and the event would be lost — review H2).
51
+ // Per-agent FIFO queue (events accepted while no cello_await_session is blocked) and
52
+ // the per-agent list of blocked waiters. Inbound sessions are addressed to a specific
53
+ // local agent (participant_b), so both are keyed by agent name.
54
+ const inboundSessionQueues = new Map();
55
+ const inboundSessionWaiters = new Map();
56
+ // Session ids whose acceptInboundAssignment is in flight (the accept step is async
57
+ // because it may wait for the standing receiver to rebuild). Guards against two
58
+ // simultaneous frames for the SAME session both passing the getSessionRecord check
59
+ // before either has inserted the row (review M1, race half).
60
+ // DOD-LOOP-1: keyed by (agentName, sessionId), like every other structure here — NOT by session
61
+ // id alone. Two of the operator's agents can hold both ends of the same session on one daemon, and
62
+ // a bare session key would let one agent's in-flight accept suppress the other's.
63
+ const inboundInFlight = new Set();
64
+ // Inbound accepts are SERIALIZED through this chain. acceptSession synchronously
65
+ // consumes the single standing receiver and rebuilds a replacement asynchronously;
66
+ // running two accepts concurrently would let the second pass its readiness check on
67
+ // the receiver the first is about to consume, then fail on the consumed receiver
68
+ // (review M2, race). Serializing makes the second accept wait for the first's rebuild.
69
+ let inboundAcceptChain = Promise.resolve();
70
+ function enqueueInboundSession(agentName, event) {
71
+ const waiters = inboundSessionWaiters.get(agentName);
72
+ if (waiters && waiters.length > 0) {
73
+ // Hand straight to the oldest blocked waiter (deliver clears its own timeout).
74
+ const w = waiters.shift();
75
+ w.deliver(event);
76
+ return;
77
+ }
78
+ const q = inboundSessionQueues.get(agentName) ?? [];
79
+ q.push({ ...event, enqueuedAt: Date.now() }); // M8C-TTL-1: stamp queue entry time
80
+ inboundSessionQueues.set(agentName, q);
81
+ }
82
+ // M8C-TTL-1 (reviewer HIGH fix, aed2d71f, D19): expiredSessionRequests is a lasting log, not a
83
+ // consumed queue (unlike inboundSessionQueues, nothing ever drains it) — a whitelisted CONTACT-1
84
+ // contact is EXEMPT from ABUSE-1's acceptance bounds ("bounded only by disk"), so they can push
85
+ // unlimited accepted sessions the operator never claims, each becoming a permanent, unremovable
86
+ // entry every 24h for the life of the daemon process. Capped the same way STATUS_RESUMABLE_CAP
87
+ // bounds the interrupted-sessions list — keep only the MOST RECENT N per agent.
88
+ const EXPIRED_SESSION_REQUESTS_CAP = 20;
89
+ // M8C-TTL-1: move any queue entries past the TTL into expiredSessionRequests (visible via
90
+ // INBOX), instead of leaving them to sit forever or vanish silently. Called lazily on every
91
+ // read of the queue (cello_await_session's immediate-check, cello_check_notifications) rather
92
+ // than on a timer — no background sweep needed, and it's always correct-as-of-the-read.
93
+ function reapExpiredInboundSessions(agentName) {
94
+ const q = inboundSessionQueues.get(agentName);
95
+ if (!q || q.length === 0)
96
+ return;
97
+ const now = Date.now();
98
+ const live = [];
99
+ let expiredList = expiredSessionRequests.get(agentName);
100
+ for (const e of q) {
101
+ if (e.enqueuedAt !== undefined && now - e.enqueuedAt > INBOUND_SESSION_TTL_MS) {
102
+ if (!expiredList) {
103
+ expiredList = [];
104
+ expiredSessionRequests.set(agentName, expiredList);
105
+ }
106
+ expiredList.push({ sessionIdHex: e.sessionIdHex, counterpartyPubkeyHex: e.counterpartyPubkeyHex, expiredAt: now });
107
+ if (expiredList.length > EXPIRED_SESSION_REQUESTS_CAP) {
108
+ expiredList.splice(0, expiredList.length - EXPIRED_SESSION_REQUESTS_CAP); // keep newest N
109
+ }
110
+ logger.info("session.request.expired", { agentName, sessionId: e.sessionIdHex, enqueuedAt: e.enqueuedAt });
111
+ // MONIKER-2 AC2b (review F1): the offer's display name expires with the offer.
112
+ if (offeredMonikers.delete(offerKey(agentName, e.sessionIdHex))) {
113
+ logger.debug("moniker.offer.dropped", { agentName, sessionId: e.sessionIdHex, state: "expired" });
114
+ }
115
+ }
116
+ else {
117
+ live.push(e);
118
+ }
119
+ }
120
+ inboundSessionQueues.set(agentName, live);
121
+ }
122
+ // Pull the fields out of a pushed session_assignment frame. Returns null when the frame
123
+ // carries no usable assignment object / is missing the essential ids (the handler then
124
+ // ignores it rather than throwing). Field-level validity (peer id, signature type) is
125
+ // checked in the handler so it can emit a distinct, diagnosable event per failure.
126
+ function extractInboundSessionAssignment(frame) {
127
+ const raw = frame["assignment"];
128
+ if (!raw || typeof raw !== "object")
129
+ return null;
130
+ const a = raw;
131
+ const pa = a["participant_a"];
132
+ const pb = a["participant_b"];
133
+ const sessionIdHex = frameValueToHex(a["session_id"]);
134
+ const participantAPubkeyHex = pa ? frameValueToHex(pa["pubkey"]) : null;
135
+ const participantBPubkeyHex = pb ? frameValueToHex(pb["pubkey"]) : null;
136
+ if (!sessionIdHex || !participantAPubkeyHex || !participantBPubkeyHex)
137
+ return null;
138
+ // M7 DOD-SPINE-6 / MSG-001-3b: relay endpoint so the receiver also connects to the
139
+ // relay witness (so the relay can deliver the initiator's witnessed leaves to it).
140
+ const relayEndpoint = a["relay_endpoint"];
141
+ const relayPeerId = relayEndpoint && typeof relayEndpoint["peer_id"] === "string" ? relayEndpoint["peer_id"] : "";
142
+ const relayAddrs = relayEndpoint && Array.isArray(relayEndpoint["multiaddrs"])
143
+ ? relayEndpoint["multiaddrs"].filter((m) => typeof m === "string")
144
+ : [];
145
+ // MONIKER-2 AC2: validate the offered name ONCE, at this wire boundary.
146
+ const monikerResult = extractOfferedMoniker(a);
147
+ return {
148
+ sessionIdHex,
149
+ participantAPubkeyHex,
150
+ participantBPubkeyHex,
151
+ initiatorPeerId: typeof a["initiator_session_peer_id"] === "string" ? a["initiator_session_peer_id"] : "",
152
+ counterpartySessionPeerId: typeof a["counterparty_session_peer_id"] === "string" ? a["counterparty_session_peer_id"] : null,
153
+ sessionTimestamp: typeof a["session_timestamp"] === "number" ? a["session_timestamp"] : 0,
154
+ signatureType: typeof a["signature_type"] === "string" ? a["signature_type"] : null,
155
+ // M7 legibility-TBS-binding (responder verify): the FROST-signed assignment embeds the
156
+ // initiator's primary (group) pubkey as `signer_pubkey` — the key that signs the seal.
157
+ // The responder stores it so it can verify the bilateral seal signature locally, not just
158
+ // accept it (session.ts: "embedded so the counterparty can verify").
159
+ signerPubkeyHex: a["signer_pubkey"] !== undefined ? frameValueToHex(a["signer_pubkey"]) : null,
160
+ relayPeerId,
161
+ relayAddrs,
162
+ offeredMoniker: monikerResult.offeredMoniker,
163
+ monikerRejected: monikerResult.rejected,
164
+ monikerRejectReason: monikerResult.reason ?? null,
165
+ };
166
+ }
167
+ // Wait (bounded) for THIS AGENT's standing receiver to be ready. acceptSession consumes the
168
+ // agent's standing receiver and rebuilds a replacement asynchronously, so a burst of inbound
169
+ // assignments for that agent would otherwise drop all but the first (review M2). Polling the
170
+ // per-agent readiness lets each accept proceed once the prior rebuild completes. Must check the
171
+ // OWNING agent — `getStandingReceiverReady()` with no arg returns true if ANY agent has one,
172
+ // which in the loopback case (alice + bob on one daemon) would falsely pass while bob's own SR
173
+ // is still mid-rebuild and drop bob's session (DOD-LOOP-1).
174
+ async function waitForStandingReceiver(agentName, maxWaitMs = 3_000, stepMs = 25) {
175
+ if (sessionNodeManager.getStandingReceiverReady(agentName))
176
+ return true;
177
+ const deadline = Date.now() + maxWaitMs;
178
+ while (Date.now() < deadline) {
179
+ await new Promise((r) => setTimeout(r, stepMs));
180
+ if (sessionNodeManager.getStandingReceiverReady(agentName))
181
+ return true;
182
+ }
183
+ return sessionNodeManager.getStandingReceiverReady(agentName);
184
+ }
185
+ async function acceptInboundAssignment(parsed, agentName, correlationId) {
186
+ try {
187
+ // M8C-ABUSE-1 + DOD-TIER-2/3: bound acceptance by the sender's TIER — a per-sender cap that is
188
+ // the sender's tier cap (BLOCKED 0 → refused here, indistinguishably from an over-cap stranger),
189
+ // plus a global anti-swarm cap that applies only to the UNKNOWN-tier stranger pool. No tier is
190
+ // unbounded (INV-TIER-BOUND); KNOWN+ are exempt from the GLOBAL pool only, not from their own
191
+ // cap. Checked FIRST, before any standing-receiver work, so a refusal is cheap.
192
+ // CC-10: reap provably-dead ghosts for THIS agent before counting — otherwise invisible
193
+ // interrupted 0-received sessions (post-restart shape) consume the sender's budget forever
194
+ // and lock the stranger out with no list read ever clearing them. Safe here: abandonSession
195
+ // flips the DB status synchronously, so the bound query below sees the reaped state.
196
+ reapDeadHalfOpenSessions(agentName);
197
+ const bound = sessionNodeManager.checkUnknownSenderAcceptanceBound(agentName, parsed.participantAPubkeyHex);
198
+ if (!bound.ok) {
199
+ logger.warn("session.inbound.accept.failed", {
200
+ sessionId: parsed.sessionIdHex,
201
+ agentName,
202
+ reason: bound.reason,
203
+ correlationId,
204
+ });
205
+ return;
206
+ }
207
+ // DOD-RENAME-1 AC1 (review F1 / DEC-AB-4): record the offered name as the rename baseline the
208
+ // moment the offer passes the acceptance gate — an ALLOWED peer (the bound check let them
209
+ // through) is tracked even if session formation transiently fails below. Deliberately AFTER the
210
+ // bound check, not at the raw parse point: a BLOCKED or over-cap peer must NOT be able to drive
211
+ // the operator's rename baseline or push notices into their inbox. Guarded by offeredMoniker !==
212
+ // null so a silent offer never clears the baseline (AC5).
213
+ if (parsed.offeredMoniker !== null) {
214
+ sessionNodeManager.recordOfferedMoniker(agentName, parsed.participantAPubkeyHex, parsed.offeredMoniker);
215
+ }
216
+ // M8B F14 (fix 2): KICK creation before polling — an inbound offer arriving while no
217
+ // receiver exists and none is being created must trigger the ensure itself (the doc
218
+ // comment's "retries on demand" made true), instead of polling a creation nobody
219
+ // started and dropping the offer. Fire-and-forget: the poll below observes readiness.
220
+ void sessionNodeManager.ensureStandingReceiverForAgent(agentName).catch((err) => {
221
+ logger.warn("session.standing_receiver.ensure.failed", {
222
+ agentName,
223
+ reason: err instanceof Error ? err.message : String(err),
224
+ correlationId,
225
+ });
226
+ });
227
+ // M2: do not drop the session if this agent's standing receiver is mid-rebuild.
228
+ const ready = await waitForStandingReceiver(agentName);
229
+ if (!ready) {
230
+ logger.warn("session.inbound.accept.failed", {
231
+ sessionId: parsed.sessionIdHex,
232
+ agentName,
233
+ reason: "standing_receiver_unavailable",
234
+ correlationId,
235
+ });
236
+ return;
237
+ }
238
+ // M7 DOD-SPINE-6 / MSG-001-3b: relay witness for the receiver. Build from the
239
+ // inbound assignment's relay endpoint + this agent's K_local + the 16-byte session id.
240
+ const kp = getKeyProvider(agentName);
241
+ let relayParams;
242
+ if (kp && parsed.relayPeerId && parsed.relayAddrs.length > 0) {
243
+ relayParams = {
244
+ relayPeerId: parsed.relayPeerId,
245
+ relayAddrs: parsed.relayAddrs,
246
+ keyProvider: kp,
247
+ senderPubkey: await kp.getPublicKey(),
248
+ sessionIdBytes: new Uint8Array(Buffer.from(parsed.sessionIdHex, "hex")),
249
+ };
250
+ }
251
+ const result = await sessionNodeManager.acceptSession(parsed.sessionIdHex, agentName, parsed.participantAPubkeyHex, // the initiator is OUR counterparty
252
+ parsed.initiatorPeerId, correlationId, relayParams);
253
+ if (!result.ok) {
254
+ logger.warn("session.inbound.accept.failed", {
255
+ sessionId: parsed.sessionIdHex,
256
+ agentName,
257
+ reason: result.reason,
258
+ correlationId,
259
+ });
260
+ return;
261
+ }
262
+ // M7 legibility-TBS-binding (responder verify): store the initiator's primary (the seal
263
+ // signer, carried as signer_pubkey on the FROST-signed assignment) so the bilateral seal
264
+ // signature can be verified locally rather than accepted on faith.
265
+ if (parsed.signerPubkeyHex) {
266
+ sessionNodeManager.recordCounterpartyPrimary(agentName, parsed.sessionIdHex, parsed.signerPubkeyHex);
267
+ }
268
+ // H1: genesis_prev_root is the canonical two-party genesis value — the SAME value
269
+ // baked into the FROST-signed session-establishment TBS and derived by the initiator
270
+ // and directory — NOT the daemon's (empty) tree root. computeGenesisPrevRoot sorts
271
+ // the pubkeys internally, so natural (A, B) order is correct.
272
+ const genesisPrevRootHex = Buffer.from(computeGenesisPrevRoot(Buffer.from(parsed.participantAPubkeyHex, "hex"), Buffer.from(parsed.participantBPubkeyHex, "hex"), Buffer.from(parsed.sessionIdHex, "hex"), parsed.sessionTimestamp)).toString("hex");
273
+ logger.info("session.inbound.accepted", {
274
+ sessionId: parsed.sessionIdHex,
275
+ agentName,
276
+ sessionPeerId: result.peerId,
277
+ correlationId,
278
+ });
279
+ // MONIKER-2 AC2: a present-but-invalid moniker is a red flag (the sender runs modified
280
+ // code) — logged with the spec'd fields and NEVER the raw value. Not grounds to refuse
281
+ // the session (version skew is real; refusing hands strangers a DoS lever).
282
+ if (parsed.monikerRejected) {
283
+ logger.info("moniker.rejected", {
284
+ agentName,
285
+ pubkey: parsed.participantAPubkeyHex,
286
+ reason: parsed.monikerRejectReason ?? "invalid",
287
+ correlationId,
288
+ });
289
+ }
290
+ // MONIKER-2 AC2b: display material for THIS offer/session only (never persisted, never
291
+ // auto-written to contacts — AC3). Session-scoped: MONIKER-4's dispatcher resolves
292
+ // whoLabel from here; entries are dropped when the session's terminal state dispatches.
293
+ // DOD-MONIKER-6: scoped to `agentName` — the agent this offer was received FOR.
294
+ if (parsed.offeredMoniker !== null) {
295
+ offeredMonikers.set(offerKey(agentName, parsed.sessionIdHex), parsed.offeredMoniker);
296
+ // (DOD-RENAME-1's rename-baseline update runs earlier, right after the acceptance bound — see
297
+ // the recordOfferedMoniker call there. This map is only the session-scoped display material.)
298
+ }
299
+ enqueueInboundSession(agentName, {
300
+ sessionIdHex: parsed.sessionIdHex,
301
+ counterpartyPubkeyHex: parsed.participantAPubkeyHex,
302
+ genesisPrevRootHex,
303
+ offeredMoniker: parsed.offeredMoniker,
304
+ });
305
+ dispatchSessionStateChangedWithTelegram(agentName, parsed.sessionIdHex, "created", parsed.participantAPubkeyHex);
306
+ // M8C-TGDOOR-1: session requests ALWAYS ring (DoD) — no coalescing, unlike message-waiting.
307
+ void sendTelegramDoorbell(agentName, parsed.sessionIdHex, "session_request", "New session request");
308
+ // M8C-AWAY-1: an unattended agent auto-acks a fresh inbound session request. Fire-and-forget
309
+ // (sendAwayResponse never throws) — best-effort, must not delay/block acceptance completion.
310
+ void sendAwayResponse(agentName, parsed.sessionIdHex, "request");
311
+ // CC-1 (2026-07-07): do NOT auto-add the requester here. Accepting the *connection* must not
312
+ // grant *trust*. The old auto-add promoted any stranger who knocked once to "known" (Level-4
313
+ // fast-track), which defeated BOTH the screening layer AND the ABUSE-1 acceptance caps
314
+ // (a higher tier raises the per-sender cap, so auto-promoting a stranger would have let their
315
+ // sessions 2+ ride a larger bound — DOD-TIER-2). Promotion to "known" now requires operator engagement only:
316
+ // an outbound cello_initiate_session (below, ~3137), the operator replying INTO the session via
317
+ // cello_send, or an explicit cello_contact_add. An unattended stranger is never auto-whitelisted.
318
+ // See docs/planning/.../2026-07-07_1700_four-level-screening-policy.md (D21).
319
+ }
320
+ finally {
321
+ inboundInFlight.delete(offerKey(agentName, parsed.sessionIdHex));
322
+ }
323
+ }
324
+ function handleInboundSessionAssignment(frame) {
325
+ // M4: one correlationId minted per inbound flow, threaded through EVERY event below.
326
+ const correlationId = randomUUID();
327
+ const parsed = extractInboundSessionAssignment(frame);
328
+ if (!parsed) {
329
+ logger.warn("session.inbound.assignment.malformed", {
330
+ reason: "missing_assignment_or_ids",
331
+ correlationId,
332
+ });
333
+ return;
334
+ }
335
+ // L1: refuse M1 single-key assignments outright (downgrade guard). Distinct from the
336
+ // deferred FROST verification below — track it so SESSION-004's re-home keeps it.
337
+ if (parsed.signatureType === "single") {
338
+ logger.warn("session.inbound.assignment.refused", {
339
+ sessionId: parsed.sessionIdHex,
340
+ reason: "unsupported_signature_type",
341
+ correlationId,
342
+ });
343
+ return;
344
+ }
345
+ // M3: the initiator session peer id is the AC-015 hand-off gate (acceptSession passes
346
+ // it to gater.setAllowedPeer). An empty value would gate the handed-off receiver to "",
347
+ // defeating "only the initiator may connect". The dead stack treated this as malformed.
348
+ if (!parsed.initiatorPeerId) {
349
+ logger.warn("session.inbound.assignment.malformed", {
350
+ sessionId: parsed.sessionIdHex,
351
+ reason: "missing_initiator_peer_id",
352
+ correlationId,
353
+ });
354
+ return;
355
+ }
356
+ // Resolve which local agent is participant_b. participant pubkeys are the agents'
357
+ // K_local identity pubkeys (same convention as the seal-interrupted responder's
358
+ // counterparty match above). If none of our agents is the counterparty, this
359
+ // assignment is not for this daemon — drop it.
360
+ const localAgent = agents.find((ag) => ag.pubkey === parsed.participantBPubkeyHex);
361
+ if (!localAgent) {
362
+ logger.debug("session.inbound.not_local", {
363
+ sessionId: parsed.sessionIdHex,
364
+ counterpartyPubkey: parsed.participantBPubkeyHex,
365
+ correlationId,
366
+ });
367
+ return;
368
+ }
369
+ // DOD-INBOUND-GUARD-1 (D3): the receive-side mirror of the initiator's F13 guard (~3189).
370
+ // An empty counterparty endpoint means the offer-accept never happened (this agent's standing
371
+ // receiver was not up when the directory's session_offer arrived) and the directory signed the
372
+ // assignment anyway, with "empty defaults". The initiator refuses that assignment and creates
373
+ // NO session — accepting it here builds a phantom session whose away-reply lands in the
374
+ // initiator's transcript with no session row: permanently unread AND unreadable. Refuse it
375
+ // loudly, before any session state exists. Nothing legitimate is lost — a session whose
376
+ // initiator has no address to dial is unusable by construction.
377
+ if (!parsed.counterpartySessionPeerId) {
378
+ logger.warn("session.inbound.assignment.incomplete", {
379
+ agentName: localAgent.name,
380
+ sessionId: parsed.sessionIdHex,
381
+ correlationId,
382
+ });
383
+ return;
384
+ }
385
+ // M1: idempotency — a retransmitted assignment for an already-known session (persisted
386
+ // row OR currently in flight) must not double-accept (orphaned node) or double-enqueue.
387
+ if (inboundInFlight.has(offerKey(localAgent.name, parsed.sessionIdHex)) || sessionNodeManager.getSessionRecord(localAgent.name, parsed.sessionIdHex)) {
388
+ logger.info("session.inbound.duplicate.ignored", {
389
+ sessionId: parsed.sessionIdHex,
390
+ agentName: localAgent.name,
391
+ correlationId,
392
+ });
393
+ return;
394
+ }
395
+ // SECURITY — DEFERRED (SESSION-004 re-home): the directory's FROST threshold signature
396
+ // on the assignment (directory_signature over the TBS, verified against signer_pubkey)
397
+ // is NOT yet verified here. The old client's receiveSessionAssignment performed that
398
+ // check; it must be re-homed natively before this path faces a real (untrusted)
399
+ // directory. Until then we accept directory-pushed assignments on trust — the in-process
400
+ // seam tests inject trusted frames.
401
+ // M8B F15: logged at DEBUG with an "expected" note — it fires on EVERY healthy inbound
402
+ // session, and at WARN it read as a failure and actively misled live diagnosis. The
403
+ // deferred-verification state is a known, tracked gap (SESSION-004), not a per-session
404
+ // anomaly.
405
+ logger.debug("session.inbound.assignment.unverified", {
406
+ sessionId: parsed.sessionIdHex,
407
+ agentName: localAgent.name,
408
+ note: "FROST assignment signature verification deferred to SESSION-004 re-home (expected on every inbound session until SESSION-004)",
409
+ correlationId,
410
+ });
411
+ inboundInFlight.add(offerKey(localAgent.name, parsed.sessionIdHex));
412
+ // Serialize: the next accept does not begin until this one (and any standing-receiver
413
+ // rebuild it triggers) settles. A throw inside one accept must not break the chain.
414
+ const agentName = localAgent.name;
415
+ inboundAcceptChain = inboundAcceptChain
416
+ .then(() => acceptInboundAssignment(parsed, agentName, correlationId))
417
+ .catch((err) => {
418
+ inboundInFlight.delete(offerKey(localAgent.name, parsed.sessionIdHex));
419
+ logger.error("session.inbound.accept.error", {
420
+ sessionId: parsed.sessionIdHex,
421
+ agentName,
422
+ error: err instanceof Error ? err.message : String(err),
423
+ correlationId,
424
+ });
425
+ });
426
+ }
427
+ // CELLO-M7-CONN-001 (DOD-CONN-2): wire the inbound session/seal responders onto a GIVEN
428
+ // signaling manager. Called for EVERY agent's own per-agent manager (via getAgentSignaling)
429
+ // so each agent receives inbound session_assignment + seal_interrupted_request on its OWN
430
+ // authenticated stream — closing the SPINE-5 gap where only the primary (whose stream WAS
431
+ // the keystone) received them. A frame arrives on exactly one agent's stream, so there is no
432
+ // double-dispatch; each handler resolves the local agent internally and that resolution
433
+ // matches the stream the directory routed the frame to.
434
+ // CELLO-M8-TRUST-001: open + verify + store + ACK a sealed trust signal pushed from the directory
435
+ // pickup queue. The daemon is the ONLY party that can open the seal (k_local — SI-001); it verifies
436
+ // the recomputed hash against the directory's anchor before storing, and ACKs only on success so the
437
+ // directory deletes the ciphertext (AC-001/AC-002). open-fail / hash-mismatch / store-fail → NO ACK
438
+ // (the directory keeps the pickup for a later retry; the signal is re-mintable).
439
+ async function handleTrustSignalPickup(frame, keyProvider, mgr, agentName) {
440
+ const id = typeof frame["id"] === "string" ? frame["id"] : null;
441
+ const signalKind = typeof frame["signal_kind"] === "string" ? frame["signal_kind"] : null;
442
+ const signalHash = typeof frame["signal_hash"] === "string" ? frame["signal_hash"] : null;
443
+ const ciphertext = frame["ciphertext"];
444
+ if (!id || !signalKind || !signalHash || !(ciphertext instanceof Uint8Array)) {
445
+ // Neither stores nor ACKs → the directory retains the row and re-delivers. Log it: a PERMANENTLY
446
+ // malformed frame would otherwise be re-delivered forever with zero daemon-side signal (fallback-finder).
447
+ logger.warn("daemon.trust_signal.malformed", {
448
+ agentName,
449
+ hasId: !!id,
450
+ hasSignalKind: !!signalKind,
451
+ hasSignalHash: !!signalHash,
452
+ ciphertextOk: ciphertext instanceof Uint8Array,
453
+ });
454
+ return;
455
+ }
456
+ if (!keyProvider.openContentSeal) {
457
+ // A session-node stub key cannot open content seals. No ACK → the directory re-delivers; log so a
458
+ // pickup persistently routed to a stub-key agent is visible rather than a silent forever-retry.
459
+ logger.warn("daemon.trust_signal.no_content_key", { agentName, signalKind, correlationId: id });
460
+ return;
461
+ }
462
+ // The pickup id correlates the directory's deliver/ack with the daemon's receive (TRUST-001 obs).
463
+ const correlationId = id;
464
+ let recovered;
465
+ try {
466
+ recovered = await keyProvider.openContentSeal(ciphertext);
467
+ }
468
+ catch {
469
+ recovered = null;
470
+ }
471
+ if (!recovered) {
472
+ logger.warn("daemon.trust_signal.open_failed", { agentName, signalKind, correlationId });
473
+ return;
474
+ }
475
+ const recomputed = Buffer.from(cryptoHash(recovered)).toString("hex");
476
+ if (recomputed !== signalHash) {
477
+ logger.error("daemon.trust_signal.hash_mismatch", { agentName, signalKind, correlationId });
478
+ return;
479
+ }
480
+ try {
481
+ const store = new DbIdentityStore(sessionNodeManager.getDb(), logger);
482
+ store.storeTrustSignal({ signalHash, agentId: null, signalKind, payload: recovered });
483
+ }
484
+ catch (err) {
485
+ logger.error("daemon.trust_signal.store_failed", {
486
+ agentName,
487
+ signalKind,
488
+ correlationId,
489
+ error: err instanceof Error ? err.message : String(err),
490
+ });
491
+ return;
492
+ }
493
+ logger.info("daemon.trust_signal.received", { agentName, signalKind, verified: true, correlationId });
494
+ // DOD-SENDRAW-1: sendRaw never throws — a discarded result hid every failed ack, leaving the
495
+ // sender to retransmit against a daemon that believed it had answered.
496
+ const ackRes = await mgr.sendRaw({ type: "trust_signal_ack", id });
497
+ if (!ackRes.ok) {
498
+ logger.warn("daemon.trust_signal.ack_send_failed", {
499
+ agentName,
500
+ signalKind,
501
+ correlationId,
502
+ detail: ackRes.reason ?? "send_not_ok",
503
+ ...(ackRes.guidance ? { guidance: ackRes.guidance } : {}),
504
+ });
505
+ }
506
+ }
507
+ function wirePerAgentSessionInbound(mgr) {
508
+ mgr.registerInboundHandler((frame) => {
509
+ if (frame["type"] !== "seal_interrupted_request")
510
+ return;
511
+ void handleInboundSealInterruptedRequest(frame);
512
+ });
513
+ mgr.registerInboundHandler((frame) => {
514
+ if (frame["type"] !== "session_assignment")
515
+ return;
516
+ handleInboundSessionAssignment(frame);
517
+ });
518
+ }
519
+ // CONN-001: test path only — the shared manager's inbound session/seal responders. Production
520
+ // wires them per-agent in getAgentSignaling (each agent receives on its own stream).
521
+ if (sharedSignaling)
522
+ wirePerAgentSessionInbound(sharedSignaling);
523
+ // M7 DOD-SPINE-7 / CELLO-M7-CONN-001: the seal-completion listeners (session_sealed /
524
+ // seal_unilateral_confirmed / seal_unilateral_notification) are registered PER-AGENT inside
525
+ // getAgentSignaling (the directory routes each over the session-owning agent's authenticated
526
+ // stream), and on the shared manager for the test path via wireSharedHandlers. No keystone, no
527
+ // runtime election — a fresh-install agent gets them when it comes online (create/start).
528
+ /**
529
+ * Phase 2: register the IPC handler, once the handler map exists.
530
+ *
531
+ * Split from construction because this module is constructed EARLY — the per-agent signaling
532
+ * wiring calls into it at boot, before the handler map is built. Fusing the two would force
533
+ * construction after the map, which pushes the eager per-agent connect below
534
+ * `await flushAwaitingContent()` and serializes every agent's directory handshake behind a
535
+ * relay drain. Same pattern as content-park.ts.
536
+ */
537
+ function registerHandlers(handlers) {
538
+ // cello_await_session — the counterparty's blocking pull for the next inbound session.
539
+ // Returns immediately if one is already queued for the current agent (FIFO), otherwise
540
+ // blocks until one arrives or timeout_ms elapses.
541
+ handlers.set("cello_await_session", async (params, connectionId) => {
542
+ const connState = getConnState(connectionId);
543
+ // CC-3 / M8C-AUTOSTART-1 F18: resolve the target agent — explicit { agent } wins, else this
544
+ // connection's current agent, else the sole online agent (removes the no_current_agent papercut
545
+ // after a /mcp reconnect when exactly one agent is online). 2+ online with none selected → null.
546
+ const agentName = resolveCurrentAgent(connState, params?.agent);
547
+ if (!agentName) {
548
+ return NO_CURRENT_AGENT_RESPONSE;
549
+ }
550
+ const timeoutMs = typeof params?.["timeout_ms"] === "number" ? params["timeout_ms"] : 30_000;
551
+ const toResponse = (e) => ({
552
+ type: "new_session",
553
+ session_id: e.sessionIdHex,
554
+ counterparty_pubkey: e.counterpartyPubkeyHex,
555
+ genesis_prev_root: e.genesisPrevRootHex,
556
+ // MONIKER-2: validated-at-boundary display hint; null = absent or rejected.
557
+ offered_moniker: e.offeredMoniker ?? null,
558
+ });
559
+ reapExpiredInboundSessions(agentName); // M8C-TTL-1: don't hand back a stale expired entry
560
+ const queued = inboundSessionQueues.get(agentName);
561
+ if (queued && queued.length > 0) {
562
+ return toResponse(queued.shift());
563
+ }
564
+ const event = await new Promise((resolve) => {
565
+ const waiters = inboundSessionWaiters.get(agentName) ?? [];
566
+ const waiter = {
567
+ connectionId,
568
+ deliver: (e) => {
569
+ clearTimeout(timer);
570
+ resolve(e);
571
+ },
572
+ };
573
+ waiters.push(waiter);
574
+ inboundSessionWaiters.set(agentName, waiters);
575
+ const timer = setTimeout(() => {
576
+ const list = inboundSessionWaiters.get(agentName);
577
+ if (list) {
578
+ const idx = list.indexOf(waiter);
579
+ if (idx !== -1)
580
+ list.splice(idx, 1);
581
+ }
582
+ resolve(null);
583
+ }, timeoutMs);
584
+ });
585
+ if (event === null)
586
+ return { type: "timeout" };
587
+ return toResponse(event);
588
+ });
589
+ }
590
+ return {
591
+ registerHandlers,
592
+ wirePerAgentSessionInbound,
593
+ handleTrustSignalPickup,
594
+ enqueueInboundSession,
595
+ reapExpiredInboundSessions,
596
+ inboundSessionQueues,
597
+ inboundSessionWaiters,
598
+ expiredSessionRequests,
599
+ offeredMonikers,
600
+ offerKey,
601
+ };
602
+ }
603
+ //# sourceMappingURL=inbound-sessions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inbound-sessions.js","sourceRoot":"","sources":["../src/inbound-sessions.ts"],"names":[],"mappings":"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"}