@cello-protocol/daemon 0.0.3 → 0.0.5

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 (153) hide show
  1. package/dist/agent-loader.d.ts +41 -0
  2. package/dist/agent-loader.d.ts.map +1 -0
  3. package/dist/agent-loader.js +94 -0
  4. package/dist/agent-loader.js.map +1 -0
  5. package/dist/bin/cello-daemon.d.ts +13 -0
  6. package/dist/bin/cello-daemon.d.ts.map +1 -0
  7. package/dist/bin/cello-daemon.js +170 -0
  8. package/dist/bin/cello-daemon.js.map +1 -0
  9. package/dist/cello-node-transport-dialer.d.ts +59 -0
  10. package/dist/cello-node-transport-dialer.d.ts.map +1 -0
  11. package/dist/cello-node-transport-dialer.js +108 -0
  12. package/dist/cello-node-transport-dialer.js.map +1 -0
  13. package/dist/challenge-verifier.d.ts +12 -0
  14. package/dist/challenge-verifier.d.ts.map +1 -0
  15. package/dist/challenge-verifier.js +11 -0
  16. package/dist/challenge-verifier.js.map +1 -0
  17. package/dist/connect-or-start.d.ts +25 -0
  18. package/dist/connect-or-start.d.ts.map +1 -0
  19. package/dist/connect-or-start.js +117 -0
  20. package/dist/connect-or-start.js.map +1 -0
  21. package/dist/content-park-client.d.ts +49 -0
  22. package/dist/content-park-client.d.ts.map +1 -0
  23. package/dist/content-park-client.js +196 -0
  24. package/dist/content-park-client.js.map +1 -0
  25. package/dist/daemon.d.ts +65 -0
  26. package/dist/daemon.d.ts.map +1 -0
  27. package/dist/daemon.js +3202 -0
  28. package/dist/daemon.js.map +1 -0
  29. package/dist/directory-bootstrap.d.ts +55 -0
  30. package/dist/directory-bootstrap.d.ts.map +1 -0
  31. package/dist/directory-bootstrap.js +102 -0
  32. package/dist/directory-bootstrap.js.map +1 -0
  33. package/dist/file-manifest-provider.d.ts +18 -0
  34. package/dist/file-manifest-provider.d.ts.map +1 -0
  35. package/dist/file-manifest-provider.js +72 -0
  36. package/dist/file-manifest-provider.js.map +1 -0
  37. package/dist/index.d.ts +18 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +18 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/ipc-client.d.ts +31 -0
  42. package/dist/ipc-client.d.ts.map +1 -0
  43. package/dist/ipc-client.js +112 -0
  44. package/dist/ipc-client.js.map +1 -0
  45. package/dist/ipc-server.d.ts +49 -0
  46. package/dist/ipc-server.d.ts.map +1 -0
  47. package/dist/ipc-server.js +268 -0
  48. package/dist/ipc-server.js.map +1 -0
  49. package/dist/lock-file.d.ts +27 -0
  50. package/dist/lock-file.d.ts.map +1 -0
  51. package/dist/lock-file.js +84 -0
  52. package/dist/lock-file.js.map +1 -0
  53. package/dist/manifest-loader.d.ts +33 -0
  54. package/dist/manifest-loader.d.ts.map +1 -0
  55. package/dist/manifest-loader.js +70 -0
  56. package/dist/manifest-loader.js.map +1 -0
  57. package/dist/manifest-poll-scheduler.d.ts +31 -0
  58. package/dist/manifest-poll-scheduler.d.ts.map +1 -0
  59. package/dist/manifest-poll-scheduler.js +59 -0
  60. package/dist/manifest-poll-scheduler.js.map +1 -0
  61. package/dist/manifest-version-store-file.d.ts +18 -0
  62. package/dist/manifest-version-store-file.d.ts.map +1 -0
  63. package/dist/manifest-version-store-file.js +40 -0
  64. package/dist/manifest-version-store-file.js.map +1 -0
  65. package/dist/manifest-version-store.d.ts +14 -0
  66. package/dist/manifest-version-store.d.ts.map +1 -0
  67. package/dist/manifest-version-store.js +13 -0
  68. package/dist/manifest-version-store.js.map +1 -0
  69. package/dist/network-directory-node.d.ts +94 -0
  70. package/dist/network-directory-node.d.ts.map +1 -0
  71. package/dist/network-directory-node.js +626 -0
  72. package/dist/network-directory-node.js.map +1 -0
  73. package/dist/nonce-dedup.d.ts +68 -0
  74. package/dist/nonce-dedup.d.ts.map +1 -0
  75. package/dist/nonce-dedup.js +204 -0
  76. package/dist/nonce-dedup.js.map +1 -0
  77. package/dist/notification-dispatcher.d.ts +65 -0
  78. package/dist/notification-dispatcher.d.ts.map +1 -0
  79. package/dist/notification-dispatcher.js +138 -0
  80. package/dist/notification-dispatcher.js.map +1 -0
  81. package/dist/registration-context.d.ts +69 -0
  82. package/dist/registration-context.d.ts.map +1 -0
  83. package/dist/registration-context.js +118 -0
  84. package/dist/registration-context.js.map +1 -0
  85. package/dist/registration-manager.d.ts +72 -0
  86. package/dist/registration-manager.d.ts.map +1 -0
  87. package/dist/registration-manager.js +267 -0
  88. package/dist/registration-manager.js.map +1 -0
  89. package/dist/registration-persistence.d.ts +131 -0
  90. package/dist/registration-persistence.d.ts.map +1 -0
  91. package/dist/registration-persistence.js +233 -0
  92. package/dist/registration-persistence.js.map +1 -0
  93. package/dist/retry-queue.d.ts +144 -0
  94. package/dist/retry-queue.d.ts.map +1 -0
  95. package/dist/retry-queue.js +444 -0
  96. package/dist/retry-queue.js.map +1 -0
  97. package/dist/seal-frontier-verify.d.ts +58 -0
  98. package/dist/seal-frontier-verify.d.ts.map +1 -0
  99. package/dist/seal-frontier-verify.js +87 -0
  100. package/dist/seal-frontier-verify.js.map +1 -0
  101. package/dist/seal-legibility-tbs.d.ts +25 -0
  102. package/dist/seal-legibility-tbs.d.ts.map +1 -0
  103. package/dist/seal-legibility-tbs.js +78 -0
  104. package/dist/seal-legibility-tbs.js.map +1 -0
  105. package/dist/seal-upgrade.d.ts +90 -0
  106. package/dist/seal-upgrade.d.ts.map +1 -0
  107. package/dist/seal-upgrade.js +178 -0
  108. package/dist/seal-upgrade.js.map +1 -0
  109. package/dist/session-assignment-parser.d.ts +22 -0
  110. package/dist/session-assignment-parser.d.ts.map +1 -0
  111. package/dist/session-assignment-parser.js +139 -0
  112. package/dist/session-assignment-parser.js.map +1 -0
  113. package/dist/session-ceremony.d.ts +156 -0
  114. package/dist/session-ceremony.d.ts.map +1 -0
  115. package/dist/session-ceremony.js +447 -0
  116. package/dist/session-ceremony.js.map +1 -0
  117. package/dist/session-connection-gater.d.ts +91 -0
  118. package/dist/session-connection-gater.d.ts.map +1 -0
  119. package/dist/session-connection-gater.js +146 -0
  120. package/dist/session-connection-gater.js.map +1 -0
  121. package/dist/session-node-manager.d.ts +585 -0
  122. package/dist/session-node-manager.d.ts.map +1 -0
  123. package/dist/session-node-manager.js +2609 -0
  124. package/dist/session-node-manager.js.map +1 -0
  125. package/dist/session-relay-client.d.ts +101 -0
  126. package/dist/session-relay-client.d.ts.map +1 -0
  127. package/dist/session-relay-client.js +520 -0
  128. package/dist/session-relay-client.js.map +1 -0
  129. package/dist/session-tree.d.ts +80 -0
  130. package/dist/session-tree.d.ts.map +1 -0
  131. package/dist/session-tree.js +123 -0
  132. package/dist/session-tree.js.map +1 -0
  133. package/dist/signaling-connect.d.ts +83 -0
  134. package/dist/signaling-connect.d.ts.map +1 -0
  135. package/dist/signaling-connect.js +266 -0
  136. package/dist/signaling-connect.js.map +1 -0
  137. package/dist/transcript-cipher.d.ts +31 -0
  138. package/dist/transcript-cipher.d.ts.map +1 -0
  139. package/dist/transcript-cipher.js +74 -0
  140. package/dist/transcript-cipher.js.map +1 -0
  141. package/dist/transport-composition.d.ts +31 -0
  142. package/dist/transport-composition.d.ts.map +1 -0
  143. package/dist/transport-composition.js +55 -0
  144. package/dist/transport-composition.js.map +1 -0
  145. package/dist/transport-selector.d.ts +189 -0
  146. package/dist/transport-selector.d.ts.map +1 -0
  147. package/dist/transport-selector.js +195 -0
  148. package/dist/transport-selector.js.map +1 -0
  149. package/dist/types.d.ts +265 -0
  150. package/dist/types.d.ts.map +1 -0
  151. package/dist/types.js +33 -0
  152. package/dist/types.js.map +1 -0
  153. package/package.json +4 -4
