@cello-protocol/daemon 0.0.227 → 0.0.229

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 +454 -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,964 @@
1
+ /**
2
+ * Session-signing FROST ceremony participation — daemon side (DOD-SPINE-5, increment 3).
3
+ *
4
+ * When an initiator's `cello_initiate_session` reaches the directory, the directory
5
+ * FROST-signs the SessionAssignment by DELEGATING to the initiator: its
6
+ * `ClientDelegatedSigner.participateInCeremony` sends a `ceremony_request`
7
+ * {ceremony_id, tbs, context} over the initiator's authenticated signaling stream and
8
+ * awaits a `ceremony_result` {ceremony_id, signature}. The initiator (coordinator) runs
9
+ * the FROST ceremony with its share + the directory's K_server_X shares, and replies.
10
+ *
11
+ * This wires that handler onto a PER-AGENT signaling stream (the same per-agent routing used for
12
+ * registration).
13
+ *
14
+ * The threshold signer is reconstructed lazily from the agent's persisted
15
+ * `frost-share.json` (the daemon holds no FrostThresholdSigner after registration —
16
+ * the registration-time signer was on the disposed RegistrationContext).
17
+ */
18
+ import { decode } from "cbor-x";
19
+ import { encodeCbor } from "@cello-protocol/protocol-types";
20
+ import { createHash } from "node:crypto";
21
+ import { buildSealTbs } from "@cello-protocol/protocol-types";
22
+ import { bindLegibilityToTbs } from "./seal-legibility-tbs.js";
23
+ import { reDeriveFrontiers, findInflatedFrontier } from "./seal-frontier-verify.js";
24
+ import { FrostThresholdSigner } from "@cello-protocol/crypto";
25
+ import { storeDkgResult } from "@cello-protocol/crypto/frost/frost-threshold-signer.js";
26
+ import { NetworkDirectoryNode, runNetworkRefresh } from "./network-directory-node.js";
27
+ import { extractErrorMessage } from "./error-message.js";
28
+ /**
29
+ * WIRE-002: answer the directory's `session_offer` on a per-agent signaling stream. When an
30
+ * initiator's session_request names this agent as the target, the directory sends a
31
+ * `session_offer {session_id}` before it builds the FROST-signed assignment; the agent must
32
+ * reply `session_offer_accept` advertising its SESSION endpoint (its standing receiver, which
33
+ * `acceptSession` reuses as the receiver-side session node) so the directory can fold the
34
+ * counterparty endpoint into the assignment and the initiator can reach it. Without this, the
35
+ * assignment carries an empty counterparty endpoint and content delivery can never connect.
36
+ */
37
+ export function wireSessionOfferHandler(deps) {
38
+ // DOD-OFFER-REJECT-1 (D1): answer, never vanish. A silent abort left the directory waiting
39
+ // 2 s for an accept that would never come, after which it FROST-signed an assignment with an
40
+ // EMPTY counterparty endpoint and pushed it to both parties — the phantom session's origin.
41
+ // The reject lets the directory fail fast (D2 resolves its waiter on this frame; until the
42
+ // directory understands it, the frame is inert and the timeout path still applies). This is
43
+ // the Generic Reject of the inbound-state matrix, arriving as a protocol necessity.
44
+ // session_id is echoed when present; a no_session_id offer has nothing to echo, so the field
45
+ // is omitted (never an empty value on the wire — same rule as the directory's encoder).
46
+ async function sendOfferReject(sessionId, reason) {
47
+ const rejectFrame = { type: "session_offer_reject", reason };
48
+ if (sessionId)
49
+ rejectFrame["session_id"] = sessionId;
50
+ try {
51
+ // The production seam (transport SignalingManager.sendRaw) NEVER throws — it resolves
52
+ // {ok:false, reason} on every failure (reconnecting, lost, stream throw). Discarding the
53
+ // result would log reject.sent while nothing left the machine (D1 review F1). The catch
54
+ // stays as belt-and-braces for a seam that does throw.
55
+ const res = await deps.signaling.sendRaw(rejectFrame);
56
+ if (res.ok) {
57
+ deps.logger.info("session.offer.reject.sent", { agentName: deps.agentName, reason });
58
+ }
59
+ else {
60
+ deps.logger.warn("session.offer.reject.failed", {
61
+ agentName: deps.agentName,
62
+ reason,
63
+ detail: res.reason ?? "send_not_ok",
64
+ ...(res.guidance ? { guidance: res.guidance } : {}),
65
+ });
66
+ }
67
+ }
68
+ catch (err) {
69
+ deps.logger.warn("session.offer.reject.failed", {
70
+ agentName: deps.agentName,
71
+ reason,
72
+ detail: extractErrorMessage(err),
73
+ });
74
+ }
75
+ }
76
+ return deps.signaling.registerInboundHandler((frame) => {
77
+ if (frame["type"] !== "session_offer")
78
+ return;
79
+ void (async () => {
80
+ const sidRaw = frame["session_id"];
81
+ const sessionId = sidRaw instanceof Uint8Array ? sidRaw : Buffer.isBuffer(sidRaw) ? new Uint8Array(sidRaw) : null;
82
+ if (!sessionId) {
83
+ deps.logger.warn("session.offer.abort", { agentName: deps.agentName, reason: "no_session_id" });
84
+ await sendOfferReject(null, "no_session_id");
85
+ return;
86
+ }
87
+ /**
88
+ * M16: A CHANNEL NEVER CONVERSES — and it says so BEFORE it gives anything away. Accepting here
89
+ * would take a relay reservation and send the caller this agent's session peer id and
90
+ * addresses, all for a session the verified assignment is then refused over. The offer is
91
+ * unauthenticated, but this question is about the LOCAL agent only, so a forged offer can do
92
+ * no more than trigger a refusal that was coming anyway. The assignment gate in
93
+ * inbound-sessions.ts stays as the authenticated line.
94
+ */
95
+ if (deps.isChannelAgent()) {
96
+ deps.logger.warn("session.offer.abort", { agentName: deps.agentName, reason: "channel_identity" });
97
+ await sendOfferReject(sessionId, "channel_identity");
98
+ return;
99
+ }
100
+ let sr = deps.getStandingReceiverEndpoint();
101
+ if (!sr) {
102
+ deps.logger.warn("session.offer.abort", { agentName: deps.agentName, reason: "standing_receiver_unavailable" });
103
+ await sendOfferReject(sessionId, "standing_receiver_unavailable");
104
+ return;
105
+ }
106
+ /**
107
+ * 055-ONDEMAND — **RESERVE NOW, BECAUSE AN IDLE AGENT HOLDS NOTHING.**
108
+ *
109
+ * This is the whole of the capacity change, seen from the receiving end. The agent no longer
110
+ * carries a slot on every relay against the chance that somebody calls; it takes ONE, on the
111
+ * relay this offer names, at the moment somebody does. The accept below then advertises the
112
+ * circuit address that came back.
113
+ *
114
+ * ⚠️ **THE RELAY IS THE DIRECTORY'S CHOICE, NOT OURS.** The assignment the relay will check
115
+ * names the same relay, from the same variable on the directory's side. Reserving on one we
116
+ * picked ourselves would leave us holding a slot the relay will not route through.
117
+ *
118
+ * ⚠️ **A FAILURE HERE IS NOT FATAL BY ITSELF.** Without a circuit we are still reachable by a
119
+ * peer that can dial us directly; it is relay-only that turns this into a refusal, and that
120
+ * check is deliberately BELOW this line rather than above it — see its own note.
121
+ */
122
+ const offeredRelay = frame["relay_endpoint"];
123
+ const relayPeerId = typeof offeredRelay?.peer_id === "string" ? offeredRelay.peer_id : null;
124
+ const relayAddrs = Array.isArray(offeredRelay?.multiaddrs)
125
+ ? offeredRelay.multiaddrs.filter((a) => typeof a === "string")
126
+ : [];
127
+ if (relayPeerId && relayAddrs.length > 0) {
128
+ const base = relayAddrs[0];
129
+ // The circuit address form the walk uses: the relay's own address with `/p2p-circuit`.
130
+ const circuitAddr = base.includes(`/p2p/${relayPeerId}`)
131
+ ? `${base}/p2p-circuit`
132
+ : `${base}/p2p/${relayPeerId}/p2p-circuit`;
133
+ const took = await deps.reserveOnDemand(circuitAddr, Buffer.from(sessionId).toString("hex"));
134
+ deps.logger.info("session.offer.reservation", {
135
+ agentName: deps.agentName,
136
+ relayPeerId,
137
+ granted: took,
138
+ impact: took
139
+ ? "this agent is dialable through the relay the directory named, for the life of this session"
140
+ : "no reservation on the offered relay — a counterparty behind NAT cannot dial this " +
141
+ "agent for this session, and it will be reached over the relay's store-and-forward",
142
+ });
143
+ // Re-read: the endpoint we advertise has to include the circuit we just took.
144
+ sr = deps.getStandingReceiverEndpoint() ?? sr;
145
+ }
146
+ else {
147
+ /**
148
+ * ⚠️ **AN OFFER THAT NAMES NO RELAY USED TO ASK NOBODY AND SAY NOTHING — 056-SLOTDEAD, F8.**
149
+ *
150
+ * `session.offer.reservation` only fires when a relay WAS named, so this branch was silent.
151
+ * The failure that makes silence expensive: if the directory stops naming a relay — an old
152
+ * node in the pool, a bad roll, a regression in `pickRelay` — a relay-only agent refuses
153
+ * every inbound call with `relay_only_no_reservation`. That reason reads as "no relay would
154
+ * grant me a slot", so the operator goes and looks at relay capacity, and the fault is on
155
+ * the directory and has nothing to do with slots. One line makes that a grep.
156
+ *
157
+ * INFO, not WARN: against a directory that has not rolled yet this is the expected shape,
158
+ * and the agent degrades correctly to its direct address. It is loud enough to find, and it
159
+ * says which of the two states it is.
160
+ */
161
+ deps.logger.info("session.offer.reservation.not_offered", {
162
+ agentName: deps.agentName,
163
+ hasRelayEndpoint: offeredRelay !== undefined,
164
+ impact: offeredRelay === undefined
165
+ ? "the directory's offer named no relay, so this agent asked nobody for a slot and will " +
166
+ "answer with the addresses it already has. Expected against a directory that predates " +
167
+ "on-demand reservations; unexpected otherwise, and under relay-only it means the call " +
168
+ "is about to be refused for a reason that points at the wrong side."
169
+ : "the offer carried a relay_endpoint this agent could not read — no usable peer id or " +
170
+ "no multiaddrs — so no slot was asked for. That is a malformed frame from the " +
171
+ "directory, not a relay at capacity.",
172
+ });
173
+ }
174
+ // DOD-M15-RELAYONLY-1: ANSWER, never publish an empty address list — **but only when
175
+ // relay-only is what emptied it.**
176
+ //
177
+ // ⚠️ An empty `addrs` is NOT exclusively a relay-only condition, and the first version of this
178
+ // guard refused unconditionally — which broke the pre-existing accept path for a receiver that
179
+ // legitimately has no addresses yet, a case `session-ceremony-verify` covers on purpose. A
180
+ // privacy control that changes behaviour when it is switched OFF is its own defect.
181
+ //
182
+ // ⚠️ Under relay-only the endpoint is already filtered to circuit addresses, and with no relay
183
+ // reservation that set is EMPTY. The directory folds an accept only
184
+ // `if (counterparty_session_addrs.length > 0)` — **with no `else`** — so an empty accept is
185
+ // dropped in silence, the offer waiter never resolves, and the INITIATOR's operator is told
186
+ // `counterparty_unavailable`: a lie about our state, produced by our setting. Rejecting
187
+ // explicitly keeps the failure attributable to the side that caused it, and is the same
188
+ // answer-never-vanish contract the reject path above already implements.
189
+ /**
190
+ * ⚠️ **AFTER THE ON-DEMAND RESERVE, NOT BEFORE IT — 055-ONDEMAND.** An idle agent holds no
191
+ * reservation by design now, so this guard sitting above the reserve would fire on EVERY
192
+ * inbound offer and take `DOD-M15-RELAYONLY-1` — the control that stops a session revealing
193
+ * the operator's IP — to a 100% refusal rate. Down here it means what it has always meant:
194
+ * relay-only is on and we could not get a circuit, so there is nothing we are willing to
195
+ * advertise.
196
+ */
197
+ if (sr.addrs.length === 0 && (deps.isRelayOnly?.() ?? false)) {
198
+ deps.logger.warn("session.offer.abort", {
199
+ agentName: deps.agentName,
200
+ reason: "relay_only_no_reservation",
201
+ impact: "relay-only is on and this agent holds no relay reservation, so it has no circuit " +
202
+ "address to advertise and will not reveal its own — the offer is refused rather than " +
203
+ "answered with an empty endpoint the directory would silently drop",
204
+ });
205
+ await sendOfferReject(sessionId, "relay_only_no_reservation");
206
+ return;
207
+ }
208
+ /**
209
+ * DOD-M15-ASSIGN-1 — open the door to the named dialer, and ONLY then publish our address.
210
+ *
211
+ * The ordering is the whole mechanism. Our receiver admits nobody until this line runs; the
212
+ * accept below is what tells the directory (and through it, the initiator) where we listen.
213
+ * Narrowing first means the gate names the initiator before the initiator can possibly know
214
+ * where to dial, so there is no interval in which the address is reachable by anyone else.
215
+ *
216
+ * REFUSED WHEN THE OFFER NAMES NOBODY. The directory rejects any session_request that omits
217
+ * `initiator_session_peer_id` (`session_request_missing_peer_id`), so a well-formed request
218
+ * cannot produce a nameless offer — one here means a directory that is broken or lying.
219
+ * Advertising anyway would be the worse failure: the initiator would dial an address whose
220
+ * gate refuses them, and the session would die at the transport with no one able to say why.
221
+ * Rejecting names the cause on the frame the directory is already waiting for.
222
+ */
223
+ const offeredDialerRaw = frame["initiator_session_peer_id"];
224
+ const offeredDialer = typeof offeredDialerRaw === "string" ? offeredDialerRaw : "";
225
+ // Keyed by SESSION (review F1): two overlapping offers to one agent must not overwrite
226
+ // each other's record, or a legitimate session is refused and the check disarms itself.
227
+ const narrowed = deps.admitOfferedDialer(offeredDialer, Buffer.from(sessionId).toString("hex"));
228
+ if (narrowed !== "narrowed") {
229
+ /**
230
+ * Review F6 — ONE REASON PER CAUSE. This branch used to report `offer_named_no_dialer` for
231
+ * both outcomes, and its guidance sent the operator to "the directory is not populating
232
+ * initiator_session_peer_id" even when the truth was that this agent had no standing
233
+ * receiver. That is a local problem wearing a remote label, which is the exact shape that
234
+ * costs days. `standing_receiver_unavailable` already exists two branches above and is the
235
+ * correct name for it.
236
+ */
237
+ const isLocal = narrowed === "no_receiver";
238
+ const reason = isLocal ? "standing_receiver_unavailable" : "offer_named_no_dialer";
239
+ deps.logger.warn("session.offer.abort", {
240
+ agentName: deps.agentName,
241
+ reason,
242
+ impact: isLocal
243
+ ? "this agent has no standing receiver to open, so it cannot serve the session; the session was refused rather than accepted with nowhere to be dialled"
244
+ : "the directory's offer did not say who would dial, so this agent could not open its receiver to exactly one peer; the session was refused rather than served behind a door open to anyone",
245
+ guidance: isLocal
246
+ ? "the receiver is created when the agent comes online — check that cello_start_agent reached this daemon, then have the initiator retry"
247
+ : "the initiator should retry; a repeat means the directory is not populating initiator_session_peer_id and the session cannot be established safely",
248
+ });
249
+ await sendOfferReject(sessionId, reason);
250
+ return;
251
+ }
252
+ try {
253
+ // Same production contract as the reject above (D1 review F3, pre-existing): sendRaw
254
+ // resolves {ok:false, reason} instead of throwing. Logging "accepted" on {ok:false}
255
+ // pointed the operator away from the exact failure that fabricates phantom sessions —
256
+ // the directory hears nothing, stalls 2 s, and signs an endpoint-less assignment.
257
+ const res = await deps.signaling.sendRaw({
258
+ type: "session_offer_accept",
259
+ session_id: sessionId,
260
+ counterparty_session_peer_id: sr.peerId,
261
+ counterparty_session_addrs: sr.addrs,
262
+ });
263
+ if (res.ok) {
264
+ deps.logger.info("session.offer.accepted", {
265
+ agentName: deps.agentName,
266
+ sessionPeerId: sr.peerId,
267
+ });
268
+ }
269
+ else {
270
+ deps.logger.warn("session.offer.accept.failed", {
271
+ agentName: deps.agentName,
272
+ detail: res.reason ?? "send_not_ok",
273
+ ...(res.guidance ? { guidance: res.guidance } : {}),
274
+ });
275
+ }
276
+ }
277
+ catch (err) {
278
+ deps.logger.warn("session.offer.accept.failed", {
279
+ agentName: deps.agentName,
280
+ detail: extractErrorMessage(err),
281
+ });
282
+ }
283
+ })();
284
+ });
285
+ }
286
+ /**
287
+ * Reconstruct the agent's FROST threshold signer from its persisted share, configured to
288
+ * drive the ceremony's `/cello/frost/1.0.0` round-trips on the agent's directory node.
289
+ * Returns null when no share is persisted or the share is unreadable.
290
+ */
291
+ async function hydrateShareAndStubs(deps) {
292
+ const share = await deps.persistence.loadActiveFrostKeyShare();
293
+ if (!share)
294
+ return null;
295
+ const frostSecret = { identifier: share.identifier, signingShare: new Uint8Array(share.signingShare) };
296
+ let commitments = [];
297
+ const verifyingShares = {};
298
+ try {
299
+ const dc = decode(Buffer.from(share.commitmentsCbor));
300
+ if (Array.isArray(dc)) {
301
+ commitments = dc.map((c) => c instanceof Uint8Array ? c : Buffer.isBuffer(c) ? new Uint8Array(c) : new Uint8Array(0));
302
+ }
303
+ const dvs = decode(Buffer.from(share.verifyingSharesCbor));
304
+ if (dvs && typeof dvs === "object" && !Array.isArray(dvs)) {
305
+ for (const [k, v] of Object.entries(dvs)) {
306
+ verifyingShares[k] = v instanceof Uint8Array ? v : Buffer.isBuffer(v) ? new Uint8Array(v) : new Uint8Array(0);
307
+ }
308
+ }
309
+ }
310
+ catch (err) {
311
+ deps.logger.error("session.ceremony.share.load.failed", {
312
+ agentName: deps.agentName,
313
+ reason: "cbor_deserialize_failed",
314
+ detail: extractErrorMessage(err),
315
+ });
316
+ return null;
317
+ }
318
+ const frostPublic = { signers: { min: share.threshold, max: share.participants + 1 }, commitments, verifyingShares };
319
+ try {
320
+ // SI-001: storeDkgResult does not log the secret. Cast via the function's own param
321
+ // types (the daemon has no direct @noble/curves dependency).
322
+ storeDkgResult(deps.agentPubkeyHex, frostSecret, frostPublic);
323
+ }
324
+ catch (err) {
325
+ deps.logger.error("session.ceremony.share.load.failed", {
326
+ agentName: deps.agentName,
327
+ reason: "storeDkgResult_failed",
328
+ detail: extractErrorMessage(err),
329
+ });
330
+ return null;
331
+ }
332
+ // DOD-SIGN-1: build a directory-node stub PER consortium node so the FROST threshold signer
333
+ // can run the signing ceremony across ALL N nodes (it reaches any T and excludes a node that's
334
+ // down — "kill a node, still signs"). With no consortium manifest configured the roster is null
335
+ // → the single primary endpoint (M6/M7 single-node back-compat). NOTE: the share's threshold T
336
+ // (from the multi-node DKG) is FIXED — a degraded roster (fewer than T reachable) makes signing
337
+ // FAIL, it can never forge a lower-threshold signature, so a single-stub fallback is safe.
338
+ let directoryNodeStubs;
339
+ const node = deps.getNode();
340
+ const roster = await deps.getConsortiumEndpoints();
341
+ // Use the share's CURRENT epoch (advances after a proactive refresh) — NOT a hardcoded epoch:1, else
342
+ // post-refresh signing would target the now-EXPIRED epoch and fail (DOD-REFRESH-1). For an un-refreshed
343
+ // agent share.epochId IS "…:epoch:1", so this is identical to the prior behavior.
344
+ const epochId = share.epochId;
345
+ // The stub's FROST identifier (`id`) MUST be the node's DKG label, NOT its libp2p peerId. The directory
346
+ // derives each node's FROST participant identifier as derive(nodeId), where nodeId = the node's region
347
+ // (frost-handler.ts:23 `nodeIdentifier = derive(nodeId)`; the bin sets nodeId = region). So the group's
348
+ // node shares are bound to derive(region), and the node SIGNS under derive(region). If the client verifies
349
+ // /aggregates partials under derive(peerId) instead, every verifyShare fails → all nodes excluded →
350
+ // ceremony_exhausted. `id` feeds Identifier.derive() in the signer; `directoryPeerId` is the network dial
351
+ // and stays the libp2p peerId. (nodeId and peerId coincide only for legacy single-node agents whose DKG
352
+ // predates the region-as-nodeId change — the single-node fallback below passes peerId for that reason.)
353
+ const mkStub = (nodeId, peerId, multiaddr) => {
354
+ const stub = new NetworkDirectoryNode({
355
+ id: nodeId,
356
+ node: node,
357
+ directoryPeerId: peerId,
358
+ directoryMultiaddrs: [multiaddr],
359
+ logger: deps.logger,
360
+ });
361
+ stub.setBootstrapContext(deps.agentPubkeyHex, epochId, (h) => deps.keyProvider.sign(h)); // SEC-2
362
+ return stub;
363
+ };
364
+ if (node && roster !== null && roster.length > 0) {
365
+ // M8B quorum: filter the live roster to the SHARE-HOLDER quorum Q the agent registered with
366
+ // (share.directoryNodeIds), so the seal targets holders — not nodes that came back online after a
367
+ // quorum registration but hold NO share for this agent (they'd pad the count via isReachable()===true
368
+ // and burn the retry budget). Absent Q (pre-quorum agent / single-node) → full roster (unchanged
369
+ // DOD-SIGN-1). Defensive: if every Q node has vanished from the roster, fall back to the full roster
370
+ // rather than an empty signer set (the ceremony's own below-threshold pre-check then applies).
371
+ const q = share.directoryNodeIds;
372
+ const filtered = q && q.length > 0 ? roster.filter((ep) => q.includes(ep.nodeId)) : roster;
373
+ const holders = filtered.length > 0 ? filtered : roster;
374
+ // FROST id = ep.nodeId (region — the DKG label); network dial = ep.peerId.
375
+ directoryNodeStubs = holders.map((ep) => mkStub(ep.nodeId, ep.peerId, ep.multiaddr));
376
+ }
377
+ else if (node) {
378
+ // No consortium manifest (roster null) or a configured manifest that resolved EMPTY → the single
379
+ // primary endpoint. INTENTIONAL asymmetry with DKG-1 (which REFUSES a configured-but-empty roster
380
+ // because DKG needs all N): for SIGNING the share's threshold T is FIXED, so a degraded/single
381
+ // stub makes participateInCeremony fail the `reachable < T-1` pre-check rather than forge a weaker
382
+ // seal — safe. WARN distinctly on the configured-but-unreachable case so the operator sees "your
383
+ // consortium was unreachable" rather than a generic below-threshold error (fallback-finder F3).
384
+ if (roster !== null && roster.length === 0) {
385
+ deps.logger.warn("session.ceremony.consortium_unreachable", { agentName: deps.agentName });
386
+ }
387
+ const ep = await deps.getDirectoryEndpoint();
388
+ if (ep && ep.multiaddr) {
389
+ // Single-node back-compat: no region is available from getDirectoryEndpoint, and legacy single-node
390
+ // agents' DKG labeled the node by peerId (pre region-as-nodeId), so the FROST id stays the peerId here.
391
+ directoryNodeStubs = [mkStub(ep.peerId, ep.peerId, ep.multiaddr)];
392
+ }
393
+ }
394
+ return { share, stubs: directoryNodeStubs };
395
+ }
396
+ export async function reconstructThresholdSigner(deps,
397
+ /**
398
+ * DOD-M15-SEALPARTIES-1: the signed leaves this ceremony's TBS is a root over, forwarded to every
399
+ * directory node so each reaches its own verdict instead of signing a claim. Supplied on the seal
400
+ * ceremony and on nothing else — a co-signer requires it under the seal context and ignores it
401
+ * everywhere else.
402
+ */
403
+ sealEvidence) {
404
+ const h = await hydrateShareAndStubs(deps);
405
+ if (!h)
406
+ return null;
407
+ if (sealEvidence)
408
+ for (const stub of h.stubs ?? [])
409
+ stub.setSealEvidence(sealEvidence);
410
+ return new FrostThresholdSigner({ threshold: h.share.threshold, participants: h.share.participants, directoryNodeStubs: h.stubs }, Buffer.from(deps.agentPubkeyHex, "hex"));
411
+ }
412
+ /**
413
+ * M8B DOD-REFRESH-1: run a proactive share refresh for an already-registered agent. Rotates the client's
414
+ * + every directory node's share to the next epoch (group public key unchanged), then persists the
415
+ * client's new share as the active one so subsequent signing uses the new epoch and old-epoch shares die.
416
+ */
417
+ export async function runAgentRefresh(deps) {
418
+ const h = await hydrateShareAndStubs(deps);
419
+ if (!h)
420
+ return { ok: false, reason: "no_active_share" };
421
+ if (!h.stubs || h.stubs.length === 0)
422
+ return { ok: false, reason: "no_directory_nodes" };
423
+ const fromEpochN = Number(/:epoch:(\d+)$/.exec(h.share.epochId)?.[1] ?? "1");
424
+ let result;
425
+ try {
426
+ result = await runNetworkRefresh(Buffer.from(deps.agentPubkeyHex, "hex"), {
427
+ threshold: h.share.threshold,
428
+ participants: h.share.participants,
429
+ directoryNodes: h.stubs,
430
+ fromEpochN,
431
+ signAuth: (hash) => deps.keyProvider.sign(hash), // SEC-2
432
+ });
433
+ }
434
+ catch (err) {
435
+ deps.logger.error("refresh.ceremony.failed", {
436
+ agentName: deps.agentName,
437
+ detail: extractErrorMessage(err),
438
+ });
439
+ return { ok: false, reason: "ceremony_failed" };
440
+ }
441
+ const primaryPubkeyHex = Buffer.from(result.primaryPubkey).toString("hex");
442
+ // M2 (defense-in-depth): the group public key MUST be byte-identical to the PRE-refresh key. The
443
+ // cross-node check inside runNetworkRefresh only proves all parties AGREE post-refresh — a uniform
444
+ // secret-shift (a crypto-core regression) would move the key on every party identically and pass it,
445
+ // while silently diverging from the registered key counterparties verify seals against. Assert against
446
+ // the KNOWN pre-refresh key (h.share.primaryPubkey) and abort WITHOUT persisting on mismatch.
447
+ if (primaryPubkeyHex !== h.share.primaryPubkey) {
448
+ deps.logger.error("refresh.ceremony.group_key_changed", {
449
+ agentName: deps.agentName,
450
+ expected: h.share.primaryPubkey.slice(0, 16),
451
+ got: primaryPubkeyHex.slice(0, 16),
452
+ });
453
+ return { ok: false, reason: "group_key_changed" };
454
+ }
455
+ // verifyingShares are PUBLIC (s_j·G per participant) and MOVE on a real refresh while commitments[0]
456
+ // (the group key) does not — so their digest is the one observable that distinguishes a genuine
457
+ // rotation from a no-op "relabel" (the spine asserts it changes across two refreshes). SI-001-safe.
458
+ const verifyingSharesDigest = createHash("sha256")
459
+ .update(Object.keys(result.verifyingShares)
460
+ .sort()
461
+ .map((k) => `${k}:${Buffer.from(result.verifyingShares[k]).toString("hex")}`)
462
+ .join("|"))
463
+ .digest("hex");
464
+ // L7: a persist failure here is the most dangerous point (directories already advanced) — surface it
465
+ // as a STRUCTURED reason rather than letting a raw throw escape the handler.
466
+ try {
467
+ await deps.persistence.persistFrostKeyShare({
468
+ epochId: `${deps.agentPubkeyHex}:epoch:${result.toEpochN}`,
469
+ primaryPubkey: primaryPubkeyHex,
470
+ identifier: result.identifier,
471
+ signingShare: result.signingShare,
472
+ threshold: h.share.threshold,
473
+ participants: h.share.participants,
474
+ commitmentsCbor: encodeCbor(result.commitments),
475
+ verifyingSharesCbor: encodeCbor(result.verifyingShares),
476
+ dkgMethod: "network_dkg",
477
+ // M8B quorum: a proactive refresh re-randomizes shares among the SAME membership — carry the
478
+ // quorum Q forward, else this UPDATE wipes frost_directory_node_ids to NULL and the next restart's
479
+ // seal falls back to the full roster (reintroducing the padding/retry-budget bug the persist fixed).
480
+ directoryNodeIds: h.share.directoryNodeIds,
481
+ });
482
+ }
483
+ catch (err) {
484
+ deps.logger.error("refresh.ceremony.persist_failed", {
485
+ agentName: deps.agentName,
486
+ detail: extractErrorMessage(err),
487
+ });
488
+ return { ok: false, reason: "persist_failed" };
489
+ }
490
+ deps.logger.info("refresh.ceremony.complete", {
491
+ agentName: deps.agentName,
492
+ toEpoch: result.toEpochN,
493
+ primaryPubkey: primaryPubkeyHex.slice(0, 16),
494
+ });
495
+ return { ok: true, toEpochN: result.toEpochN, primaryPubkey: primaryPubkeyHex, verifyingSharesDigest };
496
+ }
497
+ /**
498
+ * Register a `ceremony_request` handler on the agent's signaling seam. On the directory's
499
+ * delegated-signing request, run the agent's threshold signer's participateInCeremony and
500
+ * reply with `ceremony_result`. The signer is reconstructed lazily and cached. Returns the
501
+ * unregister function. SI-001: tbs/signature never logged.
502
+ */
503
+ /**
504
+ * DOD-SPINE-7: register a `seal_verified` handler on the agent's signaling seam. After the
505
+ * directory rebuilds + verifies the bilateral seal's signed Merkle chain (relay-mediated
506
+ * processSeal FROST path), it sends the SEAL INITIATOR a `seal_verified` {session_id,
507
+ * sealed_root, leaf_count, timestamp} and waits for the initiator to COORDINATE the seal FROST
508
+ * ceremony. This handler reconstructs the agent's threshold signer (same machinery as the
509
+ * session ceremony), runs participateInCeremony over buildSealTbs with context
510
+ * "cello-frost-seal-v1", and replies `seal_frost_signature` {session_id, frost_signature}. The
511
+ * directory's #processSealFrostSignature then completes notarization and delivers
512
+ * `session_sealed` (the byte-identical sealed_root) to both parties.
513
+ *
514
+ * SI-001: tbs/signature never logged.
515
+ */
516
+ export function wireSealCeremonyHandler(deps) {
517
+ return deps.signaling.registerInboundHandler((frame) => {
518
+ if (frame["type"] !== "seal_verified")
519
+ return;
520
+ void (async () => {
521
+ const toU8 = (v) => v instanceof Uint8Array ? v : Buffer.isBuffer(v) ? new Uint8Array(v) : null;
522
+ const sessionId = toU8(frame["session_id"]);
523
+ const sealedRoot = toU8(frame["sealed_root"]);
524
+ const leafCountRaw = frame["leaf_count"];
525
+ const leafCount = typeof leafCountRaw === "number" ? leafCountRaw : null;
526
+ const tsRaw = frame["timestamp"];
527
+ const timestamp = typeof tsRaw === "number" ? tsRaw : typeof tsRaw === "bigint" ? Number(tsRaw) : null;
528
+ if (!sessionId || !sealedRoot || leafCount === null || timestamp === null) {
529
+ deps.logger.warn("session.seal.ceremony.abort", {
530
+ agentName: deps.agentName,
531
+ reason: !sessionId ? "no_session_id" : !sealedRoot ? "no_sealed_root" : leafCount === null ? "no_leaf_count" : "no_timestamp",
532
+ });
533
+ return;
534
+ }
535
+ const sidHex = Buffer.from(sessionId).toString("hex");
536
+ /**
537
+ * DOD-M15-SEALPARTIES-1: forward the raw signed leaves to every co-signing directory.
538
+ *
539
+ * They arrive on `seal_verified` and are already re-verified on this side (the frontier
540
+ * re-derivation below reads the same array). Forwarding them is what lets a node that did NOT
541
+ * run the verification rebuild the root itself and refuse a certificate over a leaf set the
542
+ * participants never produced — the difference between three signatures that mean three
543
+ * independent judgements and three that rest on one node's reading.
544
+ *
545
+ * Absent here means the frame carried none, and the directories refuse on that: it is not
546
+ * this side's place to decide the evidence was optional.
547
+ */
548
+ const sealEvidenceLeaves = Array.isArray(frame["frontier_leaves"]) && frame["frontier_leaves"].length > 0
549
+ ? frame["frontier_leaves"]
550
+ : undefined;
551
+ // Reconstruct a FRESH signer per ceremony (same rationale as the session ceremony:
552
+ // fresh directory endpoint, no shared FROST state across concurrent ceremonies).
553
+ /**
554
+ * ⚠️ ABSENT IS PASSED AS ABSENT — fallback hunt, finding 4. This used to send `[]`, which the
555
+ * co-signer classified as MALFORMED ("compare builds") rather than MISSING ("someone is asking
556
+ * for a signature without showing the record"). The seal failed either way; the diagnosis the
557
+ * module exists to produce was the one case it could never reach.
558
+ */
559
+ /**
560
+ * Review F6: what each holder SAID, kept so the recorded failure can name it. "Threshold not
561
+ * met" is a count; `SEAL_ROOT_UNSUPPORTED` from a holder is an accusation against the
562
+ * verifying directory, and the operator surface should be able to tell them apart.
563
+ */
564
+ const cosignRefusals = new Set();
565
+ const signer = await reconstructThresholdSigner(deps, sealEvidenceLeaves
566
+ ? { leaves: sealEvidenceLeaves, closeTimestamp: timestamp, onRefused: (r) => cosignRefusals.add(r) }
567
+ : undefined);
568
+ if (!signer) {
569
+ deps.logger.warn("session.seal.ceremony.abort", { agentName: deps.agentName, sessionId: sidHex, reason: "no_signer" });
570
+ deps.recordSealFailure(deps.agentName, sidHex, "seal_ceremony_no_signer", "unresolved");
571
+ return;
572
+ }
573
+ // M7 legibility-TBS-binding: when the directory's seal_verified carries `legibility` (the
574
+ // bilateral seal), fold its canonical hash into the TBS we co-sign — so the FROST signature
575
+ // covers the legibility and a MITM cannot tamper answered/frontier/attestation_mode in
576
+ // transit. The directory binds the IDENTICAL hash (it built the TBS it verifies against);
577
+ // the receiving client re-binds and verifies. Unilateral seal_verified carries no legibility
578
+ // → plain TBS (bindLegibilityToTbs is a no-op), matching the directory's unilateral TBS.
579
+ const legibility = frame["legibility"];
580
+ const legForHash = legibility && typeof legibility === "object" ? legibility : null;
581
+ // DOD-LEG-2 (SI-002): the INITIATOR must not co-sign an inflated certificate — otherwise a
582
+ // validly-FROST-signed inflated cert would exist as a durable artifact. Re-derive each party's
583
+ // content_frontier_seq from the signed leaves the directory ships on seal_verified and ABORT
584
+ // the ceremony (no signature) if any published frontier is inflated. Same logic the receiver
585
+ // applies at session_sealed; doing it here means a lying directory gets NO signature at all.
586
+ const wireParts = legForHash && Array.isArray(legForHash.participants)
587
+ ? (legForHash.participants)
588
+ : null;
589
+ if (wireParts) {
590
+ // Wire pubkeys are Uint8Array; normalise to hex for comparison with the re-derived map.
591
+ const parts = wireParts.map((p) => ({
592
+ pubkey: p.pubkey instanceof Uint8Array
593
+ ? Buffer.from(p.pubkey).toString("hex")
594
+ : (typeof p.pubkey === "string" ? p.pubkey : null),
595
+ content_frontier_seq: typeof p.content_frontier_seq === "number" ? p.content_frontier_seq : null,
596
+ }));
597
+ const malformed = parts.some((p) => p.pubkey === null || p.content_frontier_seq === null);
598
+ const anyClaimed = parts.some((p) => (p.content_frontier_seq ?? 0) > 0);
599
+ const flRaw = frame["frontier_leaves"];
600
+ const haveLeaves = Array.isArray(flRaw) && flRaw.length > 0;
601
+ if (malformed || (anyClaimed && !haveLeaves)) {
602
+ const abortReason = malformed ? "frontier_participant_malformed" : "frontier_leaves_missing";
603
+ deps.logger.warn("session.seal.ceremony.abort", {
604
+ agentName: deps.agentName, sessionId: sidHex, reason: abortReason,
605
+ });
606
+ deps.recordSealFailure(deps.agentName, sidHex, abortReason, "unresolved");
607
+ return;
608
+ }
609
+ if (haveLeaves) {
610
+ const toLeaf = (v) => (v instanceof Uint8Array ? v : new Uint8Array(v));
611
+ const leaves = flRaw.map((l) => {
612
+ const o = l;
613
+ return { structure1_cbor: toLeaf(o["structure1_cbor"]), sender_pubkey: toLeaf(o["sender_pubkey"]), sender_signature: toLeaf(o["sender_signature"]) };
614
+ });
615
+ const rederived = reDeriveFrontiers(leaves, sessionId);
616
+ const inflated = rederived.ok
617
+ ? findInflatedFrontier(parts, rederived.frontiers)
618
+ : null;
619
+ if (!rederived.ok || inflated) {
620
+ const inflatedReason = rederived.ok ? "frontier_unverifiable" : rederived.reason;
621
+ deps.logger.warn("session.seal.ceremony.abort", {
622
+ agentName: deps.agentName, sessionId: sidHex,
623
+ reason: inflatedReason,
624
+ ...(inflated ? { party: inflated.party, publishedFrontier: inflated.publishedFrontier, derivedFrontier: inflated.derivedFrontier } : {}),
625
+ });
626
+ deps.recordSealFailure(deps.agentName, sidHex, inflatedReason, "unresolved");
627
+ return; // refuse to co-sign — the directory gets no signature for an inflated cert
628
+ }
629
+ }
630
+ }
631
+ /**
632
+ * DO NOT SIGN A ROOT THIS AGENT HAS NOT CHECKED — bullet 2's co-signing half (review F1).
633
+ *
634
+ * Same predicate as the receiving path, deliberately: one implementation, so the two halves
635
+ * cannot drift into disagreeing about what counts as a mismatch.
636
+ *
637
+ * `cannot_judge` REFUSES here, where the accept path tolerates it — and the asymmetry is the
638
+ * point. Accepting an unverifiable certificate keeps a receipt that already exists; SIGNING an
639
+ * unverifiable one manufactures a new, durable, non-repudiable claim with this agent's key on
640
+ * it. The safe default is opposite in each direction: tolerate on the way in, refuse on the way
641
+ * out.
642
+ */
643
+ // The evidence travels too: a side that restarted mid-session can never receive the counterparty's
644
+ // SEAL leaf, but the request it is being asked to sign already carries it, signed.
645
+ const rootCheck = deps.verifyCertifiedRoot(deps.agentPubkeyHex, sidHex, sealedRoot, leafCount, sealEvidenceLeaves);
646
+ if (rootCheck.verdict !== "match") {
647
+ deps.logger.error("session.seal.ceremony.abort", {
648
+ agentName: deps.agentName, sessionId: sidHex,
649
+ reason: rootCheck.verdict === "mismatch" ? "root_mismatch" : "root_unverifiable",
650
+ detail: rootCheck.verdict === "mismatch" ? rootCheck.detail : rootCheck.reason,
651
+ ...(rootCheck.verdict === "mismatch" && rootCheck.ownRootHex ? { ownRoot: rootCheck.ownRootHex } : {}),
652
+ impact: "this agent REFUSED to co-sign. Signing would have put its key on a notarization it " +
653
+ "cannot confirm describes this conversation — a durable, valid, non-repudiable claim " +
654
+ "about a transcript it never checked. The session is not sealed; nothing is lost.",
655
+ guidance: "Compare the leaf count with the counterparty and check the directory and relay logs for " +
656
+ "this session id. Do NOT force-abandon: that forfeits the receipt permanently.",
657
+ });
658
+ deps.recordSealFailure(deps.agentName, sidHex, rootCheck.verdict === "mismatch" ? "seal_root_mismatch" : "seal_root_unverifiable", "unresolved");
659
+ return; // refuse to co-sign — the directory gets no signature for a root we cannot verify
660
+ }
661
+ const tbs = bindLegibilityToTbs(buildSealTbs(sessionId, sealedRoot, leafCount, timestamp), legForHash);
662
+ let frostSignature = null;
663
+ try {
664
+ // The initiator COORDINATES the seal FROST ceremony (its signer drives the
665
+ // /cello/frost round-trips with the directory's K_server shares via directoryNodeStubs).
666
+ const result = await signer.participateInCeremony(`seal:${sidHex}`, tbs, "cello-frost-seal-v1");
667
+ frostSignature = result.ok ? new Uint8Array(result.signature) : null;
668
+ deps.logger.info("session.seal.ceremony.participated", { agentName: deps.agentName, sessionId: sidHex, ok: result.ok });
669
+ }
670
+ catch (err) {
671
+ deps.logger.warn("session.seal.ceremony.failed", {
672
+ agentName: deps.agentName,
673
+ sessionId: sidHex,
674
+ detail: extractErrorMessage(err),
675
+ });
676
+ deps.recordSealFailure(deps.agentName, sidHex, "seal_ceremony_threw", "unresolved");
677
+ return;
678
+ }
679
+ if (!frostSignature) {
680
+ /**
681
+ * ⚠️ THIS WAS `if (!frostSignature) return;` WITH NO LOG AND NO RECORD —
682
+ * `DOD-M15-SEALPARTIES-1`.
683
+ *
684
+ * It is where a seal lands when the FROST ceremony produces nothing, and requiring the
685
+ * co-signing directories to judge the leaves makes it reachable for a NEW and important
686
+ * reason: a holder looked at the record, decided it does not support the root, and declined.
687
+ * That is the strongest signal this system produces, and its entire trace was a bare return.
688
+ *
689
+ * The refusing node's own reason is on the coordinating side too — `network-directory-node`
690
+ * logs `frost.directory.sign.refused` per node with what that node said — because a
691
+ * threshold failure is a count, and the count does not say WHY any particular holder said
692
+ * no.
693
+ */
694
+ deps.logger.error("session.seal.ceremony.no_signature", {
695
+ agentName: deps.agentName,
696
+ sessionId: sidHex,
697
+ cosignRefusals: [...cosignRefusals].sort(),
698
+ impact: "the seal FROST ceremony ended with no signature, so this session has no certificate " +
699
+ "and nothing was signed with this agent's key. Enough share-holding directories " +
700
+ "declined or were unreachable that the threshold was not met.",
701
+ guidance: "Look for frost.directory.sign.refused in this daemon's log — each line names one " +
702
+ "directory and the reason it gave. A SEAL_ROOT_UNSUPPORTED there means a holder rebuilt " +
703
+ "the root from the leaves and got a different answer, which is a fault in the verifying " +
704
+ "directory or the relay, not in this agent. Do NOT force-abandon: that forfeits the " +
705
+ "receipt permanently.",
706
+ });
707
+ deps.recordSealFailure(deps.agentName, sidHex, cosignRefusals.size > 0
708
+ ? `seal_cosigners_refused:${[...cosignRefusals].sort().join(",")}`
709
+ : "seal_ceremony_threshold_not_met", "unresolved");
710
+ return;
711
+ }
712
+ await sendSealFrostSignature(deps, sessionId, sidHex, frostSignature);
713
+ })();
714
+ });
715
+ }
716
+ /**
717
+ * DOD-SENDRAW-1: deliver the co-signed seal FROST signature to the directory, branching on the
718
+ * seam's RESOLVED result. The production seam (transport SignalingManager.sendRaw) never throws —
719
+ * it resolves {ok:false, reason} on every failure — so the old try/catch logged `.sent` for a
720
+ * signature that never left the machine, inside the non-repudiation ceremony, and the failure
721
+ * event was unreachable. Exported so the send contract is testable without a live FROST ceremony.
722
+ */
723
+ export async function sendSealFrostSignature(deps, sessionId, sidHex, frostSignature) {
724
+ try {
725
+ const res = await deps.signaling.sendRaw({ type: "seal_frost_signature", session_id: sessionId, frost_signature: frostSignature });
726
+ if (res.ok) {
727
+ deps.logger.info("session.seal.frost.signature.sent", { agentName: deps.agentName, sessionId: sidHex });
728
+ }
729
+ else {
730
+ deps.logger.warn("session.seal.frost.signature.send.failed", {
731
+ agentName: deps.agentName,
732
+ sessionId: sidHex,
733
+ detail: res.reason ?? "send_not_ok",
734
+ ...(res.guidance ? { guidance: res.guidance } : {}),
735
+ });
736
+ }
737
+ }
738
+ catch (err) {
739
+ deps.logger.warn("session.seal.frost.signature.send.failed", {
740
+ agentName: deps.agentName,
741
+ sessionId: sidHex,
742
+ detail: extractErrorMessage(err),
743
+ });
744
+ }
745
+ }
746
+ /**
747
+ * SESSION-002 (DOD-SEAL-3): verify a unilateral seal certificate WITHOUT trusting the
748
+ * channel. Rebuilds the canonical seal TBS from the cert fields and verifies the signature
749
+ * against a key trusted independently of the delivering frame: the session primary_pubkey
750
+ * (commitments[0] of this agent's FROST share) for 'frost'. A channel-swapped sealed_root
751
+ * (or any TBS-bound field) fails this check (SI-003).
752
+ *
753
+ * 'single' is not a second variant this function is missing — it is a DOWNGRADE, refused by name
754
+ * before a session exists (`assignment_signature_type_downgraded`, assignment-verify.ts, checked
755
+ * against the directory's only producer of `signature_type`). A cert carrying it is a shape no
756
+ * honest peer can produce, so the branch below refuses rather than verifying. Do not "finish" it
757
+ * by adding a manifest-key path: that would make the downgrade verifiable instead of refused,
758
+ * which is the outcome the upstream check exists to prevent.
759
+ */
760
+ export async function verifyUnilateralCertificate(deps, cert) {
761
+ const tbs = buildSealTbs(cert.sessionId, cert.sealedRoot, cert.leafCount, cert.closeTimestamp);
762
+ if (cert.signatureType !== "frost") {
763
+ // 'single' is a DOWNGRADE, not an unfinished path. A pre-DKG single-key assignment is refused
764
+ // by name upstream (`assignment_signature_type_downgraded`, assignment-verify.ts), so a cert
765
+ // reaching here with one is a shape that should never arrive. Refusing is the correct end state;
766
+ // there is nothing to wire.
767
+ return { ok: false, reason: "single_key_verification_unsupported" };
768
+ }
769
+ const share = await deps.persistence.loadActiveFrostKeyShare();
770
+ if (!share)
771
+ return { ok: false, reason: "no_frost_share" };
772
+ let primaryPubkey = null;
773
+ try {
774
+ const dc = decode(Buffer.from(share.commitmentsCbor));
775
+ if (Array.isArray(dc) && dc.length > 0) {
776
+ const c0 = dc[0];
777
+ primaryPubkey = c0 instanceof Uint8Array ? c0 : Buffer.isBuffer(c0) ? new Uint8Array(c0) : null;
778
+ }
779
+ }
780
+ catch (err) {
781
+ deps.logger.warn("session.unilateral.certificate.share.decode.failed", {
782
+ agentPubkey: deps.agentPubkeyHex,
783
+ detail: extractErrorMessage(err),
784
+ });
785
+ return { ok: false, reason: "share_decode_failed" };
786
+ }
787
+ if (!primaryPubkey || primaryPubkey.length !== 32)
788
+ return { ok: false, reason: "no_primary_pubkey" };
789
+ const verifier = new FrostThresholdSigner({ threshold: 1, participants: 1 }, Buffer.from(deps.agentPubkeyHex, "hex"));
790
+ const valid = verifier.verifySignature(cert.frostSignature, tbs, "cello-frost-seal-v1", primaryPubkey);
791
+ return valid ? { ok: true } : { ok: false, reason: "signature_invalid" };
792
+ }
793
+ /**
794
+ * M7 legibility-TBS-binding: verify a BILATERAL session_sealed certificate's signature over the
795
+ * legibility-bound TBS, channel-independently.
796
+ *
797
+ * KEY STRUCTURE (why verifiability is asymmetric TODAY): the seal's FROST signature is produced by
798
+ * the group key (commitments[0] of the DKG share) of whichever party CLOSED THE SESSION FIRST — the
799
+ * directory designates the sender of the first SEAL ctrl leaf as the "seal initiator" and signs
800
+ * against that party's primary (directory-node.ts). This is NOT a fixed initiator/responder role:
801
+ * either the session initiator or the responder can be the first closer.
802
+ *
803
+ * A party can channel-independently verify here only against a group primary it HOLDS locally:
804
+ * - its OWN primary — loaded from its own DKG share (`signer_pubkey === own primary`); or
805
+ * - the counterparty's primary — recorded via recordCounterpartyPrimary (see below).
806
+ * It then verifies the FROST signature over `buildSealTbs ‖ legibilityHash`. A tampered legibility
807
+ * (answered / content_frontier_seq / attestation_mode — carried unsigned on the frame) changes the
808
+ * hash → the signature fails → REJECT.
809
+ *
810
+ * When the signer's key is NOT held locally, the party ACCEPTS (`verified:false`, with a `reason`).
811
+ * This is sound for the LIVE path: session_sealed arrives over the daemon↔directory libp2p Noise
812
+ * channel (authenticated + encrypted), so it is not MITM-tamperable in transit; the binding's
813
+ * primary value is OUT-OF-BAND (any holder of the signer's primary — e.g. an arbitrator — can verify
814
+ * an exported cert's legibility).
815
+ *
816
+ * SYMMETRY: both closing orders verify locally, and it takes BOTH bindings to stay that way. The
817
+ * initiator learns the responder's primary from `participant_b_primary_pubkey` with a binding
818
+ * signed by participant_b's own K_local, recorded by `initiate-session-handler.ts`; the responder
819
+ * learns the initiator's from `signer_pubkey` with `participant_a_key_binding`, verified before the
820
+ * assignment's threshold signature is checked at all and recorded by `inbound-sessions.ts`. Both
821
+ * are refused by name when absent or invalid (`assignment-verify.ts`).
822
+ *
823
+ * The binding, not the key, is the load-bearing part: carrying a group key alone would let a
824
+ * directory name one of its choosing, so a change that keeps either key and drops its binding
825
+ * breaks verification while appearing to work.
826
+ *
827
+ * `signer_key_not_held` is therefore NOT the ordinary responder-first outcome. It remains reachable
828
+ * for a session row that predates the recording, or one whose assignment never reached this path,
829
+ * and it is the honest answer there, which is why the branch stays.
830
+ *
831
+ * `legibility` MUST be the AS-RECEIVED wire object (not a normalised copy) — the directory signed
832
+ * over the canonical hash of exactly what it sent.
833
+ */
834
+ export async function verifyBilateralSealCertificate(deps, cert) {
835
+ // F2-a: every verified:false branch carries a `reason` so the daemon's
836
+ // session.sealed.signature.checked log can never read as a silently-tolerated FAILED check.
837
+ // A genuinely failed check takes the { ok:false, reason:"signature_invalid" } path, which the
838
+ // caller REJECTS (never marks sealed). verified:false is always "no key held to verify → accepted
839
+ // on the authenticated Noise channel", never "a check ran and failed".
840
+ if (cert.signatureType !== "frost")
841
+ return { ok: true, verified: false, reason: "non_frost_certificate" };
842
+ if (cert.signerPubkey.length !== 32)
843
+ return { ok: false, reason: "no_signer_pubkey" };
844
+ const signerHex = Buffer.from(cert.signerPubkey).toString("hex");
845
+ const share = await deps.persistence.loadActiveFrostKeyShare();
846
+ if (!share)
847
+ return { ok: true, verified: false, reason: "no_frost_share" }; // no share to verify with — accept (Noise-delivered)
848
+ let ownPrimary = null;
849
+ try {
850
+ const dc = decode(Buffer.from(share.commitmentsCbor));
851
+ if (Array.isArray(dc) && dc.length > 0) {
852
+ const c0 = dc[0];
853
+ ownPrimary = c0 instanceof Uint8Array ? c0 : Buffer.isBuffer(c0) ? new Uint8Array(c0) : null;
854
+ }
855
+ }
856
+ catch {
857
+ return { ok: true, verified: false, reason: "commitments_decode_failed" };
858
+ }
859
+ if (!ownPrimary || ownPrimary.length !== 32)
860
+ return { ok: true, verified: false, reason: "own_primary_unavailable" };
861
+ // The seal is signed by the INITIATOR's primary (group) key. This party can verify against a
862
+ // key it holds independently: its OWN primary (when it is the initiator) or the counterparty's
863
+ // primary from the FROST-signed SessionAssignment (when it is the responder). SI-003: the signer
864
+ // must be one of these — never a key supplied only by the (untrusted) cert frame.
865
+ const cpHex = deps.counterpartyPrimaryHex ?? null;
866
+ if (signerHex === Buffer.from(ownPrimary).toString("hex")) {
867
+ // initiator path — verify against own primary.
868
+ }
869
+ else if (cpHex && signerHex === cpHex.toLowerCase()) {
870
+ // responder path — verify against the known counterparty primary.
871
+ }
872
+ else if (cpHex) {
873
+ // We know the counterparty primary and the signer is NEITHER participant → unknown signer.
874
+ return { ok: false, reason: "signer_not_a_session_participant" };
875
+ }
876
+ else {
877
+ // We do not hold the signer's key (no counterparty primary recorded) → cannot verify; accept
878
+ // (the live frame arrived over the authenticated Noise channel; the binding aids out-of-band).
879
+ // Reachable only for a session whose assignment never carried (or never recorded) the
880
+ // counterparty's bound primary — a pre-038-KEYBIND row. A CURRENT session reaching here means
881
+ // `recordCounterpartyPrimary` did not run on either side (`initiate-session-handler.ts` for the
882
+ // initiator, `inbound-sessions.ts` for the responder), which is a defect, not a close order.
883
+ return { ok: true, verified: false, reason: "signer_key_not_held" };
884
+ }
885
+ const tbs = bindLegibilityToTbs(buildSealTbs(cert.sessionId, cert.sealedRoot, cert.leafCount, cert.closeTimestamp), cert.legibility);
886
+ const verifier = new FrostThresholdSigner({ threshold: 1, participants: 1 }, Buffer.from(deps.agentPubkeyHex, "hex"));
887
+ const valid = verifier.verifySignature(cert.frostSignature, tbs, "cello-frost-seal-v1", cert.signerPubkey);
888
+ return valid ? { ok: true, verified: true } : { ok: false, reason: "signature_invalid" };
889
+ }
890
+ export function wireSessionCeremonyHandler(deps) {
891
+ return deps.signaling.registerInboundHandler((frame) => {
892
+ if (frame["type"] !== "ceremony_request")
893
+ return;
894
+ void (async () => {
895
+ const ceremonyId = typeof frame["ceremony_id"] === "string" ? frame["ceremony_id"] : undefined;
896
+ const tbsRaw = frame["tbs"];
897
+ const tbs = tbsRaw instanceof Uint8Array ? tbsRaw : Buffer.isBuffer(tbsRaw) ? new Uint8Array(tbsRaw) : null;
898
+ const context = typeof frame["context"] === "string" ? frame["context"] : undefined;
899
+ // L3: the reply send is best-effort — a throw here must not become an unhandled
900
+ // rejection in this fire-and-forget handler. DOD-SENDRAW-1: the production seam never
901
+ // throws — it resolves {ok:false, reason} — so the failure must be read off the RESULT;
902
+ // catch-only made session.ceremony.reply.failed unreachable in production.
903
+ const reply = async (signature) => {
904
+ if (!ceremonyId)
905
+ return;
906
+ try {
907
+ const res = await deps.signaling.sendRaw({ type: "ceremony_result", ceremony_id: ceremonyId, signature });
908
+ if (!res.ok) {
909
+ deps.logger.warn("session.ceremony.reply.failed", {
910
+ agentName: deps.agentName,
911
+ detail: res.reason ?? "send_not_ok",
912
+ ...(res.guidance ? { guidance: res.guidance } : {}),
913
+ });
914
+ }
915
+ }
916
+ catch (err) {
917
+ deps.logger.warn("session.ceremony.reply.failed", {
918
+ agentName: deps.agentName,
919
+ detail: extractErrorMessage(err),
920
+ });
921
+ }
922
+ };
923
+ // L1: a request with no addressable ceremony_id cannot be replied to (the reply is
924
+ // keyed by it) — log and drop rather than send an unkeyed result.
925
+ if (!ceremonyId) {
926
+ deps.logger.warn("session.ceremony.abort", { agentName: deps.agentName, reason: "no_ceremony_id" });
927
+ return;
928
+ }
929
+ if (!tbs || !context) {
930
+ deps.logger.warn("session.ceremony.abort", { agentName: deps.agentName, reason: !tbs ? "no_tbs" : "no_context" });
931
+ await reply(null);
932
+ return;
933
+ }
934
+ // H1 / M1 / concurrency: reconstruct a FRESH signer (fresh directory endpoint +
935
+ // NetworkDirectoryNode) PER ceremony. No caching — so signaling reconnecting to a
936
+ // different directory node is picked up, a transient reconstruction failure retries
937
+ // on the next request, and concurrent ceremonies never share one signer's FROST
938
+ // state. (storeDkgResult is idempotent for the same share; reconstruction is cheap.)
939
+ const signer = await reconstructThresholdSigner(deps);
940
+ if (!signer) {
941
+ deps.logger.warn("session.ceremony.abort", { agentName: deps.agentName, reason: "no_signer" });
942
+ await reply(null);
943
+ return;
944
+ }
945
+ try {
946
+ const result = await signer.participateInCeremony(ceremonyId, tbs, context);
947
+ deps.logger.info("session.ceremony.participated", {
948
+ agentName: deps.agentName,
949
+ ceremonyId: ceremonyId.slice(0, 16),
950
+ ok: result.ok,
951
+ });
952
+ await reply(result.ok ? new Uint8Array(result.signature) : null);
953
+ }
954
+ catch (err) {
955
+ deps.logger.warn("session.ceremony.failed", {
956
+ agentName: deps.agentName,
957
+ detail: extractErrorMessage(err),
958
+ });
959
+ await reply(null);
960
+ }
961
+ })();
962
+ });
963
+ }
964
+ //# sourceMappingURL=session-ceremony.js.map