@cello-protocol/daemon 0.0.227 → 0.0.228
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-admin-handlers.d.ts +56 -0
- package/dist/agent-admin-handlers.d.ts.map +1 -0
- package/dist/agent-admin-handlers.js +73 -0
- package/dist/agent-admin-handlers.js.map +1 -0
- package/dist/agent-handlers.d.ts +72 -0
- package/dist/agent-handlers.d.ts.map +1 -0
- package/dist/agent-handlers.js +604 -0
- package/dist/agent-handlers.js.map +1 -0
- package/dist/agent-id-migration.d.ts +70 -0
- package/dist/agent-id-migration.d.ts.map +1 -0
- package/dist/agent-id-migration.js +468 -0
- package/dist/agent-id-migration.js.map +1 -0
- package/dist/agent-loader.d.ts +37 -0
- package/dist/agent-loader.d.ts.map +1 -0
- package/dist/agent-loader.js +37 -0
- package/dist/agent-loader.js.map +1 -0
- package/dist/agent-selection-root.d.ts +29 -0
- package/dist/agent-selection-root.d.ts.map +1 -0
- package/dist/agent-selection-root.js +126 -0
- package/dist/agent-selection-root.js.map +1 -0
- package/dist/agent-selection.d.ts +73 -0
- package/dist/agent-selection.d.ts.map +1 -0
- package/dist/agent-selection.js +80 -0
- package/dist/agent-selection.js.map +1 -0
- package/dist/agent-settings-keys.d.ts +52 -0
- package/dist/agent-settings-keys.d.ts.map +1 -0
- package/dist/agent-settings-keys.js +114 -0
- package/dist/agent-settings-keys.js.map +1 -0
- package/dist/agent-state.d.ts +67 -0
- package/dist/agent-state.d.ts.map +1 -0
- package/dist/agent-state.js +66 -0
- package/dist/agent-state.js.map +1 -0
- package/dist/assignment-verify.d.ts +90 -0
- package/dist/assignment-verify.d.ts.map +1 -0
- package/dist/assignment-verify.js +301 -0
- package/dist/assignment-verify.js.map +1 -0
- package/dist/attendance-wiring.d.ts +23 -0
- package/dist/attendance-wiring.d.ts.map +1 -0
- package/dist/attendance-wiring.js +248 -0
- package/dist/attendance-wiring.js.map +1 -0
- package/dist/attestation-body.d.ts +47 -0
- package/dist/attestation-body.d.ts.map +1 -0
- package/dist/attestation-body.js +71 -0
- package/dist/attestation-body.js.map +1 -0
- package/dist/authorship-verification.d.ts +91 -0
- package/dist/authorship-verification.d.ts.map +1 -0
- package/dist/authorship-verification.js +532 -0
- package/dist/authorship-verification.js.map +1 -0
- package/dist/away-detection.d.ts +139 -0
- package/dist/away-detection.d.ts.map +1 -0
- package/dist/away-detection.js +186 -0
- package/dist/away-detection.js.map +1 -0
- package/dist/away-inbox-oneshot.d.ts +40 -0
- package/dist/away-inbox-oneshot.d.ts.map +1 -0
- package/dist/away-inbox-oneshot.js +311 -0
- package/dist/away-inbox-oneshot.js.map +1 -0
- package/dist/backup-restore-handlers.d.ts +10 -0
- package/dist/backup-restore-handlers.d.ts.map +1 -0
- package/dist/backup-restore-handlers.js +82 -0
- package/dist/backup-restore-handlers.js.map +1 -0
- package/dist/backup-restore.d.ts +102 -0
- package/dist/backup-restore.d.ts.map +1 -0
- package/dist/backup-restore.js +341 -0
- package/dist/backup-restore.js.map +1 -0
- package/dist/bin/cello-daemon.d.ts +13 -0
- package/dist/bin/cello-daemon.d.ts.map +1 -0
- package/dist/bin/cello-daemon.js.map +1 -0
- package/dist/boot-agents.d.ts +64 -0
- package/dist/boot-agents.d.ts.map +1 -0
- package/dist/boot-agents.js +241 -0
- package/dist/boot-agents.js.map +1 -0
- package/dist/boot-connection-state.d.ts +38 -0
- package/dist/boot-connection-state.d.ts.map +1 -0
- package/dist/boot-connection-state.js +95 -0
- package/dist/boot-connection-state.js.map +1 -0
- package/dist/boot-core.d.ts +36 -0
- package/dist/boot-core.d.ts.map +1 -0
- package/dist/boot-core.js +293 -0
- package/dist/boot-core.js.map +1 -0
- package/dist/boot-parked-content.d.ts +34 -0
- package/dist/boot-parked-content.d.ts.map +1 -0
- package/dist/boot-parked-content.js +528 -0
- package/dist/boot-parked-content.js.map +1 -0
- package/dist/boot-sweeps.d.ts +22 -0
- package/dist/boot-sweeps.d.ts.map +1 -0
- package/dist/boot-sweeps.js +51 -0
- package/dist/boot-sweeps.js.map +1 -0
- package/dist/bundled-consortium-manifest.d.ts +47 -0
- package/dist/bundled-consortium-manifest.d.ts.map +1 -0
- package/dist/bundled-consortium-manifest.js +116 -0
- package/dist/bundled-consortium-manifest.js.map +1 -0
- package/dist/cbor-blob-migration.d.ts +8 -0
- package/dist/cbor-blob-migration.d.ts.map +1 -0
- package/dist/cbor-blob-migration.js +116 -0
- package/dist/cbor-blob-migration.js.map +1 -0
- package/dist/challenge-verifier.d.ts +12 -0
- package/dist/challenge-verifier.d.ts.map +1 -0
- package/dist/challenge-verifier.js +11 -0
- package/dist/challenge-verifier.js.map +1 -0
- package/dist/channel-log-store.d.ts +80 -0
- package/dist/channel-log-store.d.ts.map +1 -0
- package/dist/channel-log-store.js +290 -0
- package/dist/channel-log-store.js.map +1 -0
- package/dist/close-commitment.d.ts +67 -0
- package/dist/close-commitment.d.ts.map +1 -0
- package/dist/close-commitment.js +78 -0
- package/dist/close-commitment.js.map +1 -0
- package/dist/close-session-handler.d.ts +94 -0
- package/dist/close-session-handler.d.ts.map +1 -0
- package/dist/close-session-handler.js +1418 -0
- package/dist/close-session-handler.js.map +1 -0
- package/dist/co-attendance.d.ts +29 -0
- package/dist/co-attendance.d.ts.map +1 -0
- package/dist/co-attendance.js +32 -0
- package/dist/co-attendance.js.map +1 -0
- package/dist/column-birth.d.ts +40 -0
- package/dist/column-birth.d.ts.map +1 -0
- package/dist/column-birth.js +61 -0
- package/dist/column-birth.js.map +1 -0
- package/dist/connect-or-start.d.ts +25 -0
- package/dist/connect-or-start.d.ts.map +1 -0
- package/dist/connect-or-start.js +175 -0
- package/dist/connect-or-start.js.map +1 -0
- package/dist/connection-agents.d.ts +16 -0
- package/dist/connection-agents.d.ts.map +1 -0
- package/dist/connection-agents.js +68 -0
- package/dist/connection-agents.js.map +1 -0
- package/dist/consent-migration.d.ts +49 -0
- package/dist/consent-migration.d.ts.map +1 -0
- package/dist/consent-migration.js +128 -0
- package/dist/consent-migration.js.map +1 -0
- package/dist/consortium-bootstrap.d.ts +138 -0
- package/dist/consortium-bootstrap.d.ts.map +1 -0
- package/dist/consortium-bootstrap.js +339 -0
- package/dist/consortium-bootstrap.js.map +1 -0
- package/dist/consortium-fingerprint.d.ts +115 -0
- package/dist/consortium-fingerprint.d.ts.map +1 -0
- package/dist/consortium-fingerprint.js +175 -0
- package/dist/consortium-fingerprint.js.map +1 -0
- package/dist/contact-handlers.d.ts +59 -0
- package/dist/contact-handlers.d.ts.map +1 -0
- package/dist/contact-handlers.js +343 -0
- package/dist/contact-handlers.js.map +1 -0
- package/dist/contact-pubkey-case.d.ts +65 -0
- package/dist/contact-pubkey-case.d.ts.map +1 -0
- package/dist/contact-pubkey-case.js +136 -0
- package/dist/contact-pubkey-case.js.map +1 -0
- package/dist/contacts-tier-migration.d.ts +90 -0
- package/dist/contacts-tier-migration.d.ts.map +1 -0
- package/dist/contacts-tier-migration.js +150 -0
- package/dist/contacts-tier-migration.js.map +1 -0
- package/dist/content-encryption-status.d.ts +111 -0
- package/dist/content-encryption-status.d.ts.map +1 -0
- package/dist/content-encryption-status.js +158 -0
- package/dist/content-encryption-status.js.map +1 -0
- package/dist/content-park-client.d.ts +90 -0
- package/dist/content-park-client.d.ts.map +1 -0
- package/dist/content-park-client.js +362 -0
- package/dist/content-park-client.js.map +1 -0
- package/dist/content-park.d.ts +52 -0
- package/dist/content-park.d.ts.map +1 -0
- package/dist/content-park.js +1309 -0
- package/dist/content-park.js.map +1 -0
- package/dist/cross-node-negotiation.d.ts +44 -0
- package/dist/cross-node-negotiation.d.ts.map +1 -0
- package/dist/cross-node-negotiation.js +34 -0
- package/dist/cross-node-negotiation.js.map +1 -0
- package/dist/daemon-handle.d.ts +57 -0
- package/dist/daemon-handle.d.ts.map +1 -0
- package/dist/daemon-handle.js +2 -0
- package/dist/daemon-handle.js.map +1 -0
- package/dist/daemon-status-report.d.ts +50 -0
- package/dist/daemon-status-report.d.ts.map +1 -0
- package/dist/daemon-status-report.js +81 -0
- package/dist/daemon-status-report.js.map +1 -0
- package/dist/daemon.d.ts +45 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +1177 -0
- package/dist/daemon.js.map +1 -0
- package/dist/db-identity-store.d.ts +159 -0
- package/dist/db-identity-store.d.ts.map +1 -0
- package/dist/db-identity-store.js +502 -0
- package/dist/db-identity-store.js.map +1 -0
- package/dist/delivery-open-registry.d.ts +92 -0
- package/dist/delivery-open-registry.d.ts.map +1 -0
- package/dist/delivery-open-registry.js +121 -0
- package/dist/delivery-open-registry.js.map +1 -0
- package/dist/delivery-session-suspects.d.ts +56 -0
- package/dist/delivery-session-suspects.d.ts.map +1 -0
- package/dist/delivery-session-suspects.js +94 -0
- package/dist/delivery-session-suspects.js.map +1 -0
- package/dist/directory-auth-posture.d.ts +87 -0
- package/dist/directory-auth-posture.d.ts.map +1 -0
- package/dist/directory-auth-posture.js +134 -0
- package/dist/directory-auth-posture.js.map +1 -0
- package/dist/directory-bootstrap.d.ts +310 -0
- package/dist/directory-bootstrap.d.ts.map +1 -0
- package/dist/directory-bootstrap.js +557 -0
- package/dist/directory-bootstrap.js.map +1 -0
- package/dist/directory-connect.d.ts +27 -0
- package/dist/directory-connect.d.ts.map +1 -0
- package/dist/directory-connect.js +106 -0
- package/dist/directory-connect.js.map +1 -0
- package/dist/disconnect-cleanup.d.ts +51 -0
- package/dist/disconnect-cleanup.d.ts.map +1 -0
- package/dist/disconnect-cleanup.js +72 -0
- package/dist/disconnect-cleanup.js.map +1 -0
- package/dist/document-amendment-store.d.ts +120 -0
- package/dist/document-amendment-store.d.ts.map +1 -0
- package/dist/document-amendment-store.js +266 -0
- package/dist/document-amendment-store.js.map +1 -0
- package/dist/document-delivery-transport.d.ts +168 -0
- package/dist/document-delivery-transport.d.ts.map +1 -0
- package/dist/document-delivery-transport.js +206 -0
- package/dist/document-delivery-transport.js.map +1 -0
- package/dist/document-engine.d.ts +134 -0
- package/dist/document-engine.d.ts.map +1 -0
- package/dist/document-engine.js +282 -0
- package/dist/document-engine.js.map +1 -0
- package/dist/document-flag.d.ts +58 -0
- package/dist/document-flag.d.ts.map +1 -0
- package/dist/document-flag.js +70 -0
- package/dist/document-flag.js.map +1 -0
- package/dist/document-frame-router.d.ts +245 -0
- package/dist/document-frame-router.d.ts.map +1 -0
- package/dist/document-frame-router.js +397 -0
- package/dist/document-frame-router.js.map +1 -0
- package/dist/document-gate-wiring.d.ts +61 -0
- package/dist/document-gate-wiring.d.ts.map +1 -0
- package/dist/document-gate-wiring.js +125 -0
- package/dist/document-gate-wiring.js.map +1 -0
- package/dist/document-gate.d.ts +149 -0
- package/dist/document-gate.d.ts.map +1 -0
- package/dist/document-gate.js +509 -0
- package/dist/document-gate.js.map +1 -0
- package/dist/document-handlers.d.ts +47 -0
- package/dist/document-handlers.d.ts.map +1 -0
- package/dist/document-handlers.js +2203 -0
- package/dist/document-handlers.js.map +1 -0
- package/dist/document-handshake.d.ts +176 -0
- package/dist/document-handshake.d.ts.map +1 -0
- package/dist/document-handshake.js +452 -0
- package/dist/document-handshake.js.map +1 -0
- package/dist/document-inbound.d.ts +162 -0
- package/dist/document-inbound.d.ts.map +1 -0
- package/dist/document-inbound.js +530 -0
- package/dist/document-inbound.js.map +1 -0
- package/dist/document-json.d.ts +120 -0
- package/dist/document-json.d.ts.map +1 -0
- package/dist/document-json.js +191 -0
- package/dist/document-json.js.map +1 -0
- package/dist/document-layer.d.ts +215 -0
- package/dist/document-layer.d.ts.map +1 -0
- package/dist/document-layer.js +1025 -0
- package/dist/document-layer.js.map +1 -0
- package/dist/document-lifecycle.d.ts +52 -0
- package/dist/document-lifecycle.d.ts.map +1 -0
- package/dist/document-lifecycle.js +134 -0
- package/dist/document-lifecycle.js.map +1 -0
- package/dist/document-live-docs.d.ts +58 -0
- package/dist/document-live-docs.d.ts.map +1 -0
- package/dist/document-live-docs.js +126 -0
- package/dist/document-live-docs.js.map +1 -0
- package/dist/document-notify.d.ts +228 -0
- package/dist/document-notify.d.ts.map +1 -0
- package/dist/document-notify.js +580 -0
- package/dist/document-notify.js.map +1 -0
- package/dist/document-profile.d.ts +61 -0
- package/dist/document-profile.d.ts.map +1 -0
- package/dist/document-profile.js +112 -0
- package/dist/document-profile.js.map +1 -0
- package/dist/document-publish.d.ts +87 -0
- package/dist/document-publish.d.ts.map +1 -0
- package/dist/document-publish.js +173 -0
- package/dist/document-publish.js.map +1 -0
- package/dist/document-reachability.d.ts +42 -0
- package/dist/document-reachability.d.ts.map +1 -0
- package/dist/document-reachability.js +80 -0
- package/dist/document-reachability.js.map +1 -0
- package/dist/document-reconcile-engine.d.ts +66 -0
- package/dist/document-reconcile-engine.d.ts.map +1 -0
- package/dist/document-reconcile-engine.js +225 -0
- package/dist/document-reconcile-engine.js.map +1 -0
- package/dist/document-reconcile-scheduler.d.ts +163 -0
- package/dist/document-reconcile-scheduler.d.ts.map +1 -0
- package/dist/document-reconcile-scheduler.js +303 -0
- package/dist/document-reconcile-scheduler.js.map +1 -0
- package/dist/document-rejection.d.ts +251 -0
- package/dist/document-rejection.d.ts.map +1 -0
- package/dist/document-rejection.js +435 -0
- package/dist/document-rejection.js.map +1 -0
- package/dist/document-screen.d.ts +114 -0
- package/dist/document-screen.d.ts.map +1 -0
- package/dist/document-screen.js +223 -0
- package/dist/document-screen.js.map +1 -0
- package/dist/document-store.d.ts +372 -0
- package/dist/document-store.d.ts.map +1 -0
- package/dist/document-store.js +931 -0
- package/dist/document-store.js.map +1 -0
- package/dist/document-surface.d.ts +32 -0
- package/dist/document-surface.d.ts.map +1 -0
- package/dist/document-surface.js +151 -0
- package/dist/document-surface.js.map +1 -0
- package/dist/document-types.d.ts +94 -0
- package/dist/document-types.d.ts.map +1 -0
- package/dist/document-types.js +90 -0
- package/dist/document-types.js.map +1 -0
- package/dist/document-watch.d.ts +69 -0
- package/dist/document-watch.d.ts.map +1 -0
- package/dist/document-watch.js +108 -0
- package/dist/document-watch.js.map +1 -0
- package/dist/document-wiring.d.ts +53 -0
- package/dist/document-wiring.d.ts.map +1 -0
- package/dist/document-wiring.js +323 -0
- package/dist/document-wiring.js.map +1 -0
- package/dist/document-write-guard.d.ts +66 -0
- package/dist/document-write-guard.d.ts.map +1 -0
- package/dist/document-write-guard.js +98 -0
- package/dist/document-write-guard.js.map +1 -0
- package/dist/document-write-path.d.ts +94 -0
- package/dist/document-write-path.d.ts.map +1 -0
- package/dist/document-write-path.js +530 -0
- package/dist/document-write-path.js.map +1 -0
- package/dist/error-message.d.ts +7 -0
- package/dist/error-message.d.ts.map +1 -0
- package/dist/error-message.js +19 -0
- package/dist/error-message.js.map +1 -0
- package/dist/file-manifest-provider.d.ts +37 -0
- package/dist/file-manifest-provider.d.ts.map +1 -0
- package/dist/file-manifest-provider.js +105 -0
- package/dist/file-manifest-provider.js.map +1 -0
- package/dist/frame-values.d.ts +3 -0
- package/dist/frame-values.d.ts.map +1 -0
- package/dist/frame-values.js +84 -0
- package/dist/frame-values.js.map +1 -0
- package/dist/frontier-mismatch.d.ts +73 -0
- package/dist/frontier-mismatch.d.ts.map +1 -0
- package/dist/frontier-mismatch.js +89 -0
- package/dist/frontier-mismatch.js.map +1 -0
- package/dist/gateway-config-handlers.d.ts +26 -0
- package/dist/gateway-config-handlers.d.ts.map +1 -0
- package/dist/gateway-config-handlers.js +429 -0
- package/dist/gateway-config-handlers.js.map +1 -0
- package/dist/held-content.d.ts +145 -0
- package/dist/held-content.d.ts.map +1 -0
- package/dist/held-content.js +389 -0
- package/dist/held-content.js.map +1 -0
- package/dist/http-manifest-poll.d.ts +67 -0
- package/dist/http-manifest-poll.d.ts.map +1 -0
- package/dist/http-manifest-poll.js +150 -0
- package/dist/http-manifest-poll.js.map +1 -0
- package/dist/identity-migration.d.ts +40 -0
- package/dist/identity-migration.d.ts.map +1 -0
- package/dist/identity-migration.js +461 -0
- package/dist/identity-migration.js.map +1 -0
- package/dist/inbound-refusals.d.ts +283 -0
- package/dist/inbound-refusals.d.ts.map +1 -0
- package/dist/inbound-refusals.js +919 -0
- package/dist/inbound-refusals.js.map +1 -0
- package/dist/inbound-seal-request.d.ts +32 -0
- package/dist/inbound-seal-request.d.ts.map +1 -0
- package/dist/inbound-seal-request.js +228 -0
- package/dist/inbound-seal-request.js.map +1 -0
- package/dist/inbound-sessions.d.ts +291 -0
- package/dist/inbound-sessions.d.ts.map +1 -0
- package/dist/inbound-sessions.js +1609 -0
- package/dist/inbound-sessions.js.map +1 -0
- package/dist/inclusion-proof-handlers.d.ts +43 -0
- package/dist/inclusion-proof-handlers.d.ts.map +1 -0
- package/dist/inclusion-proof-handlers.js +565 -0
- package/dist/inclusion-proof-handlers.js.map +1 -0
- package/dist/inclusion-proof.d.ts +151 -0
- package/dist/inclusion-proof.d.ts.map +1 -0
- package/dist/inclusion-proof.js +228 -0
- package/dist/inclusion-proof.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js.map +1 -0
- package/dist/initiate-session-handler.d.ts +55 -0
- package/dist/initiate-session-handler.d.ts.map +1 -0
- package/dist/initiate-session-handler.js +310 -0
- package/dist/initiate-session-handler.js.map +1 -0
- package/dist/ipc-client.d.ts +31 -0
- package/dist/ipc-client.d.ts.map +1 -0
- package/dist/ipc-client.js +113 -0
- package/dist/ipc-client.js.map +1 -0
- package/dist/ipc-server.d.ts +63 -0
- package/dist/ipc-server.d.ts.map +1 -0
- package/dist/ipc-server.js +429 -0
- package/dist/ipc-server.js.map +1 -0
- package/dist/ipc-surface.d.ts +44 -0
- package/dist/ipc-surface.d.ts.map +1 -0
- package/dist/ipc-surface.js +107 -0
- package/dist/ipc-surface.js.map +1 -0
- package/dist/line-lcs.d.ts +51 -0
- package/dist/line-lcs.d.ts.map +1 -0
- package/dist/line-lcs.js +71 -0
- package/dist/line-lcs.js.map +1 -0
- package/dist/lock-file.d.ts +39 -0
- package/dist/lock-file.d.ts.map +1 -0
- package/dist/lock-file.js +120 -0
- package/dist/lock-file.js.map +1 -0
- package/dist/log-collapse.d.ts +66 -0
- package/dist/log-collapse.d.ts.map +1 -0
- package/dist/log-collapse.js +244 -0
- package/dist/log-collapse.js.map +1 -0
- package/dist/log-rotate.d.ts +67 -0
- package/dist/log-rotate.d.ts.map +1 -0
- package/dist/log-rotate.js +134 -0
- package/dist/log-rotate.js.map +1 -0
- package/dist/manifest-deps.d.ts +25 -0
- package/dist/manifest-deps.d.ts.map +1 -0
- package/dist/manifest-deps.js +151 -0
- package/dist/manifest-deps.js.map +1 -0
- package/dist/manifest-poll-scheduler.d.ts +31 -0
- package/dist/manifest-poll-scheduler.d.ts.map +1 -0
- package/dist/manifest-poll-scheduler.js +59 -0
- package/dist/manifest-poll-scheduler.js.map +1 -0
- package/dist/manifest-validity.d.ts +153 -0
- package/dist/manifest-validity.d.ts.map +1 -0
- package/dist/manifest-validity.js +268 -0
- package/dist/manifest-validity.js.map +1 -0
- package/dist/manifest-version-store-db.d.ts +24 -0
- package/dist/manifest-version-store-db.d.ts.map +1 -0
- package/dist/manifest-version-store-db.js +58 -0
- package/dist/manifest-version-store-db.js.map +1 -0
- package/dist/manifest-version-store.d.ts +16 -0
- package/dist/manifest-version-store.d.ts.map +1 -0
- package/dist/manifest-version-store.js +15 -0
- package/dist/manifest-version-store.js.map +1 -0
- package/dist/network-directory-node.d.ts +136 -0
- package/dist/network-directory-node.d.ts.map +1 -0
- package/dist/network-directory-node.js +810 -0
- package/dist/network-directory-node.js.map +1 -0
- package/dist/nonce-dedup.d.ts +68 -0
- package/dist/nonce-dedup.d.ts.map +1 -0
- package/dist/nonce-dedup.js +205 -0
- package/dist/nonce-dedup.js.map +1 -0
- package/dist/notification-dispatcher.d.ts +92 -0
- package/dist/notification-dispatcher.d.ts.map +1 -0
- package/dist/notification-dispatcher.js +210 -0
- package/dist/notification-dispatcher.js.map +1 -0
- package/dist/notification-handlers.d.ts +53 -0
- package/dist/notification-handlers.d.ts.map +1 -0
- package/dist/notification-handlers.js +461 -0
- package/dist/notification-handlers.js.map +1 -0
- package/dist/onboarding-guidance.d.ts +79 -0
- package/dist/onboarding-guidance.d.ts.map +1 -0
- package/dist/onboarding-guidance.js +95 -0
- package/dist/onboarding-guidance.js.map +1 -0
- package/dist/operator-guidance.d.ts +25 -0
- package/dist/operator-guidance.d.ts.map +1 -0
- package/dist/operator-guidance.js +50 -0
- package/dist/operator-guidance.js.map +1 -0
- package/dist/orphan-triage.d.ts +130 -0
- package/dist/orphan-triage.d.ts.map +1 -0
- package/dist/orphan-triage.js +207 -0
- package/dist/orphan-triage.js.map +1 -0
- package/dist/outbound-sessions.d.ts +126 -0
- package/dist/outbound-sessions.d.ts.map +1 -0
- package/dist/outbound-sessions.js +1052 -0
- package/dist/outbound-sessions.js.map +1 -0
- package/dist/park-envelope.d.ts +329 -0
- package/dist/park-envelope.d.ts.map +1 -0
- package/dist/park-envelope.js +509 -0
- package/dist/park-envelope.js.map +1 -0
- package/dist/park-recovery.d.ts +273 -0
- package/dist/park-recovery.d.ts.map +1 -0
- package/dist/park-recovery.js +717 -0
- package/dist/park-recovery.js.map +1 -0
- package/dist/park-refusals.d.ts +147 -0
- package/dist/park-refusals.d.ts.map +1 -0
- package/dist/park-refusals.js +331 -0
- package/dist/park-refusals.js.map +1 -0
- package/dist/quarantine-framing.d.ts +92 -0
- package/dist/quarantine-framing.d.ts.map +1 -0
- package/dist/quarantine-framing.js +111 -0
- package/dist/quarantine-framing.js.map +1 -0
- package/dist/reconnect-drain.d.ts +22 -0
- package/dist/reconnect-drain.d.ts.map +1 -0
- package/dist/reconnect-drain.js +65 -0
- package/dist/reconnect-drain.js.map +1 -0
- package/dist/recovered-position.d.ts +14 -0
- package/dist/recovered-position.d.ts.map +1 -0
- package/dist/recovered-position.js +59 -0
- package/dist/recovered-position.js.map +1 -0
- package/dist/refusal-notices.d.ts +196 -0
- package/dist/refusal-notices.d.ts.map +1 -0
- package/dist/refusal-notices.js +516 -0
- package/dist/refusal-notices.js.map +1 -0
- package/dist/refusal-reasons.d.ts +245 -0
- package/dist/refusal-reasons.d.ts.map +1 -0
- package/dist/refusal-reasons.js +363 -0
- package/dist/refusal-reasons.js.map +1 -0
- package/dist/register-handler.d.ts +36 -0
- package/dist/register-handler.d.ts.map +1 -0
- package/dist/register-handler.js +285 -0
- package/dist/register-handler.js.map +1 -0
- package/dist/registration-context.d.ts +72 -0
- package/dist/registration-context.d.ts.map +1 -0
- package/dist/registration-context.js +126 -0
- package/dist/registration-context.js.map +1 -0
- package/dist/registration-manager.d.ts +94 -0
- package/dist/registration-manager.d.ts.map +1 -0
- package/dist/registration-manager.js +585 -0
- package/dist/registration-manager.js.map +1 -0
- package/dist/registration-persistence.d.ts +183 -0
- package/dist/registration-persistence.d.ts.map +1 -0
- package/dist/registration-persistence.js +263 -0
- package/dist/registration-persistence.js.map +1 -0
- package/dist/registry-poll.d.ts +52 -0
- package/dist/registry-poll.d.ts.map +1 -0
- package/dist/registry-poll.js +140 -0
- package/dist/registry-poll.js.map +1 -0
- package/dist/registry-version-store-db.d.ts +22 -0
- package/dist/registry-version-store-db.d.ts.map +1 -0
- package/dist/registry-version-store-db.js +50 -0
- package/dist/registry-version-store-db.js.map +1 -0
- package/dist/relay-endpoints.d.ts +18 -0
- package/dist/relay-endpoints.d.ts.map +1 -0
- package/dist/relay-endpoints.js +9 -0
- package/dist/relay-endpoints.js.map +1 -0
- package/dist/relay-only.d.ts +140 -0
- package/dist/relay-only.d.ts.map +1 -0
- package/dist/relay-only.js +193 -0
- package/dist/relay-only.js.map +1 -0
- package/dist/relay-receipt-store.d.ts +155 -0
- package/dist/relay-receipt-store.d.ts.map +1 -0
- package/dist/relay-receipt-store.js +284 -0
- package/dist/relay-receipt-store.js.map +1 -0
- package/dist/relay-reconnect.d.ts +32 -0
- package/dist/relay-reconnect.d.ts.map +1 -0
- package/dist/relay-reconnect.js +29 -0
- package/dist/relay-reconnect.js.map +1 -0
- package/dist/reply-lag.d.ts +11 -0
- package/dist/reply-lag.d.ts.map +1 -0
- package/dist/reply-lag.js +46 -0
- package/dist/reply-lag.js.map +1 -0
- package/dist/resolve-named-agent.d.ts +49 -0
- package/dist/resolve-named-agent.d.ts.map +1 -0
- package/dist/resolve-named-agent.js +77 -0
- package/dist/resolve-named-agent.js.map +1 -0
- package/dist/restart-seal-resolver.d.ts +110 -0
- package/dist/restart-seal-resolver.d.ts.map +1 -0
- package/dist/restart-seal-resolver.js +353 -0
- package/dist/restart-seal-resolver.js.map +1 -0
- package/dist/resume-last-seen.d.ts +15 -0
- package/dist/resume-last-seen.d.ts.map +1 -0
- package/dist/resume-last-seen.js +44 -0
- package/dist/resume-last-seen.js.map +1 -0
- package/dist/retry-queue.d.ts +203 -0
- package/dist/retry-queue.d.ts.map +1 -0
- package/dist/retry-queue.js +701 -0
- package/dist/retry-queue.js.map +1 -0
- package/dist/roster-freshness.d.ts +160 -0
- package/dist/roster-freshness.d.ts.map +1 -0
- package/dist/roster-freshness.js +250 -0
- package/dist/roster-freshness.js.map +1 -0
- package/dist/screening-status.d.ts +15 -0
- package/dist/screening-status.d.ts.map +1 -0
- package/dist/screening-status.js +65 -0
- package/dist/screening-status.js.map +1 -0
- package/dist/seal-carried-close.d.ts +37 -0
- package/dist/seal-carried-close.d.ts.map +1 -0
- package/dist/seal-carried-close.js +179 -0
- package/dist/seal-carried-close.js.map +1 -0
- package/dist/seal-certificate-pull.d.ts +79 -0
- package/dist/seal-certificate-pull.d.ts.map +1 -0
- package/dist/seal-certificate-pull.js +186 -0
- package/dist/seal-certificate-pull.js.map +1 -0
- package/dist/seal-certified-root-check.d.ts +37 -0
- package/dist/seal-certified-root-check.d.ts.map +1 -0
- package/dist/seal-certified-root-check.js +127 -0
- package/dist/seal-certified-root-check.js.map +1 -0
- package/dist/seal-coordinator.d.ts +118 -0
- package/dist/seal-coordinator.d.ts.map +1 -0
- package/dist/seal-coordinator.js +927 -0
- package/dist/seal-coordinator.js.map +1 -0
- package/dist/seal-escalation.d.ts +80 -0
- package/dist/seal-escalation.d.ts.map +1 -0
- package/dist/seal-escalation.js +283 -0
- package/dist/seal-escalation.js.map +1 -0
- package/dist/seal-evidence-root-check.d.ts +70 -0
- package/dist/seal-evidence-root-check.d.ts.map +1 -0
- package/dist/seal-evidence-root-check.js +199 -0
- package/dist/seal-evidence-root-check.js.map +1 -0
- package/dist/seal-failure-store.d.ts +139 -0
- package/dist/seal-failure-store.d.ts.map +1 -0
- package/dist/seal-failure-store.js +207 -0
- package/dist/seal-failure-store.js.map +1 -0
- package/dist/seal-flows.d.ts +107 -0
- package/dist/seal-flows.d.ts.map +1 -0
- package/dist/seal-flows.js +638 -0
- package/dist/seal-flows.js.map +1 -0
- package/dist/seal-frontier-verify.d.ts +103 -0
- package/dist/seal-frontier-verify.d.ts.map +1 -0
- package/dist/seal-frontier-verify.js +143 -0
- package/dist/seal-frontier-verify.js.map +1 -0
- package/dist/seal-leaf.d.ts +58 -0
- package/dist/seal-leaf.d.ts.map +1 -0
- package/dist/seal-leaf.js +112 -0
- package/dist/seal-leaf.js.map +1 -0
- package/dist/seal-legibility-tbs.d.ts +25 -0
- package/dist/seal-legibility-tbs.d.ts.map +1 -0
- package/dist/seal-legibility-tbs.js +77 -0
- package/dist/seal-legibility-tbs.js.map +1 -0
- package/dist/seal-local-terminus.d.ts +41 -0
- package/dist/seal-local-terminus.d.ts.map +1 -0
- package/dist/seal-local-terminus.js +170 -0
- package/dist/seal-local-terminus.js.map +1 -0
- package/dist/seal-receipt-upgrade.d.ts +30 -0
- package/dist/seal-receipt-upgrade.d.ts.map +1 -0
- package/dist/seal-receipt-upgrade.js +49 -0
- package/dist/seal-receipt-upgrade.js.map +1 -0
- package/dist/seal-relay-silence.d.ts +51 -0
- package/dist/seal-relay-silence.d.ts.map +1 -0
- package/dist/seal-relay-silence.js +76 -0
- package/dist/seal-relay-silence.js.map +1 -0
- package/dist/seal-settle.d.ts +38 -0
- package/dist/seal-settle.d.ts.map +1 -0
- package/dist/seal-settle.js +33 -0
- package/dist/seal-settle.js.map +1 -0
- package/dist/seal-upgrade.d.ts +107 -0
- package/dist/seal-upgrade.d.ts.map +1 -0
- package/dist/seal-upgrade.js +200 -0
- package/dist/seal-upgrade.js.map +1 -0
- package/dist/sealed-conversation.d.ts +36 -0
- package/dist/sealed-conversation.d.ts.map +1 -0
- package/dist/sealed-conversation.js +171 -0
- package/dist/sealed-conversation.js.map +1 -0
- package/dist/sealed-leaf-set.d.ts +92 -0
- package/dist/sealed-leaf-set.d.ts.map +1 -0
- package/dist/sealed-leaf-set.js +122 -0
- package/dist/sealed-leaf-set.js.map +1 -0
- package/dist/send-claims.d.ts +56 -0
- package/dist/send-claims.d.ts.map +1 -0
- package/dist/send-claims.js +50 -0
- package/dist/send-claims.js.map +1 -0
- package/dist/session-assignment-parser.d.ts +104 -0
- package/dist/session-assignment-parser.d.ts.map +1 -0
- package/dist/session-assignment-parser.js +345 -0
- package/dist/session-assignment-parser.js.map +1 -0
- package/dist/session-category.d.ts +19 -0
- package/dist/session-category.d.ts.map +1 -0
- package/dist/session-category.js +14 -0
- package/dist/session-category.js.map +1 -0
- package/dist/session-ceremony.d.ts +297 -0
- package/dist/session-ceremony.d.ts.map +1 -0
- package/dist/session-ceremony.js +964 -0
- package/dist/session-ceremony.js.map +1 -0
- package/dist/session-closed.d.ts +79 -0
- package/dist/session-closed.d.ts.map +1 -0
- package/dist/session-closed.js +189 -0
- package/dist/session-closed.js.map +1 -0
- package/dist/session-connection-gater.d.ts +148 -0
- package/dist/session-connection-gater.d.ts.map +1 -0
- package/dist/session-connection-gater.js +332 -0
- package/dist/session-connection-gater.js.map +1 -0
- package/dist/session-content-context.d.ts +162 -0
- package/dist/session-content-context.d.ts.map +1 -0
- package/dist/session-content-context.js +2 -0
- package/dist/session-content-context.js.map +1 -0
- package/dist/session-content-handlers.d.ts +82 -0
- package/dist/session-content-handlers.d.ts.map +1 -0
- package/dist/session-content-handlers.js +1382 -0
- package/dist/session-content-handlers.js.map +1 -0
- package/dist/session-content-ingest.d.ts +206 -0
- package/dist/session-content-ingest.d.ts.map +1 -0
- package/dist/session-content-ingest.js +2167 -0
- package/dist/session-content-ingest.js.map +1 -0
- package/dist/session-content-send.d.ts +191 -0
- package/dist/session-content-send.d.ts.map +1 -0
- package/dist/session-content-send.js +1360 -0
- package/dist/session-content-send.js.map +1 -0
- package/dist/session-delivery-acks.d.ts +169 -0
- package/dist/session-delivery-acks.d.ts.map +1 -0
- package/dist/session-delivery-acks.js +569 -0
- package/dist/session-delivery-acks.js.map +1 -0
- package/dist/session-ephemerals.d.ts +279 -0
- package/dist/session-ephemerals.d.ts.map +1 -0
- package/dist/session-ephemerals.js +591 -0
- package/dist/session-ephemerals.js.map +1 -0
- package/dist/session-leaf-records.d.ts +159 -0
- package/dist/session-leaf-records.d.ts.map +1 -0
- package/dist/session-leaf-records.js +408 -0
- package/dist/session-leaf-records.js.map +1 -0
- package/dist/session-lifecycle.d.ts +303 -0
- package/dist/session-lifecycle.d.ts.map +1 -0
- package/dist/session-lifecycle.js +1679 -0
- package/dist/session-lifecycle.js.map +1 -0
- package/dist/session-liveness.d.ts +135 -0
- package/dist/session-liveness.d.ts.map +1 -0
- package/dist/session-liveness.js +347 -0
- package/dist/session-liveness.js.map +1 -0
- package/dist/session-name.d.ts +35 -0
- package/dist/session-name.d.ts.map +1 -0
- package/dist/session-name.js +60 -0
- package/dist/session-name.js.map +1 -0
- package/dist/session-node-factory.d.ts +18 -0
- package/dist/session-node-factory.d.ts.map +1 -0
- package/dist/session-node-factory.js +182 -0
- package/dist/session-node-factory.js.map +1 -0
- package/dist/session-node-manager.d.ts +877 -0
- package/dist/session-node-manager.d.ts.map +1 -0
- package/dist/session-node-manager.js +2998 -0
- package/dist/session-node-manager.js.map +1 -0
- package/dist/session-node-types.d.ts +1057 -0
- package/dist/session-node-types.d.ts.map +1 -0
- package/dist/session-node-types.js +657 -0
- package/dist/session-node-types.js.map +1 -0
- package/dist/session-notify.d.ts +46 -0
- package/dist/session-notify.d.ts.map +1 -0
- package/dist/session-notify.js +116 -0
- package/dist/session-notify.js.map +1 -0
- package/dist/session-own-chain-store.d.ts +65 -0
- package/dist/session-own-chain-store.d.ts.map +1 -0
- package/dist/session-own-chain-store.js +75 -0
- package/dist/session-own-chain-store.js.map +1 -0
- package/dist/session-queries.d.ts +476 -0
- package/dist/session-queries.d.ts.map +1 -0
- package/dist/session-queries.js +1007 -0
- package/dist/session-queries.js.map +1 -0
- package/dist/session-read-handlers.d.ts +87 -0
- package/dist/session-read-handlers.d.ts.map +1 -0
- package/dist/session-read-handlers.js +689 -0
- package/dist/session-read-handlers.js.map +1 -0
- package/dist/session-records.d.ts +341 -0
- package/dist/session-records.d.ts.map +1 -0
- package/dist/session-records.js +858 -0
- package/dist/session-records.js.map +1 -0
- package/dist/session-relay-client.d.ts +659 -0
- package/dist/session-relay-client.d.ts.map +1 -0
- package/dist/session-relay-client.js +2876 -0
- package/dist/session-relay-client.js.map +1 -0
- package/dist/session-relay.d.ts +397 -0
- package/dist/session-relay.d.ts.map +1 -0
- package/dist/session-relay.js +1636 -0
- package/dist/session-relay.js.map +1 -0
- package/dist/session-salt-agreement.d.ts +331 -0
- package/dist/session-salt-agreement.d.ts.map +1 -0
- package/dist/session-salt-agreement.js +472 -0
- package/dist/session-salt-agreement.js.map +1 -0
- package/dist/session-salts.d.ts +432 -0
- package/dist/session-salts.d.ts.map +1 -0
- package/dist/session-salts.js +1540 -0
- package/dist/session-salts.js.map +1 -0
- package/dist/session-schema.d.ts +30 -0
- package/dist/session-schema.d.ts.map +1 -0
- package/dist/session-schema.js +877 -0
- package/dist/session-schema.js.map +1 -0
- package/dist/session-seal-leaf-store.d.ts +70 -0
- package/dist/session-seal-leaf-store.d.ts.map +1 -0
- package/dist/session-seal-leaf-store.js +105 -0
- package/dist/session-seal-leaf-store.js.map +1 -0
- package/dist/session-seal.d.ts +334 -0
- package/dist/session-seal.d.ts.map +1 -0
- package/dist/session-seal.js +1017 -0
- package/dist/session-seal.js.map +1 -0
- package/dist/session-terminal-refusal.d.ts +65 -0
- package/dist/session-terminal-refusal.d.ts.map +1 -0
- package/dist/session-terminal-refusal.js +87 -0
- package/dist/session-terminal-refusal.js.map +1 -0
- package/dist/session-tree.d.ts +110 -0
- package/dist/session-tree.d.ts.map +1 -0
- package/dist/session-tree.js +144 -0
- package/dist/session-tree.js.map +1 -0
- package/dist/session-views.d.ts +47 -0
- package/dist/session-views.d.ts.map +1 -0
- package/dist/session-views.js +278 -0
- package/dist/session-views.js.map +1 -0
- package/dist/signal-handlers.d.ts +63 -0
- package/dist/signal-handlers.d.ts.map +1 -0
- package/dist/signal-handlers.js +980 -0
- package/dist/signal-handlers.js.map +1 -0
- package/dist/signal-requirement-policy.d.ts +51 -0
- package/dist/signal-requirement-policy.d.ts.map +1 -0
- package/dist/signal-requirement-policy.js +89 -0
- package/dist/signal-requirement-policy.js.map +1 -0
- package/dist/signal-revocability.d.ts +49 -0
- package/dist/signal-revocability.d.ts.map +1 -0
- package/dist/signal-revocability.js +93 -0
- package/dist/signal-revocability.js.map +1 -0
- package/dist/signal-submission.d.ts +181 -0
- package/dist/signal-submission.d.ts.map +1 -0
- package/dist/signal-submission.js +368 -0
- package/dist/signal-submission.js.map +1 -0
- package/dist/signaling-connect.d.ts +118 -0
- package/dist/signaling-connect.d.ts.map +1 -0
- package/dist/signaling-connect.js +538 -0
- package/dist/signaling-connect.js.map +1 -0
- package/dist/signaling-wiring.d.ts +105 -0
- package/dist/signaling-wiring.d.ts.map +1 -0
- package/dist/signaling-wiring.js +393 -0
- package/dist/signaling-wiring.js.map +1 -0
- package/dist/singleton-lock.d.ts +85 -0
- package/dist/singleton-lock.d.ts.map +1 -0
- package/dist/singleton-lock.js +219 -0
- package/dist/singleton-lock.js.map +1 -0
- package/dist/sqlcipher-db.d.ts +139 -0
- package/dist/sqlcipher-db.d.ts.map +1 -0
- package/dist/sqlcipher-db.js +357 -0
- package/dist/sqlcipher-db.js.map +1 -0
- package/dist/standing-receivers.d.ts +319 -0
- package/dist/standing-receivers.d.ts.map +1 -0
- package/dist/standing-receivers.js +1295 -0
- package/dist/standing-receivers.js.map +1 -0
- package/dist/start-agent.d.ts +64 -0
- package/dist/start-agent.d.ts.map +1 -0
- package/dist/start-agent.js +136 -0
- package/dist/start-agent.js.map +1 -0
- package/dist/status-handler.d.ts +54 -0
- package/dist/status-handler.d.ts.map +1 -0
- package/dist/status-handler.js +61 -0
- package/dist/status-handler.js.map +1 -0
- package/dist/submission-retry.d.ts +208 -0
- package/dist/submission-retry.d.ts.map +1 -0
- package/dist/submission-retry.js +506 -0
- package/dist/submission-retry.js.map +1 -0
- package/dist/telegram-bot-client.d.ts +34 -0
- package/dist/telegram-bot-client.d.ts.map +1 -0
- package/dist/telegram-bot-client.js +36 -0
- package/dist/telegram-bot-client.js.map +1 -0
- package/dist/telegram-doorbell.d.ts +38 -0
- package/dist/telegram-doorbell.d.ts.map +1 -0
- package/dist/telegram-doorbell.js +140 -0
- package/dist/telegram-doorbell.js.map +1 -0
- package/dist/test-handlers.d.ts +62 -0
- package/dist/test-handlers.d.ts.map +1 -0
- package/dist/test-handlers.js +240 -0
- package/dist/test-handlers.js.map +1 -0
- package/dist/testing.d.ts +10 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +10 -0
- package/dist/testing.js.map +1 -0
- package/dist/transport-composition.d.ts +31 -0
- package/dist/transport-composition.d.ts.map +1 -0
- package/dist/transport-composition.js +55 -0
- package/dist/transport-composition.js.map +1 -0
- package/dist/transport-selector.d.ts +202 -0
- package/dist/transport-selector.d.ts.map +1 -0
- package/dist/transport-selector.js +196 -0
- package/dist/transport-selector.js.map +1 -0
- package/dist/trust-signal-pickup-listener.d.ts +43 -0
- package/dist/trust-signal-pickup-listener.d.ts.map +1 -0
- package/dist/trust-signal-pickup-listener.js +48 -0
- package/dist/trust-signal-pickup-listener.js.map +1 -0
- package/dist/trust-signal-store.d.ts +406 -0
- package/dist/trust-signal-store.d.ts.map +1 -0
- package/dist/trust-signal-store.js +939 -0
- package/dist/trust-signal-store.js.map +1 -0
- package/dist/trust-signal-sweep-tick.d.ts +60 -0
- package/dist/trust-signal-sweep-tick.d.ts.map +1 -0
- package/dist/trust-signal-sweep-tick.js +101 -0
- package/dist/trust-signal-sweep-tick.js.map +1 -0
- package/dist/trust-signal-sweep.d.ts +94 -0
- package/dist/trust-signal-sweep.d.ts.map +1 -0
- package/dist/trust-signal-sweep.js +147 -0
- package/dist/trust-signal-sweep.js.map +1 -0
- package/dist/type-registry.d.ts +42 -0
- package/dist/type-registry.d.ts.map +1 -0
- package/dist/type-registry.js +37 -0
- package/dist/type-registry.js.map +1 -0
- package/dist/types.d.ts +746 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +20 -0
- package/dist/types.js.map +1 -0
- package/dist/unresolved-nodes-report.d.ts +14 -0
- package/dist/unresolved-nodes-report.d.ts.map +1 -0
- package/dist/unresolved-nodes-report.js +96 -0
- package/dist/unresolved-nodes-report.js.map +1 -0
- package/dist/vocabulary.d.ts +150 -0
- package/dist/vocabulary.d.ts.map +1 -0
- package/dist/vocabulary.js +386 -0
- package/dist/vocabulary.js.map +1 -0
- package/dist/who-label.d.ts +28 -0
- package/dist/who-label.d.ts.map +1 -0
- package/dist/who-label.js +31 -0
- package/dist/who-label.js.map +1 -0
- package/dist/who-resolver.d.ts +15 -0
- package/dist/who-resolver.d.ts.map +1 -0
- package/dist/who-resolver.js +47 -0
- package/dist/who-resolver.js.map +1 -0
- package/dist/wire-content-hash.d.ts +93 -0
- package/dist/wire-content-hash.d.ts.map +1 -0
- package/dist/wire-content-hash.js +116 -0
- package/dist/wire-content-hash.js.map +1 -0
- package/dist/withheld-content.d.ts +13 -0
- package/dist/withheld-content.d.ts.map +1 -0
- package/dist/withheld-content.js +46 -0
- package/dist/withheld-content.js.map +1 -0
- package/dist/witness-alerts.d.ts +40 -0
- package/dist/witness-alerts.d.ts.map +1 -0
- package/dist/witness-alerts.js +102 -0
- package/dist/witness-alerts.js.map +1 -0
- package/package.json +5 -5
|
@@ -0,0 +1,1025 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOD-DOC-INBOUND-2 / DOD-DOC-DELIVERY-2 — the composition of the document layer.
|
|
3
|
+
*
|
|
4
|
+
* Everything M14 built is a unit with injected seams. This is where they become one thing, and it
|
|
5
|
+
* is a module rather than a block inside `daemon.ts` for one reason: the assembly makes decisions.
|
|
6
|
+
* Which verifier, which live-doc policy, and — the one that matters — whether the layer is present
|
|
7
|
+
* at all.
|
|
8
|
+
*
|
|
9
|
+
* ── ALL OR NOTHING ────────────────────────────────────────────────────────────────────────────
|
|
10
|
+
*
|
|
11
|
+
* The layer is built completely or not built. There is no partially-wired mode, because every
|
|
12
|
+
* half-wiring is a distinct silent failure: an inbound path with no ack producer leaves the peer
|
|
13
|
+
* retrying until their document stalls; a delivery worker with no inbound counterpart publishes
|
|
14
|
+
* envelopes nobody can answer. `DOD-DOC-DELIVERY-2` records that ordering constraint on its own
|
|
15
|
+
* line, and this is where it is enforced instead of remembered.
|
|
16
|
+
*
|
|
17
|
+
* ── THE VERIFIER IS REQUIRED, AND RESOLVES THROUGH THE CALLER ─────────────────────────────────
|
|
18
|
+
*
|
|
19
|
+
* Signature verification needs an agent id → public key mapping, which lives with the daemon's
|
|
20
|
+
* contact and session state rather than here. It is passed in, and there is no default: a default
|
|
21
|
+
* would be a default answer to "is this authentic", and both inbound paths refuse rather than
|
|
22
|
+
* admit when it says no.
|
|
23
|
+
*/
|
|
24
|
+
import { verify } from "@cello-protocol/crypto";
|
|
25
|
+
import { DocumentStore } from "./document-store.js";
|
|
26
|
+
import { DocumentEngine } from "./document-engine.js";
|
|
27
|
+
import { DocumentGate } from "./document-gate.js";
|
|
28
|
+
import { screeningRule, SCREEN_RULE_ID } from "./document-screen.js";
|
|
29
|
+
import { DocumentRejections } from "./document-rejection.js";
|
|
30
|
+
import { DocumentInbound } from "./document-inbound.js";
|
|
31
|
+
import { DocumentAmendmentStore } from "./document-amendment-store.js";
|
|
32
|
+
import { DocumentFrameRouter } from "./document-frame-router.js";
|
|
33
|
+
import { LiveDocuments } from "./document-live-docs.js";
|
|
34
|
+
import { DocumentLifecycle } from "./document-lifecycle.js";
|
|
35
|
+
import { DocumentNotifications, changedKeyPaths } from "./document-notify.js";
|
|
36
|
+
import { matchWatchedPaths, matchingWatches } from "./document-watch.js";
|
|
37
|
+
import { projectDocumentText } from "./document-json.js";
|
|
38
|
+
import { rootForDocumentType } from "./document-types.js";
|
|
39
|
+
import { DocumentHandshake } from "./document-handshake.js";
|
|
40
|
+
import { DocumentWritePath } from "./document-write-path.js";
|
|
41
|
+
import { decodeDocumentRejection, buildDocumentRejectionTbs, documentRejectionHash, decodeDocumentProposalAck, buildDocumentProposalAckTbs, decodeDocumentUpdateEnvelope, encodeDocumentAmendment, decodeDocumentAmendment, decodeDocumentProposal, encodeDocumentProposal, documentIdFromProposal, buildDocumentProposalTbs, encodeDocumentProposalAck, DOCUMENT_PROPOSAL_ACK_VERSION, MAX_PROPOSAL_REFUSAL_REASON_LENGTH, documentAmendmentHash, documentGovernancePolicy, arrangementGenesisFromProposal, deriveDocumentState, deriveDocumentStateAt, checkEntryAdmissible, decodeDocumentReconcile, encodeDocumentReconcile, DOCUMENT_RECONCILE_EXCHANGE_VERSION, } from "@cello-protocol/protocol-types";
|
|
42
|
+
import { LEAF_KIND_REJECT } from "./session-relay-client.js";
|
|
43
|
+
import { buildReconcileBlock, respondToReconcile, } from "./document-reconcile-engine.js";
|
|
44
|
+
import { extractErrorMessage } from "./error-message.js";
|
|
45
|
+
/**
|
|
46
|
+
* The default `publicKeyFor`: a remote agent's id IS its K_local public key, hex-encoded (M14-D5).
|
|
47
|
+
*
|
|
48
|
+
* `agent_id` in this daemon is a LOCAL primary key on the `agents` table — it names rows in our own
|
|
49
|
+
* database and cannot identify a remote peer. The pubkey is the only self-verifying identifier
|
|
50
|
+
* available: the signature checks against it directly, with no lookup that could be stale, missing
|
|
51
|
+
* or poisoned sitting on the critical path of every authentication.
|
|
52
|
+
*
|
|
53
|
+
* Malformed input returns null rather than throwing, and null is a refusal. An id that is not a
|
|
54
|
+
* 32-byte hex key is not "a peer we have no key for" — it is a frame that does not follow the
|
|
55
|
+
* protocol — but both must refuse, and refusing loudly at the verify step is where it belongs.
|
|
56
|
+
*/
|
|
57
|
+
export function agentPublicKeyFromId(agentId) {
|
|
58
|
+
if (!/^[0-9a-f]{64}$/.test(agentId))
|
|
59
|
+
return null;
|
|
60
|
+
return Uint8Array.from(Buffer.from(agentId, "hex"));
|
|
61
|
+
}
|
|
62
|
+
export function createDocumentLayer(deps) {
|
|
63
|
+
const { db, logger } = deps;
|
|
64
|
+
const store = new DocumentStore(db, logger);
|
|
65
|
+
const engine = new DocumentEngine(logger);
|
|
66
|
+
const gate = new DocumentGate(engine, {}, logger);
|
|
67
|
+
// DOD-DOC-SCREEN-1 — REGISTERED, not merely written.
|
|
68
|
+
//
|
|
69
|
+
// The gate has carried a comment saying this rule plugs in here since the gate was built, and the
|
|
70
|
+
// rule not existing was the whole gap: document content reached the CRDT with no content gate at
|
|
71
|
+
// all, because the message sanitizer is deliberately kept off this path (it REWRITES, and
|
|
72
|
+
// rewriting a replica is permanent divergence).
|
|
73
|
+
//
|
|
74
|
+
// Registered at construction rather than by a caller, for the reason this milestone learned four
|
|
75
|
+
// separate times — a unit with no caller reads exactly like a working one. If this line is
|
|
76
|
+
// deleted the screening tests still pass, so `document-surface-e2e` asserts a refusal end to end.
|
|
77
|
+
gate.addRule(SCREEN_RULE_ID, screeningRule);
|
|
78
|
+
const rejections = new DocumentRejections(store, logger);
|
|
79
|
+
// Epoch zero comes from the stored PROPOSAL, not from the envelope log — see `LiveDocuments.get`.
|
|
80
|
+
// Declared before `handshake` exists, so it is resolved lazily; a rebuild only ever happens long
|
|
81
|
+
// after construction.
|
|
82
|
+
const live = new LiveDocuments(store, engine, logger, (ownerAgentId, documentId) => {
|
|
83
|
+
const record = handshake.get(ownerAgentId, documentId);
|
|
84
|
+
return record?.envelope.starting_content ?? null;
|
|
85
|
+
});
|
|
86
|
+
const lifecycle = new DocumentLifecycle(store, logger,
|
|
87
|
+
// SYNC-D8 — "was this owner written out?" answered by the same fold as everything else.
|
|
88
|
+
(ownerAgentId, documentId) => standingOf(ownerAgentId, documentId, ownerAgentId) === "removed",
|
|
89
|
+
// Review F2 — "is it ended?" answered by the fold too; `derived: false` hands the pre-pivot
|
|
90
|
+
// bilateral record back to its column.
|
|
91
|
+
(ownerAgentId, documentId) => {
|
|
92
|
+
const derived = reconcileReads(ownerAgentId).deriveState(documentId);
|
|
93
|
+
return derived.ok
|
|
94
|
+
? { derived: true, ended: derived.state.ended }
|
|
95
|
+
: { derived: false, ended: null };
|
|
96
|
+
});
|
|
97
|
+
const notifications = new DocumentNotifications(store, logger);
|
|
98
|
+
// THE FILE SURFACE. Built, tested and instantiated NOWHERE until now — the same defect the tool
|
|
99
|
+
// surface had: a complete unit with no production caller reads exactly like a working feature.
|
|
100
|
+
// Without it §4.1's whole premise is missing, because a human collaborating on a document edits a
|
|
101
|
+
// file in their editor, and an agent with file tools reaches for them before any MCP verb.
|
|
102
|
+
const writePath = deps.workspaceRoot ? new DocumentWritePath(engine, deps.workspaceRoot, logger) : null;
|
|
103
|
+
/**
|
|
104
|
+
* One verifier for both paths. Ed25519 (RFC 8032) over the TBS the caller built.
|
|
105
|
+
*
|
|
106
|
+
* An UNKNOWN agent verifies as FALSE, and is logged distinctly. "We have no key for this peer"
|
|
107
|
+
* and "the signature is wrong" both have to refuse — admitting what we cannot authenticate is
|
|
108
|
+
* the outcome the verify step exists to prevent — but they are different things to tell an
|
|
109
|
+
* operator, and only one of them is a peer misbehaving.
|
|
110
|
+
*
|
|
111
|
+
* No try/catch: `verify` already fails closed on a malformed key or signature (its own body is a
|
|
112
|
+
* try returning false), so a catch here would be a branch nothing can reach.
|
|
113
|
+
*/
|
|
114
|
+
const verifySignature = (agentId, tbs, signature) => {
|
|
115
|
+
const pubkey = deps.publicKeyFor(agentId);
|
|
116
|
+
if (pubkey === null) {
|
|
117
|
+
logger.warn("document.verify.no_key", { agentId });
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
return verify(pubkey, tbs, signature);
|
|
121
|
+
};
|
|
122
|
+
const inbound = new DocumentInbound({
|
|
123
|
+
store,
|
|
124
|
+
engine,
|
|
125
|
+
gate,
|
|
126
|
+
rejections,
|
|
127
|
+
logger,
|
|
128
|
+
...(deps.screenProjected ? { screenProjected: deps.screenProjected } : {}),
|
|
129
|
+
verifySignature,
|
|
130
|
+
liveDocFor: (ownerAgentId, documentId) => live.get(ownerAgentId, documentId),
|
|
131
|
+
standingOf: (ownerAgentId, documentId, agentId) => standingOf(ownerAgentId, documentId, agentId),
|
|
132
|
+
// The CONTENT door: strictly participants (R17 — invited seats receive, never author).
|
|
133
|
+
currentHolders: (ownerAgentId, documentId) => participantsFor(ownerAgentId, documentId),
|
|
134
|
+
// SYNC-G1 — the world an envelope's signed frontier names (R20's input for the causal gate).
|
|
135
|
+
deriveAtFrontier: (ownerAgentId, documentId, frontier) => {
|
|
136
|
+
const record = handshake.get(ownerAgentId, documentId);
|
|
137
|
+
if (!record)
|
|
138
|
+
return { ok: false, reason: "document_genesis_missing" };
|
|
139
|
+
try {
|
|
140
|
+
const at = deriveDocumentStateAt(arrangementGenesisFromProposal(record.envelope), amendments.chain(ownerAgentId, documentId), frontier, documentGovernancePolicy, verifySignature);
|
|
141
|
+
if (!at.ok)
|
|
142
|
+
return { ok: false, reason: at.reason, missing: at.missing };
|
|
143
|
+
return {
|
|
144
|
+
ok: true,
|
|
145
|
+
participants: at.state.participants,
|
|
146
|
+
invited: at.state.invited,
|
|
147
|
+
ended: at.state.ended,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
return {
|
|
152
|
+
ok: false,
|
|
153
|
+
reason: `document_chain_undecodable: ${extractErrorMessage(err)}`,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
sign: deps.sign,
|
|
158
|
+
});
|
|
159
|
+
// The handshake verifies a proposal against its NAMED proposer — the same resolver, so a forged
|
|
160
|
+
// proposal is refused before it can occupy a document_id (ON CONFLICT DO NOTHING makes the first
|
|
161
|
+
// arrival's bytes permanent for that id).
|
|
162
|
+
const handshake = new DocumentHandshake(db, logger, verifySignature);
|
|
163
|
+
// M14B / DOD-MP-JOIN-1 — the amendment chain and the join-consent stores. The membership READ
|
|
164
|
+
// path (`currentDocumentEpoch`) has run through DocumentStore since AMEND-1; these are the
|
|
165
|
+
// WRITE path, and every append below validates first (the standing AMEND-1 condition).
|
|
166
|
+
const amendments = new DocumentAmendmentStore(db, logger);
|
|
167
|
+
/**
|
|
168
|
+
* M14B / DOD-MP-FANOUT-1 — the CURRENT holders of a document, derived from genesis + the
|
|
169
|
+
* recorded chain. Null when the document is unknown or its chain does not derive — NOT an
|
|
170
|
+
* empty list, because "nobody holds this" and "this cannot be answered" are different facts
|
|
171
|
+
* and the worker schedules them differently.
|
|
172
|
+
*/
|
|
173
|
+
const holdersFor = (ownerAgentId, documentId) => {
|
|
174
|
+
const genesisRecord = handshake.get(ownerAgentId, documentId);
|
|
175
|
+
if (!genesisRecord) {
|
|
176
|
+
// The SAME event the publish refusal points at — an operator hunting
|
|
177
|
+
// document.holders.underivable must find it for BOTH null causes (review M6).
|
|
178
|
+
logger.error("document.holders.underivable", {
|
|
179
|
+
documentId,
|
|
180
|
+
reason: "no_genesis_record: the document has a row but no stored genesis proposal",
|
|
181
|
+
});
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
// CONTAINED. `chain()` decodes every stored amendment and THROWS on bytes this build cannot
|
|
185
|
+
// read, and this function's own contract is to return null when it cannot derive — so the throw
|
|
186
|
+
// escaped past every caller written against that contract. It reached the operator on
|
|
187
|
+
// `cello_doc_write` as a raw `Data read, but end of buffer not reached`: a CBOR library naming
|
|
188
|
+
// where it surfaced, in place of the refusal the publish path was already holding ready.
|
|
189
|
+
let derived;
|
|
190
|
+
try {
|
|
191
|
+
derived = deriveDocumentState(arrangementGenesisFromProposal(genesisRecord.envelope), amendments.chain(ownerAgentId, documentId), documentGovernancePolicy, verifySignature);
|
|
192
|
+
}
|
|
193
|
+
catch (err) {
|
|
194
|
+
logger.error("document.holders.undecodable", {
|
|
195
|
+
documentId,
|
|
196
|
+
reason: extractErrorMessage(err),
|
|
197
|
+
});
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
if (!derived.ok) {
|
|
201
|
+
logger.error("document.holders.underivable", {
|
|
202
|
+
documentId,
|
|
203
|
+
reason: derived.reason,
|
|
204
|
+
});
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
// PARTICIPANTS ∪ INVITED (P2 review F4/F5): this is the "who is seated" set — delivery
|
|
208
|
+
// targets, control-frame addressing, and the close agreement all reach every seat, because a
|
|
209
|
+
// peer whose consent entry is still in flight must neither be starved of the entries they
|
|
210
|
+
// will need nor ended around. An invited seat still cannot AUTHOR anything but its own
|
|
211
|
+
// consent/refusal — the CONTENT door checks `participantsFor`, and the fold enforces it for
|
|
212
|
+
// governance regardless of who we send to.
|
|
213
|
+
return [...derived.state.participants, ...derived.state.invited];
|
|
214
|
+
};
|
|
215
|
+
/**
|
|
216
|
+
* Strictly-consented participants — the CONTENT-AUTHORSHIP set (R17: an invited seat may
|
|
217
|
+
* receive, never author). The inbound sender gate checks this; everything delivery-facing uses
|
|
218
|
+
* `holdersFor`, which also counts invited seats.
|
|
219
|
+
*/
|
|
220
|
+
const participantsFor = (ownerAgentId, documentId) => {
|
|
221
|
+
const genesisRecord = handshake.get(ownerAgentId, documentId);
|
|
222
|
+
if (!genesisRecord)
|
|
223
|
+
return null;
|
|
224
|
+
let derived;
|
|
225
|
+
try {
|
|
226
|
+
derived = deriveDocumentState(arrangementGenesisFromProposal(genesisRecord.envelope), amendments.chain(ownerAgentId, documentId), documentGovernancePolicy, verifySignature);
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
if (!derived.ok)
|
|
232
|
+
return null;
|
|
233
|
+
return [...derived.state.participants];
|
|
234
|
+
};
|
|
235
|
+
/**
|
|
236
|
+
* SYNC-D8 — the ONE derivation of an agent's standing in a document, from the fold. The old
|
|
237
|
+
* old linear membership walk was a second derivation that could disagree with
|
|
238
|
+
* the fold about who is seated; every consumer now asks this.
|
|
239
|
+
*
|
|
240
|
+
* - participant / invited: seated, per R17.
|
|
241
|
+
* - removed: not seated, and an APPLIED remove_holder entry names them (fold-void removals
|
|
242
|
+
* do not count — a void contributed nothing, F4).
|
|
243
|
+
* - stranger: not seated, never removed.
|
|
244
|
+
* - unknown: the chain does not derive (no genesis, undecodable bytes) — callers must not
|
|
245
|
+
* treat this as any of the other four.
|
|
246
|
+
*/
|
|
247
|
+
const standingOf = (ownerAgentId, documentId, agentId) => {
|
|
248
|
+
const derived = reconcileReads(ownerAgentId).deriveState(documentId);
|
|
249
|
+
if (!derived.ok)
|
|
250
|
+
return "unknown";
|
|
251
|
+
if (derived.state.participants.has(agentId))
|
|
252
|
+
return "participant";
|
|
253
|
+
if (derived.state.invited.has(agentId))
|
|
254
|
+
return "invited";
|
|
255
|
+
const inert = new Set([
|
|
256
|
+
...derived.state.voids.map((v) => v.hash),
|
|
257
|
+
...derived.state.excluded.map((e) => e.hash),
|
|
258
|
+
]);
|
|
259
|
+
let chain;
|
|
260
|
+
try {
|
|
261
|
+
chain = [...amendments.chain(ownerAgentId, documentId)];
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
return "unknown";
|
|
265
|
+
}
|
|
266
|
+
for (const env of chain) {
|
|
267
|
+
if (env.body.kind !== "remove_holder" || env.body.subject_agent_id !== agentId)
|
|
268
|
+
continue;
|
|
269
|
+
const hash = Buffer.from(documentAmendmentHash(env.body)).toString("hex");
|
|
270
|
+
if (!inert.has(hash))
|
|
271
|
+
return "removed";
|
|
272
|
+
}
|
|
273
|
+
return "stranger";
|
|
274
|
+
};
|
|
275
|
+
/**
|
|
276
|
+
* DOD-DOC-PUSH-NOT-POLL-1 — WHAT WE HOLD THAT THIS PARTY HAS NOT CONFIRMED RECEIVING, as a
|
|
277
|
+
* fingerprint the scheduler compares and never interprets; `null` means nothing is pending.
|
|
278
|
+
*
|
|
279
|
+
* This is the SAME comparison that answers "are they behind" on the list surface, deliberately
|
|
280
|
+
* written once: two copies of it is two daemons disagreeing about who needs an exchange. The
|
|
281
|
+
* list projects it to a boolean; the sweep needs the VALUE, because it must tell an unchanged
|
|
282
|
+
* holding (already offered — go quiet) from a new one (a trigger — speak now).
|
|
283
|
+
*
|
|
284
|
+
* A party with no view row at all has confirmed nothing, so everything we hold is pending.
|
|
285
|
+
*
|
|
286
|
+
* NOT the retired `pendingContent` count (R47): that was an operator-facing number no ledger
|
|
287
|
+
* could make truthful. This never leaves the scheduler, and holds no authority — R41 stands,
|
|
288
|
+
* it may only delay an exchange.
|
|
289
|
+
*/
|
|
290
|
+
const pendingAgainstView = (ownerAgentId, documentId, view) => {
|
|
291
|
+
const parts = [];
|
|
292
|
+
for (const [author, mark] of amendments.watermarks(ownerAgentId, documentId)) {
|
|
293
|
+
if (mark.seq > (view?.govSeqs[author] ?? 0))
|
|
294
|
+
parts.push(`g:${author}:${mark.seq}`);
|
|
295
|
+
}
|
|
296
|
+
for (const [author, count] of store.envelopeCountsBySender(ownerAgentId, documentId)) {
|
|
297
|
+
if (count > (view?.contentCounts[author] ?? 0))
|
|
298
|
+
parts.push(`c:${author}:${count}`);
|
|
299
|
+
}
|
|
300
|
+
if (parts.length === 0)
|
|
301
|
+
return null;
|
|
302
|
+
parts.sort();
|
|
303
|
+
return parts.join(",");
|
|
304
|
+
};
|
|
305
|
+
const pendingFor = (ownerAgentId, documentId, partyAgentId) => pendingAgainstView(ownerAgentId, documentId, store.partyView(ownerAgentId, documentId, partyAgentId));
|
|
306
|
+
/**
|
|
307
|
+
* SYNC-R46 / spec §9 — one party's sync state for the LIST SURFACE, projected from `pendingFor`
|
|
308
|
+
* against our own positions. Never a correctness input (R44): the same comparison decides what
|
|
309
|
+
* the operator is shown and whether the sweep has anything to say, so the two cannot disagree.
|
|
310
|
+
*/
|
|
311
|
+
const partySync = (ownerAgentId, documentId, partyAgentId) => {
|
|
312
|
+
const view = store.partyView(ownerAgentId, documentId, partyAgentId);
|
|
313
|
+
if (!view)
|
|
314
|
+
return { sync: "unseen", lastSyncedAtMs: null };
|
|
315
|
+
// The row we already hold — re-reading it here doubled the row reads on a surface that walks
|
|
316
|
+
// every party of every document (review F6).
|
|
317
|
+
const behind = pendingAgainstView(ownerAgentId, documentId, view) !== null;
|
|
318
|
+
const blockedBy = view.refused.length === 0
|
|
319
|
+
? undefined
|
|
320
|
+
: view.refused.find((hash) => store.getEnvelopeLog(ownerAgentId, documentId).some((row) => row.docPrevHash === hash));
|
|
321
|
+
return {
|
|
322
|
+
sync: behind ? "behind" : "in_sync",
|
|
323
|
+
lastSyncedAtMs: view.lastExchangeMs,
|
|
324
|
+
...(blockedBy ? { blockedBy } : {}),
|
|
325
|
+
};
|
|
326
|
+
};
|
|
327
|
+
/**
|
|
328
|
+
* SYNC-P5 (R43) — every (party → shared ACTIVE documents) pair one owner's sweep considers.
|
|
329
|
+
* Seats come from the FOLD, per document; an ended or underivable document contributes
|
|
330
|
+
* nothing, which is what lets a converged-and-ended document reach quiescence.
|
|
331
|
+
*/
|
|
332
|
+
const sweepTargets = (ownerAgentId) => {
|
|
333
|
+
const targets = new Map();
|
|
334
|
+
for (const doc of store.listDocuments(ownerAgentId)) {
|
|
335
|
+
if (doc.status !== "active")
|
|
336
|
+
continue;
|
|
337
|
+
const derived = reconcileReads(ownerAgentId).deriveState(doc.documentId);
|
|
338
|
+
if (!derived.ok || derived.state.ended !== null)
|
|
339
|
+
continue;
|
|
340
|
+
const seats = [...derived.state.participants, ...derived.state.invited];
|
|
341
|
+
// A HOLDER THAT NO LONGER HOLDS A SEAT HAS NOTHING TO EXCHANGE.
|
|
342
|
+
//
|
|
343
|
+
// Removal is forward-only: the copy and its history stay ours to read, but edits no longer
|
|
344
|
+
// publish outward and theirs no longer arrive. So there is, by derivation, nothing left to
|
|
345
|
+
// reconcile — and the peers say so, refusing with `terminal: true` and the words "there is
|
|
346
|
+
// nothing further to reconcile".
|
|
347
|
+
//
|
|
348
|
+
// Without this the sweep derived its targets from the OTHER seats and never asked whether we
|
|
349
|
+
// still occupied one, so a removed holder asked forever: measured 105 refusals against one
|
|
350
|
+
// document in 85 minutes, every one of them terminal, every one of them asked again.
|
|
351
|
+
//
|
|
352
|
+
// The cost is not the wasted dial. Each attempt opens a session and pushes ack frames, and
|
|
353
|
+
// every frame consumes a relay canonical position while the receiving tree does not advance
|
|
354
|
+
// with it. That is what drives a conversation's tree behind the relay counter and strands
|
|
355
|
+
// real messages behind an ordering gap that nothing fills.
|
|
356
|
+
if (!seats.includes(ownerAgentId))
|
|
357
|
+
continue;
|
|
358
|
+
for (const seat of seats) {
|
|
359
|
+
if (seat === ownerAgentId)
|
|
360
|
+
continue;
|
|
361
|
+
const docs = targets.get(seat);
|
|
362
|
+
if (docs)
|
|
363
|
+
docs.push(doc.documentId);
|
|
364
|
+
else
|
|
365
|
+
targets.set(seat, [doc.documentId]);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
return targets;
|
|
369
|
+
};
|
|
370
|
+
/** Is this agent a CURRENT holder — the ack gate's membership question. */
|
|
371
|
+
const isCurrentHolder = (ownerAgentId, documentId, agentId) => {
|
|
372
|
+
const holders = holdersFor(ownerAgentId, documentId);
|
|
373
|
+
return holders !== null && holders.includes(agentId);
|
|
374
|
+
};
|
|
375
|
+
const recordAmendmentImpl = (ownerAgentId, wire, nowMs) => {
|
|
376
|
+
// An entry reaching an EXISTING holder. The door refuses only what no future entry can
|
|
377
|
+
// ever make good — a broken collection binding, an unproven author, a failed signature
|
|
378
|
+
// (checkEntryAdmissible). Everything semantic is the FOLD's ruling at consumption, and a
|
|
379
|
+
// fold-void entry is still history (F4): bouncing it here would leave two holders holding
|
|
380
|
+
// different sets.
|
|
381
|
+
const env = decodeDocumentAmendment(wire);
|
|
382
|
+
const documentId = env.body.document_id;
|
|
383
|
+
if (!store.getDocument(ownerAgentId, documentId)) {
|
|
384
|
+
throw new Error(`document_unknown: no document ${documentId.slice(0, 16)}… for this agent`);
|
|
385
|
+
}
|
|
386
|
+
const record = handshake.get(ownerAgentId, documentId);
|
|
387
|
+
if (!record) {
|
|
388
|
+
throw new Error(`document_genesis_missing: ${documentId.slice(0, 16)}… has a row but no stored genesis ` +
|
|
389
|
+
`proposal to replay from`);
|
|
390
|
+
}
|
|
391
|
+
const admissible = checkEntryAdmissible(env, verifySignature);
|
|
392
|
+
if (!admissible.ok)
|
|
393
|
+
throw new Error(admissible.reason);
|
|
394
|
+
// THE STRANGER DOOR (SYNC-R18, interim until P3's full entitlement classes): a fold-void
|
|
395
|
+
// entry is history only when its author is KNOWN to this document — a genesis party or
|
|
396
|
+
// someone an EFFECTIVE admission names (which covers invited and removed authors, whose
|
|
397
|
+
// earlier work must still converge, R20). Effective, not merely held: a hostile holder can
|
|
398
|
+
// mint a self-signed, fold-void admission naming any key, and counting it would hand that
|
|
399
|
+
// key an unbounded license to grow every holder's entry set (review F4). A stranger's
|
|
400
|
+
// governance is refused by name, never stored.
|
|
401
|
+
const author = env.body.author_agent_id;
|
|
402
|
+
const genesisArr = arrangementGenesisFromProposal(record.envelope);
|
|
403
|
+
let authorKnown = genesisArr.proposerAgentId === author || genesisArr.peerAgentId === author;
|
|
404
|
+
if (!authorKnown) {
|
|
405
|
+
const held = amendments.chain(ownerAgentId, documentId);
|
|
406
|
+
const doorDerived = deriveDocumentState(genesisArr, held, documentGovernancePolicy, verifySignature);
|
|
407
|
+
if (!doorDerived.ok)
|
|
408
|
+
throw new Error(doorDerived.reason);
|
|
409
|
+
const inert = new Set([
|
|
410
|
+
...doorDerived.state.voids.map((v) => v.hash),
|
|
411
|
+
...doorDerived.state.excluded.map((e) => e.hash),
|
|
412
|
+
]);
|
|
413
|
+
authorKnown = held.some((e) => e.body.kind === "add_holder" &&
|
|
414
|
+
e.body.subject_agent_id === author &&
|
|
415
|
+
!inert.has(Buffer.from(documentAmendmentHash(e.body)).toString("hex")));
|
|
416
|
+
}
|
|
417
|
+
if (!authorKnown) {
|
|
418
|
+
throw new Error(`document_author_stranger: ${author} is neither a genesis party nor named by any ` +
|
|
419
|
+
`effective admission — a stranger's governance is refused, not stored`);
|
|
420
|
+
}
|
|
421
|
+
const appended = amendments.append(ownerAgentId, documentId, wire, nowMs);
|
|
422
|
+
// Post-apply surfacing runs for EVERYTHING that just applied: the direct arrival, and
|
|
423
|
+
// every held entry this arrival promoted (review F2 — the held path silently dropped the
|
|
424
|
+
// removal notice and the lifecycle completion, reintroducing the stuck-`active` defect
|
|
425
|
+
// CLOSE-N-1 fixed, on exactly the out-of-order path the pending table exists for).
|
|
426
|
+
const surfaceApplied = (applied) => {
|
|
427
|
+
// DOD-MP-REMOVE-1 — a removal NAMING THIS AGENT is applied and SURFACED, not just
|
|
428
|
+
// stored: the row flips to `removed` (publishes refuse locally, naming the condition;
|
|
429
|
+
// the copy, the file, the history all remain — forward-only by doctrine), and the event
|
|
430
|
+
// is the operator's notice. Everyone else's arrangement changes are visible through
|
|
431
|
+
// list/inbox derivation; being written out of one is the change an operator must not
|
|
432
|
+
// miss.
|
|
433
|
+
if (applied.body.kind === "remove_holder" &&
|
|
434
|
+
applied.body.subject_agent_id === ownerAgentId) {
|
|
435
|
+
logger.warn("document.removed_from", {
|
|
436
|
+
documentId,
|
|
437
|
+
removedBy: applied.collection.required_signers.join(","),
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
// THE ARRIVING CONSENT IS THE JOIN ANSWER (SYNC-P3, the D5 replacement): an inviter's
|
|
441
|
+
// pending row settles from the entry itself — the subject's own signed yes or no — so
|
|
442
|
+
// the legacy answer frame carries nothing the record does not. Settle-once semantics
|
|
443
|
+
// SYNC-P4 (R27/R28, review F2): the stored status is a DISPLAY PROJECTION of the derived
|
|
444
|
+
// ending — recomputed on EVERY applied entry, in BOTH directions. One-way, kind-gated
|
|
445
|
+
// syncing let two holders converge on the fold while holding different status columns
|
|
446
|
+
// forever: a concurrently-authored admission re-opens the derivation (an invited seat
|
|
447
|
+
// blocks closure), and nothing ever wrote `active` back. The derivation is the truth; the
|
|
448
|
+
// column exists so the list surface does not re-derive every row, and no correctness gate
|
|
449
|
+
// reads it for endings anymore (canPublish/canAdmit ask the fold).
|
|
450
|
+
{
|
|
451
|
+
const derivedEnd = reconcileReads(ownerAgentId).deriveState(documentId);
|
|
452
|
+
if (derivedEnd.ok) {
|
|
453
|
+
const current = store.getDocument(ownerAgentId, documentId)?.status;
|
|
454
|
+
if (derivedEnd.state.ended !== null && current === "active") {
|
|
455
|
+
store.setDocumentStatus(ownerAgentId, documentId, derivedEnd.state.ended === "killed" ? "killed" : "closed");
|
|
456
|
+
logger.info("document.ended.derived", { documentId, ended: derivedEnd.state.ended });
|
|
457
|
+
}
|
|
458
|
+
else if (derivedEnd.state.ended === null &&
|
|
459
|
+
(current === "closed" || current === "killed")) {
|
|
460
|
+
store.setDocumentStatus(ownerAgentId, documentId, "active");
|
|
461
|
+
logger.info("document.reopened.derived", { documentId });
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
};
|
|
466
|
+
// An entry held for missing parents (R14) is recorded but NOT applied — its notices wait
|
|
467
|
+
// with it and fire on promotion. The store's `document.entry.held` event is the trace.
|
|
468
|
+
if (!appended.held)
|
|
469
|
+
surfaceApplied(env);
|
|
470
|
+
for (const promoted of appended.promoted)
|
|
471
|
+
surfaceApplied(promoted.envelope);
|
|
472
|
+
};
|
|
473
|
+
const rewriteFileImpl = async (ownerAgentId, inResponseTo) => {
|
|
474
|
+
if (!writePath)
|
|
475
|
+
return;
|
|
476
|
+
const env = decodeDocumentUpdateEnvelope(inResponseTo);
|
|
477
|
+
const document = store.getDocument(ownerAgentId, env.document_id);
|
|
478
|
+
if (!document)
|
|
479
|
+
return;
|
|
480
|
+
await writePath.materialize(ownerAgentId, env.document_id, document.documentType, live.get(ownerAgentId, env.document_id));
|
|
481
|
+
};
|
|
482
|
+
const noticeInboundUpdateImpl = (ownerAgentId, inResponseTo) => {
|
|
483
|
+
const env = decodeDocumentUpdateEnvelope(inResponseTo);
|
|
484
|
+
// COUNTED FROM THE LOG, not incremented blindly: envelopes redeliver, and a counter bumped on
|
|
485
|
+
// every arrival would drift upward on ordinary retries and tell the operator there is more to
|
|
486
|
+
// read than there is.
|
|
487
|
+
const unread = notifications.unreadFromPeer(ownerAgentId, env.document_id);
|
|
488
|
+
notifications.notice(ownerAgentId, env.document_id, unread, Date.now());
|
|
489
|
+
// DOD-DOC-WATCH-1 — the selective nudge.
|
|
490
|
+
//
|
|
491
|
+
// Matched against what changed since THIS agent last READ, not against this envelope. Per
|
|
492
|
+
// envelope re-fires on redelivery and on the peer's every keystroke; the net difference from
|
|
493
|
+
// the read mark asks the question an operator actually has — has the thing I am waiting on
|
|
494
|
+
// moved since I saw it — and self-cancels the moment they read.
|
|
495
|
+
//
|
|
496
|
+
// Wrapped whole: a notification is a courtesy on a path whose real job (admitting the peer's
|
|
497
|
+
// update) has already succeeded, and must never be able to fail it.
|
|
498
|
+
try {
|
|
499
|
+
const watches = notifications.watches(ownerAgentId, env.document_id);
|
|
500
|
+
if (watches.length === 0)
|
|
501
|
+
return;
|
|
502
|
+
if (!notifications.nudgeOwed(ownerAgentId, env.document_id))
|
|
503
|
+
return;
|
|
504
|
+
const document = store.getDocument(ownerAgentId, env.document_id);
|
|
505
|
+
if (!document)
|
|
506
|
+
return;
|
|
507
|
+
const seen = notifications.lastSeen(ownerAgentId, env.document_id);
|
|
508
|
+
const after = projectDocumentText(live.get(ownerAgentId, env.document_id), document.documentType);
|
|
509
|
+
// NEVER READ is not "everything changed" for the purposes of a nudge — the agent has not
|
|
510
|
+
// established a baseline, so there is nothing it can be waiting on a change to.
|
|
511
|
+
if (seen === null || seen === after)
|
|
512
|
+
return;
|
|
513
|
+
// A text document has no key paths, so the only thing it can report is that it moved. That
|
|
514
|
+
// is why the whole-document watch has to be spelled `*` rather than implied.
|
|
515
|
+
const paths = rootForDocumentType(document.documentType) === "map"
|
|
516
|
+
? changedKeyPaths(seen, after) ?? ["*"]
|
|
517
|
+
: ["*"];
|
|
518
|
+
const hits = matchWatchedPaths(watches, paths);
|
|
519
|
+
if (hits.length === 0)
|
|
520
|
+
return;
|
|
521
|
+
// THE AGENT'S OWN PATTERNS travel, never the changed paths. A changed path can carry a key
|
|
522
|
+
// the PEER named, and a doorbell body is an unscreened route into the agent's context —
|
|
523
|
+
// see `matchingWatches`. The precise field comes from cello_doc_diff, which IS screened.
|
|
524
|
+
const firedWatches = matchingWatches(watches, paths);
|
|
525
|
+
notifications.markNudged(ownerAgentId, env.document_id, Date.now());
|
|
526
|
+
logger.info("document.watch.nudged", {
|
|
527
|
+
documentId: env.document_id,
|
|
528
|
+
paths: hits.length,
|
|
529
|
+
watches: firedWatches.length,
|
|
530
|
+
});
|
|
531
|
+
deps.nudge?.(ownerAgentId, env.document_id, firedWatches);
|
|
532
|
+
}
|
|
533
|
+
catch (err) {
|
|
534
|
+
logger.warn("document.watch.nudge_failed", {
|
|
535
|
+
documentId: env.document_id,
|
|
536
|
+
error: extractErrorMessage(err),
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
};
|
|
540
|
+
/** SYNC-P3 — the reads the reconcile engine consumes, over THIS owner's stores. */
|
|
541
|
+
const reconcileReads = (ownerAgentId) => ({
|
|
542
|
+
deriveState: (documentId) => {
|
|
543
|
+
const record = handshake.get(ownerAgentId, documentId);
|
|
544
|
+
if (!record)
|
|
545
|
+
return { ok: false, reason: "document_genesis_missing" };
|
|
546
|
+
try {
|
|
547
|
+
return deriveDocumentState(arrangementGenesisFromProposal(record.envelope), amendments.chain(ownerAgentId, documentId), documentGovernancePolicy, verifySignature);
|
|
548
|
+
}
|
|
549
|
+
catch (err) {
|
|
550
|
+
return {
|
|
551
|
+
ok: false,
|
|
552
|
+
reason: `document_chain_undecodable: ${extractErrorMessage(err)}`,
|
|
553
|
+
};
|
|
554
|
+
}
|
|
555
|
+
},
|
|
556
|
+
watermarks: (documentId) => amendments.watermarks(ownerAgentId, documentId),
|
|
557
|
+
entriesByAuthorAfter: (documentId, author, afterSeq) => amendments.entriesByAuthorAfter(ownerAgentId, documentId, author, afterSeq),
|
|
558
|
+
envelopeLog: (documentId) => store.getEnvelopeLog(ownerAgentId, documentId),
|
|
559
|
+
refusedHashes: (documentId) => rejections.quarantined(ownerAgentId, documentId).map((q) => q.rejectedEnvelopeHash),
|
|
560
|
+
// SYNC-R35: the exact signed frames, from the quarantine — rows born before the column hold
|
|
561
|
+
// none, and the exchange simply has nothing to attach for them.
|
|
562
|
+
refusalRecords: (documentId) => rejections
|
|
563
|
+
.quarantined(ownerAgentId, documentId)
|
|
564
|
+
.map((q) => q.rejectionWire)
|
|
565
|
+
.filter((w) => w !== undefined),
|
|
566
|
+
standingOf: (documentId, agentId) => standingOf(ownerAgentId, documentId, agentId),
|
|
567
|
+
genesisBytes: (documentId) => {
|
|
568
|
+
const record = handshake.get(ownerAgentId, documentId);
|
|
569
|
+
return record ? new Uint8Array(encodeDocumentProposal(record.envelope)) : null;
|
|
570
|
+
},
|
|
571
|
+
removalClosure: (documentId, agentId) => {
|
|
572
|
+
// The LAST removal naming them, plus every ancestor — walked over the held entry set.
|
|
573
|
+
const chain = amendments.chain(ownerAgentId, documentId);
|
|
574
|
+
const byHash = new Map(chain.map((env) => [
|
|
575
|
+
Buffer.from(documentAmendmentHash(env.body)).toString("hex"),
|
|
576
|
+
env,
|
|
577
|
+
]));
|
|
578
|
+
let removalHash = null;
|
|
579
|
+
for (const [hash, env] of byHash) {
|
|
580
|
+
if (env.body.kind === "remove_holder" && env.body.subject_agent_id === agentId) {
|
|
581
|
+
removalHash = hash;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
if (!removalHash)
|
|
585
|
+
return null;
|
|
586
|
+
const wanted = new Set([removalHash]);
|
|
587
|
+
const queue = [removalHash];
|
|
588
|
+
while (queue.length > 0) {
|
|
589
|
+
const env = byHash.get(queue.pop());
|
|
590
|
+
if (!env)
|
|
591
|
+
continue;
|
|
592
|
+
for (const parent of env.body.parents) {
|
|
593
|
+
if (!wanted.has(parent)) {
|
|
594
|
+
wanted.add(parent);
|
|
595
|
+
queue.push(parent);
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
// Foldable order: parents before children — the chain read is already epoch/seq ordered.
|
|
600
|
+
return chain
|
|
601
|
+
.filter((env) => wanted.has(Buffer.from(documentAmendmentHash(env.body)).toString("hex")))
|
|
602
|
+
.map((env) => new Uint8Array(encodeDocumentAmendment(env)));
|
|
603
|
+
},
|
|
604
|
+
});
|
|
605
|
+
/**
|
|
606
|
+
* SYNC-P3 — one arriving reconcile frame, all three steps. Apply what it carries (governance
|
|
607
|
+
* entries FIRST, R12 — through the same causal door every amendment takes; then content
|
|
608
|
+
* envelopes through the same inbound gate every update takes), then answer: a version this
|
|
609
|
+
* build does not speak or a stranger gets the named refusal ON the frame; a peer that lacks
|
|
610
|
+
* something gets the difference; a converged exchange gets silence — which is what terminates
|
|
611
|
+
* it (R15: idempotence is the absence of a difference, not bookkeeping).
|
|
612
|
+
*/
|
|
613
|
+
const handleReconcile = async (ownerAgentId, wire, senderAgentId, nowMs, correlationId) => {
|
|
614
|
+
const frame = decodeDocumentReconcile(wire);
|
|
615
|
+
if (frame.refusal) {
|
|
616
|
+
// The peer's answer to OUR exchange — a fact to surface, never to retry blindly.
|
|
617
|
+
logger.warn("document.reconcile.refused_by_peer", {
|
|
618
|
+
senderAgentId, reason: frame.refusal.reason, terminal: frame.refusal.terminal, correlationId,
|
|
619
|
+
});
|
|
620
|
+
// ACTED ON, not merely surfaced. The comment above has always said "never to retry blindly",
|
|
621
|
+
// and until now nothing downstream could tell a refusal from a success.
|
|
622
|
+
deps.onPeerRefusal?.(ownerAgentId, senderAgentId, frame.refusal.terminal);
|
|
623
|
+
return { ok: true };
|
|
624
|
+
}
|
|
625
|
+
for (const block of frame.documents) {
|
|
626
|
+
if (block.refusal) {
|
|
627
|
+
logger.warn("document.reconcile.refused_by_peer", {
|
|
628
|
+
documentId: block.document_id, senderAgentId,
|
|
629
|
+
reason: block.refusal.reason, terminal: block.refusal.terminal, correlationId,
|
|
630
|
+
});
|
|
631
|
+
deps.onPeerRefusal?.(ownerAgentId, senderAgentId, block.refusal.terminal);
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
if (frame.exchange_version !== DOCUMENT_RECONCILE_EXCHANGE_VERSION) {
|
|
635
|
+
const reason = `document_reconcile_version: you speak exchange version ${frame.exchange_version} and ` +
|
|
636
|
+
`this holder speaks ${DOCUMENT_RECONCILE_EXCHANGE_VERSION} — upgrade together; there is ` +
|
|
637
|
+
`no dual-speak mode`;
|
|
638
|
+
logger.warn("document.reconcile.version_refused", { senderAgentId, correlationId, reason });
|
|
639
|
+
await deps.sendFrame(ownerAgentId, senderAgentId, encodeDocumentReconcile({
|
|
640
|
+
type: "document_reconcile",
|
|
641
|
+
exchange_version: DOCUMENT_RECONCILE_EXCHANGE_VERSION,
|
|
642
|
+
documents: [],
|
|
643
|
+
refusal: { reason, terminal: false },
|
|
644
|
+
}));
|
|
645
|
+
return { ok: false, reason: "document_reconcile_version" };
|
|
646
|
+
}
|
|
647
|
+
const reads = reconcileReads(ownerAgentId);
|
|
648
|
+
const replyBlocks = [];
|
|
649
|
+
// One reply frame's payload allowance, shared across its blocks (review F3): headroom under
|
|
650
|
+
// the router's 2 MiB frame ceiling so positions, hashes, and CBOR overhead always fit.
|
|
651
|
+
const replyBudget = { remainingBytes: 1_500_000 };
|
|
652
|
+
for (const block of frame.documents) {
|
|
653
|
+
// THE NOTICE, RECEIVED (R25): a position for a document this holder does not hold, with
|
|
654
|
+
// no genesis attached, IS the invitation pointer — the frame already names the document
|
|
655
|
+
// and the session names the inviter. The answer is our EMPTY position ("I hold nothing;
|
|
656
|
+
// send everything"), and the peer's reply carries the genesis and the lot. Two empty
|
|
657
|
+
// hands stay silent, so nothing ping-pongs.
|
|
658
|
+
if (!block.genesis && !store.getDocument(ownerAgentId, block.document_id)) {
|
|
659
|
+
const peerClaimsAnything = block.governance.length > 0 || block.content.length > 0 ||
|
|
660
|
+
block.entries.length > 0 || block.envelopes.length > 0;
|
|
661
|
+
if (peerClaimsAnything) {
|
|
662
|
+
replyBlocks.push({
|
|
663
|
+
document_id: block.document_id,
|
|
664
|
+
governance: [], content: [], refused: [], entries: [], envelopes: [],
|
|
665
|
+
});
|
|
666
|
+
logger.info("document.reconcile.notice_received", {
|
|
667
|
+
documentId: block.document_id, viaAgentId: senderAgentId, correlationId,
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
continue;
|
|
671
|
+
}
|
|
672
|
+
// THE JOINER BOOTSTRAP (spec §4 — a joiner is simply very far behind): a block carrying
|
|
673
|
+
// the genesis for a document this holder does not have is the invitation arriving. The
|
|
674
|
+
// anchor is validated the way every genesis is — its hash IS the document id, its
|
|
675
|
+
// signature is the proposer's — and recording it is idempotent. The invitee then derives
|
|
676
|
+
// their own standing (invited) from the entries that follow; their ACCEPT is the ordinary
|
|
677
|
+
// consent-authoring accept.
|
|
678
|
+
if (block.genesis && !store.getDocument(ownerAgentId, block.document_id)) {
|
|
679
|
+
try {
|
|
680
|
+
const genesisEnv = decodeDocumentProposal(block.genesis);
|
|
681
|
+
if (documentIdFromProposal(genesisEnv) !== block.document_id) {
|
|
682
|
+
throw new Error("document_reconcile_genesis_mismatch: the carried genesis does not hash to the " +
|
|
683
|
+
"block's document id — the anchor cannot be swapped");
|
|
684
|
+
}
|
|
685
|
+
// THE ANCHOR IS VERIFIED, NOT TAKEN (P3 review F2): a proposal is only a proposal
|
|
686
|
+
// under its proposer's own signature — an unsigned or forged genesis stored here
|
|
687
|
+
// would attribute a document to someone who never made it, and hand any session
|
|
688
|
+
// peer an unlimited license to grow this store with fabricated documents.
|
|
689
|
+
if (!verifySignature(genesisEnv.proposer_agent_id, buildDocumentProposalTbs(genesisEnv), genesisEnv.signature)) {
|
|
690
|
+
throw new Error(`document_reconcile_genesis_unsigned: the carried genesis does not verify ` +
|
|
691
|
+
`against its named proposer ${genesisEnv.proposer_agent_id}`);
|
|
692
|
+
}
|
|
693
|
+
// AND IT MUST NAME US (F2's entitlement half): this holder bootstraps only a
|
|
694
|
+
// document it is a party to — the genesis peer, or the subject of an admission
|
|
695
|
+
// carried in the same block. Anything else is a stranger's document and is refused,
|
|
696
|
+
// not stored.
|
|
697
|
+
const namedAsGenesisPeer = genesisEnv.peer_agent_id === ownerAgentId;
|
|
698
|
+
const namedByAdmission = block.entries.some((entryWire) => {
|
|
699
|
+
try {
|
|
700
|
+
const env = decodeDocumentAmendment(entryWire);
|
|
701
|
+
return env.body.kind === "add_holder" && env.body.subject_agent_id === ownerAgentId;
|
|
702
|
+
}
|
|
703
|
+
catch {
|
|
704
|
+
return false;
|
|
705
|
+
}
|
|
706
|
+
});
|
|
707
|
+
if (!namedAsGenesisPeer && !namedByAdmission) {
|
|
708
|
+
throw new Error("document_reconcile_not_invited: the carried world names this holder nowhere — " +
|
|
709
|
+
"neither the genesis peer nor the subject of any carried admission; a document " +
|
|
710
|
+
"we are no party to is refused, not stored");
|
|
711
|
+
}
|
|
712
|
+
handshake.recordJoined(ownerAgentId, block.genesis, nowMs);
|
|
713
|
+
store.createDocument({
|
|
714
|
+
documentId: block.document_id,
|
|
715
|
+
ownerAgentId,
|
|
716
|
+
// The GENESIS FACT, not the messenger (F6): the peer column is the proposer's —
|
|
717
|
+
// whoever's session happened to carry the frame may be any holder (forwarding).
|
|
718
|
+
peerAgentId: genesisEnv.proposer_agent_id,
|
|
719
|
+
documentType: genesisEnv.document_type,
|
|
720
|
+
properties: genesisEnv.properties,
|
|
721
|
+
status: "active",
|
|
722
|
+
createdAtMs: nowMs,
|
|
723
|
+
});
|
|
724
|
+
logger.info("document.reconcile.joined", {
|
|
725
|
+
documentId: block.document_id, viaAgentId: senderAgentId, correlationId,
|
|
726
|
+
});
|
|
727
|
+
}
|
|
728
|
+
catch (err) {
|
|
729
|
+
logger.warn("document.reconcile.genesis_refused", {
|
|
730
|
+
documentId: block.document_id, senderAgentId, correlationId,
|
|
731
|
+
reason: extractErrorMessage(err),
|
|
732
|
+
});
|
|
733
|
+
continue;
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
// APPLY FIRST (R12 order: governance, then content). Both doors are the ordinary ones —
|
|
737
|
+
// idempotent, held-until-whole, refusal-recording — so a redelivered exchange changes
|
|
738
|
+
// nothing.
|
|
739
|
+
for (const entryWire of block.entries) {
|
|
740
|
+
try {
|
|
741
|
+
recordAmendmentImpl(ownerAgentId, entryWire, nowMs);
|
|
742
|
+
}
|
|
743
|
+
catch (err) {
|
|
744
|
+
logger.warn("document.reconcile.entry_refused", {
|
|
745
|
+
documentId: block.document_id, senderAgentId, correlationId,
|
|
746
|
+
reason: extractErrorMessage(err),
|
|
747
|
+
});
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
// SYNC-R35: the sender's SIGNED refusal records — verified against their named refuser
|
|
751
|
+
// and recorded as received rejections, exactly as a directly-sent frame would be. This is
|
|
752
|
+
// how a third holder wedged behind a refused hash learns its name and reason (F5/F8), and
|
|
753
|
+
// how the refusal keeps traveling once the refuser is gone. Idempotent by primary key.
|
|
754
|
+
for (const refusalWire of block.refusals ?? []) {
|
|
755
|
+
try {
|
|
756
|
+
const rej = decodeDocumentRejection(new Uint8Array(refusalWire));
|
|
757
|
+
if (rej.document_id !== block.document_id) {
|
|
758
|
+
throw new Error("document_refusal_document_mismatch: the record names another document");
|
|
759
|
+
}
|
|
760
|
+
if (!verifySignature(rej.rejecting_agent_id, buildDocumentRejectionTbs(rej), rej.signature)) {
|
|
761
|
+
throw new Error(`document_rejection_signature_invalid: the refusal claims to come from ` +
|
|
762
|
+
`${rej.rejecting_agent_id} but its signature does not verify against that agent`);
|
|
763
|
+
}
|
|
764
|
+
rejections.recordIncomingRejection(ownerAgentId, rej.document_id, {
|
|
765
|
+
rejectionEnvelopeHash: documentRejectionHash(rej),
|
|
766
|
+
rejectedEnvelopeHash: rej.rejected_envelope_hash,
|
|
767
|
+
reason: rej.reason,
|
|
768
|
+
detail: rej.detail,
|
|
769
|
+
fromAgentId: rej.rejecting_agent_id,
|
|
770
|
+
});
|
|
771
|
+
}
|
|
772
|
+
catch (err) {
|
|
773
|
+
logger.warn("document.reconcile.refusal_record_refused", {
|
|
774
|
+
documentId: block.document_id, senderAgentId, correlationId,
|
|
775
|
+
reason: extractErrorMessage(err),
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
for (const envWire of block.envelopes) {
|
|
780
|
+
const res = await inbound.receive(ownerAgentId, envWire, nowMs, correlationId);
|
|
781
|
+
if (res.ok && res.admitted) {
|
|
782
|
+
try {
|
|
783
|
+
noticeInboundUpdateImpl(ownerAgentId, envWire);
|
|
784
|
+
}
|
|
785
|
+
catch { /* the notice is a row; the content is already the truth */ }
|
|
786
|
+
void rewriteFileImpl(ownerAgentId, envWire).catch((err) => {
|
|
787
|
+
logger.warn("document.reconcile.rewrite_failed", {
|
|
788
|
+
correlationId,
|
|
789
|
+
reason: extractErrorMessage(err),
|
|
790
|
+
});
|
|
791
|
+
});
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
const answer = respondToReconcile(reads, senderAgentId, block, replyBudget);
|
|
795
|
+
// SYNC-P5 (spec §9): the block's position IS what this party last claimed — recorded as
|
|
796
|
+
// the display cache the list surface reads (in_sync|behind|unseen). AFTER the entitlement
|
|
797
|
+
// ruling (P5 review F9): a stranger's claimed position is not worth a row. Never consulted
|
|
798
|
+
// for correctness (R44).
|
|
799
|
+
if (!answer.block.refusal && store.getDocument(ownerAgentId, block.document_id)) {
|
|
800
|
+
store.recordPartyView(ownerAgentId, block.document_id, senderAgentId, {
|
|
801
|
+
govSeqs: Object.fromEntries(block.governance.map((g) => [g.author, g.seq])),
|
|
802
|
+
contentCounts: Object.fromEntries(block.content.map((c) => [c.author, c.count])),
|
|
803
|
+
refused: [...block.refused],
|
|
804
|
+
}, nowMs);
|
|
805
|
+
}
|
|
806
|
+
if (answer.block.refusal) {
|
|
807
|
+
// Per-document, on the block (review F4) — a batch never silences one document's no.
|
|
808
|
+
logger.warn("document.reconcile.refused", {
|
|
809
|
+
documentId: block.document_id, senderAgentId,
|
|
810
|
+
reason: answer.block.refusal.reason, terminal: answer.block.refusal.terminal,
|
|
811
|
+
correlationId,
|
|
812
|
+
});
|
|
813
|
+
replyBlocks.push(answer.block);
|
|
814
|
+
continue;
|
|
815
|
+
}
|
|
816
|
+
if (answer.truncated) {
|
|
817
|
+
// The byte budget cut the payload (review F3) — LOUD, never a silently-oversized frame
|
|
818
|
+
// the router would drop as unshaped. The exchange is idempotent: the peer's next
|
|
819
|
+
// initiate picks up from its advanced position.
|
|
820
|
+
logger.warn("document.reconcile.truncated", {
|
|
821
|
+
documentId: block.document_id, senderAgentId, correlationId,
|
|
822
|
+
});
|
|
823
|
+
}
|
|
824
|
+
// Refusal records RIDE replies; they never CAUSE one — counting them here would make any
|
|
825
|
+
// document with one standing refusal answer every exchange forever, and the exchange is
|
|
826
|
+
// terminated by silence. The wedge they exist to cure (F5) always involves a real
|
|
827
|
+
// difference, so they are on board whenever they matter.
|
|
828
|
+
const hasDifference = answer.block.entries.length > 0 || answer.block.envelopes.length > 0;
|
|
829
|
+
if (hasDifference || answer.peerAhead) {
|
|
830
|
+
replyBlocks.push(answer.block);
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
if (replyBlocks.length > 0) {
|
|
834
|
+
await deps.sendFrame(ownerAgentId, senderAgentId, encodeDocumentReconcile({
|
|
835
|
+
type: "document_reconcile",
|
|
836
|
+
exchange_version: DOCUMENT_RECONCILE_EXCHANGE_VERSION,
|
|
837
|
+
documents: replyBlocks,
|
|
838
|
+
}));
|
|
839
|
+
}
|
|
840
|
+
return { ok: true };
|
|
841
|
+
};
|
|
842
|
+
/** SYNC-P3 — step 1: send our position for these documents to a peer. */
|
|
843
|
+
// DOD-M12B-SHUTDOWN-1: THE CHOKE POINT for outbound reconciles. The scheduler is only one of the
|
|
844
|
+
// four callers — `nudgeSeats` and the two invite notices reach here directly, outside it — so
|
|
845
|
+
// gating the scheduler alone left three paths still dialling on the way out. `cello_doc_write`,
|
|
846
|
+
// `cello_doc_publish` and `cello_doc_invite` are all still SERVED during shutdown, because the
|
|
847
|
+
// IPC server is the last thing stopped, so this is not a theoretical window.
|
|
848
|
+
let reconcileStopped = false;
|
|
849
|
+
const initiateReconcile = async (ownerAgentId, peerAgentId, documentIds) => {
|
|
850
|
+
if (reconcileStopped)
|
|
851
|
+
return { ok: false, reason: "daemon_shutting_down" };
|
|
852
|
+
const reads = reconcileReads(ownerAgentId);
|
|
853
|
+
const blocks = documentIds.map((id) => buildReconcileBlock(reads, id));
|
|
854
|
+
const sent = await deps.sendFrame(ownerAgentId, peerAgentId, encodeDocumentReconcile({
|
|
855
|
+
type: "document_reconcile",
|
|
856
|
+
exchange_version: DOCUMENT_RECONCILE_EXCHANGE_VERSION,
|
|
857
|
+
documents: blocks,
|
|
858
|
+
}));
|
|
859
|
+
if (!sent.ok)
|
|
860
|
+
return { ok: false, reason: sent.reason ?? "document_reconcile_send_failed" };
|
|
861
|
+
logger.info("document.reconcile.initiated", { peerAgentId, documents: documentIds.length });
|
|
862
|
+
return { ok: true };
|
|
863
|
+
};
|
|
864
|
+
const router = new DocumentFrameRouter({
|
|
865
|
+
inbound,
|
|
866
|
+
handleReconcile,
|
|
867
|
+
logger,
|
|
868
|
+
ownerKeyFor: deps.ownerKeyFor,
|
|
869
|
+
recordProposal: (ownerAgentId, wire, nowMs) => {
|
|
870
|
+
// THROWS on a forged or misaddressed proposal, which the router contains and reports. That is
|
|
871
|
+
// right: those are refusals, and nothing should be recorded for them.
|
|
872
|
+
const recorded = handshake.recordProposal(ownerAgentId, wire, nowMs);
|
|
873
|
+
// BOTH ENDS GET THE SENTENCE (TOPOLOGY-1 review F1, the join path's rule applied here):
|
|
874
|
+
// an arrival auto-refusal — seam violation, version mismatch — used to write its sentence
|
|
875
|
+
// to OUR database and answer the proposer with silence, a hang they diagnose as a network
|
|
876
|
+
// fault. The signed refusal ack now travels best-effort; the proposal verified against its
|
|
877
|
+
// named proposer at record time, so the answer goes to an authenticated party.
|
|
878
|
+
const refusalReason = recorded.reason;
|
|
879
|
+
if (recorded.state === "refused" && refusalReason !== undefined) {
|
|
880
|
+
const proposal = decodeDocumentProposal(wire);
|
|
881
|
+
void (async () => {
|
|
882
|
+
try {
|
|
883
|
+
const ack = {
|
|
884
|
+
type: "document_proposal_ack",
|
|
885
|
+
ack_version: DOCUMENT_PROPOSAL_ACK_VERSION,
|
|
886
|
+
document_id: recorded.documentId,
|
|
887
|
+
acker_agent_id: ownerAgentId,
|
|
888
|
+
accepted: false,
|
|
889
|
+
refusal_reason: refusalReason.slice(0, MAX_PROPOSAL_REFUSAL_REASON_LENGTH),
|
|
890
|
+
decided_at_ms: Date.now(),
|
|
891
|
+
signature: new Uint8Array(0),
|
|
892
|
+
};
|
|
893
|
+
ack.signature = await deps.sign(ownerAgentId, buildDocumentProposalAckTbs(ack));
|
|
894
|
+
await deps.sendFrame(ownerAgentId, proposal.proposer_agent_id, encodeDocumentProposalAck(ack));
|
|
895
|
+
}
|
|
896
|
+
catch (err) {
|
|
897
|
+
logger.warn("document.proposal.auto_refusal_ack_failed", {
|
|
898
|
+
documentId: recorded.documentId,
|
|
899
|
+
error: extractErrorMessage(err),
|
|
900
|
+
});
|
|
901
|
+
}
|
|
902
|
+
})();
|
|
903
|
+
}
|
|
904
|
+
},
|
|
905
|
+
recordAmendment: recordAmendmentImpl,
|
|
906
|
+
// `_nowMs` unused: the received-rejection row takes its clock where it is written, and the
|
|
907
|
+
// rejection's own SIGNED timestamp is inside the envelope. A second clock read here would put a
|
|
908
|
+
// third time on one event.
|
|
909
|
+
rewriteFile: rewriteFileImpl,
|
|
910
|
+
noticeInboundUpdate: noticeInboundUpdateImpl,
|
|
911
|
+
sendFrameToPeer: async (ownerAgentId, inResponseTo, bytes) => {
|
|
912
|
+
// Addressed to whoever AUTHORED the envelope being answered, taken from the envelope itself
|
|
913
|
+
// rather than from the document row: the row's peer and the envelope's sender are the same
|
|
914
|
+
// party in a two-party document, and reading it from the signed bytes means a refusal can
|
|
915
|
+
// only ever go back to the agent that actually sent the thing refused.
|
|
916
|
+
const env = decodeDocumentUpdateEnvelope(inResponseTo);
|
|
917
|
+
const sent = await deps.sendFrame(ownerAgentId, env.sender_agent_id, bytes, LEAF_KIND_REJECT);
|
|
918
|
+
if (!sent.ok) {
|
|
919
|
+
logger.warn("document.rejection.unsent", {
|
|
920
|
+
documentId: env.document_id,
|
|
921
|
+
peerAgentId: env.sender_agent_id,
|
|
922
|
+
reason: sent.reason,
|
|
923
|
+
});
|
|
924
|
+
}
|
|
925
|
+
},
|
|
926
|
+
recordProposalAck: (ownerAgentId, wire, _nowMs) => {
|
|
927
|
+
const ack = decodeDocumentProposalAck(wire);
|
|
928
|
+
// VERIFIED against the agent it names, before anything is written. A refusal ack makes the
|
|
929
|
+
// proposer stop waiting and, at the surface, reads as "they said no" — so unsigned, anyone on
|
|
930
|
+
// the channel could make a proposal appear refused by a party who never saw it, and the two
|
|
931
|
+
// operators would each believe the other walked away.
|
|
932
|
+
if (!verifySignature(ack.acker_agent_id, buildDocumentProposalAckTbs(ack), ack.signature)) {
|
|
933
|
+
throw new Error(`document_proposal_ack_signature_invalid: the answer claims to come from ` +
|
|
934
|
+
`${ack.acker_agent_id} but its signature does not verify against that agent`);
|
|
935
|
+
}
|
|
936
|
+
// The acker is passed through and CHECKED against the proposal's peer. Verifying the
|
|
937
|
+
// signature proves the frame is authentic; it says nothing about whether its author was
|
|
938
|
+
// entitled to answer this proposal.
|
|
939
|
+
const stored = handshake.recordPeerDecision(ownerAgentId, ack.document_id, ack.acker_agent_id, {
|
|
940
|
+
accepted: ack.accepted,
|
|
941
|
+
...(ack.refusal_reason !== undefined ? { reason: ack.refusal_reason } : {}),
|
|
942
|
+
decidedAtMs: ack.decided_at_ms,
|
|
943
|
+
});
|
|
944
|
+
if (!stored.ok) {
|
|
945
|
+
// SETTLE ONCE — a contradicting second answer is an error, never an update. A peer that
|
|
946
|
+
// accepted must not be able to later claim it refused, or the proposer tears down a
|
|
947
|
+
// document the peer is still editing.
|
|
948
|
+
throw new Error(`${stored.reason}: ${stored.detail}`);
|
|
949
|
+
}
|
|
950
|
+
},
|
|
951
|
+
recordRejection: (ownerAgentId, wire, _nowMs) => {
|
|
952
|
+
const env = decodeDocumentRejection(wire);
|
|
953
|
+
if (!verifySignature(env.rejecting_agent_id, buildDocumentRejectionTbs(env), env.signature)) {
|
|
954
|
+
// A rejection stops the sender retrying and makes them supersede. Unsigned, anyone on the
|
|
955
|
+
// channel could freeze a document by asserting a refusal nobody made.
|
|
956
|
+
throw new Error(`document_rejection_signature_invalid: the rejection claims to come from ` +
|
|
957
|
+
`${env.rejecting_agent_id} but its signature does not verify against that agent`);
|
|
958
|
+
}
|
|
959
|
+
rejections.recordIncomingRejection(ownerAgentId, env.document_id, {
|
|
960
|
+
rejectionEnvelopeHash: documentRejectionHash(env),
|
|
961
|
+
rejectedEnvelopeHash: env.rejected_envelope_hash,
|
|
962
|
+
reason: env.reason,
|
|
963
|
+
detail: env.detail,
|
|
964
|
+
fromAgentId: env.rejecting_agent_id,
|
|
965
|
+
});
|
|
966
|
+
},
|
|
967
|
+
});
|
|
968
|
+
return {
|
|
969
|
+
/** DOD-M12B-SHUTDOWN-1 — see the interface. One-way, idempotent, and the single place that
|
|
970
|
+
* closes the whole class rather than one of the four callers. */
|
|
971
|
+
stopReconciling() { reconcileStopped = true; },
|
|
972
|
+
amendments,
|
|
973
|
+
verifySignature,
|
|
974
|
+
holdersFor,
|
|
975
|
+
isCurrentHolder,
|
|
976
|
+
standingOf,
|
|
977
|
+
partySync,
|
|
978
|
+
pendingFor,
|
|
979
|
+
sweepTargets,
|
|
980
|
+
initiateReconcile,
|
|
981
|
+
governanceFrontierFor: (ownerAgentId, documentId) => {
|
|
982
|
+
const derived = reconcileReads(ownerAgentId).deriveState(documentId);
|
|
983
|
+
if (!derived.ok) {
|
|
984
|
+
// NAMED, not collapsed to null (review F4): the derivation's own reason — a missing
|
|
985
|
+
// genesis, undecodable bytes, a fold refusal — is the thing the operator hunts for,
|
|
986
|
+
// and the old holders gate logged it while this gate ran first and said nothing.
|
|
987
|
+
logger.error("document.frontier.underivable", { documentId, reason: derived.reason });
|
|
988
|
+
return null;
|
|
989
|
+
}
|
|
990
|
+
return [...derived.state.frontier];
|
|
991
|
+
},
|
|
992
|
+
deriveEnded: (ownerAgentId, documentId) => {
|
|
993
|
+
const derived = reconcileReads(ownerAgentId).deriveState(documentId);
|
|
994
|
+
if (!derived.ok)
|
|
995
|
+
return null;
|
|
996
|
+
return {
|
|
997
|
+
ended: derived.state.ended,
|
|
998
|
+
// Who the ending still waits on: every participant without a close entry, AND every open
|
|
999
|
+
// invitation — an invited seat IS a seat (Entry 54), so a close cannot settle around it.
|
|
1000
|
+
waitingOn: [
|
|
1001
|
+
...[...derived.state.participants].filter((participant) => !derived.state.closedBy.has(participant)),
|
|
1002
|
+
...derived.state.invited,
|
|
1003
|
+
],
|
|
1004
|
+
};
|
|
1005
|
+
},
|
|
1006
|
+
store,
|
|
1007
|
+
writePath,
|
|
1008
|
+
handshake,
|
|
1009
|
+
engine,
|
|
1010
|
+
live,
|
|
1011
|
+
lifecycle,
|
|
1012
|
+
notifications,
|
|
1013
|
+
rejections,
|
|
1014
|
+
router,
|
|
1015
|
+
onDocumentFrame: (agentName, _sessionId, content, senderPubkey, correlationId) =>
|
|
1016
|
+
// `agentName` names the owning agent for the session; the router maps it to the owner KEY
|
|
1017
|
+
// that scopes the store. The session id and the sender's transport pubkey are unused: a
|
|
1018
|
+
// document is bound to its PEER by the handshake, not to whichever session carried the
|
|
1019
|
+
// frame, and the envelope's own signed `sender_agent_id` is what the inbound path checks
|
|
1020
|
+
// against that binding. Trusting the transport identity instead would let a frame arriving
|
|
1021
|
+
// on any session act on any document that session's peer happens to share.
|
|
1022
|
+
router.routeSync(agentName, content, Date.now(), correlationId ?? "frame", senderPubkey),
|
|
1023
|
+
};
|
|
1024
|
+
}
|
|
1025
|
+
//# sourceMappingURL=document-layer.js.map
|