@cello-protocol/daemon 0.0.227 → 0.0.228

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 (895) hide show
  1. package/dist/agent-admin-handlers.d.ts +56 -0
  2. package/dist/agent-admin-handlers.d.ts.map +1 -0
  3. package/dist/agent-admin-handlers.js +73 -0
  4. package/dist/agent-admin-handlers.js.map +1 -0
  5. package/dist/agent-handlers.d.ts +72 -0
  6. package/dist/agent-handlers.d.ts.map +1 -0
  7. package/dist/agent-handlers.js +604 -0
  8. package/dist/agent-handlers.js.map +1 -0
  9. package/dist/agent-id-migration.d.ts +70 -0
  10. package/dist/agent-id-migration.d.ts.map +1 -0
  11. package/dist/agent-id-migration.js +468 -0
  12. package/dist/agent-id-migration.js.map +1 -0
  13. package/dist/agent-loader.d.ts +37 -0
  14. package/dist/agent-loader.d.ts.map +1 -0
  15. package/dist/agent-loader.js +37 -0
  16. package/dist/agent-loader.js.map +1 -0
  17. package/dist/agent-selection-root.d.ts +29 -0
  18. package/dist/agent-selection-root.d.ts.map +1 -0
  19. package/dist/agent-selection-root.js +126 -0
  20. package/dist/agent-selection-root.js.map +1 -0
  21. package/dist/agent-selection.d.ts +73 -0
  22. package/dist/agent-selection.d.ts.map +1 -0
  23. package/dist/agent-selection.js +80 -0
  24. package/dist/agent-selection.js.map +1 -0
  25. package/dist/agent-settings-keys.d.ts +52 -0
  26. package/dist/agent-settings-keys.d.ts.map +1 -0
  27. package/dist/agent-settings-keys.js +114 -0
  28. package/dist/agent-settings-keys.js.map +1 -0
  29. package/dist/agent-state.d.ts +67 -0
  30. package/dist/agent-state.d.ts.map +1 -0
  31. package/dist/agent-state.js +66 -0
  32. package/dist/agent-state.js.map +1 -0
  33. package/dist/assignment-verify.d.ts +90 -0
  34. package/dist/assignment-verify.d.ts.map +1 -0
  35. package/dist/assignment-verify.js +301 -0
  36. package/dist/assignment-verify.js.map +1 -0
  37. package/dist/attendance-wiring.d.ts +23 -0
  38. package/dist/attendance-wiring.d.ts.map +1 -0
  39. package/dist/attendance-wiring.js +248 -0
  40. package/dist/attendance-wiring.js.map +1 -0
  41. package/dist/attestation-body.d.ts +47 -0
  42. package/dist/attestation-body.d.ts.map +1 -0
  43. package/dist/attestation-body.js +71 -0
  44. package/dist/attestation-body.js.map +1 -0
  45. package/dist/authorship-verification.d.ts +91 -0
  46. package/dist/authorship-verification.d.ts.map +1 -0
  47. package/dist/authorship-verification.js +532 -0
  48. package/dist/authorship-verification.js.map +1 -0
  49. package/dist/away-detection.d.ts +139 -0
  50. package/dist/away-detection.d.ts.map +1 -0
  51. package/dist/away-detection.js +186 -0
  52. package/dist/away-detection.js.map +1 -0
  53. package/dist/away-inbox-oneshot.d.ts +40 -0
  54. package/dist/away-inbox-oneshot.d.ts.map +1 -0
  55. package/dist/away-inbox-oneshot.js +311 -0
  56. package/dist/away-inbox-oneshot.js.map +1 -0
  57. package/dist/backup-restore-handlers.d.ts +10 -0
  58. package/dist/backup-restore-handlers.d.ts.map +1 -0
  59. package/dist/backup-restore-handlers.js +82 -0
  60. package/dist/backup-restore-handlers.js.map +1 -0
  61. package/dist/backup-restore.d.ts +102 -0
  62. package/dist/backup-restore.d.ts.map +1 -0
  63. package/dist/backup-restore.js +341 -0
  64. package/dist/backup-restore.js.map +1 -0
  65. package/dist/bin/cello-daemon.d.ts +13 -0
  66. package/dist/bin/cello-daemon.d.ts.map +1 -0
  67. package/dist/bin/cello-daemon.js.map +1 -0
  68. package/dist/boot-agents.d.ts +64 -0
  69. package/dist/boot-agents.d.ts.map +1 -0
  70. package/dist/boot-agents.js +241 -0
  71. package/dist/boot-agents.js.map +1 -0
  72. package/dist/boot-connection-state.d.ts +38 -0
  73. package/dist/boot-connection-state.d.ts.map +1 -0
  74. package/dist/boot-connection-state.js +95 -0
  75. package/dist/boot-connection-state.js.map +1 -0
  76. package/dist/boot-core.d.ts +36 -0
  77. package/dist/boot-core.d.ts.map +1 -0
  78. package/dist/boot-core.js +293 -0
  79. package/dist/boot-core.js.map +1 -0
  80. package/dist/boot-parked-content.d.ts +34 -0
  81. package/dist/boot-parked-content.d.ts.map +1 -0
  82. package/dist/boot-parked-content.js +528 -0
  83. package/dist/boot-parked-content.js.map +1 -0
  84. package/dist/boot-sweeps.d.ts +22 -0
  85. package/dist/boot-sweeps.d.ts.map +1 -0
  86. package/dist/boot-sweeps.js +51 -0
  87. package/dist/boot-sweeps.js.map +1 -0
  88. package/dist/bundled-consortium-manifest.d.ts +47 -0
  89. package/dist/bundled-consortium-manifest.d.ts.map +1 -0
  90. package/dist/bundled-consortium-manifest.js +116 -0
  91. package/dist/bundled-consortium-manifest.js.map +1 -0
  92. package/dist/cbor-blob-migration.d.ts +8 -0
  93. package/dist/cbor-blob-migration.d.ts.map +1 -0
  94. package/dist/cbor-blob-migration.js +116 -0
  95. package/dist/cbor-blob-migration.js.map +1 -0
  96. package/dist/challenge-verifier.d.ts +12 -0
  97. package/dist/challenge-verifier.d.ts.map +1 -0
  98. package/dist/challenge-verifier.js +11 -0
  99. package/dist/challenge-verifier.js.map +1 -0
  100. package/dist/channel-log-store.d.ts +80 -0
  101. package/dist/channel-log-store.d.ts.map +1 -0
  102. package/dist/channel-log-store.js +290 -0
  103. package/dist/channel-log-store.js.map +1 -0
  104. package/dist/close-commitment.d.ts +67 -0
  105. package/dist/close-commitment.d.ts.map +1 -0
  106. package/dist/close-commitment.js +78 -0
  107. package/dist/close-commitment.js.map +1 -0
  108. package/dist/close-session-handler.d.ts +94 -0
  109. package/dist/close-session-handler.d.ts.map +1 -0
  110. package/dist/close-session-handler.js +1418 -0
  111. package/dist/close-session-handler.js.map +1 -0
  112. package/dist/co-attendance.d.ts +29 -0
  113. package/dist/co-attendance.d.ts.map +1 -0
  114. package/dist/co-attendance.js +32 -0
  115. package/dist/co-attendance.js.map +1 -0
  116. package/dist/column-birth.d.ts +40 -0
  117. package/dist/column-birth.d.ts.map +1 -0
  118. package/dist/column-birth.js +61 -0
  119. package/dist/column-birth.js.map +1 -0
  120. package/dist/connect-or-start.d.ts +25 -0
  121. package/dist/connect-or-start.d.ts.map +1 -0
  122. package/dist/connect-or-start.js +175 -0
  123. package/dist/connect-or-start.js.map +1 -0
  124. package/dist/connection-agents.d.ts +16 -0
  125. package/dist/connection-agents.d.ts.map +1 -0
  126. package/dist/connection-agents.js +68 -0
  127. package/dist/connection-agents.js.map +1 -0
  128. package/dist/consent-migration.d.ts +49 -0
  129. package/dist/consent-migration.d.ts.map +1 -0
  130. package/dist/consent-migration.js +128 -0
  131. package/dist/consent-migration.js.map +1 -0
  132. package/dist/consortium-bootstrap.d.ts +138 -0
  133. package/dist/consortium-bootstrap.d.ts.map +1 -0
  134. package/dist/consortium-bootstrap.js +339 -0
  135. package/dist/consortium-bootstrap.js.map +1 -0
  136. package/dist/consortium-fingerprint.d.ts +115 -0
  137. package/dist/consortium-fingerprint.d.ts.map +1 -0
  138. package/dist/consortium-fingerprint.js +175 -0
  139. package/dist/consortium-fingerprint.js.map +1 -0
  140. package/dist/contact-handlers.d.ts +59 -0
  141. package/dist/contact-handlers.d.ts.map +1 -0
  142. package/dist/contact-handlers.js +343 -0
  143. package/dist/contact-handlers.js.map +1 -0
  144. package/dist/contact-pubkey-case.d.ts +65 -0
  145. package/dist/contact-pubkey-case.d.ts.map +1 -0
  146. package/dist/contact-pubkey-case.js +136 -0
  147. package/dist/contact-pubkey-case.js.map +1 -0
  148. package/dist/contacts-tier-migration.d.ts +90 -0
  149. package/dist/contacts-tier-migration.d.ts.map +1 -0
  150. package/dist/contacts-tier-migration.js +150 -0
  151. package/dist/contacts-tier-migration.js.map +1 -0
  152. package/dist/content-encryption-status.d.ts +111 -0
  153. package/dist/content-encryption-status.d.ts.map +1 -0
  154. package/dist/content-encryption-status.js +158 -0
  155. package/dist/content-encryption-status.js.map +1 -0
  156. package/dist/content-park-client.d.ts +90 -0
  157. package/dist/content-park-client.d.ts.map +1 -0
  158. package/dist/content-park-client.js +362 -0
  159. package/dist/content-park-client.js.map +1 -0
  160. package/dist/content-park.d.ts +52 -0
  161. package/dist/content-park.d.ts.map +1 -0
  162. package/dist/content-park.js +1309 -0
  163. package/dist/content-park.js.map +1 -0
  164. package/dist/cross-node-negotiation.d.ts +44 -0
  165. package/dist/cross-node-negotiation.d.ts.map +1 -0
  166. package/dist/cross-node-negotiation.js +34 -0
  167. package/dist/cross-node-negotiation.js.map +1 -0
  168. package/dist/daemon-handle.d.ts +57 -0
  169. package/dist/daemon-handle.d.ts.map +1 -0
  170. package/dist/daemon-handle.js +2 -0
  171. package/dist/daemon-handle.js.map +1 -0
  172. package/dist/daemon-status-report.d.ts +50 -0
  173. package/dist/daemon-status-report.d.ts.map +1 -0
  174. package/dist/daemon-status-report.js +81 -0
  175. package/dist/daemon-status-report.js.map +1 -0
  176. package/dist/daemon.d.ts +45 -0
  177. package/dist/daemon.d.ts.map +1 -0
  178. package/dist/daemon.js +1177 -0
  179. package/dist/daemon.js.map +1 -0
  180. package/dist/db-identity-store.d.ts +159 -0
  181. package/dist/db-identity-store.d.ts.map +1 -0
  182. package/dist/db-identity-store.js +502 -0
  183. package/dist/db-identity-store.js.map +1 -0
  184. package/dist/delivery-open-registry.d.ts +92 -0
  185. package/dist/delivery-open-registry.d.ts.map +1 -0
  186. package/dist/delivery-open-registry.js +121 -0
  187. package/dist/delivery-open-registry.js.map +1 -0
  188. package/dist/delivery-session-suspects.d.ts +56 -0
  189. package/dist/delivery-session-suspects.d.ts.map +1 -0
  190. package/dist/delivery-session-suspects.js +94 -0
  191. package/dist/delivery-session-suspects.js.map +1 -0
  192. package/dist/directory-auth-posture.d.ts +87 -0
  193. package/dist/directory-auth-posture.d.ts.map +1 -0
  194. package/dist/directory-auth-posture.js +134 -0
  195. package/dist/directory-auth-posture.js.map +1 -0
  196. package/dist/directory-bootstrap.d.ts +310 -0
  197. package/dist/directory-bootstrap.d.ts.map +1 -0
  198. package/dist/directory-bootstrap.js +557 -0
  199. package/dist/directory-bootstrap.js.map +1 -0
  200. package/dist/directory-connect.d.ts +27 -0
  201. package/dist/directory-connect.d.ts.map +1 -0
  202. package/dist/directory-connect.js +106 -0
  203. package/dist/directory-connect.js.map +1 -0
  204. package/dist/disconnect-cleanup.d.ts +51 -0
  205. package/dist/disconnect-cleanup.d.ts.map +1 -0
  206. package/dist/disconnect-cleanup.js +72 -0
  207. package/dist/disconnect-cleanup.js.map +1 -0
  208. package/dist/document-amendment-store.d.ts +120 -0
  209. package/dist/document-amendment-store.d.ts.map +1 -0
  210. package/dist/document-amendment-store.js +266 -0
  211. package/dist/document-amendment-store.js.map +1 -0
  212. package/dist/document-delivery-transport.d.ts +168 -0
  213. package/dist/document-delivery-transport.d.ts.map +1 -0
  214. package/dist/document-delivery-transport.js +206 -0
  215. package/dist/document-delivery-transport.js.map +1 -0
  216. package/dist/document-engine.d.ts +134 -0
  217. package/dist/document-engine.d.ts.map +1 -0
  218. package/dist/document-engine.js +282 -0
  219. package/dist/document-engine.js.map +1 -0
  220. package/dist/document-flag.d.ts +58 -0
  221. package/dist/document-flag.d.ts.map +1 -0
  222. package/dist/document-flag.js +70 -0
  223. package/dist/document-flag.js.map +1 -0
  224. package/dist/document-frame-router.d.ts +245 -0
  225. package/dist/document-frame-router.d.ts.map +1 -0
  226. package/dist/document-frame-router.js +397 -0
  227. package/dist/document-frame-router.js.map +1 -0
  228. package/dist/document-gate-wiring.d.ts +61 -0
  229. package/dist/document-gate-wiring.d.ts.map +1 -0
  230. package/dist/document-gate-wiring.js +125 -0
  231. package/dist/document-gate-wiring.js.map +1 -0
  232. package/dist/document-gate.d.ts +149 -0
  233. package/dist/document-gate.d.ts.map +1 -0
  234. package/dist/document-gate.js +509 -0
  235. package/dist/document-gate.js.map +1 -0
  236. package/dist/document-handlers.d.ts +47 -0
  237. package/dist/document-handlers.d.ts.map +1 -0
  238. package/dist/document-handlers.js +2203 -0
  239. package/dist/document-handlers.js.map +1 -0
  240. package/dist/document-handshake.d.ts +176 -0
  241. package/dist/document-handshake.d.ts.map +1 -0
  242. package/dist/document-handshake.js +452 -0
  243. package/dist/document-handshake.js.map +1 -0
  244. package/dist/document-inbound.d.ts +162 -0
  245. package/dist/document-inbound.d.ts.map +1 -0
  246. package/dist/document-inbound.js +530 -0
  247. package/dist/document-inbound.js.map +1 -0
  248. package/dist/document-json.d.ts +120 -0
  249. package/dist/document-json.d.ts.map +1 -0
  250. package/dist/document-json.js +191 -0
  251. package/dist/document-json.js.map +1 -0
  252. package/dist/document-layer.d.ts +215 -0
  253. package/dist/document-layer.d.ts.map +1 -0
  254. package/dist/document-layer.js +1025 -0
  255. package/dist/document-layer.js.map +1 -0
  256. package/dist/document-lifecycle.d.ts +52 -0
  257. package/dist/document-lifecycle.d.ts.map +1 -0
  258. package/dist/document-lifecycle.js +134 -0
  259. package/dist/document-lifecycle.js.map +1 -0
  260. package/dist/document-live-docs.d.ts +58 -0
  261. package/dist/document-live-docs.d.ts.map +1 -0
  262. package/dist/document-live-docs.js +126 -0
  263. package/dist/document-live-docs.js.map +1 -0
  264. package/dist/document-notify.d.ts +228 -0
  265. package/dist/document-notify.d.ts.map +1 -0
  266. package/dist/document-notify.js +580 -0
  267. package/dist/document-notify.js.map +1 -0
  268. package/dist/document-profile.d.ts +61 -0
  269. package/dist/document-profile.d.ts.map +1 -0
  270. package/dist/document-profile.js +112 -0
  271. package/dist/document-profile.js.map +1 -0
  272. package/dist/document-publish.d.ts +87 -0
  273. package/dist/document-publish.d.ts.map +1 -0
  274. package/dist/document-publish.js +173 -0
  275. package/dist/document-publish.js.map +1 -0
  276. package/dist/document-reachability.d.ts +42 -0
  277. package/dist/document-reachability.d.ts.map +1 -0
  278. package/dist/document-reachability.js +80 -0
  279. package/dist/document-reachability.js.map +1 -0
  280. package/dist/document-reconcile-engine.d.ts +66 -0
  281. package/dist/document-reconcile-engine.d.ts.map +1 -0
  282. package/dist/document-reconcile-engine.js +225 -0
  283. package/dist/document-reconcile-engine.js.map +1 -0
  284. package/dist/document-reconcile-scheduler.d.ts +163 -0
  285. package/dist/document-reconcile-scheduler.d.ts.map +1 -0
  286. package/dist/document-reconcile-scheduler.js +303 -0
  287. package/dist/document-reconcile-scheduler.js.map +1 -0
  288. package/dist/document-rejection.d.ts +251 -0
  289. package/dist/document-rejection.d.ts.map +1 -0
  290. package/dist/document-rejection.js +435 -0
  291. package/dist/document-rejection.js.map +1 -0
  292. package/dist/document-screen.d.ts +114 -0
  293. package/dist/document-screen.d.ts.map +1 -0
  294. package/dist/document-screen.js +223 -0
  295. package/dist/document-screen.js.map +1 -0
  296. package/dist/document-store.d.ts +372 -0
  297. package/dist/document-store.d.ts.map +1 -0
  298. package/dist/document-store.js +931 -0
  299. package/dist/document-store.js.map +1 -0
  300. package/dist/document-surface.d.ts +32 -0
  301. package/dist/document-surface.d.ts.map +1 -0
  302. package/dist/document-surface.js +151 -0
  303. package/dist/document-surface.js.map +1 -0
  304. package/dist/document-types.d.ts +94 -0
  305. package/dist/document-types.d.ts.map +1 -0
  306. package/dist/document-types.js +90 -0
  307. package/dist/document-types.js.map +1 -0
  308. package/dist/document-watch.d.ts +69 -0
  309. package/dist/document-watch.d.ts.map +1 -0
  310. package/dist/document-watch.js +108 -0
  311. package/dist/document-watch.js.map +1 -0
  312. package/dist/document-wiring.d.ts +53 -0
  313. package/dist/document-wiring.d.ts.map +1 -0
  314. package/dist/document-wiring.js +323 -0
  315. package/dist/document-wiring.js.map +1 -0
  316. package/dist/document-write-guard.d.ts +66 -0
  317. package/dist/document-write-guard.d.ts.map +1 -0
  318. package/dist/document-write-guard.js +98 -0
  319. package/dist/document-write-guard.js.map +1 -0
  320. package/dist/document-write-path.d.ts +94 -0
  321. package/dist/document-write-path.d.ts.map +1 -0
  322. package/dist/document-write-path.js +530 -0
  323. package/dist/document-write-path.js.map +1 -0
  324. package/dist/error-message.d.ts +7 -0
  325. package/dist/error-message.d.ts.map +1 -0
  326. package/dist/error-message.js +19 -0
  327. package/dist/error-message.js.map +1 -0
  328. package/dist/file-manifest-provider.d.ts +37 -0
  329. package/dist/file-manifest-provider.d.ts.map +1 -0
  330. package/dist/file-manifest-provider.js +105 -0
  331. package/dist/file-manifest-provider.js.map +1 -0
  332. package/dist/frame-values.d.ts +3 -0
  333. package/dist/frame-values.d.ts.map +1 -0
  334. package/dist/frame-values.js +84 -0
  335. package/dist/frame-values.js.map +1 -0
  336. package/dist/frontier-mismatch.d.ts +73 -0
  337. package/dist/frontier-mismatch.d.ts.map +1 -0
  338. package/dist/frontier-mismatch.js +89 -0
  339. package/dist/frontier-mismatch.js.map +1 -0
  340. package/dist/gateway-config-handlers.d.ts +26 -0
  341. package/dist/gateway-config-handlers.d.ts.map +1 -0
  342. package/dist/gateway-config-handlers.js +429 -0
  343. package/dist/gateway-config-handlers.js.map +1 -0
  344. package/dist/held-content.d.ts +145 -0
  345. package/dist/held-content.d.ts.map +1 -0
  346. package/dist/held-content.js +389 -0
  347. package/dist/held-content.js.map +1 -0
  348. package/dist/http-manifest-poll.d.ts +67 -0
  349. package/dist/http-manifest-poll.d.ts.map +1 -0
  350. package/dist/http-manifest-poll.js +150 -0
  351. package/dist/http-manifest-poll.js.map +1 -0
  352. package/dist/identity-migration.d.ts +40 -0
  353. package/dist/identity-migration.d.ts.map +1 -0
  354. package/dist/identity-migration.js +461 -0
  355. package/dist/identity-migration.js.map +1 -0
  356. package/dist/inbound-refusals.d.ts +283 -0
  357. package/dist/inbound-refusals.d.ts.map +1 -0
  358. package/dist/inbound-refusals.js +919 -0
  359. package/dist/inbound-refusals.js.map +1 -0
  360. package/dist/inbound-seal-request.d.ts +32 -0
  361. package/dist/inbound-seal-request.d.ts.map +1 -0
  362. package/dist/inbound-seal-request.js +228 -0
  363. package/dist/inbound-seal-request.js.map +1 -0
  364. package/dist/inbound-sessions.d.ts +291 -0
  365. package/dist/inbound-sessions.d.ts.map +1 -0
  366. package/dist/inbound-sessions.js +1609 -0
  367. package/dist/inbound-sessions.js.map +1 -0
  368. package/dist/inclusion-proof-handlers.d.ts +43 -0
  369. package/dist/inclusion-proof-handlers.d.ts.map +1 -0
  370. package/dist/inclusion-proof-handlers.js +565 -0
  371. package/dist/inclusion-proof-handlers.js.map +1 -0
  372. package/dist/inclusion-proof.d.ts +151 -0
  373. package/dist/inclusion-proof.d.ts.map +1 -0
  374. package/dist/inclusion-proof.js +228 -0
  375. package/dist/inclusion-proof.js.map +1 -0
  376. package/dist/index.d.ts +32 -0
  377. package/dist/index.d.ts.map +1 -0
  378. package/dist/index.js.map +1 -0
  379. package/dist/initiate-session-handler.d.ts +55 -0
  380. package/dist/initiate-session-handler.d.ts.map +1 -0
  381. package/dist/initiate-session-handler.js +310 -0
  382. package/dist/initiate-session-handler.js.map +1 -0
  383. package/dist/ipc-client.d.ts +31 -0
  384. package/dist/ipc-client.d.ts.map +1 -0
  385. package/dist/ipc-client.js +113 -0
  386. package/dist/ipc-client.js.map +1 -0
  387. package/dist/ipc-server.d.ts +63 -0
  388. package/dist/ipc-server.d.ts.map +1 -0
  389. package/dist/ipc-server.js +429 -0
  390. package/dist/ipc-server.js.map +1 -0
  391. package/dist/ipc-surface.d.ts +44 -0
  392. package/dist/ipc-surface.d.ts.map +1 -0
  393. package/dist/ipc-surface.js +107 -0
  394. package/dist/ipc-surface.js.map +1 -0
  395. package/dist/line-lcs.d.ts +51 -0
  396. package/dist/line-lcs.d.ts.map +1 -0
  397. package/dist/line-lcs.js +71 -0
  398. package/dist/line-lcs.js.map +1 -0
  399. package/dist/lock-file.d.ts +39 -0
  400. package/dist/lock-file.d.ts.map +1 -0
  401. package/dist/lock-file.js +120 -0
  402. package/dist/lock-file.js.map +1 -0
  403. package/dist/log-collapse.d.ts +66 -0
  404. package/dist/log-collapse.d.ts.map +1 -0
  405. package/dist/log-collapse.js +244 -0
  406. package/dist/log-collapse.js.map +1 -0
  407. package/dist/log-rotate.d.ts +67 -0
  408. package/dist/log-rotate.d.ts.map +1 -0
  409. package/dist/log-rotate.js +134 -0
  410. package/dist/log-rotate.js.map +1 -0
  411. package/dist/manifest-deps.d.ts +25 -0
  412. package/dist/manifest-deps.d.ts.map +1 -0
  413. package/dist/manifest-deps.js +151 -0
  414. package/dist/manifest-deps.js.map +1 -0
  415. package/dist/manifest-poll-scheduler.d.ts +31 -0
  416. package/dist/manifest-poll-scheduler.d.ts.map +1 -0
  417. package/dist/manifest-poll-scheduler.js +59 -0
  418. package/dist/manifest-poll-scheduler.js.map +1 -0
  419. package/dist/manifest-validity.d.ts +153 -0
  420. package/dist/manifest-validity.d.ts.map +1 -0
  421. package/dist/manifest-validity.js +268 -0
  422. package/dist/manifest-validity.js.map +1 -0
  423. package/dist/manifest-version-store-db.d.ts +24 -0
  424. package/dist/manifest-version-store-db.d.ts.map +1 -0
  425. package/dist/manifest-version-store-db.js +58 -0
  426. package/dist/manifest-version-store-db.js.map +1 -0
  427. package/dist/manifest-version-store.d.ts +16 -0
  428. package/dist/manifest-version-store.d.ts.map +1 -0
  429. package/dist/manifest-version-store.js +15 -0
  430. package/dist/manifest-version-store.js.map +1 -0
  431. package/dist/network-directory-node.d.ts +136 -0
  432. package/dist/network-directory-node.d.ts.map +1 -0
  433. package/dist/network-directory-node.js +810 -0
  434. package/dist/network-directory-node.js.map +1 -0
  435. package/dist/nonce-dedup.d.ts +68 -0
  436. package/dist/nonce-dedup.d.ts.map +1 -0
  437. package/dist/nonce-dedup.js +205 -0
  438. package/dist/nonce-dedup.js.map +1 -0
  439. package/dist/notification-dispatcher.d.ts +92 -0
  440. package/dist/notification-dispatcher.d.ts.map +1 -0
  441. package/dist/notification-dispatcher.js +210 -0
  442. package/dist/notification-dispatcher.js.map +1 -0
  443. package/dist/notification-handlers.d.ts +53 -0
  444. package/dist/notification-handlers.d.ts.map +1 -0
  445. package/dist/notification-handlers.js +461 -0
  446. package/dist/notification-handlers.js.map +1 -0
  447. package/dist/onboarding-guidance.d.ts +79 -0
  448. package/dist/onboarding-guidance.d.ts.map +1 -0
  449. package/dist/onboarding-guidance.js +95 -0
  450. package/dist/onboarding-guidance.js.map +1 -0
  451. package/dist/operator-guidance.d.ts +25 -0
  452. package/dist/operator-guidance.d.ts.map +1 -0
  453. package/dist/operator-guidance.js +50 -0
  454. package/dist/operator-guidance.js.map +1 -0
  455. package/dist/orphan-triage.d.ts +130 -0
  456. package/dist/orphan-triage.d.ts.map +1 -0
  457. package/dist/orphan-triage.js +207 -0
  458. package/dist/orphan-triage.js.map +1 -0
  459. package/dist/outbound-sessions.d.ts +126 -0
  460. package/dist/outbound-sessions.d.ts.map +1 -0
  461. package/dist/outbound-sessions.js +1052 -0
  462. package/dist/outbound-sessions.js.map +1 -0
  463. package/dist/park-envelope.d.ts +329 -0
  464. package/dist/park-envelope.d.ts.map +1 -0
  465. package/dist/park-envelope.js +509 -0
  466. package/dist/park-envelope.js.map +1 -0
  467. package/dist/park-recovery.d.ts +273 -0
  468. package/dist/park-recovery.d.ts.map +1 -0
  469. package/dist/park-recovery.js +717 -0
  470. package/dist/park-recovery.js.map +1 -0
  471. package/dist/park-refusals.d.ts +147 -0
  472. package/dist/park-refusals.d.ts.map +1 -0
  473. package/dist/park-refusals.js +331 -0
  474. package/dist/park-refusals.js.map +1 -0
  475. package/dist/quarantine-framing.d.ts +92 -0
  476. package/dist/quarantine-framing.d.ts.map +1 -0
  477. package/dist/quarantine-framing.js +111 -0
  478. package/dist/quarantine-framing.js.map +1 -0
  479. package/dist/reconnect-drain.d.ts +22 -0
  480. package/dist/reconnect-drain.d.ts.map +1 -0
  481. package/dist/reconnect-drain.js +65 -0
  482. package/dist/reconnect-drain.js.map +1 -0
  483. package/dist/recovered-position.d.ts +14 -0
  484. package/dist/recovered-position.d.ts.map +1 -0
  485. package/dist/recovered-position.js +59 -0
  486. package/dist/recovered-position.js.map +1 -0
  487. package/dist/refusal-notices.d.ts +196 -0
  488. package/dist/refusal-notices.d.ts.map +1 -0
  489. package/dist/refusal-notices.js +516 -0
  490. package/dist/refusal-notices.js.map +1 -0
  491. package/dist/refusal-reasons.d.ts +245 -0
  492. package/dist/refusal-reasons.d.ts.map +1 -0
  493. package/dist/refusal-reasons.js +363 -0
  494. package/dist/refusal-reasons.js.map +1 -0
  495. package/dist/register-handler.d.ts +36 -0
  496. package/dist/register-handler.d.ts.map +1 -0
  497. package/dist/register-handler.js +285 -0
  498. package/dist/register-handler.js.map +1 -0
  499. package/dist/registration-context.d.ts +72 -0
  500. package/dist/registration-context.d.ts.map +1 -0
  501. package/dist/registration-context.js +126 -0
  502. package/dist/registration-context.js.map +1 -0
  503. package/dist/registration-manager.d.ts +94 -0
  504. package/dist/registration-manager.d.ts.map +1 -0
  505. package/dist/registration-manager.js +585 -0
  506. package/dist/registration-manager.js.map +1 -0
  507. package/dist/registration-persistence.d.ts +183 -0
  508. package/dist/registration-persistence.d.ts.map +1 -0
  509. package/dist/registration-persistence.js +263 -0
  510. package/dist/registration-persistence.js.map +1 -0
  511. package/dist/registry-poll.d.ts +52 -0
  512. package/dist/registry-poll.d.ts.map +1 -0
  513. package/dist/registry-poll.js +140 -0
  514. package/dist/registry-poll.js.map +1 -0
  515. package/dist/registry-version-store-db.d.ts +22 -0
  516. package/dist/registry-version-store-db.d.ts.map +1 -0
  517. package/dist/registry-version-store-db.js +50 -0
  518. package/dist/registry-version-store-db.js.map +1 -0
  519. package/dist/relay-endpoints.d.ts +18 -0
  520. package/dist/relay-endpoints.d.ts.map +1 -0
  521. package/dist/relay-endpoints.js +9 -0
  522. package/dist/relay-endpoints.js.map +1 -0
  523. package/dist/relay-only.d.ts +140 -0
  524. package/dist/relay-only.d.ts.map +1 -0
  525. package/dist/relay-only.js +193 -0
  526. package/dist/relay-only.js.map +1 -0
  527. package/dist/relay-receipt-store.d.ts +155 -0
  528. package/dist/relay-receipt-store.d.ts.map +1 -0
  529. package/dist/relay-receipt-store.js +284 -0
  530. package/dist/relay-receipt-store.js.map +1 -0
  531. package/dist/relay-reconnect.d.ts +32 -0
  532. package/dist/relay-reconnect.d.ts.map +1 -0
  533. package/dist/relay-reconnect.js +29 -0
  534. package/dist/relay-reconnect.js.map +1 -0
  535. package/dist/reply-lag.d.ts +11 -0
  536. package/dist/reply-lag.d.ts.map +1 -0
  537. package/dist/reply-lag.js +46 -0
  538. package/dist/reply-lag.js.map +1 -0
  539. package/dist/resolve-named-agent.d.ts +49 -0
  540. package/dist/resolve-named-agent.d.ts.map +1 -0
  541. package/dist/resolve-named-agent.js +77 -0
  542. package/dist/resolve-named-agent.js.map +1 -0
  543. package/dist/restart-seal-resolver.d.ts +110 -0
  544. package/dist/restart-seal-resolver.d.ts.map +1 -0
  545. package/dist/restart-seal-resolver.js +353 -0
  546. package/dist/restart-seal-resolver.js.map +1 -0
  547. package/dist/resume-last-seen.d.ts +15 -0
  548. package/dist/resume-last-seen.d.ts.map +1 -0
  549. package/dist/resume-last-seen.js +44 -0
  550. package/dist/resume-last-seen.js.map +1 -0
  551. package/dist/retry-queue.d.ts +203 -0
  552. package/dist/retry-queue.d.ts.map +1 -0
  553. package/dist/retry-queue.js +701 -0
  554. package/dist/retry-queue.js.map +1 -0
  555. package/dist/roster-freshness.d.ts +160 -0
  556. package/dist/roster-freshness.d.ts.map +1 -0
  557. package/dist/roster-freshness.js +250 -0
  558. package/dist/roster-freshness.js.map +1 -0
  559. package/dist/screening-status.d.ts +15 -0
  560. package/dist/screening-status.d.ts.map +1 -0
  561. package/dist/screening-status.js +65 -0
  562. package/dist/screening-status.js.map +1 -0
  563. package/dist/seal-carried-close.d.ts +37 -0
  564. package/dist/seal-carried-close.d.ts.map +1 -0
  565. package/dist/seal-carried-close.js +179 -0
  566. package/dist/seal-carried-close.js.map +1 -0
  567. package/dist/seal-certificate-pull.d.ts +79 -0
  568. package/dist/seal-certificate-pull.d.ts.map +1 -0
  569. package/dist/seal-certificate-pull.js +186 -0
  570. package/dist/seal-certificate-pull.js.map +1 -0
  571. package/dist/seal-certified-root-check.d.ts +37 -0
  572. package/dist/seal-certified-root-check.d.ts.map +1 -0
  573. package/dist/seal-certified-root-check.js +127 -0
  574. package/dist/seal-certified-root-check.js.map +1 -0
  575. package/dist/seal-coordinator.d.ts +118 -0
  576. package/dist/seal-coordinator.d.ts.map +1 -0
  577. package/dist/seal-coordinator.js +927 -0
  578. package/dist/seal-coordinator.js.map +1 -0
  579. package/dist/seal-escalation.d.ts +80 -0
  580. package/dist/seal-escalation.d.ts.map +1 -0
  581. package/dist/seal-escalation.js +283 -0
  582. package/dist/seal-escalation.js.map +1 -0
  583. package/dist/seal-evidence-root-check.d.ts +70 -0
  584. package/dist/seal-evidence-root-check.d.ts.map +1 -0
  585. package/dist/seal-evidence-root-check.js +199 -0
  586. package/dist/seal-evidence-root-check.js.map +1 -0
  587. package/dist/seal-failure-store.d.ts +139 -0
  588. package/dist/seal-failure-store.d.ts.map +1 -0
  589. package/dist/seal-failure-store.js +207 -0
  590. package/dist/seal-failure-store.js.map +1 -0
  591. package/dist/seal-flows.d.ts +107 -0
  592. package/dist/seal-flows.d.ts.map +1 -0
  593. package/dist/seal-flows.js +638 -0
  594. package/dist/seal-flows.js.map +1 -0
  595. package/dist/seal-frontier-verify.d.ts +103 -0
  596. package/dist/seal-frontier-verify.d.ts.map +1 -0
  597. package/dist/seal-frontier-verify.js +143 -0
  598. package/dist/seal-frontier-verify.js.map +1 -0
  599. package/dist/seal-leaf.d.ts +58 -0
  600. package/dist/seal-leaf.d.ts.map +1 -0
  601. package/dist/seal-leaf.js +112 -0
  602. package/dist/seal-leaf.js.map +1 -0
  603. package/dist/seal-legibility-tbs.d.ts +25 -0
  604. package/dist/seal-legibility-tbs.d.ts.map +1 -0
  605. package/dist/seal-legibility-tbs.js +77 -0
  606. package/dist/seal-legibility-tbs.js.map +1 -0
  607. package/dist/seal-local-terminus.d.ts +41 -0
  608. package/dist/seal-local-terminus.d.ts.map +1 -0
  609. package/dist/seal-local-terminus.js +170 -0
  610. package/dist/seal-local-terminus.js.map +1 -0
  611. package/dist/seal-receipt-upgrade.d.ts +30 -0
  612. package/dist/seal-receipt-upgrade.d.ts.map +1 -0
  613. package/dist/seal-receipt-upgrade.js +49 -0
  614. package/dist/seal-receipt-upgrade.js.map +1 -0
  615. package/dist/seal-relay-silence.d.ts +51 -0
  616. package/dist/seal-relay-silence.d.ts.map +1 -0
  617. package/dist/seal-relay-silence.js +76 -0
  618. package/dist/seal-relay-silence.js.map +1 -0
  619. package/dist/seal-settle.d.ts +38 -0
  620. package/dist/seal-settle.d.ts.map +1 -0
  621. package/dist/seal-settle.js +33 -0
  622. package/dist/seal-settle.js.map +1 -0
  623. package/dist/seal-upgrade.d.ts +107 -0
  624. package/dist/seal-upgrade.d.ts.map +1 -0
  625. package/dist/seal-upgrade.js +200 -0
  626. package/dist/seal-upgrade.js.map +1 -0
  627. package/dist/sealed-conversation.d.ts +36 -0
  628. package/dist/sealed-conversation.d.ts.map +1 -0
  629. package/dist/sealed-conversation.js +171 -0
  630. package/dist/sealed-conversation.js.map +1 -0
  631. package/dist/sealed-leaf-set.d.ts +92 -0
  632. package/dist/sealed-leaf-set.d.ts.map +1 -0
  633. package/dist/sealed-leaf-set.js +122 -0
  634. package/dist/sealed-leaf-set.js.map +1 -0
  635. package/dist/send-claims.d.ts +56 -0
  636. package/dist/send-claims.d.ts.map +1 -0
  637. package/dist/send-claims.js +50 -0
  638. package/dist/send-claims.js.map +1 -0
  639. package/dist/session-assignment-parser.d.ts +104 -0
  640. package/dist/session-assignment-parser.d.ts.map +1 -0
  641. package/dist/session-assignment-parser.js +345 -0
  642. package/dist/session-assignment-parser.js.map +1 -0
  643. package/dist/session-category.d.ts +19 -0
  644. package/dist/session-category.d.ts.map +1 -0
  645. package/dist/session-category.js +14 -0
  646. package/dist/session-category.js.map +1 -0
  647. package/dist/session-ceremony.d.ts +297 -0
  648. package/dist/session-ceremony.d.ts.map +1 -0
  649. package/dist/session-ceremony.js +964 -0
  650. package/dist/session-ceremony.js.map +1 -0
  651. package/dist/session-closed.d.ts +79 -0
  652. package/dist/session-closed.d.ts.map +1 -0
  653. package/dist/session-closed.js +189 -0
  654. package/dist/session-closed.js.map +1 -0
  655. package/dist/session-connection-gater.d.ts +148 -0
  656. package/dist/session-connection-gater.d.ts.map +1 -0
  657. package/dist/session-connection-gater.js +332 -0
  658. package/dist/session-connection-gater.js.map +1 -0
  659. package/dist/session-content-context.d.ts +162 -0
  660. package/dist/session-content-context.d.ts.map +1 -0
  661. package/dist/session-content-context.js +2 -0
  662. package/dist/session-content-context.js.map +1 -0
  663. package/dist/session-content-handlers.d.ts +82 -0
  664. package/dist/session-content-handlers.d.ts.map +1 -0
  665. package/dist/session-content-handlers.js +1382 -0
  666. package/dist/session-content-handlers.js.map +1 -0
  667. package/dist/session-content-ingest.d.ts +206 -0
  668. package/dist/session-content-ingest.d.ts.map +1 -0
  669. package/dist/session-content-ingest.js +2167 -0
  670. package/dist/session-content-ingest.js.map +1 -0
  671. package/dist/session-content-send.d.ts +191 -0
  672. package/dist/session-content-send.d.ts.map +1 -0
  673. package/dist/session-content-send.js +1360 -0
  674. package/dist/session-content-send.js.map +1 -0
  675. package/dist/session-delivery-acks.d.ts +169 -0
  676. package/dist/session-delivery-acks.d.ts.map +1 -0
  677. package/dist/session-delivery-acks.js +569 -0
  678. package/dist/session-delivery-acks.js.map +1 -0
  679. package/dist/session-ephemerals.d.ts +279 -0
  680. package/dist/session-ephemerals.d.ts.map +1 -0
  681. package/dist/session-ephemerals.js +591 -0
  682. package/dist/session-ephemerals.js.map +1 -0
  683. package/dist/session-leaf-records.d.ts +159 -0
  684. package/dist/session-leaf-records.d.ts.map +1 -0
  685. package/dist/session-leaf-records.js +408 -0
  686. package/dist/session-leaf-records.js.map +1 -0
  687. package/dist/session-lifecycle.d.ts +303 -0
  688. package/dist/session-lifecycle.d.ts.map +1 -0
  689. package/dist/session-lifecycle.js +1679 -0
  690. package/dist/session-lifecycle.js.map +1 -0
  691. package/dist/session-liveness.d.ts +135 -0
  692. package/dist/session-liveness.d.ts.map +1 -0
  693. package/dist/session-liveness.js +347 -0
  694. package/dist/session-liveness.js.map +1 -0
  695. package/dist/session-name.d.ts +35 -0
  696. package/dist/session-name.d.ts.map +1 -0
  697. package/dist/session-name.js +60 -0
  698. package/dist/session-name.js.map +1 -0
  699. package/dist/session-node-factory.d.ts +18 -0
  700. package/dist/session-node-factory.d.ts.map +1 -0
  701. package/dist/session-node-factory.js +182 -0
  702. package/dist/session-node-factory.js.map +1 -0
  703. package/dist/session-node-manager.d.ts +877 -0
  704. package/dist/session-node-manager.d.ts.map +1 -0
  705. package/dist/session-node-manager.js +2998 -0
  706. package/dist/session-node-manager.js.map +1 -0
  707. package/dist/session-node-types.d.ts +1057 -0
  708. package/dist/session-node-types.d.ts.map +1 -0
  709. package/dist/session-node-types.js +657 -0
  710. package/dist/session-node-types.js.map +1 -0
  711. package/dist/session-notify.d.ts +46 -0
  712. package/dist/session-notify.d.ts.map +1 -0
  713. package/dist/session-notify.js +116 -0
  714. package/dist/session-notify.js.map +1 -0
  715. package/dist/session-own-chain-store.d.ts +65 -0
  716. package/dist/session-own-chain-store.d.ts.map +1 -0
  717. package/dist/session-own-chain-store.js +75 -0
  718. package/dist/session-own-chain-store.js.map +1 -0
  719. package/dist/session-queries.d.ts +476 -0
  720. package/dist/session-queries.d.ts.map +1 -0
  721. package/dist/session-queries.js +1007 -0
  722. package/dist/session-queries.js.map +1 -0
  723. package/dist/session-read-handlers.d.ts +87 -0
  724. package/dist/session-read-handlers.d.ts.map +1 -0
  725. package/dist/session-read-handlers.js +689 -0
  726. package/dist/session-read-handlers.js.map +1 -0
  727. package/dist/session-records.d.ts +341 -0
  728. package/dist/session-records.d.ts.map +1 -0
  729. package/dist/session-records.js +858 -0
  730. package/dist/session-records.js.map +1 -0
  731. package/dist/session-relay-client.d.ts +659 -0
  732. package/dist/session-relay-client.d.ts.map +1 -0
  733. package/dist/session-relay-client.js +2876 -0
  734. package/dist/session-relay-client.js.map +1 -0
  735. package/dist/session-relay.d.ts +397 -0
  736. package/dist/session-relay.d.ts.map +1 -0
  737. package/dist/session-relay.js +1636 -0
  738. package/dist/session-relay.js.map +1 -0
  739. package/dist/session-salt-agreement.d.ts +331 -0
  740. package/dist/session-salt-agreement.d.ts.map +1 -0
  741. package/dist/session-salt-agreement.js +472 -0
  742. package/dist/session-salt-agreement.js.map +1 -0
  743. package/dist/session-salts.d.ts +432 -0
  744. package/dist/session-salts.d.ts.map +1 -0
  745. package/dist/session-salts.js +1540 -0
  746. package/dist/session-salts.js.map +1 -0
  747. package/dist/session-schema.d.ts +30 -0
  748. package/dist/session-schema.d.ts.map +1 -0
  749. package/dist/session-schema.js +877 -0
  750. package/dist/session-schema.js.map +1 -0
  751. package/dist/session-seal-leaf-store.d.ts +70 -0
  752. package/dist/session-seal-leaf-store.d.ts.map +1 -0
  753. package/dist/session-seal-leaf-store.js +105 -0
  754. package/dist/session-seal-leaf-store.js.map +1 -0
  755. package/dist/session-seal.d.ts +334 -0
  756. package/dist/session-seal.d.ts.map +1 -0
  757. package/dist/session-seal.js +1017 -0
  758. package/dist/session-seal.js.map +1 -0
  759. package/dist/session-terminal-refusal.d.ts +65 -0
  760. package/dist/session-terminal-refusal.d.ts.map +1 -0
  761. package/dist/session-terminal-refusal.js +87 -0
  762. package/dist/session-terminal-refusal.js.map +1 -0
  763. package/dist/session-tree.d.ts +110 -0
  764. package/dist/session-tree.d.ts.map +1 -0
  765. package/dist/session-tree.js +144 -0
  766. package/dist/session-tree.js.map +1 -0
  767. package/dist/session-views.d.ts +47 -0
  768. package/dist/session-views.d.ts.map +1 -0
  769. package/dist/session-views.js +278 -0
  770. package/dist/session-views.js.map +1 -0
  771. package/dist/signal-handlers.d.ts +63 -0
  772. package/dist/signal-handlers.d.ts.map +1 -0
  773. package/dist/signal-handlers.js +980 -0
  774. package/dist/signal-handlers.js.map +1 -0
  775. package/dist/signal-requirement-policy.d.ts +51 -0
  776. package/dist/signal-requirement-policy.d.ts.map +1 -0
  777. package/dist/signal-requirement-policy.js +89 -0
  778. package/dist/signal-requirement-policy.js.map +1 -0
  779. package/dist/signal-revocability.d.ts +49 -0
  780. package/dist/signal-revocability.d.ts.map +1 -0
  781. package/dist/signal-revocability.js +93 -0
  782. package/dist/signal-revocability.js.map +1 -0
  783. package/dist/signal-submission.d.ts +181 -0
  784. package/dist/signal-submission.d.ts.map +1 -0
  785. package/dist/signal-submission.js +368 -0
  786. package/dist/signal-submission.js.map +1 -0
  787. package/dist/signaling-connect.d.ts +118 -0
  788. package/dist/signaling-connect.d.ts.map +1 -0
  789. package/dist/signaling-connect.js +538 -0
  790. package/dist/signaling-connect.js.map +1 -0
  791. package/dist/signaling-wiring.d.ts +105 -0
  792. package/dist/signaling-wiring.d.ts.map +1 -0
  793. package/dist/signaling-wiring.js +393 -0
  794. package/dist/signaling-wiring.js.map +1 -0
  795. package/dist/singleton-lock.d.ts +85 -0
  796. package/dist/singleton-lock.d.ts.map +1 -0
  797. package/dist/singleton-lock.js +219 -0
  798. package/dist/singleton-lock.js.map +1 -0
  799. package/dist/sqlcipher-db.d.ts +139 -0
  800. package/dist/sqlcipher-db.d.ts.map +1 -0
  801. package/dist/sqlcipher-db.js +357 -0
  802. package/dist/sqlcipher-db.js.map +1 -0
  803. package/dist/standing-receivers.d.ts +319 -0
  804. package/dist/standing-receivers.d.ts.map +1 -0
  805. package/dist/standing-receivers.js +1295 -0
  806. package/dist/standing-receivers.js.map +1 -0
  807. package/dist/start-agent.d.ts +64 -0
  808. package/dist/start-agent.d.ts.map +1 -0
  809. package/dist/start-agent.js +136 -0
  810. package/dist/start-agent.js.map +1 -0
  811. package/dist/status-handler.d.ts +54 -0
  812. package/dist/status-handler.d.ts.map +1 -0
  813. package/dist/status-handler.js +61 -0
  814. package/dist/status-handler.js.map +1 -0
  815. package/dist/submission-retry.d.ts +208 -0
  816. package/dist/submission-retry.d.ts.map +1 -0
  817. package/dist/submission-retry.js +506 -0
  818. package/dist/submission-retry.js.map +1 -0
  819. package/dist/telegram-bot-client.d.ts +34 -0
  820. package/dist/telegram-bot-client.d.ts.map +1 -0
  821. package/dist/telegram-bot-client.js +36 -0
  822. package/dist/telegram-bot-client.js.map +1 -0
  823. package/dist/telegram-doorbell.d.ts +38 -0
  824. package/dist/telegram-doorbell.d.ts.map +1 -0
  825. package/dist/telegram-doorbell.js +140 -0
  826. package/dist/telegram-doorbell.js.map +1 -0
  827. package/dist/test-handlers.d.ts +62 -0
  828. package/dist/test-handlers.d.ts.map +1 -0
  829. package/dist/test-handlers.js +240 -0
  830. package/dist/test-handlers.js.map +1 -0
  831. package/dist/testing.d.ts +10 -0
  832. package/dist/testing.d.ts.map +1 -0
  833. package/dist/testing.js +10 -0
  834. package/dist/testing.js.map +1 -0
  835. package/dist/transport-composition.d.ts +31 -0
  836. package/dist/transport-composition.d.ts.map +1 -0
  837. package/dist/transport-composition.js +55 -0
  838. package/dist/transport-composition.js.map +1 -0
  839. package/dist/transport-selector.d.ts +202 -0
  840. package/dist/transport-selector.d.ts.map +1 -0
  841. package/dist/transport-selector.js +196 -0
  842. package/dist/transport-selector.js.map +1 -0
  843. package/dist/trust-signal-pickup-listener.d.ts +43 -0
  844. package/dist/trust-signal-pickup-listener.d.ts.map +1 -0
  845. package/dist/trust-signal-pickup-listener.js +48 -0
  846. package/dist/trust-signal-pickup-listener.js.map +1 -0
  847. package/dist/trust-signal-store.d.ts +406 -0
  848. package/dist/trust-signal-store.d.ts.map +1 -0
  849. package/dist/trust-signal-store.js +939 -0
  850. package/dist/trust-signal-store.js.map +1 -0
  851. package/dist/trust-signal-sweep-tick.d.ts +60 -0
  852. package/dist/trust-signal-sweep-tick.d.ts.map +1 -0
  853. package/dist/trust-signal-sweep-tick.js +101 -0
  854. package/dist/trust-signal-sweep-tick.js.map +1 -0
  855. package/dist/trust-signal-sweep.d.ts +94 -0
  856. package/dist/trust-signal-sweep.d.ts.map +1 -0
  857. package/dist/trust-signal-sweep.js +147 -0
  858. package/dist/trust-signal-sweep.js.map +1 -0
  859. package/dist/type-registry.d.ts +42 -0
  860. package/dist/type-registry.d.ts.map +1 -0
  861. package/dist/type-registry.js +37 -0
  862. package/dist/type-registry.js.map +1 -0
  863. package/dist/types.d.ts +746 -0
  864. package/dist/types.d.ts.map +1 -0
  865. package/dist/types.js +20 -0
  866. package/dist/types.js.map +1 -0
  867. package/dist/unresolved-nodes-report.d.ts +14 -0
  868. package/dist/unresolved-nodes-report.d.ts.map +1 -0
  869. package/dist/unresolved-nodes-report.js +96 -0
  870. package/dist/unresolved-nodes-report.js.map +1 -0
  871. package/dist/vocabulary.d.ts +150 -0
  872. package/dist/vocabulary.d.ts.map +1 -0
  873. package/dist/vocabulary.js +386 -0
  874. package/dist/vocabulary.js.map +1 -0
  875. package/dist/who-label.d.ts +28 -0
  876. package/dist/who-label.d.ts.map +1 -0
  877. package/dist/who-label.js +31 -0
  878. package/dist/who-label.js.map +1 -0
  879. package/dist/who-resolver.d.ts +15 -0
  880. package/dist/who-resolver.d.ts.map +1 -0
  881. package/dist/who-resolver.js +47 -0
  882. package/dist/who-resolver.js.map +1 -0
  883. package/dist/wire-content-hash.d.ts +93 -0
  884. package/dist/wire-content-hash.d.ts.map +1 -0
  885. package/dist/wire-content-hash.js +116 -0
  886. package/dist/wire-content-hash.js.map +1 -0
  887. package/dist/withheld-content.d.ts +13 -0
  888. package/dist/withheld-content.d.ts.map +1 -0
  889. package/dist/withheld-content.js +46 -0
  890. package/dist/withheld-content.js.map +1 -0
  891. package/dist/witness-alerts.d.ts +40 -0
  892. package/dist/witness-alerts.d.ts.map +1 -0
  893. package/dist/witness-alerts.js +102 -0
  894. package/dist/witness-alerts.js.map +1 -0
  895. package/package.json +5 -5
