@cello-protocol/daemon 0.0.227 → 0.0.228

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (895) hide show
  1. package/dist/agent-admin-handlers.d.ts +56 -0
  2. package/dist/agent-admin-handlers.d.ts.map +1 -0
  3. package/dist/agent-admin-handlers.js +73 -0
  4. package/dist/agent-admin-handlers.js.map +1 -0
  5. package/dist/agent-handlers.d.ts +72 -0
  6. package/dist/agent-handlers.d.ts.map +1 -0
  7. package/dist/agent-handlers.js +604 -0
  8. package/dist/agent-handlers.js.map +1 -0
  9. package/dist/agent-id-migration.d.ts +70 -0
  10. package/dist/agent-id-migration.d.ts.map +1 -0
  11. package/dist/agent-id-migration.js +468 -0
  12. package/dist/agent-id-migration.js.map +1 -0
  13. package/dist/agent-loader.d.ts +37 -0
  14. package/dist/agent-loader.d.ts.map +1 -0
  15. package/dist/agent-loader.js +37 -0
  16. package/dist/agent-loader.js.map +1 -0
  17. package/dist/agent-selection-root.d.ts +29 -0
  18. package/dist/agent-selection-root.d.ts.map +1 -0
  19. package/dist/agent-selection-root.js +126 -0
  20. package/dist/agent-selection-root.js.map +1 -0
  21. package/dist/agent-selection.d.ts +73 -0
  22. package/dist/agent-selection.d.ts.map +1 -0
  23. package/dist/agent-selection.js +80 -0
  24. package/dist/agent-selection.js.map +1 -0
  25. package/dist/agent-settings-keys.d.ts +52 -0
  26. package/dist/agent-settings-keys.d.ts.map +1 -0
  27. package/dist/agent-settings-keys.js +114 -0
  28. package/dist/agent-settings-keys.js.map +1 -0
  29. package/dist/agent-state.d.ts +67 -0
  30. package/dist/agent-state.d.ts.map +1 -0
  31. package/dist/agent-state.js +66 -0
  32. package/dist/agent-state.js.map +1 -0
  33. package/dist/assignment-verify.d.ts +90 -0
  34. package/dist/assignment-verify.d.ts.map +1 -0
  35. package/dist/assignment-verify.js +301 -0
  36. package/dist/assignment-verify.js.map +1 -0
  37. package/dist/attendance-wiring.d.ts +23 -0
  38. package/dist/attendance-wiring.d.ts.map +1 -0
  39. package/dist/attendance-wiring.js +248 -0
  40. package/dist/attendance-wiring.js.map +1 -0
  41. package/dist/attestation-body.d.ts +47 -0
  42. package/dist/attestation-body.d.ts.map +1 -0
  43. package/dist/attestation-body.js +71 -0
  44. package/dist/attestation-body.js.map +1 -0
  45. package/dist/authorship-verification.d.ts +91 -0
  46. package/dist/authorship-verification.d.ts.map +1 -0
  47. package/dist/authorship-verification.js +532 -0
  48. package/dist/authorship-verification.js.map +1 -0
  49. package/dist/away-detection.d.ts +139 -0
  50. package/dist/away-detection.d.ts.map +1 -0
  51. package/dist/away-detection.js +186 -0
  52. package/dist/away-detection.js.map +1 -0
  53. package/dist/away-inbox-oneshot.d.ts +40 -0
  54. package/dist/away-inbox-oneshot.d.ts.map +1 -0
  55. package/dist/away-inbox-oneshot.js +311 -0
  56. package/dist/away-inbox-oneshot.js.map +1 -0
  57. package/dist/backup-restore-handlers.d.ts +10 -0
  58. package/dist/backup-restore-handlers.d.ts.map +1 -0
  59. package/dist/backup-restore-handlers.js +82 -0
  60. package/dist/backup-restore-handlers.js.map +1 -0
  61. package/dist/backup-restore.d.ts +102 -0
  62. package/dist/backup-restore.d.ts.map +1 -0
  63. package/dist/backup-restore.js +341 -0
  64. package/dist/backup-restore.js.map +1 -0
  65. package/dist/bin/cello-daemon.d.ts +13 -0
  66. package/dist/bin/cello-daemon.d.ts.map +1 -0
  67. package/dist/bin/cello-daemon.js.map +1 -0
  68. package/dist/boot-agents.d.ts +64 -0
  69. package/dist/boot-agents.d.ts.map +1 -0
  70. package/dist/boot-agents.js +241 -0
  71. package/dist/boot-agents.js.map +1 -0
  72. package/dist/boot-connection-state.d.ts +38 -0
  73. package/dist/boot-connection-state.d.ts.map +1 -0
  74. package/dist/boot-connection-state.js +95 -0
  75. package/dist/boot-connection-state.js.map +1 -0
  76. package/dist/boot-core.d.ts +36 -0
  77. package/dist/boot-core.d.ts.map +1 -0
  78. package/dist/boot-core.js +293 -0
  79. package/dist/boot-core.js.map +1 -0
  80. package/dist/boot-parked-content.d.ts +34 -0
  81. package/dist/boot-parked-content.d.ts.map +1 -0
  82. package/dist/boot-parked-content.js +528 -0
  83. package/dist/boot-parked-content.js.map +1 -0
  84. package/dist/boot-sweeps.d.ts +22 -0
  85. package/dist/boot-sweeps.d.ts.map +1 -0
  86. package/dist/boot-sweeps.js +51 -0
  87. package/dist/boot-sweeps.js.map +1 -0
  88. package/dist/bundled-consortium-manifest.d.ts +47 -0
  89. package/dist/bundled-consortium-manifest.d.ts.map +1 -0
  90. package/dist/bundled-consortium-manifest.js +116 -0
  91. package/dist/bundled-consortium-manifest.js.map +1 -0
  92. package/dist/cbor-blob-migration.d.ts +8 -0
  93. package/dist/cbor-blob-migration.d.ts.map +1 -0
  94. package/dist/cbor-blob-migration.js +116 -0
  95. package/dist/cbor-blob-migration.js.map +1 -0
  96. package/dist/challenge-verifier.d.ts +12 -0
  97. package/dist/challenge-verifier.d.ts.map +1 -0
  98. package/dist/challenge-verifier.js +11 -0
  99. package/dist/challenge-verifier.js.map +1 -0
  100. package/dist/channel-log-store.d.ts +80 -0
  101. package/dist/channel-log-store.d.ts.map +1 -0
  102. package/dist/channel-log-store.js +290 -0
  103. package/dist/channel-log-store.js.map +1 -0
  104. package/dist/close-commitment.d.ts +67 -0
  105. package/dist/close-commitment.d.ts.map +1 -0
  106. package/dist/close-commitment.js +78 -0
  107. package/dist/close-commitment.js.map +1 -0
  108. package/dist/close-session-handler.d.ts +94 -0
  109. package/dist/close-session-handler.d.ts.map +1 -0
  110. package/dist/close-session-handler.js +1418 -0
  111. package/dist/close-session-handler.js.map +1 -0
  112. package/dist/co-attendance.d.ts +29 -0
  113. package/dist/co-attendance.d.ts.map +1 -0
  114. package/dist/co-attendance.js +32 -0
  115. package/dist/co-attendance.js.map +1 -0
  116. package/dist/column-birth.d.ts +40 -0
  117. package/dist/column-birth.d.ts.map +1 -0
  118. package/dist/column-birth.js +61 -0
  119. package/dist/column-birth.js.map +1 -0
  120. package/dist/connect-or-start.d.ts +25 -0
  121. package/dist/connect-or-start.d.ts.map +1 -0
  122. package/dist/connect-or-start.js +175 -0
  123. package/dist/connect-or-start.js.map +1 -0
  124. package/dist/connection-agents.d.ts +16 -0
  125. package/dist/connection-agents.d.ts.map +1 -0
  126. package/dist/connection-agents.js +68 -0
  127. package/dist/connection-agents.js.map +1 -0
  128. package/dist/consent-migration.d.ts +49 -0
  129. package/dist/consent-migration.d.ts.map +1 -0
  130. package/dist/consent-migration.js +128 -0
  131. package/dist/consent-migration.js.map +1 -0
  132. package/dist/consortium-bootstrap.d.ts +138 -0
  133. package/dist/consortium-bootstrap.d.ts.map +1 -0
  134. package/dist/consortium-bootstrap.js +339 -0
  135. package/dist/consortium-bootstrap.js.map +1 -0
  136. package/dist/consortium-fingerprint.d.ts +115 -0
  137. package/dist/consortium-fingerprint.d.ts.map +1 -0
  138. package/dist/consortium-fingerprint.js +175 -0
  139. package/dist/consortium-fingerprint.js.map +1 -0
  140. package/dist/contact-handlers.d.ts +59 -0
  141. package/dist/contact-handlers.d.ts.map +1 -0
  142. package/dist/contact-handlers.js +343 -0
  143. package/dist/contact-handlers.js.map +1 -0
  144. package/dist/contact-pubkey-case.d.ts +65 -0
  145. package/dist/contact-pubkey-case.d.ts.map +1 -0
  146. package/dist/contact-pubkey-case.js +136 -0
  147. package/dist/contact-pubkey-case.js.map +1 -0
  148. package/dist/contacts-tier-migration.d.ts +90 -0
  149. package/dist/contacts-tier-migration.d.ts.map +1 -0
  150. package/dist/contacts-tier-migration.js +150 -0
  151. package/dist/contacts-tier-migration.js.map +1 -0
  152. package/dist/content-encryption-status.d.ts +111 -0
  153. package/dist/content-encryption-status.d.ts.map +1 -0
  154. package/dist/content-encryption-status.js +158 -0
  155. package/dist/content-encryption-status.js.map +1 -0
  156. package/dist/content-park-client.d.ts +90 -0
  157. package/dist/content-park-client.d.ts.map +1 -0
  158. package/dist/content-park-client.js +362 -0
  159. package/dist/content-park-client.js.map +1 -0
  160. package/dist/content-park.d.ts +52 -0
  161. package/dist/content-park.d.ts.map +1 -0
  162. package/dist/content-park.js +1309 -0
  163. package/dist/content-park.js.map +1 -0
  164. package/dist/cross-node-negotiation.d.ts +44 -0
  165. package/dist/cross-node-negotiation.d.ts.map +1 -0
  166. package/dist/cross-node-negotiation.js +34 -0
  167. package/dist/cross-node-negotiation.js.map +1 -0
  168. package/dist/daemon-handle.d.ts +57 -0
  169. package/dist/daemon-handle.d.ts.map +1 -0
  170. package/dist/daemon-handle.js +2 -0
  171. package/dist/daemon-handle.js.map +1 -0
  172. package/dist/daemon-status-report.d.ts +50 -0
  173. package/dist/daemon-status-report.d.ts.map +1 -0
  174. package/dist/daemon-status-report.js +81 -0
  175. package/dist/daemon-status-report.js.map +1 -0
  176. package/dist/daemon.d.ts +45 -0
  177. package/dist/daemon.d.ts.map +1 -0
  178. package/dist/daemon.js +1177 -0
  179. package/dist/daemon.js.map +1 -0
  180. package/dist/db-identity-store.d.ts +159 -0
  181. package/dist/db-identity-store.d.ts.map +1 -0
  182. package/dist/db-identity-store.js +502 -0
  183. package/dist/db-identity-store.js.map +1 -0
  184. package/dist/delivery-open-registry.d.ts +92 -0
  185. package/dist/delivery-open-registry.d.ts.map +1 -0
  186. package/dist/delivery-open-registry.js +121 -0
  187. package/dist/delivery-open-registry.js.map +1 -0
  188. package/dist/delivery-session-suspects.d.ts +56 -0
  189. package/dist/delivery-session-suspects.d.ts.map +1 -0
  190. package/dist/delivery-session-suspects.js +94 -0
  191. package/dist/delivery-session-suspects.js.map +1 -0
  192. package/dist/directory-auth-posture.d.ts +87 -0
  193. package/dist/directory-auth-posture.d.ts.map +1 -0
  194. package/dist/directory-auth-posture.js +134 -0
  195. package/dist/directory-auth-posture.js.map +1 -0
  196. package/dist/directory-bootstrap.d.ts +310 -0
  197. package/dist/directory-bootstrap.d.ts.map +1 -0
  198. package/dist/directory-bootstrap.js +557 -0
  199. package/dist/directory-bootstrap.js.map +1 -0
  200. package/dist/directory-connect.d.ts +27 -0
  201. package/dist/directory-connect.d.ts.map +1 -0
  202. package/dist/directory-connect.js +106 -0
  203. package/dist/directory-connect.js.map +1 -0
  204. package/dist/disconnect-cleanup.d.ts +51 -0
  205. package/dist/disconnect-cleanup.d.ts.map +1 -0
  206. package/dist/disconnect-cleanup.js +72 -0
  207. package/dist/disconnect-cleanup.js.map +1 -0
  208. package/dist/document-amendment-store.d.ts +120 -0
  209. package/dist/document-amendment-store.d.ts.map +1 -0
  210. package/dist/document-amendment-store.js +266 -0
  211. package/dist/document-amendment-store.js.map +1 -0
  212. package/dist/document-delivery-transport.d.ts +168 -0
  213. package/dist/document-delivery-transport.d.ts.map +1 -0
  214. package/dist/document-delivery-transport.js +206 -0
  215. package/dist/document-delivery-transport.js.map +1 -0
  216. package/dist/document-engine.d.ts +134 -0
  217. package/dist/document-engine.d.ts.map +1 -0
  218. package/dist/document-engine.js +282 -0
  219. package/dist/document-engine.js.map +1 -0
  220. package/dist/document-flag.d.ts +58 -0
  221. package/dist/document-flag.d.ts.map +1 -0
  222. package/dist/document-flag.js +70 -0
  223. package/dist/document-flag.js.map +1 -0
  224. package/dist/document-frame-router.d.ts +245 -0
  225. package/dist/document-frame-router.d.ts.map +1 -0
  226. package/dist/document-frame-router.js +397 -0
  227. package/dist/document-frame-router.js.map +1 -0
  228. package/dist/document-gate-wiring.d.ts +61 -0
  229. package/dist/document-gate-wiring.d.ts.map +1 -0
  230. package/dist/document-gate-wiring.js +125 -0
  231. package/dist/document-gate-wiring.js.map +1 -0
  232. package/dist/document-gate.d.ts +149 -0
  233. package/dist/document-gate.d.ts.map +1 -0
  234. package/dist/document-gate.js +509 -0
  235. package/dist/document-gate.js.map +1 -0
  236. package/dist/document-handlers.d.ts +47 -0
  237. package/dist/document-handlers.d.ts.map +1 -0
  238. package/dist/document-handlers.js +2203 -0
  239. package/dist/document-handlers.js.map +1 -0
  240. package/dist/document-handshake.d.ts +176 -0
  241. package/dist/document-handshake.d.ts.map +1 -0
  242. package/dist/document-handshake.js +452 -0
  243. package/dist/document-handshake.js.map +1 -0
  244. package/dist/document-inbound.d.ts +162 -0
  245. package/dist/document-inbound.d.ts.map +1 -0
  246. package/dist/document-inbound.js +530 -0
  247. package/dist/document-inbound.js.map +1 -0
  248. package/dist/document-json.d.ts +120 -0
  249. package/dist/document-json.d.ts.map +1 -0
  250. package/dist/document-json.js +191 -0
  251. package/dist/document-json.js.map +1 -0
  252. package/dist/document-layer.d.ts +215 -0
  253. package/dist/document-layer.d.ts.map +1 -0
  254. package/dist/document-layer.js +1025 -0
  255. package/dist/document-layer.js.map +1 -0
  256. package/dist/document-lifecycle.d.ts +52 -0
  257. package/dist/document-lifecycle.d.ts.map +1 -0
  258. package/dist/document-lifecycle.js +134 -0
  259. package/dist/document-lifecycle.js.map +1 -0
  260. package/dist/document-live-docs.d.ts +58 -0
  261. package/dist/document-live-docs.d.ts.map +1 -0
  262. package/dist/document-live-docs.js +126 -0
  263. package/dist/document-live-docs.js.map +1 -0
  264. package/dist/document-notify.d.ts +228 -0
  265. package/dist/document-notify.d.ts.map +1 -0
  266. package/dist/document-notify.js +580 -0
  267. package/dist/document-notify.js.map +1 -0
  268. package/dist/document-profile.d.ts +61 -0
  269. package/dist/document-profile.d.ts.map +1 -0
  270. package/dist/document-profile.js +112 -0
  271. package/dist/document-profile.js.map +1 -0
  272. package/dist/document-publish.d.ts +87 -0
  273. package/dist/document-publish.d.ts.map +1 -0
  274. package/dist/document-publish.js +173 -0
  275. package/dist/document-publish.js.map +1 -0
  276. package/dist/document-reachability.d.ts +42 -0
  277. package/dist/document-reachability.d.ts.map +1 -0
  278. package/dist/document-reachability.js +80 -0
  279. package/dist/document-reachability.js.map +1 -0
  280. package/dist/document-reconcile-engine.d.ts +66 -0
  281. package/dist/document-reconcile-engine.d.ts.map +1 -0
  282. package/dist/document-reconcile-engine.js +225 -0
  283. package/dist/document-reconcile-engine.js.map +1 -0
  284. package/dist/document-reconcile-scheduler.d.ts +163 -0
  285. package/dist/document-reconcile-scheduler.d.ts.map +1 -0
  286. package/dist/document-reconcile-scheduler.js +303 -0
  287. package/dist/document-reconcile-scheduler.js.map +1 -0
  288. package/dist/document-rejection.d.ts +251 -0
  289. package/dist/document-rejection.d.ts.map +1 -0
  290. package/dist/document-rejection.js +435 -0
  291. package/dist/document-rejection.js.map +1 -0
  292. package/dist/document-screen.d.ts +114 -0
  293. package/dist/document-screen.d.ts.map +1 -0
  294. package/dist/document-screen.js +223 -0
  295. package/dist/document-screen.js.map +1 -0
  296. package/dist/document-store.d.ts +372 -0
  297. package/dist/document-store.d.ts.map +1 -0
  298. package/dist/document-store.js +931 -0
  299. package/dist/document-store.js.map +1 -0
  300. package/dist/document-surface.d.ts +32 -0
  301. package/dist/document-surface.d.ts.map +1 -0
  302. package/dist/document-surface.js +151 -0
  303. package/dist/document-surface.js.map +1 -0
  304. package/dist/document-types.d.ts +94 -0
  305. package/dist/document-types.d.ts.map +1 -0
  306. package/dist/document-types.js +90 -0
  307. package/dist/document-types.js.map +1 -0
  308. package/dist/document-watch.d.ts +69 -0
  309. package/dist/document-watch.d.ts.map +1 -0
  310. package/dist/document-watch.js +108 -0
  311. package/dist/document-watch.js.map +1 -0
  312. package/dist/document-wiring.d.ts +53 -0
  313. package/dist/document-wiring.d.ts.map +1 -0
  314. package/dist/document-wiring.js +323 -0
  315. package/dist/document-wiring.js.map +1 -0
  316. package/dist/document-write-guard.d.ts +66 -0
  317. package/dist/document-write-guard.d.ts.map +1 -0
  318. package/dist/document-write-guard.js +98 -0
  319. package/dist/document-write-guard.js.map +1 -0
  320. package/dist/document-write-path.d.ts +94 -0
  321. package/dist/document-write-path.d.ts.map +1 -0
  322. package/dist/document-write-path.js +530 -0
  323. package/dist/document-write-path.js.map +1 -0
  324. package/dist/error-message.d.ts +7 -0
  325. package/dist/error-message.d.ts.map +1 -0
  326. package/dist/error-message.js +19 -0
  327. package/dist/error-message.js.map +1 -0
  328. package/dist/file-manifest-provider.d.ts +37 -0
  329. package/dist/file-manifest-provider.d.ts.map +1 -0
  330. package/dist/file-manifest-provider.js +105 -0
  331. package/dist/file-manifest-provider.js.map +1 -0
  332. package/dist/frame-values.d.ts +3 -0
  333. package/dist/frame-values.d.ts.map +1 -0
  334. package/dist/frame-values.js +84 -0
  335. package/dist/frame-values.js.map +1 -0
  336. package/dist/frontier-mismatch.d.ts +73 -0
  337. package/dist/frontier-mismatch.d.ts.map +1 -0
  338. package/dist/frontier-mismatch.js +89 -0
  339. package/dist/frontier-mismatch.js.map +1 -0
  340. package/dist/gateway-config-handlers.d.ts +26 -0
  341. package/dist/gateway-config-handlers.d.ts.map +1 -0
  342. package/dist/gateway-config-handlers.js +429 -0
  343. package/dist/gateway-config-handlers.js.map +1 -0
  344. package/dist/held-content.d.ts +145 -0
  345. package/dist/held-content.d.ts.map +1 -0
  346. package/dist/held-content.js +389 -0
  347. package/dist/held-content.js.map +1 -0
  348. package/dist/http-manifest-poll.d.ts +67 -0
  349. package/dist/http-manifest-poll.d.ts.map +1 -0
  350. package/dist/http-manifest-poll.js +150 -0
  351. package/dist/http-manifest-poll.js.map +1 -0
  352. package/dist/identity-migration.d.ts +40 -0
  353. package/dist/identity-migration.d.ts.map +1 -0
  354. package/dist/identity-migration.js +461 -0
  355. package/dist/identity-migration.js.map +1 -0
  356. package/dist/inbound-refusals.d.ts +283 -0
  357. package/dist/inbound-refusals.d.ts.map +1 -0
  358. package/dist/inbound-refusals.js +919 -0
  359. package/dist/inbound-refusals.js.map +1 -0
  360. package/dist/inbound-seal-request.d.ts +32 -0
  361. package/dist/inbound-seal-request.d.ts.map +1 -0
  362. package/dist/inbound-seal-request.js +228 -0
  363. package/dist/inbound-seal-request.js.map +1 -0
  364. package/dist/inbound-sessions.d.ts +291 -0
  365. package/dist/inbound-sessions.d.ts.map +1 -0
  366. package/dist/inbound-sessions.js +1609 -0
  367. package/dist/inbound-sessions.js.map +1 -0
  368. package/dist/inclusion-proof-handlers.d.ts +43 -0
  369. package/dist/inclusion-proof-handlers.d.ts.map +1 -0
  370. package/dist/inclusion-proof-handlers.js +565 -0
  371. package/dist/inclusion-proof-handlers.js.map +1 -0
  372. package/dist/inclusion-proof.d.ts +151 -0
  373. package/dist/inclusion-proof.d.ts.map +1 -0
  374. package/dist/inclusion-proof.js +228 -0
  375. package/dist/inclusion-proof.js.map +1 -0
  376. package/dist/index.d.ts +32 -0
  377. package/dist/index.d.ts.map +1 -0
  378. package/dist/index.js.map +1 -0
  379. package/dist/initiate-session-handler.d.ts +55 -0
  380. package/dist/initiate-session-handler.d.ts.map +1 -0
  381. package/dist/initiate-session-handler.js +310 -0
  382. package/dist/initiate-session-handler.js.map +1 -0
  383. package/dist/ipc-client.d.ts +31 -0
  384. package/dist/ipc-client.d.ts.map +1 -0
  385. package/dist/ipc-client.js +113 -0
  386. package/dist/ipc-client.js.map +1 -0
  387. package/dist/ipc-server.d.ts +63 -0
  388. package/dist/ipc-server.d.ts.map +1 -0
  389. package/dist/ipc-server.js +429 -0
  390. package/dist/ipc-server.js.map +1 -0
  391. package/dist/ipc-surface.d.ts +44 -0
  392. package/dist/ipc-surface.d.ts.map +1 -0
  393. package/dist/ipc-surface.js +107 -0
  394. package/dist/ipc-surface.js.map +1 -0
  395. package/dist/line-lcs.d.ts +51 -0
  396. package/dist/line-lcs.d.ts.map +1 -0
  397. package/dist/line-lcs.js +71 -0
  398. package/dist/line-lcs.js.map +1 -0
  399. package/dist/lock-file.d.ts +39 -0
  400. package/dist/lock-file.d.ts.map +1 -0
  401. package/dist/lock-file.js +120 -0
  402. package/dist/lock-file.js.map +1 -0
  403. package/dist/log-collapse.d.ts +66 -0
  404. package/dist/log-collapse.d.ts.map +1 -0
  405. package/dist/log-collapse.js +244 -0
  406. package/dist/log-collapse.js.map +1 -0
  407. package/dist/log-rotate.d.ts +67 -0
  408. package/dist/log-rotate.d.ts.map +1 -0
  409. package/dist/log-rotate.js +134 -0
  410. package/dist/log-rotate.js.map +1 -0
  411. package/dist/manifest-deps.d.ts +25 -0
  412. package/dist/manifest-deps.d.ts.map +1 -0
  413. package/dist/manifest-deps.js +151 -0
  414. package/dist/manifest-deps.js.map +1 -0
  415. package/dist/manifest-poll-scheduler.d.ts +31 -0
  416. package/dist/manifest-poll-scheduler.d.ts.map +1 -0
  417. package/dist/manifest-poll-scheduler.js +59 -0
  418. package/dist/manifest-poll-scheduler.js.map +1 -0
  419. package/dist/manifest-validity.d.ts +153 -0
  420. package/dist/manifest-validity.d.ts.map +1 -0
  421. package/dist/manifest-validity.js +268 -0
  422. package/dist/manifest-validity.js.map +1 -0
  423. package/dist/manifest-version-store-db.d.ts +24 -0
  424. package/dist/manifest-version-store-db.d.ts.map +1 -0
  425. package/dist/manifest-version-store-db.js +58 -0
  426. package/dist/manifest-version-store-db.js.map +1 -0
  427. package/dist/manifest-version-store.d.ts +16 -0
  428. package/dist/manifest-version-store.d.ts.map +1 -0
  429. package/dist/manifest-version-store.js +15 -0
  430. package/dist/manifest-version-store.js.map +1 -0
  431. package/dist/network-directory-node.d.ts +136 -0
  432. package/dist/network-directory-node.d.ts.map +1 -0
  433. package/dist/network-directory-node.js +810 -0
  434. package/dist/network-directory-node.js.map +1 -0
  435. package/dist/nonce-dedup.d.ts +68 -0
  436. package/dist/nonce-dedup.d.ts.map +1 -0
  437. package/dist/nonce-dedup.js +205 -0
  438. package/dist/nonce-dedup.js.map +1 -0
  439. package/dist/notification-dispatcher.d.ts +92 -0
  440. package/dist/notification-dispatcher.d.ts.map +1 -0
  441. package/dist/notification-dispatcher.js +210 -0
  442. package/dist/notification-dispatcher.js.map +1 -0
  443. package/dist/notification-handlers.d.ts +53 -0
  444. package/dist/notification-handlers.d.ts.map +1 -0
  445. package/dist/notification-handlers.js +461 -0
  446. package/dist/notification-handlers.js.map +1 -0
  447. package/dist/onboarding-guidance.d.ts +79 -0
  448. package/dist/onboarding-guidance.d.ts.map +1 -0
  449. package/dist/onboarding-guidance.js +95 -0
  450. package/dist/onboarding-guidance.js.map +1 -0
  451. package/dist/operator-guidance.d.ts +25 -0
  452. package/dist/operator-guidance.d.ts.map +1 -0
  453. package/dist/operator-guidance.js +50 -0
  454. package/dist/operator-guidance.js.map +1 -0
  455. package/dist/orphan-triage.d.ts +130 -0
  456. package/dist/orphan-triage.d.ts.map +1 -0
  457. package/dist/orphan-triage.js +207 -0
  458. package/dist/orphan-triage.js.map +1 -0
  459. package/dist/outbound-sessions.d.ts +126 -0
  460. package/dist/outbound-sessions.d.ts.map +1 -0
  461. package/dist/outbound-sessions.js +1052 -0
  462. package/dist/outbound-sessions.js.map +1 -0
  463. package/dist/park-envelope.d.ts +329 -0
  464. package/dist/park-envelope.d.ts.map +1 -0
  465. package/dist/park-envelope.js +509 -0
  466. package/dist/park-envelope.js.map +1 -0
  467. package/dist/park-recovery.d.ts +273 -0
  468. package/dist/park-recovery.d.ts.map +1 -0
  469. package/dist/park-recovery.js +717 -0
  470. package/dist/park-recovery.js.map +1 -0
  471. package/dist/park-refusals.d.ts +147 -0
  472. package/dist/park-refusals.d.ts.map +1 -0
  473. package/dist/park-refusals.js +331 -0
  474. package/dist/park-refusals.js.map +1 -0
  475. package/dist/quarantine-framing.d.ts +92 -0
  476. package/dist/quarantine-framing.d.ts.map +1 -0
  477. package/dist/quarantine-framing.js +111 -0
  478. package/dist/quarantine-framing.js.map +1 -0
  479. package/dist/reconnect-drain.d.ts +22 -0
  480. package/dist/reconnect-drain.d.ts.map +1 -0
  481. package/dist/reconnect-drain.js +65 -0
  482. package/dist/reconnect-drain.js.map +1 -0
  483. package/dist/recovered-position.d.ts +14 -0
  484. package/dist/recovered-position.d.ts.map +1 -0
  485. package/dist/recovered-position.js +59 -0
  486. package/dist/recovered-position.js.map +1 -0
  487. package/dist/refusal-notices.d.ts +196 -0
  488. package/dist/refusal-notices.d.ts.map +1 -0
  489. package/dist/refusal-notices.js +516 -0
  490. package/dist/refusal-notices.js.map +1 -0
  491. package/dist/refusal-reasons.d.ts +245 -0
  492. package/dist/refusal-reasons.d.ts.map +1 -0
  493. package/dist/refusal-reasons.js +363 -0
  494. package/dist/refusal-reasons.js.map +1 -0
  495. package/dist/register-handler.d.ts +36 -0
  496. package/dist/register-handler.d.ts.map +1 -0
  497. package/dist/register-handler.js +285 -0
  498. package/dist/register-handler.js.map +1 -0
  499. package/dist/registration-context.d.ts +72 -0
  500. package/dist/registration-context.d.ts.map +1 -0
  501. package/dist/registration-context.js +126 -0
  502. package/dist/registration-context.js.map +1 -0
  503. package/dist/registration-manager.d.ts +94 -0
  504. package/dist/registration-manager.d.ts.map +1 -0
  505. package/dist/registration-manager.js +585 -0
  506. package/dist/registration-manager.js.map +1 -0
  507. package/dist/registration-persistence.d.ts +183 -0
  508. package/dist/registration-persistence.d.ts.map +1 -0
  509. package/dist/registration-persistence.js +263 -0
  510. package/dist/registration-persistence.js.map +1 -0
  511. package/dist/registry-poll.d.ts +52 -0
  512. package/dist/registry-poll.d.ts.map +1 -0
  513. package/dist/registry-poll.js +140 -0
  514. package/dist/registry-poll.js.map +1 -0
  515. package/dist/registry-version-store-db.d.ts +22 -0
  516. package/dist/registry-version-store-db.d.ts.map +1 -0
  517. package/dist/registry-version-store-db.js +50 -0
  518. package/dist/registry-version-store-db.js.map +1 -0
  519. package/dist/relay-endpoints.d.ts +18 -0
  520. package/dist/relay-endpoints.d.ts.map +1 -0
  521. package/dist/relay-endpoints.js +9 -0
  522. package/dist/relay-endpoints.js.map +1 -0
  523. package/dist/relay-only.d.ts +140 -0
  524. package/dist/relay-only.d.ts.map +1 -0
  525. package/dist/relay-only.js +193 -0
  526. package/dist/relay-only.js.map +1 -0
  527. package/dist/relay-receipt-store.d.ts +155 -0
  528. package/dist/relay-receipt-store.d.ts.map +1 -0
  529. package/dist/relay-receipt-store.js +284 -0
  530. package/dist/relay-receipt-store.js.map +1 -0
  531. package/dist/relay-reconnect.d.ts +32 -0
  532. package/dist/relay-reconnect.d.ts.map +1 -0
  533. package/dist/relay-reconnect.js +29 -0
  534. package/dist/relay-reconnect.js.map +1 -0
  535. package/dist/reply-lag.d.ts +11 -0
  536. package/dist/reply-lag.d.ts.map +1 -0
  537. package/dist/reply-lag.js +46 -0
  538. package/dist/reply-lag.js.map +1 -0
  539. package/dist/resolve-named-agent.d.ts +49 -0
  540. package/dist/resolve-named-agent.d.ts.map +1 -0
  541. package/dist/resolve-named-agent.js +77 -0
  542. package/dist/resolve-named-agent.js.map +1 -0
  543. package/dist/restart-seal-resolver.d.ts +110 -0
  544. package/dist/restart-seal-resolver.d.ts.map +1 -0
  545. package/dist/restart-seal-resolver.js +353 -0
  546. package/dist/restart-seal-resolver.js.map +1 -0
  547. package/dist/resume-last-seen.d.ts +15 -0
  548. package/dist/resume-last-seen.d.ts.map +1 -0
  549. package/dist/resume-last-seen.js +44 -0
  550. package/dist/resume-last-seen.js.map +1 -0
  551. package/dist/retry-queue.d.ts +203 -0
  552. package/dist/retry-queue.d.ts.map +1 -0
  553. package/dist/retry-queue.js +701 -0
  554. package/dist/retry-queue.js.map +1 -0
  555. package/dist/roster-freshness.d.ts +160 -0
  556. package/dist/roster-freshness.d.ts.map +1 -0
  557. package/dist/roster-freshness.js +250 -0
  558. package/dist/roster-freshness.js.map +1 -0
  559. package/dist/screening-status.d.ts +15 -0
  560. package/dist/screening-status.d.ts.map +1 -0
  561. package/dist/screening-status.js +65 -0
  562. package/dist/screening-status.js.map +1 -0
  563. package/dist/seal-carried-close.d.ts +37 -0
  564. package/dist/seal-carried-close.d.ts.map +1 -0
  565. package/dist/seal-carried-close.js +179 -0
  566. package/dist/seal-carried-close.js.map +1 -0
  567. package/dist/seal-certificate-pull.d.ts +79 -0
  568. package/dist/seal-certificate-pull.d.ts.map +1 -0
  569. package/dist/seal-certificate-pull.js +186 -0
  570. package/dist/seal-certificate-pull.js.map +1 -0
  571. package/dist/seal-certified-root-check.d.ts +37 -0
  572. package/dist/seal-certified-root-check.d.ts.map +1 -0
  573. package/dist/seal-certified-root-check.js +127 -0
  574. package/dist/seal-certified-root-check.js.map +1 -0
  575. package/dist/seal-coordinator.d.ts +118 -0
  576. package/dist/seal-coordinator.d.ts.map +1 -0
  577. package/dist/seal-coordinator.js +927 -0
  578. package/dist/seal-coordinator.js.map +1 -0
  579. package/dist/seal-escalation.d.ts +80 -0
  580. package/dist/seal-escalation.d.ts.map +1 -0
  581. package/dist/seal-escalation.js +283 -0
  582. package/dist/seal-escalation.js.map +1 -0
  583. package/dist/seal-evidence-root-check.d.ts +70 -0
  584. package/dist/seal-evidence-root-check.d.ts.map +1 -0
  585. package/dist/seal-evidence-root-check.js +199 -0
  586. package/dist/seal-evidence-root-check.js.map +1 -0
  587. package/dist/seal-failure-store.d.ts +139 -0
  588. package/dist/seal-failure-store.d.ts.map +1 -0
  589. package/dist/seal-failure-store.js +207 -0
  590. package/dist/seal-failure-store.js.map +1 -0
  591. package/dist/seal-flows.d.ts +107 -0
  592. package/dist/seal-flows.d.ts.map +1 -0
  593. package/dist/seal-flows.js +638 -0
  594. package/dist/seal-flows.js.map +1 -0
  595. package/dist/seal-frontier-verify.d.ts +103 -0
  596. package/dist/seal-frontier-verify.d.ts.map +1 -0
  597. package/dist/seal-frontier-verify.js +143 -0
  598. package/dist/seal-frontier-verify.js.map +1 -0
  599. package/dist/seal-leaf.d.ts +58 -0
  600. package/dist/seal-leaf.d.ts.map +1 -0
  601. package/dist/seal-leaf.js +112 -0
  602. package/dist/seal-leaf.js.map +1 -0
  603. package/dist/seal-legibility-tbs.d.ts +25 -0
  604. package/dist/seal-legibility-tbs.d.ts.map +1 -0
  605. package/dist/seal-legibility-tbs.js +77 -0
  606. package/dist/seal-legibility-tbs.js.map +1 -0
  607. package/dist/seal-local-terminus.d.ts +41 -0
  608. package/dist/seal-local-terminus.d.ts.map +1 -0
  609. package/dist/seal-local-terminus.js +170 -0
  610. package/dist/seal-local-terminus.js.map +1 -0
  611. package/dist/seal-receipt-upgrade.d.ts +30 -0
  612. package/dist/seal-receipt-upgrade.d.ts.map +1 -0
  613. package/dist/seal-receipt-upgrade.js +49 -0
  614. package/dist/seal-receipt-upgrade.js.map +1 -0
  615. package/dist/seal-relay-silence.d.ts +51 -0
  616. package/dist/seal-relay-silence.d.ts.map +1 -0
  617. package/dist/seal-relay-silence.js +76 -0
  618. package/dist/seal-relay-silence.js.map +1 -0
  619. package/dist/seal-settle.d.ts +38 -0
  620. package/dist/seal-settle.d.ts.map +1 -0
  621. package/dist/seal-settle.js +33 -0
  622. package/dist/seal-settle.js.map +1 -0
  623. package/dist/seal-upgrade.d.ts +107 -0
  624. package/dist/seal-upgrade.d.ts.map +1 -0
  625. package/dist/seal-upgrade.js +200 -0
  626. package/dist/seal-upgrade.js.map +1 -0
  627. package/dist/sealed-conversation.d.ts +36 -0
  628. package/dist/sealed-conversation.d.ts.map +1 -0
  629. package/dist/sealed-conversation.js +171 -0
  630. package/dist/sealed-conversation.js.map +1 -0
  631. package/dist/sealed-leaf-set.d.ts +92 -0
  632. package/dist/sealed-leaf-set.d.ts.map +1 -0
  633. package/dist/sealed-leaf-set.js +122 -0
  634. package/dist/sealed-leaf-set.js.map +1 -0
  635. package/dist/send-claims.d.ts +56 -0
  636. package/dist/send-claims.d.ts.map +1 -0
  637. package/dist/send-claims.js +50 -0
  638. package/dist/send-claims.js.map +1 -0
  639. package/dist/session-assignment-parser.d.ts +104 -0
  640. package/dist/session-assignment-parser.d.ts.map +1 -0
  641. package/dist/session-assignment-parser.js +345 -0
  642. package/dist/session-assignment-parser.js.map +1 -0
  643. package/dist/session-category.d.ts +19 -0
  644. package/dist/session-category.d.ts.map +1 -0
  645. package/dist/session-category.js +14 -0
  646. package/dist/session-category.js.map +1 -0
  647. package/dist/session-ceremony.d.ts +297 -0
  648. package/dist/session-ceremony.d.ts.map +1 -0
  649. package/dist/session-ceremony.js +964 -0
  650. package/dist/session-ceremony.js.map +1 -0
  651. package/dist/session-closed.d.ts +79 -0
  652. package/dist/session-closed.d.ts.map +1 -0
  653. package/dist/session-closed.js +189 -0
  654. package/dist/session-closed.js.map +1 -0
  655. package/dist/session-connection-gater.d.ts +148 -0
  656. package/dist/session-connection-gater.d.ts.map +1 -0
  657. package/dist/session-connection-gater.js +332 -0
  658. package/dist/session-connection-gater.js.map +1 -0
  659. package/dist/session-content-context.d.ts +162 -0
  660. package/dist/session-content-context.d.ts.map +1 -0
  661. package/dist/session-content-context.js +2 -0
  662. package/dist/session-content-context.js.map +1 -0
  663. package/dist/session-content-handlers.d.ts +82 -0
  664. package/dist/session-content-handlers.d.ts.map +1 -0
  665. package/dist/session-content-handlers.js +1382 -0
  666. package/dist/session-content-handlers.js.map +1 -0
  667. package/dist/session-content-ingest.d.ts +206 -0
  668. package/dist/session-content-ingest.d.ts.map +1 -0
  669. package/dist/session-content-ingest.js +2167 -0
  670. package/dist/session-content-ingest.js.map +1 -0
  671. package/dist/session-content-send.d.ts +191 -0
  672. package/dist/session-content-send.d.ts.map +1 -0
  673. package/dist/session-content-send.js +1360 -0
  674. package/dist/session-content-send.js.map +1 -0
  675. package/dist/session-delivery-acks.d.ts +169 -0
  676. package/dist/session-delivery-acks.d.ts.map +1 -0
  677. package/dist/session-delivery-acks.js +569 -0
  678. package/dist/session-delivery-acks.js.map +1 -0
  679. package/dist/session-ephemerals.d.ts +279 -0
  680. package/dist/session-ephemerals.d.ts.map +1 -0
  681. package/dist/session-ephemerals.js +591 -0
  682. package/dist/session-ephemerals.js.map +1 -0
  683. package/dist/session-leaf-records.d.ts +159 -0
  684. package/dist/session-leaf-records.d.ts.map +1 -0
  685. package/dist/session-leaf-records.js +408 -0
  686. package/dist/session-leaf-records.js.map +1 -0
  687. package/dist/session-lifecycle.d.ts +303 -0
  688. package/dist/session-lifecycle.d.ts.map +1 -0
  689. package/dist/session-lifecycle.js +1679 -0
  690. package/dist/session-lifecycle.js.map +1 -0
  691. package/dist/session-liveness.d.ts +135 -0
  692. package/dist/session-liveness.d.ts.map +1 -0
  693. package/dist/session-liveness.js +347 -0
  694. package/dist/session-liveness.js.map +1 -0
  695. package/dist/session-name.d.ts +35 -0
  696. package/dist/session-name.d.ts.map +1 -0
  697. package/dist/session-name.js +60 -0
  698. package/dist/session-name.js.map +1 -0
  699. package/dist/session-node-factory.d.ts +18 -0
  700. package/dist/session-node-factory.d.ts.map +1 -0
  701. package/dist/session-node-factory.js +182 -0
  702. package/dist/session-node-factory.js.map +1 -0
  703. package/dist/session-node-manager.d.ts +877 -0
  704. package/dist/session-node-manager.d.ts.map +1 -0
  705. package/dist/session-node-manager.js +2998 -0
  706. package/dist/session-node-manager.js.map +1 -0
  707. package/dist/session-node-types.d.ts +1057 -0
  708. package/dist/session-node-types.d.ts.map +1 -0
  709. package/dist/session-node-types.js +657 -0
  710. package/dist/session-node-types.js.map +1 -0
  711. package/dist/session-notify.d.ts +46 -0
  712. package/dist/session-notify.d.ts.map +1 -0
  713. package/dist/session-notify.js +116 -0
  714. package/dist/session-notify.js.map +1 -0
  715. package/dist/session-own-chain-store.d.ts +65 -0
  716. package/dist/session-own-chain-store.d.ts.map +1 -0
  717. package/dist/session-own-chain-store.js +75 -0
  718. package/dist/session-own-chain-store.js.map +1 -0
  719. package/dist/session-queries.d.ts +476 -0
  720. package/dist/session-queries.d.ts.map +1 -0
  721. package/dist/session-queries.js +1007 -0
  722. package/dist/session-queries.js.map +1 -0
  723. package/dist/session-read-handlers.d.ts +87 -0
  724. package/dist/session-read-handlers.d.ts.map +1 -0
  725. package/dist/session-read-handlers.js +689 -0
  726. package/dist/session-read-handlers.js.map +1 -0
  727. package/dist/session-records.d.ts +341 -0
  728. package/dist/session-records.d.ts.map +1 -0
  729. package/dist/session-records.js +858 -0
  730. package/dist/session-records.js.map +1 -0
  731. package/dist/session-relay-client.d.ts +659 -0
  732. package/dist/session-relay-client.d.ts.map +1 -0
  733. package/dist/session-relay-client.js +2876 -0
  734. package/dist/session-relay-client.js.map +1 -0
  735. package/dist/session-relay.d.ts +397 -0
  736. package/dist/session-relay.d.ts.map +1 -0
  737. package/dist/session-relay.js +1636 -0
  738. package/dist/session-relay.js.map +1 -0
  739. package/dist/session-salt-agreement.d.ts +331 -0
  740. package/dist/session-salt-agreement.d.ts.map +1 -0
  741. package/dist/session-salt-agreement.js +472 -0
  742. package/dist/session-salt-agreement.js.map +1 -0
  743. package/dist/session-salts.d.ts +432 -0
  744. package/dist/session-salts.d.ts.map +1 -0
  745. package/dist/session-salts.js +1540 -0
  746. package/dist/session-salts.js.map +1 -0
  747. package/dist/session-schema.d.ts +30 -0
  748. package/dist/session-schema.d.ts.map +1 -0
  749. package/dist/session-schema.js +877 -0
  750. package/dist/session-schema.js.map +1 -0
  751. package/dist/session-seal-leaf-store.d.ts +70 -0
  752. package/dist/session-seal-leaf-store.d.ts.map +1 -0
  753. package/dist/session-seal-leaf-store.js +105 -0
  754. package/dist/session-seal-leaf-store.js.map +1 -0
  755. package/dist/session-seal.d.ts +334 -0
  756. package/dist/session-seal.d.ts.map +1 -0
  757. package/dist/session-seal.js +1017 -0
  758. package/dist/session-seal.js.map +1 -0
  759. package/dist/session-terminal-refusal.d.ts +65 -0
  760. package/dist/session-terminal-refusal.d.ts.map +1 -0
  761. package/dist/session-terminal-refusal.js +87 -0
  762. package/dist/session-terminal-refusal.js.map +1 -0
  763. package/dist/session-tree.d.ts +110 -0
  764. package/dist/session-tree.d.ts.map +1 -0
  765. package/dist/session-tree.js +144 -0
  766. package/dist/session-tree.js.map +1 -0
  767. package/dist/session-views.d.ts +47 -0
  768. package/dist/session-views.d.ts.map +1 -0
  769. package/dist/session-views.js +278 -0
  770. package/dist/session-views.js.map +1 -0
  771. package/dist/signal-handlers.d.ts +63 -0
  772. package/dist/signal-handlers.d.ts.map +1 -0
  773. package/dist/signal-handlers.js +980 -0
  774. package/dist/signal-handlers.js.map +1 -0
  775. package/dist/signal-requirement-policy.d.ts +51 -0
  776. package/dist/signal-requirement-policy.d.ts.map +1 -0
  777. package/dist/signal-requirement-policy.js +89 -0
  778. package/dist/signal-requirement-policy.js.map +1 -0
  779. package/dist/signal-revocability.d.ts +49 -0
  780. package/dist/signal-revocability.d.ts.map +1 -0
  781. package/dist/signal-revocability.js +93 -0
  782. package/dist/signal-revocability.js.map +1 -0
  783. package/dist/signal-submission.d.ts +181 -0
  784. package/dist/signal-submission.d.ts.map +1 -0
  785. package/dist/signal-submission.js +368 -0
  786. package/dist/signal-submission.js.map +1 -0
  787. package/dist/signaling-connect.d.ts +118 -0
  788. package/dist/signaling-connect.d.ts.map +1 -0
  789. package/dist/signaling-connect.js +538 -0
  790. package/dist/signaling-connect.js.map +1 -0
  791. package/dist/signaling-wiring.d.ts +105 -0
  792. package/dist/signaling-wiring.d.ts.map +1 -0
  793. package/dist/signaling-wiring.js +393 -0
  794. package/dist/signaling-wiring.js.map +1 -0
  795. package/dist/singleton-lock.d.ts +85 -0
  796. package/dist/singleton-lock.d.ts.map +1 -0
  797. package/dist/singleton-lock.js +219 -0
  798. package/dist/singleton-lock.js.map +1 -0
  799. package/dist/sqlcipher-db.d.ts +139 -0
  800. package/dist/sqlcipher-db.d.ts.map +1 -0
  801. package/dist/sqlcipher-db.js +357 -0
  802. package/dist/sqlcipher-db.js.map +1 -0
  803. package/dist/standing-receivers.d.ts +319 -0
  804. package/dist/standing-receivers.d.ts.map +1 -0
  805. package/dist/standing-receivers.js +1295 -0
  806. package/dist/standing-receivers.js.map +1 -0
  807. package/dist/start-agent.d.ts +64 -0
  808. package/dist/start-agent.d.ts.map +1 -0
  809. package/dist/start-agent.js +136 -0
  810. package/dist/start-agent.js.map +1 -0
  811. package/dist/status-handler.d.ts +54 -0
  812. package/dist/status-handler.d.ts.map +1 -0
  813. package/dist/status-handler.js +61 -0
  814. package/dist/status-handler.js.map +1 -0
  815. package/dist/submission-retry.d.ts +208 -0
  816. package/dist/submission-retry.d.ts.map +1 -0
  817. package/dist/submission-retry.js +506 -0
  818. package/dist/submission-retry.js.map +1 -0
  819. package/dist/telegram-bot-client.d.ts +34 -0
  820. package/dist/telegram-bot-client.d.ts.map +1 -0
  821. package/dist/telegram-bot-client.js +36 -0
  822. package/dist/telegram-bot-client.js.map +1 -0
  823. package/dist/telegram-doorbell.d.ts +38 -0
  824. package/dist/telegram-doorbell.d.ts.map +1 -0
  825. package/dist/telegram-doorbell.js +140 -0
  826. package/dist/telegram-doorbell.js.map +1 -0
  827. package/dist/test-handlers.d.ts +62 -0
  828. package/dist/test-handlers.d.ts.map +1 -0
  829. package/dist/test-handlers.js +240 -0
  830. package/dist/test-handlers.js.map +1 -0
  831. package/dist/testing.d.ts +10 -0
  832. package/dist/testing.d.ts.map +1 -0
  833. package/dist/testing.js +10 -0
  834. package/dist/testing.js.map +1 -0
  835. package/dist/transport-composition.d.ts +31 -0
  836. package/dist/transport-composition.d.ts.map +1 -0
  837. package/dist/transport-composition.js +55 -0
  838. package/dist/transport-composition.js.map +1 -0
  839. package/dist/transport-selector.d.ts +202 -0
  840. package/dist/transport-selector.d.ts.map +1 -0
  841. package/dist/transport-selector.js +196 -0
  842. package/dist/transport-selector.js.map +1 -0
  843. package/dist/trust-signal-pickup-listener.d.ts +43 -0
  844. package/dist/trust-signal-pickup-listener.d.ts.map +1 -0
  845. package/dist/trust-signal-pickup-listener.js +48 -0
  846. package/dist/trust-signal-pickup-listener.js.map +1 -0
  847. package/dist/trust-signal-store.d.ts +406 -0
  848. package/dist/trust-signal-store.d.ts.map +1 -0
  849. package/dist/trust-signal-store.js +939 -0
  850. package/dist/trust-signal-store.js.map +1 -0
  851. package/dist/trust-signal-sweep-tick.d.ts +60 -0
  852. package/dist/trust-signal-sweep-tick.d.ts.map +1 -0
  853. package/dist/trust-signal-sweep-tick.js +101 -0
  854. package/dist/trust-signal-sweep-tick.js.map +1 -0
  855. package/dist/trust-signal-sweep.d.ts +94 -0
  856. package/dist/trust-signal-sweep.d.ts.map +1 -0
  857. package/dist/trust-signal-sweep.js +147 -0
  858. package/dist/trust-signal-sweep.js.map +1 -0
  859. package/dist/type-registry.d.ts +42 -0
  860. package/dist/type-registry.d.ts.map +1 -0
  861. package/dist/type-registry.js +37 -0
  862. package/dist/type-registry.js.map +1 -0
  863. package/dist/types.d.ts +746 -0
  864. package/dist/types.d.ts.map +1 -0
  865. package/dist/types.js +20 -0
  866. package/dist/types.js.map +1 -0
  867. package/dist/unresolved-nodes-report.d.ts +14 -0
  868. package/dist/unresolved-nodes-report.d.ts.map +1 -0
  869. package/dist/unresolved-nodes-report.js +96 -0
  870. package/dist/unresolved-nodes-report.js.map +1 -0
  871. package/dist/vocabulary.d.ts +150 -0
  872. package/dist/vocabulary.d.ts.map +1 -0
  873. package/dist/vocabulary.js +386 -0
  874. package/dist/vocabulary.js.map +1 -0
  875. package/dist/who-label.d.ts +28 -0
  876. package/dist/who-label.d.ts.map +1 -0
  877. package/dist/who-label.js +31 -0
  878. package/dist/who-label.js.map +1 -0
  879. package/dist/who-resolver.d.ts +15 -0
  880. package/dist/who-resolver.d.ts.map +1 -0
  881. package/dist/who-resolver.js +47 -0
  882. package/dist/who-resolver.js.map +1 -0
  883. package/dist/wire-content-hash.d.ts +93 -0
  884. package/dist/wire-content-hash.d.ts.map +1 -0
  885. package/dist/wire-content-hash.js +116 -0
  886. package/dist/wire-content-hash.js.map +1 -0
  887. package/dist/withheld-content.d.ts +13 -0
  888. package/dist/withheld-content.d.ts.map +1 -0
  889. package/dist/withheld-content.js +46 -0
  890. package/dist/withheld-content.js.map +1 -0
  891. package/dist/witness-alerts.d.ts +40 -0
  892. package/dist/witness-alerts.d.ts.map +1 -0
  893. package/dist/witness-alerts.js +102 -0
  894. package/dist/witness-alerts.js.map +1 -0
  895. package/package.json +5 -5
