@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/inbound-refusals.js
DELETED
|
@@ -1,919 +0,0 @@
|
|
|
1
|
-
import { REFUSAL_KINDS } from "./refusal-reasons.js";
|
|
2
|
-
import { TIER, normalizeTier } from "./contacts-tier-migration.js";
|
|
3
|
-
import { extractErrorMessage } from "./error-message.js";
|
|
4
|
-
import { normalizeContactPubkey } from "./contact-pubkey-case.js";
|
|
5
|
-
import { decodeStructure1 } from "@cello-protocol/protocol-types";
|
|
6
|
-
import { decode } from "cbor-x";
|
|
7
|
-
import { TERMINAL_REFUSAL_REASONS, TERMINAL_REFUSAL_READ_RETRY_MS, MAX_TERMINAL_REFUSALS_PER_SESSION, MAX_UNREADABLE_ALG_FRAMES, ACK_HASH_REASONS, AUTHORSHIP_SELF_CHAIN_MISMATCH, AUTHORSHIP_ACK_HASH_MISMATCH, AUTHORSHIP_ACK_HASH_UNKNOWN, AUTHORSHIP_CONTENT_HASH_MISMATCH, AUTHORSHIP_SESSION_MISMATCH, REFUSAL_MAY_STILL_ARRIVE, REFUSAL_NO_OTHER_ROUTE, } from "./session-node-types.js";
|
|
8
|
-
export class InboundRefusals {
|
|
9
|
-
#ctx;
|
|
10
|
-
constructor(ctx) {
|
|
11
|
-
this.#ctx = ctx;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* ⚠️ A GETTER SO THE MOVED CODE IS UNCHANGED. Every query below still reads `this.#db` and still
|
|
15
|
-
* narrows through `if (!this.#db) throw ...`, exactly as it did inside the manager. Rewriting
|
|
16
|
-
* those to a call would have been a diff on every database access in this file for no behavioural
|
|
17
|
-
* reason, and the narrowing would have had to become a null assertion — turning checked accesses
|
|
18
|
-
* into unchecked ones at precisely the sites that do the checking.
|
|
19
|
-
*/
|
|
20
|
-
get #db() {
|
|
21
|
-
return this.#ctx.db();
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Frames refused because they named a content-hash algorithm this build cannot read, keyed by
|
|
25
|
-
* session → the refused frame's content hash → the name it used. Review F2, corrected by F-D.
|
|
26
|
-
*
|
|
27
|
-
* ⚠️ KEYED BY THE FRAME, NOT THE SESSION, and the first version was keyed by the session. That
|
|
28
|
-
* made it fire on the NORMAL case: after one junk-alg frame, every subsequent park recovery on
|
|
29
|
-
* that session logged a WARN forever, for entirely unrelated messages — and the text asserted the
|
|
30
|
-
* two events were "the same message arriving twice by different routes", which nothing had
|
|
31
|
-
* established. A warning that fires on the benign steady state is not a signal.
|
|
32
|
-
*
|
|
33
|
-
* Hash-keyed, the claim becomes a fact and the event fires exactly once per affected message: the
|
|
34
|
-
* entry is removed the moment it is reconciled.
|
|
35
|
-
*/
|
|
36
|
-
#unreadableAlgSeen = new Map();
|
|
37
|
-
/**
|
|
38
|
-
* `DOD-M15-AUTHORSHIP-ABSENT-1` review H1, widened by `029c` review F4 — the content hashes this
|
|
39
|
-
* side refused ON THE DIRECT PATH, for any reason, so the park path can say so when the same
|
|
40
|
-
* message arrives the other way.
|
|
41
|
-
*
|
|
42
|
-
* One map rather than one per refusal: what the park path needs to know is "did we turn this
|
|
43
|
-
* content away and tell somebody so", and the reason is already on the notice.
|
|
44
|
-
*
|
|
45
|
-
* **The silence this closes.** A direct-path refusal sends no delivery ACK, so the sender's TTF
|
|
46
|
-
* backstop parks the message and it arrives through the relay mailbox seconds later — where the
|
|
47
|
-
* ENVELOPE's signature is what authenticates it, and recovery correctly accepts it. So the
|
|
48
|
-
* message is delivered, with no per-message proof, moments after the operator was told it was
|
|
49
|
-
* refused. Nothing tied the two events together, which is the same shape the algorithm refusal
|
|
50
|
-
* above already had and the same remedy.
|
|
51
|
-
*
|
|
52
|
-
* Same bounded shape and the same reason: it is fed entirely by a remote party, so losing an
|
|
53
|
-
* entry costs one reconciliation line and an unbounded map would be a leak with a peer's hand on
|
|
54
|
-
* the tap.
|
|
55
|
-
*/
|
|
56
|
-
#refusedOnDirectPath = new Map();
|
|
57
|
-
/**
|
|
58
|
-
* DOD-M15-REFUSALTERMINAL-1: content hashes refused for a reason no retry can get past — a READ
|
|
59
|
-
* CACHE over `terminal_content_refusals`, never the record itself.
|
|
60
|
-
*
|
|
61
|
-
* ⚠️ **NOT the same fact as `#resolvedContent`, and collapsing them is the trap.** "Resolved"
|
|
62
|
-
* means we HAVE the content. Terminally refused means we have it and are never accepting it.
|
|
63
|
-
* Filing one under the other tells the next reader that refused content was delivered.
|
|
64
|
-
*/
|
|
65
|
-
#terminallyRefused = new Map();
|
|
66
|
-
/** DOD-M15-REFUSALTERMINAL-1 review F3: when the load above last FAILED, per session. Bounds the
|
|
67
|
-
* retry and the ERROR to once a minute instead of once per witnessed leaf. */
|
|
68
|
-
#terminalRefusalsReadFailedAt = new Map();
|
|
69
|
-
/** Sessions whose terminal-refusal rows have been read from the database into the map above.
|
|
70
|
-
* Nothing ever un-marks content, so a loaded set only grows and can never go stale. */
|
|
71
|
-
#terminalRefusalsLoaded = new Set();
|
|
72
|
-
/**
|
|
73
|
-
* DOD-M15-REFUSEDEVIDENCE-1 — RETAIN a message that was refused. Retention is universal; DELIVERY
|
|
74
|
-
* is what is withheld.
|
|
75
|
-
*
|
|
76
|
-
* Every refusal path that can store calls this. It writes the plaintext, the sender's key, the
|
|
77
|
-
* sender's signature and the refusal reason into the transcript, flagged `'quarantined'` so it is
|
|
78
|
-
* excluded by construction from delivery and from unread counts.
|
|
79
|
-
*
|
|
80
|
-
* ⚠️ STORING HOSTILE CONTENT IS SAFE; INTERPOLATING IT IS NOT. The blob is a bound parameter and
|
|
81
|
-
* the database never parses it — SQL injection is not the risk here and must not be defended
|
|
82
|
-
* against. The risk is on the way OUT, so nothing below puts `content` into a log line, an error
|
|
83
|
-
* message or a path. The log carries the length and the hash.
|
|
84
|
-
*
|
|
85
|
-
* Returns the sequence it was stored at, or `null` when it was not stored — which happens only for
|
|
86
|
-
* a reason the caller is expected to log.
|
|
87
|
-
*/
|
|
88
|
-
quarantineRefusedContent(agentName, sessionId, reason, content, contentHashHex, opts) {
|
|
89
|
-
const sequence = this.retainRefusedContent(agentName, sessionId, reason, content, contentHashHex, opts);
|
|
90
|
-
/**
|
|
91
|
-
* DOD-M15-REFUSALTERMINAL-1 — **THE FUNNEL, and the reason it lives here.**
|
|
92
|
-
*
|
|
93
|
-
* Every refusal that retains evidence passes through this method carrying its reason and its
|
|
94
|
-
* content hash, so this is the one place where "which reasons stop the work" can be a LIST
|
|
95
|
-
* rather than a decision copied into seven branches. `TERMINAL_REFUSAL_REASONS` decides; the
|
|
96
|
-
* six other reasons that reach here — a hash mismatch, an unreadable algorithm, a missing salt,
|
|
97
|
-
* an unresolved sender, an orphaned session, a terminal screen block — all keep retrying, and
|
|
98
|
-
* each of them can succeed on a later attempt.
|
|
99
|
-
*
|
|
100
|
-
* AFTER the retention, deliberately: the evidence has to exist before anything stops going to
|
|
101
|
-
* look for the message.
|
|
102
|
-
*/
|
|
103
|
-
this.considerTerminalRefusal(agentName, sessionId, contentHashHex, reason);
|
|
104
|
-
return sequence;
|
|
105
|
-
}
|
|
106
|
-
/** DOD-M15-REFUSEDEVIDENCE-1: the retention itself. Reached only through the funnel above. */
|
|
107
|
-
retainRefusedContent(agentName, sessionId, reason, content, contentHashHex, opts) {
|
|
108
|
-
if (!this.#db)
|
|
109
|
-
return null;
|
|
110
|
-
try {
|
|
111
|
-
const agentId = this.#ctx.requireAgentId(agentName);
|
|
112
|
-
/**
|
|
113
|
-
* ⚠️ **DEDUP FIRST — review F1, and without it retention KILLS THE CONVERSATION IT PROTECTS.**
|
|
114
|
-
*
|
|
115
|
-
* Six of the seven retaining exits refuse WITHOUT ACKNOWLEDGING, which is exactly what makes
|
|
116
|
-
* the sender's daemon redeliver. Each redelivery re-enters here, above the leaf dedup, and
|
|
117
|
-
* would take a fresh negative sequence — another full copy of the same bytes. The park drain's
|
|
118
|
-
* own comment measures that loop at *"~120 repeats per message, forever"*.
|
|
119
|
-
*
|
|
120
|
-
* **And retained bytes spend the delivery budget** (`#getReceivedBytesTotal` counts them, which
|
|
121
|
-
* is what makes the bound honest). So a counterparty on a newer build sends ONE message, the
|
|
122
|
-
* version skew refuses it un-acked, and twenty-five drains later the conversation's 25 MB is
|
|
123
|
-
* gone — permanently, because the cap does not reset. Honest traffic then hits
|
|
124
|
-
* `session_size_limit_exceeded` and the daemon tells the operator to start a new conversation.
|
|
125
|
-
*
|
|
126
|
-
* The counterbalance, stated properly this time: **evidence and delivery share one monotonic
|
|
127
|
-
* budget, and when evidence wins the conversation stops working.** Entry 69 claimed there was
|
|
128
|
-
* nothing to trade off, and this is what that claim was hiding.
|
|
129
|
-
*
|
|
130
|
-
* Keyed on (session, reason, bytes) rather than a hash column: SQLite compares BLOBs directly
|
|
131
|
-
* and short-circuits on length, the candidate set is one session's refusals, and it needs no
|
|
132
|
-
* schema change. Same bytes refused the same way is ONE piece of evidence — how many times it
|
|
133
|
-
* arrived is already counted by the refusal notice. The same bytes refused for a DIFFERENT
|
|
134
|
-
* reason is a different fact and keeps its own row.
|
|
135
|
-
*/
|
|
136
|
-
const already = this.#db
|
|
137
|
-
.prepare(`SELECT sequence FROM transcript
|
|
138
|
-
WHERE agent_id = ? AND session_id = ? AND direction = 'quarantined'
|
|
139
|
-
AND quarantine_reason = ? AND blob = ?`)
|
|
140
|
-
.get(agentId, sessionId, reason, Buffer.from(content));
|
|
141
|
-
if (already) {
|
|
142
|
-
this.#ctx.logger.debug("session.content.quarantine.duplicate", {
|
|
143
|
-
agentName, sessionId, reason, sequence: already.sequence,
|
|
144
|
-
contentHash: contentHashHex, correlationId: opts.correlationId,
|
|
145
|
-
});
|
|
146
|
-
return already.sequence;
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* THE BOUND. A session at its byte cap retains no more.
|
|
150
|
-
*
|
|
151
|
-
* `senderPubkeyHex` is absent exactly when there is no session row or no counterparty
|
|
152
|
-
* (`session_orphaned`, `sender_unresolved`), so there is no contact to look a tier up on. Those
|
|
153
|
-
* take the UNKNOWN tier — the tightest bound, and the right one for a sender we cannot name.
|
|
154
|
-
*/
|
|
155
|
-
const tier = opts.senderPubkeyHex ? this.#ctx.getTier(agentName, opts.senderPubkeyHex) : TIER.UNKNOWN;
|
|
156
|
-
const cap = this.#ctx.resolveTierBound(agentName, tier, "max_bytes");
|
|
157
|
-
const prior = this.#ctx.receivedBytesTotal(agentName, sessionId);
|
|
158
|
-
if (prior + content.length > cap) {
|
|
159
|
-
this.#ctx.logger.warn("session.content.quarantine.skipped", {
|
|
160
|
-
agentName, sessionId, reason, contentHash: contentHashHex,
|
|
161
|
-
bytes: content.length, prior, cap, tier,
|
|
162
|
-
correlationId: opts.correlationId,
|
|
163
|
-
skipped: "byte_budget_exhausted",
|
|
164
|
-
impact: "this refused message was NOT retained: the conversation has already spent its storage budget, so there is no evidence of it beyond this line and the refusal notice.",
|
|
165
|
-
});
|
|
166
|
-
return null;
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* WHERE IT SITS.
|
|
170
|
-
*
|
|
171
|
-
* A screener block already leafed at its canonical position, and the quarantine row takes that
|
|
172
|
-
* same sequence so the leaf and the evidence describe one event — DoD 7's leaf index is
|
|
173
|
-
* untouched by this unit.
|
|
174
|
-
*
|
|
175
|
-
* A refusal with NO leaf takes the next NEGATIVE sequence for the session. A leaf position is
|
|
176
|
-
* never negative, so the two spaces cannot collide, and descending from −1 means two refusals
|
|
177
|
-
* cannot overwrite each other. This is what lets `session_orphaned` — a session id with no
|
|
178
|
-
* `sessions` row at all — live in the same table as everything else, which is the whole point
|
|
179
|
-
* of one store rather than two.
|
|
180
|
-
*/
|
|
181
|
-
let sequence = opts.canonicalSeq;
|
|
182
|
-
if (sequence === undefined || sequence < 0) {
|
|
183
|
-
const low = this.#db
|
|
184
|
-
.prepare("SELECT MIN(sequence) AS lo FROM transcript WHERE agent_id = ? AND session_id = ? AND direction = 'quarantined'")
|
|
185
|
-
.get(agentId, sessionId);
|
|
186
|
-
sequence = Math.min(low.lo ?? 0, 0) - 1;
|
|
187
|
-
}
|
|
188
|
-
const stored = this.#ctx.recordTranscriptMessage(agentName, sessionId, sequence, "quarantined", content, opts.correlationId, opts.authorship, reason, opts.senderPubkeyHex ?? null);
|
|
189
|
-
if (!stored)
|
|
190
|
-
return null;
|
|
191
|
-
this.#ctx.logger.info("session.content.quarantined", {
|
|
192
|
-
agentName, sessionId, reason, sequence,
|
|
193
|
-
contentHash: contentHashHex, bytes: content.length,
|
|
194
|
-
signature: opts.authorship ? "verified" : "none",
|
|
195
|
-
correlationId: opts.correlationId,
|
|
196
|
-
});
|
|
197
|
-
return sequence;
|
|
198
|
-
}
|
|
199
|
-
catch (err) {
|
|
200
|
-
this.#ctx.logger.error("session.content.quarantine.failed", {
|
|
201
|
-
agentName, sessionId, reason, contentHash: contentHashHex,
|
|
202
|
-
error: extractErrorMessage(err),
|
|
203
|
-
impact: "a refused message could not be retained, so nothing holds a copy of it — it cannot be shown to anyone or reported.",
|
|
204
|
-
});
|
|
205
|
-
return null;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
/**
|
|
209
|
-
* DOD-M15-REFUSALTERMINAL-1 — the funnel. A refusal stops the work ONLY if its reason is in
|
|
210
|
-
* `TERMINAL_REFUSAL_REASONS`; every other reason keeps retrying, which is what makes a transient
|
|
211
|
-
* screener block or a version skew recoverable.
|
|
212
|
-
*
|
|
213
|
-
* One place decides, so "is this reason terminal?" is answerable from the set rather than from
|
|
214
|
-
* thirteen call sites.
|
|
215
|
-
*/
|
|
216
|
-
considerTerminalRefusal(agentName, sessionId, contentHashHex, reason) {
|
|
217
|
-
if (!TERMINAL_REFUSAL_REASONS.has(reason))
|
|
218
|
-
return;
|
|
219
|
-
this.markContentTerminallyRefused(agentName, sessionId, contentHashHex, reason);
|
|
220
|
-
}
|
|
221
|
-
/**
|
|
222
|
-
* DOD-M15-REFUSALTERMINAL-1: this content can NEVER be accepted on this session — cancel the
|
|
223
|
-
* pending fetch and make sure no future one is scheduled, across restarts.
|
|
224
|
-
*
|
|
225
|
-
* The durable write comes FIRST and the in-memory cache second, so a process that dies between
|
|
226
|
-
* them wakes up with the stop still in force. A failed write is announced at ERROR and the
|
|
227
|
-
* in-memory mark is still taken: the loop stops for the life of THIS process, and the log says
|
|
228
|
-
* plainly that it will resume after a restart. That is a degraded stop, not a silent one.
|
|
229
|
-
*/
|
|
230
|
-
markContentTerminallyRefused(agentName, sessionId, contentHashHex, reason) {
|
|
231
|
-
const key = this.#ctx.sessionKey(agentName, sessionId);
|
|
232
|
-
/**
|
|
233
|
-
* Read BEFORE the write, so the announcement below fires on the TRANSITION rather than on every
|
|
234
|
-
* re-refusal. The same message can be refused again by a drain triggered for another reason, and
|
|
235
|
-
* an INFO line per repeat is a smaller version of the noise this unit exists to remove.
|
|
236
|
-
*
|
|
237
|
-
* The durable write is still ATTEMPTED every time, deliberately: `INSERT OR IGNORE` costs
|
|
238
|
-
* nothing when the row is already there, and skipping it would mean a write that failed once —
|
|
239
|
-
* the branch that logs the error below — never got another chance to succeed.
|
|
240
|
-
*/
|
|
241
|
-
const alreadyKnown = this.isTerminallyRefused(agentName, sessionId, contentHashHex);
|
|
242
|
-
try {
|
|
243
|
-
if (!this.#db)
|
|
244
|
-
throw new Error("database is not open");
|
|
245
|
-
const agentId = this.#ctx.requireAgentId(agentName);
|
|
246
|
-
this.#db
|
|
247
|
-
.prepare(`INSERT OR IGNORE INTO terminal_content_refusals
|
|
248
|
-
(agent_id, session_id, content_hash, reason, marked_at)
|
|
249
|
-
VALUES (?, ?, ?, ?, ?)`)
|
|
250
|
-
.run(agentId, sessionId, contentHashHex, reason, Date.now());
|
|
251
|
-
/**
|
|
252
|
-
* ⚠️ **BOUNDED, because the counterparty chooses how many rows exist — review F7.**
|
|
253
|
-
*
|
|
254
|
-
* One row per distinct content hash aimed at a closed conversation, and the funnel that calls
|
|
255
|
-
* this runs even when the byte cap has already stopped RETENTION. So a peer who has exhausted
|
|
256
|
-
* the session's storage budget can still write rows here, indefinitely, on a table nothing
|
|
257
|
-
* else deletes. Every sibling store in this file is bounded (`MAX_UNREADABLE_ALG_FRAMES`, the
|
|
258
|
-
* tier byte cap, `MAX_REFUSAL_READERS`); this one was not.
|
|
259
|
-
*
|
|
260
|
-
* Oldest-dropped, so the newest refusals keep their stop and the loop stays closed for what
|
|
261
|
-
* is arriving now. A dropped row costs at most one extra fetch for content nobody is sending
|
|
262
|
-
* any more — the pre-fix behaviour for that one hash, and nothing worse.
|
|
263
|
-
*/
|
|
264
|
-
const dropped = this.#db
|
|
265
|
-
.prepare(`DELETE FROM terminal_content_refusals
|
|
266
|
-
WHERE agent_id = ? AND session_id = ? AND content_hash NOT IN (
|
|
267
|
-
SELECT content_hash FROM terminal_content_refusals
|
|
268
|
-
WHERE agent_id = ? AND session_id = ?
|
|
269
|
-
ORDER BY marked_at DESC LIMIT ${MAX_TERMINAL_REFUSALS_PER_SESSION}
|
|
270
|
-
)`)
|
|
271
|
-
.run(agentId, sessionId, agentId, sessionId);
|
|
272
|
-
if (Number(dropped.changes) > 0) {
|
|
273
|
-
// Loud, because it means a counterparty has aimed more than the cap's worth of distinct
|
|
274
|
-
// messages at one closed conversation — which is abuse, not ordinary traffic.
|
|
275
|
-
this.#ctx.logger.warn("session.content.terminal_refusal.evicted", {
|
|
276
|
-
agentName, sessionId, dropped: Number(dropped.changes),
|
|
277
|
-
cap: MAX_TERMINAL_REFUSALS_PER_SESSION,
|
|
278
|
-
impact: "more distinct messages have been refused on this closed conversation than the cap keeps a record of, so the oldest stops were dropped. If one of those arrives again it costs one wasted fetch; nothing is delivered and nothing is lost.",
|
|
279
|
-
});
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
catch (err) {
|
|
283
|
-
this.#ctx.logger.error("session.content.terminal_refusal.persist.failed", {
|
|
284
|
-
agentName, sessionId, reason,
|
|
285
|
-
contentHash: contentHashHex,
|
|
286
|
-
error: extractErrorMessage(err),
|
|
287
|
-
impact: "this message can never be accepted on this conversation, and that fact could not be written down. Fetching for it stops while this daemon runs, and RESUMES after the next restart — which is the loop that filled a log with a quarter of a million refusals for one message.",
|
|
288
|
-
guidance: "This is a fault on THIS machine, not with the counterparty. Check free disk space and the permissions on ~/.cello; session.refusal.persist.failed in this log usually appears alongside it with the underlying error.",
|
|
289
|
-
});
|
|
290
|
-
}
|
|
291
|
-
let set = this.#terminallyRefused.get(key);
|
|
292
|
-
if (!set) {
|
|
293
|
-
set = new Set();
|
|
294
|
-
this.#terminallyRefused.set(key, set);
|
|
295
|
-
}
|
|
296
|
-
set.add(contentHashHex);
|
|
297
|
-
// The same cancellation `#markContentResolved` performs, for the opposite fact: an already-armed
|
|
298
|
-
// grace timer must not fire for content we have just decided never to accept.
|
|
299
|
-
this.#ctx.cancelLeafFetch(key, contentHashHex);
|
|
300
|
-
if (!alreadyKnown) {
|
|
301
|
-
this.#ctx.logger.info("session.content.terminal_refusal", {
|
|
302
|
-
agentName, sessionId, reason,
|
|
303
|
-
contentHash: contentHashHex,
|
|
304
|
-
impact: "no further attempt will be made to fetch this message. The conversation it was sent to is closed and signed, so no retry could ever have succeeded.",
|
|
305
|
-
});
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
/**
|
|
309
|
-
* DOD-M15-REFUSALTERMINAL-1: has this content already been refused terminally?
|
|
310
|
-
*
|
|
311
|
-
* Reads the durable rows for a session ONCE and caches them, so the hot path — a witnessed leaf
|
|
312
|
-
* on a healthy session — costs one `Set` lookup rather than a query per message. A read failure
|
|
313
|
-
* returns `false`: the cost is the loop continuing, which is the pre-fix behaviour, and it is
|
|
314
|
-
* announced rather than swallowed. Answering `true` on a failed read would be the dangerous
|
|
315
|
-
* direction, because it silently stops fetching content that was never refused.
|
|
316
|
-
*/
|
|
317
|
-
isTerminallyRefused(agentName, sessionId, contentHashHex) {
|
|
318
|
-
const key = this.#ctx.sessionKey(agentName, sessionId);
|
|
319
|
-
/**
|
|
320
|
-
* ⚠️ **A FAILING READ MUST NOT BE RETRIED PER MESSAGE — review F3.**
|
|
321
|
-
*
|
|
322
|
-
* The loaded flag is set only on success, so a database that throws (a full disk, a corrupt
|
|
323
|
-
* page) sent this method back to SQLite on EVERY witnessed leaf, logged an ERROR each time, and
|
|
324
|
-
* — because nothing was ever cached — made `alreadyKnown` false forever, so the mark's INFO
|
|
325
|
-
* fired on every refusal too. That is the ~2/s log growth this unit exists to end, reproduced
|
|
326
|
-
* by its own fix in the failure mode.
|
|
327
|
-
*
|
|
328
|
-
* Backed off instead: one attempt per session per minute, so the read still recovers when the
|
|
329
|
-
* disk does, and the ERROR is bounded rather than proportional to traffic.
|
|
330
|
-
*/
|
|
331
|
-
const failedAt = this.#terminalRefusalsReadFailedAt.get(key);
|
|
332
|
-
const backedOff = failedAt !== undefined && Date.now() - failedAt < TERMINAL_REFUSAL_READ_RETRY_MS;
|
|
333
|
-
if (!this.#terminalRefusalsLoaded.has(key) && !backedOff && this.#db) {
|
|
334
|
-
try {
|
|
335
|
-
const rows = this.#db
|
|
336
|
-
.prepare("SELECT content_hash FROM terminal_content_refusals WHERE agent_id = ? AND session_id = ?")
|
|
337
|
-
.all(this.#ctx.requireAgentId(agentName), sessionId);
|
|
338
|
-
let set = this.#terminallyRefused.get(key);
|
|
339
|
-
if (!set) {
|
|
340
|
-
set = new Set();
|
|
341
|
-
this.#terminallyRefused.set(key, set);
|
|
342
|
-
}
|
|
343
|
-
for (const r of rows)
|
|
344
|
-
set.add(r.content_hash);
|
|
345
|
-
this.#terminalRefusalsLoaded.add(key);
|
|
346
|
-
this.#terminalRefusalsReadFailedAt.delete(key);
|
|
347
|
-
}
|
|
348
|
-
catch (err) {
|
|
349
|
-
this.#terminalRefusalsReadFailedAt.set(key, Date.now());
|
|
350
|
-
this.#ctx.logger.error("session.content.terminal_refusal.read.failed", {
|
|
351
|
-
agentName, sessionId,
|
|
352
|
-
error: extractErrorMessage(err),
|
|
353
|
-
retryInMs: TERMINAL_REFUSAL_READ_RETRY_MS,
|
|
354
|
-
impact: "the record of messages this conversation can never accept could not be read, so this daemon may keep fetching one of them. Nothing is lost; the cost is repeated work and log noise. The read is retried once a minute rather than on every message, so this line is bounded — its absence for a while does NOT mean the fault cleared.",
|
|
355
|
-
guidance: "This is a fault on THIS machine, not with any counterparty. Check free disk space and the permissions on ~/.cello; the error above carries SQLite's own message.",
|
|
356
|
-
});
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
return this.#terminallyRefused.get(key)?.has(contentHashHex) === true;
|
|
360
|
-
}
|
|
361
|
-
/**
|
|
362
|
-
* 024-ORPHANTRIAGE — the three signals, read from evidence this side owns.
|
|
363
|
-
*
|
|
364
|
-
* ⚠️ **THE SEQUENCE NUMBER ON THE FRAME IS NOT ONE OF THEM.** "Was there an ongoing conversation
|
|
365
|
-
* up to this point" is tempting to answer from the position the sender wrote, and that answer is
|
|
366
|
-
* worthless: the sender picks the number, so anyone wanting the reach-out branch writes a large
|
|
367
|
-
* one. It is answered from OUR transcript rows instead — a partial local record of that
|
|
368
|
-
* conversation is something an attacker cannot put there from the wire.
|
|
369
|
-
*
|
|
370
|
-
* ⚠️ **"KNOWN" IS A TIER, NOT A ROW — review F1/F2, and reading it as a row inverted the unit.**
|
|
371
|
-
* `contacts` rows are written from the WIRE with no operator action: `inbound-sessions.ts` calls
|
|
372
|
-
* `addContact(..., "signal_presentation")` at `TIER.UNKNOWN` for any inbound offer inside the
|
|
373
|
-
* acceptance bound, because the trust-signal foreign key needs a row to point at. And BLOCKING a
|
|
374
|
-
* contact is an UPDATE to `TIER.BLOCKED`, so the row survives that too. A `SELECT … WHERE pubkey`
|
|
375
|
-
* therefore answers "yes, known" for a stranger who merely dialled, AND for a key the operator
|
|
376
|
-
* deliberately blocked — handing both the reach-out branch, which is the exact population this
|
|
377
|
-
* unit exists to refuse. `DOD-TIER-4` had already settled this and retired `isContact` for it:
|
|
378
|
-
* *"An UNKNOWN-tier contact (a mere row) is NOT known."* The tier is read from the row already
|
|
379
|
-
* being fetched, so the case-insensitivity below survives (`getTier` compares case-sensitively).
|
|
380
|
-
*
|
|
381
|
-
* ⚠️ **HEX CASE IS NOT A DIFFERENCE IN IDENTITY.** This unit originally worked around that with its
|
|
382
|
-
* own `lower(pubkey)` lookup, because `contacts.pubkey` was stored verbatim from the IPC parameter
|
|
383
|
-
* and an exact match would report a contact the operator can SEE in `cello_contacts` as an unknown
|
|
384
|
-
* stranger. The workaround is gone: `contact-pubkey-case.ts` now normalizes every contacts
|
|
385
|
-
* accessor and folds the rows already on disk, so there is one spelling and one rule.
|
|
386
|
-
*/
|
|
387
|
-
orphanEvidence(agentName, sessionId, verifiedSignerUnmatched) {
|
|
388
|
-
const signerPubkeyHex = verifiedSignerUnmatched === undefined
|
|
389
|
-
? null
|
|
390
|
-
: Buffer.from(verifiedSignerUnmatched).toString("hex");
|
|
391
|
-
/**
|
|
392
|
-
* ⚠️ `"not_checked"` IS NOT A COSMETIC THIRD STATE — review F6.
|
|
393
|
-
*
|
|
394
|
-
* These two were `false` on every path that did not look, and the log event then reported them
|
|
395
|
-
* as readings. An investigator filtering `session.content.orphaned` days later would read
|
|
396
|
-
* `ongoingConversation: false` and conclude there was no local trace, when nothing had been
|
|
397
|
-
* asked. Clause 1 says the branch RECORDS these; a default wearing the shape of a measurement
|
|
398
|
-
* is not a record, and it is the cheapest possible way to mislead the one person who comes
|
|
399
|
-
* looking.
|
|
400
|
-
*/
|
|
401
|
-
const notChecked = {
|
|
402
|
-
signerPubkeyHex, knownContact: "not_checked", contactMoniker: null, ongoingConversation: "not_checked",
|
|
403
|
-
};
|
|
404
|
-
// With no verifiable signature the other two signals mean nothing — a claimed key is a string
|
|
405
|
-
// anyone can type — so they are not looked up at all rather than looked up and ignored.
|
|
406
|
-
if (signerPubkeyHex === null)
|
|
407
|
-
return notChecked;
|
|
408
|
-
try {
|
|
409
|
-
/**
|
|
410
|
-
* ⚠️ NO `!this.#db` SHORT-CIRCUIT — review F7, and it was the silent half of this guard.
|
|
411
|
-
*
|
|
412
|
-
* The catch below logs ERROR for exactly this outcome; a bare `if (!this.#db) return` did not,
|
|
413
|
-
* and the state is reachable while the operator still gets a notice — `noteContentRefusal`
|
|
414
|
-
* keeps its own in-memory fallback when the write fails, so a daemon with an unusable store
|
|
415
|
-
* still surfaces a refusal saying "that key is not in your address book" about a key that may
|
|
416
|
-
* well be in it, with nothing anywhere recording that the address book was never opened.
|
|
417
|
-
* Throwing into the catch is also what this file's other contact reads do (`getTier`,
|
|
418
|
-
* `addContact`), and for the same reason: a read that decides how to treat a sender must not
|
|
419
|
-
* degrade to "unclassified" in silence.
|
|
420
|
-
*/
|
|
421
|
-
if (!this.#db)
|
|
422
|
-
throw new Error("database is not open");
|
|
423
|
-
const agentId = this.#ctx.requireAgentId(agentName);
|
|
424
|
-
const contact = this.#db
|
|
425
|
-
.prepare("SELECT moniker, tier FROM contacts WHERE agent_id = ? AND pubkey = ?")
|
|
426
|
-
.get(agentId, normalizeContactPubkey(signerPubkeyHex));
|
|
427
|
-
/**
|
|
428
|
-
* ⚠️ **QUARANTINED ROWS ARE NOT A LOCAL TRACE, AND WITHOUT THIS CLAUSE THE PROBE WRITES ITS
|
|
429
|
-
* OWN EVIDENCE.** Found where `023-REFUSEDEVIDENCE` met `024-ORPHANTRIAGE`.
|
|
430
|
-
*
|
|
431
|
-
* This signal answers *"does this machine hold any part of a conversation under the id the
|
|
432
|
-
* message names?"*, and a `true` is one of the two conditions that flips the triage from
|
|
433
|
-
* REPORT-ONLY to offering the operator a reach-out. Since 023, a refused message is RETAINED
|
|
434
|
-
* as a transcript row — so an unfiltered `SELECT 1 FROM transcript` sees the row this very
|
|
435
|
-
* refusal just wrote.
|
|
436
|
-
*
|
|
437
|
-
* From the operator's chair, unfiltered: a stranger with a vouched key probes an id nobody
|
|
438
|
-
* opened; the first probe is refused and retained; the second probe finds the first one's row,
|
|
439
|
-
* reads as an ongoing conversation, and the operator is invited to reach out. **The attacker
|
|
440
|
-
* manufactures the signal by sending twice** — which is precisely the outcome 024 exists to
|
|
441
|
-
* prevent, reintroduced by the unit that made evidence durable.
|
|
442
|
-
*
|
|
443
|
-
* `direction != 'quarantined'` is the same exclusion every delivery reader uses, and it is the
|
|
444
|
-
* right one: what is asked here is whether anything was ever DELIVERED under this id.
|
|
445
|
-
*/
|
|
446
|
-
const trace = this.#db
|
|
447
|
-
.prepare("SELECT 1 AS present FROM transcript WHERE agent_id = ? AND session_id = ? AND direction != 'quarantined' LIMIT 1")
|
|
448
|
-
.get(agentId, sessionId);
|
|
449
|
-
return {
|
|
450
|
-
signerPubkeyHex,
|
|
451
|
-
knownContact: contact !== undefined && normalizeTier(contact.tier) >= TIER.KNOWN,
|
|
452
|
-
contactMoniker: contact?.moniker ?? null,
|
|
453
|
-
ongoingConversation: trace !== undefined,
|
|
454
|
-
};
|
|
455
|
-
}
|
|
456
|
-
catch (err) {
|
|
457
|
-
/**
|
|
458
|
-
* NOT A SILENT FALLBACK. Both signals come back `"not_checked"`, which the triage treats
|
|
459
|
-
* exactly as it treats a stranger — REPORT, the action that is safe when nothing is known — and
|
|
460
|
-
* which the log distinguishes from a measured `false`. A read failure here must never invent
|
|
461
|
-
* the reach-out branch, and it must never be invisible.
|
|
462
|
-
*/
|
|
463
|
-
this.#ctx.logger.error("session.content.orphaned.evidence.failed", {
|
|
464
|
-
agentName, sessionId,
|
|
465
|
-
error: extractErrorMessage(err),
|
|
466
|
-
impact: "the address book and transcript could not be read, so a message whose signature DID verify is being reported to the operator as coming from a key nothing is known about. The advice is the safe one; it may be more cautious than the evidence warrants.",
|
|
467
|
-
});
|
|
468
|
-
return notChecked;
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
/**
|
|
472
|
-
* `DOD-M15-AUTHORSHIP-ABSENT-1` — the refusal an inbound frame gets when its authorship cannot be
|
|
473
|
-
* established. NOT a freeze: see `AuthorshipVerdict` for why those are different facts.
|
|
474
|
-
*
|
|
475
|
-
* Both surfaces, always. The ERROR is the durable forensic record an investigation reads days
|
|
476
|
-
* later; the notice is the CONTROL — the thing that actually reaches the operator, who otherwise
|
|
477
|
-
* watches a conversation go quiet and concludes the other person stopped replying.
|
|
478
|
-
*/
|
|
479
|
-
refuseUnprovenAuthorship(agentName, sessionId, reason, contentHash, detail, correlationId) {
|
|
480
|
-
/**
|
|
481
|
-
* ⚠️ **THREE REASONS, THREE SENTENCES — AND THE THIRD USED TO BORROW THE SECOND'S** (review of
|
|
482
|
-
* `029b`, and it is the operator half of the same finding as the check order).
|
|
483
|
-
*
|
|
484
|
-
* A replayed claim is the one branch on this path that is potentially ADVERSARIAL: a real,
|
|
485
|
-
* valid, correctly-signed line of your counterparty's, presented in a conversation it was not
|
|
486
|
-
* written for. It was reaching the operator under the `unusable` wording, which says the proof
|
|
487
|
-
* was "unreadable, or signed over different content" — neither is true — and under guidance
|
|
488
|
-
* telling them to go and ask their counterparty to upgrade. A version number is not the
|
|
489
|
-
* question, and sending someone to chase one spends their attention on the wrong thing.
|
|
490
|
-
*/
|
|
491
|
-
const impact = reason === "authorship_proof_absent"
|
|
492
|
-
? "a message arrived carrying no proof of who wrote it, so it was NOT ingested, NOT shown and NOT attributed to anyone. Every message in this conversation has to be provable to whoever reads its receipt later, and this one could not be."
|
|
493
|
-
: reason === "authorship_wrong_conversation"
|
|
494
|
-
? "a message arrived carrying a VALID signature by this conversation's counterparty — made for a DIFFERENT conversation. The same message, or an old one of theirs, was presented here. It was NOT ingested, NOT shown and NOT added to this conversation's record."
|
|
495
|
-
/**
|
|
496
|
-
* 033-ACKEMIT. Says what was OBSERVED — the two records disagree about what was said —
|
|
497
|
-
* and stops there. It does NOT say the counterparty is lying: the same signal is what a
|
|
498
|
-
* genuine fault on their side looks like, and naming a conclusion the code did not reach
|
|
499
|
-
* is the error-fidelity defect this milestone was opened for.
|
|
500
|
-
*/
|
|
501
|
-
/**
|
|
502
|
-
* ⚠️ THREE CAUSES, THREE SENTENCES — review F5. They shared one, and it described none of
|
|
503
|
-
* them properly: an ABSENT acknowledgement has no part that "does not match", because it
|
|
504
|
-
* has no part at all.
|
|
505
|
-
*
|
|
506
|
-
* All three say what was OBSERVED and stop there. None says the counterparty is lying:
|
|
507
|
-
* the same signal is what a genuine fault on their side looks like, and naming a
|
|
508
|
-
* conclusion the code did not reach is the error-fidelity defect this milestone exists
|
|
509
|
-
* for.
|
|
510
|
-
*/
|
|
511
|
-
/**
|
|
512
|
-
* `DOD-M15-SELFCHAIN-1` — THE ORDER, NOT THE CONTENT, AND IT NEEDS ITS OWN WORDS.
|
|
513
|
-
*
|
|
514
|
-
* This reached the operator under the generic `authorship_proof_unusable` sentence, which
|
|
515
|
-
* says the proof was "unreadable, or signed over different content". Neither is true: the
|
|
516
|
-
* proof is perfect and it is about this conversation. What is in dispute is WHERE this
|
|
517
|
-
* message sits — and telling someone their decoder failed sends them to audit the wrong
|
|
518
|
-
* subsystem entirely. The reason's own comment claimed it was "named apart from the
|
|
519
|
-
* acknowledgement reasons"; the surface collapsed it back, which is error substitution on
|
|
520
|
-
* the strongest evidence this protocol can produce.
|
|
521
|
-
*/
|
|
522
|
-
: reason === AUTHORSHIP_SELF_CHAIN_MISMATCH
|
|
523
|
-
? "a message arrived that is genuinely from your counterparty, about this conversation, and correctly signed — and it names a message of THEIR OWN that they never sent you. Each message says which of their own came before it, and that is what fixes the ORDER of the conversation. This one points somewhere your record has never been. It was NOT ingested and NOT shown."
|
|
524
|
-
: reason === AUTHORSHIP_ACK_HASH_MISMATCH
|
|
525
|
-
? "a message arrived that is genuinely from your counterparty — and it names a DIFFERENT message of yours in the position where your own record holds one. Both sides agree the message exists; you disagree about which one sits there. It was NOT ingested and NOT shown."
|
|
526
|
-
: reason === AUTHORSHIP_ACK_HASH_UNKNOWN
|
|
527
|
-
? "a message arrived that is genuinely from your counterparty — and it says they received something from you that this side has no record of ever holding. It was NOT ingested and NOT shown. This is the check that stops someone quietly rewriting what was said before the receipt is made."
|
|
528
|
-
: "a message arrived whose proof of authorship could not be checked against it — it was unreadable, or it was signed over different content. It was NOT ingested, NOT shown and NOT attributed to anyone.";
|
|
529
|
-
/**
|
|
530
|
-
* ⚠️ THE VERB IS THE COUNTERPARTY'S, AND THE GUIDANCE SAYS SO. The reader is the RECEIVING
|
|
531
|
-
* operator, and there is nothing on their machine to change — the missing signature is produced
|
|
532
|
-
* on the sender's. Telling them to do something local would be an affordance that resolves to
|
|
533
|
-
* nothing. So it names the one move that works (tell them to upgrade) and the one that settles
|
|
534
|
-
* the other explanation (confirm out of band), and it stops at two.
|
|
535
|
-
*
|
|
536
|
-
* ⚠️ **IT USED TO OPEN "Nothing was shown and nothing was stored." THAT SENTENCE WAS FALSE** —
|
|
537
|
-
* review H1, and it is kept here rather than deleted because it is the exact shape this
|
|
538
|
-
* milestone exists to catch: a refusal that announces a stronger outcome than it delivers.
|
|
539
|
-
*
|
|
540
|
-
* Refusing sends no delivery ACK, so the sender's TTF backstop parks the message and it arrives
|
|
541
|
-
* through the relay mailbox seconds later, where the ENVELOPE's signature authenticates it and
|
|
542
|
-
* recovery accepts it — correctly, and with no per-message proof. So the message may well be
|
|
543
|
-
* delivered, moments after the operator was told it was not. The reconciliation is logged
|
|
544
|
-
* (`content.recover.refusal_reconciled`) and the sentence below now says what is
|
|
545
|
-
* actually true of this path: nothing was shown YET, and this refusal does not stop the copy
|
|
546
|
-
* coming the other way.
|
|
547
|
-
*/
|
|
548
|
-
const guidance = reason === "authorship_wrong_conversation"
|
|
549
|
-
? "STOPPED ON PURPOSE, and this one is NOT a version problem — do not go and ask them about " +
|
|
550
|
-
"their build. The signature is real and it is theirs; what is wrong is that it was made for " +
|
|
551
|
-
"another conversation, so something replayed it into this one. That is either software on " +
|
|
552
|
-
"one of your machines re-sending an old message into the wrong session, or someone in " +
|
|
553
|
-
"between doing it deliberately. ONE thing to do: ask your counterparty OUT OF BAND (a " +
|
|
554
|
-
"channel that is not this one) whether they meant to send this, before you continue here."
|
|
555
|
-
/**
|
|
556
|
-
* ⚠️ **THIS BRANCH SHIPPED AS `NaNcopy in the relay mailbox…` AND NOTHING NOTICED** — review
|
|
557
|
-
* F1, and it is worth more than the one-line fix.
|
|
558
|
-
*
|
|
559
|
-
* Splitting the guidance in two dropped the opening literal and left behind the `+` that had
|
|
560
|
-
* joined it, which is not a concatenation with nothing on its left — it is a UNARY PLUS on the
|
|
561
|
-
* next string. `+"REACH YOU BY…"` is `NaN`, and `NaN + "copy in the relay mailbox…"` is a
|
|
562
|
-
* perfectly good string. So the flagship refusal of this whole milestone reached the operator
|
|
563
|
-
* beginning mid-word with `NaN`, with its "STOPPED ON PURPOSE" framing and its reason gone.
|
|
564
|
-
*
|
|
565
|
-
* **The test was green because it asked the wrong question.** The only assertion on this
|
|
566
|
-
* string was `.toMatch(/upgrade/i)`, and "tell them to upgrade" survives at the tail. A
|
|
567
|
-
* substring match on a sentence cannot see that the sentence lost its head — so the assertion
|
|
568
|
-
* below pins what it OPENS with, which a truncation cannot survive.
|
|
569
|
-
*/
|
|
570
|
-
/**
|
|
571
|
-
* 033-ACKEMIT — TWO PATHS, AND THE FIRST IS THE ONE THAT ACTUALLY HAPPENS.
|
|
572
|
-
*
|
|
573
|
-
* Capped at two (Invariant 4): an affordance list that enumerates everything is a menu. The
|
|
574
|
-
* verb is the counterparty's in both cases — there is nothing to change on this machine — so
|
|
575
|
-
* it names the one move that fixes the likely cause and the one that settles the other.
|
|
576
|
-
*/
|
|
577
|
-
/**
|
|
578
|
-
* ⚠️ AND THREE REMEDIES, because the shared one was WRONG for two of the three. It told the
|
|
579
|
-
* reader their counterparty's build was probably old — which is impossible for a claim that
|
|
580
|
-
* carries an acknowledgement, since only a newer build sends one — and then told them to
|
|
581
|
-
* abandon the conversation. Two is the cap on each (Invariant 4); the verb is the
|
|
582
|
-
* counterparty's in every case, because there is nothing to change on this machine.
|
|
583
|
-
*/
|
|
584
|
-
: reason === AUTHORSHIP_SELF_CHAIN_MISMATCH
|
|
585
|
-
? "STOPPED ON PURPOSE, and this is the most serious of these refusals. " +
|
|
586
|
-
(this.#ctx.mailboxRouteAvailable(agentName) ? REFUSAL_MAY_STILL_ARRIVE : REFUSAL_NO_OTHER_ROUTE) +
|
|
587
|
-
" Their signature is real and it is about this conversation. What does not hold is the " +
|
|
588
|
-
"ORDER: this message names one of their own as the one before it, and that message was " +
|
|
589
|
-
"never sent to you. Either something between you is rearranging what they say, or their " +
|
|
590
|
-
"agent's record of what it has said went out of step. THIS SESSION IS NOW FROZEN — no " +
|
|
591
|
-
"further message on it will be accepted, because carrying on writes a disputed order into " +
|
|
592
|
-
"the receipt. Reach them OUT OF BAND — a channel that is not this one — and ask them to " +
|
|
593
|
-
"read back the last few things they sent you. If it matches what you have, open a NEW " +
|
|
594
|
-
"session; if it does not, do not."
|
|
595
|
-
/**
|
|
596
|
-
* ⚠️ THESE TWO SHARED ONE SENTENCE, AND THE TEST THAT WAS MEANT TO CATCH THAT COULD NOT SEE
|
|
597
|
-
* IT — `DOD-M15-SELFCHAIN-1`.
|
|
598
|
-
*
|
|
599
|
-
* The file's thesis is "three causes, three sentences", and it compared ABSENT against
|
|
600
|
-
* MISMATCH and stopped. Mismatch and unknown-content shared a remedy the whole time; the pair
|
|
601
|
-
* was never compared, so the defect the test existed for was live inside it.
|
|
602
|
-
*
|
|
603
|
-
* They are not the same situation. A MISMATCH means you both agree a message sits at that
|
|
604
|
-
* position and disagree about which one — a record that has drifted. UNKNOWN CONTENT means
|
|
605
|
-
* they are acknowledging something this side never held at all, which is the shape of content
|
|
606
|
-
* being attributed to you that you did not send. The second is the more serious reading and
|
|
607
|
-
* the operator's next move differs, so it gets its own sentence.
|
|
608
|
-
*/
|
|
609
|
-
: reason === AUTHORSHIP_ACK_HASH_MISMATCH
|
|
610
|
-
? "STOPPED ON PURPOSE, and this is NOT about their signature or their version — both are " +
|
|
611
|
-
"fine. " +
|
|
612
|
-
(this.#ctx.mailboxRouteAvailable(agentName) ? REFUSAL_MAY_STILL_ARRIVE : REFUSAL_NO_OTHER_ROUTE) +
|
|
613
|
-
" Your record of this conversation and theirs have stopped agreeing about what you sent " +
|
|
614
|
-
"them. Confirm with them OUT OF BAND what they actually received from you. If it matches " +
|
|
615
|
-
"what you sent, this was a fault and a new session will clear it; if it does not, do not " +
|
|
616
|
-
"carry on in this one."
|
|
617
|
-
: reason === AUTHORSHIP_ACK_HASH_UNKNOWN
|
|
618
|
-
? "STOPPED ON PURPOSE, and this one is more serious than a record that has drifted. " +
|
|
619
|
-
(this.#ctx.mailboxRouteAvailable(agentName) ? REFUSAL_MAY_STILL_ARRIVE : REFUSAL_NO_OTHER_ROUTE) +
|
|
620
|
-
" They are acknowledging a message from you that this side has NEVER held — not at that " +
|
|
621
|
-
"position, not anywhere. Either their record contains something you did not send, or " +
|
|
622
|
-
"yours is missing something you did. Ask them OUT OF BAND to read you back what they " +
|
|
623
|
-
"believe you sent. Do not continue this conversation until you know which of the two it " +
|
|
624
|
-
"is: carrying on writes their version into the receipt."
|
|
625
|
-
: "STOPPED ON PURPOSE. This copy was refused and the message itself was not kept. " +
|
|
626
|
-
// Review F2: chosen from what THIS machine can do, not asserted. An agent with no identity
|
|
627
|
-
// key cannot open a mailbox copy either, and telling them to wait for one would be the same
|
|
628
|
-
// false promise on a different refusal.
|
|
629
|
-
(this.#ctx.mailboxRouteAvailable(agentName) ? REFUSAL_MAY_STILL_ARRIVE : REFUSAL_NO_OTHER_ROUTE) +
|
|
630
|
-
" Almost always their CELLO build is older than this one: a build from before message signing " +
|
|
631
|
-
"does not attach a signature at all. Ask which version they are running, and tell them to " +
|
|
632
|
-
"upgrade — this will keep happening until they do, and only they can fix it. If they are on " +
|
|
633
|
-
"the SAME version as you, that explanation does not hold: confirm with them OUT OF BAND " +
|
|
634
|
-
"before opening another session.";
|
|
635
|
-
this.#ctx.logger.error("session.content.refused", {
|
|
636
|
-
agentName, sessionId, correlationId, reason, ...detail, impact, guidance,
|
|
637
|
-
});
|
|
638
|
-
this.#ctx.noteContentRefusal(agentName, sessionId, reason, { kind: REFUSAL_KINDS.REFUSED, impact, guidance });
|
|
639
|
-
// Armed AFTER the refusal is filed, so the memo can never claim a refusal that did not happen.
|
|
640
|
-
this.noteRefusedOnDirectPath(agentName, sessionId, contentHash);
|
|
641
|
-
}
|
|
642
|
-
recordFrameOrdering(agentName, sessionId, structure1Cbor, structure2Cbor, contentHash, correlationId, source = "content_frame") {
|
|
643
|
-
try {
|
|
644
|
-
const s2 = decode(structure2Cbor);
|
|
645
|
-
const seq = typeof s2?.[0] === "number" ? s2[0] : -1;
|
|
646
|
-
const s2Sig = s2?.[3];
|
|
647
|
-
if (!(s2Sig instanceof Uint8Array) || seq < 1) {
|
|
648
|
-
// SOFT: we could not read the record, so we learned nothing about the signer either way.
|
|
649
|
-
// Position falls back to the witness stream, exactly as an absent record does.
|
|
650
|
-
// The Structure 1 reason is carried so an unreadable RECORD and an unnamed LAYOUT are
|
|
651
|
-
// distinguishable in the log — they arrive at the same soft outcome by different routes.
|
|
652
|
-
const s1Layout = decodeStructure1(structure1Cbor);
|
|
653
|
-
this.#ctx.logger.warn("session.content.ordering.malformed", {
|
|
654
|
-
sessionId,
|
|
655
|
-
correlationId,
|
|
656
|
-
...(s1Layout.ok ? {} : { structure1Reason: s1Layout.reason }),
|
|
657
|
-
});
|
|
658
|
-
return { seq: null };
|
|
659
|
-
}
|
|
660
|
-
/**
|
|
661
|
-
* `DOD-M15-AUTHORSHIP-ABSENT-1` — the same verifier the content frame uses, handed the
|
|
662
|
-
* signature the RELAY committed (`structure2_cbor` index 3) instead of the one the frame
|
|
663
|
-
* carries. Two claims about the same message, and both must hold: if the relay's copy of the
|
|
664
|
-
* sender's signature does not verify against the bytes on the frame, one of them has been
|
|
665
|
-
* altered in flight.
|
|
666
|
-
*
|
|
667
|
-
* The verdicts map to this path's own severities, which are NOT the content frame's:
|
|
668
|
-
* an `unusable` record leaves POSITION unknown and is soft here, because position may always
|
|
669
|
-
* fall back to the witness stream. Identity is the half that may never be soft, and it is
|
|
670
|
-
* established before this is called.
|
|
671
|
-
*/
|
|
672
|
-
const auth = this.#ctx.verifyAuthorshipClaim(agentName, sessionId, structure1Cbor, s2Sig, contentHash);
|
|
673
|
-
if (auth.verdict === "unusable") {
|
|
674
|
-
/**
|
|
675
|
-
* ⚠️ **THE ACK CAUSES REACH THIS PATH TOO, AND THEY ARE NOT A DECODER PROBLEM** — review F7.
|
|
676
|
-
*
|
|
677
|
-
* `#verifyAuthorshipClaim` has two callers. This one is reached from park RECOVERY, where
|
|
678
|
-
* it is the only authorship check that runs — so 033-ACKEMIT's acknowledgement causes
|
|
679
|
-
* started arriving here and fell into the generic `else` below, which logs
|
|
680
|
-
* `…ordering.malformed` and buries the cause in `structure1Reason`. That event name sends
|
|
681
|
-
* the next reader to audit a decoder for a record that decoded perfectly.
|
|
682
|
-
*
|
|
683
|
-
* SOFT, like every other `unusable` on this path, and deliberately: position may always
|
|
684
|
-
* fall back to the witness stream, and a recovered parked message is authenticated by the
|
|
685
|
-
* ENVELOPE's own signature rather than by this. What changes is that the log says which
|
|
686
|
-
* thing disagreed.
|
|
687
|
-
*/
|
|
688
|
-
if (ACK_HASH_REASONS.has(auth.reason)) {
|
|
689
|
-
this.#ctx.logger.warn("session.content.ordering.ack_hash_unverified", {
|
|
690
|
-
sessionId, correlationId, reason: auth.reason,
|
|
691
|
-
impact: "a recovered message's acknowledgement of what its sender had received does not " +
|
|
692
|
-
"reconcile with this side's record, so no canonical POSITION was taken from it. The " +
|
|
693
|
-
"message itself is authenticated by its park envelope and is not refused here.",
|
|
694
|
-
});
|
|
695
|
-
}
|
|
696
|
-
else if (auth.reason === AUTHORSHIP_CONTENT_HASH_MISMATCH) {
|
|
697
|
-
// SOFT: the record does not describe this content. Nothing is proven about the signer's
|
|
698
|
-
// identity — only that this record and these bytes do not belong together.
|
|
699
|
-
this.#ctx.logger.warn("session.content.ordering.hash_mismatch", { sessionId, correlationId });
|
|
700
|
-
}
|
|
701
|
-
else if (auth.reason === AUTHORSHIP_SESSION_MISMATCH) {
|
|
702
|
-
// Its own name, because `…malformed` points a reader at a decoder and this record decoded
|
|
703
|
-
// perfectly — it belongs to another conversation. Unreachable in practice on this path:
|
|
704
|
-
// `authenticateParkedEntry` binds `session_id` in the park TBS before anything is
|
|
705
|
-
// unsealed, so a mismatched record cannot get this far. Named anyway, because an event
|
|
706
|
-
// that lies about its cause is worse the day it does fire.
|
|
707
|
-
this.#ctx.logger.warn("session.content.ordering.session_mismatch", { sessionId, correlationId });
|
|
708
|
-
}
|
|
709
|
-
else {
|
|
710
|
-
this.#ctx.logger.warn("session.content.ordering.malformed", {
|
|
711
|
-
sessionId, correlationId, structure1Reason: auth.reason,
|
|
712
|
-
});
|
|
713
|
-
}
|
|
714
|
-
return { seq: null };
|
|
715
|
-
}
|
|
716
|
-
if (auth.verdict === "refuted" && auth.reason === "bad_signature") {
|
|
717
|
-
// FATAL. The sender supplied a signature and it does not verify against the key inside its
|
|
718
|
-
// own record. That is not an absence we could not resolve — it is a proof that failed.
|
|
719
|
-
this.#ctx.logger.warn("session.content.ordering.bad_signature", { sessionId, correlationId });
|
|
720
|
-
return { seq: null, fatal: { reason: "bad_signature" } };
|
|
721
|
-
}
|
|
722
|
-
// Sovereign-node cross-check: the signer MUST be THIS session's counterparty, not an unrelated
|
|
723
|
-
// key. FAIL CLOSED (review L) — if the counterparty pubkey is unknown we cannot prove the signer,
|
|
724
|
-
// so we do NOT trust the framed ordering record (fall back to the witness stream / arrival). The
|
|
725
|
-
// "B does not trust the counterparty for ordering" invariant is non-negotiable; never fail open.
|
|
726
|
-
if (auth.verdict !== "verified") {
|
|
727
|
-
/**
|
|
728
|
-
* FATAL when the counterparty is KNOWN and the signer is someone else (`refuted`). SOFT when
|
|
729
|
-
* we simply do not know who the counterparty is (`verified_unmatched`) — the reasoning for
|
|
730
|
-
* both, and the MITM substitution this catches, lives on `#verifyAuthorshipClaim`.
|
|
731
|
-
*
|
|
732
|
-
* The soft half is the one that matters HERE: `counterparty_unknown` means we cannot prove
|
|
733
|
-
* the signer either way, so we decline to take a POSITION from a record we cannot attribute,
|
|
734
|
-
* and the caller falls back to the witness stream. Nothing about the message is refused on
|
|
735
|
-
* this path — that decision was already made, on the frame's own proof.
|
|
736
|
-
*/
|
|
737
|
-
const reason = auth.verdict === "refuted" ? auth.reason : "counterparty_unknown";
|
|
738
|
-
this.#ctx.logger.warn("session.content.ordering.wrong_signer", { sessionId, reason, correlationId });
|
|
739
|
-
return auth.verdict === "refuted" ? { seq: null, fatal: { reason } } : { seq: null };
|
|
740
|
-
}
|
|
741
|
-
// Verified — record the relay-assigned canonical sequence (1-based → 0-based leaf index) for the gate.
|
|
742
|
-
this.#ctx.recordWitnessedSequence(agentName, sessionId, Buffer.from(contentHash).toString("hex"), seq - 1);
|
|
743
|
-
this.#ctx.logger.info("session.content.ordering.recorded", {
|
|
744
|
-
sessionId,
|
|
745
|
-
canonicalSeq: seq - 1,
|
|
746
|
-
source,
|
|
747
|
-
correlationId,
|
|
748
|
-
});
|
|
749
|
-
/**
|
|
750
|
-
* THE POSITION, AND ONLY THE POSITION — `DOD-M15-AUTHORSHIP-ABSENT-1`.
|
|
751
|
-
*
|
|
752
|
-
* `DOD-M15-SEALWIRE-1` bullet 5 had this return the verified proof as well, because this was
|
|
753
|
-
* the only place a signer was ever checked and the transcript row needed it from somewhere.
|
|
754
|
-
* The frame now carries the sender's signature beside the bytes it signs and the caller
|
|
755
|
-
* verifies it before calling this at all, so the proof reaches the transcript from there. What
|
|
756
|
-
* this answers is the question it is named for: WHERE the relay says this message sits.
|
|
757
|
-
*/
|
|
758
|
-
return { seq: seq - 1 };
|
|
759
|
-
}
|
|
760
|
-
catch (err) {
|
|
761
|
-
this.#ctx.logger.warn("session.content.ordering.decode_failed", {
|
|
762
|
-
sessionId,
|
|
763
|
-
error: extractErrorMessage(err),
|
|
764
|
-
correlationId,
|
|
765
|
-
});
|
|
766
|
-
}
|
|
767
|
-
// No verified position — the caller falls back to the announced hash-dedup path. SOFT: a decode
|
|
768
|
-
// throw tells us nothing about the signer, so it is the absent case, not the refuted one.
|
|
769
|
-
return { seq: null };
|
|
770
|
-
}
|
|
771
|
-
/**
|
|
772
|
-
* DAEMON-004: cross-check received content against its hash, append the
|
|
773
|
-
* verified leaf to the daemon-owned tree, and buffer it for cello_receive.
|
|
774
|
-
* A hash MISMATCH is genuine tamper — rejected without append or buffer.
|
|
775
|
-
*
|
|
776
|
-
* SCOPE / finding #5 — what this cross-check proves BY ITSELF, and what proves the rest:
|
|
777
|
-
* `contentHash` here is carried in the SAME content_frame as `content`, so this comparison on its
|
|
778
|
-
* own catches wire corruption of a single frame and nothing more. It is not what establishes that
|
|
779
|
-
* the sender committed to these bytes. That proof arrives separately and is checked BEFORE any
|
|
780
|
-
* caller reaches this method.
|
|
781
|
-
*
|
|
782
|
-
* ⚠️ **THE RULE THIS PARAGRAPH EXISTS TO ENFORCE: a comment that says a protection is missing
|
|
783
|
-
* must be re-read whenever the protection lands, because in a PUBLIC repository it keeps handing
|
|
784
|
-
* a reader a hole that is already closed.** This one said: *"Full tamper-evidence (EARS behavior
|
|
785
|
-
* #2) requires cross-checking against the K_local-signed content_hash leaf the sender submits to
|
|
786
|
-
* the RELAY on a separate channel; that relay hash-submit path is MSG-001's scope and **does not
|
|
787
|
-
* exist yet**. Until MSG-001 lands, a malicious sender that sends matching (content, hash) in one
|
|
788
|
-
* frame is not detected here — only the relay-relayed signed leaf closes that gap."* True when
|
|
789
|
-
* written; the quote stays because its last clause predicts the wrong closure, as below.
|
|
790
|
-
*
|
|
791
|
-
* What closes it today — and note it is NOT only the route the old sentence predicted:
|
|
792
|
-
* - The relay hash-submit path EXISTS (`relay-node.ts` `#processHashSubmit`), so the separate
|
|
793
|
-
* channel the paragraph was waiting for is built.
|
|
794
|
-
* - `DOD-M15-AUTHORSHIP-ABSENT-1` then made the relay unnecessary for this question: the
|
|
795
|
-
* sender's signature over their own Structure 1 travels on the content frame beside the bytes
|
|
796
|
-
* it signs. `#verifyAuthorshipClaim` verifies it against the pubkey inside those signed bytes
|
|
797
|
-
* and matches the signer to this session's counterparty; a frame carrying nothing checkable is
|
|
798
|
-
* refused by name (`authorship_proof_absent`), so omitting the proof is not the softer option
|
|
799
|
-
* it once was. That verdict reaches this method as `verifiedAuthorship`.
|
|
800
|
-
* - The PARK-RECOVERY caller deliberately passes no `verifiedAuthorship`, and is not an
|
|
801
|
-
* exception to the above: recovered mail is authenticated by its park ENVELOPE's own
|
|
802
|
-
* signature (`authenticateParkedEntry`) before any of it is ingested — note the order is
|
|
803
|
-
* unseal THEN authenticate, so the envelope signature gates the append, not the decrypt.
|
|
804
|
-
* Two routes, both cryptographic, and the transcript row records which one attested the
|
|
805
|
-
* message rather than implying a proof it does not have.
|
|
806
|
-
*
|
|
807
|
-
* @returns the appended leaf index (as sequenceNumber) on success.
|
|
808
|
-
*/
|
|
809
|
-
/**
|
|
810
|
-
* Mark this session's content unverifiable — review F1, and every path that fails the cross-check
|
|
811
|
-
* must come through here.
|
|
812
|
-
*
|
|
813
|
-
* It gates `getSealUpgradeReadiness().tampered` and the auto-acknowledge check, i.e. whether this
|
|
814
|
-
* agent's key signs anything covering content it could not check. Three refusal paths reach it and
|
|
815
|
-
* they carry different labels, because what the operator is told must differ; **what the gate does
|
|
816
|
-
* must not.**
|
|
817
|
-
*
|
|
818
|
-
* TAMPERED NEVER DOWNGRADES. A session that has already seen a hash mismatch stays `tampered` even
|
|
819
|
-
* if a later frame merely names an unreadable algorithm — otherwise a sender that had been caught
|
|
820
|
-
* could clear its own alarm by sending one more frame with a junk algorithm name, and the seal
|
|
821
|
-
* would auto-complete.
|
|
822
|
-
*/
|
|
823
|
-
/**
|
|
824
|
-
* Remember that THIS frame was refused for naming an unreadable algorithm, so the park path can
|
|
825
|
-
* say so if the same message comes back the other way (review F2/F-D).
|
|
826
|
-
*
|
|
827
|
-
* BOUNDED, and it has to be: a peer that keeps sending unreadable frames would otherwise grow this
|
|
828
|
-
* without limit, and it is fed entirely by a remote party. The cap is per session and it drops the
|
|
829
|
-
* OLDEST entry — losing one only costs a missing reconciliation line, whereas an unbounded map fed
|
|
830
|
-
* by a counterparty is the leak class this codebase has already caught twice.
|
|
831
|
-
*/
|
|
832
|
-
noteUnreadableAlgFrame(agentName, sessionId, contentHash, declaredAlg) {
|
|
833
|
-
const key = this.#ctx.sessionKey(agentName, sessionId);
|
|
834
|
-
let byHash = this.#unreadableAlgSeen.get(key);
|
|
835
|
-
if (!byHash) {
|
|
836
|
-
byHash = new Map();
|
|
837
|
-
this.#unreadableAlgSeen.set(key, byHash);
|
|
838
|
-
}
|
|
839
|
-
if (byHash.size >= MAX_UNREADABLE_ALG_FRAMES) {
|
|
840
|
-
const oldest = byHash.keys().next();
|
|
841
|
-
if (!oldest.done)
|
|
842
|
-
byHash.delete(oldest.value);
|
|
843
|
-
}
|
|
844
|
-
byHash.set(Buffer.from(contentHash).toString("hex"), declaredAlg);
|
|
845
|
-
}
|
|
846
|
-
/**
|
|
847
|
-
* Remember that THIS frame was refused for carrying no usable proof of who wrote it, so the park
|
|
848
|
-
* path can say so when the same content arrives through the relay mailbox — review H1.
|
|
849
|
-
*
|
|
850
|
-
* Bounded for the same reason and by the same cap as `#noteUnreadableAlgFrame`: a peer sending
|
|
851
|
-
* unprovable frames feeds this map, so it drops the oldest rather than growing.
|
|
852
|
-
*/
|
|
853
|
-
noteRefusedOnDirectPath(agentName, sessionId, contentHash) {
|
|
854
|
-
const key = this.#ctx.sessionKey(agentName, sessionId);
|
|
855
|
-
let hashes = this.#refusedOnDirectPath.get(key);
|
|
856
|
-
if (!hashes) {
|
|
857
|
-
hashes = new Set();
|
|
858
|
-
this.#refusedOnDirectPath.set(key, hashes);
|
|
859
|
-
}
|
|
860
|
-
if (hashes.size >= MAX_UNREADABLE_ALG_FRAMES) {
|
|
861
|
-
const oldest = hashes.values().next();
|
|
862
|
-
if (!oldest.done)
|
|
863
|
-
hashes.delete(oldest.value);
|
|
864
|
-
}
|
|
865
|
-
hashes.add(Buffer.from(contentHash).toString("hex"));
|
|
866
|
-
}
|
|
867
|
-
/**
|
|
868
|
-
* What algorithm did we refuse this content for naming, on the DIRECT path?
|
|
869
|
-
*
|
|
870
|
-
* Read by park recovery so it can tell the operator the message arrived by the other route after
|
|
871
|
-
* all. Returns `undefined` when there was no such refusal.
|
|
872
|
-
*/
|
|
873
|
-
priorUnreadableAlg(agentName, sessionId, contentHashHex) {
|
|
874
|
-
return this.#unreadableAlgSeen.get(this.#ctx.sessionKey(agentName, sessionId))?.get(contentHashHex);
|
|
875
|
-
}
|
|
876
|
-
/**
|
|
877
|
-
* Forget one direct-path algorithm refusal, because the same content arrived by the mailbox.
|
|
878
|
-
*
|
|
879
|
-
* ⚠️ CLEARED ONLY ON A REAL RECONCILIATION. Clearing on the LOOKUP forgets the refusal even when
|
|
880
|
-
* the recovery then fails, and the next genuine reconciliation says nothing — that was the defect,
|
|
881
|
-
* and separating the read from the clear is what fixed it. Both halves stay separate here.
|
|
882
|
-
*/
|
|
883
|
-
clearUnreadableAlg(agentName, sessionId, contentHashHex) {
|
|
884
|
-
const key = this.#ctx.sessionKey(agentName, sessionId);
|
|
885
|
-
const byHash = this.#unreadableAlgSeen.get(key);
|
|
886
|
-
byHash?.delete(contentHashHex);
|
|
887
|
-
if (byHash && byHash.size === 0)
|
|
888
|
-
this.#unreadableAlgSeen.delete(key);
|
|
889
|
-
}
|
|
890
|
-
/** Was this content refused on the direct path for carrying no usable proof of who wrote it? */
|
|
891
|
-
wasRefusedOnDirectPath(agentName, sessionId, contentHashHex) {
|
|
892
|
-
return this.#refusedOnDirectPath.get(this.#ctx.sessionKey(agentName, sessionId))?.has(contentHashHex) === true;
|
|
893
|
-
}
|
|
894
|
-
/** Forget one direct-path authorship refusal — same reconciliation rule as the algorithm memo. */
|
|
895
|
-
clearRefusedOnDirectPath(agentName, sessionId, contentHashHex) {
|
|
896
|
-
const key = this.#ctx.sessionKey(agentName, sessionId);
|
|
897
|
-
const hashes = this.#refusedOnDirectPath.get(key);
|
|
898
|
-
hashes?.delete(contentHashHex);
|
|
899
|
-
if (hashes && hashes.size === 0)
|
|
900
|
-
this.#refusedOnDirectPath.delete(key);
|
|
901
|
-
}
|
|
902
|
-
/**
|
|
903
|
-
* Forget everything this module holds for one session.
|
|
904
|
-
*
|
|
905
|
-
* ⚠️ THIS EXISTS SO NO CALLER HAS TO KNOW THE FIELD NAMES. The manager's cache eviction used to
|
|
906
|
-
* clear these five maps by hand, which made adding a sixth a silent bug waiting to happen — the
|
|
907
|
-
* kind that leaves a bounded, remote-fed map growing for the life of the process. One call now,
|
|
908
|
-
* and the list of what to forget lives beside the code that fills them.
|
|
909
|
-
*/
|
|
910
|
-
evictSession(agentName, sessionId) {
|
|
911
|
-
const key = this.#ctx.sessionKey(agentName, sessionId);
|
|
912
|
-
this.#terminallyRefused.delete(key);
|
|
913
|
-
this.#terminalRefusalsLoaded.delete(key);
|
|
914
|
-
this.#terminalRefusalsReadFailedAt.delete(key);
|
|
915
|
-
this.#unreadableAlgSeen.delete(key);
|
|
916
|
-
this.#refusedOnDirectPath.delete(key);
|
|
917
|
-
}
|
|
918
|
-
}
|
|
919
|
-
//# sourceMappingURL=inbound-refusals.js.map
|