@@ -0,0 +1,1017 @@
1
+ /**
2
+ * CELLO Daemon — CLOSING A CONVERSATION, AND PROVING IT CLOSED
3
+ *
4
+ * Split out of `session-node-manager.ts`. The seal is the artefact the whole product exists to
5
+ * produce: when both parties close, each holds a notarized root over the same transcript, and
6
+ * either can later show a third party that the conversation happened and was not altered.
7
+ *
8
+ * What is here: deciding whether a session is ready to seal and telling the operator when it is
9
+ * not, submitting our own SEAL leaf, carrying the counterparty's, persisting the commitment when a
10
+ * close is interrupted, recording the certificate, verifying a certified root against our own tree,
11
+ * and the auto-acknowledgement gate that lets a seal complete without a human on both ends.
12
+ *
13
+ * **Moved verbatim, comments included.**
14
+ *
15
+ * ⚠️ **THE TWO STORES BELOW ARE OPENED LAZILY, and that is why they are read-write on the context
16
+ * rather than passed in.** Both are created on first use, because they need the database and the
17
+ * database is opened long after the manager is constructed. The manager and this file must see the
18
+ * SAME instance — a second `SessionSealLeafStore` over the same rows is two writers that agree only
19
+ * by luck.
20
+ */
21
+ import { createHash } from "node:crypto";
22
+ import { closeOverCarriedEvidence } from "./seal-carried-close.js";
23
+ import { verifyCertifiedRoot as judgeCertifiedRoot } from "./seal-certified-root-check.js";
24
+ import { judgeFromEvidence } from "./seal-evidence-root-check.js";
25
+ import { encodeSealPayload, decodeStructure1 } from "@cello-protocol/protocol-types";
26
+ import { AUTOACK_BROKER_GRACE_MS } from "./session-node-types.js";
27
+ import { LEAF_KIND_CTRL } from "./session-relay-client.js";
28
+ import { RelayReceiptStore } from "./relay-receipt-store.js";
29
+ import { SessionSealLeafStore } from "./session-seal-leaf-store.js";
30
+ import { withheldPositionsOrNone } from "./withheld-content.js";
31
+ import { extractErrorMessage } from "./error-message.js";
32
+ import { awaitOwnRecordSettled, SEAL_SETTLE_DEADLINE_MS as SEAL_STALE_WAIT_MS } from "./seal-settle.js";
33
+ export class SessionSeal {
34
+ #ctx;
35
+ /**
36
+ * Sessions whose closing leaf THIS PROCESS signed locally, because no relay answered.
37
+ *
38
+ * Kept beside the idempotency mark rather than inside it: a retried close reads the mark and gets
39
+ * `responder_seal_already_submitted`, and without this it would lose the one fact that makes the
40
+ * eleven-minute bilateral wait pointless — so the retry would sit out a window for a ceremony that
41
+ * still cannot begin. In memory only; a restart correctly re-derives it by trying the relay again.
42
+ */
43
+ #closedViaLocalTerminus = new Set();
44
+ constructor(ctx) {
45
+ this.#ctx = ctx;
46
+ }
47
+ /** A getter so the moved queries still read `this.#db` and narrow exactly as they did. */
48
+ get #db() {
49
+ return this.#ctx.db();
50
+ }
51
+ /**
52
+ * M12-P15: what a seal leaf actually needs, resolved from a LIVE node when there is one and from
53
+ * durable state when there is not.
54
+ *
55
+ * `submitSealLeaf` used to hard-require an `#activeNodes` entry. But it is reachable — by design —
56
+ * for an `interrupted` session, and EVERY producer of that status deletes the entry. So the guard
57
+ * refused 100% of the calls the seal-interrupted path could ever make, which is what made M12-P15's
58
+ * first fix inert. `submitLeaf(node, sessionId, contentHash, leafKind)` takes everything
59
+ * explicitly; nothing about it needs a per-session node.
60
+ *
61
+ * The fallback is the same shape `startupParkFn` already uses for content: the persisted relay
62
+ * endpoint (`relay_peer_id`/`relay_addrs`, columns that exist for exactly this reason) plus the
63
+ * owning agent's standing receiver. Every failure is named for its own cause rather than collapsed
64
+ * into "no node", because that collapse is what sent this investigation at the session lifecycle
65
+ * instead of at the endpoint.
66
+ */
67
+ #resolveSealTransport(agentName, sessionId) {
68
+ const entry = this.#ctx.activeNodes.get(this.#ctx.sessionKey(agentName, sessionId));
69
+ if (entry) {
70
+ // The live path is unchanged and takes precedence — a session with its own registered client
71
+ // must never seal through a rebuilt one.
72
+ if (!entry.relayClient || !entry.relaySessionIdBytes)
73
+ return { error: "relay_unavailable" };
74
+ return { node: entry.node, relayClient: entry.relayClient, relaySessionIdBytes: entry.relaySessionIdBytes };
75
+ }
76
+ const ep = this.#ctx.queries.getPersistedRelayEndpoint(agentName, sessionId);
77
+ if (!ep)
78
+ return { error: "no_persisted_relay_endpoint" };
79
+ const node = this.#ctx.receivers.getStandingReceiverNode(agentName);
80
+ if (!node)
81
+ return { error: "standing_receiver_unavailable" };
82
+ // Reuse the agent's existing client for this relay when the process still has one; otherwise ask
83
+ // the composition root to build one. Without the builder this path would work only within the
84
+ // lifetime that created the session — and the case that matters most is precisely a daemon that
85
+ // RESTARTED, which is what marked the session interrupted in the first place.
86
+ const clientKey = `${agentName}::${ep.relayPeerId}`;
87
+ let client = this.#ctx.relayClients.get(clientKey);
88
+ if (!client) {
89
+ // Review HIGH-1: the stores are NOT optional here. Without them `#captureReceipt` silently
90
+ // `return false`s — the submit still reports ok while the relay's signed receipt and our OWN
91
+ // 0x02 ctrl leaf are never persisted. That drops the unilateral-escalation carry chain AND
92
+ // defeats this very unit's ceremony discriminator, which reads `session_seal_leaves`: a seal
93
+ // sent through here would later read as "ceremony unknown" and the peer would decline to
94
+ // sign. The fix would have broken the fix.
95
+ if (!this.#ctx.relayReceiptStore && this.#db)
96
+ this.#ctx.relayReceiptStore = new RelayReceiptStore(this.#db, this.#ctx.logger);
97
+ if (!this.#ctx.sealLeafStore && this.#db)
98
+ this.#ctx.sealLeafStore = new SessionSealLeafStore(this.#db, this.#ctx.logger);
99
+ client = this.#ctx.detachedRelayClientBuilder?.(agentName, ep.relayPeerId, [...ep.relayAddrs], {
100
+ receiptStore: this.#ctx.relayReceiptStore ?? undefined,
101
+ sealLeafStore: this.#ctx.sealLeafStore ?? undefined,
102
+ ownChainStore: this.#ctx.ownChainStore ?? undefined,
103
+ // DOD-M15-RELAYSLOTS-1: read at each auth, never snapshotted — the token expires hourly.
104
+ onlineToken: () => this.#ctx.getDirectoryOnlineToken(agentName),
105
+ });
106
+ if (!client)
107
+ return { error: "relay_client_unavailable" };
108
+ // Review MEDIUM-4: cache it, so a retry loop does not leak one authenticated relay stream per
109
+ // attempt. Safe ONLY because the client above now carries the stores — a store-less client
110
+ // cached under this key would be picked up by the live `#connectSessionRelay` path and poison
111
+ // it for the rest of the process.
112
+ this.#ctx.relayClients.set(clientKey, client);
113
+ }
114
+ // Review HIGH-2: register the session (no assignment — there is nothing to re-present) so the
115
+ // relay's `session_not_found` is interpreted honestly. Unregistered, `recordedBefore` is false,
116
+ // the retry loop runs pointlessly, and the `recordedBefore && session_not_found ->
117
+ // relay_session_gone` branch — which exists to tell "the relay never had it" apart from "the
118
+ // relay swept or sealed it" — can never fire, so the operator is handed a first-message-race
119
+ // label for a swept session.
120
+ /**
121
+ * DOD-M15-RELAYLEAK-1 — **RE-REGISTERING A SESSION THAT IS ALREADY REGISTERED BLINDS IT.**
122
+ *
123
+ * `registerSession` REPLACES the entry's `onLeafDeliver` with `onLeafDeliver ?? (() => {})`, and
124
+ * unlike `assignment` / `recorded` it does NOT carry the existing handler forward. **This path
125
+ * passes no handler.** So a detached seal on a session that still holds a live registration
126
+ * would swap that session's inbound leaf delivery for a no-op: the counterparty's leaves keep
127
+ * arriving at the relay client and are dropped on the floor, while the operator sees a healthy
128
+ * session that has simply gone quiet.
129
+ *
130
+ * A call that finds the session already registered is therefore a PASSENGER: it uses the client
131
+ * and touches nothing. It also does not release — ownership is never inferred, only claimed.
132
+ *
133
+ * ⚠️ **This is NOT justified by a concurrency race, and an earlier version of this comment said
134
+ * it was.** Review checked: `#resolveSealTransport` and everything above the first `await` are
135
+ * synchronous, and a second caller plants/hits `#responderSealSubmitted` and returns
136
+ * `responder_seal_already_submitted` before ever reaching `submitLeaf`. Two callers cannot be in
137
+ * the client at once through the only caller, so "the second one closes the client the first is
138
+ * awaiting" **cannot happen**. The wrong reason mattered: it invites a future reader to delete
139
+ * this guard as defensive clutter once they notice the race is impossible — taking the
140
+ * handler-clobbering protection with it.
141
+ */
142
+ const claimedRegistration = !client.hasSession(sessionId);
143
+ if (claimedRegistration) {
144
+ // 033-ACKEMIT: the seal transport submits a ctrl leaf like any other, so it needs the same
145
+ // acknowledgement seed. It carries no assignment of its own, so the genesis is supplied here
146
+ // from the session's own active entry rather than derived inside the client.
147
+ // 069-ORDERPROOF: the seal's ctrl leaf is submitted like any other and needs the same anchor.
148
+ // It carries no assignment, so this comes from the session's durable record — without it the
149
+ // relay's attestation for the SEAL leaf is refused and the close cannot settle.
150
+ client.registerSession(sessionId, node, undefined, undefined, this.#ctx.leafRecords.sessionGenesisPrevRoot(agentName, sessionId), this.#ctx.leafRecords.sessionRelayAnchor(agentName, sessionId));
151
+ }
152
+ else {
153
+ /**
154
+ * Review MEDIUM-1 — **A PATH THAT DECLINES TO FIX A LEAK MUST SAY SO.**
155
+ *
156
+ * Reaching here means the session is registered on this client while `#activeNodes` holds no
157
+ * entry for it — and the ways that happens are all orphans: a previous `releaseDetached()`
158
+ * that threw (loud once, then silent forever after), or a revival that registered and then
159
+ * failed to hang the client on an entry. Declining to unregister is right — we cannot prove
160
+ * no live session owns it — but without this line the orphan is invisible, which is the exact
161
+ * shape this whole line exists to remove.
162
+ */
163
+ this.#ctx.logger.info("session.seal.transport.registration_shared", {
164
+ agentName,
165
+ sessionId,
166
+ impact: "this seal is using a relay registration it did not create, so it will not release it. If " +
167
+ "no live session owns that registration the client is held until process exit.",
168
+ });
169
+ }
170
+ /**
171
+ * DOD-M15-RELAYLEAK-1 — **`releaseOnDone` IS THE RELEASE SIGNAL, and its absence was the leak.**
172
+ *
173
+ * This branch (no `#activeNodes` entry) CACHES a relay client and registers a session on it, and
174
+ * nothing ever unregistered. `#detachSessionRelay` closes a client only when
175
+ * `!client.hasSessions()`, so a registration that is never removed keeps that predicate false
176
+ * **forever** — the client, its authenticated stream and its reader survive for the process
177
+ * lifetime. The LIVE branch above registers nothing here, so only this one needs releasing, and
178
+ * marking it is what lets the caller tell them apart without guessing.
179
+ */
180
+ return {
181
+ node,
182
+ relayClient: client,
183
+ relaySessionIdBytes: new Uint8Array(Buffer.from(sessionId, "hex")),
184
+ // Not `true` unconditionally: a passenger call must not release a registration it did not
185
+ // claim — see the note above `claimedRegistration`.
186
+ ...(claimedRegistration ? { releaseOnDone: true } : {}),
187
+ };
188
+ }
189
+ /**
190
+ * Does a certificate describe the leaf set this daemon holds? The judgement lives in
191
+ * `seal-certified-root-check.ts`; this binds it to this instance's carry.
192
+ */
193
+ verifyCertifiedRoot(agentPubkeyHex, sessionIdHex, certifiedRoot, certifiedLeafCount, evidence) {
194
+ const own = judgeCertifiedRoot((pk, sid) => this.getSealCarry(pk, sid), agentPubkeyHex, sessionIdHex, certifiedRoot, certifiedLeafCount);
195
+ if (own.verdict !== "cannot_judge" || !evidence || evidence.length === 0)
196
+ return own;
197
+ return judgeFromEvidence({ ownCarry: this.getSealCarry(agentPubkeyHex, sessionIdHex), db: this.#ctx.db(), logger: this.#ctx.logger }, { ownReason: own.reason, agentPubkeyHex, sessionIdHex, certifiedRoot, certifiedLeafCount, evidence });
198
+ }
199
+ /**
200
+ * FED-OPTIONB-SEAL-001: the complete ordered leaf chain (both parties) a UNILATERAL seal carries to the
201
+ * directory for the OFFLINE tree rebuild. Empty when no leaves were logged (e.g. a direct-only session
202
+ * with no relay witness) — the caller then has nothing to carry and the seal stays bilateral/pending.
203
+ *
204
+ * ⚠️ Stranded on `verifyCertifiedRoot` before this split — the third block found doing that, and the
205
+ * reason the rule is now written down: a method reduced to a delegator leaves its documentation
206
+ * behind, and the block below it ends up carrying two descriptions of which the first is a stranger.
207
+ */
208
+ getSealCarry(agentPubkeyHex, sessionIdHex) {
209
+ if (!this.#ctx.sealLeafStore && this.#db) {
210
+ this.#ctx.sealLeafStore = new SessionSealLeafStore(this.#db, this.#ctx.logger);
211
+ }
212
+ return this.#ctx.sealLeafStore?.getCarry(agentPubkeyHex, sessionIdHex) ?? [];
213
+ }
214
+ /** Fix #1 EXTENSION: inject the broker-connection opener. Setter injection, same construction-order reason. */
215
+ setEnsureSealBroker(cb) {
216
+ this.#ctx.ensureSealBroker = cb;
217
+ }
218
+ /**
219
+ * DOD-M12B-INTERRUPTED-ESCALATE-1 — flip a session to `sealed`, synchronously, without needing a
220
+ * live node.
221
+ *
222
+ * **`destroySessionNode(…, "sealed")` cannot be relied on to do this.** It returns early at
223
+ * `if (!entry) return`, and the status write lives 26 lines BELOW that guard — so it flips the
224
+ * status only for a session that still has an `#activeNodes` entry. An interrupted session has
225
+ * none by construction: every producer of that status deletes the entry. Before this method, a
226
+ * unilateral seal on an interrupted session stored the notarized root and the certificate and
227
+ * left the row saying `interrupted` — the receipt landed and nothing that represents it moved.
228
+ * `cello_sessions` still showed it stuck, `cello_close_session` still refused it by name, and the
229
+ * restart-seal resolver re-selected it on the next boot to run the whole ceremony again against a
230
+ * session that already held a receipt.
231
+ *
232
+ * STATUS FIRST AND SYNCHRONOUS, teardown second — the order `abandonSession` uses and the one
233
+ * `retireSession` documents. The flip is the load-bearing half; the teardown makes memory agree
234
+ * with it. `#updateSessionStatus` also runs the terminal disposition hooks (held content is
235
+ * annexed, not stranded), which the early return skipped entirely.
236
+ */
237
+ markSealed(agentName, sessionId) {
238
+ // The terminal guard (abandoned/sealed must not be overwritten) lives in #updateSessionStatus,
239
+ // so it holds for destroySessionNode and retireSession too — not only for callers of this
240
+ // wrapper.
241
+ return this.#ctx.updateSessionStatus(agentName, sessionId, "sealed");
242
+ }
243
+ /**
244
+ * M8B FINDING-6 (cascade-2): persist a seal certificate for a session that may have NO local
245
+ * `sessions` row. recordSealCertificate (a manager delegator onto `session-queries.ts`) is an `UPDATE ... WHERE` — a SILENT no-op when the
246
+ * row is absent (the exact trap the cascade-2 reviewer flagged). The ABSENT party (B), learning of
247
+ * a seal on reconnect via seal_unilateral_notification, may never have persisted a row for this
248
+ * session. This ensures a minimal stub row first (INSERT OR IGNORE — a no-op if a row already
249
+ * exists, e.g. an 'interrupted' row after a restart) so B's receipt is actually durable + retrievable
250
+ * via cello_get_sealed_receipt. The counterparty pubkey is required by the schema (NOT NULL); B
251
+ * derives it from the notification's present_pubkey.
252
+ */
253
+ recordSealCertificateEnsuringRow(agentName, sessionId, counterpartyPubkeyHex, sealedRootHex, legibilityJson) {
254
+ if (!this.#db)
255
+ return;
256
+ const now = Date.now();
257
+ this.#db
258
+ .prepare(`INSERT OR IGNORE INTO sessions
259
+ (session_id, agent_id, counterparty_pubkey, status, created_at, updated_at)
260
+ VALUES (?, ?, ?, ?, ?, ?)`)
261
+ .run(sessionId, this.#ctx.requireAgentId(agentName), counterpartyPubkeyHex, "sealed", now, now);
262
+ this.#ctx.queries.recordSealCertificate(agentName, sessionId, sealedRootHex, legibilityJson);
263
+ }
264
+ /**
265
+ * M7-SESSION-001 (H-1): persist a verified bilateral SEAL-INTERRUPTED
266
+ * commitment and transition the session to 'seal_interrupted_pending'.
267
+ *
268
+ * This is NOT a seal. It records that both parties produced and exchanged
269
+ * K_local-signed SEAL-INTERRUPTED leaves over the same {leafCount, merkleRoot}.
270
+ * The FROST threshold notarization is a separate, currently-unwired step (see
271
+ * daemon.ts handleSealInterruptedFlow H-1 note), which is precisely why the
272
+ * status is 'seal_interrupted_pending' and never 'sealed'.
273
+ *
274
+ * The status update is guarded so it only advances a session out of the
275
+ * 'interrupted' state — it will not overwrite a 'sealed' row.
276
+ *
277
+ * @returns true if the session row was advanced to seal_interrupted_pending.
278
+ */
279
+ persistSealInterruptedCommitment(opts) {
280
+ if (!this.#db)
281
+ return false;
282
+ const now = Date.now();
283
+ try {
284
+ this.#db
285
+ .prepare(`INSERT OR REPLACE INTO seal_interrupted_artifacts
286
+ (agent_id, session_id, role, own_leaf, counterparty_leaf, merkle_root, nonce, created_at)
287
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)`)
288
+ .run(this.#ctx.requireAgentId(opts.agentName), opts.sessionId, opts.role, JSON.stringify(opts.ownLeaf), JSON.stringify(opts.counterpartyLeaf), opts.merkleRoot, opts.nonce, now);
289
+ }
290
+ catch (err) {
291
+ this.#ctx.logger.error("session.interrupted.db.write.failed", {
292
+ sessionId: opts.sessionId,
293
+ error: extractErrorMessage(err),
294
+ });
295
+ return false;
296
+ }
297
+ // DAEMON-004: the bilateral commitment advances a session out of either
298
+ // 'interrupted' (SESSION-001 interrupted-seal flow) OR 'active' (DAEMON-004
299
+ // active-session seal). The guard still refuses to overwrite a terminal
300
+ // 'sealed' row or an already-pending one.
301
+ const result = this.#db
302
+ .prepare("UPDATE sessions SET status = 'seal_interrupted_pending', updated_at = ? WHERE agent_id = ? AND session_id = ? AND status IN ('active', 'interrupted')")
303
+ .run(now, this.#ctx.requireAgentId(opts.agentName), opts.sessionId);
304
+ const landed = Number(result.changes) > 0;
305
+ if (landed) {
306
+ // DOD-M12B-SESSION-SEED-1 (review F3): `seal_interrupted_pending` is NOT a state revival
307
+ // exists for, and the first build's comment wrongly grouped it with `interrupted`.
308
+ // `ingestReceivedContent` (in `session-content-ingest.ts`) refuses it outright, and BOTH
309
+ // sweeps that could otherwise close a
310
+ // session — `listRestartOrphanedSessions` and `listExpiredUnrevivableSessions` — filter
311
+ // `status = 'interrupted'`, so a pending-seal session is unrevivable AND unswept. Keeping its
312
+ // identity meant holding it until the process exited. Entry 42's own measurement is that 59%
313
+ // of seals that start never finish, so that is the common path, not a corner.
314
+ this.#ctx.destroySessionSeed(opts.agentName, opts.sessionId);
315
+ }
316
+ return landed;
317
+ }
318
+ /**
319
+ * M7 DOD-SPINE-7: submit THIS party's SEAL ctrl leaf (0x02) to the relay witness.
320
+ * Structure: content_hash = SHA-256(0x02 || encodeSealPayload({session_id, final_root,
321
+ * close_timestamp, "PENDING"})), where final_root is the daemon's OWN tree root. Two
322
+ * distinct-sender SEAL leaves in the relay's log trigger the relay's #maybeProcessSeal
323
+ * → directory processSeal (rebuild + verify the signed chain) → FROST notarization →
324
+ * session_sealed. Requires an active relay client; the caller falls back to the
325
+ * directory-mediated path when this returns relay_unavailable.
326
+ */
327
+ /**
328
+ * 070-CARRIEDSEAL — close over evidence this side already holds, when the relay never answered.
329
+ * The reasoning, the gates and the refusals live in `seal-carried-close.ts`; this binds it to
330
+ * this instance's context. `null` means "not that situation" and the caller's own refusal stands.
331
+ */
332
+ #carriedClose(agentName, sessionId, cause, correlationId, standingRefusal) {
333
+ return closeOverCarriedEvidence({
334
+ ctx: this.#ctx,
335
+ db: this.#db,
336
+ getSealCarry: (pk, sid) => this.getSealCarry(pk, sid),
337
+ }, agentName, sessionId, cause, correlationId, standingRefusal);
338
+ }
339
+ async submitSealLeaf(agentName, sessionId, correlationId) {
340
+ const sealKey = this.#ctx.sessionKey(agentName, sessionId);
341
+ /**
342
+ * DOD-M15-SEALPRECOND-1 — THE PRECONDITION BY CONSTRUCTION, at the one point every seal leaf
343
+ * passes through. Review HIGH-3.
344
+ *
345
+ * The three callers wait for the record to settle and then submit, which leaves a check-then-act
346
+ * window: a `cello_send` can take its position after the caller read readiness and before the
347
+ * root is computed. The window is microseconds rather than the measured 352ms, and microseconds
348
+ * is exactly what this order says not to accept — a 14ms gap and a 14s gap fail identically.
349
+ *
350
+ * So the last word is here. Every present and future seal submission site is gated whether or
351
+ * not its author knew this rule existed, which is the property the enumeration in the order
352
+ * could only give for the sites that existed on the day it was written.
353
+ *
354
+ * Read AFTER nothing and BEFORE everything: no transport is resolved, no idempotency mark is
355
+ * taken, so a refusal here leaves the session exactly as it found it and the caller's retry is
356
+ * a genuine retry.
357
+ */
358
+ const settling = this.sealReadiness(agentName, sessionId).ownLeavesOrdered;
359
+ if (settling > 0) {
360
+ this.#ctx.logger.warn("session.seal.leaf.refused_settling", {
361
+ agentName, sessionId, ownLeavesOrdered: settling, correlationId,
362
+ impact: "a message of ours has a place in the relay's ordering this record has not taken, so NO leaf was submitted and no root was signed — a root signed short of the relay's leaf set is refused by the directory and the receipt cannot be recovered",
363
+ });
364
+ return { ok: false, reason: "own_record_settling" };
365
+ }
366
+ // M12-P15: resolved, not required. See #resolveSealTransport — an interrupted session has no
367
+ // in-memory node BY CONSTRUCTION, and refusing here is what made the first fix inert.
368
+ const transport = this.#resolveSealTransport(agentName, sessionId);
369
+ if ("error" in transport) {
370
+ // 070-CARRIEDSEAL: there is no relay to hand this leaf to. If the reason is SILENCE rather
371
+ // than a ruling, close over what we already hold instead of losing the receipt.
372
+ const local = await this.#carriedClose(agentName, sessionId, transport.error, correlationId);
373
+ if (!local)
374
+ return { ok: false, reason: transport.error };
375
+ // ⚠️ THE MARK, ON THIS PATH TOO — review MEDIUM-3. The submit-failure branch below records it
376
+ // and this one did not, so a retried close re-entered the terminus builder, hit
377
+ // `seal_carry_own_ctrl_present`, and reported the RELAY as the fault for a session whose
378
+ // closing leaf was already on disk.
379
+ this.#ctx.responderSealSubmitted.set(sealKey, { reportedRootHex: local.reportedRootHex, sequenceNumber: local.sequenceNumber });
380
+ this.#closedViaLocalTerminus.add(sealKey);
381
+ return { ...local, viaLocalTerminus: true };
382
+ }
383
+ const entry = transport;
384
+ /**
385
+ * DOD-M15-RELAYLEAK-1 — release a DETACHED seal transport when this submission is done.
386
+ *
387
+ * Only the detached branch registers a session here, so this can never remove a live one. The
388
+ * client is closed only when it has no sessions left and the cache still holds THIS client —
389
+ * the same two guards `#detachSessionRelay` uses, and for the same reason: a racing teardown
390
+ * must not close a freshly-built replacement for the same key.
391
+ */
392
+ const releaseDetached = () => {
393
+ if (transport.releaseOnDone !== true)
394
+ return;
395
+ try {
396
+ entry.relayClient.unregisterSession(sessionId);
397
+ if (!entry.relayClient.hasSessions()) {
398
+ for (const [key, cached] of this.#ctx.relayClients) {
399
+ if (cached === entry.relayClient) {
400
+ cached.close();
401
+ this.#ctx.relayClients.delete(key);
402
+ break;
403
+ }
404
+ }
405
+ }
406
+ }
407
+ catch (err) {
408
+ this.#ctx.logger.warn("session.seal.transport.release_failed", {
409
+ agentName,
410
+ sessionId,
411
+ reason: extractErrorMessage(err),
412
+ impact: "a detached seal relay client could not be released; it is held until process exit",
413
+ });
414
+ }
415
+ };
416
+ /**
417
+ * ⚠️ try/finally, NOT a call at each return. There are three exits today and adding a release
418
+ * to each would be a hand-kept list — the shape this milestone has been bitten by repeatedly,
419
+ * where the FOURTH exit added later quietly leaks. Here the release cannot be bypassed by a new
420
+ * return, and it runs on the throw path too, which is where a leak matters most.
421
+ */
422
+ try {
423
+ // M7-UPGRADE-002 idempotency: this party submits its responder SEAL leaf AT MOST ONCE per
424
+ // session. BOTH cello_close_session and the auto-acknowledge path call here; the first to reach
425
+ // this point wins, the second short-circuits. The check+set is SYNCHRONOUS (before any await) so
426
+ // two near-simultaneous triggers (e.g. B's own close racing A's delivered SEAL ctrl leaf) cannot
427
+ // both submit. Cleared below on a relay submit failure so a genuine retry can proceed.
428
+ // DOD-M12B-INTERRUPTED-ESCALATE-1 — THE MARK MUST SURVIVE A RESTART, or one automatic retry
429
+ // permanently forfeits the receipt.
430
+ //
431
+ // `#responderSealSubmitted` is in memory. A session whose close was in flight when the daemon
432
+ // stopped already has our SEAL ctrl leaf in the relay log — and on the next boot the mark is
433
+ // empty, so the restart-seal resolver's automatic close would submit a SECOND one. The
434
+ // directory requires exactly one ctrl leaf (`ctrlLeaves.length !== 1 → unilateral_seal_leaf_invalid`)
435
+ // and the carry is durable, so every future attempt would carry both and be refused forever.
436
+ //
437
+ // The durable evidence already exists and was simply not consulted: our own ctrl leaf is in
438
+ // `session_seal_leaves`. Recover the escalation values from it instead of submitting again.
439
+ if (!this.#ctx.responderSealSubmitted.has(sealKey)) {
440
+ const durable = this.#ctx.park.recoverOwnSealCtrlLeaf(agentName, sessionId);
441
+ if (durable === "unknown") {
442
+ // REFUSE, do not submit. A second ctrl leaf makes the session unsealable forever, and the
443
+ // question "is one already there?" just failed to answer. Refusing costs this close; a
444
+ // second leaf costs the receipt permanently.
445
+ return { ok: false, reason: "seal_leaf_recovery_unavailable" };
446
+ }
447
+ if (durable !== "none") {
448
+ this.#ctx.logger.info("session.seal.leaf.already_submitted.recovered", {
449
+ sessionId, agentName, sequenceNumber: durable.sequenceNumber,
450
+ impact: "our SEAL ctrl leaf is already in the relay log from a previous run; submitting a second would make this session unsealable forever",
451
+ });
452
+ this.#ctx.responderSealSubmitted.set(sealKey, durable);
453
+ }
454
+ }
455
+ if (this.#ctx.responderSealSubmitted.has(sealKey)) {
456
+ // M8B FINDING-1: carry the FIRST submit's reported root/sequence so a retry close can
457
+ // still escalate to a unilateral seal. A null value means that submit is still in
458
+ // flight — return the bare reason and let the caller fall back to the pending path.
459
+ const prior = this.#ctx.responderSealSubmitted.get(sealKey);
460
+ return prior
461
+ ? {
462
+ ok: false,
463
+ reason: "responder_seal_already_submitted",
464
+ reportedRootHex: prior.reportedRootHex,
465
+ sequenceNumber: prior.sequenceNumber,
466
+ // Carried so a retry does not sit out a bilateral window that still cannot open.
467
+ ...(this.#closedViaLocalTerminus.has(sealKey) ? { viaLocalTerminus: true } : {}),
468
+ }
469
+ : { ok: false, reason: "responder_seal_already_submitted" };
470
+ }
471
+ this.#ctx.responderSealSubmitted.set(sealKey, null);
472
+ // A throw anywhere before the mark is finalized would strand the null in-flight marker
473
+ // and lock every future close out of escalation (a FINDING-1-shaped deadlock via a
474
+ // different trigger) — clear the mark on any unexpected exception.
475
+ try {
476
+ const signClose = () => {
477
+ const finalRootHex = this.#ctx.getSessionTreeRootHex(agentName, sessionId);
478
+ const payload = encodeSealPayload({
479
+ session_id: entry.relaySessionIdBytes,
480
+ final_root: new Uint8Array(Buffer.from(finalRootHex, "hex")),
481
+ close_timestamp: Date.now(),
482
+ attestation: "PENDING",
483
+ });
484
+ // content_hash = SHA-256(0x02 || seal_payload) — the ctrl leaf kind byte is 0x02.
485
+ const hash = new Uint8Array(createHash("sha256").update(new Uint8Array([LEAF_KIND_CTRL])).update(payload).digest());
486
+ return { sealPayload: payload, contentHash: hash };
487
+ };
488
+ let { sealPayload, contentHash } = signClose();
489
+ /**
490
+ * ⚠️ `sealPayload` IS PASSED, AND ITS ABSENCE WAS THE WHOLE DEFECT — `DOD-M15-SEALWIRE-1`
491
+ * bullets 3+4, review pass 1, F1.
492
+ *
493
+ * These exact bytes were computed two lines above, hashed, and then dropped: `submitLeaf` had
494
+ * no parameter for them. So the directory received a SHA-256 pre-image nobody transmitted, and
495
+ * the client's SIGNED `final_root` — the one value in the seal the relay cannot produce — was
496
+ * unrecoverable. Four legs of this line shipped and were reviewed green while the head of the
497
+ * chain did not exist.
498
+ *
499
+ * The payload and the hash MUST come from the same derivation. If they ever diverge the
500
+ * directory reports `seal_payload_unbound`, whose guidance says *"someone between them and here
501
+ * altered or fabricated the payload — the relay is the only party on that path"* — a correct
502
+ * relay accused by name, in an error written to sound like an attack, for a mismatch made here.
503
+ */
504
+ const relaySidHex = Buffer.from(entry.relaySessionIdBytes).toString("hex");
505
+ const seenBefore = entry.relayClient.lastSeenAck(relaySidHex)?.seq ?? 0;
506
+ // A message the other side filed but never delivered would be claimed by this close and missing from its root; refuse by name (withheld-content.ts).
507
+ const withheld = withheldPositionsOrNone(this.#db, this.#ctx.logger, () => ({ agentId: this.#ctx.requireAgentId(agentName), agentPubkeyHex: entry.relayClient.senderPubkeyHex, sessionId, relaySessionHex: relaySidHex, upToSeq: seenBefore }));
508
+ if (withheld.length > 0) {
509
+ this.#ctx.responderSealSubmitted.delete(sealKey);
510
+ this.#ctx.logger.warn("session.seal.counterparty_content_missing", { sessionId, agentName, positions: withheld, correlationId });
511
+ return { ok: false, reason: "counterparty_content_missing" };
512
+ }
513
+ let result = await entry.relayClient.submitLeaf(entry.node, entry.relaySessionIdBytes, contentHash, LEAF_KIND_CTRL, sealPayload);
514
+ /**
515
+ * `seal_stale`: the relay already filed a message from the other side that this close did not
516
+ * include — it reached the relay just before our close. Signing anyway would notarize a root
517
+ * missing it, and both seals would fail. Wait for that message to land in our record (the
518
+ * acknowledgement moves only when it is placed), then sign ONCE more. A condition on state,
519
+ * bounded so a message that never arrives cannot hold the close; past the bound this falls
520
+ * through to the ordinary failure handling below.
521
+ */
522
+ if (!result.ok && result.reason === "seal_stale") {
523
+ const deadline = Date.now() + SEAL_STALE_WAIT_MS;
524
+ // Wait for the position the relay named; an older relay names none, so any advance will do.
525
+ const needed = ("awaited_seq" in result && result.awaited_seq !== undefined) ? result.awaited_seq : seenBefore + 1;
526
+ while ((entry.relayClient.lastSeenAck(relaySidHex)?.seq ?? 0) < needed && Date.now() < deadline) {
527
+ await new Promise((r) => { const t = setTimeout(r, 20); t.unref?.(); });
528
+ }
529
+ this.#ctx.logger.info("session.seal.leaf.stale_resign", {
530
+ sessionId, correlationId, advanced: (entry.relayClient.lastSeenAck(relaySidHex)?.seq ?? 0) > seenBefore,
531
+ });
532
+ ({ sealPayload, contentHash } = signClose());
533
+ result = await entry.relayClient.submitLeaf(entry.node, entry.relaySessionIdBytes, contentHash, LEAF_KIND_CTRL, sealPayload);
534
+ }
535
+ if (!result.ok) {
536
+ // Clear the idempotency mark so a genuine retry (agent close / reconnect) can proceed (DB-001).
537
+ this.#ctx.responderSealSubmitted.delete(sealKey);
538
+ this.#ctx.logger.warn("session.seal.leaf.submit.failed", { sessionId, reason: result.reason, correlationId });
539
+ // 070-CARRIEDSEAL: the relay was asked and said nothing. Same answer as having no relay at
540
+ // all — write the closing leaf here rather than lose a receipt for a witnessed record.
541
+ // The relay client is in hand here, so its standing verdict can be asked for directly —
542
+ // the reason string above cannot carry it.
543
+ const local = await this.#carriedClose(agentName, sessionId, result.reason, correlationId, entry.relayClient.getLastAuthRefusal());
544
+ if (local) {
545
+ this.#ctx.responderSealSubmitted.set(sealKey, { reportedRootHex: local.reportedRootHex, sequenceNumber: local.sequenceNumber });
546
+ this.#closedViaLocalTerminus.add(sealKey);
547
+ return { ...local, viaLocalTerminus: true };
548
+ }
549
+ return { ok: false, reason: result.reason };
550
+ }
551
+ // SESSION-002: the reported_root for a unilateral seal is the content-hash root the
552
+ // local tree WOULD have with this SEAL ctrl leaf appended — the same root the directory
553
+ // rebuilds from the relay's content-hash chain (the relay records the identical
554
+ // content_hash for this ctrl leaf). Computed without mutating the durable tree /
555
+ // message_count, so the bilateral + interrupted seal paths are unaffected.
556
+ const contentHashHex = Buffer.from(contentHash).toString("hex");
557
+ const reportedRootHex = this.#ctx.getSessionTree(agentName, sessionId).rootWithAppendedHex(contentHashHex);
558
+ // M8B FINDING-1: durably associate the submit's escalation values with the idempotency
559
+ // mark, so any LATER close call can retrieve them via the already-submitted result.
560
+ this.#ctx.responderSealSubmitted.set(sealKey, { reportedRootHex, sequenceNumber: result.sequence_number });
561
+ this.#ctx.logger.info("session.seal.leaf.submitted", {
562
+ sessionId,
563
+ sequenceNumber: result.sequence_number,
564
+ correlationId,
565
+ });
566
+ // M7-UPGRADE-002: #responderSealSubmitted was set synchronously at the top of this method —
567
+ // the guard now blocks any second submit (auto-ack OR a redelivered counterparty SEAL ctrl leaf).
568
+ return { ok: true, sequenceNumber: result.sequence_number, reportedRootHex };
569
+ }
570
+ catch (err) {
571
+ this.#ctx.responderSealSubmitted.delete(sealKey);
572
+ throw err;
573
+ }
574
+ }
575
+ finally {
576
+ releaseDetached();
577
+ }
578
+ }
579
+ /**
580
+ * CELLO-M7-UPGRADE-001 (DOD-UP-1): readiness of a session for B to RATIFY a unilateral seal
581
+ * (the returning absent party). This is the SAME verifiability bar as the UP-2 auto-ack gate:
582
+ *
583
+ * - `known`: the session exists locally with its content (B has a transcript to ratify). After a
584
+ * restart B reloads it from SQLite, and autoRecoverForAgent re-pulls any parked content first.
585
+ * - `tampered`: the content cross-check flagged a content_hash mismatch (#contentDesynced) — B
586
+ * must NEVER ratify content it could not integrity-verify (the KERNEL refusal, AC-003).
587
+ *
588
+ * The directory separately verifies B's ack signature is genuine; B separately verifies the
589
+ * unilateral cert signature (R1 is authentic). NOTE: a full "B's frontier covers R1's tail"
590
+ * completeness check (the `desynced` reason) requires the deferred MSG-001-3b canonical-sequence
591
+ * reconciliation — same documented limitation as the UP-2 gate above.
592
+ */
593
+ getSealUpgradeReadiness(agentName, sessionId) {
594
+ const record = this.#ctx.queries.getSessionRecord(agentName, sessionId);
595
+ return {
596
+ known: !!record,
597
+ /**
598
+ * THE REASON TRAVELS WITH THE VERDICT — review F-A, correcting review F1's fix.
599
+ *
600
+ * F1 made the gate binary and moved the label into the log, and I did that in ONE consumer.
601
+ * This struct feeds a second one (`evaluateSealUpgrade`), which had only a boolean to read and
602
+ * therefore called every cause `content_tamper` — at ERROR, with no guidance. An honest peer on
603
+ * a newer build raised a security alarm on B's reconnect: exactly the harm the F1 fix was
604
+ * written to remove, reached through the consumer it did not check.
605
+ *
606
+ * Returning the LABEL rather than a boolean is what makes that impossible to reintroduce: a
607
+ * caller cannot flatten what it never receives flat.
608
+ */
609
+ unverifiable: this.#ctx.contentDesynced.get(this.#ctx.sessionKey(agentName, sessionId)) ?? null,
610
+ };
611
+ }
612
+ /**
613
+ * M7-UPGRADE-002: auto-acknowledge close (POSTMORTEM Workstream E / C-5). When B's daemon
614
+ * ingests the COUNTERPARTY's SEAL control leaf and B has verified the content, B's OWN node
615
+ * auto-co-signs + submits its responder SEAL leaf WITHOUT waiting for B's agent to call
616
+ * cello_close_session — so a bilateral seal completes promptly instead of degrading to
617
+ * unilateral on a slow/busy/crashed agent.
618
+ *
619
+ * SI-001 (non-negotiable): B's signature is ALWAYS produced by B's own node — submitSealLeaf
620
+ * signs the responder SEAL leaf with B's K_local. We remove the agent PROMPT, never the SIGNER;
621
+ * nothing here lets the directory or the peer synthesize B's acknowledgement.
622
+ *
623
+ * SI-002 (verifiability gate): auto-ack ONLY content B has verified. A session whose content
624
+ * cross-check failed (content_hash_mismatch = tamper, recorded in #contentDesynced) is NEVER
625
+ * auto-signed — it surfaces to the agent as a genuine decision point. DISAGREEMENT with the
626
+ * content is NOT a gate failure (C-6): the gate is "can I verify integrity?", never "do I agree?"
627
+ * — a verified-but-disliked tail is auto-sealed and the transcript speaks for B.
628
+ *
629
+ * Idempotent + non-throwing: marks #responderSealSubmitted BEFORE the async submit so a
630
+ * redelivered ctrl leaf cannot double-submit; clears the mark on submit failure so a later
631
+ * agent close / reconnect can still complete the seal (DB-001 — never a silent half-seal).
632
+ */
633
+ maybeAutoAcknowledgeSeal(agentName, sessionId, correlationId) {
634
+ const ackKey = this.#ctx.sessionKey(agentName, sessionId);
635
+ // Idempotency: at most one responder seal per session (auto-ack or agent close).
636
+ if (this.#ctx.responderSealSubmitted.has(ackKey))
637
+ return;
638
+ const record = this.#ctx.queries.getSessionRecord(agentName, sessionId);
639
+ // Only an ACTIVE session auto-acks. A committed/sealing/sealed/interrupted session is out of
640
+ // scope (already sealing, or needs the interrupted/upgrade path), not an auto-ack candidate.
641
+ if (!record || record.status !== "active")
642
+ return;
643
+ /**
644
+ * SI-002 verifiability gate: never auto-sign a session whose content we could not verify.
645
+ *
646
+ * ⚠️ THIS COMMENT SAID THE OPPOSITE UNTIL `DOD-M15-SEALWIRE-1` part B1 (review F-C). It read
647
+ * *"Today the ONLY tracked unverifiable cause is a content_hash mismatch = TAMPER"*, which was
648
+ * true when a mismatch was the only way to fail the cross-check and is false now: B1 added an
649
+ * unreadable algorithm name and a salted frame with no salt, and **both are ordinary**.
650
+ *
651
+ * Genuine tamper is a SECURITY event — ERROR, reason `content_tamper`, which is what the AC-008
652
+ * alarm keys on. The other two must NOT wear that name, or the alarm fires on an honest peer
653
+ * running a newer build and the operator learns to dismiss it.
654
+ *
655
+ * 🚨 AND `content_unverifiable` IS RESERVED — DO NOT REUSE IT HERE. It is specced for *parked
656
+ * content unrecoverable*, one of the two reasons (with `desynced`, B's tree behind the canonical
657
+ * sealed tail) awaiting the deferred MSG-001-3b canonical-sequence reconciliation. B1's first
658
+ * attempt emitted exactly that string for a different condition, which would have made the two
659
+ * indistinguishable in the log the day the follow-on landed. Hence
660
+ * `content_verification_unavailable`, deliberately distinct.
661
+ */
662
+ const unverifiable = this.#ctx.contentDesynced.get(ackKey);
663
+ if (unverifiable) {
664
+ /**
665
+ * DOD-M15-SEALWIRE-1 part B1 (review F1) — THE GATE FIRES FOR BOTH, THE ALARM ONLY FOR ONE.
666
+ *
667
+ * `content_tamper` is what the AC-008 alarm keys on, and it must keep meaning what it says. A
668
+ * frame we could not verify because the peer named an algorithm this build cannot read is an
669
+ * ordinary version difference; raising a tamper alarm for it would train an operator to
670
+ * dismiss the alarm, which costs more than the skew.
671
+ *
672
+ * But the REFUSAL TO AUTO-SIGN is identical in both cases and non-negotiable: SI-002 is "never
673
+ * auto-sign a session whose content we could not verify", and "could not" covers both.
674
+ */
675
+ this.#ctx.logger.error("session.seal.autoack.skipped", {
676
+ sessionId,
677
+ reason: unverifiable === "tampered" ? "content_tamper" : "content_verification_unavailable",
678
+ correlationId,
679
+ });
680
+ // AC-002: the verifiability gate refused — surface counterparty_closing to B's agent as a
681
+ // GENUINE decision point (the seal will not auto-complete; B must decide). Uses the existing
682
+ // session-state push to the live MCP clients; best-effort (never throws out of this gate).
683
+ try {
684
+ this.#ctx.onSessionStateChanged?.(record.agent_name, sessionId, "counterparty_closing", record.counterparty_pubkey);
685
+ }
686
+ catch (err) {
687
+ this.#ctx.logger.debug("session.state.notify.failed", {
688
+ sessionId,
689
+ reason: extractErrorMessage(err),
690
+ });
691
+ }
692
+ return;
693
+ }
694
+ const entry = this.#ctx.activeNodes.get(ackKey);
695
+ const responderPubkey = entry?.relayClient?.senderPubkeyHex ?? "unknown";
696
+ // submitSealLeaf owns the #responderSealSubmitted idempotency mark (set synchronously at its
697
+ // top), so the auto-ack does not pre-mark — it just reacts to the result.
698
+ // Establish the broker visiting connection BEFORE submitting, not after. The directory acts on
699
+ // the leaf in ~60ms and pushes `seal_verified` straight back; if the stream is not up by then it
700
+ // defers the frame and the seal stalls. Proven on GCP: leaf submitted 18:41:56.555, directory
701
+ // deferred at 18:41:56.615 (initiator_stream_absent), the explicit-close path opened the
702
+ // connection at 18:42:01.529 — five seconds too late.
703
+ void (async () => {
704
+ let sealBrokerConn = null;
705
+ try {
706
+ sealBrokerConn = (await this.#ctx.ensureSealBroker?.(agentName, sessionId)) ?? null;
707
+ }
708
+ catch (err) {
709
+ // Best-effort: a same-node session needs no visiting connection, and a failure here must not
710
+ // suppress the seal leaf — losing the leaf is strictly worse than racing the push.
711
+ this.#ctx.logger.warn("session.seal.autoack.broker.failed", {
712
+ sessionId,
713
+ correlationId,
714
+ reason: extractErrorMessage(err),
715
+ });
716
+ }
717
+ /**
718
+ * DOD-M15-SEALPRECOND-1 — the responder must not co-sign a record still being written either.
719
+ *
720
+ * This side signs its OWN root over its OWN tree, so a send of ours the relay has ordered and
721
+ * this tree has not placed produces exactly the short root the initiator produced on
722
+ * 2026-09-11. It was the one seal submission site with no gate at all.
723
+ *
724
+ * It WAITS first — the condition clears in milliseconds and declining costs a prompt
725
+ * bilateral seal. The REFUSAL is not written here: `submitSealLeaf` reads the same condition
726
+ * and answers `own_record_settling`, so this waits and then asks, and the one refusal travels
727
+ * out through the ordinary result handling below (review HIGH-1/LOW-5 — an early return here
728
+ * skipped the broker release and logged the same skip twice).
729
+ */
730
+ await awaitOwnRecordSettled(this, agentName, sessionId);
731
+ const submitted = await this.submitSealLeaf(agentName, sessionId, correlationId);
732
+ // RELEASE AFTER A GRACE WINDOW, not when the submit resolves.
733
+ //
734
+ // `submitSealLeaf` settles at the relay ack plus a local root computation — milliseconds — while
735
+ // the frame this connection exists to catch arrives ~60ms LATER (the timeline in the comment
736
+ // above is the measurement). Releasing on submit therefore closed the stream before the push it
737
+ // was opened for, which is the stall it was written to prevent.
738
+ //
739
+ // It is worse than a lost race. The directory drains its DURABLE notification queue on ANY
740
+ // stream that authenticates — visiting included — and DELETES each row once sent. So a visiting
741
+ // stream that authenticates and dies milliseconds later invites the directory to send-and-delete
742
+ // queued seal frames into a closing stream: the receipt is gone from the queue and never
743
+ // arrived. That is permanent loss, not a retry.
744
+ //
745
+ // The close path holds its connection around the entire bilateral wait; this path has no waiter
746
+ // to hang off, so it uses a bounded grace instead — generous against a ~60ms push, and bounded
747
+ // so a stalled seal cannot leak the connection. Unref'd: it must never hold the process open.
748
+ if (sealBrokerConn) {
749
+ const conn = sealBrokerConn;
750
+ const t = setTimeout(() => { void conn.stop("autoack-seal-grace-elapsed").catch(() => { }); }, AUTOACK_BROKER_GRACE_MS);
751
+ t.unref?.();
752
+ }
753
+ return submitted;
754
+ })()
755
+ .then((result) => {
756
+ if (result.ok) {
757
+ // SI-001: the responder SEAL leaf was signed by B's OWN node (K_local) in submitSealLeaf.
758
+ this.#ctx.logger.info("session.seal.autoacknowledged", {
759
+ sessionId,
760
+ responderPubkey,
761
+ correlationId,
762
+ });
763
+ }
764
+ else if (result.reason === "responder_seal_already_submitted") {
765
+ // B's agent close already submitted the responder seal (it won the race) — nothing to do.
766
+ return;
767
+ }
768
+ else {
769
+ // Submission failed (e.g. relay path down) — the agent close / reconnect can still
770
+ // complete the seal; never a silent half-seal (DB-001).
771
+ this.#ctx.logger.warn("session.seal.autoack.skipped", {
772
+ sessionId,
773
+ reason: result.reason,
774
+ correlationId,
775
+ });
776
+ /**
777
+ * DOD-M15-SEALPRECOND-1 review HIGH-2 — SAY IT TO SOMEBODY WHO CAN ACT ON IT.
778
+ *
779
+ * A refusal that only reaches the log promises a recovery nothing performs: the initiator
780
+ * waits out its unilateral timeout — two hours on the session this order was written from
781
+ * — and the receipt is lost anyway. The SI-002 gate twelve lines up already solved this
782
+ * by pushing `counterparty_closing` so B's agent drives an explicit close, and this is the
783
+ * same situation: a refusal to AUTO-sign, where a human close still completes the seal.
784
+ *
785
+ * Scoped to the settling reason on purpose. The other reasons here (relay down, transport
786
+ * gone) are not conditions a prompt close can fix, and pushing a decision point for them
787
+ * would train the agent to ignore the one that matters.
788
+ */
789
+ if (result.reason === "own_record_settling") {
790
+ try {
791
+ this.#ctx.onSessionStateChanged?.(record.agent_name, sessionId, "counterparty_closing", record.counterparty_pubkey);
792
+ }
793
+ catch (err) {
794
+ this.#ctx.logger.debug("session.state.notify.failed", { sessionId, reason: extractErrorMessage(err) });
795
+ }
796
+ }
797
+ }
798
+ })
799
+ .catch((err) => {
800
+ this.#ctx.logger.warn("session.seal.autoack.skipped", {
801
+ sessionId,
802
+ reason: extractErrorMessage(err),
803
+ correlationId,
804
+ });
805
+ });
806
+ }
807
+ /**
808
+ * M12-P14: is this side's chain COMPLETE enough to be sealed?
809
+ *
810
+ * A seal is a bilateral signature over the same conversation, so a side that is missing a leaf
811
+ * cannot produce a signable one — the counterparty compares frontiers and refuses with
812
+ * `leaf_count_mismatch`. That refusal is correct and it is also terminal: there is no backfill
813
+ * request in the protocol, so the only exit is a force-abandon, which yields NO notarized receipt.
814
+ * Measured 2026-08-05 on two sessions that died exactly this way (initiator 2 leaves, responder 3).
815
+ *
816
+ * The cheap prevention is to notice BEFORE asking. Two local signals already exist and, until now,
817
+ * nothing read either of them at close time:
818
+ * - `#highWaterSeq` — the largest canonical sequence the RELAY has witnessed for this session.
819
+ * The relay is the ordering authority, so a high-water above our own frontier is proof that a
820
+ * leaf exists which we have not appended. (Its own doc comment called it "reserved … NOT yet
821
+ * consumed by the gate" — this is that consumer.)
822
+ * - `#heldContent` — content we HAVE received and verified but cannot append because it sits
823
+ * behind a gap. Holding content and sealing anyway would seal a chain we know is short.
824
+ *
825
+ * Deliberately NOT a network call: it must work when the counterparty is unreachable, which is
826
+ * the whole situation a seal-interrupted exists for.
827
+ *
828
+ * KNOWN LIMIT, stated rather than hidden: both maps are in-memory and cleared on teardown, so
829
+ * after a daemon restart this returns ready for a session whose gap predates the restart — which
830
+ * is the shape of the 2026-08-05 incident itself. Closing that needs the mailbox drained (or the
831
+ * high-water persisted) before the check; tracked with M12-P14, not claimed here.
832
+ */
833
+ sealReadiness(agentName, sessionId) {
834
+ const key = this.#ctx.sessionKey(agentName, sessionId);
835
+ // DOD-M12B-STRAND-1: hydrate first. An under-counted `heldCount` reports a gapped session as
836
+ // READY, and this gate's whole purpose is to stop a short chain being signed — the counterparty
837
+ // answers `leaf_count_mismatch`, which is TERMINAL and costs the receipt permanently. Failing
838
+ // open here is the one outcome worse than refusing a healthy close.
839
+ //
840
+ // Hydrate WITHOUT releasing: this is a read path now — the status surface asks it for every
841
+ // active session — and a read that appends leaves, advances the root and rings the doorbell is
842
+ // a diagnostic command that delivers messages. The release still runs on every path that was
843
+ // going to mutate anyway.
844
+ this.#ctx.held.ensureHeldRestored(agentName, sessionId, { release: false });
845
+ const treeSize = this.#ctx.getSessionTree(agentName, sessionId).size();
846
+ const highWaterSeq = this.#ctx.highWaterSeq.get(key) ?? -1;
847
+ const heldCount = this.#ctx.heldContent.get(key)?.size ?? 0;
848
+ // Review HIGH-2: NOT `(highWaterSeq + 1) - treeSize`. That subtraction silently assumes the
849
+ // relay's sequence space and this tree's index space count the same things, and they do not:
850
+ // `relay-node.ts` increments seq_counter for EVERY accepted leaf including CTRL (0x02), while
851
+ // NOTHING APPENDS A CTRL LEAF TO THIS TREE — `submitSealLeaf` deliberately computes its root
852
+ // without mutating the durable tree. So one seal ctrl leaf offsets the two spaces permanently,
853
+ // and any msg witnessed afterwards would read as a missing leaf FOREVER. That is a false
854
+ // positive, and a false positive here is worse than the bug it guards: it makes a healthy
855
+ // session unsealable, leaving force-abandon (no receipt) as the only exit. `seal-upgrade.ts`
856
+ //
857
+ // ⚠️ THIS SENTENCE USED TO READ *"`appendSessionLeaf` is only ever called with 'msg'"*, AND THAT
858
+ // WAS FALSE WHEN IT WAS WRITTEN — corrected, not deleted, per review pass 1 F8. Line ~7730
859
+ // appends "doc", and `WritableSessionTreeLeafKind` permits "ctrl" outright, so the type does not
860
+ // enforce it either. Doc leaves are harmless to this subtraction because they are witnessed by
861
+ // the relay too (LEAF_KIND_DOC) and counted in BOTH spaces; the load-bearing property is only
862
+ // ever about CTRL. Stating it as "msg only" made a narrower claim than the code supports and a
863
+ // stronger one than it holds — so a reader checking it would find a counter-example, conclude
864
+ // the reasoning was stale, and be one step from "fixing" the subtraction back.
865
+ // already documents the same `leaf_count - 1` offset.
866
+ //
867
+ // `#witnessedSeq` answers the question directly instead of inferring it. It gains an entry when
868
+ // the relay witnesses a COUNTERPARTY msg leaf (ctrl leaves are excluded at the call site) and
869
+ // loses it the moment that leaf is appended. So its remaining size IS the count of leaves the
870
+ // ordering authority has committed and this tree has not — no arithmetic, no space mismatch,
871
+ // and it cannot go negative.
872
+ const missingLeaves = this.#ctx.witnessedSeq.get(key)?.size ?? 0;
873
+ // DOD-M12B-INDEX-1: our OWN held sends are counted separately. They block a seal just as a
874
+ // received hold does, but they are not "a message from the counterparty that has not arrived" —
875
+ // and a refusal that calls them that tells the operator to wait for something already in hand,
876
+ // which is how a close-retry loop ends at force-abandon and no receipt.
877
+ let heldOwn = 0;
878
+ for (const e of this.#ctx.heldContent.get(key)?.values() ?? [])
879
+ if (e.origin === "sent")
880
+ heldOwn++;
881
+ // DOD-M15-DIVERGE-1: the third term, and the one that closes the asymmetry. `#diverged` is set
882
+ // only where the parting is PROVEN — an ack came back behind our frontier — never where it is
883
+ // merely suspected, because a gate that refuses a healthy session forever is worse than the bug
884
+ // it guards: force-abandon, with no receipt, becomes the only exit.
885
+ const diverged = this.#ctx.records.isSessionDiverged(agentName, sessionId);
886
+ /**
887
+ * DOD-M15-SEALPRECOND-1. A marker whose position the tree has ALREADY passed is spent — the
888
+ * leaf is in, or something else took the position and `diverged` says so — so it is dropped
889
+ * rather than counted, and no marker outlives its condition with no clock involved.
890
+ */
891
+ const ordered = this.#ctx.ownLeavesOrdered.get(key);
892
+ let ownLeavesOrdered = 0;
893
+ if (ordered) {
894
+ for (const [hash, seq] of [...ordered]) {
895
+ if (seq < treeSize)
896
+ ordered.delete(hash);
897
+ else
898
+ ownLeavesOrdered++;
899
+ }
900
+ if (ordered.size === 0)
901
+ this.#ctx.ownLeavesOrdered.delete(key);
902
+ }
903
+ return {
904
+ ready: missingLeaves === 0 && heldCount === 0 && !diverged && ownLeavesOrdered === 0,
905
+ treeSize, highWaterSeq, heldCount, missingLeaves,
906
+ heldOwn, heldReceived: heldCount - heldOwn,
907
+ diverged, ownLeavesOrdered,
908
+ };
909
+ }
910
+ /**
911
+ * DOD-M12B-SEAL-STUCK-1 — the operator-facing answer to "can this session be closed?".
912
+ *
913
+ * THREE STATES, because there are three answers. `sealReadiness` above returns a boolean plus raw
914
+ * counters, and both of its counters are easy to misread on a surface:
915
+ *
916
+ * - `missingLeaves` is `#witnessedSeq.size`, which is every position the relay witnessed that
917
+ * this tree has not appended — and a HELD frame keeps its witness entry. So it INCLUDES the
918
+ * held ones. Reporting it beside `heldCount` counts the same message twice and labels one copy
919
+ * "never received" when it is sitting on our own disk. Split here into what each actually is.
920
+ * - Neither counter survives a restart on its own: `#witnessedSeq` is memory-only. Held content
921
+ * is durable since DOD-M12B-STRAND-1, but a position the relay witnessed for content that
922
+ * never arrived leaves no trace. So for a session carrying leaves this process did not watch
923
+ * arrive, "clean" is unknowable — and saying `ready` there invites a close that gets
924
+ * `leaf_count_mismatch` back, which is terminal and costs the receipt for good.
925
+ */
926
+ sealReadinessView(agentName, sessionId) {
927
+ const key = this.#ctx.sessionKey(agentName, sessionId);
928
+ const r = this.sealReadiness(agentName, sessionId);
929
+ // DOD-M15-DIVERGE-1: READ THIS BEFORE THE `!ready` BRANCH, and the order is load-bearing.
930
+ // `diverged` is now a term in `ready`, so a diverged session reaches `!ready` — where it would
931
+ // report `blocked` with awaitingArrival and heldBehindGap both ZERO, replacing an accurate,
932
+ // specific answer with one that describes nothing and invites a retry that can never work.
933
+ // Divergence is permanent and has its own state; the gap cases below are the ones that resolve.
934
+ if (r.diverged) {
935
+ // NOT `ready`. The tree is ahead of the relay's counter for good, so a close here signs a root
936
+ // the counterparty answers `leaf_count_mismatch` to — terminal, and the receipt is gone. The
937
+ // raw counters cannot see this: nothing is missing and nothing is held.
938
+ return { state: "unknown", reason: "record_diverged_from_relay" };
939
+ }
940
+ /**
941
+ * DOD-M15-SEALPRECOND-1 — READ BEFORE THE `!ready` BRANCH, for the reason stated above it.
942
+ * A settling record has nothing missing and nothing held, so `blocked` would report zeros for
943
+ * both — describing nothing, and pointing at a counterparty who has done nothing.
944
+ */
945
+ if (r.ownLeavesOrdered > 0) {
946
+ return { state: "settling", ownSendsInFlight: r.ownLeavesOrdered };
947
+ }
948
+ if (!r.ready) {
949
+ const oldestHeldMs = this.#ctx.queries.oldestHeldMs(agentName, sessionId);
950
+ return {
951
+ state: "blocked",
952
+ // The witness map counts a held frame until it is appended, so subtract the RECEIVED holds
953
+ // to avoid reporting one message twice. NOT the own-sends: the witness map only ever
954
+ // carries counterparty leaves, so subtracting ours would push this count below the truth.
955
+ awaitingArrival: Math.max(0, r.missingLeaves - r.heldReceived),
956
+ heldBehindGap: r.heldCount,
957
+ oldestHeldMs,
958
+ };
959
+ }
960
+ if (r.treeSize > 0 && !this.#ctx.orderingObserved.has(key)) {
961
+ return {
962
+ state: "unknown",
963
+ reason: "witness_state_predates_daemon_start",
964
+ };
965
+ }
966
+ return { state: "ready" };
967
+ }
968
+ /**
969
+ * WHERE THE MUTUALLY-SIGNED PREFIX ENDS, DERIVED FROM THIS DAEMON'S OWN LEAVES —
970
+ * `DOD-M15-UNILATERAL-1`, review F2.
971
+ *
972
+ * ⚠️ **THE FIRST VERSION COMPUTED THIS FROM THE CERTIFICATE'S OWN PARTICIPANT LIST, AND CALLED
973
+ * THAT "recomputed, cannot be steered".** It could be steered. On the SOLO path the certificate's
974
+ * TBS binds no legibility at all, and the client verifies only the *live* party's frontier — so
975
+ * the absent party's `content_frontier_seq` and every `last_authored_seq` arrived unchecked. One
976
+ * directory node could publish the absent party's frontier as 3 and the receipt would say
977
+ * "mutually signed through 3" over a transcript that party never signed for. That is the precise
978
+ * conflation this field exists to prevent, reintroduced by the field itself.
979
+ *
980
+ * The carry answers it without trusting anybody. This daemon holds the counterparty's own leaves,
981
+ * each carrying, inside the bytes THEY signed, both the sequence they authored and the
982
+ * `last_seen_seq` they acknowledged. So a party's commitment reaches
983
+ * `max(highest sequence they authored, highest sequence they acknowledged)`, and the transcript is
984
+ * mutually signed only as far as the LEAST-committed party reaches.
985
+ *
986
+ * Fewer than two distinct authors ⇒ `0`: nobody countersigned anything, which is the honest floor
987
+ * for a conversation where the other side only ever received. `null` when the carry is empty or
988
+ * unreadable — the caller must then publish NO boundary rather than fall back to a number
989
+ * somebody else supplied.
990
+ */
991
+ countersignedThroughSeqFromCarry(agentPubkeyHex, sessionIdHex) {
992
+ const carry = this.getSealCarry(agentPubkeyHex, sessionIdHex);
993
+ if (carry.length === 0)
994
+ return null;
995
+ const reach = new Map();
996
+ for (const leaf of carry) {
997
+ // Structure 1 = [version, content_hash, sender_pubkey, session_id, last_seen_seq, timestamp],
998
+ // plus last_seen_hash at 6 on a v2 claim. `last_seen_seq` is index 4 in both — 020-ACKHASH
999
+ // APPENDS, so this read did not move. The hash is not consulted here: this derives a
1000
+ // POSITIONAL boundary, which is the job last_seen_seq keeps doing alongside the new field.
1001
+ const s1 = decodeStructure1(leaf.structure1Cbor);
1002
+ // Unreadable, or a layout this build cannot name: publish no boundary rather than a
1003
+ // half-derived one somebody else could have shaped.
1004
+ if (!s1.ok)
1005
+ return null;
1006
+ const signedLastSeen = Number.isFinite(Number(s1.fields.lastSeenSeq))
1007
+ ? Number(s1.fields.lastSeenSeq)
1008
+ : 0;
1009
+ const prior = reach.get(leaf.senderPubkeyHex) ?? 0;
1010
+ reach.set(leaf.senderPubkeyHex, Math.max(prior, leaf.sequenceNumber, signedLastSeen));
1011
+ }
1012
+ if (reach.size < 2)
1013
+ return 0;
1014
+ return Math.min(...reach.values());
1015
+ }
1016
+ }
1017
+ //# sourceMappingURL=session-seal.js.map