@@ -0,0 +1,939 @@
1
+ /**
2
+ * M10 / DOD-STORE-CLIENT-1 — the daemon's two trust-signal tables.
3
+ *
4
+ * TWO tables, never one with a role flag (M10-D4). They answer different questions and obey
5
+ * different scoping rules, and a single table with a `role` column is how one set of rules ends up
6
+ * applied to the other's rows.
7
+ *
8
+ * `wallet_trust_signals` — signals ABOUT this daemon's agents, held so they can be PRESENTED.
9
+ * `contact_trust_signals` — signals OTHER agents PRESENTED TO one of my agents.
10
+ *
11
+ * THE WALLET CARRIES NO AGENT ASSOCIATION (M10-D14). PK = `signal_hash`; one row per signal per
12
+ * daemon, and nothing more. It is the envelope's own HASHED `subject_kind`/`subject` that decides
13
+ * who may present it, evaluated at presentation time — not a local attribution decided at delivery
14
+ * time. That is the whole point: an account-subject signal (phone, email) serves every agent under
15
+ * the account, so **adding an agent to an existing daemon is ZERO signal work** — no assignment
16
+ * sweep, no re-attribution at renewal, no copies to keep in step at expiry. A per-agent column
17
+ * would quietly reintroduce every one of those chores.
18
+ *
19
+ * THE RECEIVED STORE IS PER-AGENT, AND THE DATABASE ENFORCES IT (INV-AGENT-SCOPED). Consent is
20
+ * genuinely per-agent here: a signal Bob showed to my agent `alice` must be invisible to my agent
21
+ * `bob` on the same daemon. `agent_id` is NOT NULL and the row hangs off a contact row by composite
22
+ * FK, so an unscoped row cannot be written at all — as opposed to being merely discouraged by a
23
+ * query convention that every future caller must remember. (This requires `PRAGMA foreign_keys = ON`,
24
+ * set at open in sqlcipher-db.ts — M10-D19. Without it the FK is decorative.) This is where the M8
25
+ * scaffold's `agent_id = null` defect dies.
26
+ *
27
+ * EVIDENCE, NOT AN INPUT (M10-D4 / INV-STATELESS-RECIPIENT). Received rows are re-checkable evidence
28
+ * of what was presented and when we verified it. They are NEVER an input to policy evaluation, which
29
+ * consumes only the currently-presented set, and they are never trusted for freshness (that is
30
+ * re-checked on use). This module therefore exposes no "is this contact trusted?" read — the absence
31
+ * is deliberate and structural. Do not add one.
32
+ *
33
+ * OPAQUE THROUGHOUT (INV-ZERO-BUMP / INV-TYPE-CARRY). `type` is a TEXT column with no CHECK, no
34
+ * enum, and no index predicated on a type value; `payload` is a BLOB that is never parsed and whose
35
+ * fields are never hoisted into columns. A type string this code has never seen stores, reads, and
36
+ * presents exactly like a known one. Adding a signal type must require no change to this file.
37
+ */
38
+ import { verifyTrustSignalHash } from "@cello-protocol/protocol-types";
39
+ import { migrateWalletAddConsentState, CONSENT_ACCEPTED } from "./consent-migration.js";
40
+ import { extractErrorMessage } from "./error-message.js";
41
+ export class SignalDeliveryRejected extends Error {
42
+ reason;
43
+ constructor(reason, detail) {
44
+ super(`signal_delivery_${reason}: ${detail}`);
45
+ this.reason = reason;
46
+ this.name = "SignalDeliveryRejected";
47
+ }
48
+ }
49
+ /**
50
+ * ⚠️ TWO TIME UNITS LIVE IN THESE TABLES, AND MIXING THEM SILENTLY PRESENTS EXPIRED SIGNALS.
51
+ *
52
+ * issued_at / expires_at — epoch **SECONDS**. These are ENVELOPE fields: they are HASHED, so the
53
+ * protocol fixed the unit and we do not get to choose it.
54
+ * received_at / verified_at / consent_notified_at
55
+ * — epoch **MILLISECONDS** (`Date.now()`). Local bookkeeping only, never
56
+ * hashed, and matching the house convention of every other daemon table
57
+ * (`contacts.added_at`, `sessions.updated_at`). A review read
58
+ * `consent_notified_at` as an outlier among "seconds" siblings and
59
+ * proposed converting it; that is backwards — it is not hashed and not
60
+ * compared against `expires_at`, so it belongs with this group. Named
61
+ * here so the next reader does not have to re-derive it.
62
+ *
63
+ * A factor-of-1000 error between them does not throw. Compared against a 1970 timestamp, every
64
+ * expiry is still in the future — so the failure mode is an expired signal being cheerfully
65
+ * presented. Anything that compares against `expires_at` must be in SECONDS; see `listPresentable`.
66
+ */
67
+ const ENVELOPE_COLUMNS = `
68
+ signal_hash TEXT NOT NULL,
69
+ subject_kind TEXT NOT NULL,
70
+ subject TEXT NOT NULL,
71
+ issuer_kind TEXT NOT NULL,
72
+ issuer_pubkey TEXT NOT NULL,
73
+ type TEXT NOT NULL,
74
+ schema_version INTEGER NOT NULL,
75
+ payload BLOB NOT NULL,
76
+ issued_at INTEGER NOT NULL,
77
+ expires_at INTEGER,
78
+ supersedes_hash TEXT,
79
+ status TEXT NOT NULL`;
80
+ /** Content-addressed: the row IS its hash (spec §14.11 — this is what makes wallet rows portable
81
+ * between a user's daemons, and duplicate delivery a no-op). */
82
+ const CREATE_WALLET_SQL = `
83
+ CREATE TABLE IF NOT EXISTS wallet_trust_signals (
84
+ ${ENVELOPE_COLUMNS},
85
+ received_at INTEGER NOT NULL,
86
+ default_present INTEGER NOT NULL DEFAULT 1,
87
+ -- M10B-D14r2 — NULLABLE, and that is forced rather than chosen: SQLite cannot ADD COLUMN with
88
+ -- NOT NULL and no DEFAULT, so a MIGRATED database can only ever have a nullable column. Making
89
+ -- the fresh DDL stricter would give fresh installs a different schema from migrated ones, and
90
+ -- the divergence would surface only on fresh installs — i.e. on every new operator, which is the
91
+ -- worst possible audience for it. The repo's "fresh == migrated" convention wins.
92
+ --
93
+ -- Nullability costs nothing here because presentability is enforced by the PREDICATE, which tests
94
+ -- for exactly 'accepted' rather than for the absence of a bad value. NULL, '', 'ACCEPTED' and any
95
+ -- future state all fail closed by construction (§5a), so the column constraint was never what was
96
+ -- protecting the invariant.
97
+ consent_state TEXT,
98
+ -- DOD-END-PENDING-1 — when the operator was TOLD about this pending decision. NULL = not yet
99
+ -- told. Separate from consent_state because the item and the notification have different
100
+ -- lifetimes: the decision persists until made, the nag stops once seen.
101
+ consent_notified_at INTEGER,
102
+ -- M10B / DOD-END-COUNT-1. Stored because the PRESENTER must re-encode the envelope byte-identically
103
+ -- to what was notarized: re-encoding with the wrong value changes the hash and the recipient's
104
+ -- verification fails. It is also what a recipient's floor predicate reads to exclude co-ownership
105
+ -- endorsements from a min_count.
106
+ same_operator INTEGER NOT NULL DEFAULT 0,
107
+ PRIMARY KEY (signal_hash)
108
+ );
109
+ `;
110
+ const CREATE_RECEIVED_SQL = `
111
+ CREATE TABLE IF NOT EXISTS contact_trust_signals (
112
+ agent_id TEXT NOT NULL,
113
+ contact_pubkey TEXT NOT NULL,
114
+ ${ENVELOPE_COLUMNS},
115
+ -- M10B / DOD-END-COUNT-1 — what the recipient's floor predicate reads to exclude co-ownership
116
+ -- from a min_count. It lives on BOTH tables and is NOT in ENVELOPE_COLUMNS, which is a wart worth
117
+ -- naming: the wallet needs it to re-encode the envelope byte-identically at presentation, and
118
+ -- this table needs it for the predicate. Same envelope field, two different reasons.
119
+ same_operator INTEGER NOT NULL DEFAULT 0,
120
+ verified_at INTEGER NOT NULL,
121
+ received_at INTEGER NOT NULL,
122
+ PRIMARY KEY (agent_id, contact_pubkey, signal_hash),
123
+ FOREIGN KEY (agent_id, contact_pubkey) REFERENCES contacts(agent_id, pubkey) ON DELETE CASCADE
124
+ );
125
+ `;
126
+ /**
127
+ * Idempotent schema. Must run AFTER `contacts` exists — the composite FK's parent. SQLite resolves
128
+ * an FK's parent at DML time, not at DDL time, so creating this first would not fail here; it would
129
+ * fail later, on the first insert, which is a far worse place to find out.
130
+ */
131
+ /**
132
+ * What THIS daemon has SUBMITTED about other agents — the third table, and the one that was missing.
133
+ *
134
+ * The wallet holds signals ABOUT me; `contact_trust_signals` holds signals PRESENTED to me. Neither
135
+ * records what I SAID ABOUT SOMEONE ELSE, so an operator who endorsed a counterparty had no way to
136
+ * see it afterwards and — the part that matters — `DOD-END-WITHDRAW-1` had nothing to NAME: you
137
+ * cannot withdraw a submission whose id you never kept. The submission id is content-derived, so it
138
+ * is reproducible in principle, but only by re-composing the exact original body, which the operator
139
+ * no longer has.
140
+ *
141
+ * NO BODY IS STORED. The text was the operator's own words about a third party; keeping it here
142
+ * would put in the clear, on disk, the one thing the whole sealed-submission path exists to keep
143
+ * from being readable by anyone but the portal. The id, the subject and the verb are enough to name
144
+ * a submission for withdrawal, which is what this table is for.
145
+ */
146
+ const CREATE_ISSUED_SQL = `
147
+ CREATE TABLE IF NOT EXISTS issued_submissions (
148
+ submission_id TEXT NOT NULL,
149
+ agent_id TEXT NOT NULL,
150
+ subject_pubkey TEXT NOT NULL,
151
+ op TEXT NOT NULL,
152
+ intake_key_id TEXT NOT NULL,
153
+ -- Whether the accepting node reported it as newly stored. FALSE means a node already held this
154
+ -- id: a benign retry, or single-node censorship, and they are indistinguishable from here.
155
+ stored INTEGER NOT NULL,
156
+ submitted_at INTEGER NOT NULL,
157
+ -- Content-derived, so the same body re-submitted is the SAME row rather than a second one. Keyed
158
+ -- with agent_id because two agents on one daemon can each submit about the same subject, and the
159
+ -- rows are per-agent facts.
160
+ PRIMARY KEY (agent_id, submission_id)
161
+ );
162
+ `;
163
+ export function ensureTrustSignalSchema(db, _logger) {
164
+ db.exec(CREATE_WALLET_SQL);
165
+ db.exec(CREATE_RECEIVED_SQL);
166
+ db.exec(CREATE_ISSUED_SQL);
167
+ // Presentation reads by subject; nothing reads by `type`, and nothing may (INV-ZERO-BUMP — an
168
+ // index predicated on a type VALUE is a per-type construct in the schema).
169
+ db.exec("CREATE INDEX IF NOT EXISTS idx_wallet_signals_subject ON wallet_trust_signals (subject_kind, subject)");
170
+ // Additive migration: add default_present if the table already exists without it.
171
+ try {
172
+ db.exec("ALTER TABLE wallet_trust_signals ADD COLUMN default_present INTEGER NOT NULL DEFAULT 1");
173
+ }
174
+ catch {
175
+ // Column already exists — safe to ignore.
176
+ }
177
+ // M10B / DOD-END-COUNT-1 — additive on BOTH tables, for databases created before the slot existed.
178
+ //
179
+ // WITHOUT THESE THE UPGRADE PATH IS BROKEN, not merely incomplete: the fresh DDL above gained the
180
+ // column, so a NEW operator works while an EXISTING one — anyone whose wallet predates it — hits
181
+ // "table has no column named same_operator" on the first insert and cannot receive or present any
182
+ // signal at all. Adding a column to the CREATE and stopping there is the classic client-side
183
+ // migration miss, and it is invisible in CI because every test database is fresh.
184
+ //
185
+ // `NOT NULL DEFAULT 0` is legal for ALTER (SQLite only refuses NOT NULL with NO default), so the
186
+ // migrated schema is identical to the fresh one — the repo's "fresh == migrated" rule holds here,
187
+ // unlike `consent_state` below where it could not.
188
+ for (const table of ["wallet_trust_signals", "contact_trust_signals"]) {
189
+ try {
190
+ db.exec(`ALTER TABLE ${table} ADD COLUMN same_operator INTEGER NOT NULL DEFAULT 0`);
191
+ }
192
+ catch (err) {
193
+ // VERIFY, DO NOT ASSUME, THE FAILURE WAS "already exists".
194
+ //
195
+ // A bare swallow here rests on the assumption that duplicate-column is the ONLY way this can
196
+ // fail. It is not: `sqlcipher-db.ts` sets no `busy_timeout`, so SQLITE_BUSY returns immediately
197
+ // — and "two daemons on one DB" is a named real condition in this project, not a hypothetical.
198
+ // SQLITE_READONLY and SQLITE_FULL swallow identically.
199
+ //
200
+ // What that costs: the ALTER silently does not run, then `putReceivedSignal` throws "table has
201
+ // no column named same_operator", which is caught upstream as a WARN — so the session forms
202
+ // normally and NO presented signal is ever stored. On the wallet side it surfaces as a delivery
203
+ // rejection with no ACK, and the directory re-delivers forever. A migration that fails silently
204
+ // is indistinguishable from one that worked until something much later looks wrong.
205
+ //
206
+ // So re-read the schema and rethrow if the column is genuinely absent. The idempotent case
207
+ // stays silent; every other cause becomes loud. This mirrors `migrateWalletAddConsentState`
208
+ // below, which checks `PRAGMA table_info` for exactly this reason.
209
+ const cols = db.prepare(`PRAGMA table_info(${table})`).all()
210
+ .map((c) => c.name);
211
+ if (!cols.includes("same_operator")) {
212
+ throw new Error(`failed to add same_operator to ${table} and the column is still absent — the daemon cannot ` +
213
+ `store or present trust signals in this state: ${extractErrorMessage(err)}`);
214
+ }
215
+ // Present: the ALTER was a genuine no-op. No backfill is needed either — 0 (not co-owned) is
216
+ // correct for every pre-existing row, because no signal minted before the slot existed could
217
+ // have carried the flag.
218
+ }
219
+ }
220
+ // M10B-D14r2 — DELIBERATELY OUTSIDE the try/catch above. That swallow is safe for an idempotent
221
+ // ALTER whose only expected failure is "already exists"; it is NOT safe for a migration with a
222
+ // one-time backfill, where a swallowed failure leaves the daemon running against a schema it
223
+ // believes gates consent and does not. This one is birth-gated and rethrows.
224
+ migrateWalletAddConsentState(db, _logger);
225
+ }
226
+ const toBuf = (b) => Buffer.from(b);
227
+ /**
228
+ * The payload column is `BLOB NOT NULL`, so an unrecognized shape coming back from the driver means
229
+ * something is wrong — NOT that the payload is empty.
230
+ *
231
+ * Returning `new Uint8Array(0)` here (the previous behavior) is the silent-fallback pattern: a signal
232
+ * whose payload failed to materialise would flow on to presentation and verification looking like a
233
+ * perfectly valid signal that simply has no content. Its hash would then not match, and the operator
234
+ * would be sent to hunt a canonicalization bug that does not exist. ABSENT IS NOT FINE — refuse, and
235
+ * name the actual cause.
236
+ */
237
+ const toBytes = (v) => {
238
+ if (v instanceof Uint8Array)
239
+ return new Uint8Array(v);
240
+ if (Buffer.isBuffer(v))
241
+ return new Uint8Array(v);
242
+ throw new Error(`signal_payload_not_bytes: the payload column returned ${v === null ? "null" : typeof v}` +
243
+ `${v && typeof v === "object" ? ` (${v.constructor?.name})` : ""}, but the column is BLOB NOT NULL. ` +
244
+ "This is a storage-layer fault, not an empty payload — an empty payload would be a zero-length BLOB.");
245
+ };
246
+ /**
247
+ * Refuse anything that is not a 32-byte K_local pubkey as lowercase hex.
248
+ *
249
+ * SHARED, because it was written once for `listAllActive` and then DROPPED by three methods that
250
+ * copied its SQL predicate without it (review F3). The predicate alone fails closed, but silently:
251
+ * a device-local `agent_id` UUID — the natural thing to have in hand in an IPC handler — matches
252
+ * zero rows, which is indistinguishable from "this operator has nothing pending". For the consent
253
+ * queue that silence IS the bug the queue exists to prevent, and `markConsentNotified` would still
254
+ * match account rows and log success, so the surface would look like it was working.
255
+ */
256
+ function requireAgentPubkeyHex(value, caller) {
257
+ if (!/^[0-9a-f]{64}$/.test(value ?? "")) {
258
+ throw new Error(`${caller} requires the agent's 32-byte K_local pubkey as lowercase hex — ` +
259
+ `refusing rather than returning an empty result that reads as "nothing to show"`);
260
+ }
261
+ }
262
+ function toWalletRow(r) {
263
+ return {
264
+ signalHash: r.signal_hash,
265
+ consentState: r.consent_state,
266
+ sameOperator: r.same_operator === 1,
267
+ subjectKind: r.subject_kind,
268
+ subject: r.subject,
269
+ issuerKind: r.issuer_kind,
270
+ issuerPubkey: r.issuer_pubkey,
271
+ type: r.type,
272
+ schemaVersion: r.schema_version,
273
+ payload: toBytes(r.payload),
274
+ issuedAt: r.issued_at,
275
+ expiresAt: r.expires_at,
276
+ supersedesHash: r.supersedes_hash,
277
+ status: r.status,
278
+ receivedAt: r.received_at,
279
+ // Rows written before this column existed have null here; treat as true (default-on).
280
+ defaultPresent: r.default_present !== 0,
281
+ };
282
+ }
283
+ export class TrustSignalStore {
284
+ #db;
285
+ #logger;
286
+ /**
287
+ * Does NOT create the schema. `SessionNodeManager.initialize()` owns it, and must — the received
288
+ * table's FK parent is `contacts`, which that init creates. A store that created its own schema
289
+ * would happily build `contact_trust_signals` on any handle lacking `contacts`, producing a
290
+ * dangling FK that then fails on the first INSERT with `no such table: main.contacts` — an error
291
+ * that names the wrong subsystem, at the wrong time, far from the cause.
292
+ */
293
+ constructor(db, logger) {
294
+ this.#db = db;
295
+ this.#logger = logger;
296
+ }
297
+ /**
298
+ * Store a signal this daemon holds about one of its agents.
299
+ *
300
+ * `INSERT OR IGNORE`, and that is a correctness property, not a convenience: the row is keyed by
301
+ * its own content hash, so a second delivery of the same hash is by definition the same signal.
302
+ * If the bytes really differed, the hash would differ. A differing payload under an identical hash
303
+ * is therefore a liar, and it must not overwrite the truth. This is also what makes duplicate
304
+ * delivery a no-op and wallet rows safely mergeable across a user's daemons (spec §14.11).
305
+ */
306
+ /** Returns true iff a NEW row was inserted (false = the content-addressed row already existed, a
307
+ * benign duplicate). */
308
+ putWalletSignal(s) {
309
+ // _id suffix signals default to excluded; everything else defaults to included.
310
+ const defaultPresent = s.defaultPresent !== undefined ? s.defaultPresent : !s.type.endsWith("_id");
311
+ const res = this.#db
312
+ .prepare(`INSERT OR IGNORE INTO wallet_trust_signals
313
+ (signal_hash, subject_kind, subject, issuer_kind, issuer_pubkey, type, schema_version,
314
+ payload, issued_at, expires_at, supersedes_hash, status, received_at, default_present,
315
+ consent_state, same_operator)
316
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
317
+ .run(s.signalHash, s.subjectKind, s.subject, s.issuerKind, s.issuerPubkey, s.type, s.schemaVersion, toBuf(s.payload), s.issuedAt, s.expiresAt, s.supersedesHash, s.status, Date.now(), defaultPresent ? 1 : 0,
318
+ // M10B-D14r2 / INV-CONSENT. Keys on ISSUER_KIND, never on the type string, so every future
319
+ // client-sourced type inherits consent for free (M10B-D1). An `agent`-issued signal was
320
+ // authored by somebody else ABOUT the operator and is unpresentable until they say so; a
321
+ // `portal`-issued one was minted for them, at their own action, and has no third party to
322
+ // wait for. Written at the one insert path, and the SQL predicate fails closed regardless.
323
+ s.issuerKind === "agent" ? "pending" : CONSENT_ACCEPTED, s.sameOperator === true ? 1 : 0);
324
+ if (res.changes > 0) {
325
+ this.#logger.info("signal.wallet.stored", {
326
+ signalHash: s.signalHash, type: s.type, subjectKind: s.subjectKind, issuerKind: s.issuerKind,
327
+ });
328
+ if (s.issuerKind === "agent") {
329
+ // DOD-END-PENDING-1 named event. Emitted where the decision is CREATED, so the log shows a
330
+ // decision being owed even if the operator never selects the agent again.
331
+ this.#logger.info("signal.consent.pending", {
332
+ signalHash: s.signalHash, subject: s.subject.slice(0, 16), issuerPubkey: s.issuerPubkey.slice(0, 16),
333
+ });
334
+ }
335
+ }
336
+ return res.changes > 0;
337
+ }
338
+ /**
339
+ * Accept a trust-signal envelope delivered to this holder: RE-VERIFY its hash, then store it.
340
+ *
341
+ * This is the holder's own chokepoint (INV-CANONICAL / M10-D4): the daemon does not trust the
342
+ * `claimedHash` the delivery frame carried — it re-derives the hash from the envelope with the SAME
343
+ * canonical component every party uses, and REFUSES a mismatch. A delivered envelope whose bytes do
344
+ * not hash to the claim is a corrupted or tampered delivery; storing it would let the wallet present
345
+ * a signal the directory never notarized.
346
+ *
347
+ * Storage is idempotent (content-addressed PK) — a re-delivery is a no-op (§14.11). Returns whether
348
+ * a new row was stored, so the caller can ACK only a genuinely-accepted delivery.
349
+ */
350
+ deliverWalletSignal(envelope, claimedHash) {
351
+ // A malformed claim STRING and a genuine byte-tamper are two different causes — name them apart
352
+ // (a directory version-skew emitting uppercase hex must not read as universal tamper and send the
353
+ // operator to the wrong subsystem). Both refuse-and-don't-store; only the message differs.
354
+ if (!/^[0-9a-f]{64}$/.test(claimedHash)) {
355
+ this.#logger.warn("signal.delivery.claimed_hash_malformed", { claimedHash, type: envelope.type });
356
+ throw new SignalDeliveryRejected("claimed_hash_malformed", `claimed hash is not 64-char lowercase hex: ${claimedHash}`);
357
+ }
358
+ if (!verifyTrustSignalHash(envelope, new Uint8Array(Buffer.from(claimedHash, "hex")))) {
359
+ this.#logger.warn("signal.delivery.hash_mismatch", {
360
+ claimedHash, type: envelope.type, subjectKind: envelope.subject_kind,
361
+ });
362
+ throw new SignalDeliveryRejected("hash_mismatch", `delivered envelope does not hash to the claimed ${claimedHash}`);
363
+ }
364
+ const supersedesHash = envelope.supersedes_hash === null ? null : Buffer.from(envelope.supersedes_hash).toString("hex");
365
+ // putWalletSignal is idempotent (content-addressed PK) and reports whether it inserted — use that
366
+ // directly rather than a second SELECT (no read-then-write, no theoretical race).
367
+ const inserted = this.putWalletSignal({
368
+ signalHash: claimedHash,
369
+ subjectKind: envelope.subject_kind,
370
+ subject: envelope.subject,
371
+ issuerKind: envelope.issuer_kind,
372
+ issuerPubkey: envelope.issuer_pubkey,
373
+ type: envelope.type,
374
+ schemaVersion: envelope.schema_version,
375
+ payload: envelope.payload,
376
+ issuedAt: envelope.issued_at,
377
+ expiresAt: envelope.expires_at,
378
+ supersedesHash,
379
+ // THE DELIVERED FLAG, not the column default. Omitting this stored `false` for a co-owned
380
+ // endorsement, and the damage was not the wrong flag — it was that PRESENTATION re-encodes from
381
+ // this row, so the envelope bytes no longer hashed to the notarized hash and the RECIPIENT
382
+ // rejected a perfectly valid signal. A field dropped on the way into the wallet is silent until
383
+ // it surfaces one hop away as somebody else's `hash_mismatch`.
384
+ sameOperator: envelope.same_operator,
385
+ status: "active",
386
+ });
387
+ if (inserted) {
388
+ // ⚠️ SUPERSESSION IS A DESTRUCTIVE WRITE BY A THIRD PARTY, so it is gated twice.
389
+ //
390
+ // GATE 1 — CONSENT (M10B / DOD-END-ACCEPT-1 review F1). An `issuer_kind: agent` delivery lands
391
+ // `pending` and is unpresentable, which stops a rogue endorsement being DISPLAYED. It does not
392
+ // stop it ERASING: without this gate the rogue's insert superseded the subject's own ACCEPTED
393
+ // endorsement of the same type, and Alice presented NOTHING. Consent that blocks display but
394
+ // not deletion closes half the threat Andre named. An unconsented signal supersedes nothing;
395
+ // `setConsentState` re-runs these effects if and when the subject accepts it.
396
+ //
397
+ // GATE 2 — AUTHORITY (review F2, pre-existing since M10). `supersedes_hash` was honoured
398
+ // without asking whether the new issuer is entitled to supersede the target, so any third
399
+ // party who could get one signal delivered could knock out ANY row in the wallet — including
400
+ // phone and email — just by naming its hash. Supersession now requires the SAME ISSUER: for an
401
+ // agent the key IS the identity, and for the portal it is the one logical issuer. This mirrors
402
+ // what the directory does in V54, where an unauthorised write must not change what a third
403
+ // party can present.
404
+ const consented = this.getWalletSignal(claimedHash)?.consentState === CONSENT_ACCEPTED;
405
+ if (consented) {
406
+ this.#applySupersession(envelope, claimedHash, supersedesHash);
407
+ }
408
+ else {
409
+ this.#logger.info("signal.supersede.deferred", {
410
+ signalHash: claimedHash,
411
+ issuerKind: envelope.issuer_kind,
412
+ reason: "not consented — supersession is re-evaluated on acceptance",
413
+ });
414
+ }
415
+ }
416
+ return { stored: inserted };
417
+ }
418
+ /**
419
+ * Apply a newly-consented signal's supersession effects, with the ISSUER-AUTHORITY check.
420
+ *
421
+ * Extracted so acceptance can re-run it: a signal that arrived `pending` supersedes nothing until
422
+ * the subject accepts it, and at that moment the same rules must apply as if it had arrived
423
+ * accepted. One implementation, so the two entry points cannot drift.
424
+ */
425
+ #applySupersession(envelope, claimedHash, supersedesHash) {
426
+ if (supersedesHash) {
427
+ const target = this.getWalletSignal(supersedesHash);
428
+ // SAME ISSUER, or refuse. A missing target is NOT an invitation to proceed (§5a): if we cannot
429
+ // see what is being superseded we cannot judge the authority, so we do not act.
430
+ const authorized = target !== null && target.issuerPubkey === envelope.issuer_pubkey;
431
+ if (authorized) {
432
+ this.setWalletStatus(supersedesHash, "superseded");
433
+ }
434
+ else {
435
+ this.#logger.warn("signal.supersede.refused", {
436
+ signalHash: claimedHash,
437
+ supersedesHash,
438
+ reason: target === null ? "target_not_held" : "issuer_mismatch",
439
+ newIssuer: envelope.issuer_pubkey.slice(0, 16),
440
+ targetIssuer: target === null ? null : target.issuerPubkey.slice(0, 16),
441
+ });
442
+ }
443
+ }
444
+ // Type-dedup: another active signal of the same (subject_kind, subject, type) is superseded by
445
+ // the new one — duplicates delivered without supersedes_hash (e.g. a type re-minted on a fresh
446
+ // portal login with no prior-hash lookup). SCOPED TO THE SAME ISSUER for the same reason: a
447
+ // stranger's endorsement is not a newer version of yours just because it shares a type string.
448
+ this.#db
449
+ .prepare(`UPDATE wallet_trust_signals
450
+ SET status = 'superseded'
451
+ WHERE subject_kind = ? AND subject = ? AND type = ?
452
+ AND signal_hash != ?
453
+ AND issuer_pubkey = ?
454
+ AND status = 'active'`)
455
+ .run(envelope.subject_kind, envelope.subject, envelope.type, claimedHash, envelope.issuer_pubkey);
456
+ }
457
+ getWalletSignal(signalHash) {
458
+ const row = this.#db
459
+ .prepare("SELECT * FROM wallet_trust_signals WHERE signal_hash = ?")
460
+ .get(signalHash);
461
+ return row ? toWalletRow(row) : null;
462
+ }
463
+ /**
464
+ * Status is the ONE mutable field — it lives outside the hash precisely so this is possible.
465
+ *
466
+ * REVOCATION IS TERMINAL. A revoked signal can never go back to `active`. Without that guard this
467
+ * is a blind UPDATE, and a stale or replayed directory read reporting `active` for a hash we
468
+ * already revoked would resurrect it — and `listPresentable` would start offering it again. The
469
+ * directory is the authority on revocation, but a LATE answer from it is not a NEW answer; the
470
+ * monotonic rule makes out-of-order responses harmless instead of dangerous.
471
+ *
472
+ * `superseded` may still be overtaken by `revoked` (a superseded signal can also be revoked), but
473
+ * never the reverse, and never back to `active`.
474
+ */
475
+ setWalletStatus(signalHash, status) {
476
+ const res = this.#db
477
+ .prepare(`UPDATE wallet_trust_signals SET status = ?
478
+ WHERE signal_hash = ?
479
+ AND status != 'revoked'
480
+ AND NOT (status = 'superseded' AND ? = 'active')`)
481
+ .run(status, signalHash, status);
482
+ if (res.changes > 0) {
483
+ this.#logger.info("signal.wallet.status.changed", { signalHash, status });
484
+ return;
485
+ }
486
+ // No change is not necessarily an error (the row may already hold this status), but a REFUSED
487
+ // downgrade is worth surfacing — it means something tried to resurrect a dead signal.
488
+ const current = this.#db
489
+ .prepare("SELECT status FROM wallet_trust_signals WHERE signal_hash = ?")
490
+ .get(signalHash);
491
+ if (current && current.status !== status) {
492
+ this.#logger.warn("signal.wallet.status.change_refused", {
493
+ signalHash, current: current.status, attempted: status,
494
+ reason: "revocation is terminal — a revoked or superseded signal is never returned to active",
495
+ });
496
+ }
497
+ }
498
+ /**
499
+ * The signals an agent may present, resolved from the ENVELOPE, not from a stored attribution:
500
+ * an `account`-subject row is presentable by every agent under `accountId`; an `agent`-subject row
501
+ * only by its own subject (M10-D5/M10-D14).
502
+ *
503
+ * **`agentPubkeyHex` is the K_local pubkey hex, NOT the daemon's device-local `agent_id`.** An
504
+ * agent-subject envelope's `subject` holds the pubkey — that is the value the directory joins on
505
+ * (`ap.k_local_pubkey = sr.subject`) — and a UUID compared against it matches nothing at all.
506
+ *
507
+ * NOTE (`DOD-END-SCOPE-FIX-1`): this method has no production callers; the live wire path is
508
+ * `listAllActive`, which now carries the agent-subject half of this scoping. Kept because it is
509
+ * the only implementation of the ACCOUNT-subject half, which is deferred behind a named
510
+ * prerequisite — the daemon holds no `accountId` anywhere in production code.
511
+ *
512
+ * Excludes expired and non-active rows. Selective disclosure (all / some / none) is the CALLER's
513
+ * choice on top of this — DOD-PRESENT-1; this returns what is *eligible*, never what to send.
514
+ */
515
+ listPresentable(opts) {
516
+ // `nowSec` is epoch SECONDS, and it is named for its unit deliberately. The envelope's
517
+ // `issued_at`/`expires_at` are seconds (they are HASHED, and the protocol fixed the unit);
518
+ // `Date.now()` is milliseconds. An unnamed `now` here invites a caller to pass one where the
519
+ // other is meant, and a factor-of-1000 error in an expiry check does not throw — it silently
520
+ // presents an EXPIRED signal (compared against a 1970 timestamp, every expiry is still in the
521
+ // future). The first version of this method took `now` and its own test passed seconds into a
522
+ // parameter that was divided by 1000; it only went green because the fixture's expiry was 1.
523
+ const nowSec = opts.nowSec ?? Math.floor(Date.now() / 1000);
524
+ const rows = this.#db
525
+ .prepare(`SELECT * FROM wallet_trust_signals
526
+ WHERE status = 'active'
527
+ AND (expires_at IS NULL OR expires_at > ?)
528
+ AND ( (subject_kind = 'account' AND subject = ?)
529
+ OR (subject_kind = 'agent' AND subject = ?) )
530
+ AND consent_state = '${CONSENT_ACCEPTED}'`)
531
+ .all(nowSec, opts.accountId, opts.agentPubkeyHex);
532
+ return rows.map(toWalletRow);
533
+ }
534
+ /**
535
+ * All wallet signals regardless of status — for operator inspection via `cello trust-signals list`.
536
+ * Ordered by issued_at DESC so the most recent signal of each type appears first.
537
+ */
538
+ listAllWalletSignals() {
539
+ const rows = this.#db
540
+ .prepare("SELECT * FROM wallet_trust_signals ORDER BY issued_at DESC, received_at DESC")
541
+ .all();
542
+ return rows.map(toWalletRow);
543
+ }
544
+ /**
545
+ * Look up a wallet signal by hash prefix (minimum 8 chars). Returns the unique matching signal,
546
+ * or null if no match, or throws if the prefix is ambiguous (multiple matches).
547
+ */
548
+ getWalletSignalByPrefix(prefix) {
549
+ if (prefix.length < 8) {
550
+ throw new Error("hash prefix too short — supply at least 8 characters");
551
+ }
552
+ const rows = this.#db
553
+ .prepare("SELECT * FROM wallet_trust_signals WHERE signal_hash LIKE ?")
554
+ .all(prefix + "%");
555
+ if (rows.length === 0)
556
+ return null;
557
+ if (rows.length > 1)
558
+ throw new Error(`ambiguous hash prefix '${prefix}' matches ${rows.length} signals — supply more characters`);
559
+ return toWalletRow(rows[0]);
560
+ }
561
+ /**
562
+ * Hard-delete a wallet signal by hash (GDPR removal). Returns true if a row was deleted.
563
+ *
564
+ * This is a permanent DELETE, not a status transition. Revocation is directory-driven and leaves
565
+ * the row for audit; this is the operator exercising their own right to remove a signal from their
566
+ * own device with no directory involvement.
567
+ */
568
+ removeWalletSignal(signalHash) {
569
+ const res = this.#db
570
+ .prepare("DELETE FROM wallet_trust_signals WHERE signal_hash = ?")
571
+ .run(signalHash);
572
+ if (Number(res.changes) > 0) {
573
+ this.#logger.info("signal.wallet.removed", { signalHash });
574
+ return true;
575
+ }
576
+ return false;
577
+ }
578
+ /**
579
+ * Active, non-expired wallet signals THIS agent is eligible to present — the live wire path
580
+ * (`outbound-sessions.ts`).
581
+ *
582
+ * `presentingAgentPubkeyHex` is the presenting agent's K_local pubkey hex, and it is REQUIRED.
583
+ * An `agent`-subject row is presentable only by its own subject (M10-D5/M10-D14); the wallet is
584
+ * daemon-wide and shared by every agent on the device, so without this predicate each agent
585
+ * offers every co-resident agent's agent-subject signals to its own counterparties —
586
+ * `INV-AGENT-SCOPED`, which is what `DOD-END-SCOPE-FIX-1` closes. The scoping is in the SQL, not
587
+ * a JS filter, because `include` already routes around `default_present` and a JS branch would
588
+ * route around this the same way.
589
+ *
590
+ * **`lower(subject)`, because hex has a case and this comparison is byte-exact.** SQLite `TEXT`
591
+ * uses BINARY collation, so `AABB…` and `aabb…` — the same key — do not match, and the row would
592
+ * be silently un-presented with no error. The daemon's own `k_local_pubkey` is always lowercase
593
+ * (`agent-loader.ts` derives it with `.toString("hex")`), so only the STORED side can vary, and it
594
+ * can: `putWalletSignal` already names "a directory version-skew emitting uppercase hex" as a real
595
+ * condition. Comparing case-insensitively is the correct equality for hex, not a fallback that
596
+ * papers over a mismatch.
597
+ *
598
+ * Note the residual, because it is NOT closed here — it is `DOD-M15-HEXCASE-MINT-1`: the directory's
599
+ * `JOIN agent_profiles ap ON ap.k_local_pubkey = sr.subject` is case-sensitive too, so an
600
+ * uppercase-hex subject that ever got minted would still be invisible THERE. Closing that means
601
+ * constraining the value where it is produced (the portal's mint) — which spans three components
602
+ * and is its own decision, not something to smuggle into a presentation-scoping unit.
603
+ *
604
+ * **ACCOUNT-subject rows are deliberately NOT scoped here, and that half is deferred, not done.**
605
+ * `listPresentable` scopes them on `accountId` — but the daemon holds no `accountId` anywhere in
606
+ * production code, so there is nothing to compare against and inventing one is a separate
607
+ * decision (M10B fourth review F5). Today's behavior for account rows is therefore unchanged:
608
+ * every agent on the daemon may present them, which is also what M10-D5 says for agents under the
609
+ * same account. It becomes wrong only when one daemon holds agents of two different accounts,
610
+ * and that trigger is the whole of `DOD-M15-ACCOUNT-SCOPE-1` — which is where this gets closed,
611
+ * not by inventing a daemon-side `accountId` to satisfy the predicate.
612
+ *
613
+ * Default behavior: returns only signals where `default_present = 1`.
614
+ * `include` overrides the default — only the listed types are returned regardless of `default_present`.
615
+ * `exclude` removes types from the default set.
616
+ * Both `include` and `exclude` are type strings. Unknown types cause a validation error at the
617
+ * IPC layer (the caller must pre-validate against listAllWalletSignals before calling this).
618
+ */
619
+ listAllActive(opts) {
620
+ // ABSENT IS NOT FINE (§5a), AND SO IS MALFORMED. A caller that cannot say who is presenting gets
621
+ // a refusal, never the whole wallet: the fail-open direction here IS the defect this method was
622
+ // fixed for, and it would hand a counterparty another agent's signals with no error and no log.
623
+ //
624
+ // The SHAPE check is the half that is easy to omit and expensive to omit. An empty string is
625
+ // caught by any guard; a device-local `agent_id` UUID, an agent NAME, or uppercase hex all sail
626
+ // through a truthiness check and then match zero rows — which is indistinguishable, to every
627
+ // caller, from "this operator holds no signals". That silence is precisely the trap
628
+ // `DOD-END-SCOPE-FIX-1` exists to close, so it is closed by construction here rather than by
629
+ // remembering to pass the right thing. 32-byte Ed25519 key, lowercase hex, as `agent-loader.ts`
630
+ // produces it.
631
+ requireAgentPubkeyHex(opts.presentingAgentPubkeyHex, "listAllActive");
632
+ const nowSec = opts.nowSec ?? Math.floor(Date.now() / 1000);
633
+ const rows = this.#db
634
+ .prepare(`SELECT * FROM wallet_trust_signals
635
+ WHERE status = 'active'
636
+ AND (expires_at IS NULL OR expires_at > ?)
637
+ AND (subject_kind <> 'agent' OR lower(subject) = ?)
638
+ AND consent_state = '${CONSENT_ACCEPTED}'`)
639
+ .all(nowSec, opts.presentingAgentPubkeyHex);
640
+ const all = rows.map(toWalletRow);
641
+ if (opts.include) {
642
+ const set = new Set(opts.include);
643
+ return all.filter((s) => set.has(s.type));
644
+ }
645
+ const excluded = new Set(opts.exclude ?? []);
646
+ return all.filter((s) => s.defaultPresent && !excluded.has(s.type));
647
+ }
648
+ /**
649
+ * The distinct signal TYPES this agent could present — active, unexpired, and scoped to the
650
+ * presenting agent exactly as `listAllActive` scopes rows.
651
+ *
652
+ * Deliberately ignores `default_present`, because this answers "may this type be named in a
653
+ * filter", and `include` exists precisely to override the default. Validating a filter against
654
+ * `listAllActive`'s output would reject a type the operator holds but has defaulted off — the
655
+ * filter rejecting the thing it was built to select.
656
+ *
657
+ * The scoping is the point: the wallet is daemon-wide, so validating a filter against the whole
658
+ * wallet accepts a type only a CO-RESIDENT agent holds, and the session then presents nothing with
659
+ * no error (review MEDIUM-4).
660
+ */
661
+ listPresentableTypes(presentingAgentPubkeyHex, nowSec) {
662
+ const now = nowSec ?? Math.floor(Date.now() / 1000);
663
+ const rows = this.#db
664
+ .prepare(`SELECT DISTINCT type FROM wallet_trust_signals
665
+ WHERE status = 'active'
666
+ AND (expires_at IS NULL OR expires_at > ?)
667
+ AND (subject_kind <> 'agent' OR lower(subject) = ?)
668
+ AND consent_state = '${CONSENT_ACCEPTED}'`)
669
+ .all(now, presentingAgentPubkeyHex);
670
+ return rows.map((r) => r.type);
671
+ }
672
+ /**
673
+ * Record the subject's consent decision (D-23). The ONLY writer of this column after insert.
674
+ *
675
+ * `refused` is terminal in spirit but not enforced as one-way here: `M10B-D4` allows Bob to issue a
676
+ * CORRECTED endorsement after a refusal, and that is a NEW signal with its own hash — it does not
677
+ * reuse this row. What must never happen is a refusal being silently undone, which is why the
678
+ * migration is birth-gated rather than NULL-driven.
679
+ */
680
+ setConsentState(signalHash, state) {
681
+ const res = this.#db
682
+ .prepare("UPDATE wallet_trust_signals SET consent_state = ? WHERE signal_hash = ?")
683
+ .run(state, signalHash);
684
+ if (Number(res.changes) === 0)
685
+ return false;
686
+ this.#logger.info("signal.consent.changed", { signalHash, consentState: state });
687
+ // ACCEPTANCE IS WHEN SUPERSESSION BECOMES LEGITIMATE (review F1). Delivery deliberately defers
688
+ // it — an unconsented signal must not erase a consented one — so the effects are applied here
689
+ // instead, through the SAME authority-checked path, at the moment the subject says yes. Without
690
+ // this an accepted re-issue would sit alongside the endorsement it replaces rather than
691
+ // superseding it, and the operator would present both.
692
+ if (state === CONSENT_ACCEPTED) {
693
+ const row = this.getWalletSignal(signalHash);
694
+ if (row) {
695
+ this.#applySupersession({
696
+ subject_kind: row.subjectKind,
697
+ subject: row.subject,
698
+ type: row.type,
699
+ issuer_kind: row.issuerKind,
700
+ issuer_pubkey: row.issuerPubkey,
701
+ }, signalHash, row.supersedesHash);
702
+ }
703
+ }
704
+ return true;
705
+ }
706
+ /**
707
+ * DOD-END-PENDING-1 — the decisions this agent still owes (`M10B-D5`).
708
+ *
709
+ * Its OWN surface, deliberately not the transcript inbox: an inbox item is cleared by reading or
710
+ * dismissing a transcript, and an endorsement awaiting consent has no transcript, so it would be an
711
+ * item the operator could never clear the normal way.
712
+ *
713
+ * Keyed by CONSENT STATE, never by type — that is what makes a whole new queue legal under
714
+ * INV-ZEROBUMP, and it is why a future client-sourced type appears here with no code change.
715
+ *
716
+ * SCOPING, STATED HONESTLY. Agent-subject items are scoped to their subject, on the same axis as
717
+ * presentation (DOD-END-SCOPE-FIX-1). ACCOUNT-subject items are visible to every agent on the
718
+ * daemon — the same deferred residual `listAllActive` carries, because the daemon holds no
719
+ * `accountId` anywhere in production code and per M10-D5 account signals serve every agent under
720
+ * the account.
721
+ *
722
+ * ⚠️ BUT THE RESIDUAL CHANGES CHARACTER HERE, and that is worth naming rather than inheriting
723
+ * silently: in `listAllActive` the consequence is SHOWING the wrong signal; here it is DECIDING.
724
+ * Any agent on the daemon can accept an account-subject endorsement on another's behalf, and
725
+ * acceptance runs a destructive supersession. Nobody has ruled on whether account-subject consent
726
+ * should be per-agent or per-account — M10B-D9 says acceptance is recorded once per account-subject
727
+ * SIGNAL, which points at "any agent may decide", but it was written about the operator surface,
728
+ * not about authority. Recorded as an open question on `DOD-END-SURFACE-1` rather than settled by
729
+ * whichever predicate got copied first.
730
+ */
731
+ /**
732
+ * Find a consent item this agent may DECIDE ON — pending, or ALREADY ACCEPTED.
733
+ *
734
+ * Refusal used to be reachable only while an item was `pending`, so "I accepted this endorsement
735
+ * and now I want it gone" had no path at all. This widens it, and the widening is the whole point:
736
+ * a refused signal is inert everywhere it is checked, which is the mechanism for taking back
737
+ * something you previously agreed to show.
738
+ *
739
+ * ── `issuer_kind <> 'portal'` IS THE LOAD-BEARING CLAUSE, NOT A TIDY-UP ────────────────────────
740
+ * Refusal makes a signal inert. So widening refusal without this filter would hand every operator
741
+ * a back door to suppressing their own MANDATORY signals — refuse your `track_record` and it stops
742
+ * being presented, achieving by consent exactly what revocation is forbidden from doing. The
743
+ * behavioural record is portal-issued; peer-claimed attestations are not. That is the axis, and it
744
+ * is the same one the DIRECTORY uses (`issuer_kind`), rather than a list of type names the client
745
+ * would have to keep in step.
746
+ *
747
+ * Deliberately NOT filtered by type: a hostile peer can issue a signal it CALLS `track_record`, and
748
+ * refusing a stranger's claim about you is precisely what this is for. The mandatory rule protects
749
+ * the portal's behavioural record, never a third party's assertion.
750
+ *
751
+ * Same agent-scoping predicate as `listPendingConsent` — including its unresolved question about
752
+ * who may decide for an account-subject item. Copied rather than diverged: two different answers to
753
+ * "may this agent decide" would be worse than one unresolved answer.
754
+ */
755
+ findDecidableConsent(agentPubkeyHex, prefix) {
756
+ requireAgentPubkeyHex(agentPubkeyHex, "findDecidableConsent");
757
+ const rows = this.#db
758
+ .prepare(`SELECT * FROM wallet_trust_signals
759
+ WHERE consent_state IN ('pending', 'accepted')
760
+ AND status = 'active'
761
+ AND issuer_kind <> 'portal'
762
+ AND (expires_at IS NULL OR expires_at > ?)
763
+ AND (subject_kind <> 'agent' OR lower(subject) = ?)
764
+ AND signal_hash LIKE ? || '%'
765
+ ORDER BY received_at ASC`)
766
+ .all(Math.floor(Date.now() / 1000), agentPubkeyHex, prefix);
767
+ return rows.length > 0 ? toWalletRow(rows[0]) : null;
768
+ }
769
+ listPendingConsent(agentPubkeyHex) {
770
+ requireAgentPubkeyHex(agentPubkeyHex, "listPendingConsent");
771
+ const rows = this.#db
772
+ .prepare(`SELECT * FROM wallet_trust_signals
773
+ WHERE consent_state = 'pending'
774
+ AND status = 'active'
775
+ AND (expires_at IS NULL OR expires_at > ?)
776
+ AND (subject_kind <> 'agent' OR lower(subject) = ?)
777
+ ORDER BY received_at ASC`)
778
+ .all(Math.floor(Date.now() / 1000), agentPubkeyHex);
779
+ return rows.map(toWalletRow);
780
+ }
781
+ /**
782
+ * How many pending decisions this agent has NOT yet been told about.
783
+ *
784
+ * Asked on every agent selection, so it must go quiet once the operator has been told — while the
785
+ * ITEM stays in `listPendingConsent` until they actually decide. A new arrival raises it again,
786
+ * because the silence is per-item and not a permanent "already notified" flag on the agent.
787
+ */
788
+ countUnnotifiedConsent(agentPubkeyHex) {
789
+ requireAgentPubkeyHex(agentPubkeyHex, "countUnnotifiedConsent");
790
+ const row = this.#db
791
+ .prepare(`SELECT COUNT(*) AS n FROM wallet_trust_signals
792
+ WHERE consent_state = 'pending'
793
+ AND consent_notified_at IS NULL
794
+ AND status = 'active'
795
+ AND (expires_at IS NULL OR expires_at > ?)
796
+ AND (subject_kind <> 'agent' OR lower(subject) = ?)`)
797
+ .get(Math.floor(Date.now() / 1000), agentPubkeyHex);
798
+ return Number(row.n);
799
+ }
800
+ /** Record that the operator has been told about this agent's currently-pending decisions. */
801
+ markConsentNotified(agentPubkeyHex) {
802
+ requireAgentPubkeyHex(agentPubkeyHex, "markConsentNotified");
803
+ const res = this.#db
804
+ .prepare(
805
+ // The predicate MUST match countUnnotifiedConsent's exactly. It did not: this omitted the
806
+ // status and expiry clauses, so it marked rows the counter never counted — the mark and the
807
+ // count drifting apart is precisely how an item goes quiet without ever being shown.
808
+ `UPDATE wallet_trust_signals
809
+ SET consent_notified_at = ?
810
+ WHERE consent_state = 'pending'
811
+ AND consent_notified_at IS NULL
812
+ AND status = 'active'
813
+ AND (expires_at IS NULL OR expires_at > ?)
814
+ AND (subject_kind <> 'agent' OR lower(subject) = ?)`)
815
+ .run(Date.now(), Math.floor(Date.now() / 1000), agentPubkeyHex);
816
+ const n = Number(res.changes);
817
+ if (n > 0)
818
+ this.#logger.info("signal.consent.notified", { agentPubkey: agentPubkeyHex.slice(0, 16), count: n });
819
+ return n;
820
+ }
821
+ /** Set the persistent default-presentation flag for a wallet signal. */
822
+ setDefaultPresent(signalHash, value) {
823
+ const res = this.#db
824
+ .prepare("UPDATE wallet_trust_signals SET default_present = ? WHERE signal_hash = ?")
825
+ .run(value ? 1 : 0, signalHash);
826
+ if (Number(res.changes) > 0) {
827
+ this.#logger.info("signal.wallet.default_present.changed", { signalHash, defaultPresent: value });
828
+ return true;
829
+ }
830
+ return false;
831
+ }
832
+ /**
833
+ * Store a signal a contact PRESENTED to one of my agents, after it was verified.
834
+ *
835
+ * The FK refuses a row for a contact that does not exist — an unscoped received signal is not
836
+ * merely discouraged, it is unwritable. `verified_at` is RE-STAMPED on re-presentation: it records
837
+ * when WE last re-verified, and a stale value that looked fresh would be worse than no value at
838
+ * all (freshness is re-checked on use — M10-D4).
839
+ */
840
+ /**
841
+ * Record a submission THIS daemon sent. Idempotent on (agent_id, submission_id): the id is
842
+ * content-derived, so a safe re-submit is the SAME row rather than a second one — which is what
843
+ * makes "re-sending is safe" true at this layer too, not just at the directory's.
844
+ *
845
+ * `stored` is UPDATED on conflict, and that direction is deliberate: a retry that finally lands as
846
+ * newly-stored should not keep reporting the earlier duplicate answer.
847
+ */
848
+ recordIssuedSubmission(s) {
849
+ this.#db
850
+ .prepare(`INSERT INTO issued_submissions
851
+ (agent_id, submission_id, subject_pubkey, op, intake_key_id, stored, submitted_at)
852
+ VALUES (?, ?, ?, ?, ?, ?, ?)
853
+ ON CONFLICT (agent_id, submission_id) DO UPDATE SET stored = excluded.stored`)
854
+ .run(s.agentId, s.submissionId, s.subjectPubkey, s.op, s.intakeKeyId, s.stored ? 1 : 0, Date.now());
855
+ this.#logger.info("signal.submission.recorded", {
856
+ agentId: s.agentId, submissionId: s.submissionId, op: s.op, stored: s.stored,
857
+ });
858
+ }
859
+ /** What this agent has submitted, newest first. No body — see the table comment. */
860
+ listIssuedSubmissions(agentId) {
861
+ const rows = this.#db
862
+ .prepare(`SELECT agent_id, submission_id, subject_pubkey, op, intake_key_id, stored, submitted_at
863
+ FROM issued_submissions WHERE agent_id = ? ORDER BY submitted_at DESC`)
864
+ .all(agentId);
865
+ return rows.map((r) => ({
866
+ agentId: String(r["agent_id"]),
867
+ submissionId: String(r["submission_id"]),
868
+ subjectPubkey: String(r["subject_pubkey"]),
869
+ op: String(r["op"]),
870
+ intakeKeyId: String(r["intake_key_id"]),
871
+ stored: r["stored"] === 1,
872
+ submittedAt: Number(r["submitted_at"]),
873
+ }));
874
+ }
875
+ putReceivedSignal(s) {
876
+ this.#db
877
+ .prepare(`INSERT INTO contact_trust_signals
878
+ (agent_id, contact_pubkey, signal_hash, subject_kind, subject, issuer_kind, issuer_pubkey,
879
+ type, schema_version, payload, issued_at, expires_at, supersedes_hash, same_operator,
880
+ status, verified_at, received_at)
881
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
882
+ ON CONFLICT (agent_id, contact_pubkey, signal_hash)
883
+ DO UPDATE SET
884
+ verified_at = excluded.verified_at,
885
+ -- OUR verdict may only ever get WORSE, never better. A re-presentation cannot launder a
886
+ -- signal we already caught as revoked/superseded back to active: the party a revocation
887
+ -- indicts does not get to erase the indictment. (The envelope fields are not updated at
888
+ -- all — they are hashed, so an identical signal_hash means identical envelope bytes; a
889
+ -- differing value under the same hash is a liar and must not win.)
890
+ status = CASE WHEN contact_trust_signals.status = 'active' THEN excluded.status
891
+ ELSE contact_trust_signals.status END`)
892
+ .run(s.agentId, s.contactPubkey, s.signalHash, s.subjectKind, s.subject, s.issuerKind, s.issuerPubkey, s.type, s.schemaVersion, toBuf(s.payload), s.issuedAt, s.expiresAt,
893
+ // WITHOUT THIS THE COUNT EXCLUSION IS INERT. `evaluateSignalPolicy` filters on `sameOperator`,
894
+ // and this insert is the ONLY way a received signal ever gets one — omitting it meant the column
895
+ // always took its `0` default, every received endorsement read as not-co-owned, and
896
+ // DOD-END-COUNT-1's ten-agents-under-one-operator defence silently did nothing in production.
897
+ // The unit tests did not catch it because they construct rows directly rather than arriving
898
+ // through this path, which is exactly the gap a store-level default hides.
899
+ s.supersedesHash, s.sameOperator === true ? 1 : 0, s.verdict, s.verifiedAt, Date.now());
900
+ this.#logger.info("signal.received.stored", {
901
+ agentId: s.agentId, signalHash: s.signalHash, type: s.type, issuerKind: s.issuerKind,
902
+ verdict: s.verdict,
903
+ });
904
+ }
905
+ /**
906
+ * Mark a received signal as superseded. Same monotonic rules as setWalletStatus: revoked wins,
907
+ * and a superseded signal never goes back to active.
908
+ */
909
+ setReceivedStatus(opts) {
910
+ const res = this.#db
911
+ .prepare(`UPDATE contact_trust_signals SET status = ?
912
+ WHERE agent_id = ? AND contact_pubkey = ? AND signal_hash = ?
913
+ AND status != 'revoked'
914
+ AND NOT (status = 'superseded' AND ? = 'active')`)
915
+ .run(opts.status, opts.agentId, opts.contactPubkey, opts.signalHash, opts.status);
916
+ if (res.changes > 0) {
917
+ this.#logger.info("signal.received.status.changed", {
918
+ agentId: opts.agentId, signalHash: opts.signalHash, status: opts.status,
919
+ });
920
+ }
921
+ }
922
+ /** Evidence only. Never an input to policy — see the header. */
923
+ listReceived(opts) {
924
+ const rows = this.#db
925
+ .prepare(`SELECT * FROM contact_trust_signals WHERE agent_id = ? AND contact_pubkey = ?`)
926
+ .all(opts.agentId, opts.contactPubkey);
927
+ return rows.map((r) => {
928
+ const { status, ...envelope } = toWalletRow(r);
929
+ return {
930
+ ...envelope,
931
+ agentId: opts.agentId,
932
+ contactPubkey: opts.contactPubkey,
933
+ verifiedAt: r.verified_at,
934
+ verdict: status,
935
+ };
936
+ });
937
+ }
938
+ }
939
+ //# sourceMappingURL=trust-signal-store.js.map