@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/seal-coordinator.js
DELETED
|
@@ -1,927 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The seal cluster: bilateral seal, unilateral escalation, and the returning-absent-party upgrade.
|
|
3
|
-
*
|
|
4
|
-
* Five pieces of mutable state and the four signaling listeners that drive them. They were already
|
|
5
|
-
* seal-private inside startDaemon — nothing else touched them — but "private" was a convention you
|
|
6
|
-
* had to verify by reading 6,000 lines. Here it is the module boundary.
|
|
7
|
-
*
|
|
8
|
-
* What the cluster actually needs from the daemon is five things: the session store, a logger, the
|
|
9
|
-
* per-agent FROST persistence, the per-agent key provider, and a way to recover parked content
|
|
10
|
-
* before ratifying a seal. Notably NOT the signaling hub — a SignalingManager is passed in per
|
|
11
|
-
* listener registration, so the coordinator never reaches for the daemon's nervous system.
|
|
12
|
-
*
|
|
13
|
-
* The state objects (the waiter maps, the in-progress sets) are returned as-is rather than hidden
|
|
14
|
-
* behind accessors: cello_close_session drives them directly from ~30 sites and stays in daemon.ts
|
|
15
|
-
* (it inlines the cursor gate, governance, transcript append and retry enqueue — see the refactor
|
|
16
|
-
* plan's DO-NOT-CUT list). Preserving behavior beats tightening encapsulation in the same move;
|
|
17
|
-
* the encapsulation is a later, separate change with its own tests.
|
|
18
|
-
*/
|
|
19
|
-
import { Buffer } from "node:buffer";
|
|
20
|
-
import { attemptSealUpgrade as attemptSealUpgradeImpl, verifyUpgradeConfirmedCert } from "./seal-upgrade.js";
|
|
21
|
-
import { upgradeAbsentToRecovered, hasAbsentParticipant } from "./seal-receipt-upgrade.js";
|
|
22
|
-
import { verifyUnilateralCertificate, verifyBilateralSealCertificate } from "./session-ceremony.js";
|
|
23
|
-
import { reDeriveFrontiers, findInflatedFrontier, checkUnilateralFrontier } from "./seal-frontier-verify.js";
|
|
24
|
-
import { frameValueToHex, normalizeLegibility } from "./frame-values.js";
|
|
25
|
-
import { extractErrorMessage } from "./error-message.js";
|
|
26
|
-
/**
|
|
27
|
-
* The signed leaves a seal frame carried, or undefined when it carried none.
|
|
28
|
-
*
|
|
29
|
-
* Shape-only: every caller re-checks the signatures (`reDeriveFrontiers` / `checkUnilateralFrontier`)
|
|
30
|
-
* or the root (`recordCertifiedLeafSet`) before believing anything in here.
|
|
31
|
-
*/
|
|
32
|
-
function parseFrontierLeaves(raw) {
|
|
33
|
-
if (!Array.isArray(raw) || raw.length === 0)
|
|
34
|
-
return undefined;
|
|
35
|
-
const toU8 = (v) => (v instanceof Uint8Array ? v : new Uint8Array(v));
|
|
36
|
-
return raw.map((l) => {
|
|
37
|
-
const o = l;
|
|
38
|
-
return {
|
|
39
|
-
structure1_cbor: toU8(o["structure1_cbor"]),
|
|
40
|
-
sender_pubkey: toU8(o["sender_pubkey"]),
|
|
41
|
-
sender_signature: toU8(o["sender_signature"]),
|
|
42
|
-
};
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* DOD-M15-INCLUSION-1: keep the leaf set this certificate is signed over, so a single message can
|
|
47
|
-
* later be proved to sit under it.
|
|
48
|
-
*
|
|
49
|
-
* The local `SessionTree` cannot stand in — it holds content leaves only, while the certified root
|
|
50
|
-
* covers the seal's CONTROL leaves too, so a path built from it lands on a root no certificate names.
|
|
51
|
-
* These are the only frames that ever carry the full set.
|
|
52
|
-
*
|
|
53
|
-
* `recordCertifiedLeafSet` refuses anything that does not reproduce `sealedRootHex`, so a failure
|
|
54
|
-
* here costs the SESSION its inclusion proofs and costs the RECEIPT nothing — hence a warn that says
|
|
55
|
-
* so, and no `return` that would abandon a seal over it.
|
|
56
|
-
*/
|
|
57
|
-
function keepCertifiedLeafSet(deps, agentName, sidHex, frame, sealedRootHex, path) {
|
|
58
|
-
const leaves = parseFrontierLeaves(frame["frontier_leaves"]);
|
|
59
|
-
if (!leaves) {
|
|
60
|
-
/**
|
|
61
|
-
* ABSENT IS NOT FINE — it is just not fatal. And WHICH absence this is decides what the operator
|
|
62
|
-
* should do, so it is recorded rather than flattened (fallback-finder findings 1 and 3).
|
|
63
|
-
*
|
|
64
|
-
* ⚠️ THIS GUIDANCE USED TO END *"The other party, whose confirm frame carries the leaves, can
|
|
65
|
-
* still issue proofs."* That is true on the `unilateral_notification` path and FALSE on
|
|
66
|
-
* `unilateral`: there, WE are the present party and the other party is the ABSENT one, who holds
|
|
67
|
-
* strictly less. So the one string sent each side to ask the other for something neither has —
|
|
68
|
-
* a remedy that reads actionable and is not, which spends the reader's trust as well as their
|
|
69
|
-
* time.
|
|
70
|
-
*/
|
|
71
|
-
const state = path === "unilateral_notification" ? "not_carried_absent_party" : "not_carried_present_party";
|
|
72
|
-
deps.sessionNodeManager.noteCertifiedLeafSetUnavailable(agentName, sidHex, state, `no frontier_leaves on the ${path} seal frame`);
|
|
73
|
-
/**
|
|
74
|
-
* INFO on the absent-party path, WARN on the other two — review F6.
|
|
75
|
-
*
|
|
76
|
-
* `directory-node.ts` attaches `frontier_leaves` to the PRESENT party's confirm frame only, and
|
|
77
|
-
* `seal_upgrade_confirmed` carries none either. So this branch is the ONLY outcome the
|
|
78
|
-
* `unilateral_notification` site can ever take: warning there fires on 100% of a designed path,
|
|
79
|
-
* which trains a reader to skip the level rather than to read it. The disclosure still happens —
|
|
80
|
-
* it is the state row and the refusal that carry it — but the level stops pretending an attempt
|
|
81
|
-
* was made and failed.
|
|
82
|
-
*/
|
|
83
|
-
deps.logger[state === "not_carried_absent_party" ? "info" : "warn"]("seal.certified_leaves.not_carried", {
|
|
84
|
-
sessionId: sidHex,
|
|
85
|
-
agentName,
|
|
86
|
-
path,
|
|
87
|
-
state,
|
|
88
|
-
impact: "this seal frame carried no signed leaves, so this side holds no certified leaf set for the " +
|
|
89
|
-
"session and cannot issue an inclusion proof for any message in it; the sealed receipt itself " +
|
|
90
|
-
"is complete and unaffected",
|
|
91
|
-
guidance: state === "not_carried_absent_party"
|
|
92
|
-
? "cello_get_inclusion_proof refuses this session by name (certified_leaves_unavailable). This side was the ABSENT party, so the counterparty — whose confirm frame carries the leaves — can still issue proofs."
|
|
93
|
-
: "cello_get_inclusion_proof refuses this session by name (certified_leaves_not_carried). This side was PRESENT and the directory sent no leaves, so NEITHER side can prove an individual message here; do not send the operator to the counterparty for one.",
|
|
94
|
-
});
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
try {
|
|
98
|
-
deps.sessionNodeManager.recordCertifiedLeafSet(agentName, sidHex, leaves, sealedRootHex);
|
|
99
|
-
}
|
|
100
|
-
catch (error) {
|
|
101
|
-
deps.logger.warn("seal.certified_leaves.persist.failed", {
|
|
102
|
-
sessionId: sidHex,
|
|
103
|
-
agentName,
|
|
104
|
-
path,
|
|
105
|
-
reason: extractErrorMessage(error),
|
|
106
|
-
impact: "no inclusion proof can be issued for this session; the sealed receipt is unaffected",
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Stamp the receipt with WHERE THE MUTUALLY-SIGNED PREFIX ENDS, derived locally —
|
|
112
|
-
* `DOD-M15-UNILATERAL-1`, review F2.
|
|
113
|
-
*
|
|
114
|
-
* Called on every path that persists a certificate, immediately before it is written, so the stored
|
|
115
|
-
* receipt's boundary is always this daemon's own arithmetic over leaves the counterparty signed —
|
|
116
|
-
* never a number the certificate supplied. On a solo seal nothing in that certificate is bound to
|
|
117
|
-
* the seal signature, so a published boundary is a claim; this replaces it with a derivation.
|
|
118
|
-
*
|
|
119
|
-
* When the carry cannot answer, the field is LEFT ABSENT and said so out loud. Absent reads as "this
|
|
120
|
-
* daemon could not establish the boundary", which is true and checkable; a fallback number would
|
|
121
|
-
* read as an established one.
|
|
122
|
-
*/
|
|
123
|
-
function stampCountersignedBoundary(deps, agentPubkeyHex, sessionIdHex, legibility, path) {
|
|
124
|
-
if (!legibility || typeof legibility !== "object")
|
|
125
|
-
return;
|
|
126
|
-
const derived = deps.sessionNodeManager.countersignedThroughSeqFromCarry(agentPubkeyHex, sessionIdHex);
|
|
127
|
-
if (derived === null) {
|
|
128
|
-
deps.logger.warn("seal.certificate.countersigned_boundary.underivable", {
|
|
129
|
-
sessionId: sessionIdHex,
|
|
130
|
-
path,
|
|
131
|
-
impact: "the stored receipt does not say where both parties' signatures stop covering it, because " +
|
|
132
|
-
"this daemon's own leaf record could not answer. The seal itself is unaffected; a reader " +
|
|
133
|
-
"cannot tell the mutually-signed prefix from the uncountersigned tail from this receipt.",
|
|
134
|
-
guidance: "Compare with the counterparty's receipt, which is derived from their own copy of the same leaves.",
|
|
135
|
-
});
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
legibility.countersigned_through_seq = derived;
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* What an operator should DO about a seal the DIRECTORY refused.
|
|
142
|
-
*
|
|
143
|
-
* Exported so the wording is testable on its own and so there is one place to keep it true. Each
|
|
144
|
-
* branch names a different next step, because each reason accuses a different party: a counterparty
|
|
145
|
-
* whose agent sent no approval, a counterparty whose record disagrees, or a relay that altered the
|
|
146
|
-
* leaf set. Telling all three to "compare transcripts" would send two of them somewhere useless.
|
|
147
|
-
*/
|
|
148
|
-
export function sealRejectionGuidance(reason, detail) {
|
|
149
|
-
const tail = detail ? ` (${detail})` : "";
|
|
150
|
-
switch (reason) {
|
|
151
|
-
case "seal_approval_missing":
|
|
152
|
-
return ("The seal was REFUSED because your counterparty's own signed record of the conversation did " +
|
|
153
|
-
`not arrive, so only one side had approved it${tail}. Nothing was signed and your transcript ` +
|
|
154
|
-
"is untouched. This close now falls through to a SOLO seal over your own record, so you do " +
|
|
155
|
-
"not lose the receipt — read the answer below it for whether that succeeded. Ask your " +
|
|
156
|
-
"counterparty to close again if you want the stronger two-party receipt; their agent, or the " +
|
|
157
|
-
"relay carrying it, did not send their approval. Do NOT force-abandon: that permanently " +
|
|
158
|
-
"forfeits any receipt.");
|
|
159
|
-
case "seal_parties_disagree":
|
|
160
|
-
return ("The seal was REFUSED because you and your counterparty signed DIFFERENT records of this " +
|
|
161
|
-
`conversation${tail}. One of you is missing messages the other has. Nothing was signed. ` +
|
|
162
|
-
"Compare the message list and count with them directly, out of band — the disagreement is " +
|
|
163
|
-
"about content, so no answer from inside this session can settle it. This close still tries " +
|
|
164
|
-
"the solo path over YOUR record; the directory decides whether a counterparty who is present " +
|
|
165
|
-
"and disagreeing may be sealed around, and it is right that it, not this daemon, decides.");
|
|
166
|
-
case "seal_leaves_invalid":
|
|
167
|
-
return (`The seal was REFUSED: the record presented for sealing contained a leaf that does not belong ` +
|
|
168
|
-
`to this conversation${tail}. Nothing was signed. This is tampering by whoever assembled the ` +
|
|
169
|
-
"leaf set — the relay serving this session — not something you or your counterparty did. " +
|
|
170
|
-
"The solo path over your OWN carried chain is exactly the remedy for that, and this close " +
|
|
171
|
-
"takes it. Report the session id. Do NOT force-abandon.");
|
|
172
|
-
default:
|
|
173
|
-
return (`The directory refused to certify this seal (${reason})${tail}. Nothing was signed, the ` +
|
|
174
|
-
"session is NOT marked sealed, and your transcript is untouched. Compare the message count " +
|
|
175
|
-
"with your counterparty and report the session id. Do NOT force-abandon: that permanently " +
|
|
176
|
-
"forfeits any receipt.");
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
export function createSealCoordinator(deps) {
|
|
180
|
-
const { logger, sessionNodeManager, getPersistence, getKeyProvider, recoverContent, recordSealFailure } = deps;
|
|
181
|
-
// DOD-LOOP-1: daemon-level seal bookkeeping is keyed by (agentName, sessionId), NOT sessionId
|
|
182
|
-
// alone — two of the operator's agents can hold both ends of the same session_id on one daemon
|
|
183
|
-
// (loopback), and each end seals independently. Keying by session_id alone would let A's close
|
|
184
|
-
// block B's (false seal_interrupted_in_progress) and make their seal waiters collide.
|
|
185
|
-
const sealKey = (agentName, sessionId) => `${agentName}\x1f${sessionId}`;
|
|
186
|
-
// M7-SESSION-001: tracks seal-interrupted flows currently in progress.
|
|
187
|
-
// Prevents duplicate concurrent seal-interrupted attempts for the same (agent, session) (AC-011).
|
|
188
|
-
const sealInterruptedInProgress = new Set();
|
|
189
|
-
// M7 DOD-SPINE-7: relay-mediated bilateral seal. cello_close_session registers a waiter
|
|
190
|
-
// per session_id (hex); the directory's session_sealed frame — delivered over the agent's
|
|
191
|
-
// signaling stream after FROST notarization, once BOTH parties have submitted their SEAL
|
|
192
|
-
// ctrl leaf — resolves it with the sealed_root.
|
|
193
|
-
// M7-SESSION-004: the bilateral seal resolves with the sealed_root AND the legibility
|
|
194
|
-
// certificate (per-party frontiers, attestation modes, final_message).
|
|
195
|
-
const pendingSealWaiters = new Map();
|
|
196
|
-
// M7 DOD-SPINE-7: register the session_sealed completion handler on a signaling manager — per-agent
|
|
197
|
-
// in production (the directory routes session_sealed to the session-owning agent's authenticated
|
|
198
|
-
// stream), or the shared manager on the test path. Function declaration so getAgentSignaling
|
|
199
|
-
// (defined earlier, called at runtime) can wire it per-agent.
|
|
200
|
-
function registerSessionSealedListener(signaling, agentName, agentPubkeyHex) {
|
|
201
|
-
return signaling.registerInboundHandler((frame) => {
|
|
202
|
-
if (frame["type"] !== "session_sealed")
|
|
203
|
-
return;
|
|
204
|
-
const sidHex = frameValueToHex(frame["session_id"]);
|
|
205
|
-
const rootHex = frameValueToHex(frame["sealed_root"]);
|
|
206
|
-
if (!sidHex || !rootHex)
|
|
207
|
-
return;
|
|
208
|
-
void (async () => {
|
|
209
|
-
const toU8 = (v) => v instanceof Uint8Array ? v : Buffer.isBuffer(v) ? new Uint8Array(v) : null;
|
|
210
|
-
// M7 legibility-TBS-binding: when THIS party is the seal's signer (the initiator, whose
|
|
211
|
-
// group key produced the FROST signature), verify the signature over the legibility-bound
|
|
212
|
-
// TBS. A tampered legibility (answered / content_frontier_seq / attestation_mode, carried
|
|
213
|
-
// unsigned on the frame) changes the hash → the signature fails → the seal is REJECTED. The
|
|
214
|
-
// non-initiator does not hold the signer's key, so it accepts (verified:false): the frame
|
|
215
|
-
// arrived over the authenticated Noise channel, and the binding lets any out-of-band holder
|
|
216
|
-
// of the initiator's primary verify an exported cert.
|
|
217
|
-
if (frame["signature_type"] === "frost") {
|
|
218
|
-
const sessionIdBytes = toU8(frame["session_id"]);
|
|
219
|
-
const sealedRootBytes = toU8(frame["sealed_root"]);
|
|
220
|
-
const frostSig = toU8(frame["frost_signature"]);
|
|
221
|
-
const signerPubkey = toU8(frame["signer_pubkey"]);
|
|
222
|
-
const leafCount = typeof frame["leaf_count"] === "number" ? frame["leaf_count"] : null;
|
|
223
|
-
const ctRaw = frame["close_timestamp"];
|
|
224
|
-
const closeTs = typeof ctRaw === "number" ? ctRaw : typeof ctRaw === "bigint" ? Number(ctRaw) : null;
|
|
225
|
-
if (!sessionIdBytes || !sealedRootBytes || !frostSig || !signerPubkey || leafCount === null || closeTs === null) {
|
|
226
|
-
logger.error("session.sealed.signature.invalid", { sessionId: sidHex, reason: "missing_certificate_fields" });
|
|
227
|
-
return;
|
|
228
|
-
}
|
|
229
|
-
const record = sessionNodeManager.getSessionRecord(agentName, sidHex);
|
|
230
|
-
const verdict = await verifyBilateralSealCertificate({ persistence: getPersistence(agentName), agentPubkeyHex, logger, counterpartyPrimaryHex: record?.counterparty_primary_pubkey ?? null }, {
|
|
231
|
-
sessionId: sessionIdBytes,
|
|
232
|
-
sealedRoot: sealedRootBytes,
|
|
233
|
-
leafCount,
|
|
234
|
-
closeTimestamp: closeTs,
|
|
235
|
-
frostSignature: frostSig,
|
|
236
|
-
signerPubkey,
|
|
237
|
-
signatureType: "frost",
|
|
238
|
-
legibility: frame["legibility"] && typeof frame["legibility"] === "object"
|
|
239
|
-
? frame["legibility"]
|
|
240
|
-
: null,
|
|
241
|
-
});
|
|
242
|
-
if (!verdict.ok) {
|
|
243
|
-
// tamper-evidence: do NOT mark sealed, do NOT resolve the waiter as success.
|
|
244
|
-
logger.error("session.sealed.signature.invalid", { sessionId: sidHex, reason: verdict.reason });
|
|
245
|
-
return;
|
|
246
|
-
}
|
|
247
|
-
/**
|
|
248
|
-
* IS THIS A ROOT OVER *OUR* CONVERSATION? — `DOD-M15-SEALWIRE-1` bullet 2.
|
|
249
|
-
*
|
|
250
|
-
* The signature check above proves the directory signed these bytes. It does not prove the
|
|
251
|
-
* bytes describe this session. Until bullet 1 the client could not tell: the certified root
|
|
252
|
-
* was the relay/directory internal root, which carries relay-assigned fields this daemon
|
|
253
|
-
* never sees for the counterparty's leaves. So the root computed one step earlier was
|
|
254
|
-
* discarded, and at co-signing time this key signed a root it had never checked.
|
|
255
|
-
*
|
|
256
|
-
* Now both live in the content-hash domain and it is a comparison.
|
|
257
|
-
*
|
|
258
|
-
* THE COUNTERBALANCE, and why this is not simply "refuse on any difference": a wrong
|
|
259
|
-
* comparison makes every session unsealable, leaving force-abandon — no receipt — as the
|
|
260
|
-
* only exit. That is worse than the defect it guards. So the daemon distinguishes "the
|
|
261
|
-
* roots disagree" from "I cannot judge": the carry is this daemon's own view and may be
|
|
262
|
-
* legitimately short at this instant, because the counterparty's SEAL leaf is what
|
|
263
|
-
* TRIGGERS the seal and may not have been witnessed here yet. Only a provably complete
|
|
264
|
-
* carry can accuse.
|
|
265
|
-
*/
|
|
266
|
-
const rootCheck = sessionNodeManager.verifyCertifiedRoot(agentPubkeyHex, sidHex, sealedRootBytes, leafCount, undefined);
|
|
267
|
-
if (rootCheck.verdict === "mismatch") {
|
|
268
|
-
/**
|
|
269
|
-
* RESOLVE THE WAITER AS REFUSED — review F4. Dropping it left the caller to time out and
|
|
270
|
-
* be told something false. The close now answers with what actually happened.
|
|
271
|
-
*/
|
|
272
|
-
const waiter = pendingSealWaiters.get(sealKey(agentName, sidHex));
|
|
273
|
-
if (waiter) {
|
|
274
|
-
pendingSealWaiters.delete(sealKey(agentName, sidHex));
|
|
275
|
-
waiter({
|
|
276
|
-
refused: true,
|
|
277
|
-
reason: "seal_root_mismatch",
|
|
278
|
-
detail: rootCheck.detail,
|
|
279
|
-
ownRootHex: rootCheck.ownRootHex,
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
logger.error("session.sealed.root.mismatch", {
|
|
283
|
-
/**
|
|
284
|
-
* `agentName` — review pass 1 on bullet 8, H2. Both verdict events carried only
|
|
285
|
-
* `sessionId`, and ONE DAEMON CAN HOST BOTH ENDS OF ONE SESSION (`DOD-LOOP-1`
|
|
286
|
-
* loopback). Two verdicts then land under the same key, indistinguishable, and a
|
|
287
|
-
* reader — or a journey scraping the log — attributes one end's answer to the other.
|
|
288
|
-
* It is also why `j-loopback` could not use the new journey assertion at all.
|
|
289
|
-
*/
|
|
290
|
-
agentName,
|
|
291
|
-
sessionId: sidHex,
|
|
292
|
-
certifiedRoot: rootHex,
|
|
293
|
-
ownRoot: rootCheck.ownRootHex,
|
|
294
|
-
detail: rootCheck.detail,
|
|
295
|
-
leafCount,
|
|
296
|
-
impact: "the directory signed a root over a leaf set this daemon does not hold. The signature " +
|
|
297
|
-
"is valid, so this is not a forged certificate — it is a certificate over a DIFFERENT " +
|
|
298
|
-
"conversation, or over this one with leaves added, dropped or reordered. Refusing: " +
|
|
299
|
-
"storing it would produce a receipt that proves nothing about what was actually said.",
|
|
300
|
-
guidance: "The session is NOT marked sealed and the transcript is untouched. Compare the leaf " +
|
|
301
|
-
"count with the counterparty, and check the relay and directory logs for this session id.",
|
|
302
|
-
});
|
|
303
|
-
return;
|
|
304
|
-
}
|
|
305
|
-
logger.info("session.sealed.root.checked", {
|
|
306
|
-
agentName,
|
|
307
|
-
sessionId: sidHex,
|
|
308
|
-
verdict: rootCheck.verdict,
|
|
309
|
-
...(rootCheck.verdict === "cannot_judge" ? { reason: rootCheck.reason } : {}),
|
|
310
|
-
...(rootCheck.verdict === "cannot_judge"
|
|
311
|
-
? {
|
|
312
|
-
impact: "the certified root was accepted WITHOUT being checked against this daemon's own " +
|
|
313
|
-
"leaves, because this daemon cannot yet prove it holds the same leaf set. The " +
|
|
314
|
-
"signature was verified; the CONTENT was not.",
|
|
315
|
-
}
|
|
316
|
-
: {}),
|
|
317
|
-
});
|
|
318
|
-
// F2-a: on verified:false, surface WHY (signer_key_not_held / no_frost_share / …) so this
|
|
319
|
-
// event can never be mistaken for a tolerated failed check. A real failure took the early
|
|
320
|
-
// return above (session.sealed.signature.invalid) and never reaches here.
|
|
321
|
-
logger.info("session.sealed.signature.checked", {
|
|
322
|
-
sessionId: sidHex,
|
|
323
|
-
verified: verdict.verified,
|
|
324
|
-
...(verdict.verified ? {} : { reason: verdict.reason }),
|
|
325
|
-
});
|
|
326
|
-
}
|
|
327
|
-
// M7-SESSION-004 (AC-005): normalise the wire legibility (Uint8Array pubkeys → hex) into a
|
|
328
|
-
// JSON-safe certificate and persist it with the sealed record so it survives a restart and
|
|
329
|
-
// is readable via the seal_certificate IPC read — per-party frontiers,
|
|
330
|
-
// attestation modes, and final_message.answered.
|
|
331
|
-
const legibility = normalizeLegibility(frame["legibility"]);
|
|
332
|
-
logger.info("session.sealed.received", {
|
|
333
|
-
sessionId: sidHex,
|
|
334
|
-
sealedRoot: rootHex,
|
|
335
|
-
hasLegibility: legibility !== undefined,
|
|
336
|
-
finalMessageAnswered: legibility && typeof legibility === "object" && "final_message" in legibility
|
|
337
|
-
? legibility.final_message?.answered
|
|
338
|
-
: undefined,
|
|
339
|
-
});
|
|
340
|
-
// DOD-LEG-2 (SI-002): independently re-derive each party's content_frontier_seq from the
|
|
341
|
-
// signed leaves the directory shipped, and REJECT the certificate if any published frontier
|
|
342
|
-
// is inflated beyond what the signed leaves support. The client does NOT trust the directory
|
|
343
|
-
// for the frontier VALUE — only for transporting signed bytes it re-checks itself. When no
|
|
344
|
-
// frontier_leaves are present (a pre-LEG-2 directory), the guard is skipped (backward-compat).
|
|
345
|
-
const frontierLeavesRaw = frame["frontier_leaves"];
|
|
346
|
-
if (legibility !== undefined) {
|
|
347
|
-
const rawParticipants = legibility.participants ?? [];
|
|
348
|
-
// Any party claiming to have received content (frontier > 0) MUST be backed by signed leaves.
|
|
349
|
-
const anyClaimedFrontier = rawParticipants.some((p) => typeof p.content_frontier_seq === "number" && p.content_frontier_seq > 0);
|
|
350
|
-
const haveLeaves = Array.isArray(frontierLeavesRaw) && frontierLeavesRaw.length > 0;
|
|
351
|
-
// HIGH (fail-closed): a malicious directory must not bypass the guard by OMITTING the leaves
|
|
352
|
-
// while still publishing a frontier. No leaves + a claimed frontier → reject.
|
|
353
|
-
if (anyClaimedFrontier && !haveLeaves) {
|
|
354
|
-
logger.error("seal.certificate.frontier.unverifiable", { sessionId: sidHex, reason: "frontier_leaves_missing" });
|
|
355
|
-
return;
|
|
356
|
-
}
|
|
357
|
-
// LOW (robustness): a malformed/malicious legibility (null pubkey or non-numeric frontier)
|
|
358
|
-
// must be rejected, never crash the guard.
|
|
359
|
-
for (const p of rawParticipants) {
|
|
360
|
-
if (typeof p.pubkey !== "string" || typeof p.content_frontier_seq !== "number") {
|
|
361
|
-
logger.error("seal.certificate.frontier.unverifiable", { sessionId: sidHex, reason: "participant_malformed" });
|
|
362
|
-
return;
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
const participants = rawParticipants;
|
|
366
|
-
if (haveLeaves) {
|
|
367
|
-
const toU8 = (v) => (v instanceof Uint8Array ? v : new Uint8Array(v));
|
|
368
|
-
const leaves = frontierLeavesRaw.map((l) => {
|
|
369
|
-
const o = l;
|
|
370
|
-
return {
|
|
371
|
-
structure1_cbor: toU8(o["structure1_cbor"]),
|
|
372
|
-
sender_pubkey: toU8(o["sender_pubkey"]),
|
|
373
|
-
sender_signature: toU8(o["sender_signature"]),
|
|
374
|
-
};
|
|
375
|
-
});
|
|
376
|
-
// Session-bound re-derivation (BLOCKING fix): leaves must be from THIS session, so a
|
|
377
|
-
// malicious directory cannot replay a party's leaves from another session to inflate.
|
|
378
|
-
const rederived = reDeriveFrontiers(leaves, toU8(frame["session_id"]));
|
|
379
|
-
if (!rederived.ok) {
|
|
380
|
-
logger.error("seal.certificate.frontier.unverifiable", { sessionId: sidHex, reason: rederived.reason });
|
|
381
|
-
return;
|
|
382
|
-
}
|
|
383
|
-
const inflated = findInflatedFrontier(participants, rederived.frontiers);
|
|
384
|
-
if (inflated) {
|
|
385
|
-
// The directory published a frontier higher than the signed leaves support — refuse the
|
|
386
|
-
// seal (do NOT persist, do NOT resolve the close as success), exactly like a bad signature.
|
|
387
|
-
logger.error("seal.certificate.frontier.unverifiable", {
|
|
388
|
-
sessionId: sidHex,
|
|
389
|
-
party: inflated.party,
|
|
390
|
-
publishedFrontier: inflated.publishedFrontier,
|
|
391
|
-
derivedFrontier: inflated.derivedFrontier,
|
|
392
|
-
});
|
|
393
|
-
return;
|
|
394
|
-
}
|
|
395
|
-
logger.info("seal.certificate.frontier.verified", {
|
|
396
|
-
sessionId: sidHex,
|
|
397
|
-
parties: participants.length,
|
|
398
|
-
});
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
if (legibility !== undefined) {
|
|
402
|
-
// F2: the boundary is derived from THIS daemon's signed carry, never from the certificate.
|
|
403
|
-
stampCountersignedBoundary({ logger, sessionNodeManager }, agentPubkeyHex, sidHex, legibility, "bilateral");
|
|
404
|
-
try {
|
|
405
|
-
sessionNodeManager.recordSealCertificate(agentName, sidHex, rootHex, JSON.stringify(legibility));
|
|
406
|
-
}
|
|
407
|
-
catch (error) {
|
|
408
|
-
logger.warn("seal.certificate.persist.failed", {
|
|
409
|
-
sessionId: sidHex,
|
|
410
|
-
reason: extractErrorMessage(error),
|
|
411
|
-
});
|
|
412
|
-
}
|
|
413
|
-
keepCertifiedLeafSet({ logger, sessionNodeManager }, agentName, sidHex, frame, rootHex, "bilateral");
|
|
414
|
-
}
|
|
415
|
-
const waiter = pendingSealWaiters.get(sealKey(agentName, sidHex));
|
|
416
|
-
if (waiter) {
|
|
417
|
-
pendingSealWaiters.delete(sealKey(agentName, sidHex));
|
|
418
|
-
waiter({ rootHex, legibility });
|
|
419
|
-
}
|
|
420
|
-
// STATUS FIRST AND SYNCHRONOUS, teardown second. The comment here used to read "mark the
|
|
421
|
-
// session sealed + tear the node down (idempotent — safe if already gone)" — it asserted the
|
|
422
|
-
// property the code lacked, which is why the gap survived. `destroySessionNode` returns
|
|
423
|
-
// early at `if (!entry) return` and writes the status BELOW that guard, so for a session
|
|
424
|
-
// with no live node the receipt landed and the row never moved.
|
|
425
|
-
try {
|
|
426
|
-
sessionNodeManager.markSealed(agentName, sidHex);
|
|
427
|
-
}
|
|
428
|
-
catch (err) {
|
|
429
|
-
logger.error("session.seal.status.write.threw", {
|
|
430
|
-
sessionId: sidHex, agentName,
|
|
431
|
-
error: extractErrorMessage(err),
|
|
432
|
-
impact: "the seal COMPLETED and the certificate is stored, but this row still reads interrupted",
|
|
433
|
-
});
|
|
434
|
-
}
|
|
435
|
-
void sessionNodeManager.destroySessionNode(agentName, sidHex, "sealed");
|
|
436
|
-
})();
|
|
437
|
-
});
|
|
438
|
-
}
|
|
439
|
-
// SESSION-002 (DOD-SEAL): cello_close_session escalates to a UNILATERAL seal when the
|
|
440
|
-
// counterparty never co-closes. The waiter is resolved by the seal_unilateral_confirmed
|
|
441
|
-
// listener AFTER it verifies the certificate signature (channel-independent), or by
|
|
442
|
-
// seal_unilateral_too_early (grace not elapsed). Keyed by session_id hex.
|
|
443
|
-
// F20: `remainingSeconds` carries the directory's seal_unilateral_too_early countdown so the
|
|
444
|
-
// close result can tell the operator WHEN a unilateral seal becomes available.
|
|
445
|
-
// M8B FINDING-3 (cascade-2): a successful unilateral seal now carries the legibility certificate
|
|
446
|
-
// (normalized, JSON-safe) so cello_close_session returns it inline — the same RESPONSE SHAPE as the
|
|
447
|
-
// bilateral close (not cryptographic parity: this cert is directory-attested, see FINDING-5). undefined
|
|
448
|
-
// when the directory shipped none (a pre-cascade-2 directory): the seal still completes, but no
|
|
449
|
-
// retrievable receipt is produced (the pre-fix behavior).
|
|
450
|
-
// KEYED `agent\x1f session`, like `sealInterruptedInProgress` — NOT by session id alone.
|
|
451
|
-
//
|
|
452
|
-
// Two agents on one daemon is a supported topology (and the one the operator actually runs), and
|
|
453
|
-
// the away-path one-shot escalation can overlap a manual close. Keyed by session id, whichever
|
|
454
|
-
// registered second CLOBBERED the first's resolver: the loser waited out the full 30 s and
|
|
455
|
-
// reported `seal_unilateral_timeout` for a seal that SUCCEEDED — the operator is then told the
|
|
456
|
-
// directory could not verify their root, for a session that is notarized.
|
|
457
|
-
const pendingUnilateralWaiters = new Map();
|
|
458
|
-
// SESSION-002: per-agent listener for the unilateral certificate. Verifies the FROST
|
|
459
|
-
// signature over the rebuilt TBS against the agent's own primary_pubkey BEFORE resolving
|
|
460
|
-
// the close as sealed (SI-003: a channel-swapped sealed_root fails the signature check).
|
|
461
|
-
function registerUnilateralConfirmedListener(signaling, agentName, agentPubkeyHex) {
|
|
462
|
-
return signaling.registerInboundHandler((frame) => {
|
|
463
|
-
const ftype = frame["type"];
|
|
464
|
-
if (ftype !== "seal_unilateral_confirmed" && ftype !== "seal_unilateral_too_early")
|
|
465
|
-
return;
|
|
466
|
-
const sidHex = frameValueToHex(frame["session_id"]);
|
|
467
|
-
if (!sidHex)
|
|
468
|
-
return;
|
|
469
|
-
const waiter = pendingUnilateralWaiters.get(sealKey(agentName, sidHex));
|
|
470
|
-
if (!waiter)
|
|
471
|
-
return;
|
|
472
|
-
if (ftype === "seal_unilateral_too_early") {
|
|
473
|
-
pendingUnilateralWaiters.delete(sealKey(agentName, sidHex));
|
|
474
|
-
// F20: thread the directory's remaining_seconds through so the close guidance can
|
|
475
|
-
// say when the unilateral seal becomes available.
|
|
476
|
-
const rs = frame["remaining_seconds"];
|
|
477
|
-
/**
|
|
478
|
-
* Review F1: carry WHICH refusal it was, against the closed set. An unrecognised value is
|
|
479
|
-
* dropped rather than passed through — the guidance switches on this, and an unknown string
|
|
480
|
-
* would land on the default anyway; dropping it gets there without pretending we understood.
|
|
481
|
-
*/
|
|
482
|
-
const rawCause = frame["cause"];
|
|
483
|
-
const cause = rawCause === "too_early" || rawCause === "counterparty_present" ||
|
|
484
|
-
rawCause === "high_stakes_evidence_required" || rawCause === "already_sealed"
|
|
485
|
-
? rawCause
|
|
486
|
-
: undefined;
|
|
487
|
-
waiter({
|
|
488
|
-
ok: false,
|
|
489
|
-
reason: "seal_unilateral_too_early",
|
|
490
|
-
...(typeof rs === "number" ? { remainingSeconds: rs } : {}),
|
|
491
|
-
...(cause !== undefined ? { cause } : {}),
|
|
492
|
-
});
|
|
493
|
-
return;
|
|
494
|
-
}
|
|
495
|
-
void (async () => {
|
|
496
|
-
const toU8 = (v) => v instanceof Uint8Array ? v : Buffer.isBuffer(v) ? new Uint8Array(v) : null;
|
|
497
|
-
const sessionId = toU8(frame["session_id"]);
|
|
498
|
-
const sealedRoot = toU8(frame["sealed_root"]);
|
|
499
|
-
const frostSig = toU8(frame["frost_signature"]);
|
|
500
|
-
const leafCount = typeof frame["leaf_count"] === "number" ? frame["leaf_count"] : null;
|
|
501
|
-
const tsRaw = frame["close_timestamp"];
|
|
502
|
-
const closeTs = typeof tsRaw === "number" ? tsRaw : typeof tsRaw === "bigint" ? Number(tsRaw) : null;
|
|
503
|
-
const sigType = frame["signature_type"];
|
|
504
|
-
if (!sessionId || !sealedRoot || !frostSig || leafCount === null || closeTs === null ||
|
|
505
|
-
(sigType !== "frost" && sigType !== "single")) {
|
|
506
|
-
logger.warn("session.unilateral.certificate.invalid", { sessionId: sidHex, reason: "malformed_certificate" });
|
|
507
|
-
pendingUnilateralWaiters.delete(sealKey(agentName, sidHex));
|
|
508
|
-
waiter({ ok: false, reason: "malformed_certificate" });
|
|
509
|
-
return;
|
|
510
|
-
}
|
|
511
|
-
const result = await verifyUnilateralCertificate({ persistence: getPersistence(agentName), agentPubkeyHex, logger }, { sessionId, sealedRoot, leafCount, closeTimestamp: closeTs, frostSignature: frostSig, signatureType: sigType });
|
|
512
|
-
pendingUnilateralWaiters.delete(sealKey(agentName, sidHex));
|
|
513
|
-
if (!result.ok) {
|
|
514
|
-
// SI-003: do NOT mark sealed when the certificate signature does not verify.
|
|
515
|
-
logger.warn("session.unilateral.certificate.invalid", { sessionId: sidHex, reason: result.reason, signatureType: sigType });
|
|
516
|
-
waiter({ ok: false, reason: `certificate_invalid:${result.reason}` });
|
|
517
|
-
return;
|
|
518
|
-
}
|
|
519
|
-
logger.info("session.unilateral.certificate.verified", { sessionId: sidHex, signatureType: sigType, party: "present" });
|
|
520
|
-
// M8B FINDING-3 (cascade-2): normalise + PERSIST the legibility certificate the directory
|
|
521
|
-
// now ships on this frame — the SAME store the bilateral session_sealed handler writes
|
|
522
|
-
// (recordSealCertificate → read back by cello_get_sealed_receipt). Without this a unilateral
|
|
523
|
-
// close returned ok+root but sealed_receipt_not_found forever: the whole point of sealing
|
|
524
|
-
// when your counterparty vanished is walking away with a DURABLE, RETRIEVABLE receipt.
|
|
525
|
-
// Persist BEFORE destroying the node (bilateral ordering) so the sessions row still exists
|
|
526
|
-
// for the UPDATE. undefined legibility (a pre-cascade-2 directory) → nothing persisted; the
|
|
527
|
-
// seal still completes — surfaced loudly so this can never masquerade as a produced receipt.
|
|
528
|
-
const rootHex = Buffer.from(sealedRoot).toString("hex");
|
|
529
|
-
const legibility = normalizeLegibility(frame["legibility"]);
|
|
530
|
-
// M8B FINDING-5 (SI-002): before persisting, INDEPENDENTLY re-derive each CLIENT-VERIFIABLE
|
|
531
|
-
// ('live', the present party) frontier from the signed frontier_leaves and OVERRIDE an inflated
|
|
532
|
-
// directory-published value DOWN to the provable one (the directory cannot forge signed leaves,
|
|
533
|
-
// so the re-derived value is truth). We OVERRIDE, never reject — the unilateral seal has a
|
|
534
|
-
// directory-side dedup guard that makes a client rejection unrecoverable (a retry close is
|
|
535
|
-
// silently ignored → no receipt ever, worse than FINDING-3; cascade-2 reviewer Critical 2). The
|
|
536
|
-
// absent party's frontier stays directory-attested (its remainder is not re-derivable here). No
|
|
537
|
-
// frontier_leaves (pre-FINDING-5 directory) → the cert stays directory-attested (FINDING-3).
|
|
538
|
-
// A receipt is ALWAYS persisted; the close never dead-ends here.
|
|
539
|
-
if (legibility !== undefined) {
|
|
540
|
-
const rawParticipants = legibility.participants ?? [];
|
|
541
|
-
const guardParticipants = rawParticipants
|
|
542
|
-
.filter((p) => typeof p.pubkey === "string" && typeof p.attestation_mode === "string")
|
|
543
|
-
.map((p) => ({
|
|
544
|
-
pubkey: p.pubkey,
|
|
545
|
-
content_frontier_seq: typeof p.content_frontier_seq === "number" ? p.content_frontier_seq : 0,
|
|
546
|
-
attestation_mode: p.attestation_mode,
|
|
547
|
-
}));
|
|
548
|
-
const frontierLeavesRaw = frame["frontier_leaves"];
|
|
549
|
-
const toU8f = (v) => (v instanceof Uint8Array ? v : new Uint8Array(v));
|
|
550
|
-
const parsedFrontierLeaves = Array.isArray(frontierLeavesRaw) && frontierLeavesRaw.length > 0
|
|
551
|
-
? frontierLeavesRaw.map((l) => {
|
|
552
|
-
const o = l;
|
|
553
|
-
return {
|
|
554
|
-
structure1_cbor: toU8f(o["structure1_cbor"]),
|
|
555
|
-
sender_pubkey: toU8f(o["sender_pubkey"]),
|
|
556
|
-
sender_signature: toU8f(o["sender_signature"]),
|
|
557
|
-
};
|
|
558
|
-
})
|
|
559
|
-
: undefined;
|
|
560
|
-
const check = checkUnilateralFrontier(guardParticipants, parsedFrontierLeaves, sessionId);
|
|
561
|
-
// Apply any frontier corrections to the object we persist — override inflated 'live'
|
|
562
|
-
// frontier(s) DOWN to the provable value, so the stored receipt never claims more than the
|
|
563
|
-
// signed leaves support. Runs for both 'corrected' (valid leaves) and 'leaves_invalid'
|
|
564
|
-
// (forged leaves → corrected to 0). Never rejects → the close never dead-ends.
|
|
565
|
-
if (check.corrections.size > 0) {
|
|
566
|
-
for (const p of rawParticipants) {
|
|
567
|
-
if (typeof p.pubkey === "string" && check.corrections.has(p.pubkey.toLowerCase())) {
|
|
568
|
-
p.content_frontier_seq = check.corrections.get(p.pubkey.toLowerCase());
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
if (check.status === "corrected") {
|
|
573
|
-
logger.error("seal.certificate.frontier.overridden", {
|
|
574
|
-
sessionId: sidHex,
|
|
575
|
-
corrections: [...check.corrections.entries()].map(([party, seq]) => ({ party, correctedTo: seq })),
|
|
576
|
-
path: "unilateral",
|
|
577
|
-
});
|
|
578
|
-
}
|
|
579
|
-
else if (check.status === "verified") {
|
|
580
|
-
logger.info("seal.certificate.frontier.verified", {
|
|
581
|
-
sessionId: sidHex,
|
|
582
|
-
parties: guardParticipants.filter((p) => p.attestation_mode === "live").length,
|
|
583
|
-
path: "unilateral",
|
|
584
|
-
});
|
|
585
|
-
}
|
|
586
|
-
else if (check.status === "leaves_invalid") {
|
|
587
|
-
// Forged / cross-session leaves — a tamper signal. The 'live' frontier(s) have been
|
|
588
|
-
// corrected to 0 above (zero trustworthy evidence); persist that (never reject → never
|
|
589
|
-
// dead-end). Surfaced loudly for audit.
|
|
590
|
-
logger.error("seal.certificate.frontier.leaves_invalid", {
|
|
591
|
-
sessionId: sidHex,
|
|
592
|
-
reason: check.reason,
|
|
593
|
-
corrections: [...check.corrections.entries()].map(([party, seq]) => ({ party, correctedTo: seq })),
|
|
594
|
-
path: "unilateral",
|
|
595
|
-
});
|
|
596
|
-
}
|
|
597
|
-
else {
|
|
598
|
-
// directory_attested: no frontier_leaves shipped (pre-FINDING-5 directory). Frontiers stay
|
|
599
|
-
// DIRECTORY-attested (already marked per-participant) — visible/auditable, never silently
|
|
600
|
-
// presented as client-verified.
|
|
601
|
-
logger.warn("seal.certificate.frontier.directory_attested", {
|
|
602
|
-
sessionId: sidHex,
|
|
603
|
-
reason: "no_frontier_leaves",
|
|
604
|
-
path: "unilateral",
|
|
605
|
-
});
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
if (legibility !== undefined) {
|
|
609
|
-
// F2: the boundary is derived from THIS daemon's signed carry, never from the certificate.
|
|
610
|
-
// Stamped AFTER the frontier corrections above so nothing downstream can reorder past it.
|
|
611
|
-
stampCountersignedBoundary({ logger, sessionNodeManager }, agentPubkeyHex, sidHex, legibility, "unilateral");
|
|
612
|
-
try {
|
|
613
|
-
sessionNodeManager.recordSealCertificate(agentName, sidHex, rootHex, JSON.stringify(legibility));
|
|
614
|
-
logger.info("session.unilateral.receipt.persisted", {
|
|
615
|
-
sessionId: sidHex,
|
|
616
|
-
sealedRoot: rootHex,
|
|
617
|
-
finalMessageAnswered: legibility && typeof legibility === "object" && "final_message" in legibility
|
|
618
|
-
? legibility.final_message?.answered
|
|
619
|
-
: undefined,
|
|
620
|
-
});
|
|
621
|
-
}
|
|
622
|
-
catch (error) {
|
|
623
|
-
logger.warn("seal.certificate.persist.failed", {
|
|
624
|
-
sessionId: sidHex,
|
|
625
|
-
reason: extractErrorMessage(error),
|
|
626
|
-
});
|
|
627
|
-
}
|
|
628
|
-
keepCertifiedLeafSet({ logger, sessionNodeManager }, agentName, sidHex, frame, rootHex, "unilateral");
|
|
629
|
-
}
|
|
630
|
-
else {
|
|
631
|
-
// The seal is valid, but no receipt is retrievable — a directory that predates cascade-2.
|
|
632
|
-
logger.warn("session.unilateral.receipt.absent", { sessionId: sidHex, reason: "no_legibility_on_frame" });
|
|
633
|
-
}
|
|
634
|
-
// THE WAITER IS ANSWERED FIRST. `markSealed` is SYNCHRONOUS and reaches `#requireAgentId`,
|
|
635
|
-
// which throws for a retired agent or a closed database — and a throw here would escape
|
|
636
|
-
// this frame, leave the waiter unresolved, and make the close sit out its full timeout and
|
|
637
|
-
// report `seal_unilateral_timeout` for a seal that COMPLETED and whose certificate is
|
|
638
|
-
// already on disk. That is the error-substitution defect this milestone was opened on,
|
|
639
|
-
// reproduced on the path that fixes it. The old line was an async `void`, whose throw
|
|
640
|
-
// became a discarded rejection and could not do this.
|
|
641
|
-
waiter({ ok: true, sealedRootHex: rootHex, legibility });
|
|
642
|
-
// STATUS THEN TEARDOWN — and on THIS path the node is gone by construction. A unilateral
|
|
643
|
-
// seal is what an interrupted session escalates to, and every producer of `interrupted`
|
|
644
|
-
// deletes the `#activeNodes` entry, so `destroySessionNode` alone would return before the
|
|
645
|
-
// status write every single time.
|
|
646
|
-
try {
|
|
647
|
-
sessionNodeManager.markSealed(agentName, sidHex);
|
|
648
|
-
}
|
|
649
|
-
catch (err) {
|
|
650
|
-
logger.error("session.seal.status.write.threw", {
|
|
651
|
-
sessionId: sidHex, agentName,
|
|
652
|
-
error: extractErrorMessage(err),
|
|
653
|
-
impact: "the seal COMPLETED and the certificate is stored, but this row still reads interrupted",
|
|
654
|
-
});
|
|
655
|
-
}
|
|
656
|
-
void sessionNodeManager.destroySessionNode(agentName, sidHex, "sealed");
|
|
657
|
-
})();
|
|
658
|
-
});
|
|
659
|
-
}
|
|
660
|
-
// ─── DOD-UP-1: returning-absent-party seal upgrade (unilateral → bilateral) ───
|
|
661
|
-
// Per-session idempotency guard so a notification burst (reconnect re-delivery) cannot launch
|
|
662
|
-
// concurrent upgrade attempts. Keyed `${agentName}:${sessionIdHex}`; cleared after each attempt.
|
|
663
|
-
const sealUpgradeInFlight = new Set();
|
|
664
|
-
/**
|
|
665
|
-
* DOD-UP-1: B (the absent party) ratifies a unilateral seal it learns about on reconnect.
|
|
666
|
-
*
|
|
667
|
-
* THE KERNEL: B signs the ratification ONLY after it has recovered + integrity-verified the
|
|
668
|
-
* content behind the sealed root. We (0) verify the unilateral cert so R1 is provably authentic
|
|
669
|
-
* (SI-003 — a channel-swapped root fails); (1) recover any parked content from the relay; (2) gate
|
|
670
|
-
* on getSealUpgradeReadiness — refuse content_unrecoverable (session unknown) or content_tamper
|
|
671
|
-
* (cross-check mismatch, AC-003); only then (3) sign the ack over R1 with B's OWN K_local and send
|
|
672
|
-
* seal_upgrade_request. B never co-signs content it could not verify.
|
|
673
|
-
*/
|
|
674
|
-
// Thin wrapper over the extracted, unit-tested seal-upgrade.ts module (the KERNEL + AC-008 + H1/M1
|
|
675
|
-
// hardening live there so the refusal/reject bodies run under adversarial tests). This wrapper owns
|
|
676
|
-
// only the per-session in-flight guard and the real-dep injection.
|
|
677
|
-
async function attemptSealUpgrade(signaling, agentName, agentPubkeyHex, sidHex, frame) {
|
|
678
|
-
const key = `${agentName}:${sidHex}`;
|
|
679
|
-
if (sealUpgradeInFlight.has(key))
|
|
680
|
-
return;
|
|
681
|
-
sealUpgradeInFlight.add(key);
|
|
682
|
-
try {
|
|
683
|
-
const result = await attemptSealUpgradeImpl({
|
|
684
|
-
logger, agentName, agentPubkeyHex,
|
|
685
|
-
getReadiness: (a, s) => sessionNodeManager.getSealUpgradeReadiness(a, s),
|
|
686
|
-
getContentLeafCount: (a, s) => sessionNodeManager.getSessionTree(a, s).size(),
|
|
687
|
-
recoverContent: (a) => recoverContent(a),
|
|
688
|
-
getKeyProvider: (a) => getKeyProvider(a),
|
|
689
|
-
sendRaw: (f) => signaling.sendRaw(f),
|
|
690
|
-
}, sidHex, frame);
|
|
691
|
-
// M8B FINDING-6 (3b): the ABSENT party (B) persists its UNILATERAL receipt from the
|
|
692
|
-
// notification's legibility — but ONLY after the KERNEL content-recovery/verify gate passed.
|
|
693
|
-
// `result.sent` is true iff attemptSealUpgradeImpl recovered + integrity-verified the content
|
|
694
|
-
// behind R1 and sent the ratification request; a tampered/unrecoverable/incomplete case returns
|
|
695
|
-
// sent:false → NO receipt (never a receipt for content B could not verify). B may hold no local
|
|
696
|
-
// `sessions` row (recordSealCertificateEnsuringRow inserts a stub, counterparty = A's pubkey).
|
|
697
|
-
// The notification carries no frontier_leaves (FINDING-5 ships those only on the present party's
|
|
698
|
-
// confirm frame), so B's legibility is directory-attested — consistent with FINDING-5's
|
|
699
|
-
// directory_attested path; B trusts its own KERNEL-verified content, not a re-derivation.
|
|
700
|
-
if (result.sent) {
|
|
701
|
-
try {
|
|
702
|
-
// ONE-WAY RATCHET (cascade-2 FINDING-6 review): a re-delivered seal_unilateral_notification
|
|
703
|
-
// (reconnect burst) re-runs this path and would re-persist the notification's ORIGINAL
|
|
704
|
-
// legibility (counterparty 'absent'). If a prior upgrade already flipped the stored receipt
|
|
705
|
-
// to 'recovered' (no 'absent' participant), re-persisting would REGRESS it — and no later
|
|
706
|
-
// event restores 'recovered' (the directory dedups the duplicate as already_bilateral →
|
|
707
|
-
// seal_upgrade_rejected, which only logs). So skip the re-persist once the cert is upgraded.
|
|
708
|
-
const existing = sessionNodeManager.getSealCertificate(agentName, sidHex);
|
|
709
|
-
if (existing && !hasAbsentParticipant(existing.legibility)) {
|
|
710
|
-
logger.debug("session.unilateral.receipt.persist.skipped", { sessionId: sidHex, reason: "already_upgraded" });
|
|
711
|
-
}
|
|
712
|
-
else {
|
|
713
|
-
const legibility = normalizeLegibility(frame["legibility"]);
|
|
714
|
-
const rootHex = frameValueToHex(frame["sealed_root"]);
|
|
715
|
-
const counterpartyHex = frameValueToHex(frame["present_pubkey"]); // A — the present party
|
|
716
|
-
if (legibility !== undefined && rootHex && counterpartyHex) {
|
|
717
|
-
// F2: derived locally here too. This is the ABSENT party persisting its own copy, and
|
|
718
|
-
// it holds the same leaves — so it can answer the boundary for itself rather than
|
|
719
|
-
// inheriting the number from the notification it was sent.
|
|
720
|
-
stampCountersignedBoundary({ logger, sessionNodeManager }, agentPubkeyHex, sidHex, legibility, "unilateral_notification");
|
|
721
|
-
sessionNodeManager.recordSealCertificateEnsuringRow(agentName, sidHex, counterpartyHex, rootHex, JSON.stringify(legibility));
|
|
722
|
-
logger.info("session.unilateral.receipt.persisted", { sessionId: sidHex, sealedRoot: rootHex, party: "absent" });
|
|
723
|
-
keepCertifiedLeafSet({ logger, sessionNodeManager }, agentName, sidHex, frame, rootHex, "unilateral_notification");
|
|
724
|
-
}
|
|
725
|
-
else if (legibility === undefined) {
|
|
726
|
-
logger.warn("session.unilateral.receipt.absent", { sessionId: sidHex, reason: "no_legibility_on_notification" });
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
|
-
}
|
|
730
|
-
catch (error) {
|
|
731
|
-
logger.warn("seal.certificate.persist.failed", { sessionId: sidHex, reason: extractErrorMessage(error) });
|
|
732
|
-
}
|
|
733
|
-
}
|
|
734
|
-
}
|
|
735
|
-
finally {
|
|
736
|
-
// Clear the guard so a later reconnect can retry if the request never reached the directory;
|
|
737
|
-
// the directory dedups a repeat with already_bilateral.
|
|
738
|
-
sealUpgradeInFlight.delete(key);
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
// Thin wrapper: verify the dual-attestation cert (module, AC-008 + H1), then APPLY — mark bilateral
|
|
742
|
-
// ONLY on ok. Never trust the directory's "bilateral" claim.
|
|
743
|
-
async function verifyAndApplyUpgradeConfirmed(agentName, agentPubkeyHex, sidHex, frame) {
|
|
744
|
-
const result = await verifyUpgradeConfirmedCert({
|
|
745
|
-
logger, agentName, agentPubkeyHex, persistence: getPersistence(agentName),
|
|
746
|
-
getCounterpartyHex: (a, s) => sessionNodeManager.getSessionRecord(a, s)?.counterparty_pubkey ?? null,
|
|
747
|
-
}, sidHex, frame);
|
|
748
|
-
if (!result.ok)
|
|
749
|
-
return; // cert.invalid already logged inside; do NOT accept as bilateral.
|
|
750
|
-
logger.info("session.seal.upgraded", { sessionId: sidHex, agentName, party: result.party });
|
|
751
|
-
// M8B FINDING-6 (3a): the seal is now BILATERAL (verified) — upgrade THIS party's own stored
|
|
752
|
-
// receipt so the counterparty recorded 'absent' becomes 'recovered'. Client-side: the directory
|
|
753
|
-
// ships no bilateral legibility at upgrade time (the seal leaves aren't persisted there), so each
|
|
754
|
-
// party rebuilds from the cert it already holds — the present party's from its unilateral close
|
|
755
|
-
// (FINDING-3), the returning party's from the notification it persisted after the KERNEL gate
|
|
756
|
-
// (3b). The seal signatures do not bind the (unsigned) legibility, so mutating it is sound; only
|
|
757
|
-
// the attestation flips (frontiers unchanged — never overstated). No-op if no cert is stored yet.
|
|
758
|
-
const stored = sessionNodeManager.getSealCertificate(agentName, sidHex);
|
|
759
|
-
if (stored) {
|
|
760
|
-
try {
|
|
761
|
-
const upgraded = upgradeAbsentToRecovered(stored.legibility);
|
|
762
|
-
sessionNodeManager.recordSealCertificate(agentName, sidHex, stored.sealed_root, JSON.stringify(upgraded));
|
|
763
|
-
logger.info("session.seal.receipt.upgraded", { sessionId: sidHex, agentName, party: result.party });
|
|
764
|
-
}
|
|
765
|
-
catch (error) {
|
|
766
|
-
logger.warn("seal.certificate.persist.failed", { sessionId: sidHex, reason: extractErrorMessage(error) });
|
|
767
|
-
}
|
|
768
|
-
}
|
|
769
|
-
// STATUS FIRST — same reason as the two sites above.
|
|
770
|
-
try {
|
|
771
|
-
sessionNodeManager.markSealed(agentName, sidHex);
|
|
772
|
-
}
|
|
773
|
-
catch (err) {
|
|
774
|
-
logger.error("session.seal.status.write.threw", {
|
|
775
|
-
sessionId: sidHex, agentName,
|
|
776
|
-
error: extractErrorMessage(err),
|
|
777
|
-
impact: "the seal COMPLETED and the certificate is stored, but this row still reads interrupted",
|
|
778
|
-
});
|
|
779
|
-
}
|
|
780
|
-
void sessionNodeManager.destroySessionNode(agentName, sidHex, "sealed");
|
|
781
|
-
}
|
|
782
|
-
/**
|
|
783
|
-
* DOD-UP-1: per-agent listener for the absent-party seal upgrade. On reconnect the directory
|
|
784
|
-
* delivers a queued seal_unilateral_notification to B (the absent party) — that triggers the
|
|
785
|
-
* ratification attempt. The directory's seal_upgrade_confirmed / seal_upgrade_rejected responses
|
|
786
|
-
* are observed here too (B marks the session bilaterally sealed / logs the refusal).
|
|
787
|
-
*/
|
|
788
|
-
function registerUnilateralUpgradeListener(signaling, agentName, agentPubkeyHex) {
|
|
789
|
-
return signaling.registerInboundHandler((frame) => {
|
|
790
|
-
const ftype = frame["type"];
|
|
791
|
-
if (ftype === "seal_upgrade_confirmed") {
|
|
792
|
-
const sidHex = frameValueToHex(frame["session_id"]);
|
|
793
|
-
if (!sidHex)
|
|
794
|
-
return;
|
|
795
|
-
// AC-008: do NOT accept "bilateral" on the directory's word — verify the dual attestation.
|
|
796
|
-
void verifyAndApplyUpgradeConfirmed(agentName, agentPubkeyHex, sidHex, frame);
|
|
797
|
-
return;
|
|
798
|
-
}
|
|
799
|
-
if (ftype === "seal_upgrade_rejected") {
|
|
800
|
-
const sidHex = frameValueToHex(frame["session_id"]);
|
|
801
|
-
if (!sidHex)
|
|
802
|
-
return;
|
|
803
|
-
logger.warn("session.seal.upgrade.rejected", { sessionId: sidHex, agentName, reason: frame["reason"] });
|
|
804
|
-
return;
|
|
805
|
-
}
|
|
806
|
-
if (ftype !== "seal_unilateral_notification")
|
|
807
|
-
return;
|
|
808
|
-
const sidHex = frameValueToHex(frame["session_id"]);
|
|
809
|
-
if (!sidHex)
|
|
810
|
-
return;
|
|
811
|
-
// Only the ABSENT party receives this frame — B reacts by attempting the ratification.
|
|
812
|
-
void attemptSealUpgrade(signaling, agentName, agentPubkeyHex, sidHex, frame);
|
|
813
|
-
});
|
|
814
|
-
}
|
|
815
|
-
/**
|
|
816
|
-
* Wire the WHOLE seal listener set onto an authenticated signaling stream.
|
|
817
|
-
*
|
|
818
|
-
* A BUNDLE, deliberately — the three listeners are NOT exported individually, because being able
|
|
819
|
-
* to register two of the three is what caused the bug this replaced. The daemon's VISITING stream
|
|
820
|
-
* registered `session_sealed` + `seal_unilateral_confirmed` but not the upgrade listener, and that
|
|
821
|
-
* looked intentional. It was not: the directory drains its DURABLE notification queue on any
|
|
822
|
-
* stream that authenticates — visiting included — and DELETES each row once sent. So a
|
|
823
|
-
* `seal_unilateral_notification` pushed down a visiting stream hit no handler, was dropped, and
|
|
824
|
-
* its durable row was gone. The absent party never ratified, and the seal stayed unilateral
|
|
825
|
-
* forever: silent, permanent loss of a notarized receipt.
|
|
826
|
-
*
|
|
827
|
-
* Every stream that can carry a seal frame gets every seal listener. Making the partial case
|
|
828
|
-
* impossible to express is the fix; a comment asking future callers to remember all three is not.
|
|
829
|
-
*
|
|
830
|
-
* Safe to call on any stream, including transient ones: `attemptSealUpgrade` holds a per-session
|
|
831
|
-
* in-flight guard, the receipt persist is behind the one-way ratchet, and the directory dedups a
|
|
832
|
-
* repeated ratification with `already_bilateral`.
|
|
833
|
-
*/
|
|
834
|
-
/**
|
|
835
|
-
* THE DIRECTORY REFUSED THE SEAL, AND UNTIL NOW NOBODY IN THIS CLIENT WAS LISTENING —
|
|
836
|
-
* `DOD-M15-SEALPARTIES-1`, clause 6.
|
|
837
|
-
*
|
|
838
|
-
* `session_seal_rejected` is a frame the directory has sent since M1. Searching this repository
|
|
839
|
-
* for it found exactly one occurrence: the type declaration in `protocol-types`. It had **no
|
|
840
|
-
* consumer**. So every refusal — a stranger's leaf in the record, a relay that dropped a message,
|
|
841
|
-
* and now a counterparty who approved nothing — arrived, was decoded, matched no handler, and was
|
|
842
|
-
* dropped. Both operators then sat out the full close window and were told the counterparty had
|
|
843
|
-
* not closed, about a seal the directory had already decided against.
|
|
844
|
-
*
|
|
845
|
-
* That is the difference this makes to a person: the answer arrives in seconds and says what
|
|
846
|
-
* actually happened, instead of eleven minutes later saying something false.
|
|
847
|
-
*
|
|
848
|
-
* ⚠️ **Guarded on holding the session.** The directory still BROADCASTS this frame to every
|
|
849
|
-
* authenticated stream on the node for the refusal paths that fire before it has resolved the
|
|
850
|
-
* roster, so an agent with no part in the conversation can receive one. Acting on it would let a
|
|
851
|
-
* stranger's session id write a phantom failure into this agent's record.
|
|
852
|
-
*/
|
|
853
|
-
function registerSealRejectedListener(signaling, agentName) {
|
|
854
|
-
return signaling.registerInboundHandler((frame) => {
|
|
855
|
-
if (frame["type"] !== "session_seal_rejected")
|
|
856
|
-
return;
|
|
857
|
-
const sidHex = frameValueToHex(frame["session_id"]);
|
|
858
|
-
if (!sidHex)
|
|
859
|
-
return;
|
|
860
|
-
if (!sessionNodeManager.getSessionRecord(agentName, sidHex)) {
|
|
861
|
-
/**
|
|
862
|
-
* Not silent — fallback hunt, finding 6. The guard is right (the directory still broadcasts
|
|
863
|
-
* this frame on the paths that refuse before it resolves the roster), but a LEGITIMATE
|
|
864
|
-
* refusal can also land here: a record purged before a queued refusal drained. Dropping it
|
|
865
|
-
* with no trace at any level leaves the operator nothing on either surface.
|
|
866
|
-
*/
|
|
867
|
-
logger.debug("session.seal.rejected.not_ours", {
|
|
868
|
-
agentName,
|
|
869
|
-
sessionId: sidHex,
|
|
870
|
-
impact: "this agent holds no record for that session, so the refusal was not acted on. " +
|
|
871
|
-
"Expected for a broadcast refusal about someone else's conversation; unexpected if this " +
|
|
872
|
-
"agent did close that session.",
|
|
873
|
-
});
|
|
874
|
-
return;
|
|
875
|
-
}
|
|
876
|
-
const reason = typeof frame["reason"] === "string" && frame["reason"].length > 0
|
|
877
|
-
? frame["reason"]
|
|
878
|
-
: "seal_rejected_unstated";
|
|
879
|
-
const detail = typeof frame["detail"] === "string" ? frame["detail"] : "";
|
|
880
|
-
const guidance = sealRejectionGuidance(reason, detail);
|
|
881
|
-
// The durable forensic record keeps its half; the response below is the control. Never one
|
|
882
|
-
// instead of the other.
|
|
883
|
-
logger.error("session.seal.rejected", {
|
|
884
|
-
agentName,
|
|
885
|
-
sessionId: sidHex,
|
|
886
|
-
reason,
|
|
887
|
-
detail,
|
|
888
|
-
impact: "the directory refused to certify this seal, so no signature over it exists and the " +
|
|
889
|
-
"session is NOT sealed. The transcript is untouched and nothing was signed with this " +
|
|
890
|
-
"agent's key.",
|
|
891
|
-
guidance,
|
|
892
|
-
});
|
|
893
|
-
// Clause 6's second surface: the response is gone once its caller reads it, and a close that
|
|
894
|
-
// has already returned (or never ran on this side) has nowhere else to leave the answer.
|
|
895
|
-
// `"refused"` — a VERDICT, not a symptom (`DOD-M15-SEALREFUSED-STUCK-1`). It is terminal in
|
|
896
|
-
// the store, so the escalation's later `seal_unilateral_timeout` cannot overwrite it and tell
|
|
897
|
-
// both operators their counterparty never closed.
|
|
898
|
-
recordSealFailure(agentName, sidHex, reason, "refused");
|
|
899
|
-
const key = sealKey(agentName, sidHex);
|
|
900
|
-
const waiter = pendingSealWaiters.get(key);
|
|
901
|
-
if (!waiter)
|
|
902
|
-
return;
|
|
903
|
-
pendingSealWaiters.delete(key);
|
|
904
|
-
waiter({ refused: true, reason, detail, ownRootHex: null, guidance, source: "directory" });
|
|
905
|
-
});
|
|
906
|
-
}
|
|
907
|
-
function registerSealListeners(signaling, agentName, agentPubkeyHex) {
|
|
908
|
-
const unregisterSealed = registerSessionSealedListener(signaling, agentName, agentPubkeyHex);
|
|
909
|
-
const unregisterRejected = registerSealRejectedListener(signaling, agentName);
|
|
910
|
-
const unregisterUnilateral = registerUnilateralConfirmedListener(signaling, agentName, agentPubkeyHex);
|
|
911
|
-
const unregisterUpgrade = registerUnilateralUpgradeListener(signaling, agentName, agentPubkeyHex);
|
|
912
|
-
return () => {
|
|
913
|
-
unregisterSealed();
|
|
914
|
-
unregisterRejected();
|
|
915
|
-
unregisterUnilateral();
|
|
916
|
-
unregisterUpgrade();
|
|
917
|
-
};
|
|
918
|
-
}
|
|
919
|
-
return {
|
|
920
|
-
sealKey,
|
|
921
|
-
sealInterruptedInProgress,
|
|
922
|
-
pendingSealWaiters,
|
|
923
|
-
pendingUnilateralWaiters,
|
|
924
|
-
registerSealListeners,
|
|
925
|
-
};
|
|
926
|
-
}
|
|
927
|
-
//# sourceMappingURL=seal-coordinator.js.map
|