@cello-protocol/daemon 0.0.225 → 0.0.227
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.
- package/package.json +5 -5
- package/dist/agent-admin-handlers.d.ts +0 -56
- package/dist/agent-admin-handlers.d.ts.map +0 -1
- package/dist/agent-admin-handlers.js +0 -73
- package/dist/agent-admin-handlers.js.map +0 -1
- package/dist/agent-handlers.d.ts +0 -72
- package/dist/agent-handlers.d.ts.map +0 -1
- package/dist/agent-handlers.js +0 -604
- package/dist/agent-handlers.js.map +0 -1
- package/dist/agent-id-migration.d.ts +0 -70
- package/dist/agent-id-migration.d.ts.map +0 -1
- package/dist/agent-id-migration.js +0 -468
- package/dist/agent-id-migration.js.map +0 -1
- package/dist/agent-loader.d.ts +0 -37
- package/dist/agent-loader.d.ts.map +0 -1
- package/dist/agent-loader.js +0 -37
- package/dist/agent-loader.js.map +0 -1
- package/dist/agent-selection-root.d.ts +0 -29
- package/dist/agent-selection-root.d.ts.map +0 -1
- package/dist/agent-selection-root.js +0 -126
- package/dist/agent-selection-root.js.map +0 -1
- package/dist/agent-selection.d.ts +0 -73
- package/dist/agent-selection.d.ts.map +0 -1
- package/dist/agent-selection.js +0 -80
- package/dist/agent-selection.js.map +0 -1
- package/dist/agent-settings-keys.d.ts +0 -52
- package/dist/agent-settings-keys.d.ts.map +0 -1
- package/dist/agent-settings-keys.js +0 -114
- package/dist/agent-settings-keys.js.map +0 -1
- package/dist/agent-state.d.ts +0 -67
- package/dist/agent-state.d.ts.map +0 -1
- package/dist/agent-state.js +0 -66
- package/dist/agent-state.js.map +0 -1
- package/dist/assignment-verify.d.ts +0 -90
- package/dist/assignment-verify.d.ts.map +0 -1
- package/dist/assignment-verify.js +0 -301
- package/dist/assignment-verify.js.map +0 -1
- package/dist/attendance-wiring.d.ts +0 -23
- package/dist/attendance-wiring.d.ts.map +0 -1
- package/dist/attendance-wiring.js +0 -248
- package/dist/attendance-wiring.js.map +0 -1
- package/dist/attestation-body.d.ts +0 -47
- package/dist/attestation-body.d.ts.map +0 -1
- package/dist/attestation-body.js +0 -71
- package/dist/attestation-body.js.map +0 -1
- package/dist/authorship-verification.d.ts +0 -91
- package/dist/authorship-verification.d.ts.map +0 -1
- package/dist/authorship-verification.js +0 -532
- package/dist/authorship-verification.js.map +0 -1
- package/dist/away-detection.d.ts +0 -139
- package/dist/away-detection.d.ts.map +0 -1
- package/dist/away-detection.js +0 -186
- package/dist/away-detection.js.map +0 -1
- package/dist/away-inbox-oneshot.d.ts +0 -40
- package/dist/away-inbox-oneshot.d.ts.map +0 -1
- package/dist/away-inbox-oneshot.js +0 -311
- package/dist/away-inbox-oneshot.js.map +0 -1
- package/dist/backup-restore-handlers.d.ts +0 -10
- package/dist/backup-restore-handlers.d.ts.map +0 -1
- package/dist/backup-restore-handlers.js +0 -82
- package/dist/backup-restore-handlers.js.map +0 -1
- package/dist/backup-restore.d.ts +0 -102
- package/dist/backup-restore.d.ts.map +0 -1
- package/dist/backup-restore.js +0 -341
- package/dist/backup-restore.js.map +0 -1
- package/dist/bin/cello-daemon.d.ts +0 -13
- package/dist/bin/cello-daemon.d.ts.map +0 -1
- package/dist/bin/cello-daemon.js.map +0 -1
- package/dist/boot-agents.d.ts +0 -64
- package/dist/boot-agents.d.ts.map +0 -1
- package/dist/boot-agents.js +0 -241
- package/dist/boot-agents.js.map +0 -1
- package/dist/boot-connection-state.d.ts +0 -38
- package/dist/boot-connection-state.d.ts.map +0 -1
- package/dist/boot-connection-state.js +0 -95
- package/dist/boot-connection-state.js.map +0 -1
- package/dist/boot-core.d.ts +0 -36
- package/dist/boot-core.d.ts.map +0 -1
- package/dist/boot-core.js +0 -293
- package/dist/boot-core.js.map +0 -1
- package/dist/boot-parked-content.d.ts +0 -34
- package/dist/boot-parked-content.d.ts.map +0 -1
- package/dist/boot-parked-content.js +0 -528
- package/dist/boot-parked-content.js.map +0 -1
- package/dist/boot-sweeps.d.ts +0 -22
- package/dist/boot-sweeps.d.ts.map +0 -1
- package/dist/boot-sweeps.js +0 -51
- package/dist/boot-sweeps.js.map +0 -1
- package/dist/bundled-consortium-manifest.d.ts +0 -47
- package/dist/bundled-consortium-manifest.d.ts.map +0 -1
- package/dist/bundled-consortium-manifest.js +0 -116
- package/dist/bundled-consortium-manifest.js.map +0 -1
- package/dist/cbor-blob-migration.d.ts +0 -8
- package/dist/cbor-blob-migration.d.ts.map +0 -1
- package/dist/cbor-blob-migration.js +0 -116
- package/dist/cbor-blob-migration.js.map +0 -1
- package/dist/challenge-verifier.d.ts +0 -12
- package/dist/challenge-verifier.d.ts.map +0 -1
- package/dist/challenge-verifier.js +0 -11
- package/dist/challenge-verifier.js.map +0 -1
- package/dist/close-commitment.d.ts +0 -67
- package/dist/close-commitment.d.ts.map +0 -1
- package/dist/close-commitment.js +0 -78
- package/dist/close-commitment.js.map +0 -1
- package/dist/close-session-handler.d.ts +0 -94
- package/dist/close-session-handler.d.ts.map +0 -1
- package/dist/close-session-handler.js +0 -1418
- package/dist/close-session-handler.js.map +0 -1
- package/dist/co-attendance.d.ts +0 -29
- package/dist/co-attendance.d.ts.map +0 -1
- package/dist/co-attendance.js +0 -32
- package/dist/co-attendance.js.map +0 -1
- package/dist/column-birth.d.ts +0 -40
- package/dist/column-birth.d.ts.map +0 -1
- package/dist/column-birth.js +0 -61
- package/dist/column-birth.js.map +0 -1
- package/dist/connect-or-start.d.ts +0 -25
- package/dist/connect-or-start.d.ts.map +0 -1
- package/dist/connect-or-start.js +0 -175
- package/dist/connect-or-start.js.map +0 -1
- package/dist/connection-agents.d.ts +0 -16
- package/dist/connection-agents.d.ts.map +0 -1
- package/dist/connection-agents.js +0 -68
- package/dist/connection-agents.js.map +0 -1
- package/dist/consent-migration.d.ts +0 -49
- package/dist/consent-migration.d.ts.map +0 -1
- package/dist/consent-migration.js +0 -128
- package/dist/consent-migration.js.map +0 -1
- package/dist/consortium-bootstrap.d.ts +0 -138
- package/dist/consortium-bootstrap.d.ts.map +0 -1
- package/dist/consortium-bootstrap.js +0 -339
- package/dist/consortium-bootstrap.js.map +0 -1
- package/dist/consortium-fingerprint.d.ts +0 -115
- package/dist/consortium-fingerprint.d.ts.map +0 -1
- package/dist/consortium-fingerprint.js +0 -175
- package/dist/consortium-fingerprint.js.map +0 -1
- package/dist/contact-handlers.d.ts +0 -59
- package/dist/contact-handlers.d.ts.map +0 -1
- package/dist/contact-handlers.js +0 -343
- package/dist/contact-handlers.js.map +0 -1
- package/dist/contact-pubkey-case.d.ts +0 -65
- package/dist/contact-pubkey-case.d.ts.map +0 -1
- package/dist/contact-pubkey-case.js +0 -136
- package/dist/contact-pubkey-case.js.map +0 -1
- package/dist/contacts-tier-migration.d.ts +0 -90
- package/dist/contacts-tier-migration.d.ts.map +0 -1
- package/dist/contacts-tier-migration.js +0 -150
- package/dist/contacts-tier-migration.js.map +0 -1
- package/dist/content-encryption-status.d.ts +0 -111
- package/dist/content-encryption-status.d.ts.map +0 -1
- package/dist/content-encryption-status.js +0 -158
- package/dist/content-encryption-status.js.map +0 -1
- package/dist/content-park-client.d.ts +0 -90
- package/dist/content-park-client.d.ts.map +0 -1
- package/dist/content-park-client.js +0 -362
- package/dist/content-park-client.js.map +0 -1
- package/dist/content-park.d.ts +0 -52
- package/dist/content-park.d.ts.map +0 -1
- package/dist/content-park.js +0 -1309
- package/dist/content-park.js.map +0 -1
- package/dist/cross-node-negotiation.d.ts +0 -44
- package/dist/cross-node-negotiation.d.ts.map +0 -1
- package/dist/cross-node-negotiation.js +0 -34
- package/dist/cross-node-negotiation.js.map +0 -1
- package/dist/daemon-handle.d.ts +0 -57
- package/dist/daemon-handle.d.ts.map +0 -1
- package/dist/daemon-handle.js +0 -2
- package/dist/daemon-handle.js.map +0 -1
- package/dist/daemon-status-report.d.ts +0 -50
- package/dist/daemon-status-report.d.ts.map +0 -1
- package/dist/daemon-status-report.js +0 -81
- package/dist/daemon-status-report.js.map +0 -1
- package/dist/daemon.d.ts +0 -45
- package/dist/daemon.d.ts.map +0 -1
- package/dist/daemon.js +0 -1177
- package/dist/daemon.js.map +0 -1
- package/dist/db-identity-store.d.ts +0 -159
- package/dist/db-identity-store.d.ts.map +0 -1
- package/dist/db-identity-store.js +0 -502
- package/dist/db-identity-store.js.map +0 -1
- package/dist/delivery-open-registry.d.ts +0 -92
- package/dist/delivery-open-registry.d.ts.map +0 -1
- package/dist/delivery-open-registry.js +0 -121
- package/dist/delivery-open-registry.js.map +0 -1
- package/dist/delivery-session-suspects.d.ts +0 -56
- package/dist/delivery-session-suspects.d.ts.map +0 -1
- package/dist/delivery-session-suspects.js +0 -94
- package/dist/delivery-session-suspects.js.map +0 -1
- package/dist/directory-auth-posture.d.ts +0 -87
- package/dist/directory-auth-posture.d.ts.map +0 -1
- package/dist/directory-auth-posture.js +0 -134
- package/dist/directory-auth-posture.js.map +0 -1
- package/dist/directory-bootstrap.d.ts +0 -310
- package/dist/directory-bootstrap.d.ts.map +0 -1
- package/dist/directory-bootstrap.js +0 -557
- package/dist/directory-bootstrap.js.map +0 -1
- package/dist/directory-connect.d.ts +0 -27
- package/dist/directory-connect.d.ts.map +0 -1
- package/dist/directory-connect.js +0 -106
- package/dist/directory-connect.js.map +0 -1
- package/dist/disconnect-cleanup.d.ts +0 -51
- package/dist/disconnect-cleanup.d.ts.map +0 -1
- package/dist/disconnect-cleanup.js +0 -72
- package/dist/disconnect-cleanup.js.map +0 -1
- package/dist/document-amendment-store.d.ts +0 -120
- package/dist/document-amendment-store.d.ts.map +0 -1
- package/dist/document-amendment-store.js +0 -266
- package/dist/document-amendment-store.js.map +0 -1
- package/dist/document-delivery-transport.d.ts +0 -168
- package/dist/document-delivery-transport.d.ts.map +0 -1
- package/dist/document-delivery-transport.js +0 -206
- package/dist/document-delivery-transport.js.map +0 -1
- package/dist/document-engine.d.ts +0 -134
- package/dist/document-engine.d.ts.map +0 -1
- package/dist/document-engine.js +0 -282
- package/dist/document-engine.js.map +0 -1
- package/dist/document-flag.d.ts +0 -58
- package/dist/document-flag.d.ts.map +0 -1
- package/dist/document-flag.js +0 -70
- package/dist/document-flag.js.map +0 -1
- package/dist/document-frame-router.d.ts +0 -245
- package/dist/document-frame-router.d.ts.map +0 -1
- package/dist/document-frame-router.js +0 -397
- package/dist/document-frame-router.js.map +0 -1
- package/dist/document-gate-wiring.d.ts +0 -61
- package/dist/document-gate-wiring.d.ts.map +0 -1
- package/dist/document-gate-wiring.js +0 -125
- package/dist/document-gate-wiring.js.map +0 -1
- package/dist/document-gate.d.ts +0 -149
- package/dist/document-gate.d.ts.map +0 -1
- package/dist/document-gate.js +0 -509
- package/dist/document-gate.js.map +0 -1
- package/dist/document-handlers.d.ts +0 -47
- package/dist/document-handlers.d.ts.map +0 -1
- package/dist/document-handlers.js +0 -2203
- package/dist/document-handlers.js.map +0 -1
- package/dist/document-handshake.d.ts +0 -176
- package/dist/document-handshake.d.ts.map +0 -1
- package/dist/document-handshake.js +0 -452
- package/dist/document-handshake.js.map +0 -1
- package/dist/document-inbound.d.ts +0 -162
- package/dist/document-inbound.d.ts.map +0 -1
- package/dist/document-inbound.js +0 -530
- package/dist/document-inbound.js.map +0 -1
- package/dist/document-json.d.ts +0 -120
- package/dist/document-json.d.ts.map +0 -1
- package/dist/document-json.js +0 -191
- package/dist/document-json.js.map +0 -1
- package/dist/document-layer.d.ts +0 -215
- package/dist/document-layer.d.ts.map +0 -1
- package/dist/document-layer.js +0 -1025
- package/dist/document-layer.js.map +0 -1
- package/dist/document-lifecycle.d.ts +0 -52
- package/dist/document-lifecycle.d.ts.map +0 -1
- package/dist/document-lifecycle.js +0 -134
- package/dist/document-lifecycle.js.map +0 -1
- package/dist/document-live-docs.d.ts +0 -58
- package/dist/document-live-docs.d.ts.map +0 -1
- package/dist/document-live-docs.js +0 -126
- package/dist/document-live-docs.js.map +0 -1
- package/dist/document-notify.d.ts +0 -228
- package/dist/document-notify.d.ts.map +0 -1
- package/dist/document-notify.js +0 -580
- package/dist/document-notify.js.map +0 -1
- package/dist/document-profile.d.ts +0 -61
- package/dist/document-profile.d.ts.map +0 -1
- package/dist/document-profile.js +0 -112
- package/dist/document-profile.js.map +0 -1
- package/dist/document-publish.d.ts +0 -87
- package/dist/document-publish.d.ts.map +0 -1
- package/dist/document-publish.js +0 -173
- package/dist/document-publish.js.map +0 -1
- package/dist/document-reachability.d.ts +0 -42
- package/dist/document-reachability.d.ts.map +0 -1
- package/dist/document-reachability.js +0 -80
- package/dist/document-reachability.js.map +0 -1
- package/dist/document-reconcile-engine.d.ts +0 -66
- package/dist/document-reconcile-engine.d.ts.map +0 -1
- package/dist/document-reconcile-engine.js +0 -225
- package/dist/document-reconcile-engine.js.map +0 -1
- package/dist/document-reconcile-scheduler.d.ts +0 -163
- package/dist/document-reconcile-scheduler.d.ts.map +0 -1
- package/dist/document-reconcile-scheduler.js +0 -303
- package/dist/document-reconcile-scheduler.js.map +0 -1
- package/dist/document-rejection.d.ts +0 -251
- package/dist/document-rejection.d.ts.map +0 -1
- package/dist/document-rejection.js +0 -435
- package/dist/document-rejection.js.map +0 -1
- package/dist/document-screen.d.ts +0 -114
- package/dist/document-screen.d.ts.map +0 -1
- package/dist/document-screen.js +0 -223
- package/dist/document-screen.js.map +0 -1
- package/dist/document-store.d.ts +0 -372
- package/dist/document-store.d.ts.map +0 -1
- package/dist/document-store.js +0 -931
- package/dist/document-store.js.map +0 -1
- package/dist/document-surface.d.ts +0 -32
- package/dist/document-surface.d.ts.map +0 -1
- package/dist/document-surface.js +0 -151
- package/dist/document-surface.js.map +0 -1
- package/dist/document-types.d.ts +0 -94
- package/dist/document-types.d.ts.map +0 -1
- package/dist/document-types.js +0 -90
- package/dist/document-types.js.map +0 -1
- package/dist/document-watch.d.ts +0 -69
- package/dist/document-watch.d.ts.map +0 -1
- package/dist/document-watch.js +0 -108
- package/dist/document-watch.js.map +0 -1
- package/dist/document-wiring.d.ts +0 -53
- package/dist/document-wiring.d.ts.map +0 -1
- package/dist/document-wiring.js +0 -323
- package/dist/document-wiring.js.map +0 -1
- package/dist/document-write-guard.d.ts +0 -66
- package/dist/document-write-guard.d.ts.map +0 -1
- package/dist/document-write-guard.js +0 -98
- package/dist/document-write-guard.js.map +0 -1
- package/dist/document-write-path.d.ts +0 -94
- package/dist/document-write-path.d.ts.map +0 -1
- package/dist/document-write-path.js +0 -530
- package/dist/document-write-path.js.map +0 -1
- package/dist/error-message.d.ts +0 -7
- package/dist/error-message.d.ts.map +0 -1
- package/dist/error-message.js +0 -19
- package/dist/error-message.js.map +0 -1
- package/dist/file-manifest-provider.d.ts +0 -37
- package/dist/file-manifest-provider.d.ts.map +0 -1
- package/dist/file-manifest-provider.js +0 -105
- package/dist/file-manifest-provider.js.map +0 -1
- package/dist/frame-values.d.ts +0 -3
- package/dist/frame-values.d.ts.map +0 -1
- package/dist/frame-values.js +0 -84
- package/dist/frame-values.js.map +0 -1
- package/dist/frontier-mismatch.d.ts +0 -73
- package/dist/frontier-mismatch.d.ts.map +0 -1
- package/dist/frontier-mismatch.js +0 -89
- package/dist/frontier-mismatch.js.map +0 -1
- package/dist/gateway-config-handlers.d.ts +0 -26
- package/dist/gateway-config-handlers.d.ts.map +0 -1
- package/dist/gateway-config-handlers.js +0 -429
- package/dist/gateway-config-handlers.js.map +0 -1
- package/dist/held-content.d.ts +0 -145
- package/dist/held-content.d.ts.map +0 -1
- package/dist/held-content.js +0 -389
- package/dist/held-content.js.map +0 -1
- package/dist/http-manifest-poll.d.ts +0 -67
- package/dist/http-manifest-poll.d.ts.map +0 -1
- package/dist/http-manifest-poll.js +0 -150
- package/dist/http-manifest-poll.js.map +0 -1
- package/dist/identity-migration.d.ts +0 -40
- package/dist/identity-migration.d.ts.map +0 -1
- package/dist/identity-migration.js +0 -461
- package/dist/identity-migration.js.map +0 -1
- package/dist/inbound-refusals.d.ts +0 -283
- package/dist/inbound-refusals.d.ts.map +0 -1
- package/dist/inbound-refusals.js +0 -919
- package/dist/inbound-refusals.js.map +0 -1
- package/dist/inbound-seal-request.d.ts +0 -32
- package/dist/inbound-seal-request.d.ts.map +0 -1
- package/dist/inbound-seal-request.js +0 -228
- package/dist/inbound-seal-request.js.map +0 -1
- package/dist/inbound-sessions.d.ts +0 -291
- package/dist/inbound-sessions.d.ts.map +0 -1
- package/dist/inbound-sessions.js +0 -1609
- package/dist/inbound-sessions.js.map +0 -1
- package/dist/inclusion-proof-handlers.d.ts +0 -43
- package/dist/inclusion-proof-handlers.d.ts.map +0 -1
- package/dist/inclusion-proof-handlers.js +0 -565
- package/dist/inclusion-proof-handlers.js.map +0 -1
- package/dist/inclusion-proof.d.ts +0 -151
- package/dist/inclusion-proof.d.ts.map +0 -1
- package/dist/inclusion-proof.js +0 -228
- package/dist/inclusion-proof.js.map +0 -1
- package/dist/index.d.ts +0 -32
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/initiate-session-handler.d.ts +0 -55
- package/dist/initiate-session-handler.d.ts.map +0 -1
- package/dist/initiate-session-handler.js +0 -310
- package/dist/initiate-session-handler.js.map +0 -1
- package/dist/ipc-client.d.ts +0 -31
- package/dist/ipc-client.d.ts.map +0 -1
- package/dist/ipc-client.js +0 -113
- package/dist/ipc-client.js.map +0 -1
- package/dist/ipc-server.d.ts +0 -63
- package/dist/ipc-server.d.ts.map +0 -1
- package/dist/ipc-server.js +0 -429
- package/dist/ipc-server.js.map +0 -1
- package/dist/ipc-surface.d.ts +0 -44
- package/dist/ipc-surface.d.ts.map +0 -1
- package/dist/ipc-surface.js +0 -107
- package/dist/ipc-surface.js.map +0 -1
- package/dist/line-lcs.d.ts +0 -51
- package/dist/line-lcs.d.ts.map +0 -1
- package/dist/line-lcs.js +0 -71
- package/dist/line-lcs.js.map +0 -1
- package/dist/lock-file.d.ts +0 -39
- package/dist/lock-file.d.ts.map +0 -1
- package/dist/lock-file.js +0 -120
- package/dist/lock-file.js.map +0 -1
- package/dist/log-collapse.d.ts +0 -66
- package/dist/log-collapse.d.ts.map +0 -1
- package/dist/log-collapse.js +0 -244
- package/dist/log-collapse.js.map +0 -1
- package/dist/log-rotate.d.ts +0 -67
- package/dist/log-rotate.d.ts.map +0 -1
- package/dist/log-rotate.js +0 -134
- package/dist/log-rotate.js.map +0 -1
- package/dist/manifest-deps.d.ts +0 -25
- package/dist/manifest-deps.d.ts.map +0 -1
- package/dist/manifest-deps.js +0 -151
- package/dist/manifest-deps.js.map +0 -1
- package/dist/manifest-poll-scheduler.d.ts +0 -31
- package/dist/manifest-poll-scheduler.d.ts.map +0 -1
- package/dist/manifest-poll-scheduler.js +0 -59
- package/dist/manifest-poll-scheduler.js.map +0 -1
- package/dist/manifest-validity.d.ts +0 -153
- package/dist/manifest-validity.d.ts.map +0 -1
- package/dist/manifest-validity.js +0 -268
- package/dist/manifest-validity.js.map +0 -1
- package/dist/manifest-version-store-db.d.ts +0 -24
- package/dist/manifest-version-store-db.d.ts.map +0 -1
- package/dist/manifest-version-store-db.js +0 -58
- package/dist/manifest-version-store-db.js.map +0 -1
- package/dist/manifest-version-store.d.ts +0 -16
- package/dist/manifest-version-store.d.ts.map +0 -1
- package/dist/manifest-version-store.js +0 -15
- package/dist/manifest-version-store.js.map +0 -1
- package/dist/network-directory-node.d.ts +0 -136
- package/dist/network-directory-node.d.ts.map +0 -1
- package/dist/network-directory-node.js +0 -810
- package/dist/network-directory-node.js.map +0 -1
- package/dist/nonce-dedup.d.ts +0 -68
- package/dist/nonce-dedup.d.ts.map +0 -1
- package/dist/nonce-dedup.js +0 -205
- package/dist/nonce-dedup.js.map +0 -1
- package/dist/notification-dispatcher.d.ts +0 -92
- package/dist/notification-dispatcher.d.ts.map +0 -1
- package/dist/notification-dispatcher.js +0 -210
- package/dist/notification-dispatcher.js.map +0 -1
- package/dist/notification-handlers.d.ts +0 -53
- package/dist/notification-handlers.d.ts.map +0 -1
- package/dist/notification-handlers.js +0 -461
- package/dist/notification-handlers.js.map +0 -1
- package/dist/onboarding-guidance.d.ts +0 -79
- package/dist/onboarding-guidance.d.ts.map +0 -1
- package/dist/onboarding-guidance.js +0 -95
- package/dist/onboarding-guidance.js.map +0 -1
- package/dist/operator-guidance.d.ts +0 -25
- package/dist/operator-guidance.d.ts.map +0 -1
- package/dist/operator-guidance.js +0 -50
- package/dist/operator-guidance.js.map +0 -1
- package/dist/orphan-triage.d.ts +0 -130
- package/dist/orphan-triage.d.ts.map +0 -1
- package/dist/orphan-triage.js +0 -207
- package/dist/orphan-triage.js.map +0 -1
- package/dist/outbound-sessions.d.ts +0 -126
- package/dist/outbound-sessions.d.ts.map +0 -1
- package/dist/outbound-sessions.js +0 -1052
- package/dist/outbound-sessions.js.map +0 -1
- package/dist/park-envelope.d.ts +0 -329
- package/dist/park-envelope.d.ts.map +0 -1
- package/dist/park-envelope.js +0 -509
- package/dist/park-envelope.js.map +0 -1
- package/dist/park-recovery.d.ts +0 -273
- package/dist/park-recovery.d.ts.map +0 -1
- package/dist/park-recovery.js +0 -717
- package/dist/park-recovery.js.map +0 -1
- package/dist/park-refusals.d.ts +0 -147
- package/dist/park-refusals.d.ts.map +0 -1
- package/dist/park-refusals.js +0 -331
- package/dist/park-refusals.js.map +0 -1
- package/dist/quarantine-framing.d.ts +0 -92
- package/dist/quarantine-framing.d.ts.map +0 -1
- package/dist/quarantine-framing.js +0 -111
- package/dist/quarantine-framing.js.map +0 -1
- package/dist/reconnect-drain.d.ts +0 -22
- package/dist/reconnect-drain.d.ts.map +0 -1
- package/dist/reconnect-drain.js +0 -65
- package/dist/reconnect-drain.js.map +0 -1
- package/dist/recovered-position.d.ts +0 -14
- package/dist/recovered-position.d.ts.map +0 -1
- package/dist/recovered-position.js +0 -59
- package/dist/recovered-position.js.map +0 -1
- package/dist/refusal-notices.d.ts +0 -196
- package/dist/refusal-notices.d.ts.map +0 -1
- package/dist/refusal-notices.js +0 -516
- package/dist/refusal-notices.js.map +0 -1
- package/dist/refusal-reasons.d.ts +0 -245
- package/dist/refusal-reasons.d.ts.map +0 -1
- package/dist/refusal-reasons.js +0 -363
- package/dist/refusal-reasons.js.map +0 -1
- package/dist/register-handler.d.ts +0 -36
- package/dist/register-handler.d.ts.map +0 -1
- package/dist/register-handler.js +0 -285
- package/dist/register-handler.js.map +0 -1
- package/dist/registration-context.d.ts +0 -72
- package/dist/registration-context.d.ts.map +0 -1
- package/dist/registration-context.js +0 -126
- package/dist/registration-context.js.map +0 -1
- package/dist/registration-manager.d.ts +0 -94
- package/dist/registration-manager.d.ts.map +0 -1
- package/dist/registration-manager.js +0 -585
- package/dist/registration-manager.js.map +0 -1
- package/dist/registration-persistence.d.ts +0 -183
- package/dist/registration-persistence.d.ts.map +0 -1
- package/dist/registration-persistence.js +0 -263
- package/dist/registration-persistence.js.map +0 -1
- package/dist/registry-poll.d.ts +0 -52
- package/dist/registry-poll.d.ts.map +0 -1
- package/dist/registry-poll.js +0 -140
- package/dist/registry-poll.js.map +0 -1
- package/dist/registry-version-store-db.d.ts +0 -22
- package/dist/registry-version-store-db.d.ts.map +0 -1
- package/dist/registry-version-store-db.js +0 -50
- package/dist/registry-version-store-db.js.map +0 -1
- package/dist/relay-endpoints.d.ts +0 -18
- package/dist/relay-endpoints.d.ts.map +0 -1
- package/dist/relay-endpoints.js +0 -9
- package/dist/relay-endpoints.js.map +0 -1
- package/dist/relay-only.d.ts +0 -140
- package/dist/relay-only.d.ts.map +0 -1
- package/dist/relay-only.js +0 -193
- package/dist/relay-only.js.map +0 -1
- package/dist/relay-receipt-store.d.ts +0 -155
- package/dist/relay-receipt-store.d.ts.map +0 -1
- package/dist/relay-receipt-store.js +0 -284
- package/dist/relay-receipt-store.js.map +0 -1
- package/dist/relay-reconnect.d.ts +0 -32
- package/dist/relay-reconnect.d.ts.map +0 -1
- package/dist/relay-reconnect.js +0 -29
- package/dist/relay-reconnect.js.map +0 -1
- package/dist/reply-lag.d.ts +0 -11
- package/dist/reply-lag.d.ts.map +0 -1
- package/dist/reply-lag.js +0 -46
- package/dist/reply-lag.js.map +0 -1
- package/dist/resolve-named-agent.d.ts +0 -49
- package/dist/resolve-named-agent.d.ts.map +0 -1
- package/dist/resolve-named-agent.js +0 -77
- package/dist/resolve-named-agent.js.map +0 -1
- package/dist/restart-seal-resolver.d.ts +0 -110
- package/dist/restart-seal-resolver.d.ts.map +0 -1
- package/dist/restart-seal-resolver.js +0 -353
- package/dist/restart-seal-resolver.js.map +0 -1
- package/dist/resume-last-seen.d.ts +0 -15
- package/dist/resume-last-seen.d.ts.map +0 -1
- package/dist/resume-last-seen.js +0 -44
- package/dist/resume-last-seen.js.map +0 -1
- package/dist/retry-queue.d.ts +0 -203
- package/dist/retry-queue.d.ts.map +0 -1
- package/dist/retry-queue.js +0 -701
- package/dist/retry-queue.js.map +0 -1
- package/dist/roster-freshness.d.ts +0 -160
- package/dist/roster-freshness.d.ts.map +0 -1
- package/dist/roster-freshness.js +0 -250
- package/dist/roster-freshness.js.map +0 -1
- package/dist/screening-status.d.ts +0 -15
- package/dist/screening-status.d.ts.map +0 -1
- package/dist/screening-status.js +0 -65
- package/dist/screening-status.js.map +0 -1
- package/dist/seal-carried-close.d.ts +0 -37
- package/dist/seal-carried-close.d.ts.map +0 -1
- package/dist/seal-carried-close.js +0 -179
- package/dist/seal-carried-close.js.map +0 -1
- package/dist/seal-certificate-pull.d.ts +0 -79
- package/dist/seal-certificate-pull.d.ts.map +0 -1
- package/dist/seal-certificate-pull.js +0 -186
- package/dist/seal-certificate-pull.js.map +0 -1
- package/dist/seal-certified-root-check.d.ts +0 -37
- package/dist/seal-certified-root-check.d.ts.map +0 -1
- package/dist/seal-certified-root-check.js +0 -127
- package/dist/seal-certified-root-check.js.map +0 -1
- package/dist/seal-coordinator.d.ts +0 -118
- package/dist/seal-coordinator.d.ts.map +0 -1
- package/dist/seal-coordinator.js +0 -927
- package/dist/seal-coordinator.js.map +0 -1
- package/dist/seal-escalation.d.ts +0 -80
- package/dist/seal-escalation.d.ts.map +0 -1
- package/dist/seal-escalation.js +0 -283
- package/dist/seal-escalation.js.map +0 -1
- package/dist/seal-evidence-root-check.d.ts +0 -70
- package/dist/seal-evidence-root-check.d.ts.map +0 -1
- package/dist/seal-evidence-root-check.js +0 -199
- package/dist/seal-evidence-root-check.js.map +0 -1
- package/dist/seal-failure-store.d.ts +0 -129
- package/dist/seal-failure-store.d.ts.map +0 -1
- package/dist/seal-failure-store.js +0 -173
- package/dist/seal-failure-store.js.map +0 -1
- package/dist/seal-flows.d.ts +0 -107
- package/dist/seal-flows.d.ts.map +0 -1
- package/dist/seal-flows.js +0 -638
- package/dist/seal-flows.js.map +0 -1
- package/dist/seal-frontier-verify.d.ts +0 -103
- package/dist/seal-frontier-verify.d.ts.map +0 -1
- package/dist/seal-frontier-verify.js +0 -143
- package/dist/seal-frontier-verify.js.map +0 -1
- package/dist/seal-leaf.d.ts +0 -58
- package/dist/seal-leaf.d.ts.map +0 -1
- package/dist/seal-leaf.js +0 -112
- package/dist/seal-leaf.js.map +0 -1
- package/dist/seal-legibility-tbs.d.ts +0 -25
- package/dist/seal-legibility-tbs.d.ts.map +0 -1
- package/dist/seal-legibility-tbs.js +0 -77
- package/dist/seal-legibility-tbs.js.map +0 -1
- package/dist/seal-local-terminus.d.ts +0 -41
- package/dist/seal-local-terminus.d.ts.map +0 -1
- package/dist/seal-local-terminus.js +0 -170
- package/dist/seal-local-terminus.js.map +0 -1
- package/dist/seal-receipt-upgrade.d.ts +0 -30
- package/dist/seal-receipt-upgrade.d.ts.map +0 -1
- package/dist/seal-receipt-upgrade.js +0 -49
- package/dist/seal-receipt-upgrade.js.map +0 -1
- package/dist/seal-relay-silence.d.ts +0 -51
- package/dist/seal-relay-silence.d.ts.map +0 -1
- package/dist/seal-relay-silence.js +0 -76
- package/dist/seal-relay-silence.js.map +0 -1
- package/dist/seal-settle.d.ts +0 -38
- package/dist/seal-settle.d.ts.map +0 -1
- package/dist/seal-settle.js +0 -33
- package/dist/seal-settle.js.map +0 -1
- package/dist/seal-upgrade.d.ts +0 -107
- package/dist/seal-upgrade.d.ts.map +0 -1
- package/dist/seal-upgrade.js +0 -200
- package/dist/seal-upgrade.js.map +0 -1
- package/dist/sealed-conversation.d.ts +0 -36
- package/dist/sealed-conversation.d.ts.map +0 -1
- package/dist/sealed-conversation.js +0 -171
- package/dist/sealed-conversation.js.map +0 -1
- package/dist/sealed-leaf-set.d.ts +0 -92
- package/dist/sealed-leaf-set.d.ts.map +0 -1
- package/dist/sealed-leaf-set.js +0 -122
- package/dist/sealed-leaf-set.js.map +0 -1
- package/dist/send-claims.d.ts +0 -56
- package/dist/send-claims.d.ts.map +0 -1
- package/dist/send-claims.js +0 -50
- package/dist/send-claims.js.map +0 -1
- package/dist/session-assignment-parser.d.ts +0 -98
- package/dist/session-assignment-parser.d.ts.map +0 -1
- package/dist/session-assignment-parser.js +0 -325
- package/dist/session-assignment-parser.js.map +0 -1
- package/dist/session-category.d.ts +0 -19
- package/dist/session-category.d.ts.map +0 -1
- package/dist/session-category.js +0 -14
- package/dist/session-category.js.map +0 -1
- package/dist/session-ceremony.d.ts +0 -297
- package/dist/session-ceremony.d.ts.map +0 -1
- package/dist/session-ceremony.js +0 -964
- package/dist/session-ceremony.js.map +0 -1
- package/dist/session-closed.d.ts +0 -79
- package/dist/session-closed.d.ts.map +0 -1
- package/dist/session-closed.js +0 -189
- package/dist/session-closed.js.map +0 -1
- package/dist/session-connection-gater.d.ts +0 -148
- package/dist/session-connection-gater.d.ts.map +0 -1
- package/dist/session-connection-gater.js +0 -332
- package/dist/session-connection-gater.js.map +0 -1
- package/dist/session-content-context.d.ts +0 -162
- package/dist/session-content-context.d.ts.map +0 -1
- package/dist/session-content-context.js +0 -2
- package/dist/session-content-context.js.map +0 -1
- package/dist/session-content-handlers.d.ts +0 -82
- package/dist/session-content-handlers.d.ts.map +0 -1
- package/dist/session-content-handlers.js +0 -1382
- package/dist/session-content-handlers.js.map +0 -1
- package/dist/session-content-ingest.d.ts +0 -206
- package/dist/session-content-ingest.d.ts.map +0 -1
- package/dist/session-content-ingest.js +0 -2167
- package/dist/session-content-ingest.js.map +0 -1
- package/dist/session-content-send.d.ts +0 -191
- package/dist/session-content-send.d.ts.map +0 -1
- package/dist/session-content-send.js +0 -1360
- package/dist/session-content-send.js.map +0 -1
- package/dist/session-delivery-acks.d.ts +0 -169
- package/dist/session-delivery-acks.d.ts.map +0 -1
- package/dist/session-delivery-acks.js +0 -569
- package/dist/session-delivery-acks.js.map +0 -1
- package/dist/session-ephemerals.d.ts +0 -279
- package/dist/session-ephemerals.d.ts.map +0 -1
- package/dist/session-ephemerals.js +0 -591
- package/dist/session-ephemerals.js.map +0 -1
- package/dist/session-leaf-records.d.ts +0 -159
- package/dist/session-leaf-records.d.ts.map +0 -1
- package/dist/session-leaf-records.js +0 -408
- package/dist/session-leaf-records.js.map +0 -1
- package/dist/session-lifecycle.d.ts +0 -303
- package/dist/session-lifecycle.d.ts.map +0 -1
- package/dist/session-lifecycle.js +0 -1679
- package/dist/session-lifecycle.js.map +0 -1
- package/dist/session-liveness.d.ts +0 -135
- package/dist/session-liveness.d.ts.map +0 -1
- package/dist/session-liveness.js +0 -347
- package/dist/session-liveness.js.map +0 -1
- package/dist/session-name.d.ts +0 -35
- package/dist/session-name.d.ts.map +0 -1
- package/dist/session-name.js +0 -60
- package/dist/session-name.js.map +0 -1
- package/dist/session-node-factory.d.ts +0 -18
- package/dist/session-node-factory.d.ts.map +0 -1
- package/dist/session-node-factory.js +0 -182
- package/dist/session-node-factory.js.map +0 -1
- package/dist/session-node-manager.d.ts +0 -875
- package/dist/session-node-manager.d.ts.map +0 -1
- package/dist/session-node-manager.js +0 -2995
- package/dist/session-node-manager.js.map +0 -1
- package/dist/session-node-types.d.ts +0 -1057
- package/dist/session-node-types.d.ts.map +0 -1
- package/dist/session-node-types.js +0 -657
- package/dist/session-node-types.js.map +0 -1
- package/dist/session-notify.d.ts +0 -46
- package/dist/session-notify.d.ts.map +0 -1
- package/dist/session-notify.js +0 -116
- package/dist/session-notify.js.map +0 -1
- package/dist/session-own-chain-store.d.ts +0 -65
- package/dist/session-own-chain-store.d.ts.map +0 -1
- package/dist/session-own-chain-store.js +0 -75
- package/dist/session-own-chain-store.js.map +0 -1
- package/dist/session-queries.d.ts +0 -476
- package/dist/session-queries.d.ts.map +0 -1
- package/dist/session-queries.js +0 -1007
- package/dist/session-queries.js.map +0 -1
- package/dist/session-read-handlers.d.ts +0 -87
- package/dist/session-read-handlers.d.ts.map +0 -1
- package/dist/session-read-handlers.js +0 -682
- package/dist/session-read-handlers.js.map +0 -1
- package/dist/session-records.d.ts +0 -341
- package/dist/session-records.d.ts.map +0 -1
- package/dist/session-records.js +0 -858
- package/dist/session-records.js.map +0 -1
- package/dist/session-relay-client.d.ts +0 -659
- package/dist/session-relay-client.d.ts.map +0 -1
- package/dist/session-relay-client.js +0 -2876
- package/dist/session-relay-client.js.map +0 -1
- package/dist/session-relay.d.ts +0 -397
- package/dist/session-relay.d.ts.map +0 -1
- package/dist/session-relay.js +0 -1636
- package/dist/session-relay.js.map +0 -1
- package/dist/session-salt-agreement.d.ts +0 -331
- package/dist/session-salt-agreement.d.ts.map +0 -1
- package/dist/session-salt-agreement.js +0 -472
- package/dist/session-salt-agreement.js.map +0 -1
- package/dist/session-salts.d.ts +0 -432
- package/dist/session-salts.d.ts.map +0 -1
- package/dist/session-salts.js +0 -1540
- package/dist/session-salts.js.map +0 -1
- package/dist/session-schema.d.ts +0 -30
- package/dist/session-schema.d.ts.map +0 -1
- package/dist/session-schema.js +0 -877
- package/dist/session-schema.js.map +0 -1
- package/dist/session-seal-leaf-store.d.ts +0 -70
- package/dist/session-seal-leaf-store.d.ts.map +0 -1
- package/dist/session-seal-leaf-store.js +0 -105
- package/dist/session-seal-leaf-store.js.map +0 -1
- package/dist/session-seal.d.ts +0 -334
- package/dist/session-seal.d.ts.map +0 -1
- package/dist/session-seal.js +0 -1017
- package/dist/session-seal.js.map +0 -1
- package/dist/session-terminal-refusal.d.ts +0 -65
- package/dist/session-terminal-refusal.d.ts.map +0 -1
- package/dist/session-terminal-refusal.js +0 -87
- package/dist/session-terminal-refusal.js.map +0 -1
- package/dist/session-tree.d.ts +0 -110
- package/dist/session-tree.d.ts.map +0 -1
- package/dist/session-tree.js +0 -144
- package/dist/session-tree.js.map +0 -1
- package/dist/session-views.d.ts +0 -47
- package/dist/session-views.d.ts.map +0 -1
- package/dist/session-views.js +0 -278
- package/dist/session-views.js.map +0 -1
- package/dist/signal-handlers.d.ts +0 -63
- package/dist/signal-handlers.d.ts.map +0 -1
- package/dist/signal-handlers.js +0 -980
- package/dist/signal-handlers.js.map +0 -1
- package/dist/signal-requirement-policy.d.ts +0 -51
- package/dist/signal-requirement-policy.d.ts.map +0 -1
- package/dist/signal-requirement-policy.js +0 -89
- package/dist/signal-requirement-policy.js.map +0 -1
- package/dist/signal-revocability.d.ts +0 -49
- package/dist/signal-revocability.d.ts.map +0 -1
- package/dist/signal-revocability.js +0 -93
- package/dist/signal-revocability.js.map +0 -1
- package/dist/signal-submission.d.ts +0 -181
- package/dist/signal-submission.d.ts.map +0 -1
- package/dist/signal-submission.js +0 -368
- package/dist/signal-submission.js.map +0 -1
- package/dist/signaling-connect.d.ts +0 -118
- package/dist/signaling-connect.d.ts.map +0 -1
- package/dist/signaling-connect.js +0 -538
- package/dist/signaling-connect.js.map +0 -1
- package/dist/signaling-wiring.d.ts +0 -105
- package/dist/signaling-wiring.d.ts.map +0 -1
- package/dist/signaling-wiring.js +0 -393
- package/dist/signaling-wiring.js.map +0 -1
- package/dist/singleton-lock.d.ts +0 -85
- package/dist/singleton-lock.d.ts.map +0 -1
- package/dist/singleton-lock.js +0 -219
- package/dist/singleton-lock.js.map +0 -1
- package/dist/sqlcipher-db.d.ts +0 -139
- package/dist/sqlcipher-db.d.ts.map +0 -1
- package/dist/sqlcipher-db.js +0 -357
- package/dist/sqlcipher-db.js.map +0 -1
- package/dist/standing-receivers.d.ts +0 -319
- package/dist/standing-receivers.d.ts.map +0 -1
- package/dist/standing-receivers.js +0 -1295
- package/dist/standing-receivers.js.map +0 -1
- package/dist/start-agent.d.ts +0 -64
- package/dist/start-agent.d.ts.map +0 -1
- package/dist/start-agent.js +0 -136
- package/dist/start-agent.js.map +0 -1
- package/dist/status-handler.d.ts +0 -54
- package/dist/status-handler.d.ts.map +0 -1
- package/dist/status-handler.js +0 -61
- package/dist/status-handler.js.map +0 -1
- package/dist/submission-retry.d.ts +0 -208
- package/dist/submission-retry.d.ts.map +0 -1
- package/dist/submission-retry.js +0 -506
- package/dist/submission-retry.js.map +0 -1
- package/dist/telegram-bot-client.d.ts +0 -34
- package/dist/telegram-bot-client.d.ts.map +0 -1
- package/dist/telegram-bot-client.js +0 -36
- package/dist/telegram-bot-client.js.map +0 -1
- package/dist/telegram-doorbell.d.ts +0 -38
- package/dist/telegram-doorbell.d.ts.map +0 -1
- package/dist/telegram-doorbell.js +0 -140
- package/dist/telegram-doorbell.js.map +0 -1
- package/dist/test-handlers.d.ts +0 -62
- package/dist/test-handlers.d.ts.map +0 -1
- package/dist/test-handlers.js +0 -240
- package/dist/test-handlers.js.map +0 -1
- package/dist/testing.d.ts +0 -10
- package/dist/testing.d.ts.map +0 -1
- package/dist/testing.js +0 -10
- package/dist/testing.js.map +0 -1
- package/dist/transport-composition.d.ts +0 -31
- package/dist/transport-composition.d.ts.map +0 -1
- package/dist/transport-composition.js +0 -55
- package/dist/transport-composition.js.map +0 -1
- package/dist/transport-selector.d.ts +0 -202
- package/dist/transport-selector.d.ts.map +0 -1
- package/dist/transport-selector.js +0 -196
- package/dist/transport-selector.js.map +0 -1
- package/dist/trust-signal-pickup-listener.d.ts +0 -43
- package/dist/trust-signal-pickup-listener.d.ts.map +0 -1
- package/dist/trust-signal-pickup-listener.js +0 -48
- package/dist/trust-signal-pickup-listener.js.map +0 -1
- package/dist/trust-signal-store.d.ts +0 -406
- package/dist/trust-signal-store.d.ts.map +0 -1
- package/dist/trust-signal-store.js +0 -939
- package/dist/trust-signal-store.js.map +0 -1
- package/dist/trust-signal-sweep-tick.d.ts +0 -60
- package/dist/trust-signal-sweep-tick.d.ts.map +0 -1
- package/dist/trust-signal-sweep-tick.js +0 -101
- package/dist/trust-signal-sweep-tick.js.map +0 -1
- package/dist/trust-signal-sweep.d.ts +0 -94
- package/dist/trust-signal-sweep.d.ts.map +0 -1
- package/dist/trust-signal-sweep.js +0 -147
- package/dist/trust-signal-sweep.js.map +0 -1
- package/dist/type-registry.d.ts +0 -42
- package/dist/type-registry.d.ts.map +0 -1
- package/dist/type-registry.js +0 -37
- package/dist/type-registry.js.map +0 -1
- package/dist/types.d.ts +0 -746
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -20
- package/dist/types.js.map +0 -1
- package/dist/unresolved-nodes-report.d.ts +0 -14
- package/dist/unresolved-nodes-report.d.ts.map +0 -1
- package/dist/unresolved-nodes-report.js +0 -96
- package/dist/unresolved-nodes-report.js.map +0 -1
- package/dist/vocabulary.d.ts +0 -150
- package/dist/vocabulary.d.ts.map +0 -1
- package/dist/vocabulary.js +0 -386
- package/dist/vocabulary.js.map +0 -1
- package/dist/who-label.d.ts +0 -28
- package/dist/who-label.d.ts.map +0 -1
- package/dist/who-label.js +0 -31
- package/dist/who-label.js.map +0 -1
- package/dist/who-resolver.d.ts +0 -15
- package/dist/who-resolver.d.ts.map +0 -1
- package/dist/who-resolver.js +0 -47
- package/dist/who-resolver.js.map +0 -1
- package/dist/wire-content-hash.d.ts +0 -93
- package/dist/wire-content-hash.d.ts.map +0 -1
- package/dist/wire-content-hash.js +0 -116
- package/dist/wire-content-hash.js.map +0 -1
- package/dist/withheld-content.d.ts +0 -13
- package/dist/withheld-content.d.ts.map +0 -1
- package/dist/withheld-content.js +0 -46
- package/dist/withheld-content.js.map +0 -1
- package/dist/witness-alerts.d.ts +0 -40
- package/dist/witness-alerts.d.ts.map +0 -1
- package/dist/witness-alerts.js +0 -102
- package/dist/witness-alerts.js.map +0 -1
package/dist/session-queries.js
DELETED
|
@@ -1,1007 +0,0 @@
|
|
|
1
|
-
import { extractErrorMessage } from "./error-message.js";
|
|
2
|
-
import { SessionTree, sessionTreeLeafKindFromDb } from "./session-tree.js";
|
|
3
|
-
import { TIER } from "./contacts-tier-migration.js";
|
|
4
|
-
import { CAP_COUNTS, CAP_COUNT_SQL, capStaleBefore, REFUSED_SESSIONS_CAP, MAX_REFUSAL_READERS, } from "./session-node-types.js";
|
|
5
|
-
export class SessionQueries {
|
|
6
|
-
#ctx;
|
|
7
|
-
constructor(ctx) {
|
|
8
|
-
this.#ctx = ctx;
|
|
9
|
-
}
|
|
10
|
-
/** A getter so every moved query still reads `this.#db` and narrows exactly as it did. */
|
|
11
|
-
get #db() {
|
|
12
|
-
return this.#ctx.db();
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* DOD-M12B-REVIVAL-BOUND-1 — interrupted sessions that can no longer be revived, and must close.
|
|
16
|
-
*
|
|
17
|
-
* Andre, 2026-08-18: *"after that, those peer IDs and that peer connection needs to be shut down.
|
|
18
|
-
* It is an open connection that a malicious agent can farm for."* The tenet is **leave nothing
|
|
19
|
-
* open that is no longer needed**, and the threat model is a daemon that has been reprogrammed —
|
|
20
|
-
* so the guarantee has to hold on the side that is not the attacker.
|
|
21
|
-
*
|
|
22
|
-
* WHAT IS OPEN. `ingestReceivedContent` refuses `sealed`, `seal_interrupted_pending` and
|
|
23
|
-
* `abandoned`, but deliberately ACCEPTS `interrupted` — that acceptance is the only reason
|
|
24
|
-
* recovery can work. Nothing else ever leaves `interrupted`, so it means accepts FOREVER.
|
|
25
|
-
*
|
|
26
|
-
* **THIS IS THE BACKSTOP, NOT THE COMPLEMENT.** The seal path gets first refusal on every
|
|
27
|
-
* local-cause session, because a session whose ending we can describe truthfully earns a
|
|
28
|
-
* notarized receipt. But "the seal path owns it" is not the same as "the seal path will finish
|
|
29
|
-
* it", and two populations fall through the gap between those:
|
|
30
|
-
*
|
|
31
|
-
* - **The resolver gave up.** `markRestartSealGaveUp` writes only `restart_seal_gave_up_at`;
|
|
32
|
-
* the status stays `interrupted`, and `listRestartOrphanedSessions` then excludes the row by
|
|
33
|
-
* `restart_seal_gave_up_at IS NULL` so it is never retried. `TERMINAL_SEAL_REFUSALS` has ten
|
|
34
|
-
* entries and the measured figure is that 59% of seals that start never finish, so this is
|
|
35
|
-
* the common case, not a corner.
|
|
36
|
-
* - **Zero-message local sessions.** The resolver requires `message_count > 0` — a dead
|
|
37
|
-
* handshake is not worth a ceremony. It is still an open write surface.
|
|
38
|
-
*
|
|
39
|
-
* Excluding those left them permanently interrupted and permanently writable, which is the exact
|
|
40
|
-
* condition this line exists to end. And the population is about to become the majority: no row
|
|
41
|
-
* has ever carried `interrupted_by = 'local'` yet, and from the next shutdown onward every
|
|
42
|
-
* shutdown-orphaned session will. So the sweep takes a local-cause session once the seal path
|
|
43
|
-
* has either declined it or exhausted it — never before.
|
|
44
|
-
*
|
|
45
|
-
* **THE CLOCK MUST BE ONE THE COUNTERPARTY CANNOT MOVE.** The obvious fallback for a row with no
|
|
46
|
-
* `interrupted_at` is `updated_at` — and it is exactly wrong. `ingestReceivedContent` accepts
|
|
47
|
-
* content into an `interrupted` session (that acceptance is this whole line's premise), and a
|
|
48
|
-
* successful ingest runs `UPDATE sessions SET message_count = ?, updated_at = <now>`. So
|
|
49
|
-
* `updated_at` is a clock the reprogrammed peer holds: one message every 24 hours and the session
|
|
50
|
-
* never expires, forever. The fallback would have handed the attacker the off switch for the
|
|
51
|
-
* control built to stop them.
|
|
52
|
-
*
|
|
53
|
-
* Instead the missing timestamps are STAMPED ONCE, by `#stampMissingInterruptedAt` immediately
|
|
54
|
-
* before this query runs, and this query reads `interrupted_at` and nothing else. The stamp is
|
|
55
|
-
* written under `WHERE interrupted_at IS NULL`, so it is monotone — set once, never moved, by us
|
|
56
|
-
* and not by a peer. A legacy row therefore gets its full window starting from the first sweep
|
|
57
|
-
* that sees it, which is later than the true interruption but is the only bound that is sound.
|
|
58
|
-
*
|
|
59
|
-
* Same retired-agent INNER JOIN as the sibling query: a retired agent's rows are kept for
|
|
60
|
-
* accountability, are not resumable, and are not writable either.
|
|
61
|
-
*
|
|
62
|
-
* **THE TIME ARITHMETIC IS LOAD-BEARING, AND BOTH OBVIOUS FORMS OF IT ARE WRONG.** These two
|
|
63
|
-
* columns do not hold the same kind of value:
|
|
64
|
-
*
|
|
65
|
-
* `interrupted_at` TEXT, an ISO-8601 string — `new Date(now).toISOString()`.
|
|
66
|
-
* `updated_at` INTEGER, epoch milliseconds.
|
|
67
|
-
*
|
|
68
|
-
* There are FOUR writers of `status = 'interrupted'`, not three. The fourth is
|
|
69
|
-
* `destroySessionNode` → `#updateSessionStatus(…, "interrupted", "local")`, which historically
|
|
70
|
-
* wrote `interrupted_by` and **no timestamp at all** — and it is the path that produced the two
|
|
71
|
-
* rows in Entry 41. It now stamps `interrupted_at` like the others, so NULL is a legacy state
|
|
72
|
-
* rather than one production keeps creating.
|
|
73
|
-
*
|
|
74
|
-
* So a bare `interrupted_at <= ?` against a numeric bound is **always false** — the column has
|
|
75
|
-
* TEXT affinity and the bound parameter has none, so SQLite applies TEXT affinity to the
|
|
76
|
-
* parameter and compares them as STRINGS (`'2026-08-18T05:32:04.183Z' <= 1755000000000` → 0).
|
|
77
|
-
* The query silently returns nothing forever and reads as "nothing has expired yet". And
|
|
78
|
-
* `CAST(interrupted_at AS
|
|
79
|
-
* INTEGER)` is worse than useless: SQLite casts by taking the leading digits, so
|
|
80
|
-
* `'2026-08-18T05:32:04Z'` becomes **2026**, which is older than any epoch bound. That form
|
|
81
|
-
* abandons every interrupted session on the next boot, immediately, whatever its age. It was
|
|
82
|
-
* written, and `session-001`/`cello-list-sessions` failed on it in the gate.
|
|
83
|
-
*
|
|
84
|
-
* `strftime('%s', …) * 1000` parses the ISO string properly and returns NULL for anything it
|
|
85
|
-
* cannot parse — so a malformed or differently-formatted value falls through the COALESCE to
|
|
86
|
-
* `updated_at` rather than being read as the year 2026.
|
|
87
|
-
*/
|
|
88
|
-
listExpiredUnrevivableSessions(nowMs, windowMs) {
|
|
89
|
-
if (!this.#db) {
|
|
90
|
-
// ABSENT IS NOT FINE. An empty array here is indistinguishable from "the store is clean",
|
|
91
|
-
// which is the state this line exists to end — so the one boot where the sweep could not
|
|
92
|
-
// read the store must not look like the boots where it read it and found nothing.
|
|
93
|
-
this.#ctx.logger.error("session.revival_bound.enumerate.failed", {
|
|
94
|
-
error: "db not initialized",
|
|
95
|
-
impact: "no interrupted session was checked against the revival window this boot; any that "
|
|
96
|
-
+ "have expired are still accepting content",
|
|
97
|
-
});
|
|
98
|
-
return [];
|
|
99
|
-
}
|
|
100
|
-
const rows = this.#db
|
|
101
|
-
.prepare(`SELECT s.session_id AS session_id, s.interrupted_by AS cause, a.agent_name AS agent_name
|
|
102
|
-
FROM sessions s JOIN agents a ON a.agent_id = s.agent_id
|
|
103
|
-
WHERE s.status = 'interrupted' AND a.state != 'retired'
|
|
104
|
-
AND (COALESCE(s.interrupted_by, '') != 'local'
|
|
105
|
-
OR s.restart_seal_gave_up_at IS NOT NULL
|
|
106
|
-
OR s.message_count = 0)
|
|
107
|
-
AND CAST(strftime('%s', s.interrupted_at) AS INTEGER) * 1000 <= ?
|
|
108
|
-
ORDER BY CAST(strftime('%s', s.interrupted_at) AS INTEGER) * 1000 ASC`)
|
|
109
|
-
.all(nowMs - windowMs);
|
|
110
|
-
return rows.map((r) => ({ agentName: r.agent_name, sessionId: r.session_id, cause: r.cause }));
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* DOD-M12B-RESTART-SEAL-1 / DOD-M12B-PENDING-RESOLVE-1 — sessions that need a receipt and have
|
|
114
|
-
* nobody asking for one. TWO populations, one queue, each with its own safety argument.
|
|
115
|
-
*
|
|
116
|
-
* **(2) `seal_interrupted_pending` — a seal commitment nobody notarized.** Measured 2026-08-18 on
|
|
117
|
-
* the live store: 28 sessions, aged 0.3 to 12.8 days, one of them 14 messages long, 26 holding
|
|
118
|
-
* relay-witnessed seal leaves, and **not one with a sealed root**.
|
|
119
|
-
*
|
|
120
|
-
* **HALF OF THEM ARE NOT BILATERAL, and the first version of this comment claimed they were.**
|
|
121
|
-
* Measured split: 14 initiator rows, each carrying the counterparty's signed leaf — and 14
|
|
122
|
-
* responder rows with `counterparty_leaf = NULL`. A responder row is written by
|
|
123
|
-
* `inbound-seal-request.ts` from an UNSIGNED `seal_interrupted_request` frame, before its ack is
|
|
124
|
-
* even sent, so an ordinary send failure produces a one-sided pending row.
|
|
125
|
-
*
|
|
126
|
-
* So the licence is NOT "both parties signed". It is **somebody chose to end this**, on two
|
|
127
|
-
* branches: an initiator row carries the counterparty's signature, and a responder row exists
|
|
128
|
-
* because the counterparty sent a request to seal. And what makes the result VERIFIABLE is
|
|
129
|
-
* neither — it is that the directory rebuilds the tree from relay-witnessed leaves and checks
|
|
130
|
-
* their signatures, never consulting the commitment at all. The commitment is what makes it
|
|
131
|
-
* legitimate to ASK. (`close-session-handler.ts` states this in full; the first draft of this
|
|
132
|
-
* header contradicted it 200 lines away.) `PENDING-EXIT-1` built their exit and it works — but only when an operator runs
|
|
133
|
-
* `cello_close_session` on that session by hand, having somehow deduced they should. Nothing
|
|
134
|
-
* enumerated them, because both sweeps filtered `status = 'interrupted'`. An exit nobody is told
|
|
135
|
-
* about is not an exit.
|
|
136
|
-
*
|
|
137
|
-
* `interrupted_by` is deliberately NOT consulted for that population. It answers "did WE cause
|
|
138
|
-
* this, and may we therefore describe it" — and that is the wrong question once a seal was
|
|
139
|
-
* requested or signed. **SI-001 is not weakened:** it forbids notarizing *"a conversation nobody
|
|
140
|
-
* chose to end"*, and every row here was chosen to be ended by one side or the other. The only
|
|
141
|
-
* thing missing is the request to notarize it.
|
|
142
|
-
*
|
|
143
|
-
* **(1) `interrupted` — sessions our own stop orphaned, and only those.** Here `interrupted_by` is
|
|
144
|
-
* the whole safety argument. `'local'` means the boot sweep, the shutdown
|
|
145
|
-
* sweep, or the operator's own kill switch ended this session — nobody else did, and it cannot be
|
|
146
|
-
* resumed because the transport keypairs died with the process. Those are the ones the resolver
|
|
147
|
-
* may seal on its own.
|
|
148
|
-
*
|
|
149
|
-
* Everything else is excluded and must stay excluded:
|
|
150
|
-
* 'counterparty' — they hung up. SI-001: the operator may still want to wait.
|
|
151
|
-
* 'relay_stream_close' — our relay witness link ended; the session itself may be fine.
|
|
152
|
-
* NULL — written before the column existed, so the cause is UNKNOWN. An
|
|
153
|
-
* unknown cause is not a licence to notarize; it is the reason not to.
|
|
154
|
-
*
|
|
155
|
-
* Same INNER JOIN discipline as getSessionsByStatus: a retired agent's rows are kept for
|
|
156
|
-
* accountability and are not resumable, so they are not offered for sealing either.
|
|
157
|
-
*/
|
|
158
|
-
listRestartOrphanedSessions() {
|
|
159
|
-
if (!this.#db)
|
|
160
|
-
return [];
|
|
161
|
-
const rows = this.#db
|
|
162
|
-
.prepare(
|
|
163
|
-
// `message_count > 0` — a never-messaged interrupted session is a dead HANDSHAKE, which
|
|
164
|
-
// `classifySession` deliberately hides in the "failed" bucket so it does not clutter
|
|
165
|
-
// status. Sealing one spends a directory ceremony to obtain a receipt over nothing, and
|
|
166
|
-
// then moves it into the operator's CLOSED list, making the clutter visible. The whole
|
|
167
|
-
// justification for this work is "3,576 messages produced nothing" — zero messages is
|
|
168
|
-
// nothing to produce.
|
|
169
|
-
//
|
|
170
|
-
// `restart_seal_gave_up_at IS NULL` — a session we have already exhausted. Without it a
|
|
171
|
-
// machine restarting ~6 times a day re-runs five ceremonies against a hopeless session on
|
|
172
|
-
// every boot, forever.
|
|
173
|
-
`SELECT s.session_id AS session_id, s.message_count AS message_count, a.agent_name AS agent_name,
|
|
174
|
-
s.status AS status
|
|
175
|
-
FROM sessions s JOIN agents a ON a.agent_id = s.agent_id
|
|
176
|
-
WHERE a.state != 'retired'
|
|
177
|
-
AND (
|
|
178
|
-
-- (1) OURS, and we can say so. SI-001 holds: an interrupted session with an
|
|
179
|
-
-- unknown cause has no signatures behind it and must not be notarized.
|
|
180
|
-
(s.status = 'interrupted' AND s.interrupted_by = 'local')
|
|
181
|
-
-- (2) A seal commitment with nobody asking for it. review F5: the EXISTS is
|
|
182
|
-
-- STRUCTURAL, not decoration. The header's licence is "a commitment was made", and
|
|
183
|
-
-- a status check alone asserts that in prose while the query checks something
|
|
184
|
-
-- else. Today status implies an artifact row by construction, which is exactly the
|
|
185
|
-
-- kind of invariant that holds until someone adds a fourth writer.
|
|
186
|
-
OR (s.status = 'seal_interrupted_pending'
|
|
187
|
-
AND EXISTS (SELECT 1 FROM seal_interrupted_artifacts sa
|
|
188
|
-
WHERE sa.agent_id = s.agent_id AND sa.session_id = s.session_id))
|
|
189
|
-
)
|
|
190
|
-
AND s.message_count > 0
|
|
191
|
-
AND s.restart_seal_gave_up_at IS NULL
|
|
192
|
-
ORDER BY s.updated_at ASC`)
|
|
193
|
-
.all();
|
|
194
|
-
return rows.map((r) => ({
|
|
195
|
-
agentName: r.agent_name,
|
|
196
|
-
sessionId: r.session_id,
|
|
197
|
-
messageCount: r.message_count ?? 0,
|
|
198
|
-
// Carried so a give-up can say something TRUE about this session: the two populations need
|
|
199
|
-
// different words, and force-abandon is right for one and destructive for the other.
|
|
200
|
-
status: r.status === "seal_interrupted_pending" ? "seal_interrupted_pending" : "interrupted",
|
|
201
|
-
}));
|
|
202
|
-
}
|
|
203
|
-
/**
|
|
204
|
-
* DOD-M12B-STRAND-1 — write one held frame to the durable store.
|
|
205
|
-
*
|
|
206
|
-
* LOGS LOUD, does not refuse. The caller answers `held: true` either way, and that is correct:
|
|
207
|
-
* held content is never `persisted`-acked, so the sender keeps its copy and retries whether or
|
|
208
|
-
* not this row lands. What a failure costs is the restart case — the frame is memory-only again,
|
|
209
|
-
* exactly as it was before this unit — so it is reported at ERROR here and counted again by the
|
|
210
|
-
* teardown alarm, and never allowed to look like a success.
|
|
211
|
-
*/
|
|
212
|
-
persistHeldContent(agentName, sessionId, canonicalSeq, deliverContent, originalContent, contentHashHex, screenedOut, correlationId, origin = "received", leafKind = "msg") {
|
|
213
|
-
if (!this.#db)
|
|
214
|
-
return;
|
|
215
|
-
try {
|
|
216
|
-
// A position may legitimately be re-written by a redelivery of the SAME frame. Different
|
|
217
|
-
// content at the same relay position means the relay contradicted itself, and destroying the
|
|
218
|
-
// first copy silently is not an option for verified content.
|
|
219
|
-
const existing = this.#db.prepare("SELECT content_hash_hex FROM held_content WHERE agent_id = ? AND session_id = ? AND canonical_seq = ?").get(this.#ctx.requireAgentId(agentName), sessionId, canonicalSeq);
|
|
220
|
-
if (existing && existing.content_hash_hex !== contentHashHex) {
|
|
221
|
-
this.#ctx.logger.error("session.content.held.position_conflict", {
|
|
222
|
-
agentName, sessionId, canonicalSeq, correlationId,
|
|
223
|
-
existingContentHash: existing.content_hash_hex, incomingContentHash: contentHashHex,
|
|
224
|
-
impact: "two different frames claim one canonical position — the earlier held copy is being replaced",
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
this.#db.prepare(`INSERT OR REPLACE INTO held_content
|
|
228
|
-
(agent_id, session_id, canonical_seq, content_blob, original_blob, content_hash_hex, screened_out, correlation_id, held_at, origin, leaf_kind)
|
|
229
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(this.#ctx.requireAgentId(agentName), sessionId, canonicalSeq, Buffer.from(deliverContent), Buffer.from(originalContent), contentHashHex, screenedOut ? 1 : 0, correlationId ?? null, Date.now(), origin, leafKind);
|
|
230
|
-
}
|
|
231
|
-
catch (err) {
|
|
232
|
-
this.#ctx.logger.error("session.content.held.persist.failed", {
|
|
233
|
-
agentName, sessionId, canonicalSeq, contentHash: contentHashHex, correlationId,
|
|
234
|
-
impact: "this frame is held IN MEMORY ONLY and will be destroyed if the daemon restarts",
|
|
235
|
-
error: extractErrorMessage(err),
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
/**
|
|
240
|
-
* DOD-M15-REFUSEDEVIDENCE-1: read retained refused messages back — all of a session's, or the one
|
|
241
|
-
* at `sequence`.
|
|
242
|
-
*
|
|
243
|
-
* Returns the RAW payload. Every caller that hands it to a reader must frame it first
|
|
244
|
-
* (`frameQuarantinedPayload`); nothing else in the tree may read this without doing so.
|
|
245
|
-
*/
|
|
246
|
-
readQuarantined(agentName, sessionId, sequence) {
|
|
247
|
-
if (!this.#db)
|
|
248
|
-
return [];
|
|
249
|
-
const rows = this.#db
|
|
250
|
-
.prepare(`SELECT sequence, blob, created_at, sender_pubkey, sender_sig, attribution, quarantine_reason
|
|
251
|
-
FROM transcript
|
|
252
|
-
WHERE agent_id = ? AND session_id = ? AND direction = 'quarantined'
|
|
253
|
-
${sequence === undefined ? "" : "AND sequence = ?"}
|
|
254
|
-
ORDER BY sequence ASC`)
|
|
255
|
-
.all(...(sequence === undefined
|
|
256
|
-
? [this.#ctx.requireAgentId(agentName), sessionId]
|
|
257
|
-
: [this.#ctx.requireAgentId(agentName), sessionId, sequence]));
|
|
258
|
-
return rows.map((r) => ({
|
|
259
|
-
sequence: r.sequence,
|
|
260
|
-
/**
|
|
261
|
-
* ⚠️ NOT `?? "refused"` — review F11. A generic default here is a label for a state that
|
|
262
|
-
* cannot occur: the column exists before any `'quarantined'` row can be written and
|
|
263
|
-
* `#quarantineRefusedContent` always supplies a reason. A default reads to the next maintainer
|
|
264
|
-
* as a supported case and would quietly stand in for a real bug. If a NULL ever appears, the
|
|
265
|
-
* empty reason travels to the frame and the caller, which is loud enough to chase.
|
|
266
|
-
*/
|
|
267
|
-
reason: r.quarantine_reason,
|
|
268
|
-
content: r.blob instanceof Uint8Array ? r.blob : new Uint8Array(r.blob),
|
|
269
|
-
senderPubkeyHex: r.sender_pubkey,
|
|
270
|
-
senderSig: r.sender_sig === null ? null : (r.sender_sig instanceof Uint8Array ? r.sender_sig : new Uint8Array(r.sender_sig)),
|
|
271
|
-
attribution: r.attribution,
|
|
272
|
-
createdAt: r.created_at,
|
|
273
|
-
}));
|
|
274
|
-
}
|
|
275
|
-
/**
|
|
276
|
-
* DOD-M12B-REVIVAL-BOUND-1 — give every timestamp-less interrupted session a clock, once.
|
|
277
|
-
*
|
|
278
|
-
* A row with `interrupted_at IS NULL` has no bound that can be evaluated, and skipping such rows
|
|
279
|
-
* would exempt the oldest sessions in the store from the control permanently — the same "open
|
|
280
|
-
* forever" failure wearing a different NULL. The two rows measured in Entry 41 are exactly this
|
|
281
|
-
* shape, written by a `destroySessionNode` path that set the cause and no timestamp.
|
|
282
|
-
*
|
|
283
|
-
* **`WHERE interrupted_at IS NULL` is the security property, not an optimisation.** It makes the
|
|
284
|
-
* stamp write-once: this can run on every sweep forever and a row's clock still cannot be moved
|
|
285
|
-
* after the first one. That is what disqualifies `updated_at`, which a peer moves with every
|
|
286
|
-
* message it sends into the still-accepting session.
|
|
287
|
-
*
|
|
288
|
-
* The cost is honest and bounded: a legacy row's window starts at the first sweep that sees it
|
|
289
|
-
* rather than at its true interruption, so it survives up to one window longer than it should.
|
|
290
|
-
* A late close is recoverable; a clock the counterparty winds is not.
|
|
291
|
-
*
|
|
292
|
-
* @returns how many rows were stamped.
|
|
293
|
-
*/
|
|
294
|
-
stampMissingInterruptedAt(nowMs) {
|
|
295
|
-
if (!this.#db)
|
|
296
|
-
return 0;
|
|
297
|
-
try {
|
|
298
|
-
const res = this.#db
|
|
299
|
-
.prepare("UPDATE sessions SET interrupted_at = ? WHERE status = 'interrupted' AND interrupted_at IS NULL")
|
|
300
|
-
.run(new Date(nowMs).toISOString());
|
|
301
|
-
const stamped = Number(res?.changes ?? 0);
|
|
302
|
-
if (stamped > 0) {
|
|
303
|
-
this.#ctx.logger.info("session.revival_bound.clock.stamped", {
|
|
304
|
-
stamped,
|
|
305
|
-
impact: "these sessions had no interruption timestamp; their revival window starts now",
|
|
306
|
-
});
|
|
307
|
-
}
|
|
308
|
-
return stamped;
|
|
309
|
-
}
|
|
310
|
-
catch (err) {
|
|
311
|
-
this.#ctx.logger.error("session.revival_bound.clock.stamp.failed", {
|
|
312
|
-
error: extractErrorMessage(err),
|
|
313
|
-
impact: "sessions with no interruption timestamp cannot be evaluated and stay open",
|
|
314
|
-
});
|
|
315
|
-
return 0;
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
/**
|
|
319
|
-
* M7 legibility-TBS-binding (responder verify): record the counterparty's FROST primary (group)
|
|
320
|
-
* pubkey from the FROST-signed SessionAssignment, so the responder can VERIFY the bilateral seal
|
|
321
|
-
* signature locally. Best-effort — a missing row (race) is a no-op; the seal then falls back to
|
|
322
|
-
* accept-without-verify (still sound: the live frame arrives over the authenticated Noise channel).
|
|
323
|
-
*/
|
|
324
|
-
/**
|
|
325
|
-
* The counterparty's threshold group key as this agent has seen it BEFORE — trust on first use.
|
|
326
|
-
*
|
|
327
|
-
* DOD-M15-OFFER-SIGNED-1 / RESPONDER-VERIFY-1. The responder does not verify the assignment's
|
|
328
|
-
* signature (deferred to SESSION-004), so every field in it is whatever the directory said. That
|
|
329
|
-
* makes a same-frame check circular: a compromised directory just says the same thing twice.
|
|
330
|
-
*
|
|
331
|
-
* This is the one anchor the responder holds that a directory CANNOT retroactively change — its
|
|
332
|
-
* own memory of previous sessions with this counterparty. A directory that names a different
|
|
333
|
-
* threshold group key for someone you have already talked to is either substituting an identity
|
|
334
|
-
* or has been compromised since; neither is a session to accept quietly.
|
|
335
|
-
*
|
|
336
|
-
* THE BOUND, stated rather than glossed: this is worth nothing on FIRST contact, which is the
|
|
337
|
-
* definition of trust-on-first-use. It hardens every session after it, which is where a long-lived
|
|
338
|
-
* counterparty relationship actually lives.
|
|
339
|
-
*
|
|
340
|
-
* Keyed on `counterparty_pubkey` — the K_local IDENTITY, which is the stable thing — not on a
|
|
341
|
-
* session id or a display name.
|
|
342
|
-
*/
|
|
343
|
-
getPinnedCounterpartyPrimary(agentName, counterpartyPubkeyHex) {
|
|
344
|
-
if (!this.#db)
|
|
345
|
-
return null;
|
|
346
|
-
const row = this.#db
|
|
347
|
-
.prepare(`SELECT counterparty_primary_pubkey FROM sessions
|
|
348
|
-
WHERE agent_id = ? AND counterparty_pubkey = ? AND counterparty_primary_pubkey IS NOT NULL
|
|
349
|
-
ORDER BY updated_at DESC LIMIT 1`)
|
|
350
|
-
.get(this.#ctx.requireAgentId(agentName), counterpartyPubkeyHex);
|
|
351
|
-
return row?.counterparty_primary_pubkey ?? null;
|
|
352
|
-
}
|
|
353
|
-
/**
|
|
354
|
-
* M7-SESSION-001 (H-1): read back the persisted bilateral commitment artifacts
|
|
355
|
-
* for a session. Returns null when none exist.
|
|
356
|
-
*/
|
|
357
|
-
/**
|
|
358
|
-
* M12-P17: durably record verified content that arrived for an ALREADY-ENDED session.
|
|
359
|
-
*
|
|
360
|
-
* Returns true only when the row is committed — the caller confirm-deletes the relay copy on the
|
|
361
|
-
* strength of this answer, and the ORDER is load-bearing: annex first, delete second. A crash
|
|
362
|
-
* between them must lose nothing, so a failure here MUST report false and leave the relay copy
|
|
363
|
-
* alone. Getting that backwards converts a noisy re-pull loop into permanent silent loss, which is
|
|
364
|
-
* the outcome this whole unit exists to prevent.
|
|
365
|
-
*/
|
|
366
|
-
recordSealedAnnex(agentName, sessionId, contentHashHex, content, senderPubkeyHex) {
|
|
367
|
-
if (!this.#db)
|
|
368
|
-
return false;
|
|
369
|
-
try {
|
|
370
|
-
this.#db
|
|
371
|
-
.prepare(`INSERT OR IGNORE INTO sealed_session_annex (agent_id, content_hash, session_id, sender_pubkey, content, arrived_at)
|
|
372
|
-
VALUES (?, ?, ?, ?, ?, ?)`)
|
|
373
|
-
.run(this.#ctx.requireAgentId(agentName), contentHashHex, sessionId, senderPubkeyHex, Buffer.from(content), Date.now());
|
|
374
|
-
return true;
|
|
375
|
-
}
|
|
376
|
-
catch (err) {
|
|
377
|
-
// FAILS LOUD and reports false: the relay copy is the only other one in existence.
|
|
378
|
-
this.#ctx.logger.error("content.annex.write.failed", {
|
|
379
|
-
agentName, sessionId, contentHash: contentHashHex,
|
|
380
|
-
impact: "content NOT annexed — the relay copy must be kept, or the message is lost",
|
|
381
|
-
error: extractErrorMessage(err),
|
|
382
|
-
});
|
|
383
|
-
return false;
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
/**
|
|
387
|
-
* DOD-COATTEND-1 (review F5) — the single next RECEIVED message after `afterSeq`, or null.
|
|
388
|
-
*
|
|
389
|
-
* The delivery path asks this question inside a 20 ms poll, so it is asked ~47 times a second per
|
|
390
|
-
* blocked connection — ~1,400 times over a default 30 s receive. Answering it with
|
|
391
|
-
* `readTranscript()` meant, every single time: SELECT every row of the session with no predicate
|
|
392
|
-
* and no limit, `TextDecoder().decode()` every blob in it, build the array, then `.find()` one
|
|
393
|
-
* row and discard the rest. On a 200-message session with three co-attending connections blocking
|
|
394
|
-
* — which is the M8D use case, not a worst case — that is tens of thousands of blob decodes per
|
|
395
|
-
* second on the daemon's single synchronous SQLCipher handle, contending with the write path.
|
|
396
|
-
*
|
|
397
|
-
* The predicate belongs in SQL. This is O(1) on the existing (agent_id, session_id, sequence)
|
|
398
|
-
* key and decodes exactly the one blob it returns.
|
|
399
|
-
*/
|
|
400
|
-
findNextReceivedAfter(agentName, sessionId, afterSeq) {
|
|
401
|
-
if (!this.#db)
|
|
402
|
-
return null;
|
|
403
|
-
const row = this.#db
|
|
404
|
-
.prepare(`SELECT sequence, blob FROM transcript
|
|
405
|
-
WHERE agent_id = ? AND session_id = ? AND direction = 'received' AND sequence > ?
|
|
406
|
-
ORDER BY sequence ASC LIMIT 1`)
|
|
407
|
-
.get(this.#ctx.requireAgentId(agentName), sessionId, afterSeq);
|
|
408
|
-
if (!row)
|
|
409
|
-
return null;
|
|
410
|
-
const blob = row.blob instanceof Uint8Array ? row.blob : new Uint8Array(row.blob);
|
|
411
|
-
return { sequence: row.sequence, text: new TextDecoder().decode(blob) };
|
|
412
|
-
}
|
|
413
|
-
getSealInterruptedArtifacts(agentName, sessionId) {
|
|
414
|
-
if (!this.#db)
|
|
415
|
-
return null;
|
|
416
|
-
const row = this.#db
|
|
417
|
-
.prepare("SELECT * FROM seal_interrupted_artifacts WHERE agent_id = ? AND session_id = ?")
|
|
418
|
-
.get(this.#ctx.requireAgentId(agentName), sessionId);
|
|
419
|
-
if (!row)
|
|
420
|
-
return null;
|
|
421
|
-
return {
|
|
422
|
-
role: row.role,
|
|
423
|
-
ownLeaf: JSON.parse(row.own_leaf),
|
|
424
|
-
counterpartyLeaf: JSON.parse(row.counterparty_leaf),
|
|
425
|
-
merkleRoot: row.merkle_root,
|
|
426
|
-
nonce: row.nonce,
|
|
427
|
-
};
|
|
428
|
-
}
|
|
429
|
-
/**
|
|
430
|
-
* Return all sessions with a given status from SQLite.
|
|
431
|
-
* Used by cello status to surface interrupted sessions.
|
|
432
|
-
*/
|
|
433
|
-
getSessionsByStatus(status) {
|
|
434
|
-
if (!this.#db)
|
|
435
|
-
return [];
|
|
436
|
-
// Spans EVERY agent (cello_status is daemon-wide), so no single name can be resolved up front —
|
|
437
|
-
// the display name is joined in from `agents`, its one source of truth. `agent_name` is no
|
|
438
|
-
// longer a `sessions` column, so without this join buildActiveSessions/buildInterruptedSessions
|
|
439
|
-
// read `row.agent_name` as undefined.
|
|
440
|
-
//
|
|
441
|
-
// DOD-AGENT-ID-JOINKEY-1 (reviewer Finding 1): INNER JOIN with `state != 'retired'`, NOT a bare
|
|
442
|
-
// LEFT JOIN. This is the LIVE-status + reaper surface, and a retired agent is gone from the
|
|
443
|
-
// runtime — its leftover session rows (kept for accountability, never re-statused) are not
|
|
444
|
-
// resumable and must not appear here. If they did, the half-open reaper would resolve their
|
|
445
|
-
// RETIRED name via #requireAgentId, which throws, taking down cello_status for the whole daemon.
|
|
446
|
-
// Excluding them also guarantees a non-null agent_name on every returned row. The full historical
|
|
447
|
-
// archive (getAllSessions) keeps its LEFT JOIN and still shows retired/orphaned rows.
|
|
448
|
-
return this.#db
|
|
449
|
-
.prepare(`SELECT s.*, a.agent_name AS agent_name
|
|
450
|
-
FROM sessions s JOIN agents a ON a.agent_id = s.agent_id
|
|
451
|
-
WHERE s.status = ? AND a.state != 'retired'`)
|
|
452
|
-
.all(status);
|
|
453
|
-
}
|
|
454
|
-
loadTreeFromDb(agentName, sessionId) {
|
|
455
|
-
if (!this.#db)
|
|
456
|
-
return SessionTree.empty();
|
|
457
|
-
const rows = this.#db
|
|
458
|
-
.prepare("SELECT leaf_kind, leaf_hash_hex FROM session_tree_leaves WHERE agent_id = ? AND session_id = ? ORDER BY leaf_index ASC")
|
|
459
|
-
.all(this.#ctx.requireAgentId(agentName), sessionId);
|
|
460
|
-
return SessionTree.fromLeaves(rows.map((r, leafIndex) => {
|
|
461
|
-
const kind = sessionTreeLeafKindFromDb(r.leaf_kind);
|
|
462
|
-
if (kind === "unknown") {
|
|
463
|
-
// A leaf kind written by a newer build. The tree stays intact and sealable (the
|
|
464
|
-
// stored hash carries its own domain), but an operator must be able to see that
|
|
465
|
-
// this daemon is behind the one that wrote the row.
|
|
466
|
-
this.#ctx.logger.error("session.tree.leaf_kind.unrecognized", {
|
|
467
|
-
agentName,
|
|
468
|
-
sessionId,
|
|
469
|
-
leafIndex,
|
|
470
|
-
value: r.leaf_kind,
|
|
471
|
-
});
|
|
472
|
-
}
|
|
473
|
-
return { kind, hashHex: r.leaf_hash_hex };
|
|
474
|
-
}));
|
|
475
|
-
}
|
|
476
|
-
/**
|
|
477
|
-
* M12-P18: record that this agent refused a session, so parked content that later arrives for it
|
|
478
|
-
* (and fails `counterparty_unknown`, because no session row exists) can be swept instead of
|
|
479
|
-
* re-pulled forever. Keeps the most recent REFUSED_SESSIONS_CAP per agent.
|
|
480
|
-
*/
|
|
481
|
-
recordRefusedSession(agentName, sessionId, reason) {
|
|
482
|
-
if (!this.#db)
|
|
483
|
-
return;
|
|
484
|
-
const agentId = this.#ctx.requireAgentId(agentName);
|
|
485
|
-
try {
|
|
486
|
-
this.#db.prepare(`INSERT OR REPLACE INTO refused_sessions (agent_id, session_id, reason, refused_at) VALUES (?, ?, ?, ?)`).run(agentId, sessionId, reason, Date.now());
|
|
487
|
-
// Prune to the cap — oldest first.
|
|
488
|
-
this.#db.prepare(`DELETE FROM refused_sessions WHERE agent_id = ? AND session_id NOT IN (
|
|
489
|
-
SELECT session_id FROM refused_sessions WHERE agent_id = ? ORDER BY refused_at DESC LIMIT ${REFUSED_SESSIONS_CAP}
|
|
490
|
-
)`).run(agentId, agentId);
|
|
491
|
-
}
|
|
492
|
-
catch (err) {
|
|
493
|
-
this.#ctx.logger.warn("session.refused.record.failed", {
|
|
494
|
-
agentName, sessionId, error: extractErrorMessage(err),
|
|
495
|
-
});
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
/**
|
|
499
|
-
* DOD-MSG-4 (auto-recover): the DISTINCT relay endpoints this agent has sessions on, so the daemon
|
|
500
|
-
* can pull the agent's parked mailbox from each on reconnect (the relay mailbox is keyed by recipient
|
|
501
|
-
* pubkey, so one pull per relay drains all of the agent's parked content there). Distinct by relay
|
|
502
|
-
* peer id.
|
|
503
|
-
*/
|
|
504
|
-
getAgentRelayEndpoints(agentName) {
|
|
505
|
-
if (!this.#db)
|
|
506
|
-
return [];
|
|
507
|
-
const rows = this.#db
|
|
508
|
-
// Newest first, so the first row kept per relay is its most recent address, not an arbitrary one.
|
|
509
|
-
.prepare("SELECT relay_peer_id, relay_addrs FROM sessions WHERE agent_id = ? AND relay_peer_id IS NOT NULL ORDER BY updated_at DESC")
|
|
510
|
-
.all(this.#ctx.requireAgentId(agentName));
|
|
511
|
-
const byPeer = new Map();
|
|
512
|
-
for (const row of rows) {
|
|
513
|
-
if (!row.relay_peer_id || !row.relay_addrs)
|
|
514
|
-
continue;
|
|
515
|
-
try {
|
|
516
|
-
const addrs = JSON.parse(row.relay_addrs);
|
|
517
|
-
if (!Array.isArray(addrs) || addrs.length === 0)
|
|
518
|
-
continue;
|
|
519
|
-
if (!byPeer.has(row.relay_peer_id))
|
|
520
|
-
byPeer.set(row.relay_peer_id, { relayPeerId: row.relay_peer_id, relayAddrs: addrs });
|
|
521
|
-
}
|
|
522
|
-
catch {
|
|
523
|
-
/* skip malformed */
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
return [...byPeer.values()];
|
|
527
|
-
}
|
|
528
|
-
/** M8C-ABUSE-1 (anti-swarm) + DOD-TIER-2: non-terminal sessions this agent holds with UNKNOWN-tier
|
|
529
|
-
* counterparties — the global cap counts across the whole stranger pool. A sender is exempt from
|
|
530
|
-
* THIS pool iff it is a KNOWN+ contact (tier >= KNOWN); a bare stranger (no row → UNKNOWN) or an
|
|
531
|
-
* explicitly UNKNOWN-tier contact both count. Keying on `tier >= KNOWN` (bounded to <= VIP so a
|
|
532
|
-
* corrupt high value cannot grant pool-exemption) replaces the old row-existence proxy, which
|
|
533
|
-
* would have let a merely-recorded UNKNOWN contact escape the anti-swarm cap. Same
|
|
534
|
-
* 'interrupted'-status fix as countActiveSessionsForCounterparty above. */
|
|
535
|
-
countActiveSessionsFromUnknownSenders(agentName) {
|
|
536
|
-
if (!this.#db)
|
|
537
|
-
return 0;
|
|
538
|
-
const row = this.#db
|
|
539
|
-
.prepare(`SELECT COUNT(*) AS n FROM sessions s
|
|
540
|
-
WHERE s.agent_id = ?
|
|
541
|
-
AND ${CAP_COUNTS("s")}
|
|
542
|
-
AND NOT EXISTS (
|
|
543
|
-
SELECT 1 FROM contacts c
|
|
544
|
-
WHERE c.agent_id = s.agent_id AND c.pubkey = s.counterparty_pubkey
|
|
545
|
-
AND c.tier >= ${TIER.KNOWN} AND c.tier <= ${TIER.VIP}
|
|
546
|
-
)`)
|
|
547
|
-
.get(this.#ctx.requireAgentId(agentName), capStaleBefore());
|
|
548
|
-
return row.n;
|
|
549
|
-
}
|
|
550
|
-
/**
|
|
551
|
-
* M7-SESSION-004 (AC-005/AC-006): read the persisted seal certificate for a session.
|
|
552
|
-
* Returns the sealed root and the parsed legibility object (JSON-safe, hex pubkeys), or
|
|
553
|
-
* null if the session is unknown or not yet sealed. This is the cert-read surface a
|
|
554
|
-
* reader (operator, agent, arbitrator) — possibly in a DIFFERENT process than the one
|
|
555
|
-
* that built the certificate — uses to determine per-party frontiers,
|
|
556
|
-
* attestation modes, and whether the final message was answered.
|
|
557
|
-
*/
|
|
558
|
-
getSealCertificate(agentName, sessionId) {
|
|
559
|
-
if (!this.#db)
|
|
560
|
-
return null;
|
|
561
|
-
const row = this.#db
|
|
562
|
-
.prepare("SELECT sealed_root_hex, seal_legibility FROM sessions WHERE agent_id = ? AND session_id = ?")
|
|
563
|
-
.get(this.#ctx.requireAgentId(agentName), sessionId);
|
|
564
|
-
if (!row || !row.seal_legibility || !row.sealed_root_hex)
|
|
565
|
-
return null;
|
|
566
|
-
let legibility;
|
|
567
|
-
try {
|
|
568
|
-
legibility = JSON.parse(row.seal_legibility);
|
|
569
|
-
}
|
|
570
|
-
catch {
|
|
571
|
-
return null;
|
|
572
|
-
}
|
|
573
|
-
return { sealed_root: row.sealed_root_hex, legibility };
|
|
574
|
-
}
|
|
575
|
-
/**
|
|
576
|
-
* M8C-ABUSE-1: cumulative inbound byte total for a session (anti-drip-feed accounting).
|
|
577
|
-
*
|
|
578
|
-
* ⚠️ DOD-M15-REFUSEDEVIDENCE-1 — QUARANTINED BYTES COUNT, and the bound depends on it.
|
|
579
|
-
*
|
|
580
|
-
* Retaining refused messages puts real bytes on the operator's disk. Left out of this sum,
|
|
581
|
-
* retention would be an UNBOUNDED SIDE CHANNEL: a counterparty who can get messages refused —
|
|
582
|
-
* anyone who can trip the screener, which is anyone — stores against a budget that cannot see
|
|
583
|
-
* what they spent. Counting them makes total retention per session bounded by the same tier cap
|
|
584
|
-
* that bounds delivery, which is the bound the unit's no-truncation rule rests on.
|
|
585
|
-
*
|
|
586
|
-
* No new capability reaches an attacker from this: the counterparty already spends the session's
|
|
587
|
-
* byte budget by sending ordinary messages. Spending it with refused ones costs them the same.
|
|
588
|
-
*/
|
|
589
|
-
getReceivedBytesTotal(agentName, sessionId) {
|
|
590
|
-
if (!this.#db)
|
|
591
|
-
return 0;
|
|
592
|
-
const row = this.#db
|
|
593
|
-
.prepare("SELECT COALESCE(SUM(LENGTH(blob)), 0) AS total FROM transcript WHERE agent_id = ? AND session_id = ? AND direction IN ('received','quarantined')")
|
|
594
|
-
.get(this.#ctx.requireAgentId(agentName), sessionId);
|
|
595
|
-
return row.total;
|
|
596
|
-
}
|
|
597
|
-
ownPubkeyHex(agentName) {
|
|
598
|
-
if (!this.#db)
|
|
599
|
-
return null;
|
|
600
|
-
try {
|
|
601
|
-
// BY agent_id, never by agent_name. The name is a mutable, reuse-freed display label, and
|
|
602
|
-
// scoping on it hands one identity's rows to another keypair (DOD-AGENT-ID-JOINKEY-1).
|
|
603
|
-
const row = this.#db
|
|
604
|
-
.prepare("SELECT k_local_pubkey FROM agents WHERE agent_id = ?")
|
|
605
|
-
.get(this.#ctx.requireAgentId(agentName));
|
|
606
|
-
return row?.k_local_pubkey ?? null;
|
|
607
|
-
}
|
|
608
|
-
catch (err) {
|
|
609
|
-
// An unattributed annex row is truthful; an unattributed row nobody knows about is not. This
|
|
610
|
-
// throws for a retired agent, and without a line here EVERY own held message would land in
|
|
611
|
-
// the record that outlives the session with no sender and no explanation.
|
|
612
|
-
this.#ctx.logger.warn("session.own_pubkey.unresolved", {
|
|
613
|
-
agentName,
|
|
614
|
-
error: extractErrorMessage(err),
|
|
615
|
-
impact: "this agent's own held content will be annexed without a sender",
|
|
616
|
-
});
|
|
617
|
-
return null;
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
/**
|
|
621
|
-
* DOD-SESSION-NAME-1: set (string) or clear (null) THIS agent's name for a session.
|
|
622
|
-
*
|
|
623
|
-
* Returns false when the (agent_id, session_id) row does not exist — i.e. the session is not this
|
|
624
|
-
* agent's — so the caller refuses with session_not_found rather than reporting a silent success on
|
|
625
|
-
* a write that landed nowhere. Same contract as setContactMoniker.
|
|
626
|
-
*
|
|
627
|
-
* Ownership is the ONLY scope: the composite key IS the ownership check, and status is deliberately
|
|
628
|
-
* not consulted. A sealed session can be named — naming one long after the fact is the point — and
|
|
629
|
-
* a name is a local column, so writing it cannot touch the seal, a Merkle leaf, or the wire.
|
|
630
|
-
*
|
|
631
|
-
* The caller validates (validateSessionName) before calling; this stores what it is given.
|
|
632
|
-
*/
|
|
633
|
-
setSessionName(agentName, sessionId, sessionName) {
|
|
634
|
-
if (!this.#db)
|
|
635
|
-
throw new Error(`setSessionName('${agentName}'): database not initialized`);
|
|
636
|
-
const res = this.#db
|
|
637
|
-
.prepare("UPDATE sessions SET session_name = ? WHERE agent_id = ? AND session_id = ?")
|
|
638
|
-
.run(sessionName, this.#ctx.requireAgentId(agentName), sessionId);
|
|
639
|
-
return res.changes > 0;
|
|
640
|
-
}
|
|
641
|
-
/** DOD-M12B-ABANDON-NOTIFY-1 — durable "they hung up" marker. Not a status: the session stays
|
|
642
|
-
* sealable, which is the whole point of not making this terminal. */
|
|
643
|
-
markCounterpartyAbandoned(agentName, sessionId) {
|
|
644
|
-
if (!this.#db)
|
|
645
|
-
return false;
|
|
646
|
-
try {
|
|
647
|
-
const res = this.#db
|
|
648
|
-
.prepare("UPDATE sessions SET counterparty_abandoned_at = ?, updated_at = ? WHERE agent_id = ? AND session_id = ? AND counterparty_abandoned_at IS NULL")
|
|
649
|
-
.run(Date.now(), Date.now(), this.#ctx.requireAgentId(agentName), sessionId);
|
|
650
|
-
// No rows changed means it was already marked — a duplicated notice, which must not
|
|
651
|
-
// re-announce. "Did not throw" is not "landed"; the row count is the answer.
|
|
652
|
-
return Number(res?.changes ?? 0) > 0;
|
|
653
|
-
}
|
|
654
|
-
catch (err) {
|
|
655
|
-
this.#ctx.logger.error("session.counterparty.abandoned.write.failed", {
|
|
656
|
-
agentName, sessionId,
|
|
657
|
-
error: extractErrorMessage(err),
|
|
658
|
-
impact: "this side will go on trying to reach a counterparty that has hung up",
|
|
659
|
-
});
|
|
660
|
-
return false;
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
/**
|
|
664
|
-
* MSG-2 startup-flush: the persisted relay endpoint for a session, or null if none was
|
|
665
|
-
* recorded. Used by the crash-backstop flush, which runs at startup BEFORE the in-memory
|
|
666
|
-
* session entries exist, so it cannot use `entry.relayPeerId`.
|
|
667
|
-
*/
|
|
668
|
-
getPersistedRelayEndpoint(agentName, sessionId) {
|
|
669
|
-
if (!this.#db)
|
|
670
|
-
return null;
|
|
671
|
-
const row = this.#db
|
|
672
|
-
.prepare("SELECT relay_peer_id, relay_addrs FROM sessions WHERE agent_id = ? AND session_id = ?")
|
|
673
|
-
.get(this.#ctx.requireAgentId(agentName), sessionId);
|
|
674
|
-
if (!row?.relay_peer_id || !row?.relay_addrs)
|
|
675
|
-
return null;
|
|
676
|
-
try {
|
|
677
|
-
const addrs = JSON.parse(row.relay_addrs);
|
|
678
|
-
if (!Array.isArray(addrs) || addrs.length === 0)
|
|
679
|
-
return null;
|
|
680
|
-
return { relayPeerId: row.relay_peer_id, relayAddrs: addrs };
|
|
681
|
-
}
|
|
682
|
-
catch {
|
|
683
|
-
return null;
|
|
684
|
-
}
|
|
685
|
-
}
|
|
686
|
-
/** Best-effort: a failure to record WHY must never be the thing that breaks a seal. */
|
|
687
|
-
noteCertifiedLeafState(agentName, sessionId, state, detail) {
|
|
688
|
-
if (!this.#db)
|
|
689
|
-
return;
|
|
690
|
-
try {
|
|
691
|
-
this.#db
|
|
692
|
-
.prepare(`INSERT OR REPLACE INTO session_certified_leaves_state
|
|
693
|
-
(agent_id, session_id, state, detail, recorded_at)
|
|
694
|
-
VALUES (?, ?, ?, ?, ?)`)
|
|
695
|
-
.run(this.#ctx.requireAgentId(agentName), sessionId, state, detail, Date.now());
|
|
696
|
-
}
|
|
697
|
-
catch (err) {
|
|
698
|
-
this.#ctx.logger.warn("seal.certified_leaves.state.write.failed", {
|
|
699
|
-
agentName, sessionId, state, reason: extractErrorMessage(err),
|
|
700
|
-
impact: "the inclusion-proof surface will not be able to name WHY this session has no certified leaf set; it still refuses rather than proving anything",
|
|
701
|
-
});
|
|
702
|
-
}
|
|
703
|
-
}
|
|
704
|
-
/**
|
|
705
|
-
* DOD-M12B-RESTART-SEAL-1 — record that automatic sealing has exhausted this session.
|
|
706
|
-
*
|
|
707
|
-
* Durable on purpose. The resolver's attempt budget is in memory, so without this the budget
|
|
708
|
-
* resets on every boot and a session that can never seal costs five directory ceremonies a day
|
|
709
|
-
* for the life of the machine.
|
|
710
|
-
*
|
|
711
|
-
* IT IS NOT A DEAD END FOR THE OPERATOR. The row keeps status `interrupted`, so a manual
|
|
712
|
-
* `cello_close_session` still works on it and — since DOD-M12B-INTERRUPTED-ESCALATE-1 — still
|
|
713
|
-
* escalates to a unilateral seal. This column only withdraws the session from AUTOMATIC retries.
|
|
714
|
-
*/
|
|
715
|
-
markRestartSealGaveUp(agentName, sessionId, reason) {
|
|
716
|
-
if (!this.#db)
|
|
717
|
-
return;
|
|
718
|
-
this.#db
|
|
719
|
-
.prepare("UPDATE sessions SET restart_seal_gave_up_at = ?, restart_seal_gave_up_reason = ? WHERE agent_id = ? AND session_id = ?")
|
|
720
|
-
.run(Date.now(), reason, this.#ctx.requireAgentId(agentName), sessionId);
|
|
721
|
-
}
|
|
722
|
-
/** DOD-SEALED-INBOX-1: mark a terminal session as dismissed — sets read_at to now.
|
|
723
|
-
* Only valid for terminal sessions; active/interrupted sessions return session_not_terminal. */
|
|
724
|
-
dismissSession(agentName, sessionId) {
|
|
725
|
-
if (!this.#db)
|
|
726
|
-
return { ok: false, reason: "db_not_open" };
|
|
727
|
-
const agentId = this.#ctx.requireAgentId(agentName);
|
|
728
|
-
const row = this.#db
|
|
729
|
-
.prepare("SELECT status FROM sessions WHERE agent_id = ? AND session_id = ?")
|
|
730
|
-
.get(agentId, sessionId);
|
|
731
|
-
if (!row)
|
|
732
|
-
return { ok: false, reason: "session_not_found" };
|
|
733
|
-
const terminal = ["sealed", "abandoned", "seal_interrupted_pending", "interrupted"];
|
|
734
|
-
if (!terminal.includes(row.status))
|
|
735
|
-
return { ok: false, reason: "session_not_terminal" };
|
|
736
|
-
this.#db
|
|
737
|
-
.prepare("UPDATE sessions SET read_at = ? WHERE agent_id = ? AND session_id = ?")
|
|
738
|
-
.run(Date.now(), agentId, sessionId);
|
|
739
|
-
return { ok: true };
|
|
740
|
-
}
|
|
741
|
-
/**
|
|
742
|
-
* Reverse lookup: the display name of a stable agent_id, or null if no such agent.
|
|
743
|
-
*
|
|
744
|
-
* Deliberately INCLUDES retired agents. Its caller (the startup awaiting-content re-park) holds an
|
|
745
|
-
* agent_id read off a durable row and needs a name to find that agent's standing receiver. A
|
|
746
|
-
* retired agent resolves to its name and then has no standing receiver, so the park fails cleanly
|
|
747
|
-
* and loudly — which is correct. Filtering retired agents out here would instead make the row
|
|
748
|
-
* unattributable and the failure mute.
|
|
749
|
-
*/
|
|
750
|
-
agentNameForId(agentId) {
|
|
751
|
-
if (!this.#db)
|
|
752
|
-
return null;
|
|
753
|
-
const row = this.#db
|
|
754
|
-
.prepare("SELECT agent_name FROM agents WHERE agent_id = ?")
|
|
755
|
-
.get(agentId);
|
|
756
|
-
return row?.agent_name ?? null;
|
|
757
|
-
}
|
|
758
|
-
/** DOD-M12B-SEAL-STUCK-1 — how long the oldest held frame for this session has been waiting, or
|
|
759
|
-
* null when nothing is held. This is what separates "stuck since this morning" from "in flight
|
|
760
|
-
* 40 ms ago", and without it a healthy mid-conversation window reads as a stranded session. */
|
|
761
|
-
oldestHeldMs(agentName, sessionId) {
|
|
762
|
-
if (!this.#db)
|
|
763
|
-
return null;
|
|
764
|
-
try {
|
|
765
|
-
const row = this.#db.prepare("SELECT MIN(held_at) AS oldest FROM held_content WHERE agent_id = ? AND session_id = ?").get(this.#ctx.requireAgentId(agentName), sessionId);
|
|
766
|
-
if (!row || row.oldest === null)
|
|
767
|
-
return null;
|
|
768
|
-
return Date.now() - row.oldest;
|
|
769
|
-
}
|
|
770
|
-
catch {
|
|
771
|
-
// A diagnostic detail must not be able to break the surface it decorates.
|
|
772
|
-
return null;
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
/** DOD-M12B-STRAND-1 — drop one held frame from the durable store, on release or on a refusal
|
|
776
|
-
* that supersedes it. A row that outlives its release re-appends on the next boot. */
|
|
777
|
-
deleteHeldContent(agentName, sessionId, canonicalSeq) {
|
|
778
|
-
if (!this.#db)
|
|
779
|
-
return;
|
|
780
|
-
try {
|
|
781
|
-
this.#db.prepare("DELETE FROM held_content WHERE agent_id = ? AND session_id = ? AND canonical_seq = ?").run(this.#ctx.requireAgentId(agentName), sessionId, canonicalSeq);
|
|
782
|
-
}
|
|
783
|
-
catch (err) {
|
|
784
|
-
this.#ctx.logger.error("session.content.held.delete.failed", {
|
|
785
|
-
agentName, sessionId, canonicalSeq,
|
|
786
|
-
impact: "the released frame's durable row survives and will be re-appended on the next boot",
|
|
787
|
-
error: extractErrorMessage(err),
|
|
788
|
-
});
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
/** DOD-RENAME-1: pending rename notices for an agent, oldest first (surfaced in
|
|
792
|
-
* cello_check_notifications — an INBOX pull, never a real-time push). */
|
|
793
|
-
getRenameNotices(agentName) {
|
|
794
|
-
if (!this.#db)
|
|
795
|
-
return [];
|
|
796
|
-
// JOIN the local pet name so the notice can NAME the contact (AC3) — a notice only ever fires for
|
|
797
|
-
// a personally-named contact, so moniker is expected non-null (LEFT JOIN is defensive).
|
|
798
|
-
return this.#db
|
|
799
|
-
.prepare(`SELECT n.pubkey, n.offered_name, n.noticed_at, c.moniker
|
|
800
|
-
FROM contact_rename_notices n
|
|
801
|
-
LEFT JOIN contacts c ON c.agent_id = n.agent_id AND c.pubkey = n.pubkey
|
|
802
|
-
WHERE n.agent_id = ? ORDER BY n.noticed_at ASC`)
|
|
803
|
-
.all(this.#ctx.requireAgentId(agentName));
|
|
804
|
-
}
|
|
805
|
-
/**
|
|
806
|
-
* The certified leaf set, in order, or null when none was stored for this session.
|
|
807
|
-
*
|
|
808
|
-
* Null is a REFUSAL upstream, never a fallback to the local tree: the two cover different leaves
|
|
809
|
-
* and substituting one for the other is how a proof comes to land on a root nobody signed.
|
|
810
|
-
*/
|
|
811
|
-
getCertifiedLeafSet(agentName, sessionId) {
|
|
812
|
-
if (!this.#db)
|
|
813
|
-
return null;
|
|
814
|
-
const rows = this.#db
|
|
815
|
-
.prepare("SELECT content_hash_hex FROM session_certified_leaves WHERE agent_id = ? AND session_id = ? ORDER BY leaf_index ASC")
|
|
816
|
-
.all(this.#ctx.requireAgentId(agentName), sessionId);
|
|
817
|
-
return rows.length > 0 ? rows.map((r) => r.content_hash_hex) : null;
|
|
818
|
-
}
|
|
819
|
-
/** DOD-CAP-SELF-HEAL-1: the sessions with this counterparty that are consuming cap slots, oldest
|
|
820
|
-
* first. The operator is told to close some — this is WHICH, because "close three of them" with
|
|
821
|
-
* no list is not an instruction they can follow. */
|
|
822
|
-
sessionsConsumingCap(agentName, counterpartyPubkey, limit = 10) {
|
|
823
|
-
if (!this.#db)
|
|
824
|
-
return [];
|
|
825
|
-
try {
|
|
826
|
-
const rows = this.#db.prepare(`SELECT session_id FROM sessions WHERE agent_id = ? AND counterparty_pubkey = ? AND ${CAP_COUNTS()}
|
|
827
|
-
ORDER BY updated_at ASC LIMIT ?`).all(this.#ctx.requireAgentId(agentName), counterpartyPubkey, capStaleBefore(), limit);
|
|
828
|
-
return rows.map((r) => r.session_id);
|
|
829
|
-
}
|
|
830
|
-
catch {
|
|
831
|
-
return [];
|
|
832
|
-
}
|
|
833
|
-
}
|
|
834
|
-
/** Advance the read watermark (delivery marks read). MONOTONIC — never lowers, so a replayed or
|
|
835
|
-
* out-of-order cello_receive cannot un-read already-read messages. */
|
|
836
|
-
advanceLastDeliveredSeq(agentName, sessionId, seq) {
|
|
837
|
-
if (!this.#db)
|
|
838
|
-
return;
|
|
839
|
-
this.#db
|
|
840
|
-
.prepare(`INSERT INTO message_watermarks (agent_id, session_id, last_delivered_seq)
|
|
841
|
-
VALUES (?, ?, ?)
|
|
842
|
-
ON CONFLICT(agent_id, session_id)
|
|
843
|
-
DO UPDATE SET last_delivered_seq = MAX(last_delivered_seq, excluded.last_delivered_seq)`)
|
|
844
|
-
.run(this.#ctx.requireAgentId(agentName), sessionId, seq);
|
|
845
|
-
this.#ctx.logger.info("message.watermark.advanced", { agentName, sessionId, sequence: seq });
|
|
846
|
-
}
|
|
847
|
-
/** M8C-ABUSE-1: non-terminal sessions this agent currently holds with the given counterparty.
|
|
848
|
-
* Reviewer HIGH fix (aeffb82f, D18): counting `status = 'active'` ONLY let a counterparty
|
|
849
|
-
* evade the bound for free by disconnecting (a trivial, attacker-controlled action that flips
|
|
850
|
-
* a session to 'interrupted' — markInterruptedWithDetails) and opening a fresh session,
|
|
851
|
-
* repeated indefinitely. 'interrupted' sessions still accept content (ingestReceivedContent
|
|
852
|
-
* explicitly allows both statuses) and are NOT terminal (sealed/seal_interrupted_pending are),
|
|
853
|
-
* so they must still count against the bound. */
|
|
854
|
-
countActiveSessionsForCounterparty(agentName, counterpartyPubkey) {
|
|
855
|
-
if (!this.#db)
|
|
856
|
-
return 0;
|
|
857
|
-
const row = this.#db
|
|
858
|
-
.prepare(CAP_COUNT_SQL("agent_id = ? AND counterparty_pubkey = ?"))
|
|
859
|
-
.get(this.#ctx.requireAgentId(agentName), counterpartyPubkey, capStaleBefore());
|
|
860
|
-
return row.n;
|
|
861
|
-
}
|
|
862
|
-
/**
|
|
863
|
-
* The last thing that happened to this session's certified leaf set, or null if nothing has.
|
|
864
|
-
*
|
|
865
|
-
* Null here and a null from `getCertifiedLeafSet` together mean "no seal has been processed on
|
|
866
|
-
* this side yet" — which is a different sentence again from any of the recorded states.
|
|
867
|
-
*/
|
|
868
|
-
getCertifiedLeafSetState(agentName, sessionId) {
|
|
869
|
-
if (!this.#db)
|
|
870
|
-
return null;
|
|
871
|
-
const row = this.#db
|
|
872
|
-
.prepare("SELECT state, detail FROM session_certified_leaves_state WHERE agent_id = ? AND session_id = ?")
|
|
873
|
-
.get(this.#ctx.requireAgentId(agentName), sessionId);
|
|
874
|
-
return row ? { state: row.state, detail: row.detail } : null;
|
|
875
|
-
}
|
|
876
|
-
/**
|
|
877
|
-
* Return the session record for a specific sessionId, regardless of status.
|
|
878
|
-
* Used by cello_close_session to inspect session state.
|
|
879
|
-
*/
|
|
880
|
-
getSessionRecord(agentName, sessionId) {
|
|
881
|
-
if (!this.#db)
|
|
882
|
-
return null;
|
|
883
|
-
const row = this.#db
|
|
884
|
-
.prepare("SELECT * FROM sessions WHERE agent_id = ? AND session_id = ?")
|
|
885
|
-
.get(this.#ctx.requireAgentId(agentName), sessionId);
|
|
886
|
-
// `agent_name` is display-only and no longer stored on the row; stamp back the name whose
|
|
887
|
-
// agent_id scoped this lookup (~50 daemon call sites read `record.agent_name`).
|
|
888
|
-
return row ? { ...row, agent_name: agentName } : null;
|
|
889
|
-
}
|
|
890
|
-
evictOldestReads(agentId, sessionId, reason) {
|
|
891
|
-
if (!this.#db)
|
|
892
|
-
return;
|
|
893
|
-
this.#db
|
|
894
|
-
.prepare(`DELETE FROM content_refusal_reads
|
|
895
|
-
WHERE agent_id = ? AND session_id = ? AND reason = ? AND consumer_id NOT IN (
|
|
896
|
-
SELECT consumer_id FROM content_refusal_reads
|
|
897
|
-
WHERE agent_id = ? AND session_id = ? AND reason = ?
|
|
898
|
-
ORDER BY seen_at DESC LIMIT ${MAX_REFUSAL_READERS}
|
|
899
|
-
)`)
|
|
900
|
-
.run(agentId, sessionId, reason, agentId, sessionId, reason);
|
|
901
|
-
}
|
|
902
|
-
/**
|
|
903
|
-
* DOD-M15-RELAYONLY-1: is the settings store readable RIGHT NOW?
|
|
904
|
-
*
|
|
905
|
-
* ⚠️ Exists because `getSetting` cannot answer it. That method returns `null` for BOTH "the key is
|
|
906
|
-
* unset" and "there is no database", and a security setting must tell those apart: unset-means-off
|
|
907
|
-
* is correct, db-gone-means-off publishes the operator's real address during the shutdown window.
|
|
908
|
-
* `getDb()` cannot stand in either — it THROWS when there is no database, which on a catch-less
|
|
909
|
-
* ceremony path is worse than the wrong answer.
|
|
910
|
-
*/
|
|
911
|
-
hasDatabase() {
|
|
912
|
-
return this.#db !== null;
|
|
913
|
-
}
|
|
914
|
-
/** M12-P17: read the annex. Operator-initiated ONLY — never wired to a wake path or inbox count. */
|
|
915
|
-
readSealedAnnex(agentName, sessionId) {
|
|
916
|
-
if (!this.#db)
|
|
917
|
-
return [];
|
|
918
|
-
const rows = (sessionId === undefined
|
|
919
|
-
? this.#db.prepare("SELECT session_id, content_hash, sender_pubkey, content, arrived_at FROM sealed_session_annex WHERE agent_id = ? ORDER BY arrived_at ASC").all(this.#ctx.requireAgentId(agentName))
|
|
920
|
-
: this.#db.prepare("SELECT session_id, content_hash, sender_pubkey, content, arrived_at FROM sealed_session_annex WHERE agent_id = ? AND session_id = ? ORDER BY arrived_at ASC").all(this.#ctx.requireAgentId(agentName), sessionId));
|
|
921
|
-
return rows.map((r) => ({
|
|
922
|
-
session_id: r.session_id, content_hash: r.content_hash, sender_pubkey: r.sender_pubkey,
|
|
923
|
-
text: new TextDecoder().decode(new Uint8Array(r.content)), arrived_at: r.arrived_at,
|
|
924
|
-
}));
|
|
925
|
-
}
|
|
926
|
-
/** DOD-M12B-ABANDON-NOTIFY-1: has the counterparty told us they hung up? */
|
|
927
|
-
counterpartyAbandonedAt(agentName, sessionId) {
|
|
928
|
-
if (!this.#db)
|
|
929
|
-
return null;
|
|
930
|
-
try {
|
|
931
|
-
const row = this.#db
|
|
932
|
-
.prepare("SELECT counterparty_abandoned_at FROM sessions WHERE agent_id = ? AND session_id = ?")
|
|
933
|
-
.get(this.#ctx.requireAgentId(agentName), sessionId);
|
|
934
|
-
return row?.counterparty_abandoned_at ?? null;
|
|
935
|
-
}
|
|
936
|
-
catch {
|
|
937
|
-
return null;
|
|
938
|
-
}
|
|
939
|
-
}
|
|
940
|
-
/**
|
|
941
|
-
* F1-b: the durable sealed root hex for a session (written by recordSealCertificate on the
|
|
942
|
-
* bilateral path), or null if not recorded. Lets cello_receive echo the sealed root in its
|
|
943
|
-
* terminal answer without threading it through destroySessionNode.
|
|
944
|
-
*/
|
|
945
|
-
getSealedRootHex(agentName, sessionId) {
|
|
946
|
-
if (!this.#db)
|
|
947
|
-
return null;
|
|
948
|
-
const row = this.#db
|
|
949
|
-
.prepare("SELECT sealed_root_hex FROM sessions WHERE agent_id = ? AND session_id = ?")
|
|
950
|
-
.get(this.#ctx.requireAgentId(agentName), sessionId);
|
|
951
|
-
return row?.sealed_root_hex ?? null;
|
|
952
|
-
}
|
|
953
|
-
/** The highest RECEIVED transcript sequence delivered to the operator for (agent, session).
|
|
954
|
-
* -1 when nothing has been delivered yet (so a seq-0 message reads as unread). */
|
|
955
|
-
getLastDeliveredSeq(agentName, sessionId) {
|
|
956
|
-
if (!this.#db)
|
|
957
|
-
return -1;
|
|
958
|
-
const row = this.#db
|
|
959
|
-
.prepare("SELECT last_delivered_seq FROM message_watermarks WHERE agent_id = ? AND session_id = ?")
|
|
960
|
-
.get(this.#ctx.requireAgentId(agentName), sessionId);
|
|
961
|
-
return row ? row.last_delivered_seq : -1;
|
|
962
|
-
}
|
|
963
|
-
/** DOD-CAP-SELF-HEAL-1 test seam: the shutdown sweep's effect, without a shutdown. Mirrors the
|
|
964
|
-
* real UPDATE at gracefulShutdown so a test cannot pass against a label production never sets. */
|
|
965
|
-
markSessionsInterruptedByLocalShutdownForTest() {
|
|
966
|
-
// SCOPED TO UNLABELLED ROWS. Unscoped, this would relabel rows already marked
|
|
967
|
-
// `counterparty` — one call excusing every interruption every attacker ever caused, on every
|
|
968
|
-
// agent. Production never relabels; nor does this.
|
|
969
|
-
this.#db?.prepare("UPDATE sessions SET interrupted_by = 'local' WHERE status = 'interrupted' AND interrupted_by IS NULL").run();
|
|
970
|
-
}
|
|
971
|
-
/** M12-P18: did this agent refuse this session? Consulted at drain to sweep orphaned parked content. */
|
|
972
|
-
wasSessionRefused(agentName, sessionId) {
|
|
973
|
-
if (!this.#db)
|
|
974
|
-
return false;
|
|
975
|
-
const row = this.#db
|
|
976
|
-
.prepare("SELECT 1 AS present FROM refused_sessions WHERE agent_id = ? AND session_id = ?")
|
|
977
|
-
.get(this.#ctx.requireAgentId(agentName), sessionId);
|
|
978
|
-
return row !== undefined;
|
|
979
|
-
}
|
|
980
|
-
countReceivedMessages(agentName, sessionId) {
|
|
981
|
-
if (!this.#db)
|
|
982
|
-
return 0;
|
|
983
|
-
const row = this.#db
|
|
984
|
-
.prepare("SELECT COUNT(*) AS n FROM transcript WHERE agent_id = ? AND session_id = ? AND direction = 'received'")
|
|
985
|
-
.get(this.#ctx.requireAgentId(agentName), sessionId);
|
|
986
|
-
return row.n;
|
|
987
|
-
}
|
|
988
|
-
/** DOD-CAP-SELF-HEAL-1 test seam: the counterparty's stream closing, without a real peer. */
|
|
989
|
-
markInterruptedByCounterpartyForTest(agentName, sessionId) {
|
|
990
|
-
this.#db?.prepare("UPDATE sessions SET interrupted_by = 'counterparty' WHERE agent_id = ? AND session_id = ?").run(this.#ctx.requireAgentId(agentName), sessionId);
|
|
991
|
-
}
|
|
992
|
-
recordSealCertificate(agentName, sessionId, sealedRootHex, legibilityJson) {
|
|
993
|
-
if (!this.#db)
|
|
994
|
-
return;
|
|
995
|
-
this.#db
|
|
996
|
-
.prepare("UPDATE sessions SET seal_legibility = ?, sealed_root_hex = ?, updated_at = ? WHERE agent_id = ? AND session_id = ?")
|
|
997
|
-
.run(legibilityJson, sealedRootHex, Date.now(), this.#ctx.requireAgentId(agentName), sessionId);
|
|
998
|
-
}
|
|
999
|
-
recordCounterpartyPrimary(agentName, sessionId, primaryPubkeyHex) {
|
|
1000
|
-
if (!this.#db)
|
|
1001
|
-
return;
|
|
1002
|
-
this.#db
|
|
1003
|
-
.prepare("UPDATE sessions SET counterparty_primary_pubkey = ?, updated_at = ? WHERE agent_id = ? AND session_id = ?")
|
|
1004
|
-
.run(primaryPubkeyHex, Date.now(), this.#ctx.requireAgentId(agentName), sessionId);
|
|
1005
|
-
}
|
|
1006
|
-
}
|
|
1007
|
-
//# sourceMappingURL=session-queries.js.map
|