@@ -0,0 +1,585 @@
1
+ /**
2
+ * CELLO Daemon — SessionNodeManager
3
+ *
4
+ * Manages the lifecycle of all ephemeral session nodes:
5
+ * 1. Per-session nodes: fresh transport key + Peer ID, connectionGater allows
6
+ * only the designated counterparty. Created during cello_initiate_session
7
+ * (outbound) or cello_await_session (inbound, via standing receiver handoff).
8
+ * 2. Standing receiver node: pre-created, open gater, kept alive at all times.
9
+ * Handed to the first inbound session; immediately replaced.
10
+ * 3. 32-node cap: enforced before any new node is created.
11
+ * 4. Session status in SQLite: active → sealed (on close) or interrupted
12
+ * (on graceful shutdown or SIGKILL-restart detection).
13
+ *
14
+ * Pseudocode (SPARC Phase P):
15
+ *
16
+ * initialize():
17
+ * 1. Open SQLite (node:sqlite), create sessions table if not exists
18
+ * 2. Detect interrupted sessions: SELECT * FROM sessions WHERE status='active'
19
+ * → batch-update to 'interrupted', log session.interrupted.detected for each
20
+ * (source: 'daemon_restart') — runs before IPC socket opens so no race
21
+ * 3. Create standing receiver node (fresh libp2p, open gater, sentinel agentName)
22
+ * 4. Start standing receiver, set standingReceiverReady=true
23
+ * 5. Log session.node.created for the standing receiver
24
+ *
25
+ * createSessionNode(sessionId, agentName, counterpartyPubkey, counterpartyPeerId, correlationId):
26
+ * Pseudocode:
27
+ * 1. Check activeNodes.size >= MAX_SESSION_NODES → log cap.reached, return error
28
+ * 2. Create SessionConnectionGater(counterpartyPeerId) — restricted from birth
29
+ * 3. nodeFactory.createNode({gater}) → fresh libp2p node
30
+ * 4. node.start() — bind TCP ephemeral port
31
+ * 5. Insert SQLite row status='active'
32
+ * 6. Log session.node.created
33
+ * 7. Add to activeNodes map
34
+ * 8. Return {ok:true, peerId, addrs}
35
+ * On libp2p error: extract error.message (never ${error}), log create.failed, return error
36
+ *
37
+ * acceptSession(sessionId, agentName, counterpartyPubkey, initiatorPeerId, correlationId):
38
+ * Pseudocode:
39
+ * 1. If !standingReceiverReady → return standing_receiver_unavailable
40
+ * 2. Take standing receiver from slot (clear slot atomically)
41
+ * 3. gater.setAllowedPeer(initiatorPeerId) ← BEFORE returning multiaddr (AC-015)
42
+ * 4. Insert SQLite row status='active'
43
+ * 5. Log session.node.created
44
+ * 6. Add to activeNodes map
45
+ * 7. Trigger async replacement of standing receiver (do NOT await)
46
+ * 8. Return {ok:true, peerId, addrs}
47
+ *
48
+ * destroySessionNode(sessionId, reason):
49
+ * Pseudocode:
50
+ * 1. Find node in activeNodes
51
+ * 2. stop node
52
+ * 3. Update SQLite status to sealed/interrupted/error
53
+ * 4. Remove from activeNodes
54
+ * 5. Log session.node.destroyed
55
+ *
56
+ * gracefulShutdown():
57
+ * Pseudocode:
58
+ * 1. Get all activeNodes
59
+ * 2. For each: update SQLite 'interrupted', log destroyed(reason:'interrupted')
60
+ * 3. Stop all nodes
61
+ * 4. Stop standing receiver
62
+ *
63
+ * getStatus(): { standingReceiverReady: boolean }
64
+ */
65
+ import { DatabaseSync } from "node:sqlite";
66
+ import { TranscriptCipher } from "./transcript-cipher.js";
67
+ import type { Stream } from "@libp2p/interface";
68
+ import type { Logger, SessionRecord } from "./types.js";
69
+ import { SessionConnectionGater } from "./session-connection-gater.js";
70
+ import { SessionTree, type SessionTreeLeafKind } from "./session-tree.js";
71
+ import { type CelloNode, type IAutoNatService } from "@cello-protocol/transport";
72
+ import type { KeyProvider } from "@cello-protocol/crypto";
73
+ /**
74
+ * M7 DOD-SPINE-6 / MSG-001-3b: the inputs a session node needs to connect to the relay
75
+ * as the Structure-2 witness (relay endpoint from the FROST-signed assignment + the
76
+ * agent's K_local identity + the 16-byte session id). Optional on node creation: when
77
+ * absent (or connect fails), the session still works over the direct content path — the
78
+ * relay just doesn't witness the leaf yet.
79
+ */
80
+ export interface RelayConnectParams {
81
+ relayPeerId: string;
82
+ relayAddrs: string[];
83
+ keyProvider: KeyProvider;
84
+ senderPubkey: Uint8Array;
85
+ sessionIdBytes: Uint8Array;
86
+ }
87
+ /**
88
+ * Adapter interface for session node creation. Allows test injection of a
89
+ * failing factory (AC-007) without touching the real libp2p stack.
90
+ * The adapter pattern is mandatory per outline.md constraints.
91
+ */
92
+ export interface ISessionNodeFactory {
93
+ createNode(config: SessionNodeConfig): Promise<CelloNode>;
94
+ }
95
+ export interface SessionNodeConfig {
96
+ sessionId: string;
97
+ connectionGater?: SessionConnectionGater;
98
+ /**
99
+ * CELLO-M7-TRANSPORT-001: role of the node, forwarded to createNode to tune the
100
+ * libp2p service set (dcutr is included for 'session' dialers, omitted for the
101
+ * 'standing_receiver'). AutoNAT is present for both.
102
+ */
103
+ nodeType?: "session" | "standing_receiver";
104
+ /**
105
+ * M7-SESSION-003 (AC-005): keepalive ping interval for the session node so a
106
+ * counterparty that vanishes without a clean close is detected within a bounded
107
+ * window. Factories should forward this to createNode({ keepAliveIntervalMs }).
108
+ */
109
+ keepAliveIntervalMs?: number;
110
+ }
111
+ /** DAEMON-004: a piece of content received and verified, awaiting cello_receive. */
112
+ interface ReceivedContentEntry {
113
+ contentHex: string;
114
+ senderPubkey: string;
115
+ sequenceNumber: number;
116
+ }
117
+ type CreateSessionResult = {
118
+ ok: true;
119
+ peerId: string;
120
+ addrs: string[];
121
+ } | {
122
+ ok: false;
123
+ reason: string;
124
+ guidance: string;
125
+ };
126
+ export declare class SessionNodeManager {
127
+ #private;
128
+ constructor(opts: {
129
+ factory: ISessionNodeFactory;
130
+ logger: Logger;
131
+ dbPath: string;
132
+ contentTtfMs?: number;
133
+ /**
134
+ * CELLO-M7-TRANSPORT-001: provider for the AutoNAT directory-node prober set
135
+ * (SI-002). Defaults to () => [] (reconnecting — no probers), which makes
136
+ * dialability the conservative default and fires transport.autonat.unavailable.
137
+ */
138
+ autoNatProbers?: () => string[];
139
+ });
140
+ /**
141
+ * CELLO-M7-MSG-001: wire the durable-backstop side effects of the awaiting-ACK
142
+ * lifecycle. `onPersisted` clears the durable retry_queue entry when a persisted ACK
143
+ * arrives; `onTtf` records/parks the un-acked content when the TTF timer fires.
144
+ * Injected by the composition root (daemon.ts) after the RetryQueue exists.
145
+ */
146
+ setAwaitingAckHooks(hooks: {
147
+ onPersisted?: (agentName: string, sessionId: string, contentHashHex: string) => void;
148
+ onTtf?: (agentName: string, sessionId: string, contentHashHex: string, content: Uint8Array) => void;
149
+ }): void;
150
+ /**
151
+ * MSG-001-3b (2b): inject the live content-park deposit (seal + ContentParkClient.deposit).
152
+ * Injected by the composition root (daemon.ts). When absent, a not-confirmed send still records
153
+ * the durable awaiting entry (crash backstop) but does not deposit live.
154
+ */
155
+ setContentParkHook(fn: (args: {
156
+ sessionId: string;
157
+ recipientPubkeyHex: string;
158
+ relayPeerId: string;
159
+ relayAddrs: readonly string[];
160
+ contentHashHex: string;
161
+ content: Uint8Array;
162
+ structure1Cbor?: Uint8Array;
163
+ structure2Cbor?: Uint8Array;
164
+ }) => Promise<void>): void;
165
+ initialize(): Promise<void>;
166
+ /**
167
+ * Get the underlying DatabaseSync handle.
168
+ * Used by the composition root (daemon.ts) to pass to RetryQueue and
169
+ * NonceDedupStore — they share the same SQLCipher DB file (DAEMON-003 AC-008).
170
+ */
171
+ getDb(): DatabaseSync;
172
+ /**
173
+ * DOD-LOG-1: the at-rest cipher, shared with the RetryQueue so its content_blob is encrypted with
174
+ * the SAME key as the transcript. Available after initialize().
175
+ */
176
+ getTranscriptCipher(): TranscriptCipher;
177
+ /**
178
+ * DOD-LOG-1: append one readable message to the durable, encrypted-at-rest transcript, keyed by
179
+ * the canonical leaf `sequence` so it joins to the committed hash chain. Idempotent on replay
180
+ * (INSERT OR IGNORE — the same (session, sequence, direction) is written at most once). Never
181
+ * throws into the caller's content path: a transcript-write failure is logged, not fatal.
182
+ */
183
+ recordTranscriptMessage(agentName: string, sessionId: string, sequence: number, direction: "sent" | "received", plaintext: Uint8Array, correlationId?: string): void;
184
+ /**
185
+ * DOD-LOG-1: read a session's durable transcript back (after a restart), decrypted and ordered by
186
+ * canonical sequence then direction. A blob that fails to decrypt (tamper/wrong key) is skipped
187
+ * with a loud log rather than crashing the read.
188
+ */
189
+ readTranscript(agentName: string, sessionId: string): {
190
+ messages: Array<{
191
+ sequence: number;
192
+ direction: "sent" | "received";
193
+ text: string;
194
+ createdAt: number;
195
+ }>;
196
+ undecryptable: number;
197
+ };
198
+ /** DOD-LOOP-1: whether the given agent has a standing receiver ready (any agent if omitted). */
199
+ getStandingReceiverReady(agentName?: string): boolean;
200
+ /**
201
+ * The current standing receiver node's session-transport coordinates (peer id +
202
+ * listen multiaddrs), or null if it is not ready. These are the addresses a local
203
+ * SessionNegotiator advertises as this node's counterparty endpoint so the initiator
204
+ * can dial it, and the value an inbound session_assignment carries in its
205
+ * counterparty_session_* fields. Read-only — does NOT consume the standing receiver
206
+ * (unlike acceptSession, which hands it off).
207
+ */
208
+ getStandingReceiverInfo(agentName: string): {
209
+ peerId: string;
210
+ addrs: string[];
211
+ } | null;
212
+ /**
213
+ * The standing receiver's libp2p node — a general-purpose, OPEN-gater node usable for
214
+ * OUTBOUND dials that are not session-scoped (e.g. the content-park deposit/pull to the
215
+ * relay, MSG-001-3b). Session nodes have restrictive gaters; the standing receiver does not.
216
+ * Returns null until the receiver is ready.
217
+ */
218
+ getStandingReceiverNode(agentName?: string): CelloNode | null;
219
+ /**
220
+ * The libp2p Peer ID of an active session's node (N_A for an initiated session), or
221
+ * null if no active node exists for it. This is the initiator's session peer id that an
222
+ * inbound session_assignment must carry to the counterparty (so the counterparty gates
223
+ * its handed-off receiver to it). Read-only.
224
+ */
225
+ getSessionNodePeerId(agentName: string, sessionId: string): string | null;
226
+ /**
227
+ * CELLO-M7-TRANSPORT-001: the AutoNAT service wrapping the current standing
228
+ * receiver node, or null if the standing receiver is not ready. The composition
229
+ * root uses this as the daemon's runtime IAutoNatService — its getDialability()
230
+ * drives the SessionAssignment advertised address (AC-004/AC-019), and it is the
231
+ * source of the transport.autonat.result / transport.autonat.unavailable events.
232
+ */
233
+ getStandingReceiverAutoNat(): IAutoNatService | null;
234
+ /**
235
+ * M7-SESSION-001 (M-1 PUSH): register the session-state-change callback.
236
+ * Called by the composition root (daemon.ts) after the NotificationDispatcher
237
+ * exists. Setter injection avoids a construction-order/circular dependency.
238
+ */
239
+ setOnSessionStateChanged(cb: (agentName: string, sessionId: string, state: string, counterpartyPubkey: string | null) => void): void;
240
+ /**
241
+ * Create a new outbound session node.
242
+ * Called during cello_initiate_session.
243
+ *
244
+ * @param sessionId Unique session ID (hex string)
245
+ * @param agentName Name of the initiating agent
246
+ * @param counterpartyPubkey Counterparty's K_local public key (hex)
247
+ * @param counterpartyPeerId Counterparty's session-layer Peer ID (for gater)
248
+ * @param correlationId Correlation ID minted at session initiation
249
+ */
250
+ createSessionNode(sessionId: string, agentName: string, counterpartyPubkey: string, counterpartyPeerId: string, correlationId: string, reuseStandingReceiver?: boolean, relay?: RelayConnectParams): Promise<CreateSessionResult>;
251
+ /**
252
+ * M7-SESSION-003: read the direct-path counterparty liveness for a session.
253
+ * 'unknown' when no session node observation has occurred yet.
254
+ */
255
+ getSessionLiveness(agentName: string, sessionId: string): "alive" | "gone" | "unknown";
256
+ /**
257
+ * Hand the standing receiver to an inbound session.
258
+ * Called during cello_await_session.
259
+ *
260
+ * CRITICAL (AC-015): gater.setAllowedPeer() is called BEFORE returning
261
+ * the node's multiaddr to the caller. This closes the window where an
262
+ * unexpected peer could connect during the hand-off.
263
+ */
264
+ acceptSession(sessionId: string, agentName: string, counterpartyPubkey: string, initiatorPeerId: string, correlationId: string, relay?: RelayConnectParams): Promise<CreateSessionResult>;
265
+ /**
266
+ * Destroy a session node after seal or on error teardown.
267
+ * Status written to SQLite.
268
+ */
269
+ destroySessionNode(agentName: string, sessionId: string, reason: "sealed" | "interrupted" | "error"): Promise<void>;
270
+ /**
271
+ * round-2 finding #5: retire a session's live libp2p node WITHOUT changing its
272
+ * DB status. Used after the active-session bilateral seal commitment has already
273
+ * advanced the row to 'seal_interrupted_pending': the session is frozen, so we
274
+ * stop the node and unregister its /cello/content handler (no more inbound leaves,
275
+ * no leaked node per active close) but must NOT overwrite the pending/sealed status
276
+ * the way destroySessionNode would. The durable tree stays in SQLite (getSessionTree
277
+ * reloads it); the in-memory plaintext buffer is evicted.
278
+ */
279
+ retireSessionNode(agentName: string, sessionId: string): Promise<void>;
280
+ /**
281
+ * Graceful shutdown: mark all active sessions as interrupted, stop all nodes.
282
+ * Called from the SIGTERM / cello logout path (AC-009).
283
+ * SQLite writes complete before this method returns.
284
+ */
285
+ gracefulShutdown(): Promise<void>;
286
+ /**
287
+ * Return all sessions with a given status from SQLite.
288
+ * Used by cello status to surface interrupted sessions.
289
+ */
290
+ getSessionsByStatus(status: "active" | "sealed" | "interrupted"): SessionRecord[];
291
+ /**
292
+ * M7-SESSION-004 (AC-005): persist the seal certificate's legibility object with the
293
+ * sealed record. Stored as a JSON string (hex-encoded pubkeys) so it round-trips a
294
+ * daemon restart and is returned intact on the cert-read surface. The caller normalises
295
+ * the raw wire legibility (Uint8Array pubkeys) into a JSON-safe shape before storing.
296
+ * Best-effort: a session row may not yet exist (the seal arrived before the row was
297
+ * persisted); in that case we no-op rather than throw — the cert still flows through the
298
+ * live return path. The legibility content is identical regardless of delivery timing.
299
+ */
300
+ recordSealCertificate(agentName: string, sessionId: string, sealedRootHex: string, legibilityJson: string): void;
301
+ /**
302
+ * M7 legibility-TBS-binding (responder verify): record the counterparty's FROST primary (group)
303
+ * pubkey from the FROST-signed SessionAssignment, so the responder can VERIFY the bilateral seal
304
+ * signature locally. Best-effort — a missing row (race) is a no-op; the seal then falls back to
305
+ * accept-without-verify (still sound: the live frame arrives over the authenticated Noise channel).
306
+ */
307
+ recordCounterpartyPrimary(agentName: string, sessionId: string, primaryPubkeyHex: string): void;
308
+ /**
309
+ * M7-SESSION-004 (AC-005/AC-006): read the persisted seal certificate for a session.
310
+ * Returns the sealed root and the parsed legibility object (JSON-safe, hex pubkeys), or
311
+ * null if the session is unknown or not yet sealed. This is the cert-read surface a
312
+ * reader (operator, agent, arbitrator) — possibly in a DIFFERENT process than the one
313
+ * that built the certificate — uses to determine receipt-not-assent, per-party frontiers,
314
+ * attestation modes, and whether the final message was answered.
315
+ */
316
+ getSealCertificate(agentName: string, sessionId: string): {
317
+ sealed_root: string;
318
+ legibility: unknown;
319
+ } | null;
320
+ /**
321
+ * M7-SESSION-001: Mark a session as interrupted with message count and timestamp.
322
+ * Called when a relay session_interrupted frame arrives or a relay stream closes.
323
+ * Also tears down the in-memory session node if one exists for this sessionId.
324
+ *
325
+ * @param sessionId The hex session ID from the relay frame
326
+ * @param messageCount Number of message leaves at interruption
327
+ * @param source 'relay_frame' | 'stream_close'
328
+ */
329
+ markInterruptedWithDetails(agentName: string, sessionId: string, messageCount: number, source: "relay_frame" | "stream_close"): Promise<void>;
330
+ /**
331
+ * M7-SESSION-001 (H-1): persist a verified bilateral SEAL-INTERRUPTED
332
+ * commitment and transition the session to 'seal_interrupted_pending'.
333
+ *
334
+ * This is NOT a seal. It records that both parties produced and exchanged
335
+ * K_local-signed SEAL-INTERRUPTED leaves over the same {leafCount, merkleRoot}.
336
+ * The FROST threshold notarization is a separate, currently-unwired step (see
337
+ * daemon.ts handleSealInterruptedFlow H-1 note), which is precisely why the
338
+ * status is 'seal_interrupted_pending' and never 'sealed'.
339
+ *
340
+ * The status update is guarded so it only advances a session out of the
341
+ * 'interrupted' state — it will not overwrite a 'sealed' row.
342
+ *
343
+ * @returns true if the session row was advanced to seal_interrupted_pending.
344
+ */
345
+ persistSealInterruptedCommitment(opts: {
346
+ agentName: string;
347
+ sessionId: string;
348
+ role: "initiator" | "responder";
349
+ ownLeaf: unknown;
350
+ counterpartyLeaf: unknown;
351
+ merkleRoot: string;
352
+ nonce: string;
353
+ }): boolean;
354
+ /**
355
+ * M7-SESSION-001 (H-1): read back the persisted bilateral commitment artifacts
356
+ * for a session. Returns null when none exist.
357
+ */
358
+ getSealInterruptedArtifacts(agentName: string, sessionId: string): {
359
+ role: string;
360
+ ownLeaf: unknown;
361
+ counterpartyLeaf: unknown;
362
+ merkleRoot: string;
363
+ nonce: string;
364
+ } | null;
365
+ /**
366
+ * Return the session record for a specific sessionId, regardless of status.
367
+ * Used by cello_close_session to inspect session state.
368
+ */
369
+ getSessionRecord(agentName: string, sessionId: string): SessionRecord | null;
370
+ /**
371
+ * MSG-2 startup-flush: the persisted relay endpoint for a session, or null if none was
372
+ * recorded. Used by the crash-backstop flush, which runs at startup BEFORE the in-memory
373
+ * session entries exist, so it cannot use `entry.relayPeerId`.
374
+ */
375
+ getPersistedRelayEndpoint(agentName: string, sessionId: string): {
376
+ relayPeerId: string;
377
+ relayAddrs: string[];
378
+ } | null;
379
+ /**
380
+ * DOD-MSG-4 (auto-recover): the DISTINCT relay endpoints this agent has sessions on, so the daemon
381
+ * can pull the agent's parked mailbox from each on reconnect (the relay mailbox is keyed by recipient
382
+ * pubkey, so one pull per relay drains all of the agent's parked content there). Distinct by relay
383
+ * peer id.
384
+ */
385
+ getAgentRelayEndpoints(agentName: string): Array<{
386
+ relayPeerId: string;
387
+ relayAddrs: string[];
388
+ }>;
389
+ /**
390
+ * Return the daemon-owned Merkle tree for a session, loading it from SQLite
391
+ * on first access (so it survives a restart — AC-007). Never returns null;
392
+ * an unknown session yields an empty tree.
393
+ */
394
+ getSessionTree(agentName: string, sessionId: string): SessionTree;
395
+ /** Current daemon-owned tree root for a session, as hex. */
396
+ getSessionTreeRootHex(agentName: string, sessionId: string): string;
397
+ /**
398
+ * Append a leaf (by its 32-byte leaf-hash hex) to the daemon-owned tree,
399
+ * persist it, advance the root, and fire session.tree.appended.
400
+ *
401
+ * @returns the new leaf index and the recomputed root hex.
402
+ */
403
+ appendSessionLeaf(agentName: string, sessionId: string, kind: SessionTreeLeafKind, leafHashHex: string, correlationId?: string): {
404
+ leafIndex: number;
405
+ newRootHex: string;
406
+ };
407
+ /**
408
+ * SEAM 1b (dialer ⇄ session-node reconciliation): dial the counterparty THROUGH
409
+ * this session's OWN node, so the session node N_A holds the connection its content
410
+ * newStream actually rides. TRANSPORT-001's transport selector dialed on a separate
411
+ * (composition-root) node whose connection N_A could not use — the per-session node
412
+ * must be the dialer. Direct mode only here (the default content path, Part 4 D-a);
413
+ * relay-circuit + dcutr strategy via N_A is a later seam. Tries each addr in turn;
414
+ * succeeds on the first connection, returns a named failure if none connect.
415
+ */
416
+ connectToCounterparty(agentName: string, sessionId: string, addrs: string[]): Promise<{
417
+ ok: true;
418
+ } | {
419
+ ok: false;
420
+ reason: string;
421
+ error: string;
422
+ }>;
423
+ /**
424
+ * DAEMON-004: send content over the session node's direct P2P content stream.
425
+ * On a dead/missing stream this returns a NAMED, diagnosable failure — never a
426
+ * silent success and never a desync (closing the old silent fire-and-forget
427
+ * content catch in the retired in-process client send path).
428
+ *
429
+ * SCOPE / findings #3 + #4 — what this send path does and does NOT do today:
430
+ * - #4: it delivers the content over the direct /cello/content/1.0.0 P2P
431
+ * stream only. It does NOT also submit a K_local-SIGNED content_hash leaf to
432
+ * the RELAY on /cello/relay/1.0.0 (EARS behavior #1). That relay hash-submit
433
+ * is MSG-001's scope; AC-001's "relay log shows a hash_submit" evidence is
434
+ * produced once MSG-001 lands.
435
+ * - #3: because there is no relay yet, the sequence number cello_send returns
436
+ * is the LOCAL leaf index, not a relay-assigned canonical global sequence.
437
+ * Each daemon appends leaves in its own LOCAL observation order, so two
438
+ * daemons' roots agree only under perfectly ping-ponged traffic. Canonical
439
+ * cross-process ordering (and thus AC-002 root agreement under concurrent
440
+ * bidirectional traffic) requires the relay-assigned sequence from MSG-001.
441
+ */
442
+ sendContent(agentName: string, sessionId: string, content: Uint8Array, contentHash: Uint8Array, correlationId?: string): Promise<{
443
+ ok: true;
444
+ } | {
445
+ ok: false;
446
+ reason: string;
447
+ error: string;
448
+ }>;
449
+ /**
450
+ * M7 DOD-SPINE-7: submit THIS party's SEAL ctrl leaf (0x02) to the relay witness.
451
+ * Structure: content_hash = SHA-256(0x02 || encodeSealPayload({session_id, final_root,
452
+ * close_timestamp, "PENDING"})), where final_root is the daemon's OWN tree root. Two
453
+ * distinct-sender SEAL leaves in the relay's log trigger the relay's #maybeProcessSeal
454
+ * → directory processSeal (rebuild + verify the signed chain) → FROST notarization →
455
+ * session_sealed. Requires an active relay client; the caller falls back to the
456
+ * directory-mediated path when this returns relay_unavailable.
457
+ */
458
+ submitSealLeaf(agentName: string, sessionId: string, correlationId?: string): Promise<{
459
+ ok: true;
460
+ sequenceNumber: number;
461
+ reportedRootHex: string;
462
+ } | {
463
+ ok: false;
464
+ reason: string;
465
+ }>;
466
+ /**
467
+ * CELLO-M7-UPGRADE-001 (DOD-UP-1): readiness of a session for B to RATIFY a unilateral seal
468
+ * (the returning absent party). This is the SAME verifiability bar as the UP-2 auto-ack gate:
469
+ *
470
+ * - `known`: the session exists locally with its content (B has a transcript to ratify). After a
471
+ * restart B reloads it from SQLite, and autoRecoverForAgent re-pulls any parked content first.
472
+ * - `tampered`: the content cross-check flagged a content_hash mismatch (#contentDesynced) — B
473
+ * must NEVER ratify content it could not integrity-verify (the KERNEL refusal, AC-003).
474
+ *
475
+ * The directory separately verifies B's ack signature is genuine; B separately verifies the
476
+ * unilateral cert signature (R1 is authentic). NOTE: a full "B's frontier covers R1's tail"
477
+ * completeness check (the `desynced` reason) requires the deferred MSG-001-3b canonical-sequence
478
+ * reconciliation — same documented limitation as the UP-2 gate above.
479
+ */
480
+ getSealUpgradeReadiness(agentName: string, sessionId: string): {
481
+ known: boolean;
482
+ tampered: boolean;
483
+ };
484
+ /**
485
+ * DAEMON-004: cross-check received content against its hash, append the
486
+ * verified leaf to the daemon-owned tree, and buffer it for cello_receive.
487
+ * A hash MISMATCH is genuine tamper — rejected without append or buffer.
488
+ *
489
+ * SCOPE / finding #5 — what this cross-check does and does NOT prove today:
490
+ * `contentHash` here is carried in the SAME content_frame as `content`, so this
491
+ * comparison only catches wire corruption of a single frame — it does NOT prove
492
+ * the content matches what the sender independently committed. Full tamper-
493
+ * evidence (EARS behavior #2) requires cross-checking against the K_local-signed
494
+ * content_hash leaf the sender submits to the RELAY on a separate channel; that
495
+ * relay hash-submit path is MSG-001's scope and does not exist yet. Until MSG-001
496
+ * lands, a malicious sender that sends matching (content, hash) in one frame is
497
+ * not detected here — only the relay-relayed signed leaf closes that gap.
498
+ *
499
+ * @returns the appended leaf index (as sequenceNumber) on success.
500
+ */
501
+ ingestReceivedContent(agentName: string, sessionId: string, content: Uint8Array, contentHash: Uint8Array, correlationId?: string): {
502
+ ok: true;
503
+ leafIndex: number;
504
+ sequenceNumber: number;
505
+ held?: boolean;
506
+ appendedCount?: number;
507
+ } | {
508
+ ok: false;
509
+ reason: string;
510
+ };
511
+ /**
512
+ * DOD-MSG-4: record the relay-witnessed canonical sequence for a content hash. The relay is the
513
+ * ordering authority (Structure 2): it assigns each message a sequence from its hash and delivers
514
+ * B the (content_hash -> sequence) binding via leaf_deliver. The strict-in-order gate orders the
515
+ * transcript by THIS — never a sender-stamped field. Also advances the per-session high-water mark
516
+ * (the largest witnessed sequence) reserved for the future catch-up-before-live increment. Idempotent.
517
+ */
518
+ recordWitnessedSequence(agentName: string, sessionId: string, contentHashHex: string, sequenceNumber: number): void;
519
+ /**
520
+ * DOD-MSG-4: the relay's high-water canonical sequence for this session (largest witnessed leaf),
521
+ * or -1 if none. Exposed for the next sub-increment (catch-up-before-live — on reconnect B holds
522
+ * live arrivals until its tree reaches this, because it has more to recover than it has appended);
523
+ * NOT yet consumed by the gate. Also `recordWitnessedSequence` maintains it.
524
+ */
525
+ getHighWaterSeq(agentName: string, sessionId: string): number;
526
+ /** DAEMON-004: pop the oldest verified received content for cello_receive. */
527
+ takeReceivedContent(agentName: string, sessionId: string): ReceivedContentEntry | null;
528
+ /**
529
+ * DOD-MSG-4 (self-ordering content frame): verify the relay's signed ordering record carried IN the
530
+ * content frame and record the canonical sequence for the strict-in-order gate — so ordering does
531
+ * not depend on the separate leaf_deliver witness arriving first. Best-effort: any failure (malformed,
532
+ * hash mismatch, bad signature, wrong signer) is logged and ignored — the content still ingests and
533
+ * orders via the witness stream / arrival, so a bad record cannot block delivery.
534
+ *
535
+ * structure1_cbor = [1, content_hash(32), sender_pubkey(32), session_id(16), last_seen_seq, ts] —
536
+ * the EXACT bytes the sender signed (needed to verify; Structure2 omits session_id/last_seen/ts).
537
+ * structure2_cbor = [seq, sender_pubkey, content_hash, sender_signature, scan_result, prev_root].
538
+ */
539
+ /**
540
+ * DOD-MSG-4 (2b): encode the pre-seal park envelope `[1, content, structure1_cbor|null,
541
+ * structure2_cbor|null]`. The daemon seals THIS (not the bare content) so a parked entry carries
542
+ * its own signed ordering record — recover then orders it the same way the direct frame does. The
543
+ * relay still only ever holds the sealed ciphertext (INV-3 preserved).
544
+ */
545
+ encodeParkEnvelope(content: Uint8Array, structure1Cbor?: Uint8Array, structure2Cbor?: Uint8Array): Uint8Array;
546
+ /**
547
+ * DOD-MSG-4 (2b): decode a park envelope produced by encodeParkEnvelope. Falls back to treating the
548
+ * whole plaintext as raw content (no ordering record) for entries sealed the old way (e.g. test
549
+ * fixtures that seal bare content) — so recover stays backward-compatible.
550
+ */
551
+ decodeParkEnvelope(plaintext: Uint8Array): {
552
+ content: Uint8Array;
553
+ structure1Cbor?: Uint8Array;
554
+ structure2Cbor?: Uint8Array;
555
+ };
556
+ /**
557
+ * DOD-MSG-4 (2b): public entry for the recover path to verify + record a parked entry's ordering
558
+ * record (the recover handler lives in daemon.ts, which has no access to the private method).
559
+ */
560
+ recordOrderingRecord(agentName: string, sessionId: string, structure1Cbor: Uint8Array, structure2Cbor: Uint8Array, contentHash: Uint8Array, correlationId?: string): void;
561
+ /**
562
+ * M7-SESSION-001 AC-004/AC-005: Register a relay stream for an active session.
563
+ * Starts a background reader that watches for session_interrupted frames and
564
+ * stream close events. Both detection paths call markInterruptedWithDetails().
565
+ *
566
+ * The reader runs for the lifetime of the relay stream. If the stream closes
567
+ * without delivering a session_interrupted frame (AC-005 / 'stream_close' path),
568
+ * the session is still marked interrupted.
569
+ *
570
+ * @param sessionId The hex session ID
571
+ * @param stream The relay stream to monitor
572
+ * @param messageCount Number of message leaves at the time of registration
573
+ * (used as the count at interruption — best effort since exact count at frame
574
+ * receipt may differ, but this is the value available at stream setup time)
575
+ */
576
+ registerRelayStream(agentName: string, sessionId: string, stream: Stream, messageCount?: number): void;
577
+ /**
578
+ * DOD-LOOP-1: public hook for the composition root to create an agent's standing receiver when
579
+ * the agent comes online (cello_start_agent), and to tear it down when it goes offline.
580
+ */
581
+ ensureStandingReceiverForAgent(agentName: string): Promise<void>;
582
+ removeStandingReceiverForAgent(agentName: string): Promise<void>;
583
+ }
584
+ export {};
585
+ //# sourceMappingURL=session-node-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-node-manager.d.ts","sourceRoot":"","sources":["../src/session-node-manager.ts"],"names":[],"mappings":"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"}