@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/signal-handlers.js
DELETED
|
@@ -1,980 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The trust-signal surface: listing, viewing, enabling, disabling and revoking an agent's signals,
|
|
3
|
-
* issuing an attestation about someone else, the three consent verbs, and the results fetch that
|
|
4
|
-
* asks every directory in the roster what it holds.
|
|
5
|
-
*
|
|
6
|
-
* Twelve handlers plus the two helpers only they use — the selected-agent resolver and
|
|
7
|
-
* `submitForAgent`, the one path that composes, seals, sends and retries a submission. They lived
|
|
8
|
-
* inside `startDaemonHoldingLock` and closed over the daemon's state; here they NAME what they need.
|
|
9
|
-
*
|
|
10
|
-
* ⚠️ FOURTEEN MEMBERS, TWO OVER THE ORDER'S BOUND, AND THERE *IS* A SEAM. Measured, because the
|
|
11
|
-
* first version of this note asserted there was none — which is how a wrong comment survives. Four
|
|
12
|
-
* members have one consumer between them: roster, visiting connection and `waitForSignalingConnected`
|
|
13
|
-
* are `wallet_fetch_results` alone, the manifest is `submitForAgent` alone. Lift the results fetch
|
|
14
|
-
* out and eleven remain, under the bound. It is NOT lifted: it calls `resolveSelectedAgent`, so the
|
|
15
|
-
* split exports a deliberately-private helper or adds a third module, and each module costs the root
|
|
16
|
-
* another ~15-line call site — the failure the order names in bold: extraction that makes the root
|
|
17
|
-
* BIGGER. Two members are not worth that. Recorded so nobody has to re-measure it.
|
|
18
|
-
*
|
|
19
|
-
* Behavior is unchanged — bodies moved verbatim, comments included. The one edit: the per-connection
|
|
20
|
-
* state Map became `getConnState`, since these handlers only ever read one entry and the Map would
|
|
21
|
-
* hand this surface power to mutate connection state. Same narrowing as `contact-handlers.ts`.
|
|
22
|
-
*/
|
|
23
|
-
import { randomUUID } from "node:crypto";
|
|
24
|
-
import { checkAttestationBody, normalizeAttestationBody } from "./attestation-body.js";
|
|
25
|
-
import { decodeCbor } from "@cello-protocol/protocol-types";
|
|
26
|
-
import { CONSENT_ACCEPTED } from "./consent-migration.js";
|
|
27
|
-
import { revocabilityOf } from "./signal-revocability.js";
|
|
28
|
-
import { composeSealedSubmission, fetchSubmissionResults, sendSealedSubmission } from "./signal-submission.js";
|
|
29
|
-
import { DEFAULT_RETRY_WINDOW_MS, isRetryableSendFailure } from "./submission-retry.js";
|
|
30
|
-
import { TrustSignalStore } from "./trust-signal-store.js";
|
|
31
|
-
import { extractErrorMessage } from "./error-message.js";
|
|
32
|
-
/**
|
|
33
|
-
* Cap on a refusal message (M10B-D4). Generous for prose — the point is not to police what the
|
|
34
|
-
* operator writes, it is that an UNBOUNDED string reaches a signer, a sealer and a transport, and
|
|
35
|
-
* fails in the transport where the error names the wrong subsystem.
|
|
36
|
-
*/
|
|
37
|
-
const MAX_SUBMISSION_BODY_CHARS = 4000;
|
|
38
|
-
export function registerSignalHandlers(deps) {
|
|
39
|
-
const { handlers, logger, sessionNodeManager, keyProviders, onlineAgents, loadedAgents, getConnState, getAgentSignaling, openVisitingConnection, waitForSignalingConnected, resolveConsortiumRoster, verifiedManifest, submissionRetries, recordIssuedSubmission, } = deps;
|
|
40
|
-
handlers.set("wallet_list_signals", async (_params, _connectionId) => {
|
|
41
|
-
const store = new TrustSignalStore(sessionNodeManager.getDb(), logger);
|
|
42
|
-
const rows = store.listAllWalletSignals().map((r) => ({
|
|
43
|
-
type: r.type,
|
|
44
|
-
signal_hash: r.signalHash,
|
|
45
|
-
subject_kind: r.subjectKind,
|
|
46
|
-
subject: r.subject,
|
|
47
|
-
issuer_kind: r.issuerKind,
|
|
48
|
-
/**
|
|
49
|
-
* DOD-M15-SAMEOP-FALSEPOS-1: WHO ISSUED IT. The listing carried `subject` — who the signal is
|
|
50
|
-
* ABOUT — and never who SAID it, so an operator could see "someone endorsed me" and not see
|
|
51
|
-
* who. For the decision this list exists to support (do I rely on this endorsement?) the
|
|
52
|
-
* author is the primary fact, and an endorsement nobody can attribute is worth roughly
|
|
53
|
-
* nothing.
|
|
54
|
-
*
|
|
55
|
-
* `issuer_kind` reads like it answers this and does not: it says `"agent"` or `"portal"`, a
|
|
56
|
-
* category. Elsewhere a field literally named `issuer` holds `"peer-claimed"` /
|
|
57
|
-
* `"platform-verified"` — also a category. Two fields whose names promise identity, neither
|
|
58
|
-
* carrying it.
|
|
59
|
-
*
|
|
60
|
-
* It also unblocks an investigation this omission stalled: four endorsements in a wallet all
|
|
61
|
-
* read `same_operator: true`, and **nothing in the response could say whether the stranger's
|
|
62
|
-
* was among them** — so "a stranger is flagged as self-dealing" and "the stranger's
|
|
63
|
-
* endorsement never arrived" were indistinguishable from the listing. Different bugs, in
|
|
64
|
-
* different places, and the field that separates them was already in the row.
|
|
65
|
-
*
|
|
66
|
-
* Discloses nothing new: the issuer pubkey is inside the notarized envelope the recipient
|
|
67
|
-
* already holds and can already present.
|
|
68
|
-
*/
|
|
69
|
-
issuer_pubkey: r.issuerPubkey,
|
|
70
|
-
status: r.status,
|
|
71
|
-
issued_at: r.issuedAt,
|
|
72
|
-
expires_at: r.expiresAt,
|
|
73
|
-
supersedes_hash: r.supersedesHash,
|
|
74
|
-
default_present: r.defaultPresent,
|
|
75
|
-
// M10B / DOD-END-ACCEPT-1 review F4. Without this the operator cannot distinguish a signal
|
|
76
|
-
// that will be presented from one awaiting their decision — or one they already refused —
|
|
77
|
-
// because `default_present: true` looks identical in all three cases. `default_present`
|
|
78
|
-
// answers "include it by default"; this answers the prior question, "may it be presented at
|
|
79
|
-
// all".
|
|
80
|
-
consent_state: r.consentState,
|
|
81
|
-
// M10B / DOD-END-COUNT-1. The operator holds an endorsement whose worth is CAPPED — a
|
|
82
|
-
// recipient's floor excludes it from `min_count` — and until now nothing told them so. Two
|
|
83
|
-
// endorsements looked identical in this list while one could clear a counterparty's bar and the
|
|
84
|
-
// other could not, which is the kind of invisible difference that reads as the protocol being
|
|
85
|
-
// arbitrary. It is a portal-attested envelope field, so surfacing it discloses nothing the
|
|
86
|
-
// recipient will not already see.
|
|
87
|
-
same_operator: r.sameOperator,
|
|
88
|
-
}));
|
|
89
|
-
return { ok: true, signals: rows };
|
|
90
|
-
});
|
|
91
|
-
handlers.set("wallet_view_signal", async (params, _connectionId) => {
|
|
92
|
-
const prefix = typeof params?.hash_prefix === "string" ? params.hash_prefix : null;
|
|
93
|
-
if (!prefix || prefix.length < 8) {
|
|
94
|
-
return { ok: false, reason: "invalid_prefix", guidance: "hash_prefix must be at least 8 hex characters." };
|
|
95
|
-
}
|
|
96
|
-
const store = new TrustSignalStore(sessionNodeManager.getDb(), logger);
|
|
97
|
-
let row;
|
|
98
|
-
try {
|
|
99
|
-
row = store.getWalletSignalByPrefix(prefix);
|
|
100
|
-
}
|
|
101
|
-
catch (err) {
|
|
102
|
-
return { ok: false, reason: "ambiguous_prefix", guidance: extractErrorMessage(err) };
|
|
103
|
-
}
|
|
104
|
-
if (!row) {
|
|
105
|
-
return { ok: false, reason: "signal_not_found", guidance: `No wallet signal with hash prefix '${prefix}'.` };
|
|
106
|
-
}
|
|
107
|
-
let payload;
|
|
108
|
-
try {
|
|
109
|
-
payload = decodeCbor(row.payload);
|
|
110
|
-
}
|
|
111
|
-
catch {
|
|
112
|
-
payload = Buffer.from(row.payload).toString("hex");
|
|
113
|
-
}
|
|
114
|
-
return {
|
|
115
|
-
ok: true,
|
|
116
|
-
type: row.type,
|
|
117
|
-
signal_hash: row.signalHash,
|
|
118
|
-
subject_kind: row.subjectKind,
|
|
119
|
-
subject: row.subject,
|
|
120
|
-
issuer_kind: row.issuerKind,
|
|
121
|
-
issuer_pubkey: row.issuerPubkey,
|
|
122
|
-
schema_version: row.schemaVersion,
|
|
123
|
-
status: row.status,
|
|
124
|
-
default_present: row.defaultPresent,
|
|
125
|
-
consent_state: row.consentState, // review F4 — see wallet_list_signals
|
|
126
|
-
// CO-OWNERSHIP. The verb for reading a claim was the one surface that could not say the
|
|
127
|
-
// endorser and the subject share an owner. DECIDE ON THIS BOOLEAN — it is inside the notarized
|
|
128
|
-
// hash and always present; the portal's rendered sentence (payload `co_ownership_note`) is
|
|
129
|
-
// display only and is absent on anything minted before it existed.
|
|
130
|
-
same_operator: row.sameOperator,
|
|
131
|
-
issued_at: row.issuedAt,
|
|
132
|
-
expires_at: row.expiresAt,
|
|
133
|
-
supersedes_hash: row.supersedesHash,
|
|
134
|
-
payload,
|
|
135
|
-
};
|
|
136
|
-
});
|
|
137
|
-
handlers.set("wallet_enable_signal", async (params, _connectionId) => {
|
|
138
|
-
const prefix = typeof params?.hash_prefix === "string" ? params.hash_prefix : null;
|
|
139
|
-
if (!prefix || prefix.length < 8) {
|
|
140
|
-
return { ok: false, reason: "invalid_prefix", guidance: "hash_prefix must be at least 8 hex characters." };
|
|
141
|
-
}
|
|
142
|
-
const store = new TrustSignalStore(sessionNodeManager.getDb(), logger);
|
|
143
|
-
let row;
|
|
144
|
-
try {
|
|
145
|
-
row = store.getWalletSignalByPrefix(prefix);
|
|
146
|
-
}
|
|
147
|
-
catch (err) {
|
|
148
|
-
return { ok: false, reason: "ambiguous_prefix", guidance: extractErrorMessage(err) };
|
|
149
|
-
}
|
|
150
|
-
if (!row) {
|
|
151
|
-
return { ok: false, reason: "signal_not_found", guidance: `No wallet signal with hash prefix '${prefix}'.` };
|
|
152
|
-
}
|
|
153
|
-
// M10B / DOD-END-ACCEPT-1 review F4. Enabling a signal the subject has not accepted returned
|
|
154
|
-
// `{ok: true, default_present: true}` — the daemon affirming it will now be presented, when it
|
|
155
|
-
// never will. `default_present` selects from what is ELIGIBLE, and an unconsented signal is not
|
|
156
|
-
// eligible; saying yes here is a hollow success on the one verb that does respond.
|
|
157
|
-
if (row.consentState !== CONSENT_ACCEPTED) {
|
|
158
|
-
return {
|
|
159
|
-
ok: false,
|
|
160
|
-
reason: "consent_pending",
|
|
161
|
-
guidance: `This signal is '${row.consentState ?? "unset"}', not accepted, so it cannot be presented ` +
|
|
162
|
-
"regardless of the default-present flag. Accept it first; enabling it changes nothing until then.",
|
|
163
|
-
};
|
|
164
|
-
}
|
|
165
|
-
store.setDefaultPresent(row.signalHash, true);
|
|
166
|
-
return { ok: true, signal_hash: row.signalHash, default_present: true };
|
|
167
|
-
});
|
|
168
|
-
handlers.set("wallet_disable_signal", async (params, _connectionId) => {
|
|
169
|
-
const prefix = typeof params?.hash_prefix === "string" ? params.hash_prefix : null;
|
|
170
|
-
if (!prefix || prefix.length < 8) {
|
|
171
|
-
return { ok: false, reason: "invalid_prefix", guidance: "hash_prefix must be at least 8 hex characters." };
|
|
172
|
-
}
|
|
173
|
-
const store = new TrustSignalStore(sessionNodeManager.getDb(), logger);
|
|
174
|
-
let row;
|
|
175
|
-
try {
|
|
176
|
-
row = store.getWalletSignalByPrefix(prefix);
|
|
177
|
-
}
|
|
178
|
-
catch (err) {
|
|
179
|
-
return { ok: false, reason: "ambiguous_prefix", guidance: extractErrorMessage(err) };
|
|
180
|
-
}
|
|
181
|
-
if (!row) {
|
|
182
|
-
return { ok: false, reason: "signal_not_found", guidance: `No wallet signal with hash prefix '${prefix}'.` };
|
|
183
|
-
}
|
|
184
|
-
store.setDefaultPresent(row.signalHash, false);
|
|
185
|
-
return { ok: true, signal_hash: row.signalHash, default_present: false };
|
|
186
|
-
});
|
|
187
|
-
// ── M10B / DOD-END-SURFACE-1 — the consent verbs (D-23, M10B-D5) ───────────────────────────────
|
|
188
|
-
//
|
|
189
|
-
// SCOPED TO THE SELECTED AGENT, not to "the first loaded agent" the way wallet_revoke_signal is.
|
|
190
|
-
// Consent is a decision the SUBJECT makes about an object a third party wrote concerning them, so
|
|
191
|
-
// answering it on the wrong agent's behalf is not a cosmetic error — it is one agent deciding for
|
|
192
|
-
// another. The presenting-agent pubkey is also what the store's queries scope on, and passing the
|
|
193
|
-
// device-local agent_id instead now REFUSES rather than silently returning an empty queue.
|
|
194
|
-
const resolveSelectedAgent = (connectionId) => {
|
|
195
|
-
const name = getConnState(connectionId)?.currentAgent ?? null;
|
|
196
|
-
if (!name) {
|
|
197
|
-
return {
|
|
198
|
-
ok: false,
|
|
199
|
-
reason: "no_current_agent",
|
|
200
|
-
// NOT "a consent decision belongs to…" — this resolver is shared with the attestation verbs
|
|
201
|
-
// now, and `cello attestations issued` answered a plain "what happened to what I sent?" with
|
|
202
|
-
// an explanation about consent. Guidance that describes a different verb is worse than none:
|
|
203
|
-
// it sends the reader to fix something that was never wrong.
|
|
204
|
-
guidance: "Select an agent first (cello_use_agent) — these act AS a specific agent, and the wrong one would answer on another agent's behalf.",
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
const rec = loadedAgents.find((a) => a.name === name);
|
|
208
|
-
if (!rec) {
|
|
209
|
-
return { ok: false, reason: "agent_not_loaded", guidance: `Agent '${name}' is selected but not loaded on this daemon.` };
|
|
210
|
-
}
|
|
211
|
-
return { ok: true, name, pubkey: rec.pubkey };
|
|
212
|
-
};
|
|
213
|
-
/**
|
|
214
|
-
* Compose → seal → send ONE submission on behalf of the selected agent, applying every guard that
|
|
215
|
-
* must hold for any of them.
|
|
216
|
-
*
|
|
217
|
-
* Extracted because `refuse` and `issue` are the same journey with a different `op`, and a second
|
|
218
|
-
* hand-written copy is how two paths that must agree stop agreeing. The guards are the point: an
|
|
219
|
-
* agent that is not started must not be brought online by a side effect, an unbounded body must
|
|
220
|
-
* not reach the transport, and the CAUSE of a refusal must survive to the operator. Duplicating
|
|
221
|
-
* those means the next verb gets whichever subset its author remembered.
|
|
222
|
-
*
|
|
223
|
-
* INV-ATTRIBUTION holds BY CONSTRUCTION, and it did not before: this used to take the resolved
|
|
224
|
-
* `sel` as a parameter, which is exactly a parameter through which a caller could name a different
|
|
225
|
-
* identity. Both call sites happened to pass the right one, so the invariant held by CONVENTION
|
|
226
|
-
* while the comment claimed structure — and the test that "pinned" it asserted the absence of two
|
|
227
|
-
* identifiers that had never existed, so it could not fail. It now takes `connectionId` and
|
|
228
|
-
* resolves the selection itself. There is no identity input left to get wrong.
|
|
229
|
-
*/
|
|
230
|
-
async function submitForAgent(opts) {
|
|
231
|
-
const { context } = opts;
|
|
232
|
-
const resolved = resolveSelectedAgent(opts.connectionId);
|
|
233
|
-
if (!resolved.ok)
|
|
234
|
-
return { queued: false, reason: resolved.reason, guidance: `${context} ${resolved.guidance}` };
|
|
235
|
-
const sel = resolved;
|
|
236
|
-
if (opts.body.length > MAX_SUBMISSION_BODY_CHARS) {
|
|
237
|
-
return { queued: false, reason: "message_too_long",
|
|
238
|
-
guidance: `${context} it is ${opts.body.length} characters and the limit is ${MAX_SUBMISSION_BODY_CHARS}.` };
|
|
239
|
-
}
|
|
240
|
-
// `getAgentSignaling` is NOT a getter — for an agent with no manager it CONSTRUCTS one, which
|
|
241
|
-
// dials and authenticates to the directory immediately and installs an unbounded reconnect loop.
|
|
242
|
-
// Calling it on a stopped agent would silently bring it online: the directory would route
|
|
243
|
-
// sessions to it while no standing receiver exists (`standing_receiver_unavailable`), and
|
|
244
|
-
// `cello status` would still report it offline.
|
|
245
|
-
if (!onlineAgents.has(sel.name)) {
|
|
246
|
-
return { queued: false, reason: "agent_offline",
|
|
247
|
-
guidance: `${context} agent '${sel.name}' is not started. Run cello_start_agent and try again — re-sending is safe, the submission id is derived from the content.` };
|
|
248
|
-
}
|
|
249
|
-
const kp = keyProviders.get(sel.name);
|
|
250
|
-
if (!kp) {
|
|
251
|
-
logger.warn("signal.submission.refused", { agentName: sel.name, reason: "key_provider_absent", op: opts.op });
|
|
252
|
-
return { queued: false, reason: "key_provider_absent",
|
|
253
|
-
guidance: `${context} no signing key is loaded for '${sel.name}'.` };
|
|
254
|
-
}
|
|
255
|
-
try {
|
|
256
|
-
const composed = await composeSealedSubmission({
|
|
257
|
-
manifest: verifiedManifest, keyProvider: kp, op: opts.op,
|
|
258
|
-
subjectKind: opts.subjectKind, subject: opts.subject, body: opts.body,
|
|
259
|
-
issuedAt: Math.floor(Date.now() / 1000), logger,
|
|
260
|
-
});
|
|
261
|
-
if (!composed.ok) {
|
|
262
|
-
// ERRORS NAME THEIR CAUSE: manifest_unavailable / manifest_expired / intake_key_absent /
|
|
263
|
-
// intake_key_malformed each say WHICH check refused, and that survives rather than
|
|
264
|
-
// collapsing into a generic send failure that points at the network.
|
|
265
|
-
return { queued: false, reason: composed.reason, guidance: `${context} ${composed.guidance}` };
|
|
266
|
-
}
|
|
267
|
-
// Resolved ONCE, and carried. `agent_name` is a display label and is reusable after a
|
|
268
|
-
// retire; every row and every queue entry below keys on this stable id instead.
|
|
269
|
-
const agentId = sessionNodeManager.resolveAgentId(sel.name);
|
|
270
|
-
const sent = await sendSealedSubmission({
|
|
271
|
-
signaling: getAgentSignaling(sel.name, kp, sel.pubkey).signaling,
|
|
272
|
-
submissionId: composed.submissionId, intakeKeyId: composed.intakeKeyId,
|
|
273
|
-
ciphertext: composed.ciphertext, logger,
|
|
274
|
-
});
|
|
275
|
-
if (!sent.ok) {
|
|
276
|
-
// DOD-M15-ENDORSE-RETRY-1 — WORTH RETRYING, OR A VERDICT? The typed failure decides, never
|
|
277
|
-
// a string match. `submission_refused_by_node` means a node decoded it, evaluated it and
|
|
278
|
-
// said no, and it falls straight through to the plain failure below; everything else means
|
|
279
|
-
// no node ever reached a decision, so the daemon keeps it and re-sends on the reconnect.
|
|
280
|
-
/**
|
|
281
|
-
* DO NOT HOLD A BLOB PAST ITS OWN INTAKE KEY (review M4).
|
|
282
|
-
*
|
|
283
|
-
* The sealed bytes are opened by the portal's intake key from THIS manifest. Holding them
|
|
284
|
-
* across that key's expiry produces a submission the portal cannot open and cannot even
|
|
285
|
-
* attribute — poison, with no reply possible — while the operator has been told it is held
|
|
286
|
-
* and needs nothing from them. The plain failure is the better answer: they re-run it once
|
|
287
|
-
* a current manifest is loaded, and they know to.
|
|
288
|
-
*
|
|
289
|
-
* The manifest is in hand here and nowhere inside the queue, which is why the check lives
|
|
290
|
-
* at the call site rather than in the module that owns the window.
|
|
291
|
-
*/
|
|
292
|
-
const manifestExpiresAt = verifiedManifest ? Date.parse(verifiedManifest.expires) : NaN;
|
|
293
|
-
const keyOutlivesWindow = Number.isFinite(manifestExpiresAt) && manifestExpiresAt - Date.now() > DEFAULT_RETRY_WINDOW_MS;
|
|
294
|
-
if (!keyOutlivesWindow) {
|
|
295
|
-
logger.warn("signal.submission.retry.not_held", {
|
|
296
|
-
agentName: sel.name,
|
|
297
|
-
submissionId: composed.submissionId,
|
|
298
|
-
reason: "intake_key_expires_within_retry_window",
|
|
299
|
-
manifestExpires: verifiedManifest?.expires ?? null,
|
|
300
|
-
impact: "the operator is told it failed rather than being told it is held",
|
|
301
|
-
});
|
|
302
|
-
return {
|
|
303
|
-
queued: false,
|
|
304
|
-
reason: sent.reason,
|
|
305
|
-
guidance: `${context} it did not reach a directory node (${sent.reason}), and the daemon is NOT ` +
|
|
306
|
-
"holding it to retry: the portal intake key it is sealed to expires too soon, and a " +
|
|
307
|
-
"submission sent after that expires is one the portal cannot open or even attribute. " +
|
|
308
|
-
"Load a current consortium manifest (cello_status shows its validity), then send it again.",
|
|
309
|
-
};
|
|
310
|
-
}
|
|
311
|
-
if (isRetryableSendFailure(sent.reason)) {
|
|
312
|
-
const held = submissionRetries.enqueue({
|
|
313
|
-
agentName: sel.name,
|
|
314
|
-
agentId,
|
|
315
|
-
submissionId: composed.submissionId,
|
|
316
|
-
intakeKeyId: composed.intakeKeyId,
|
|
317
|
-
// THE SAME SEALED BYTES, carried rather than re-derived. A re-seal is randomised and a
|
|
318
|
-
// re-compose would take a new `issued_at` — which changes the content-derived id, and
|
|
319
|
-
// a changed id is a second endorsement rather than a retry.
|
|
320
|
-
ciphertext: composed.ciphertext,
|
|
321
|
-
op: opts.op,
|
|
322
|
-
subject: opts.subject,
|
|
323
|
-
}, sent.reason);
|
|
324
|
-
if (held) {
|
|
325
|
-
return {
|
|
326
|
-
queued: false,
|
|
327
|
-
retrying: true,
|
|
328
|
-
submissionId: composed.submissionId,
|
|
329
|
-
reason: sent.reason,
|
|
330
|
-
guidance: `${context.replace(/:$/, "")} — not yet. It did not reach a directory node ` +
|
|
331
|
-
`(${sent.reason}), so the daemon is holding it and will send it as soon as the ` +
|
|
332
|
-
"directory signaling stream is back, on whichever node that is. You do NOT need to " +
|
|
333
|
-
"run this again. Run cello_attestations_issued to see where it got to. It is held IN " +
|
|
334
|
-
"MEMORY, so if the daemon restarts before it lands you will have to write it again.",
|
|
335
|
-
};
|
|
336
|
-
}
|
|
337
|
-
// The queue is full, so nothing is holding it and saying otherwise would be a lie the
|
|
338
|
-
// operator acts on. They get the plain failure and the fact that re-sending is safe.
|
|
339
|
-
}
|
|
340
|
-
return { queued: false, reason: sent.reason, guidance: `${context} ${sent.guidance ?? sent.reason}` };
|
|
341
|
-
}
|
|
342
|
-
// F4: `sendSealedSubmission` ALREADY logs `signal.submission.queued` / `.duplicate`. Logging
|
|
343
|
-
// `queued` again here doubled every count-based alarm and, worse, emitted `queued` right after
|
|
344
|
-
// `duplicate` — partially erasing the very distinction the directory's queue repository exists
|
|
345
|
-
// to preserve. A distinct name, only for what the send layer does not know (which agent, which
|
|
346
|
-
// op).
|
|
347
|
-
logger.info("signal.submission.attributed", {
|
|
348
|
-
agentName: sel.name, op: opts.op, submissionId: composed.submissionId, stored: sent.stored,
|
|
349
|
-
});
|
|
350
|
-
// KEEP THE HANDLE, or a withdrawal has nothing to name. Recorded in the SHARED path so every
|
|
351
|
-
// verb added after this one is covered by construction, which is the same reasoning as the
|
|
352
|
-
// `storedWarning` below — and by the same helper the RETRY path uses, so the two cannot drift
|
|
353
|
-
// about what a landed submission records.
|
|
354
|
-
// A LANDED SEND RETIRES AN EARLIER GIVE-UP for the same submission. The id is content-derived,
|
|
355
|
-
// so re-issuing the same words about the same subject produces the same id — this is the "I
|
|
356
|
-
// wrote it again and it worked" case, and leaving the stale failure on the surface would show
|
|
357
|
-
// the operator two contradictory states for one submission, forever.
|
|
358
|
-
submissionRetries.clearGaveUp(agentId, composed.submissionId);
|
|
359
|
-
recordIssuedSubmission(sel.name, agentId, {
|
|
360
|
-
submissionId: composed.submissionId,
|
|
361
|
-
subject: opts.subject,
|
|
362
|
-
op: opts.op,
|
|
363
|
-
intakeKeyId: composed.intakeKeyId,
|
|
364
|
-
stored: sent.stored,
|
|
365
|
-
});
|
|
366
|
-
// F1: `stored: false` means a node reports it ALREADY HELD this submission id. That is either
|
|
367
|
-
// a benign retry or single-node censorship — an operator pre-inserting garbage under a
|
|
368
|
-
// clear-text id — and they are indistinguishable from here. Reporting it as unqualified
|
|
369
|
-
// success is what makes the attack silent. The warning lives in the SHARED path, not at one
|
|
370
|
-
// call site, because the refuse verb had it and the issue verb did not: the same omission
|
|
371
|
-
// would otherwise be available to every verb added after this one.
|
|
372
|
-
return {
|
|
373
|
-
queued: true, stored: sent.stored, submissionId: composed.submissionId,
|
|
374
|
-
...(sent.stored ? {} : {
|
|
375
|
-
storedWarning: "A directory node accepted it but reports it already held this submission id. If nothing arrives for the recipient, send it again — re-sending is safe, the submission id is derived from the content.",
|
|
376
|
-
}),
|
|
377
|
-
};
|
|
378
|
-
}
|
|
379
|
-
catch (err) {
|
|
380
|
-
const reason = extractErrorMessage(err);
|
|
381
|
-
logger.warn("signal.submission.refused", { agentName: sel.name, op: opts.op, reason });
|
|
382
|
-
return { queued: false, reason, guidance: `${context} ${reason}` };
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
/**
|
|
386
|
-
* M10B / DOD-END-SURFACE-1 — issue a trust signal ABOUT a counterparty.
|
|
387
|
-
*
|
|
388
|
-
* NOTE WHAT IS NOT HERE: a `type` parameter, and the word "endorsement" anywhere in the path. The
|
|
389
|
-
* submission wire carries no type field — the PORTAL decides what it mints from a submission — so
|
|
390
|
-
* a second client-sourced type needs no new verb, no new parameter and no client change. That is
|
|
391
|
-
* INV-ZEROBUMP holding by construction rather than by discipline, and it is what
|
|
392
|
-
* `DOD-END-PLAYBOOK-1` has to prove with an empty diff.
|
|
393
|
-
*
|
|
394
|
-
* The subject is the counterparty's K_local pubkey: the only identifier a contact actually holds.
|
|
395
|
-
* No account identifier crosses the wire — the portal resolves agent → account at intake, and the
|
|
396
|
-
* directory is hash-only by design.
|
|
397
|
-
*/
|
|
398
|
-
// M10B / DOD-END-SURFACE-1 — "see what I have submitted about others". The wallet list answers
|
|
399
|
-
// "what do people say about ME"; this answers the other direction, and it is the prerequisite for
|
|
400
|
-
// withdrawal: you cannot withdraw a submission you cannot name.
|
|
401
|
-
// M10B / `M10B-D25r2` — collect this agent's outcomes from the directory and open any sealed
|
|
402
|
-
// message with k_local. Separate from `wallet_list_issued` because it is a NETWORK call: listing
|
|
403
|
-
// what you submitted must keep working when the directory is unreachable, and folding a fetch into
|
|
404
|
-
// it would make a local read fail for a remote reason.
|
|
405
|
-
handlers.set("wallet_fetch_results", async (_params, connectionId) => {
|
|
406
|
-
const sel = resolveSelectedAgent(connectionId);
|
|
407
|
-
if (!sel.ok)
|
|
408
|
-
return sel;
|
|
409
|
-
const kp = keyProviders.get(sel.name);
|
|
410
|
-
if (!kp) {
|
|
411
|
-
return { ok: false, reason: "agent_not_loaded",
|
|
412
|
-
guidance: `Agent '${sel.name}' has no key loaded, so a sealed result could not be opened. Restart the daemon and select the agent again.` };
|
|
413
|
-
}
|
|
414
|
-
// ── ASK EVERY NODE, AND SAY WHICH ONES DID NOT ANSWER ─────────────────────────────────────────
|
|
415
|
-
// An outcome is recorded on whichever node accepted the submission, and this agent is connected
|
|
416
|
-
// to ONE node — routinely not the same one. Asking only home turns "your refusal is on another
|
|
417
|
-
// node" into "you have no results", which is the answer that makes a counterparty look silent
|
|
418
|
-
// when they were not.
|
|
419
|
-
//
|
|
420
|
-
// A NODE THAT DOES NOT ANSWER IS `unreachable`, NEVER an empty result. If a timeout collapsed
|
|
421
|
-
// into "nothing here", a down node could silently produce a negative answer — the same lie in a
|
|
422
|
-
// new place. The caller is told what was actually covered.
|
|
423
|
-
const seen = new Map();
|
|
424
|
-
const unreachable = [];
|
|
425
|
-
function mapResult(r) {
|
|
426
|
-
return {
|
|
427
|
-
submission_id: r.submissionId,
|
|
428
|
-
outcome: r.outcome,
|
|
429
|
-
reason: r.reason,
|
|
430
|
-
signal_hash: r.signalHash,
|
|
431
|
-
message: r.message,
|
|
432
|
-
created_at: r.createdAt,
|
|
433
|
-
};
|
|
434
|
-
}
|
|
435
|
-
const opener = kp;
|
|
436
|
-
// Home node first — it needs no connection and answers fastest.
|
|
437
|
-
const home = await fetchSubmissionResults({
|
|
438
|
-
signaling: getAgentSignaling(sel.name, kp, sel.pubkey).signaling,
|
|
439
|
-
keyProvider: opener,
|
|
440
|
-
logger,
|
|
441
|
-
});
|
|
442
|
-
if (home.ok)
|
|
443
|
-
for (const r of home.results)
|
|
444
|
-
seen.set(r.submissionId, mapResult(r));
|
|
445
|
-
else
|
|
446
|
-
unreachable.push("home");
|
|
447
|
-
// Then every OTHER node in the consortium, over a transient visiting connection — the same
|
|
448
|
-
// mechanism a cross-node session uses. Each is independent: one node refusing to answer must not
|
|
449
|
-
// stop the others being asked.
|
|
450
|
-
const roster = (await resolveConsortiumRoster().catch(() => null)) ?? [];
|
|
451
|
-
for (const node of roster) {
|
|
452
|
-
let visit = null;
|
|
453
|
-
try {
|
|
454
|
-
visit = openVisitingConnection(sel.name, kp, sel.pubkey, { peerId: node.peerId, multiaddr: node.multiaddr }, randomUUID(), node.nodeId);
|
|
455
|
-
// WAIT FOR THE CONNECTION BEFORE USING IT. openVisitingConnection returns SYNCHRONOUSLY and the
|
|
456
|
-
// manager dials in the background, so asking it for results on the next line finds it still
|
|
457
|
-
// connecting and gets `signaling_reconnecting` — every node, instantly. Observed live once the
|
|
458
|
-
// environment was awake: three regions "unreachable" within 3ms of each other, which no real
|
|
459
|
-
// network failure looks like. The seal-broker path above already does this; this one did not.
|
|
460
|
-
if (!(await waitForSignalingConnected(visit.mgr, 10_000))) {
|
|
461
|
-
logger.warn("signal.results.node.unreachable", { nodeId: node.nodeId, reason: "visiting_connect_timeout" });
|
|
462
|
-
unreachable.push(node.nodeId);
|
|
463
|
-
continue;
|
|
464
|
-
}
|
|
465
|
-
const r = await fetchSubmissionResults({ signaling: visit.mgr, keyProvider: opener, logger });
|
|
466
|
-
if (r.ok)
|
|
467
|
-
for (const x of r.results) {
|
|
468
|
-
if (!seen.has(x.submissionId))
|
|
469
|
-
seen.set(x.submissionId, mapResult(x));
|
|
470
|
-
}
|
|
471
|
-
else {
|
|
472
|
-
// SAY WHY. `unreachable` is a list of node ids and nothing else, so a sweep that fails
|
|
473
|
-
// everywhere reports "all three unreachable" with the cause discarded at the exact point it
|
|
474
|
-
// was known — leaving the only evidence to be guessed at afterwards.
|
|
475
|
-
logger.warn("signal.results.node.unreachable", { nodeId: node.nodeId, reason: r.reason });
|
|
476
|
-
unreachable.push(node.nodeId);
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
catch (err) {
|
|
480
|
-
logger.warn("signal.results.node.unreachable", {
|
|
481
|
-
nodeId: node.nodeId,
|
|
482
|
-
reason: extractErrorMessage(err),
|
|
483
|
-
});
|
|
484
|
-
unreachable.push(node.nodeId);
|
|
485
|
-
}
|
|
486
|
-
finally {
|
|
487
|
-
// ALWAYS torn down. A visiting connection left open holds a stream the directory will drain
|
|
488
|
-
// its durable notification queue down — the bug this connection type has already caused once.
|
|
489
|
-
await visit?.stop("results fetch complete").catch(() => { });
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
if (seen.size === 0 && unreachable.length > 0 && unreachable.length >= roster.length) {
|
|
493
|
-
// EVERY node we tried failed. Reporting an empty list here would be the exact lie this fan-out
|
|
494
|
-
// exists to prevent.
|
|
495
|
-
//
|
|
496
|
-
// AN EMPTY ROSTER IS ITS OWN ANSWER. `resolveConsortiumRoster()` returns null when there is no
|
|
497
|
-
// current manifest, and `?? []` turns "I do not know of any other nodes" into "there are no
|
|
498
|
-
// other nodes" — so a daemon that cannot resolve the consortium at all reported "No directory
|
|
499
|
-
// node answered (home)", which reads as one bad node rather than as no map. Chasing that cost
|
|
500
|
-
// real time against a hibernated environment on 2026-07-31.
|
|
501
|
-
const noRoster = roster.length === 0;
|
|
502
|
-
return {
|
|
503
|
-
ok: false,
|
|
504
|
-
reason: noRoster ? "consortium_unresolved" : "results_unreachable",
|
|
505
|
-
guidance: noRoster
|
|
506
|
-
? `This daemon cannot resolve any directory node right now, so there was nowhere to ask (${unreachable.join(", ")} also failed). Check that the directory is reachable — 'directory.consortium.node.unresolved' in the daemon log names each endpoint and why. Your outcomes are held until you collect them; nothing is lost.`
|
|
507
|
-
: `No directory node answered (${unreachable.join(", ")}). Your outcomes are held until you collect them — nothing is lost. Retry when connectivity returns.`,
|
|
508
|
-
};
|
|
509
|
-
}
|
|
510
|
-
return {
|
|
511
|
-
ok: true,
|
|
512
|
-
// WHAT WAS ACTUALLY COVERED. An empty list from a partial sweep means "nothing on the nodes we
|
|
513
|
-
// reached", which is a different claim from "nothing exists".
|
|
514
|
-
...(unreachable.length > 0 ? { unreachable_nodes: unreachable } : {}),
|
|
515
|
-
results: [...seen.values()],
|
|
516
|
-
};
|
|
517
|
-
});
|
|
518
|
-
handlers.set("wallet_list_issued", async (_params, connectionId) => {
|
|
519
|
-
const sel = resolveSelectedAgent(connectionId);
|
|
520
|
-
if (!sel.ok)
|
|
521
|
-
return sel;
|
|
522
|
-
const agentId = sessionNodeManager.resolveAgentId(sel.name);
|
|
523
|
-
const store = new TrustSignalStore(sessionNodeManager.getDb(), logger);
|
|
524
|
-
const rows = store.listIssuedSubmissions(agentId).map((r) => ({
|
|
525
|
-
submission_id: r.submissionId,
|
|
526
|
-
subject_pubkey: r.subjectPubkey,
|
|
527
|
-
op: r.op,
|
|
528
|
-
intake_key_id: r.intakeKeyId,
|
|
529
|
-
// Every row in this table reached a node. The in-flight ones below have not.
|
|
530
|
-
delivery: "accepted",
|
|
531
|
-
// FALSE means a node already held this id — a benign retry, or single-node censorship. The
|
|
532
|
-
// operator sees the distinction here rather than only in the moment they submitted.
|
|
533
|
-
stored: r.stored,
|
|
534
|
-
submitted_at: r.submittedAt,
|
|
535
|
-
}));
|
|
536
|
-
/**
|
|
537
|
-
* DOD-M15-ENDORSE-RETRY-1 — THE SUBMISSIONS THAT REACHED NO NODE, listed here because this is
|
|
538
|
-
* the verb whose whole question is "what happened to what I sent?".
|
|
539
|
-
*
|
|
540
|
-
* Without them a submission the daemon is retrying is INVISIBLE — the durable table only gets a
|
|
541
|
-
* row once a node accepted one — so the honest answer to that question was silence, which reads
|
|
542
|
-
* as "you sent nothing". And a give-up whose only consumer is a warn line in `daemon.log` is
|
|
543
|
-
* indistinguishable from the submission never having existed.
|
|
544
|
-
*
|
|
545
|
-
* These are IN MEMORY and do not survive a daemon restart (see submission-retry.ts). That is
|
|
546
|
-
* why they are a separate array rather than blended into `issued`: a caller must be able to
|
|
547
|
-
* tell a durable fact from a live one.
|
|
548
|
-
*/
|
|
549
|
-
const inFlight = submissionRetries.list(agentId).map((p) => ({
|
|
550
|
-
submission_id: p.submissionId,
|
|
551
|
-
subject_pubkey: p.subject,
|
|
552
|
-
op: p.op,
|
|
553
|
-
intake_key_id: p.intakeKeyId,
|
|
554
|
-
delivery: p.delivery.state,
|
|
555
|
-
attempts: p.delivery.attempts,
|
|
556
|
-
last_reason: p.delivery.lastReason,
|
|
557
|
-
...(p.delivery.state === "gave_up" ? { gave_up_because: p.delivery.gaveUpBecause } : {}),
|
|
558
|
-
guidance: p.delivery.guidance,
|
|
559
|
-
}));
|
|
560
|
-
return {
|
|
561
|
-
ok: true,
|
|
562
|
-
issued: rows,
|
|
563
|
-
in_flight: inFlight,
|
|
564
|
-
// NO BODY, and say so rather than letting its absence read as a bug. The text was the
|
|
565
|
-
// operator's own words about a third party; keeping it on disk in the clear is exactly what
|
|
566
|
-
// the sealed-submission path exists to prevent.
|
|
567
|
-
note: "The text you wrote is NOT stored locally — only the handle, subject and verb. That is deliberate: your words about someone else are sealed to the portal and are not kept in the clear on this machine.",
|
|
568
|
-
};
|
|
569
|
-
});
|
|
570
|
-
handlers.set("cello_attestations_issue", async (params, connectionId) => {
|
|
571
|
-
const sel = resolveSelectedAgent(connectionId);
|
|
572
|
-
if (!sel.ok)
|
|
573
|
-
return sel;
|
|
574
|
-
const subject = typeof params?.subject_pubkey === "string" ? params.subject_pubkey.toLowerCase() : "";
|
|
575
|
-
if (!/^[0-9a-f]{64}$/.test(subject)) {
|
|
576
|
-
return { ok: false, reason: "invalid_subject",
|
|
577
|
-
guidance: "subject_pubkey must be the counterparty's 32-byte public key as 64 hex characters — run cello_contacts to see the peers you know." };
|
|
578
|
-
}
|
|
579
|
-
// Normalised then checked locally — see attestation-body.ts (047-ENDORSETEXT). The portal
|
|
580
|
-
// stays the authority; this only spares an honest mistake a round trip.
|
|
581
|
-
const body = normalizeAttestationBody(typeof params?.body === "string" ? params.body : "");
|
|
582
|
-
if (body.length === 0) {
|
|
583
|
-
return { ok: false, reason: "empty_body",
|
|
584
|
-
guidance: "An issued signal needs text — it is the claim you are making about them, in your own words." };
|
|
585
|
-
}
|
|
586
|
-
const bodyRefusal = checkAttestationBody(body);
|
|
587
|
-
if (bodyRefusal)
|
|
588
|
-
return { ok: false, ...bodyRefusal };
|
|
589
|
-
// SELF is refused: issuer and subject are one identity, so there is no fact to weigh.
|
|
590
|
-
//
|
|
591
|
-
// CO-OWNERSHIP IS NOT — it is ANNOTATED (portal D-29). Minting it unflagged is the farming hole;
|
|
592
|
-
// refusing it discards a true fact AND closes the path the first wedge walks daily, since solo
|
|
593
|
-
// multi-agent is the most likely way to hit this. The daemon cannot see account linkage anyway
|
|
594
|
-
// — two agents under one account on different machines are invisible here — and the portal can.
|
|
595
|
-
if (subject === sel.pubkey.toLowerCase()) {
|
|
596
|
-
return { ok: false, reason: "self_subject",
|
|
597
|
-
guidance: "An agent cannot issue a trust signal about itself — standing has to come from somebody else." };
|
|
598
|
-
}
|
|
599
|
-
const res = await submitForAgent({
|
|
600
|
-
connectionId,
|
|
601
|
-
op: "submit", subjectKind: "agent", subject, body,
|
|
602
|
-
context: "The signal was NOT submitted:",
|
|
603
|
-
});
|
|
604
|
-
// DOD-M15-ENDORSE-RETRY-1 — `ok: true` with `delivery: "retrying"`, and both halves are
|
|
605
|
-
// deliberate. `ok: false` would send the agent to re-run a command the daemon is already
|
|
606
|
-
// handling, which is the exact operator work this unit exists to remove; `queued: true` would
|
|
607
|
-
// claim a directory node accepted something no node has seen. So: not a failure, not an
|
|
608
|
-
// acceptance, and named.
|
|
609
|
-
if (!res.queued && res.retrying) {
|
|
610
|
-
return {
|
|
611
|
-
ok: true, queued: false, delivery: "retrying",
|
|
612
|
-
submission_id: res.submissionId, reason: res.reason, guidance: res.guidance,
|
|
613
|
-
};
|
|
614
|
-
}
|
|
615
|
-
if (!res.queued)
|
|
616
|
-
return { ok: false, reason: res.reason, guidance: res.guidance };
|
|
617
|
-
return {
|
|
618
|
-
ok: true, queued: true, delivery: "accepted", stored: res.stored, submission_id: res.submissionId,
|
|
619
|
-
// Deliberately NOT "issued". Nothing is minted yet: the portal must still drain, authenticate,
|
|
620
|
-
// scan and mint, and the subject must then ACCEPT it before anyone else can see it. Reporting
|
|
621
|
-
// this as a completed endorsement would promise three steps that have not happened.
|
|
622
|
-
guidance: res.storedWarning
|
|
623
|
-
? `Submitted for '${sel.name}'. ${res.storedWarning}`
|
|
624
|
-
: `Submitted for '${sel.name}'. The portal will scan and mint it, and it stays invisible to everyone unless the subject ACCEPTS it — they are free to refuse, and a signal they have not accepted is inert. Nothing here is final until they decide.`,
|
|
625
|
-
};
|
|
626
|
-
});
|
|
627
|
-
/**
|
|
628
|
-
* M10B / DOD-END-SURFACE-1 — per-counterparty presentation choice.
|
|
629
|
-
*
|
|
630
|
-
* `present: null` CLEARS the choice rather than setting it false. Those are different states and
|
|
631
|
-
* the surface must keep them apart: cleared means "no opinion, use the signal's default", false
|
|
632
|
-
* means "specifically not this person". An operator who could only toggle true/false would be
|
|
633
|
-
* unable to undo an omission without first knowing what the default had been.
|
|
634
|
-
*/
|
|
635
|
-
handlers.set("cello_contact_set_signal", async (params, connectionId) => {
|
|
636
|
-
const sel = resolveSelectedAgent(connectionId);
|
|
637
|
-
if (!sel.ok)
|
|
638
|
-
return sel;
|
|
639
|
-
const pubkey = typeof params?.pubkey === "string" ? params.pubkey.toLowerCase() : "";
|
|
640
|
-
if (!/^[0-9a-f]{64}$/.test(pubkey)) {
|
|
641
|
-
return { ok: false, reason: "invalid_pubkey", guidance: "pubkey must be the counterparty's 32-byte public key as 64 hex characters." };
|
|
642
|
-
}
|
|
643
|
-
const prefix = typeof params?.hash_prefix === "string" ? params.hash_prefix : "";
|
|
644
|
-
if (prefix.length < 8) {
|
|
645
|
-
return { ok: false, reason: "invalid_prefix", guidance: "hash_prefix must be at least 8 hex characters — see cello_trust_signals_list." };
|
|
646
|
-
}
|
|
647
|
-
const present = params?.present === null ? null : typeof params?.present === "boolean" ? params.present : undefined;
|
|
648
|
-
if (present === undefined) {
|
|
649
|
-
return { ok: false, reason: "invalid_present", guidance: "present must be true (show it to them), false (never show it to them), or null (clear the choice and fall back to the signal's default)." };
|
|
650
|
-
}
|
|
651
|
-
// Resolve the prefix against signals this agent actually holds, so a typo cannot silently write
|
|
652
|
-
// a preference about a hash that does not exist and sit there doing nothing forever.
|
|
653
|
-
const store = new TrustSignalStore(sessionNodeManager.getDb(), logger);
|
|
654
|
-
const match = store.listAllWalletSignals().filter((r) => r.signalHash.startsWith(prefix));
|
|
655
|
-
if (match.length === 0) {
|
|
656
|
-
return { ok: false, reason: "signal_not_found", guidance: `No signal in this wallet starts with '${prefix}'.` };
|
|
657
|
-
}
|
|
658
|
-
if (match.length > 1) {
|
|
659
|
-
return { ok: false, reason: "ambiguous_prefix", guidance: `'${prefix}' matches ${match.length} signals — use more characters.` };
|
|
660
|
-
}
|
|
661
|
-
sessionNodeManager.setContactSignalPref(sel.name, pubkey, match[0].signalHash, present);
|
|
662
|
-
return {
|
|
663
|
-
ok: true, signal_hash: match[0].signalHash, pubkey, present,
|
|
664
|
-
guidance: present === null
|
|
665
|
-
? "Choice cleared — this signal now follows its own default for this contact."
|
|
666
|
-
: present
|
|
667
|
-
? "This signal will be presented to this contact when a session forms, if you have accepted it."
|
|
668
|
-
: "This signal will NOT be presented to this contact, whatever its default.",
|
|
669
|
-
};
|
|
670
|
-
});
|
|
671
|
-
handlers.set("cello_attestation_consent_list", async (_params, connectionId) => {
|
|
672
|
-
const sel = resolveSelectedAgent(connectionId);
|
|
673
|
-
if (!sel.ok)
|
|
674
|
-
return sel;
|
|
675
|
-
const store = new TrustSignalStore(sessionNodeManager.getDb(), logger);
|
|
676
|
-
const items = store.listPendingConsent(sel.pubkey).map((r) => {
|
|
677
|
-
// THE PAYLOAD IS THE POINT OF THIS CALL. The operator is being asked to stand behind a claim
|
|
678
|
-
// somebody else wrote about them, and they cannot make that decision from a byte count. An
|
|
679
|
-
// earlier version returned `payload_bytes` while both surfaces instructed the operator to
|
|
680
|
-
// "read the plaintext before accepting" — so following the instruction produced a number, and
|
|
681
|
-
// accepting was necessarily blind. Decoded here, exactly as `wallet_view_signal` does it.
|
|
682
|
-
//
|
|
683
|
-
// Undecodable payloads fall back to hex rather than throwing: one unreadable item must not
|
|
684
|
-
// make every other pending decision unreachable, and hex is honest about what it is.
|
|
685
|
-
let payload;
|
|
686
|
-
try {
|
|
687
|
-
payload = decodeCbor(r.payload);
|
|
688
|
-
}
|
|
689
|
-
catch {
|
|
690
|
-
payload = Buffer.from(r.payload).toString("hex");
|
|
691
|
-
}
|
|
692
|
-
return {
|
|
693
|
-
signal_hash: r.signalHash,
|
|
694
|
-
type: r.type,
|
|
695
|
-
subject_kind: r.subjectKind,
|
|
696
|
-
issuer_kind: r.issuerKind,
|
|
697
|
-
issuer_pubkey: r.issuerPubkey,
|
|
698
|
-
issued_at: r.issuedAt,
|
|
699
|
-
// UNTRUSTED, and labelled as such on the way out. These are the issuer's own words, carried
|
|
700
|
-
// verbatim and never restated in any other voice (INV-UNTRUSTED). A consuming model must
|
|
701
|
-
// quote and attribute them — "<issuer> says: …" — never adopt them as its own statement.
|
|
702
|
-
payload,
|
|
703
|
-
payload_is_untrusted_text: true,
|
|
704
|
-
};
|
|
705
|
-
});
|
|
706
|
-
// Seeing the list IS being told. Marking here rather than in cello_use_agent means the operator
|
|
707
|
-
// is never marked notified about something they were not actually shown.
|
|
708
|
-
store.markConsentNotified(sel.pubkey);
|
|
709
|
-
return { ok: true, agent: sel.name, pending: items };
|
|
710
|
-
});
|
|
711
|
-
handlers.set("cello_attestation_consent_accept", async (params, connectionId) => {
|
|
712
|
-
const sel = resolveSelectedAgent(connectionId);
|
|
713
|
-
if (!sel.ok)
|
|
714
|
-
return sel;
|
|
715
|
-
const prefix = typeof params?.hash_prefix === "string" ? params.hash_prefix : null;
|
|
716
|
-
if (!prefix || prefix.length < 8) {
|
|
717
|
-
return { ok: false, reason: "invalid_prefix", guidance: "hash_prefix must be at least 8 hex characters." };
|
|
718
|
-
}
|
|
719
|
-
const store = new TrustSignalStore(sessionNodeManager.getDb(), logger);
|
|
720
|
-
const item = store.listPendingConsent(sel.pubkey).find((r) => r.signalHash.startsWith(prefix));
|
|
721
|
-
if (!item) {
|
|
722
|
-
// Deliberately does NOT fall back to a wallet-wide lookup: a hash this agent has no pending
|
|
723
|
-
// decision on is not this agent's to accept, and finding it anyway would be the cross-agent
|
|
724
|
-
// decision this scoping exists to prevent.
|
|
725
|
-
return { ok: false, reason: "not_pending_for_agent", guidance: `No pending consent item for '${sel.name}' with prefix '${prefix}'.` };
|
|
726
|
-
}
|
|
727
|
-
// The write RESULT is checked, not assumed. `setConsentState` returns false when zero rows
|
|
728
|
-
// changed; reporting "accepted" regardless would tell the operator a decision was recorded that
|
|
729
|
-
// was not, and the next presentation would silently omit it.
|
|
730
|
-
if (!store.setConsentState(item.signalHash, "accepted")) {
|
|
731
|
-
return { ok: false, reason: "consent_write_failed",
|
|
732
|
-
guidance: `The acceptance was NOT recorded — the signal row changed underneath this call. Run cello_attestation_consent_list and retry.` };
|
|
733
|
-
}
|
|
734
|
-
return { ok: true, signal_hash: item.signalHash, consent_state: "accepted" };
|
|
735
|
-
});
|
|
736
|
-
handlers.set("cello_attestation_consent_refuse", async (params, connectionId) => {
|
|
737
|
-
const sel = resolveSelectedAgent(connectionId);
|
|
738
|
-
if (!sel.ok)
|
|
739
|
-
return sel;
|
|
740
|
-
const prefix = typeof params?.hash_prefix === "string" ? params.hash_prefix : null;
|
|
741
|
-
if (!prefix || prefix.length < 8) {
|
|
742
|
-
return { ok: false, reason: "invalid_prefix", guidance: "hash_prefix must be at least 8 hex characters." };
|
|
743
|
-
}
|
|
744
|
-
const store = new TrustSignalStore(sessionNodeManager.getDb(), logger);
|
|
745
|
-
// REFUSAL IS REACHABLE AFTER ACCEPTANCE, not only while pending.
|
|
746
|
-
//
|
|
747
|
-
// "I accepted this endorsement and now I want it gone" had NO path: refusal was pending-only and
|
|
748
|
-
// revocation is the issuer's to perform, not the subject's. Refusing an accepted item is the
|
|
749
|
-
// answer, and it is the better one — the decision is RECORDED rather than erased, so the trail
|
|
750
|
-
// stays honest, and a refused signal is already inert everywhere it is checked.
|
|
751
|
-
//
|
|
752
|
-
// Peer-issued only (`issuer_kind <> 'portal'`, enforced in the store). Refusal makes a signal
|
|
753
|
-
// inert, so allowing it on portal-issued signals would be a back door to suppressing a MANDATORY
|
|
754
|
-
// track record — achieving by consent exactly what revocation is forbidden from doing.
|
|
755
|
-
const item = store.findDecidableConsent(sel.pubkey, prefix);
|
|
756
|
-
if (!item) {
|
|
757
|
-
return {
|
|
758
|
-
ok: false,
|
|
759
|
-
reason: "not_decidable_for_agent",
|
|
760
|
-
guidance: `No pending or accepted attestation for '${sel.name}' with prefix '${prefix}'. Refusal ` +
|
|
761
|
-
`applies to attestations another party issued ABOUT you — signals the portal issued (your ` +
|
|
762
|
-
`track record, verified email and phone, GitHub links, security factors) are not refused ` +
|
|
763
|
-
`here. Run cello_attestation_consent_list to see what is decidable.`,
|
|
764
|
-
};
|
|
765
|
-
}
|
|
766
|
-
const wasAccepted = item.consentState === "accepted";
|
|
767
|
-
// ORDER IS LOAD-BEARING: the refusal is recorded FIRST and is never conditional on the message
|
|
768
|
-
// getting out. A refusal that only takes effect if the network cooperates would leave a signal
|
|
769
|
-
// Alice believes she rejected sitting in an unrefused state — the exact failure INV-CONSENT
|
|
770
|
-
// exists to prevent. The message is a courtesy layered on top of a decision already made.
|
|
771
|
-
//
|
|
772
|
-
// And the write is CHECKED. The ordering above is worth nothing if nothing confirms the record
|
|
773
|
-
// happened: without this, the code would go on to sign and send Bob a refusal message about a
|
|
774
|
-
// decision that is not in the database.
|
|
775
|
-
if (!store.setConsentState(item.signalHash, "refused")) {
|
|
776
|
-
return { ok: false, reason: "consent_write_failed",
|
|
777
|
-
guidance: `The refusal was NOT recorded — the signal row changed underneath this call. Run cello_attestation_consent_list and retry.` };
|
|
778
|
-
}
|
|
779
|
-
const refused = {
|
|
780
|
-
ok: true,
|
|
781
|
-
signal_hash: item.signalHash,
|
|
782
|
-
consent_state: "refused",
|
|
783
|
-
// WITHDRAWN vs REFUSED, told apart in the response, because they are different acts and the
|
|
784
|
-
// operator needs to know which one just happened. Also flags the supersession consequence:
|
|
785
|
-
// accepting a re-issue supersedes what it replaced, and refusing it afterwards does NOT bring
|
|
786
|
-
// the predecessor back. Withdrawing consent from a replacement can therefore leave you with
|
|
787
|
-
// neither — surfaced rather than discovered.
|
|
788
|
-
...(wasAccepted
|
|
789
|
-
? {
|
|
790
|
-
withdrawn_after_acceptance: true,
|
|
791
|
-
guidance: `Consent WITHDRAWN — you had accepted this and it is now refused, so it stops being ` +
|
|
792
|
-
`presented anywhere. The record of the decision remains, which is what keeps the trail ` +
|
|
793
|
-
`honest. Note: if this attestation superseded an earlier one when you accepted it, the ` +
|
|
794
|
-
`earlier one stays superseded — withdrawing from a replacement does not restore what it ` +
|
|
795
|
-
`replaced.`,
|
|
796
|
-
}
|
|
797
|
-
: {}),
|
|
798
|
-
};
|
|
799
|
-
// M10B-D4: the message back to the issuer is the subject's CHOICE. Silence is the default, and a
|
|
800
|
-
// silent refusal tells Bob NOTHING — which is what keeps D-24 intact for anyone who wants it.
|
|
801
|
-
const message = typeof params?.message === "string" ? params.message.trim() : "";
|
|
802
|
-
if (message.length === 0)
|
|
803
|
-
return { ...refused, message_queued: false };
|
|
804
|
-
// ACCOUNT-SUBJECT ITEMS DO NOT GET A MESSAGE YET, and this is a refusal, not an oversight.
|
|
805
|
-
//
|
|
806
|
-
// `listPendingConsent` scopes with `(subject_kind <> 'agent' OR lower(subject) = ?)`, so EVERY
|
|
807
|
-
// agent on this daemon can see — and therefore refuse — an account-subject item. The refusal
|
|
808
|
-
// itself is defensible (it is the account's own decision, and any of its agents speaks for it),
|
|
809
|
-
// but the MESSAGE is signed with THIS agent's K_local, so the issuer would receive a signed
|
|
810
|
-
// statement from an agent that was not the subject of anything. Which agent may speak for an
|
|
811
|
-
// account is an open question this milestone has not answered, and signing is not the place to
|
|
812
|
-
// guess at it. So the decision stands and the courtesy is withheld, with the reason named.
|
|
813
|
-
if (item.subjectKind !== "agent") {
|
|
814
|
-
return { ...refused, message_queued: false, message_error: "account_subject_message_unsupported",
|
|
815
|
-
guidance: `The refusal is recorded. Your message was NOT sent: this signal is about the ACCOUNT rather than about '${sel.name}', and a message would be signed by this agent alone — which agent may speak for an account is not yet settled.` };
|
|
816
|
-
}
|
|
817
|
-
// Rides the submission queue as the `refuse` op. The SUBJECT is the target signal hash (as it is
|
|
818
|
-
// for a withdrawal — both verbs act on an existing signal), and `subject_kind` is carried from
|
|
819
|
-
// the row rather than hardcoded: it is inside the TBS, so a hardcoded value would be a SIGNED
|
|
820
|
-
// field asserting something false.
|
|
821
|
-
const res = await submitForAgent({
|
|
822
|
-
connectionId,
|
|
823
|
-
op: "refuse", subjectKind: item.subjectKind, subject: item.signalHash, body: message,
|
|
824
|
-
context: "The refusal is recorded. Your message was NOT sent:",
|
|
825
|
-
});
|
|
826
|
-
// DOD-M15-ENDORSE-RETRY-1: the refusal itself is already recorded and unaffected either way —
|
|
827
|
-
// what is in question is only the MESSAGE back to the issuer. `message_delivery: "retrying"` is
|
|
828
|
-
// not `message_queued`, because no node has it yet, and it is not an error, because nothing is
|
|
829
|
-
// asked of the operator.
|
|
830
|
-
if (!res.queued && res.retrying) {
|
|
831
|
-
return {
|
|
832
|
-
...refused, message_queued: false, message_delivery: "retrying",
|
|
833
|
-
submission_id: res.submissionId, guidance: `The refusal is recorded. ${res.guidance}`,
|
|
834
|
-
};
|
|
835
|
-
}
|
|
836
|
-
if (!res.queued) {
|
|
837
|
-
return { ...refused, message_queued: false, message_error: res.reason, guidance: res.guidance };
|
|
838
|
-
}
|
|
839
|
-
// `message_queued`, NOT `issuer_notified`. A directory node acked a sealed blob; the portal has
|
|
840
|
-
// not drained it, scanned it, minted it, or delivered anything to the issuer.
|
|
841
|
-
//
|
|
842
|
-
// `stored` is carried through rather than collapsed into plain success: it is the ONE signal
|
|
843
|
-
// separating a benign duplicate from single-node censorship (an operator pre-inserting garbage
|
|
844
|
-
// under a clear-text submission_id), and folding them together destroys the only information
|
|
845
|
-
// that could ever tell them apart.
|
|
846
|
-
return {
|
|
847
|
-
...refused, message_queued: true, message_delivery: "accepted",
|
|
848
|
-
stored: res.stored, submission_id: res.submissionId,
|
|
849
|
-
...(res.storedWarning ? { guidance: `The refusal is recorded. ${res.storedWarning}` } : {}),
|
|
850
|
-
};
|
|
851
|
-
});
|
|
852
|
-
handlers.set("wallet_revoke_signal", async (params, connectionId) => {
|
|
853
|
-
const hashPrefix = typeof params?.hash_prefix === "string" ? params.hash_prefix : null;
|
|
854
|
-
if (!hashPrefix || hashPrefix.length < 8) {
|
|
855
|
-
return { ok: false, reason: "invalid_prefix", guidance: "hash_prefix must be at least 8 hex characters." };
|
|
856
|
-
}
|
|
857
|
-
const resolvedAgent = resolveSelectedAgent(connectionId);
|
|
858
|
-
if (!resolvedAgent.ok)
|
|
859
|
-
return resolvedAgent;
|
|
860
|
-
const sel = resolvedAgent;
|
|
861
|
-
const store = new TrustSignalStore(sessionNodeManager.getDb(), logger);
|
|
862
|
-
let row;
|
|
863
|
-
try {
|
|
864
|
-
row = store.getWalletSignalByPrefix(hashPrefix);
|
|
865
|
-
}
|
|
866
|
-
catch (err) {
|
|
867
|
-
return { ok: false, reason: "ambiguous_prefix", guidance: extractErrorMessage(err) };
|
|
868
|
-
}
|
|
869
|
-
if (!row) {
|
|
870
|
-
return { ok: false, reason: "signal_not_found", guidance: `No wallet signal with hash prefix '${hashPrefix}'.` };
|
|
871
|
-
}
|
|
872
|
-
const signalHash = row.signalHash;
|
|
873
|
-
// ── CATEGORY CHECK, BEFORE ANYTHING IS DESTROYED ───────────────────────────────────────────
|
|
874
|
-
//
|
|
875
|
-
// This handler used to accept ANY signal in the wallet by hash and go — no type check at all.
|
|
876
|
-
// The signal used in the 2026-08-10 live test was a `track_record`, and the tool accepted the
|
|
877
|
-
// instruction to destroy it and deleted the local copy. Had the directory path been working,
|
|
878
|
-
// an operator could have deleted their own behavioural history: precisely what the
|
|
879
|
-
// mandatory-signal rule exists to prevent.
|
|
880
|
-
//
|
|
881
|
-
// Placed BEFORE the signing and before the local delete, because the local delete is
|
|
882
|
-
// unconditional further down — a refusal that happens after it would still have destroyed the
|
|
883
|
-
// operator's copy.
|
|
884
|
-
//
|
|
885
|
-
// This is a courtesy, NOT the enforcement: an operator can edit this file. The portal refuses
|
|
886
|
-
// mandatory revocations server-side, and the directory already makes a non-issuer's tombstone
|
|
887
|
-
// inert for attestations. See signal-revocability.ts.
|
|
888
|
-
// M7: THE WALLET LOOKUP IS NOT AGENT-SCOPED, so refuse here rather than queue under the wrong
|
|
889
|
-
// key. `getWalletSignalByPrefix` matches on hash alone, and several agents share this daemon's
|
|
890
|
-
// database — so the SELECTED agent could sign a revocation for a signal that is another agent's.
|
|
891
|
-
// The portal blocks it across accounts, but within one account it would silently succeed under
|
|
892
|
-
// the wrong agent's key, and across accounts the operator waits for an async `not_authorized`
|
|
893
|
-
// instead of being told immediately.
|
|
894
|
-
if (row.subjectKind === "agent" && row.subject.toLowerCase() !== sel.pubkey.toLowerCase()) {
|
|
895
|
-
return {
|
|
896
|
-
ok: false,
|
|
897
|
-
reason: "not_your_signal",
|
|
898
|
-
guidance: `That signal is about a different agent, not '${sel.name}'. Select the agent it belongs to ` +
|
|
899
|
-
`with cello_use_agent and retry.`,
|
|
900
|
-
};
|
|
901
|
-
}
|
|
902
|
-
const revocability = revocabilityOf(row.type);
|
|
903
|
-
if (!revocability.revocable) {
|
|
904
|
-
return {
|
|
905
|
-
ok: false,
|
|
906
|
-
reason: revocability.category === "mandatory" ? "signal_not_revocable" : "revoke_via_portal",
|
|
907
|
-
signal_type: row.type,
|
|
908
|
-
guidance: revocability.guidance,
|
|
909
|
-
};
|
|
910
|
-
}
|
|
911
|
-
// ── VIA THE PORTAL'S SUBMISSION QUEUE, NOT A DIRECT CALL TO A DIRECTORY ────────────────────
|
|
912
|
-
//
|
|
913
|
-
// What was here POSTed `/internal/signal/revoke` to port 9090 — the HEALTH port — took the 404
|
|
914
|
-
// as an answer, returned `ok: true` regardless, and hard-deleted the local copy "regardless of
|
|
915
|
-
// directory result". Measured 2026-08-10 against the live fleet: all three nodes unchanged, the
|
|
916
|
-
// operator's copy gone, and the tool reporting success. It also asked ONE node under a comment
|
|
917
|
-
// claiming it asked all three.
|
|
918
|
-
//
|
|
919
|
-
// The route is not the fix for a wrong port. The real route lives on the internal API, which is
|
|
920
|
-
// firewalled to the VPC subnets and unreachable from an operator's machine by any URL. And the
|
|
921
|
-
// deciding reason is ENFORCEMENT, not reachability: the directory deliberately cannot tell a
|
|
922
|
-
// `track_record` from a `github_id` (opaque `type`, no enum, so a new signal type never needs a
|
|
923
|
-
// directory deploy), and both are portal-issued, so `issuer_kind` does not separate them. A
|
|
924
|
-
// direct verb would revoke a behavioural record on request with only an editable client in the
|
|
925
|
-
// way. The PORTAL minted the signal and knows what it is, so the category rule can be real there
|
|
926
|
-
// rather than advisory here.
|
|
927
|
-
//
|
|
928
|
-
// Rides the EXISTING sealed submission queue — same path as an endorsement, same results
|
|
929
|
-
// channel. No new wire verb.
|
|
930
|
-
const submitted = await submitForAgent({
|
|
931
|
-
connectionId,
|
|
932
|
-
op: "revoke",
|
|
933
|
-
// The TARGET SIGNAL HASH, exactly as `refuse` and `withdraw` carry it — this acts on an
|
|
934
|
-
// existing signal rather than asserting a fact about a party.
|
|
935
|
-
subjectKind: row.subjectKind,
|
|
936
|
-
subject: signalHash,
|
|
937
|
-
body: "",
|
|
938
|
-
context: "The revocation was NOT queued:",
|
|
939
|
-
});
|
|
940
|
-
// DOD-M15-ENDORSE-RETRY-1: the local copy survives either way (see below), so a retrying
|
|
941
|
-
// revocation is a wait, not a loss — and the operator is told which it is rather than being
|
|
942
|
-
// sent to re-run a retraction the daemon is already carrying.
|
|
943
|
-
if (!submitted.queued && submitted.retrying) {
|
|
944
|
-
return {
|
|
945
|
-
ok: true, signal_hash: signalHash, submission_id: submitted.submissionId,
|
|
946
|
-
revoked: false, queued: false, delivery: "retrying",
|
|
947
|
-
guidance: `Revocation for '${row.type}' is HELD, not yet at a directory. ${submitted.guidance} ` +
|
|
948
|
-
"Your local copy is KEPT either way, deliberately, so nothing is lost while it waits.",
|
|
949
|
-
};
|
|
950
|
-
}
|
|
951
|
-
if (!submitted.queued) {
|
|
952
|
-
return { ok: false, reason: submitted.reason, guidance: submitted.guidance };
|
|
953
|
-
}
|
|
954
|
-
// THE LOCAL COPY SURVIVES. It used to be deleted unconditionally, so a failed retraction also
|
|
955
|
-
// destroyed the ability to retry — and since the directory half never worked, that was every
|
|
956
|
-
// retraction. The signal stays until the portal confirms the revocation; the operator can see
|
|
957
|
-
// the outcome with cello_attestations_issued and the wallet reflects it on the next refresh.
|
|
958
|
-
return {
|
|
959
|
-
ok: true,
|
|
960
|
-
signal_hash: signalHash,
|
|
961
|
-
submission_id: submitted.submissionId,
|
|
962
|
-
revoked: false,
|
|
963
|
-
queued: true,
|
|
964
|
-
delivery: "accepted",
|
|
965
|
-
// M5: CARRIED, not dropped. `submitForAgent`'s own comment says the warning lives in the
|
|
966
|
-
// shared path "because the same omission would otherwise be available to every verb added
|
|
967
|
-
// after this one" — and this was the next verb added. `stored:false` means a node already held
|
|
968
|
-
// this id: usually a benign retry, but also what single-node censorship looks like, and
|
|
969
|
-
// without it that reads as unqualified success.
|
|
970
|
-
stored: submitted.stored,
|
|
971
|
-
...(submitted.storedWarning ? { stored_warning: submitted.storedWarning } : {}),
|
|
972
|
-
guidance: `Revocation QUEUED for '${row.type}' — not yet revoked. The portal opens it, checks the ` +
|
|
973
|
-
`signal is one you may retract, and revokes it at the directory; the outcome comes back on ` +
|
|
974
|
-
`the results channel. Your local copy is KEPT — deliberately, so a failure leaves you able to ` +
|
|
975
|
-
`retry. Nothing removes it automatically even on success: check the outcome with ` +
|
|
976
|
-
`cello_attestations_issued.`,
|
|
977
|
-
};
|
|
978
|
-
});
|
|
979
|
-
}
|
|
980
|
-
//# sourceMappingURL=signal-handlers.js.map
|