@cello-protocol/daemon 0.0.225 → 0.0.227
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +5 -5
- package/dist/agent-admin-handlers.d.ts +0 -56
- package/dist/agent-admin-handlers.d.ts.map +0 -1
- package/dist/agent-admin-handlers.js +0 -73
- package/dist/agent-admin-handlers.js.map +0 -1
- package/dist/agent-handlers.d.ts +0 -72
- package/dist/agent-handlers.d.ts.map +0 -1
- package/dist/agent-handlers.js +0 -604
- package/dist/agent-handlers.js.map +0 -1
- package/dist/agent-id-migration.d.ts +0 -70
- package/dist/agent-id-migration.d.ts.map +0 -1
- package/dist/agent-id-migration.js +0 -468
- package/dist/agent-id-migration.js.map +0 -1
- package/dist/agent-loader.d.ts +0 -37
- package/dist/agent-loader.d.ts.map +0 -1
- package/dist/agent-loader.js +0 -37
- package/dist/agent-loader.js.map +0 -1
- package/dist/agent-selection-root.d.ts +0 -29
- package/dist/agent-selection-root.d.ts.map +0 -1
- package/dist/agent-selection-root.js +0 -126
- package/dist/agent-selection-root.js.map +0 -1
- package/dist/agent-selection.d.ts +0 -73
- package/dist/agent-selection.d.ts.map +0 -1
- package/dist/agent-selection.js +0 -80
- package/dist/agent-selection.js.map +0 -1
- package/dist/agent-settings-keys.d.ts +0 -52
- package/dist/agent-settings-keys.d.ts.map +0 -1
- package/dist/agent-settings-keys.js +0 -114
- package/dist/agent-settings-keys.js.map +0 -1
- package/dist/agent-state.d.ts +0 -67
- package/dist/agent-state.d.ts.map +0 -1
- package/dist/agent-state.js +0 -66
- package/dist/agent-state.js.map +0 -1
- package/dist/assignment-verify.d.ts +0 -90
- package/dist/assignment-verify.d.ts.map +0 -1
- package/dist/assignment-verify.js +0 -301
- package/dist/assignment-verify.js.map +0 -1
- package/dist/attendance-wiring.d.ts +0 -23
- package/dist/attendance-wiring.d.ts.map +0 -1
- package/dist/attendance-wiring.js +0 -248
- package/dist/attendance-wiring.js.map +0 -1
- package/dist/attestation-body.d.ts +0 -47
- package/dist/attestation-body.d.ts.map +0 -1
- package/dist/attestation-body.js +0 -71
- package/dist/attestation-body.js.map +0 -1
- package/dist/authorship-verification.d.ts +0 -91
- package/dist/authorship-verification.d.ts.map +0 -1
- package/dist/authorship-verification.js +0 -532
- package/dist/authorship-verification.js.map +0 -1
- package/dist/away-detection.d.ts +0 -139
- package/dist/away-detection.d.ts.map +0 -1
- package/dist/away-detection.js +0 -186
- package/dist/away-detection.js.map +0 -1
- package/dist/away-inbox-oneshot.d.ts +0 -40
- package/dist/away-inbox-oneshot.d.ts.map +0 -1
- package/dist/away-inbox-oneshot.js +0 -311
- package/dist/away-inbox-oneshot.js.map +0 -1
- package/dist/backup-restore-handlers.d.ts +0 -10
- package/dist/backup-restore-handlers.d.ts.map +0 -1
- package/dist/backup-restore-handlers.js +0 -82
- package/dist/backup-restore-handlers.js.map +0 -1
- package/dist/backup-restore.d.ts +0 -102
- package/dist/backup-restore.d.ts.map +0 -1
- package/dist/backup-restore.js +0 -341
- package/dist/backup-restore.js.map +0 -1
- package/dist/bin/cello-daemon.d.ts +0 -13
- package/dist/bin/cello-daemon.d.ts.map +0 -1
- package/dist/bin/cello-daemon.js.map +0 -1
- package/dist/boot-agents.d.ts +0 -64
- package/dist/boot-agents.d.ts.map +0 -1
- package/dist/boot-agents.js +0 -241
- package/dist/boot-agents.js.map +0 -1
- package/dist/boot-connection-state.d.ts +0 -38
- package/dist/boot-connection-state.d.ts.map +0 -1
- package/dist/boot-connection-state.js +0 -95
- package/dist/boot-connection-state.js.map +0 -1
- package/dist/boot-core.d.ts +0 -36
- package/dist/boot-core.d.ts.map +0 -1
- package/dist/boot-core.js +0 -293
- package/dist/boot-core.js.map +0 -1
- package/dist/boot-parked-content.d.ts +0 -34
- package/dist/boot-parked-content.d.ts.map +0 -1
- package/dist/boot-parked-content.js +0 -528
- package/dist/boot-parked-content.js.map +0 -1
- package/dist/boot-sweeps.d.ts +0 -22
- package/dist/boot-sweeps.d.ts.map +0 -1
- package/dist/boot-sweeps.js +0 -51
- package/dist/boot-sweeps.js.map +0 -1
- package/dist/bundled-consortium-manifest.d.ts +0 -47
- package/dist/bundled-consortium-manifest.d.ts.map +0 -1
- package/dist/bundled-consortium-manifest.js +0 -116
- package/dist/bundled-consortium-manifest.js.map +0 -1
- package/dist/cbor-blob-migration.d.ts +0 -8
- package/dist/cbor-blob-migration.d.ts.map +0 -1
- package/dist/cbor-blob-migration.js +0 -116
- package/dist/cbor-blob-migration.js.map +0 -1
- package/dist/challenge-verifier.d.ts +0 -12
- package/dist/challenge-verifier.d.ts.map +0 -1
- package/dist/challenge-verifier.js +0 -11
- package/dist/challenge-verifier.js.map +0 -1
- package/dist/close-commitment.d.ts +0 -67
- package/dist/close-commitment.d.ts.map +0 -1
- package/dist/close-commitment.js +0 -78
- package/dist/close-commitment.js.map +0 -1
- package/dist/close-session-handler.d.ts +0 -94
- package/dist/close-session-handler.d.ts.map +0 -1
- package/dist/close-session-handler.js +0 -1418
- package/dist/close-session-handler.js.map +0 -1
- package/dist/co-attendance.d.ts +0 -29
- package/dist/co-attendance.d.ts.map +0 -1
- package/dist/co-attendance.js +0 -32
- package/dist/co-attendance.js.map +0 -1
- package/dist/column-birth.d.ts +0 -40
- package/dist/column-birth.d.ts.map +0 -1
- package/dist/column-birth.js +0 -61
- package/dist/column-birth.js.map +0 -1
- package/dist/connect-or-start.d.ts +0 -25
- package/dist/connect-or-start.d.ts.map +0 -1
- package/dist/connect-or-start.js +0 -175
- package/dist/connect-or-start.js.map +0 -1
- package/dist/connection-agents.d.ts +0 -16
- package/dist/connection-agents.d.ts.map +0 -1
- package/dist/connection-agents.js +0 -68
- package/dist/connection-agents.js.map +0 -1
- package/dist/consent-migration.d.ts +0 -49
- package/dist/consent-migration.d.ts.map +0 -1
- package/dist/consent-migration.js +0 -128
- package/dist/consent-migration.js.map +0 -1
- package/dist/consortium-bootstrap.d.ts +0 -138
- package/dist/consortium-bootstrap.d.ts.map +0 -1
- package/dist/consortium-bootstrap.js +0 -339
- package/dist/consortium-bootstrap.js.map +0 -1
- package/dist/consortium-fingerprint.d.ts +0 -115
- package/dist/consortium-fingerprint.d.ts.map +0 -1
- package/dist/consortium-fingerprint.js +0 -175
- package/dist/consortium-fingerprint.js.map +0 -1
- package/dist/contact-handlers.d.ts +0 -59
- package/dist/contact-handlers.d.ts.map +0 -1
- package/dist/contact-handlers.js +0 -343
- package/dist/contact-handlers.js.map +0 -1
- package/dist/contact-pubkey-case.d.ts +0 -65
- package/dist/contact-pubkey-case.d.ts.map +0 -1
- package/dist/contact-pubkey-case.js +0 -136
- package/dist/contact-pubkey-case.js.map +0 -1
- package/dist/contacts-tier-migration.d.ts +0 -90
- package/dist/contacts-tier-migration.d.ts.map +0 -1
- package/dist/contacts-tier-migration.js +0 -150
- package/dist/contacts-tier-migration.js.map +0 -1
- package/dist/content-encryption-status.d.ts +0 -111
- package/dist/content-encryption-status.d.ts.map +0 -1
- package/dist/content-encryption-status.js +0 -158
- package/dist/content-encryption-status.js.map +0 -1
- package/dist/content-park-client.d.ts +0 -90
- package/dist/content-park-client.d.ts.map +0 -1
- package/dist/content-park-client.js +0 -362
- package/dist/content-park-client.js.map +0 -1
- package/dist/content-park.d.ts +0 -52
- package/dist/content-park.d.ts.map +0 -1
- package/dist/content-park.js +0 -1309
- package/dist/content-park.js.map +0 -1
- package/dist/cross-node-negotiation.d.ts +0 -44
- package/dist/cross-node-negotiation.d.ts.map +0 -1
- package/dist/cross-node-negotiation.js +0 -34
- package/dist/cross-node-negotiation.js.map +0 -1
- package/dist/daemon-handle.d.ts +0 -57
- package/dist/daemon-handle.d.ts.map +0 -1
- package/dist/daemon-handle.js +0 -2
- package/dist/daemon-handle.js.map +0 -1
- package/dist/daemon-status-report.d.ts +0 -50
- package/dist/daemon-status-report.d.ts.map +0 -1
- package/dist/daemon-status-report.js +0 -81
- package/dist/daemon-status-report.js.map +0 -1
- package/dist/daemon.d.ts +0 -45
- package/dist/daemon.d.ts.map +0 -1
- package/dist/daemon.js +0 -1177
- package/dist/daemon.js.map +0 -1
- package/dist/db-identity-store.d.ts +0 -159
- package/dist/db-identity-store.d.ts.map +0 -1
- package/dist/db-identity-store.js +0 -502
- package/dist/db-identity-store.js.map +0 -1
- package/dist/delivery-open-registry.d.ts +0 -92
- package/dist/delivery-open-registry.d.ts.map +0 -1
- package/dist/delivery-open-registry.js +0 -121
- package/dist/delivery-open-registry.js.map +0 -1
- package/dist/delivery-session-suspects.d.ts +0 -56
- package/dist/delivery-session-suspects.d.ts.map +0 -1
- package/dist/delivery-session-suspects.js +0 -94
- package/dist/delivery-session-suspects.js.map +0 -1
- package/dist/directory-auth-posture.d.ts +0 -87
- package/dist/directory-auth-posture.d.ts.map +0 -1
- package/dist/directory-auth-posture.js +0 -134
- package/dist/directory-auth-posture.js.map +0 -1
- package/dist/directory-bootstrap.d.ts +0 -310
- package/dist/directory-bootstrap.d.ts.map +0 -1
- package/dist/directory-bootstrap.js +0 -557
- package/dist/directory-bootstrap.js.map +0 -1
- package/dist/directory-connect.d.ts +0 -27
- package/dist/directory-connect.d.ts.map +0 -1
- package/dist/directory-connect.js +0 -106
- package/dist/directory-connect.js.map +0 -1
- package/dist/disconnect-cleanup.d.ts +0 -51
- package/dist/disconnect-cleanup.d.ts.map +0 -1
- package/dist/disconnect-cleanup.js +0 -72
- package/dist/disconnect-cleanup.js.map +0 -1
- package/dist/document-amendment-store.d.ts +0 -120
- package/dist/document-amendment-store.d.ts.map +0 -1
- package/dist/document-amendment-store.js +0 -266
- package/dist/document-amendment-store.js.map +0 -1
- package/dist/document-delivery-transport.d.ts +0 -168
- package/dist/document-delivery-transport.d.ts.map +0 -1
- package/dist/document-delivery-transport.js +0 -206
- package/dist/document-delivery-transport.js.map +0 -1
- package/dist/document-engine.d.ts +0 -134
- package/dist/document-engine.d.ts.map +0 -1
- package/dist/document-engine.js +0 -282
- package/dist/document-engine.js.map +0 -1
- package/dist/document-flag.d.ts +0 -58
- package/dist/document-flag.d.ts.map +0 -1
- package/dist/document-flag.js +0 -70
- package/dist/document-flag.js.map +0 -1
- package/dist/document-frame-router.d.ts +0 -245
- package/dist/document-frame-router.d.ts.map +0 -1
- package/dist/document-frame-router.js +0 -397
- package/dist/document-frame-router.js.map +0 -1
- package/dist/document-gate-wiring.d.ts +0 -61
- package/dist/document-gate-wiring.d.ts.map +0 -1
- package/dist/document-gate-wiring.js +0 -125
- package/dist/document-gate-wiring.js.map +0 -1
- package/dist/document-gate.d.ts +0 -149
- package/dist/document-gate.d.ts.map +0 -1
- package/dist/document-gate.js +0 -509
- package/dist/document-gate.js.map +0 -1
- package/dist/document-handlers.d.ts +0 -47
- package/dist/document-handlers.d.ts.map +0 -1
- package/dist/document-handlers.js +0 -2203
- package/dist/document-handlers.js.map +0 -1
- package/dist/document-handshake.d.ts +0 -176
- package/dist/document-handshake.d.ts.map +0 -1
- package/dist/document-handshake.js +0 -452
- package/dist/document-handshake.js.map +0 -1
- package/dist/document-inbound.d.ts +0 -162
- package/dist/document-inbound.d.ts.map +0 -1
- package/dist/document-inbound.js +0 -530
- package/dist/document-inbound.js.map +0 -1
- package/dist/document-json.d.ts +0 -120
- package/dist/document-json.d.ts.map +0 -1
- package/dist/document-json.js +0 -191
- package/dist/document-json.js.map +0 -1
- package/dist/document-layer.d.ts +0 -215
- package/dist/document-layer.d.ts.map +0 -1
- package/dist/document-layer.js +0 -1025
- package/dist/document-layer.js.map +0 -1
- package/dist/document-lifecycle.d.ts +0 -52
- package/dist/document-lifecycle.d.ts.map +0 -1
- package/dist/document-lifecycle.js +0 -134
- package/dist/document-lifecycle.js.map +0 -1
- package/dist/document-live-docs.d.ts +0 -58
- package/dist/document-live-docs.d.ts.map +0 -1
- package/dist/document-live-docs.js +0 -126
- package/dist/document-live-docs.js.map +0 -1
- package/dist/document-notify.d.ts +0 -228
- package/dist/document-notify.d.ts.map +0 -1
- package/dist/document-notify.js +0 -580
- package/dist/document-notify.js.map +0 -1
- package/dist/document-profile.d.ts +0 -61
- package/dist/document-profile.d.ts.map +0 -1
- package/dist/document-profile.js +0 -112
- package/dist/document-profile.js.map +0 -1
- package/dist/document-publish.d.ts +0 -87
- package/dist/document-publish.d.ts.map +0 -1
- package/dist/document-publish.js +0 -173
- package/dist/document-publish.js.map +0 -1
- package/dist/document-reachability.d.ts +0 -42
- package/dist/document-reachability.d.ts.map +0 -1
- package/dist/document-reachability.js +0 -80
- package/dist/document-reachability.js.map +0 -1
- package/dist/document-reconcile-engine.d.ts +0 -66
- package/dist/document-reconcile-engine.d.ts.map +0 -1
- package/dist/document-reconcile-engine.js +0 -225
- package/dist/document-reconcile-engine.js.map +0 -1
- package/dist/document-reconcile-scheduler.d.ts +0 -163
- package/dist/document-reconcile-scheduler.d.ts.map +0 -1
- package/dist/document-reconcile-scheduler.js +0 -303
- package/dist/document-reconcile-scheduler.js.map +0 -1
- package/dist/document-rejection.d.ts +0 -251
- package/dist/document-rejection.d.ts.map +0 -1
- package/dist/document-rejection.js +0 -435
- package/dist/document-rejection.js.map +0 -1
- package/dist/document-screen.d.ts +0 -114
- package/dist/document-screen.d.ts.map +0 -1
- package/dist/document-screen.js +0 -223
- package/dist/document-screen.js.map +0 -1
- package/dist/document-store.d.ts +0 -372
- package/dist/document-store.d.ts.map +0 -1
- package/dist/document-store.js +0 -931
- package/dist/document-store.js.map +0 -1
- package/dist/document-surface.d.ts +0 -32
- package/dist/document-surface.d.ts.map +0 -1
- package/dist/document-surface.js +0 -151
- package/dist/document-surface.js.map +0 -1
- package/dist/document-types.d.ts +0 -94
- package/dist/document-types.d.ts.map +0 -1
- package/dist/document-types.js +0 -90
- package/dist/document-types.js.map +0 -1
- package/dist/document-watch.d.ts +0 -69
- package/dist/document-watch.d.ts.map +0 -1
- package/dist/document-watch.js +0 -108
- package/dist/document-watch.js.map +0 -1
- package/dist/document-wiring.d.ts +0 -53
- package/dist/document-wiring.d.ts.map +0 -1
- package/dist/document-wiring.js +0 -323
- package/dist/document-wiring.js.map +0 -1
- package/dist/document-write-guard.d.ts +0 -66
- package/dist/document-write-guard.d.ts.map +0 -1
- package/dist/document-write-guard.js +0 -98
- package/dist/document-write-guard.js.map +0 -1
- package/dist/document-write-path.d.ts +0 -94
- package/dist/document-write-path.d.ts.map +0 -1
- package/dist/document-write-path.js +0 -530
- package/dist/document-write-path.js.map +0 -1
- package/dist/error-message.d.ts +0 -7
- package/dist/error-message.d.ts.map +0 -1
- package/dist/error-message.js +0 -19
- package/dist/error-message.js.map +0 -1
- package/dist/file-manifest-provider.d.ts +0 -37
- package/dist/file-manifest-provider.d.ts.map +0 -1
- package/dist/file-manifest-provider.js +0 -105
- package/dist/file-manifest-provider.js.map +0 -1
- package/dist/frame-values.d.ts +0 -3
- package/dist/frame-values.d.ts.map +0 -1
- package/dist/frame-values.js +0 -84
- package/dist/frame-values.js.map +0 -1
- package/dist/frontier-mismatch.d.ts +0 -73
- package/dist/frontier-mismatch.d.ts.map +0 -1
- package/dist/frontier-mismatch.js +0 -89
- package/dist/frontier-mismatch.js.map +0 -1
- package/dist/gateway-config-handlers.d.ts +0 -26
- package/dist/gateway-config-handlers.d.ts.map +0 -1
- package/dist/gateway-config-handlers.js +0 -429
- package/dist/gateway-config-handlers.js.map +0 -1
- package/dist/held-content.d.ts +0 -145
- package/dist/held-content.d.ts.map +0 -1
- package/dist/held-content.js +0 -389
- package/dist/held-content.js.map +0 -1
- package/dist/http-manifest-poll.d.ts +0 -67
- package/dist/http-manifest-poll.d.ts.map +0 -1
- package/dist/http-manifest-poll.js +0 -150
- package/dist/http-manifest-poll.js.map +0 -1
- package/dist/identity-migration.d.ts +0 -40
- package/dist/identity-migration.d.ts.map +0 -1
- package/dist/identity-migration.js +0 -461
- package/dist/identity-migration.js.map +0 -1
- package/dist/inbound-refusals.d.ts +0 -283
- package/dist/inbound-refusals.d.ts.map +0 -1
- package/dist/inbound-refusals.js +0 -919
- package/dist/inbound-refusals.js.map +0 -1
- package/dist/inbound-seal-request.d.ts +0 -32
- package/dist/inbound-seal-request.d.ts.map +0 -1
- package/dist/inbound-seal-request.js +0 -228
- package/dist/inbound-seal-request.js.map +0 -1
- package/dist/inbound-sessions.d.ts +0 -291
- package/dist/inbound-sessions.d.ts.map +0 -1
- package/dist/inbound-sessions.js +0 -1609
- package/dist/inbound-sessions.js.map +0 -1
- package/dist/inclusion-proof-handlers.d.ts +0 -43
- package/dist/inclusion-proof-handlers.d.ts.map +0 -1
- package/dist/inclusion-proof-handlers.js +0 -565
- package/dist/inclusion-proof-handlers.js.map +0 -1
- package/dist/inclusion-proof.d.ts +0 -151
- package/dist/inclusion-proof.d.ts.map +0 -1
- package/dist/inclusion-proof.js +0 -228
- package/dist/inclusion-proof.js.map +0 -1
- package/dist/index.d.ts +0 -32
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/initiate-session-handler.d.ts +0 -55
- package/dist/initiate-session-handler.d.ts.map +0 -1
- package/dist/initiate-session-handler.js +0 -310
- package/dist/initiate-session-handler.js.map +0 -1
- package/dist/ipc-client.d.ts +0 -31
- package/dist/ipc-client.d.ts.map +0 -1
- package/dist/ipc-client.js +0 -113
- package/dist/ipc-client.js.map +0 -1
- package/dist/ipc-server.d.ts +0 -63
- package/dist/ipc-server.d.ts.map +0 -1
- package/dist/ipc-server.js +0 -429
- package/dist/ipc-server.js.map +0 -1
- package/dist/ipc-surface.d.ts +0 -44
- package/dist/ipc-surface.d.ts.map +0 -1
- package/dist/ipc-surface.js +0 -107
- package/dist/ipc-surface.js.map +0 -1
- package/dist/line-lcs.d.ts +0 -51
- package/dist/line-lcs.d.ts.map +0 -1
- package/dist/line-lcs.js +0 -71
- package/dist/line-lcs.js.map +0 -1
- package/dist/lock-file.d.ts +0 -39
- package/dist/lock-file.d.ts.map +0 -1
- package/dist/lock-file.js +0 -120
- package/dist/lock-file.js.map +0 -1
- package/dist/log-collapse.d.ts +0 -66
- package/dist/log-collapse.d.ts.map +0 -1
- package/dist/log-collapse.js +0 -244
- package/dist/log-collapse.js.map +0 -1
- package/dist/log-rotate.d.ts +0 -67
- package/dist/log-rotate.d.ts.map +0 -1
- package/dist/log-rotate.js +0 -134
- package/dist/log-rotate.js.map +0 -1
- package/dist/manifest-deps.d.ts +0 -25
- package/dist/manifest-deps.d.ts.map +0 -1
- package/dist/manifest-deps.js +0 -151
- package/dist/manifest-deps.js.map +0 -1
- package/dist/manifest-poll-scheduler.d.ts +0 -31
- package/dist/manifest-poll-scheduler.d.ts.map +0 -1
- package/dist/manifest-poll-scheduler.js +0 -59
- package/dist/manifest-poll-scheduler.js.map +0 -1
- package/dist/manifest-validity.d.ts +0 -153
- package/dist/manifest-validity.d.ts.map +0 -1
- package/dist/manifest-validity.js +0 -268
- package/dist/manifest-validity.js.map +0 -1
- package/dist/manifest-version-store-db.d.ts +0 -24
- package/dist/manifest-version-store-db.d.ts.map +0 -1
- package/dist/manifest-version-store-db.js +0 -58
- package/dist/manifest-version-store-db.js.map +0 -1
- package/dist/manifest-version-store.d.ts +0 -16
- package/dist/manifest-version-store.d.ts.map +0 -1
- package/dist/manifest-version-store.js +0 -15
- package/dist/manifest-version-store.js.map +0 -1
- package/dist/network-directory-node.d.ts +0 -136
- package/dist/network-directory-node.d.ts.map +0 -1
- package/dist/network-directory-node.js +0 -810
- package/dist/network-directory-node.js.map +0 -1
- package/dist/nonce-dedup.d.ts +0 -68
- package/dist/nonce-dedup.d.ts.map +0 -1
- package/dist/nonce-dedup.js +0 -205
- package/dist/nonce-dedup.js.map +0 -1
- package/dist/notification-dispatcher.d.ts +0 -92
- package/dist/notification-dispatcher.d.ts.map +0 -1
- package/dist/notification-dispatcher.js +0 -210
- package/dist/notification-dispatcher.js.map +0 -1
- package/dist/notification-handlers.d.ts +0 -53
- package/dist/notification-handlers.d.ts.map +0 -1
- package/dist/notification-handlers.js +0 -461
- package/dist/notification-handlers.js.map +0 -1
- package/dist/onboarding-guidance.d.ts +0 -79
- package/dist/onboarding-guidance.d.ts.map +0 -1
- package/dist/onboarding-guidance.js +0 -95
- package/dist/onboarding-guidance.js.map +0 -1
- package/dist/operator-guidance.d.ts +0 -25
- package/dist/operator-guidance.d.ts.map +0 -1
- package/dist/operator-guidance.js +0 -50
- package/dist/operator-guidance.js.map +0 -1
- package/dist/orphan-triage.d.ts +0 -130
- package/dist/orphan-triage.d.ts.map +0 -1
- package/dist/orphan-triage.js +0 -207
- package/dist/orphan-triage.js.map +0 -1
- package/dist/outbound-sessions.d.ts +0 -126
- package/dist/outbound-sessions.d.ts.map +0 -1
- package/dist/outbound-sessions.js +0 -1052
- package/dist/outbound-sessions.js.map +0 -1
- package/dist/park-envelope.d.ts +0 -329
- package/dist/park-envelope.d.ts.map +0 -1
- package/dist/park-envelope.js +0 -509
- package/dist/park-envelope.js.map +0 -1
- package/dist/park-recovery.d.ts +0 -273
- package/dist/park-recovery.d.ts.map +0 -1
- package/dist/park-recovery.js +0 -717
- package/dist/park-recovery.js.map +0 -1
- package/dist/park-refusals.d.ts +0 -147
- package/dist/park-refusals.d.ts.map +0 -1
- package/dist/park-refusals.js +0 -331
- package/dist/park-refusals.js.map +0 -1
- package/dist/quarantine-framing.d.ts +0 -92
- package/dist/quarantine-framing.d.ts.map +0 -1
- package/dist/quarantine-framing.js +0 -111
- package/dist/quarantine-framing.js.map +0 -1
- package/dist/reconnect-drain.d.ts +0 -22
- package/dist/reconnect-drain.d.ts.map +0 -1
- package/dist/reconnect-drain.js +0 -65
- package/dist/reconnect-drain.js.map +0 -1
- package/dist/recovered-position.d.ts +0 -14
- package/dist/recovered-position.d.ts.map +0 -1
- package/dist/recovered-position.js +0 -59
- package/dist/recovered-position.js.map +0 -1
- package/dist/refusal-notices.d.ts +0 -196
- package/dist/refusal-notices.d.ts.map +0 -1
- package/dist/refusal-notices.js +0 -516
- package/dist/refusal-notices.js.map +0 -1
- package/dist/refusal-reasons.d.ts +0 -245
- package/dist/refusal-reasons.d.ts.map +0 -1
- package/dist/refusal-reasons.js +0 -363
- package/dist/refusal-reasons.js.map +0 -1
- package/dist/register-handler.d.ts +0 -36
- package/dist/register-handler.d.ts.map +0 -1
- package/dist/register-handler.js +0 -285
- package/dist/register-handler.js.map +0 -1
- package/dist/registration-context.d.ts +0 -72
- package/dist/registration-context.d.ts.map +0 -1
- package/dist/registration-context.js +0 -126
- package/dist/registration-context.js.map +0 -1
- package/dist/registration-manager.d.ts +0 -94
- package/dist/registration-manager.d.ts.map +0 -1
- package/dist/registration-manager.js +0 -585
- package/dist/registration-manager.js.map +0 -1
- package/dist/registration-persistence.d.ts +0 -183
- package/dist/registration-persistence.d.ts.map +0 -1
- package/dist/registration-persistence.js +0 -263
- package/dist/registration-persistence.js.map +0 -1
- package/dist/registry-poll.d.ts +0 -52
- package/dist/registry-poll.d.ts.map +0 -1
- package/dist/registry-poll.js +0 -140
- package/dist/registry-poll.js.map +0 -1
- package/dist/registry-version-store-db.d.ts +0 -22
- package/dist/registry-version-store-db.d.ts.map +0 -1
- package/dist/registry-version-store-db.js +0 -50
- package/dist/registry-version-store-db.js.map +0 -1
- package/dist/relay-endpoints.d.ts +0 -18
- package/dist/relay-endpoints.d.ts.map +0 -1
- package/dist/relay-endpoints.js +0 -9
- package/dist/relay-endpoints.js.map +0 -1
- package/dist/relay-only.d.ts +0 -140
- package/dist/relay-only.d.ts.map +0 -1
- package/dist/relay-only.js +0 -193
- package/dist/relay-only.js.map +0 -1
- package/dist/relay-receipt-store.d.ts +0 -155
- package/dist/relay-receipt-store.d.ts.map +0 -1
- package/dist/relay-receipt-store.js +0 -284
- package/dist/relay-receipt-store.js.map +0 -1
- package/dist/relay-reconnect.d.ts +0 -32
- package/dist/relay-reconnect.d.ts.map +0 -1
- package/dist/relay-reconnect.js +0 -29
- package/dist/relay-reconnect.js.map +0 -1
- package/dist/reply-lag.d.ts +0 -11
- package/dist/reply-lag.d.ts.map +0 -1
- package/dist/reply-lag.js +0 -46
- package/dist/reply-lag.js.map +0 -1
- package/dist/resolve-named-agent.d.ts +0 -49
- package/dist/resolve-named-agent.d.ts.map +0 -1
- package/dist/resolve-named-agent.js +0 -77
- package/dist/resolve-named-agent.js.map +0 -1
- package/dist/restart-seal-resolver.d.ts +0 -110
- package/dist/restart-seal-resolver.d.ts.map +0 -1
- package/dist/restart-seal-resolver.js +0 -353
- package/dist/restart-seal-resolver.js.map +0 -1
- package/dist/resume-last-seen.d.ts +0 -15
- package/dist/resume-last-seen.d.ts.map +0 -1
- package/dist/resume-last-seen.js +0 -44
- package/dist/resume-last-seen.js.map +0 -1
- package/dist/retry-queue.d.ts +0 -203
- package/dist/retry-queue.d.ts.map +0 -1
- package/dist/retry-queue.js +0 -701
- package/dist/retry-queue.js.map +0 -1
- package/dist/roster-freshness.d.ts +0 -160
- package/dist/roster-freshness.d.ts.map +0 -1
- package/dist/roster-freshness.js +0 -250
- package/dist/roster-freshness.js.map +0 -1
- package/dist/screening-status.d.ts +0 -15
- package/dist/screening-status.d.ts.map +0 -1
- package/dist/screening-status.js +0 -65
- package/dist/screening-status.js.map +0 -1
- package/dist/seal-carried-close.d.ts +0 -37
- package/dist/seal-carried-close.d.ts.map +0 -1
- package/dist/seal-carried-close.js +0 -179
- package/dist/seal-carried-close.js.map +0 -1
- package/dist/seal-certificate-pull.d.ts +0 -79
- package/dist/seal-certificate-pull.d.ts.map +0 -1
- package/dist/seal-certificate-pull.js +0 -186
- package/dist/seal-certificate-pull.js.map +0 -1
- package/dist/seal-certified-root-check.d.ts +0 -37
- package/dist/seal-certified-root-check.d.ts.map +0 -1
- package/dist/seal-certified-root-check.js +0 -127
- package/dist/seal-certified-root-check.js.map +0 -1
- package/dist/seal-coordinator.d.ts +0 -118
- package/dist/seal-coordinator.d.ts.map +0 -1
- package/dist/seal-coordinator.js +0 -927
- package/dist/seal-coordinator.js.map +0 -1
- package/dist/seal-escalation.d.ts +0 -80
- package/dist/seal-escalation.d.ts.map +0 -1
- package/dist/seal-escalation.js +0 -283
- package/dist/seal-escalation.js.map +0 -1
- package/dist/seal-evidence-root-check.d.ts +0 -70
- package/dist/seal-evidence-root-check.d.ts.map +0 -1
- package/dist/seal-evidence-root-check.js +0 -199
- package/dist/seal-evidence-root-check.js.map +0 -1
- package/dist/seal-failure-store.d.ts +0 -129
- package/dist/seal-failure-store.d.ts.map +0 -1
- package/dist/seal-failure-store.js +0 -173
- package/dist/seal-failure-store.js.map +0 -1
- package/dist/seal-flows.d.ts +0 -107
- package/dist/seal-flows.d.ts.map +0 -1
- package/dist/seal-flows.js +0 -638
- package/dist/seal-flows.js.map +0 -1
- package/dist/seal-frontier-verify.d.ts +0 -103
- package/dist/seal-frontier-verify.d.ts.map +0 -1
- package/dist/seal-frontier-verify.js +0 -143
- package/dist/seal-frontier-verify.js.map +0 -1
- package/dist/seal-leaf.d.ts +0 -58
- package/dist/seal-leaf.d.ts.map +0 -1
- package/dist/seal-leaf.js +0 -112
- package/dist/seal-leaf.js.map +0 -1
- package/dist/seal-legibility-tbs.d.ts +0 -25
- package/dist/seal-legibility-tbs.d.ts.map +0 -1
- package/dist/seal-legibility-tbs.js +0 -77
- package/dist/seal-legibility-tbs.js.map +0 -1
- package/dist/seal-local-terminus.d.ts +0 -41
- package/dist/seal-local-terminus.d.ts.map +0 -1
- package/dist/seal-local-terminus.js +0 -170
- package/dist/seal-local-terminus.js.map +0 -1
- package/dist/seal-receipt-upgrade.d.ts +0 -30
- package/dist/seal-receipt-upgrade.d.ts.map +0 -1
- package/dist/seal-receipt-upgrade.js +0 -49
- package/dist/seal-receipt-upgrade.js.map +0 -1
- package/dist/seal-relay-silence.d.ts +0 -51
- package/dist/seal-relay-silence.d.ts.map +0 -1
- package/dist/seal-relay-silence.js +0 -76
- package/dist/seal-relay-silence.js.map +0 -1
- package/dist/seal-settle.d.ts +0 -38
- package/dist/seal-settle.d.ts.map +0 -1
- package/dist/seal-settle.js +0 -33
- package/dist/seal-settle.js.map +0 -1
- package/dist/seal-upgrade.d.ts +0 -107
- package/dist/seal-upgrade.d.ts.map +0 -1
- package/dist/seal-upgrade.js +0 -200
- package/dist/seal-upgrade.js.map +0 -1
- package/dist/sealed-conversation.d.ts +0 -36
- package/dist/sealed-conversation.d.ts.map +0 -1
- package/dist/sealed-conversation.js +0 -171
- package/dist/sealed-conversation.js.map +0 -1
- package/dist/sealed-leaf-set.d.ts +0 -92
- package/dist/sealed-leaf-set.d.ts.map +0 -1
- package/dist/sealed-leaf-set.js +0 -122
- package/dist/sealed-leaf-set.js.map +0 -1
- package/dist/send-claims.d.ts +0 -56
- package/dist/send-claims.d.ts.map +0 -1
- package/dist/send-claims.js +0 -50
- package/dist/send-claims.js.map +0 -1
- package/dist/session-assignment-parser.d.ts +0 -98
- package/dist/session-assignment-parser.d.ts.map +0 -1
- package/dist/session-assignment-parser.js +0 -325
- package/dist/session-assignment-parser.js.map +0 -1
- package/dist/session-category.d.ts +0 -19
- package/dist/session-category.d.ts.map +0 -1
- package/dist/session-category.js +0 -14
- package/dist/session-category.js.map +0 -1
- package/dist/session-ceremony.d.ts +0 -297
- package/dist/session-ceremony.d.ts.map +0 -1
- package/dist/session-ceremony.js +0 -964
- package/dist/session-ceremony.js.map +0 -1
- package/dist/session-closed.d.ts +0 -79
- package/dist/session-closed.d.ts.map +0 -1
- package/dist/session-closed.js +0 -189
- package/dist/session-closed.js.map +0 -1
- package/dist/session-connection-gater.d.ts +0 -148
- package/dist/session-connection-gater.d.ts.map +0 -1
- package/dist/session-connection-gater.js +0 -332
- package/dist/session-connection-gater.js.map +0 -1
- package/dist/session-content-context.d.ts +0 -162
- package/dist/session-content-context.d.ts.map +0 -1
- package/dist/session-content-context.js +0 -2
- package/dist/session-content-context.js.map +0 -1
- package/dist/session-content-handlers.d.ts +0 -82
- package/dist/session-content-handlers.d.ts.map +0 -1
- package/dist/session-content-handlers.js +0 -1382
- package/dist/session-content-handlers.js.map +0 -1
- package/dist/session-content-ingest.d.ts +0 -206
- package/dist/session-content-ingest.d.ts.map +0 -1
- package/dist/session-content-ingest.js +0 -2167
- package/dist/session-content-ingest.js.map +0 -1
- package/dist/session-content-send.d.ts +0 -191
- package/dist/session-content-send.d.ts.map +0 -1
- package/dist/session-content-send.js +0 -1360
- package/dist/session-content-send.js.map +0 -1
- package/dist/session-delivery-acks.d.ts +0 -169
- package/dist/session-delivery-acks.d.ts.map +0 -1
- package/dist/session-delivery-acks.js +0 -569
- package/dist/session-delivery-acks.js.map +0 -1
- package/dist/session-ephemerals.d.ts +0 -279
- package/dist/session-ephemerals.d.ts.map +0 -1
- package/dist/session-ephemerals.js +0 -591
- package/dist/session-ephemerals.js.map +0 -1
- package/dist/session-leaf-records.d.ts +0 -159
- package/dist/session-leaf-records.d.ts.map +0 -1
- package/dist/session-leaf-records.js +0 -408
- package/dist/session-leaf-records.js.map +0 -1
- package/dist/session-lifecycle.d.ts +0 -303
- package/dist/session-lifecycle.d.ts.map +0 -1
- package/dist/session-lifecycle.js +0 -1679
- package/dist/session-lifecycle.js.map +0 -1
- package/dist/session-liveness.d.ts +0 -135
- package/dist/session-liveness.d.ts.map +0 -1
- package/dist/session-liveness.js +0 -347
- package/dist/session-liveness.js.map +0 -1
- package/dist/session-name.d.ts +0 -35
- package/dist/session-name.d.ts.map +0 -1
- package/dist/session-name.js +0 -60
- package/dist/session-name.js.map +0 -1
- package/dist/session-node-factory.d.ts +0 -18
- package/dist/session-node-factory.d.ts.map +0 -1
- package/dist/session-node-factory.js +0 -182
- package/dist/session-node-factory.js.map +0 -1
- package/dist/session-node-manager.d.ts +0 -875
- package/dist/session-node-manager.d.ts.map +0 -1
- package/dist/session-node-manager.js +0 -2995
- package/dist/session-node-manager.js.map +0 -1
- package/dist/session-node-types.d.ts +0 -1057
- package/dist/session-node-types.d.ts.map +0 -1
- package/dist/session-node-types.js +0 -657
- package/dist/session-node-types.js.map +0 -1
- package/dist/session-notify.d.ts +0 -46
- package/dist/session-notify.d.ts.map +0 -1
- package/dist/session-notify.js +0 -116
- package/dist/session-notify.js.map +0 -1
- package/dist/session-own-chain-store.d.ts +0 -65
- package/dist/session-own-chain-store.d.ts.map +0 -1
- package/dist/session-own-chain-store.js +0 -75
- package/dist/session-own-chain-store.js.map +0 -1
- package/dist/session-queries.d.ts +0 -476
- package/dist/session-queries.d.ts.map +0 -1
- package/dist/session-queries.js +0 -1007
- package/dist/session-queries.js.map +0 -1
- package/dist/session-read-handlers.d.ts +0 -87
- package/dist/session-read-handlers.d.ts.map +0 -1
- package/dist/session-read-handlers.js +0 -682
- package/dist/session-read-handlers.js.map +0 -1
- package/dist/session-records.d.ts +0 -341
- package/dist/session-records.d.ts.map +0 -1
- package/dist/session-records.js +0 -858
- package/dist/session-records.js.map +0 -1
- package/dist/session-relay-client.d.ts +0 -659
- package/dist/session-relay-client.d.ts.map +0 -1
- package/dist/session-relay-client.js +0 -2876
- package/dist/session-relay-client.js.map +0 -1
- package/dist/session-relay.d.ts +0 -397
- package/dist/session-relay.d.ts.map +0 -1
- package/dist/session-relay.js +0 -1636
- package/dist/session-relay.js.map +0 -1
- package/dist/session-salt-agreement.d.ts +0 -331
- package/dist/session-salt-agreement.d.ts.map +0 -1
- package/dist/session-salt-agreement.js +0 -472
- package/dist/session-salt-agreement.js.map +0 -1
- package/dist/session-salts.d.ts +0 -432
- package/dist/session-salts.d.ts.map +0 -1
- package/dist/session-salts.js +0 -1540
- package/dist/session-salts.js.map +0 -1
- package/dist/session-schema.d.ts +0 -30
- package/dist/session-schema.d.ts.map +0 -1
- package/dist/session-schema.js +0 -877
- package/dist/session-schema.js.map +0 -1
- package/dist/session-seal-leaf-store.d.ts +0 -70
- package/dist/session-seal-leaf-store.d.ts.map +0 -1
- package/dist/session-seal-leaf-store.js +0 -105
- package/dist/session-seal-leaf-store.js.map +0 -1
- package/dist/session-seal.d.ts +0 -334
- package/dist/session-seal.d.ts.map +0 -1
- package/dist/session-seal.js +0 -1017
- package/dist/session-seal.js.map +0 -1
- package/dist/session-terminal-refusal.d.ts +0 -65
- package/dist/session-terminal-refusal.d.ts.map +0 -1
- package/dist/session-terminal-refusal.js +0 -87
- package/dist/session-terminal-refusal.js.map +0 -1
- package/dist/session-tree.d.ts +0 -110
- package/dist/session-tree.d.ts.map +0 -1
- package/dist/session-tree.js +0 -144
- package/dist/session-tree.js.map +0 -1
- package/dist/session-views.d.ts +0 -47
- package/dist/session-views.d.ts.map +0 -1
- package/dist/session-views.js +0 -278
- package/dist/session-views.js.map +0 -1
- package/dist/signal-handlers.d.ts +0 -63
- package/dist/signal-handlers.d.ts.map +0 -1
- package/dist/signal-handlers.js +0 -980
- package/dist/signal-handlers.js.map +0 -1
- package/dist/signal-requirement-policy.d.ts +0 -51
- package/dist/signal-requirement-policy.d.ts.map +0 -1
- package/dist/signal-requirement-policy.js +0 -89
- package/dist/signal-requirement-policy.js.map +0 -1
- package/dist/signal-revocability.d.ts +0 -49
- package/dist/signal-revocability.d.ts.map +0 -1
- package/dist/signal-revocability.js +0 -93
- package/dist/signal-revocability.js.map +0 -1
- package/dist/signal-submission.d.ts +0 -181
- package/dist/signal-submission.d.ts.map +0 -1
- package/dist/signal-submission.js +0 -368
- package/dist/signal-submission.js.map +0 -1
- package/dist/signaling-connect.d.ts +0 -118
- package/dist/signaling-connect.d.ts.map +0 -1
- package/dist/signaling-connect.js +0 -538
- package/dist/signaling-connect.js.map +0 -1
- package/dist/signaling-wiring.d.ts +0 -105
- package/dist/signaling-wiring.d.ts.map +0 -1
- package/dist/signaling-wiring.js +0 -393
- package/dist/signaling-wiring.js.map +0 -1
- package/dist/singleton-lock.d.ts +0 -85
- package/dist/singleton-lock.d.ts.map +0 -1
- package/dist/singleton-lock.js +0 -219
- package/dist/singleton-lock.js.map +0 -1
- package/dist/sqlcipher-db.d.ts +0 -139
- package/dist/sqlcipher-db.d.ts.map +0 -1
- package/dist/sqlcipher-db.js +0 -357
- package/dist/sqlcipher-db.js.map +0 -1
- package/dist/standing-receivers.d.ts +0 -319
- package/dist/standing-receivers.d.ts.map +0 -1
- package/dist/standing-receivers.js +0 -1295
- package/dist/standing-receivers.js.map +0 -1
- package/dist/start-agent.d.ts +0 -64
- package/dist/start-agent.d.ts.map +0 -1
- package/dist/start-agent.js +0 -136
- package/dist/start-agent.js.map +0 -1
- package/dist/status-handler.d.ts +0 -54
- package/dist/status-handler.d.ts.map +0 -1
- package/dist/status-handler.js +0 -61
- package/dist/status-handler.js.map +0 -1
- package/dist/submission-retry.d.ts +0 -208
- package/dist/submission-retry.d.ts.map +0 -1
- package/dist/submission-retry.js +0 -506
- package/dist/submission-retry.js.map +0 -1
- package/dist/telegram-bot-client.d.ts +0 -34
- package/dist/telegram-bot-client.d.ts.map +0 -1
- package/dist/telegram-bot-client.js +0 -36
- package/dist/telegram-bot-client.js.map +0 -1
- package/dist/telegram-doorbell.d.ts +0 -38
- package/dist/telegram-doorbell.d.ts.map +0 -1
- package/dist/telegram-doorbell.js +0 -140
- package/dist/telegram-doorbell.js.map +0 -1
- package/dist/test-handlers.d.ts +0 -62
- package/dist/test-handlers.d.ts.map +0 -1
- package/dist/test-handlers.js +0 -240
- package/dist/test-handlers.js.map +0 -1
- package/dist/testing.d.ts +0 -10
- package/dist/testing.d.ts.map +0 -1
- package/dist/testing.js +0 -10
- package/dist/testing.js.map +0 -1
- package/dist/transport-composition.d.ts +0 -31
- package/dist/transport-composition.d.ts.map +0 -1
- package/dist/transport-composition.js +0 -55
- package/dist/transport-composition.js.map +0 -1
- package/dist/transport-selector.d.ts +0 -202
- package/dist/transport-selector.d.ts.map +0 -1
- package/dist/transport-selector.js +0 -196
- package/dist/transport-selector.js.map +0 -1
- package/dist/trust-signal-pickup-listener.d.ts +0 -43
- package/dist/trust-signal-pickup-listener.d.ts.map +0 -1
- package/dist/trust-signal-pickup-listener.js +0 -48
- package/dist/trust-signal-pickup-listener.js.map +0 -1
- package/dist/trust-signal-store.d.ts +0 -406
- package/dist/trust-signal-store.d.ts.map +0 -1
- package/dist/trust-signal-store.js +0 -939
- package/dist/trust-signal-store.js.map +0 -1
- package/dist/trust-signal-sweep-tick.d.ts +0 -60
- package/dist/trust-signal-sweep-tick.d.ts.map +0 -1
- package/dist/trust-signal-sweep-tick.js +0 -101
- package/dist/trust-signal-sweep-tick.js.map +0 -1
- package/dist/trust-signal-sweep.d.ts +0 -94
- package/dist/trust-signal-sweep.d.ts.map +0 -1
- package/dist/trust-signal-sweep.js +0 -147
- package/dist/trust-signal-sweep.js.map +0 -1
- package/dist/type-registry.d.ts +0 -42
- package/dist/type-registry.d.ts.map +0 -1
- package/dist/type-registry.js +0 -37
- package/dist/type-registry.js.map +0 -1
- package/dist/types.d.ts +0 -746
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -20
- package/dist/types.js.map +0 -1
- package/dist/unresolved-nodes-report.d.ts +0 -14
- package/dist/unresolved-nodes-report.d.ts.map +0 -1
- package/dist/unresolved-nodes-report.js +0 -96
- package/dist/unresolved-nodes-report.js.map +0 -1
- package/dist/vocabulary.d.ts +0 -150
- package/dist/vocabulary.d.ts.map +0 -1
- package/dist/vocabulary.js +0 -386
- package/dist/vocabulary.js.map +0 -1
- package/dist/who-label.d.ts +0 -28
- package/dist/who-label.d.ts.map +0 -1
- package/dist/who-label.js +0 -31
- package/dist/who-label.js.map +0 -1
- package/dist/who-resolver.d.ts +0 -15
- package/dist/who-resolver.d.ts.map +0 -1
- package/dist/who-resolver.js +0 -47
- package/dist/who-resolver.js.map +0 -1
- package/dist/wire-content-hash.d.ts +0 -93
- package/dist/wire-content-hash.d.ts.map +0 -1
- package/dist/wire-content-hash.js +0 -116
- package/dist/wire-content-hash.js.map +0 -1
- package/dist/withheld-content.d.ts +0 -13
- package/dist/withheld-content.d.ts.map +0 -1
- package/dist/withheld-content.js +0 -46
- package/dist/withheld-content.js.map +0 -1
- package/dist/witness-alerts.d.ts +0 -40
- package/dist/witness-alerts.d.ts.map +0 -1
- package/dist/witness-alerts.js +0 -102
- package/dist/witness-alerts.js.map +0 -1
package/dist/daemon.js
DELETED
|
@@ -1,1177 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CELLO Daemon process — the long-running background service.
|
|
3
|
-
*
|
|
4
|
-
* Pseudocode:
|
|
5
|
-
* 1. startDaemon(config):
|
|
6
|
-
* a. M7-MANIFEST-002: Load and verify consortium manifest (BEFORE any directory connection)
|
|
7
|
-
* - On signature failure: log error, skip connection
|
|
8
|
-
* - On expiry: log directory.auth.manifest.expired at ERROR, skip connection
|
|
9
|
-
* - On version rollback: log directory.auth.manifest.version.rollback at ERROR
|
|
10
|
-
* - On success: log directory.auth.manifest.verified at INFO
|
|
11
|
-
* b. Load agents from ~/.cello/agents/ (or legacy ~/.cello/key)
|
|
12
|
-
* c. Acquire lock file atomically
|
|
13
|
-
* d. Initialize SessionNodeManager (creates standing receiver, detects interrupted sessions)
|
|
14
|
-
* e. Start IPC server on Unix domain socket
|
|
15
|
-
* f. Register method handlers (status, shutdown)
|
|
16
|
-
* g. Log daemon.started event (with manifestVerified field)
|
|
17
|
-
* h. Set up SIGTERM/SIGINT handlers for graceful shutdown
|
|
18
|
-
* i. Start background manifest polling (if pollScheduler provided and manifest verified)
|
|
19
|
-
*
|
|
20
|
-
* 2. shutdown(reason):
|
|
21
|
-
* a. Cancel manifest poll scheduler
|
|
22
|
-
* b. Log daemon.stopped event
|
|
23
|
-
* c. Call SessionNodeManager.gracefulShutdown() (marks sessions interrupted)
|
|
24
|
-
* d. Stop IPC server (finishes in-flight, sends shutdown frame)
|
|
25
|
-
* e. Remove lock file
|
|
26
|
-
* f. Exit 0
|
|
27
|
-
*/
|
|
28
|
-
import { mkdir } from "node:fs/promises";
|
|
29
|
-
import { randomUUID } from "node:crypto";
|
|
30
|
-
import { RestartSealResolver } from "./restart-seal-resolver.js";
|
|
31
|
-
import { removeLockIfOwned } from "./lock-file.js";
|
|
32
|
-
import { acquireSingletonLock } from "./singleton-lock.js";
|
|
33
|
-
import { SealFailureStore } from "./seal-failure-store.js";
|
|
34
|
-
import { registerGatewayConfigHandlers } from "./gateway-config-handlers.js";
|
|
35
|
-
import { NonceDedupStore } from "./nonce-dedup.js";
|
|
36
|
-
import { NotificationDispatcher } from "./notification-dispatcher.js";
|
|
37
|
-
import { DbIdentityStore, channelAgentLookup } from "./db-identity-store.js";
|
|
38
|
-
import { LocalAutoNatStub } from "@cello-protocol/transport";
|
|
39
|
-
import { resolveDirectoryUrl } from "./directory-bootstrap.js";
|
|
40
|
-
import { registerContactHandlers } from "./contact-handlers.js";
|
|
41
|
-
import { registerSignalHandlers } from "./signal-handlers.js";
|
|
42
|
-
import { registerTestHandlers } from "./test-handlers.js";
|
|
43
|
-
import { registerAgentAdminHandlers } from "./agent-admin-handlers.js";
|
|
44
|
-
import { registerStatusHandler } from "./status-handler.js";
|
|
45
|
-
import { registerBackupRestoreHandlers } from "./backup-restore-handlers.js";
|
|
46
|
-
import { wireDocumentGate } from "./document-gate-wiring.js";
|
|
47
|
-
import { documentsEnabled } from "./document-flag.js";
|
|
48
|
-
import { createSignalingWiring } from "./signaling-wiring.js";
|
|
49
|
-
import { createAttendanceWiring } from "./attendance-wiring.js";
|
|
50
|
-
import { createAwayInboxOneshot } from "./away-inbox-oneshot.js";
|
|
51
|
-
import { createSendClaims } from "./send-claims.js";
|
|
52
|
-
import { startBootCore } from "./boot-core.js";
|
|
53
|
-
import { startBootAgents } from "./boot-agents.js";
|
|
54
|
-
import { startBootConnectionState } from "./boot-connection-state.js";
|
|
55
|
-
import { startBootParkedContent } from "./boot-parked-content.js";
|
|
56
|
-
import { startBootSweeps } from "./boot-sweeps.js";
|
|
57
|
-
import { createSessionViews } from "./session-views.js";
|
|
58
|
-
import { createAgentSelection } from "./agent-selection-root.js";
|
|
59
|
-
import { createStartAgent } from "./start-agent.js";
|
|
60
|
-
import { createSessionNotify } from "./session-notify.js";
|
|
61
|
-
import { createConnectionAgents } from "./connection-agents.js";
|
|
62
|
-
import { createDirectoryConnect } from "./directory-connect.js";
|
|
63
|
-
import { createUnresolvedNodesReport } from "./unresolved-nodes-report.js";
|
|
64
|
-
import { createIpcSurface } from "./ipc-surface.js";
|
|
65
|
-
import { createDaemonStatusReport } from "./daemon-status-report.js";
|
|
66
|
-
import { logConsortiumAnchor } from "./consortium-fingerprint.js";
|
|
67
|
-
import { createWhoResolver } from "./who-resolver.js";
|
|
68
|
-
import { NO_CURRENT_AGENT_RESPONSE, registrationGuidance } from "./operator-guidance.js";
|
|
69
|
-
import { wireDisconnectCleanup } from "./disconnect-cleanup.js";
|
|
70
|
-
import { createSealCoordinator } from "./seal-coordinator.js";
|
|
71
|
-
import { createTelegramDoorbell } from "./telegram-doorbell.js";
|
|
72
|
-
import { registerSessionContentHandlers } from "./session-content-handlers.js";
|
|
73
|
-
import { createSealFlows } from "./seal-flows.js";
|
|
74
|
-
import { registerCloseSessionHandler } from "./close-session-handler.js";
|
|
75
|
-
import { createInboundSessions } from "./inbound-sessions.js";
|
|
76
|
-
import { createOutboundSessions } from "./outbound-sessions.js";
|
|
77
|
-
import { registerSessionReadHandlers } from "./session-read-handlers.js";
|
|
78
|
-
import { registerInclusionProofHandlers } from "./inclusion-proof-handlers.js";
|
|
79
|
-
import { pullSealCertificate } from "./seal-certificate-pull.js";
|
|
80
|
-
import { registerAgentHandlers } from "./agent-handlers.js";
|
|
81
|
-
import { registerRegisterHandler } from "./register-handler.js";
|
|
82
|
-
import { registerInitiateSessionHandler } from "./initiate-session-handler.js";
|
|
83
|
-
import { createInboundSealRequestHandler } from "./inbound-seal-request.js";
|
|
84
|
-
import { registerNotificationHandlers } from "./notification-handlers.js";
|
|
85
|
-
import { TypeRegistry } from "./type-registry.js";
|
|
86
|
-
import { DbRegistryVersionStore } from "./registry-version-store-db.js";
|
|
87
|
-
import { startRegistryPoll } from "./registry-poll.js";
|
|
88
|
-
import { countAttendance } from "./co-attendance.js";
|
|
89
|
-
import { FrontierMismatchStore } from "./frontier-mismatch.js";
|
|
90
|
-
export { ProductionSessionNodeFactory } from "./session-node-factory.js";
|
|
91
|
-
// M8C-TTL-1: ONE definition now. daemon.ts held a second copy of this constant with the same value
|
|
92
|
-
// while `inbound-sessions.ts` — the file that actually enforces the TTL — held the first. Two
|
|
93
|
-
// definitions of one contract is how the two stop agreeing; the runtime always used that one, and
|
|
94
|
-
// this re-export is what kept the test that imports it from here working.
|
|
95
|
-
export { INBOUND_SESSION_TTL_MS } from "./inbound-sessions.js";
|
|
96
|
-
import { extractErrorMessage } from "./error-message.js";
|
|
97
|
-
/**
|
|
98
|
-
* DOD-SINGLE-DAEMON-1: take the singleton lock, and make sure it is released if startup fails
|
|
99
|
-
* ANYWHERE after that point — not just on the two failure paths that happened to think of it.
|
|
100
|
-
*
|
|
101
|
-
* The real binary exits on a startup failure and the kernel reclaims the lock regardless, so this is
|
|
102
|
-
* not a production-safety hole. It is a DIAGNOSTIC one, and a nasty kind: an in-process caller (every
|
|
103
|
-
* vitest daemon, any embedder) whose startup throws — a corrupt database, a bad key, an EACCES on the
|
|
104
|
-
* lock file — would leak the lock and then be told, on the next attempt in that process, "another
|
|
105
|
-
* daemon is already running". The true cause is replaced by a lie, and the directory is wedged for the
|
|
106
|
-
* life of the process.
|
|
107
|
-
*/
|
|
108
|
-
export async function startDaemon(config) {
|
|
109
|
-
await mkdir(config.celloDir, { recursive: true });
|
|
110
|
-
const singletonLock = acquireSingletonLock(config.celloDir, config.logger);
|
|
111
|
-
try {
|
|
112
|
-
return await startDaemonHoldingLock(config, singletonLock);
|
|
113
|
-
}
|
|
114
|
-
catch (err) {
|
|
115
|
-
singletonLock.release();
|
|
116
|
-
throw err;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
async function startDaemonHoldingLock(config, singletonLock) {
|
|
120
|
-
const { celloDir, socketPath, lockFilePath, maxConnections, logger, manifestProvider, manifestPollScheduler, directoryHttpUrl, signalingConnect, challengeVerifier, directoryEndpointResolver, sessionNegotiator, getRelayCircuitAddress, telegramBotClient: injectedTelegramBotClient, } = config;
|
|
121
|
-
/**
|
|
122
|
-
* DOD-M15-CONSORTIUM-FINGERPRINT-1 — what this daemon ACTUALLY verifies manifests against.
|
|
123
|
-
*
|
|
124
|
-
* Straight off the config, because that is what `startBootCore` hands `verifyStartupManifest`.
|
|
125
|
-
* Reading the compiled-in constant instead would print the genuine CELLO fingerprint on a daemon
|
|
126
|
-
* pointed at someone else's consortium, or at none.
|
|
127
|
-
*/
|
|
128
|
-
const enforcedConsortium = { rootKeys: config.manifestRootKeys, threshold: config.manifestThreshold };
|
|
129
|
-
// 040-DAEMONROOT unit 7 (phase 1): transport, gateway, session manager, the manifest gate, the
|
|
130
|
-
// roster sweep and the type registry → boot-core.ts. Three inputs, everything below comes out.
|
|
131
|
-
const { transportSelector, securityGateway, sessionNodeManager, manifestOrigin, manifestVerified, verifiedManifest, verifiedManifestVersion, rosterSweepScheduler, stopRosterSweep, stopHttpManifestPoll, resolveConsortiumRoster, failoverEndpointResolver, getFailoverEndpoint, getUnresolvedNodes, getUnresolvedSweptAt, getDeclaredNodeCount,
|
|
132
|
-
// A READER, not a value: the sweep writes it after this returns, and `cello status` reads it
|
|
133
|
-
// later still. A snapshot here reports a healthy roster through every sweep failure.
|
|
134
|
-
lastRosterSweepError, } = await startBootCore({ config, logger, directoryHttpUrl });
|
|
135
|
-
// DOD-REGISTRY-1: type registry poll — daemon-level, runs even with zero agents.
|
|
136
|
-
// When registryPubkey is configured, the daemon polls GET /registry, verifies the inner
|
|
137
|
-
// Ed25519 signature, and updates the in-memory TypeRegistry. A poll failure never blanks
|
|
138
|
-
// classification (INV-TYPE-CARRY). Absent pubkey = polling disabled, all types unclassified.
|
|
139
|
-
const typeRegistry = new TypeRegistry();
|
|
140
|
-
let stopRegistryPoll;
|
|
141
|
-
// DOD-M12B-RESTART-SEAL-1: assigned as the last act of boot, stopped in stop().
|
|
142
|
-
let restartSealResolver;
|
|
143
|
-
if (config.registryPubkey && config.registryPollScheduler) {
|
|
144
|
-
const registryVersionStore = new DbRegistryVersionStore(sessionNodeManager.getDb(), logger);
|
|
145
|
-
stopRegistryPoll = startRegistryPoll({
|
|
146
|
-
scheduler: config.registryPollScheduler,
|
|
147
|
-
directoryUrl: directoryHttpUrl ?? resolveDirectoryUrl(process.env),
|
|
148
|
-
typeRegistry,
|
|
149
|
-
registryVersionStore,
|
|
150
|
-
registryPubkey: config.registryPubkey,
|
|
151
|
-
logger,
|
|
152
|
-
mintCorrelationId: () => randomUUID(),
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
// 040-DAEMONROOT unit 7 (phase 2): the agents this daemon holds, their keys, the content park,
|
|
156
|
-
// the reconnect drain and the submission retry queue → boot-agents.ts.
|
|
157
|
-
const { loadedAgents, getPersistence, agents, keyProviders, contentPark, autoRecoverForAgent, onSignalingConnected, submissionRetries, recordIssuedSubmission, } = await startBootAgents({
|
|
158
|
-
config, logger, sessionNodeManager, securityGateway,
|
|
159
|
-
// GETTERS: all FOUR are declared below this call and read inside callbacks that run after boot.
|
|
160
|
-
// Three are `const`, so by value they are a temporal-dead-zone crash at boot, not a silent
|
|
161
|
-
// absence — the silent shape is a `let` assigned further down, which this file still has two of
|
|
162
|
-
// (`reconcileScheduler`, `documentOwnerKeyForHook`).
|
|
163
|
-
getFlushAwaitingContent: () => flushAwaitingContent,
|
|
164
|
-
getOnlineAgents: () => onlineAgents,
|
|
165
|
-
getSharedSignaling: () => sharedSignaling,
|
|
166
|
-
getPerAgentSignaling: () => perAgentSignaling,
|
|
167
|
-
});
|
|
168
|
-
// DOD-M15-SEAL-FAILED-TERMINAL-1: a seal that ended without a receipt is discoverable rather than
|
|
169
|
-
// being a line in daemon.log. In memory on purpose — a restart makes "failed" the WRONG answer,
|
|
170
|
-
// because the boot sweep plus the restart seal resolver retry the session, so a marker whose
|
|
171
|
-
// lifetime is the process matches the lifetime of the condition it describes.
|
|
172
|
-
//
|
|
173
|
-
// Declared HERE rather than 600 lines below because the seal coordinator writes to it: a
|
|
174
|
-
// directory refusal must survive the close call waiting on it (DOD-M15-SEALPARTIES-1).
|
|
175
|
-
// Created HERE, not where the seal code used to sit (~2,500 lines down), because the listeners
|
|
176
|
-
// are wired into every signaling manager below — and the originals were FUNCTION DECLARATIONS,
|
|
177
|
-
// so hoisting silently let them be CALLED 1,900 lines before they were DEFINED. A const in their
|
|
178
|
-
// place lands in the temporal dead zone and every one of those calls throws. The dependency on
|
|
179
|
-
// hoisting was real, load-bearing and invisible; naming the construction point makes it explicit.
|
|
180
|
-
// ─── The seal cluster (seal-coordinator.ts) ───
|
|
181
|
-
// Bilateral seal, unilateral escalation, and the returning-absent-party upgrade: five pieces of
|
|
182
|
-
// state and the listeners that drive them. Already seal-private; now that is enforced by a module
|
|
183
|
-
// boundary rather than by convention. cello_close_session still drives the waiters directly.
|
|
184
|
-
//
|
|
185
|
-
const sealFailures = new SealFailureStore();
|
|
186
|
-
const { sealKey, sealInterruptedInProgress, pendingSealWaiters, pendingUnilateralWaiters, registerSealListeners, } = createSealCoordinator({
|
|
187
|
-
logger,
|
|
188
|
-
sessionNodeManager,
|
|
189
|
-
getPersistence,
|
|
190
|
-
getKeyProvider: (agentName) => keyProviders.get(agentName),
|
|
191
|
-
recoverContent: (agentName) => autoRecoverForAgent(agentName, "seal_upgrade_gate"),
|
|
192
|
-
// DOD-M15-SEALPARTIES-1: a directory refusal has to outlive the close call that is waiting on
|
|
193
|
-
// it — both surfaces read this store, and a close that already returned has nowhere else to
|
|
194
|
-
// leave the answer. `kind` carries a DIRECTORY REFUSAL through as terminal (see the store).
|
|
195
|
-
recordSealFailure: (agentName, sessionId, reason, kind) => sealFailures.record(agentName, sessionId, reason, new Date().toISOString(), kind),
|
|
196
|
-
});
|
|
197
|
-
// The two seal-initiation flows cello_close_session dispatches into (seal-flows.ts): the
|
|
198
|
-
// counterparty is gone (seal-interrupted) or live (bilateral). Neither can notarize on its own —
|
|
199
|
-
// the daemon holds no threshold signer, which IS the sovereign-node invariant.
|
|
200
|
-
// DOD-FRONTIER-STRAND-1 AC3: mismatches observed during a seal exchange, retained so the session
|
|
201
|
-
// list can show them. Detection is inherently at close time (the frontiers can only be compared
|
|
202
|
-
// when the two sides talk); what was missing is that the answer was discarded the moment it was
|
|
203
|
-
// produced, so the only way to see it again was to attempt another close.
|
|
204
|
-
const frontierMismatches = new FrontierMismatchStore();
|
|
205
|
-
const { handleSealInterruptedFlow, handleActiveSealFlow } = createSealFlows({
|
|
206
|
-
logger,
|
|
207
|
-
sessionNodeManager,
|
|
208
|
-
agents,
|
|
209
|
-
getKeyProvider: (agentName) => keyProviders.get(agentName),
|
|
210
|
-
// 040-DAEMONROOT unit 5: these two live in signaling-wiring.ts, which is constructed BELOW
|
|
211
|
-
// this call. They were function declarations in one scope, so hoisting made a direct reference
|
|
212
|
-
// work; across a module boundary it cannot. Resolved at CALL time instead — seal flows only run
|
|
213
|
-
// long after boot, so the indirection costs nothing and the alternative is a captured undefined.
|
|
214
|
-
signalingFor: (agentName) => signalingFor(agentName),
|
|
215
|
-
sendOver: (agentName, frame) => sendOver(agentName, frame),
|
|
216
|
-
recordFrontierMismatch: (agentName, sessionId, m) => frontierMismatches.record(agentName, sessionId, m, Date.now()),
|
|
217
|
-
clearFrontierMismatch: (agentName, sessionId) => frontierMismatches.clear(agentName, sessionId),
|
|
218
|
-
});
|
|
219
|
-
// 040-DAEMONROOT unit 13: how this daemon reaches a directory, and what it tells a relay about
|
|
220
|
-
// itself when it gets there → directory-connect.ts.
|
|
221
|
-
const { buildRelayConnectParams, noSharedDirectoryNode, sharedSignaling } = createDirectoryConnect({
|
|
222
|
-
logger, keyProviders, signalingConnect, directoryEndpointResolver,
|
|
223
|
-
});
|
|
224
|
-
// 040-DAEMONROOT unit 5: per-agent directory signaling → signaling-wiring.ts.
|
|
225
|
-
const { perAgentSignaling, getAgentSignaling, waitForSignalingConnected, dropAgentSignaling, signalingFor, sendOver, directorySignalingStatus, stopAllSignaling, registerPickupListener, } = createSignalingWiring({
|
|
226
|
-
logger, sessionNodeManager, loadedAgents, keyProviders, sharedSignaling, noSharedDirectoryNode,
|
|
227
|
-
verifiedManifestVersion, getPersistence, onSignalingConnected, resolveConsortiumRoster,
|
|
228
|
-
failoverEndpointResolver, getFailoverEndpoint, sealFailures, submissionRetries,
|
|
229
|
-
registerSealListeners, challengeVerifier, directoryEndpointResolver,
|
|
230
|
-
// Built ~1,200 lines BELOW this call, and only ever READ when a manager is constructed, which
|
|
231
|
-
// is later still. Getters because a by-value read here is a temporal-dead-zone crash at boot —
|
|
232
|
-
// both are `const`, so it fails loudly with the right name rather than going quiet. (The shape
|
|
233
|
-
// that goes quiet is `let x;`: still `undefined`, no error. That is unit 4's defect, and this
|
|
234
|
-
// is not it.)
|
|
235
|
-
getWirePerAgentSessionInbound: () => wirePerAgentSessionInbound,
|
|
236
|
-
getHandleTrustSignalPickup: () => handleTrustSignalPickup, getSweepTrustSignals: () => sweepTrustSignalsAndTick,
|
|
237
|
-
});
|
|
238
|
-
// CELLO-M7-CONN-001 (DOD-CONN-1, code-review HIGH): in PRODUCTION, bring up EACH loaded agent's OWN
|
|
239
|
-
// directory connection at startup. A registered agent must have a directory presence whenever the
|
|
240
|
-
// daemon runs — so the directory can route inbound session_assignment/seal to it (notably after a
|
|
241
|
-
// restart, where login does NOT auto-start agents), and `cello status` reflects directory_signaling
|
|
242
|
-
// as soon as the daemon is up. This replaces the pre-CONN-001 keystone (which connected only the
|
|
243
|
-
// loaded PRIMARY at startup) with a per-agent connection for EVERY loaded agent. Idempotent with the
|
|
244
|
-
// create/register/start connect (getAgentSignaling caches per agent).
|
|
245
|
-
// 040-DAEMONROOT unit 7 (phase 3): what the daemon remembers per IPC CONNECTION rather than per
|
|
246
|
-
// agent — the selection, the online sets, and the two read positions → boot-connection-state.ts.
|
|
247
|
-
const { perConnectionState, onlineAgents, explicitlyOfflineAgents, forgetConnection, getConnectionCursor, advanceConnectionCursor, safeCursorAdvance, safeWatermarkAdvance, } = startBootConnectionState({ sessionNodeManager });
|
|
248
|
-
/**
|
|
249
|
-
* DOD-M15-AWAYSCOPE-1 — the one answer to "is anyone attending this agent", wired once here.
|
|
250
|
-
*
|
|
251
|
-
* It lives in the composition root because it needs both halves and neither owns the other: the
|
|
252
|
-
* per-connection selections (an IPC-layer fact) and the operator's explicit offline switch.
|
|
253
|
-
* `offline` is checked FIRST — an agent taken down on purpose is not merely unwatched, and
|
|
254
|
-
* reporting it as `unattended` tells the counterparty their message will be read later, which is
|
|
255
|
-
* the opposite of what the switch means.
|
|
256
|
-
*/
|
|
257
|
-
const currentAttendance = (agentName) => explicitlyOfflineAgents.has(agentName)
|
|
258
|
-
? "offline"
|
|
259
|
-
: countAttendance(perConnectionState, agentName) > 0
|
|
260
|
-
? "attended"
|
|
261
|
-
: "unattended";
|
|
262
|
-
sessionNodeManager.setCurrentAttendanceSource(currentAttendance);
|
|
263
|
-
// 040-DAEMONROOT unit 6: attendance and the away reply → attendance-wiring.ts.
|
|
264
|
-
// DOD-M15-AWAYSCOPE-1 took the one-shot rejection out, and with it every seal dependency this
|
|
265
|
-
// wiring used to hold — it can no longer initiate a seal at all, which is the point.
|
|
266
|
-
const { attendanceCount, sendAwayResponse, backgroundSeals, awayAckSent } = createAttendanceWiring({ logger, sessionNodeManager, perConnectionState, securityGateway });
|
|
267
|
-
// DOD-INBOX-ONESHOT-1 enforces what the away reply promised, in its own file — merging it with the
|
|
268
|
-
// greeting is how both were deleted together. `sendClaims` is shared with cello_send.
|
|
269
|
-
const sendClaims = createSendClaims();
|
|
270
|
-
const { closeInboxIfIgnored } = createAwayInboxOneshot({ logger, sessionNodeManager, awayAckSent, sendClaims,
|
|
271
|
-
keyProviders, sealKey, sealInterruptedInProgress, pendingSealWaiters, pendingUnilateralWaiters, sendOver, handleActiveSealFlow });
|
|
272
|
-
// M8C-TGDOOR-1: the Telegram doorbell (telegram-doorbell.ts). Content-free by construction — the
|
|
273
|
-
// module is never handed message text, so it cannot leak any (DOD-INV-CONTENTFREE), and it has no
|
|
274
|
-
// session-send seam, so nothing from Telegram can enter a CELLO content path (D6).
|
|
275
|
-
const { sendTelegramDoorbell, clearTelegramRung, startTelegramPollerIfConfigured, stopTelegramPoller, } = createTelegramDoorbell({
|
|
276
|
-
logger,
|
|
277
|
-
getTelegramSettings: () => sessionNodeManager.getTelegramSettings(),
|
|
278
|
-
injectedClient: injectedTelegramBotClient,
|
|
279
|
-
});
|
|
280
|
-
// 040-DAEMONROOT unit 18: what to CALL a counterparty in a message an operator reads →
|
|
281
|
-
// who-resolver.ts.
|
|
282
|
-
const { resolveWho } = createWhoResolver({
|
|
283
|
-
logger, sessionNodeManager,
|
|
284
|
-
// Resolved at call time: the offer map is built below this, and a label is only ever rendered
|
|
285
|
-
// while serving a request.
|
|
286
|
-
getOfferedMoniker: (agentName, sessionIdHex) => offeredMonikers.get(offerKey(agentName, sessionIdHex)) ?? null,
|
|
287
|
-
});
|
|
288
|
-
// SYNC-P5: assigned when the document layer is wired (below); the state-change hook runs for
|
|
289
|
-
// sessions, which exist only after startup completes — the guard covers the boot window where
|
|
290
|
-
// agent restoration can dispatch state events before the scheduler exists.
|
|
291
|
-
let reconcileScheduler;
|
|
292
|
-
let documentOwnerKeyForHook;
|
|
293
|
-
// 040-DAEMONROOT unit 11: telling the operator a session changed, and staying quiet when the
|
|
294
|
-
// daemon's own delivery worker caused it → session-notify.ts.
|
|
295
|
-
const { deliveryOpens, pubkeyOfAgent, isDeliveryOpenInFlight, isDeliveryOpenToAgent, dispatchSessionStateChangedWithTelegram, } = createSessionNotify({
|
|
296
|
-
logger, loadedAgents, resolveWho, sendTelegramDoorbell, clearTelegramRung,
|
|
297
|
-
// GETTERS. The first two are `let`s ASSIGNED far below — the one shape that fails silently, and
|
|
298
|
-
// the shape unit 4 shipped. The other three are `const`s declared below, which would crash at
|
|
299
|
-
// boot; getters because they must be, not because getters are safer.
|
|
300
|
-
getNotificationDispatcher: () => notificationDispatcher,
|
|
301
|
-
getReconcileScheduler: () => reconcileScheduler,
|
|
302
|
-
getDocumentOwnerKeyFor: () => documentOwnerKeyForHook,
|
|
303
|
-
getOfferedMonikers: () => offeredMonikers,
|
|
304
|
-
getOfferKey: () => offerKey,
|
|
305
|
-
});
|
|
306
|
-
// SessionNodeManager was constructed + initialized at the top of startDaemon (PERSIST-002 — the
|
|
307
|
-
// encrypted store must open before agents load from the `agents` table). Its standing receiver +
|
|
308
|
-
// interrupted-session detection are already ready here, before the IPC socket opens.
|
|
309
|
-
// CELLO-M7-TRANSPORT-001: the daemon's runtime AutoNAT service is the one
|
|
310
|
-
// wrapping the standing receiver node (it emits transport.autonat.result /
|
|
311
|
-
// transport.autonat.unavailable and its dialability drives the SessionAssignment
|
|
312
|
-
// advertised address — AC-004/AC-019). config.autoNatService is an explicit
|
|
313
|
-
// override (tests); otherwise we use the standing receiver's, falling back to a
|
|
314
|
-
// stub only if the standing receiver failed to come up.
|
|
315
|
-
const autoNatService = config.autoNatService ??
|
|
316
|
-
sessionNodeManager.getStandingReceiverAutoNat() ??
|
|
317
|
-
new LocalAutoNatStub();
|
|
318
|
-
// The OUTBOUND session path (outbound-sessions.ts): discovery, the session request, and cross-node
|
|
319
|
-
// setup via a transient VISITING connection to the counterparty's home node.
|
|
320
|
-
const { openVisitingConnection, crossNodeBrokerBySession, resolvedSessionNegotiator, runDiscoveryLookup, sweepTrustSignalsAndTick, trustSignalSweepTicker } = createOutboundSessions({
|
|
321
|
-
logger,
|
|
322
|
-
sessionNodeManager,
|
|
323
|
-
getKeyProvider: (agentName) => keyProviders.get(agentName),
|
|
324
|
-
getPersistence,
|
|
325
|
-
getAgentSignaling: (agentName, kp, pubkeyHex) => getAgentSignaling(agentName, kp, pubkeyHex),
|
|
326
|
-
waitForSignalingConnected,
|
|
327
|
-
getFailoverEndpoint,
|
|
328
|
-
resolveConsortiumRoster,
|
|
329
|
-
registerSealListeners,
|
|
330
|
-
registerPickupListener,
|
|
331
|
-
sessionNegotiator,
|
|
332
|
-
challengeVerifier,
|
|
333
|
-
getManifestVersion: () => verifiedManifestVersion,
|
|
334
|
-
loadedAgents,
|
|
335
|
-
// DOD-M15-ERRSTRING-1: so a session failure can say "and 2 of your 5 directories are
|
|
336
|
-
// unreachable", which is very often the actual cause and was reported nowhere the operator
|
|
337
|
-
// was looking.
|
|
338
|
-
getUnresolvedNodes,
|
|
339
|
-
getDeclaredNodeCount, getOnlineAgents: () => onlineAgents,
|
|
340
|
-
// DOD-M15-SEALPARTIES-1: the visiting stream runs the seal ceremony too, so it needs the same
|
|
341
|
-
// failure sink — otherwise a cross-node close that dies leaves no trace while a same-node one does.
|
|
342
|
-
recordSealFailure: (name, sid, reason, kind) => sealFailures.record(name, sid, reason, new Date().toISOString(), kind),
|
|
343
|
-
});
|
|
344
|
-
// 040-DAEMONROOT unit 7 (phase 4): parked content and every path that gets it moving again — the
|
|
345
|
-
// retry queue, the park timers, the startup sweep and the flush → boot-parked-content.ts.
|
|
346
|
-
const { retryQueue, parkRetryTimers, flushAwaitingContent } = startBootParkedContent({
|
|
347
|
-
config, logger, sessionNodeManager, agents, keyProviders,
|
|
348
|
-
resolveConsortiumRoster, waitForSignalingConnected,
|
|
349
|
-
// Plain values: the outbound-session module is constructed 27 lines ABOVE this call. An
|
|
350
|
-
// earlier version passed getters and said the opposite in three places.
|
|
351
|
-
openVisitingConnection, crossNodeBrokerBySession,
|
|
352
|
-
});
|
|
353
|
-
// The inbound seal-interrupted REQUEST (inbound-seal-request.ts): the counterparty asks us to
|
|
354
|
-
// co-sign the seal of a session neither side can finish normally. We answer with our own signed
|
|
355
|
-
// leaf, or a rejection naming the exact mismatch — never a leaf we cannot corroborate.
|
|
356
|
-
const { handleInboundSealInterruptedRequest } = createInboundSealRequestHandler({
|
|
357
|
-
logger,
|
|
358
|
-
sessionNodeManager,
|
|
359
|
-
agents,
|
|
360
|
-
getKeyProvider: (agentName) => keyProviders.get(agentName),
|
|
361
|
-
sendOver,
|
|
362
|
-
recordFrontierMismatch: (agentName, sessionId, m) => frontierMismatches.record(agentName, sessionId, m, Date.now()),
|
|
363
|
-
clearFrontierMismatch: (agentName, sessionId) => frontierMismatches.clear(agentName, sessionId),
|
|
364
|
-
});
|
|
365
|
-
// ORDER IS LOAD-BEARING, in BOTH directions — and I got it wrong once already.
|
|
366
|
-
//
|
|
367
|
-
// The eager per-agent connect must run BEFORE `await flushAwaitingContent()`. That await does
|
|
368
|
-
// real relay network I/O for every parked item, sequentially. Put the connect loop after it and
|
|
369
|
-
// every agent's directory handshake is serialized behind the flush: on a daemon booting with
|
|
370
|
-
// parked content and a slow relay, `agent.online` is delayed by the whole drain and NOTHING in
|
|
371
|
-
// the log says the relay is the reason. Originally the two overlapped; they must keep doing so.
|
|
372
|
-
//
|
|
373
|
-
// But the loop's signaling wiring calls into the inbound-session module, which is a `const` now
|
|
374
|
-
// (it was a hoisted function declaration, which is what silently made the old ordering work). So
|
|
375
|
-
// the module is CONSTRUCTED here, immediately above the loop, rather than the loop being pushed
|
|
376
|
-
// down below the module. Construction is synchronous and its deps are all ready — the handlers
|
|
377
|
-
// it registers are fine this early because the handler map already exists.
|
|
378
|
-
// Seam 2: inbound session establishment — the counterparty side (inbound-sessions.ts).
|
|
379
|
-
const { registerHandlers: registerInboundSessionHandlers, wirePerAgentSessionInbound, handleTrustSignalPickup, enqueueInboundSession, recordRefusal, reapExpiredInboundSessions, inboundSessionQueues, inboundSessionWaiters, expiredSessionRequests, refusedSessionRequests, offeredMonikers, offerKey, } = createInboundSessions({
|
|
380
|
-
logger,
|
|
381
|
-
sessionNodeManager,
|
|
382
|
-
agents,
|
|
383
|
-
isExplicitlyOffline: (agentName) => explicitlyOfflineAgents.has(agentName),
|
|
384
|
-
// M12-P18: lets the responder send a refusal reason back to a TRUSTED sender.
|
|
385
|
-
sendOver,
|
|
386
|
-
getConnState: (connectionId) => perConnectionState.get(connectionId),
|
|
387
|
-
// 040-DAEMONROOT unit 10b: the selection rule lives in agent-selection-root.ts, constructed
|
|
388
|
-
// BELOW this consumer, and it is only ever called while serving a request.
|
|
389
|
-
resolveCurrentAgent: (connState, explicitAgent) => resolveCurrentAgent(connState, explicitAgent),
|
|
390
|
-
NO_CURRENT_AGENT_RESPONSE,
|
|
391
|
-
getKeyProvider: (agentName) => keyProviders.get(agentName),
|
|
392
|
-
sharedSignaling,
|
|
393
|
-
handleInboundSealInterruptedRequest,
|
|
394
|
-
// 040-DAEMONROOT unit 10: the reaper lives in session-views.ts, which is constructed BELOW this
|
|
395
|
-
// consumer. It is only ever called while serving a request, so it resolves at call time.
|
|
396
|
-
reapDeadHalfOpenSessions: (agentName) => reapDeadHalfOpenSessions(agentName),
|
|
397
|
-
sendAwayResponse,
|
|
398
|
-
dispatchSessionStateChangedWithTelegram,
|
|
399
|
-
sendTelegramDoorbell,
|
|
400
|
-
isDeliveryOpenToAgent, isChannelAgent: channelAgentLookup(sessionNodeManager, logger), // M16
|
|
401
|
-
});
|
|
402
|
-
if (!sharedSignaling) {
|
|
403
|
-
for (const agent of loadedAgents) {
|
|
404
|
-
getAgentSignaling(agent.name, agent.keyProvider, agent.pubkey);
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
await flushAwaitingContent();
|
|
408
|
-
const nonceDedupStore = new NonceDedupStore(sessionNodeManager.getDb(), logger);
|
|
409
|
-
nonceDedupStore.loadFromDb();
|
|
410
|
-
// 040-DAEMONROOT unit 12: the agent list from ONE connection's point of view → connection-agents.ts.
|
|
411
|
-
const { getAgentsForConnection } = createConnectionAgents({
|
|
412
|
-
agents, perConnectionState, onlineAgents, sessionNodeManager,
|
|
413
|
-
// A getter: the session views are constructed below this call, and the agent list is only ever
|
|
414
|
-
// built while serving a request.
|
|
415
|
-
agentStateFor: (a) => agentStateFor(a),
|
|
416
|
-
});
|
|
417
|
-
// 040-DAEMONROOT unit 10: the views the daemon builds of its own sessions and agents →
|
|
418
|
-
// session-views.ts. `getStatus` stays here, where its breadth is honest, and calls in.
|
|
419
|
-
const { buildInterruptedSessions, reapDeadHalfOpenSessions, buildActiveSessionsWithAttendance, agentStateFor, } = createSessionViews({
|
|
420
|
-
logger, sessionNodeManager, perConnectionState, onlineAgents, explicitlyOfflineAgents,
|
|
421
|
-
perAgentSignaling, sharedSignaling, frontierMismatches, sealKey, sealInterruptedInProgress,
|
|
422
|
-
pendingSealWaiters,
|
|
423
|
-
});
|
|
424
|
-
// 040-DAEMONROOT unit 17: the whole-daemon status the CLI renders → daemon-status-report.ts.
|
|
425
|
-
const { getStatus } = createDaemonStatusReport({
|
|
426
|
-
sessionNodeManager, retryQueue, agents, agentStateFor, buildInterruptedSessions,
|
|
427
|
-
buildActiveSessions: buildActiveSessionsWithAttendance, directorySignalingStatus, manifestOrigin,
|
|
428
|
-
// Resolved at call time: the report it produces is built below this, and a status is only ever
|
|
429
|
-
// rendered later. By value it would be undefined and every status would silently omit the block
|
|
430
|
-
// that says a directory node could not be resolved.
|
|
431
|
-
unresolvedNodesForStatus: () => unresolvedNodesForStatus(),
|
|
432
|
-
manifestProvider, directoryHttpUrl, challengeVerifier, enforcedConsortium,
|
|
433
|
-
});
|
|
434
|
-
// Register IPC handlers
|
|
435
|
-
const handlers = new Map();
|
|
436
|
-
handlers.set("status", async (_params, _connectionId) => {
|
|
437
|
-
return getStatus();
|
|
438
|
-
});
|
|
439
|
-
// ─── MCP-001: ipc.connect handler ───
|
|
440
|
-
// Registers the connection's clientType and returns the connectionId.
|
|
441
|
-
handlers.set("ipc.connect", async (params, connectionId) => {
|
|
442
|
-
const clientType = params?.clientType ?? "cli";
|
|
443
|
-
perConnectionState.set(connectionId, { currentAgent: null, clientType });
|
|
444
|
-
// MCP-002: Register connection with notification dispatcher
|
|
445
|
-
notificationDispatcher.registerConnection(connectionId);
|
|
446
|
-
// Re-log with correct clientType (overrides the default "cli" from handleConnection)
|
|
447
|
-
logger.info("daemon.ipc.connected", { connectionId, clientType });
|
|
448
|
-
return { connectionId };
|
|
449
|
-
});
|
|
450
|
-
// 040-DAEMONROOT unit 10c: bringing an agent online, and reporting whether it can be REACHED →
|
|
451
|
-
// start-agent.ts.
|
|
452
|
-
const { startAgentInternal } = createStartAgent({
|
|
453
|
-
logger, sessionNodeManager, agents, onlineAgents, explicitlyOfflineAgents, keyProviders,
|
|
454
|
-
getAgentSignaling, autoRecoverForAgent, flushAwaitingContent,
|
|
455
|
-
// A GETTER: the dispatcher is built ~575 lines below and is only touched when an agent is
|
|
456
|
-
// actually started, which is always later.
|
|
457
|
-
getNotificationDispatcher: () => notificationDispatcher,
|
|
458
|
-
});
|
|
459
|
-
// 040-DAEMONROOT unit 10b: which agent a call is for, and what to tell an operator whose agent is
|
|
460
|
-
// not registered → agent-selection-root.ts.
|
|
461
|
-
const { fallbackNoticeStore, resolveCurrentAgent } = createAgentSelection({ logger, onlineAgents });
|
|
462
|
-
// Agent lifecycle (agent-handlers.ts): create, remove, start, stop, select, list.
|
|
463
|
-
registerAgentHandlers({
|
|
464
|
-
handlers,
|
|
465
|
-
logger,
|
|
466
|
-
sessionNodeManager,
|
|
467
|
-
agents,
|
|
468
|
-
onlineAgents,
|
|
469
|
-
explicitlyOfflineAgents,
|
|
470
|
-
getNotificationDispatcher: () => notificationDispatcher,
|
|
471
|
-
getConnState: (connectionId) => perConnectionState.get(connectionId),
|
|
472
|
-
perConnectionState,
|
|
473
|
-
getAgentsForConnection,
|
|
474
|
-
startAgentInternal,
|
|
475
|
-
dropAgentSignaling, stopSweepTick: (n) => trustSignalSweepTicker.stop(n),
|
|
476
|
-
awayAckSent,
|
|
477
|
-
keyProviders,
|
|
478
|
-
loadedAgents,
|
|
479
|
-
getAgentSignaling,
|
|
480
|
-
waitForSignalingConnected,
|
|
481
|
-
perAgentSignaling,
|
|
482
|
-
});
|
|
483
|
-
// 040-DAEMONROOT unit 19: what the daemon says when a call cannot proceed → operator-guidance.ts.
|
|
484
|
-
// cello_register (register-handler.ts): T-of-N DKG with the consortium. NO SINGLE NODE can
|
|
485
|
-
// complete it alone — that is the sovereign-node invariant, and it is the point of the protocol.
|
|
486
|
-
registerRegisterHandler({
|
|
487
|
-
handlers,
|
|
488
|
-
logger,
|
|
489
|
-
keyProviders,
|
|
490
|
-
getPersistence,
|
|
491
|
-
getAgentSignaling,
|
|
492
|
-
waitForSignalingConnected,
|
|
493
|
-
dropAgentSignaling,
|
|
494
|
-
startAgentInternal,
|
|
495
|
-
directoryEndpointResolver,
|
|
496
|
-
loadedAgents,
|
|
497
|
-
registrationGuidance,
|
|
498
|
-
manifestProvider,
|
|
499
|
-
});
|
|
500
|
-
// 040-DAEMONROOT unit 3: share rotation and relay receipts → agent-admin-handlers.ts.
|
|
501
|
-
registerAgentAdminHandlers({
|
|
502
|
-
handlers, logger, sessionNodeManager, loadedAgents,
|
|
503
|
-
getConnState: (connectionId) => perConnectionState.get(connectionId),
|
|
504
|
-
resolveCurrentAgent, getPersistence, getAgentSignaling, waitForSignalingConnected,
|
|
505
|
-
resolveConsortiumRoster, getFailoverEndpoint, sealFailures,
|
|
506
|
-
});
|
|
507
|
-
// ─── Trust-signal wallet (operator-facing, no agent scope required) ───
|
|
508
|
-
// 040-DAEMONROOT unit 1: the trust-signal, attestation and consent handlers moved to
|
|
509
|
-
// signal-handlers.ts, with the two helpers only they used. What stays here is the wiring.
|
|
510
|
-
registerSignalHandlers({
|
|
511
|
-
handlers,
|
|
512
|
-
logger,
|
|
513
|
-
sessionNodeManager,
|
|
514
|
-
keyProviders,
|
|
515
|
-
onlineAgents,
|
|
516
|
-
loadedAgents,
|
|
517
|
-
getConnState: (connectionId) => perConnectionState.get(connectionId),
|
|
518
|
-
getAgentSignaling,
|
|
519
|
-
openVisitingConnection,
|
|
520
|
-
waitForSignalingConnected,
|
|
521
|
-
resolveConsortiumRoster,
|
|
522
|
-
verifiedManifest,
|
|
523
|
-
submissionRetries,
|
|
524
|
-
recordIssuedSubmission,
|
|
525
|
-
});
|
|
526
|
-
// 040-DAEMONROOT unit 14: the directory-reachability block a status read carries, and the rule for
|
|
527
|
-
// when it says nothing → unresolved-nodes-report.ts.
|
|
528
|
-
const { unresolvedNodesForStatus } = createUnresolvedNodesReport({
|
|
529
|
-
getUnresolvedNodes, getUnresolvedSweptAt, lastRosterSweepError,
|
|
530
|
-
manifestConfigured: manifestProvider !== undefined,
|
|
531
|
-
});
|
|
532
|
-
// `unresolvedNodesForStatus` is a module rather than a closure because it has TWO consumers:
|
|
533
|
-
// this handler and the daemon-wide getStatus() the CLI renders.
|
|
534
|
-
registerStatusHandler({
|
|
535
|
-
handlers, getAgentsForConnection, directorySignalingStatus, manifestOrigin, manifestProvider,
|
|
536
|
-
directoryHttpUrl, challengeVerifier, unresolvedNodesForStatus, buildInterruptedSessions, buildActiveSessions: buildActiveSessionsWithAttendance,
|
|
537
|
-
enforcedConsortium,
|
|
538
|
-
});
|
|
539
|
-
// ─── MCP-001: no_current_agent guard for session tools ───
|
|
540
|
-
// cello_send / cello_receive are NOT in this stub list — DAEMON-004 registers
|
|
541
|
-
// real handlers for them below (each enforces the no_current_agent guard inline).
|
|
542
|
-
// NOTE: cello_await_session is NOT in this stub list — Seam 2 registers a real
|
|
543
|
-
// handler for it below (inbound session establishment), with its own inline
|
|
544
|
-
// no_current_agent guard.
|
|
545
|
-
// The list below is an (empty) extension point: a tool that needs only the plain no_current_agent
|
|
546
|
-
// guard, with no handler of its own, is registered here.
|
|
547
|
-
//
|
|
548
|
-
// Do not add an "accept" or "join" tool — CELLO has no such step. Inbound sessions are
|
|
549
|
-
// auto-accepted by the standing receiver.
|
|
550
|
-
const SESSION_TOOLS_REQUIRING_AGENT = [];
|
|
551
|
-
for (const tool of SESSION_TOOLS_REQUIRING_AGENT) {
|
|
552
|
-
handlers.set(tool, async (_params, connectionId) => {
|
|
553
|
-
const connState = perConnectionState.get(connectionId);
|
|
554
|
-
if (!connState || !connState.currentAgent) {
|
|
555
|
-
return NO_CURRENT_AGENT_RESPONSE;
|
|
556
|
-
}
|
|
557
|
-
// Stub: actual session tool routing will be implemented in DAEMON-002/SIGNAL-001
|
|
558
|
-
return { ok: false, reason: "not_implemented", guidance: `Session tool '${tool}' routing is not yet implemented in the daemon. This will be available after the session node manager is wired to the IPC layer.` };
|
|
559
|
-
});
|
|
560
|
-
}
|
|
561
|
-
// cello_initiate_session (initiate-session-handler.ts). The relay witness is BEST-EFFORT: a
|
|
562
|
-
// session with no relay still runs on the direct content path. Degraded, never blocked.
|
|
563
|
-
const { openSessionFor } = registerInitiateSessionHandler({
|
|
564
|
-
handlers,
|
|
565
|
-
logger,
|
|
566
|
-
sessionNodeManager,
|
|
567
|
-
// SYNC-P5 (R39, review F5): the INITIATOR-side reachable trigger — the inbound side fires
|
|
568
|
-
// from the session-state dispatch; without this half, only the answering daemon reconciled
|
|
569
|
-
// on session-up and the initiator waited out a sweep interval.
|
|
570
|
-
onSessionOpened: (agentName, counterpartyPubkey) => {
|
|
571
|
-
if (!reconcileScheduler || !documentOwnerKeyForHook)
|
|
572
|
-
return;
|
|
573
|
-
// DOD-M12B-DELIVERY-QUIET-1: the INITIATOR half of the same circularity. This hook fires
|
|
574
|
-
// inside openSessionAs, which the delivery worker's adapter brackets with begin/release — so
|
|
575
|
-
// the intent is still in flight here and the check needs no plumbing of its own. Resetting
|
|
576
|
-
// the backoff on a session WE opened to deliver a frame wipes a refusal the peer may have
|
|
577
|
-
// given seconds ago and immediately sweeps every document, which opens more sessions.
|
|
578
|
-
// We are the OPENER here, so our own pubkey goes first — the mirror of the inbound half above.
|
|
579
|
-
if (isDeliveryOpenInFlight(pubkeyOfAgent(agentName), counterpartyPubkey)) {
|
|
580
|
-
logger.debug("document.reconcile.reachable_trigger_skipped", {
|
|
581
|
-
agentName, reason: "session_opened_by_document_delivery",
|
|
582
|
-
});
|
|
583
|
-
return;
|
|
584
|
-
}
|
|
585
|
-
const ownerAgentId = documentOwnerKeyForHook(agentName);
|
|
586
|
-
if (ownerAgentId === null)
|
|
587
|
-
return;
|
|
588
|
-
logger.info("document.reconcile.reachable_trigger_fired", {
|
|
589
|
-
agentName, trigger: "outbound_session_opened", peer: counterpartyPubkey.slice(0, 16),
|
|
590
|
-
});
|
|
591
|
-
void reconcileScheduler
|
|
592
|
-
.onReachable(ownerAgentId, counterpartyPubkey.toLowerCase())
|
|
593
|
-
.catch((err) => {
|
|
594
|
-
logger.warn("document.reconcile.reachable_trigger_failed", {
|
|
595
|
-
agentName, reason: extractErrorMessage(err),
|
|
596
|
-
});
|
|
597
|
-
});
|
|
598
|
-
},
|
|
599
|
-
getConnState: (connectionId) => perConnectionState.get(connectionId),
|
|
600
|
-
resolveCurrentAgent,
|
|
601
|
-
NO_CURRENT_AGENT_RESPONSE,
|
|
602
|
-
resolvedSessionNegotiator,
|
|
603
|
-
transportSelector,
|
|
604
|
-
autoNatService,
|
|
605
|
-
buildRelayConnectParams,
|
|
606
|
-
getRelayCircuitAddress, isChannelAgent: channelAgentLookup(sessionNodeManager, logger), // M16
|
|
607
|
-
});
|
|
608
|
-
// cello_close_session (close-session-handler.ts). Fifteen dependencies — a long list, but a KNOWN
|
|
609
|
-
// one, which is the whole difference from a closure over 73 shared locals.
|
|
610
|
-
registerCloseSessionHandler({
|
|
611
|
-
// DOD-M15-CLOSEWAIT-1 review MEDIUM-6: a detached seal tail is registered here so stop() can
|
|
612
|
-
// drain it, like every other background worker. Self-evicting, so a long-running daemon does not
|
|
613
|
-
// accumulate settled promises.
|
|
614
|
-
sealFailures,
|
|
615
|
-
registerBackgroundSeal: (p) => {
|
|
616
|
-
backgroundSeals.add(p);
|
|
617
|
-
void p.finally(() => backgroundSeals.delete(p));
|
|
618
|
-
},
|
|
619
|
-
// M12-P14: the pre-seal readiness gate drains the parked mailbox before judging, so a close
|
|
620
|
-
// does not refuse over content the relay is still holding for us.
|
|
621
|
-
recoverParkedContent: (agentName, trigger) => autoRecoverForAgent(agentName, trigger),
|
|
622
|
-
// DOD-TERMINAL-STATE-DIVERGENCE-1: the same pull `cello_sealed_receipt` uses, now also available
|
|
623
|
-
// to the close — which is where the operator actually gets stranded.
|
|
624
|
-
pullSealCertificate: (agentName, sessionIdHex) => pullSealCertificate({
|
|
625
|
-
logger,
|
|
626
|
-
sessionNodeManager,
|
|
627
|
-
signalingFor,
|
|
628
|
-
sendOver,
|
|
629
|
-
getPersistence,
|
|
630
|
-
getAgentPubkeyHex: (name) => loadedAgents.find((a) => a.name === name)?.pubkey,
|
|
631
|
-
}, agentName, sessionIdHex),
|
|
632
|
-
handlers,
|
|
633
|
-
logger,
|
|
634
|
-
sessionNodeManager,
|
|
635
|
-
getConnState: (connectionId) => perConnectionState.get(connectionId),
|
|
636
|
-
resolveCurrentAgent,
|
|
637
|
-
NO_CURRENT_AGENT_RESPONSE,
|
|
638
|
-
getKeyProvider: (agentName) => keyProviders.get(agentName),
|
|
639
|
-
signalingFor,
|
|
640
|
-
sendOver,
|
|
641
|
-
waitForSignalingConnected,
|
|
642
|
-
openVisitingConnection,
|
|
643
|
-
// The seal path's fallback when crossNodeBrokerBySession is empty — which it is after every
|
|
644
|
-
// restart, and a restart is what makes a session interrupted. Without this wired the handler
|
|
645
|
-
// silently keeps the pre-0.0.141 behaviour and its unit tests still pass, because they inject it.
|
|
646
|
-
runDiscoveryLookup,
|
|
647
|
-
crossNodeBrokerBySession,
|
|
648
|
-
sealKey,
|
|
649
|
-
sealInterruptedInProgress,
|
|
650
|
-
pendingSealWaiters,
|
|
651
|
-
pendingUnilateralWaiters,
|
|
652
|
-
handleSealInterruptedFlow,
|
|
653
|
-
handleActiveSealFlow,
|
|
654
|
-
resolveConsortiumRoster,
|
|
655
|
-
});
|
|
656
|
-
// 040-DAEMONROOT unit 3: backup and restore → backup-restore-handlers.ts.
|
|
657
|
-
registerBackupRestoreHandlers({ handlers, logger, celloDir });
|
|
658
|
-
// DOD-M15-INCLUSION-1: prove one message sits under the certified root, and check such a proof.
|
|
659
|
-
//
|
|
660
|
-
// This replaces the last entry of the MCP-001 `not_implemented` stub loop, which by the end held
|
|
661
|
-
// exactly one tool — `cello_get_inclusion_proof` — so the loop goes with it rather than being left
|
|
662
|
-
// as an empty scaffold that reads like other tools are still pending.
|
|
663
|
-
registerInclusionProofHandlers({
|
|
664
|
-
handlers,
|
|
665
|
-
logger,
|
|
666
|
-
sessionNodeManager,
|
|
667
|
-
getConnState: (connectionId) => perConnectionState.get(connectionId),
|
|
668
|
-
resolveCurrentAgent,
|
|
669
|
-
NO_CURRENT_AGENT_RESPONSE,
|
|
670
|
-
});
|
|
671
|
-
// DOD-M9B-SURFACE-1: the security layer's control surface. Registered here, defined in its own
|
|
672
|
-
// module — it needs the cello dir, a logger, and the connection's client type, and nothing else
|
|
673
|
-
// about sessions or ceremonies.
|
|
674
|
-
const disposeGatewayConfigStores = registerGatewayConfigHandlers({
|
|
675
|
-
handlers,
|
|
676
|
-
celloDir,
|
|
677
|
-
logger,
|
|
678
|
-
getClientType: (connectionId) => perConnectionState.get(connectionId)?.clientType,
|
|
679
|
-
...(config.restartSecurityGateway ? { restartSecurityGateway: config.restartSecurityGateway } : {}),
|
|
680
|
-
});
|
|
681
|
-
// The session READ surface (session-read-handlers.ts): sealed receipt, transcript, list, name.
|
|
682
|
-
// All four read the PERSISTED store, so they survive a restart and a fresh connection.
|
|
683
|
-
registerSessionReadHandlers({
|
|
684
|
-
handlers,
|
|
685
|
-
logger,
|
|
686
|
-
sessionNodeManager,
|
|
687
|
-
loadedAgents,
|
|
688
|
-
// DOD-M15-CLOSEWAIT-1 HIGH-2: the SAME predicate cello_status uses, so the two surfaces cannot
|
|
689
|
-
// disagree. Both maps — pendingSealWaiters is the active close, the other the interrupted one.
|
|
690
|
-
isSealing: (agentName, sessionId) => pendingSealWaiters.has(sealKey(agentName, sessionId)) ||
|
|
691
|
-
sealInterruptedInProgress.has(sealKey(agentName, sessionId)),
|
|
692
|
-
// DOD-M15-SEAL-FAILED-TERMINAL-1: the SAME store the close handler writes, so a failure recorded
|
|
693
|
-
// by the detached tail is the one the receipt surface reads.
|
|
694
|
-
getSealFailure: (agentName, sessionId) => sealFailures.get(agentName, sessionId),
|
|
695
|
-
getConnState: (connectionId) => perConnectionState.get(connectionId),
|
|
696
|
-
resolveCurrentAgent,
|
|
697
|
-
NO_CURRENT_AGENT_RESPONSE,
|
|
698
|
-
resolveWho,
|
|
699
|
-
safeCursorAdvance,
|
|
700
|
-
safeWatermarkAdvance,
|
|
701
|
-
reapDeadHalfOpenSessions,
|
|
702
|
-
frontierMismatches,
|
|
703
|
-
attendanceCount,
|
|
704
|
-
// DOD-TERMINAL-STATE-DIVERGENCE-1: the pull twin of the session_sealed push. Wired HERE, at the
|
|
705
|
-
// composition root, because it needs the agent's own signaling stream and its persistence — the
|
|
706
|
-
// read handlers hold neither, and giving them the whole daemon to reach one function is how a
|
|
707
|
-
// read surface acquires a network dependency nobody expects.
|
|
708
|
-
pullSealCertificate: (agentName, sessionIdHex) => pullSealCertificate({
|
|
709
|
-
logger,
|
|
710
|
-
sessionNodeManager,
|
|
711
|
-
signalingFor,
|
|
712
|
-
sendOver,
|
|
713
|
-
getPersistence,
|
|
714
|
-
getAgentPubkeyHex: (name) => loadedAgents.find((a) => a.name === name)?.pubkey,
|
|
715
|
-
}, agentName, sessionIdHex),
|
|
716
|
-
});
|
|
717
|
-
// 040-DAEMONROOT unit 2: the test-support verbs moved to test-handlers.ts. The two production
|
|
718
|
-
// registrations that sat between them stay here — they are real surfaces, not test scaffolding.
|
|
719
|
-
registerTestHandlers({
|
|
720
|
-
handlers,
|
|
721
|
-
logger,
|
|
722
|
-
sessionNodeManager,
|
|
723
|
-
retryQueue,
|
|
724
|
-
nonceDedupStore,
|
|
725
|
-
deliveryOpens,
|
|
726
|
-
pubkeyOfAgent,
|
|
727
|
-
dispatchSessionStateChangedWithTelegram,
|
|
728
|
-
enqueueInboundSession,
|
|
729
|
-
recordRefusal,
|
|
730
|
-
inboundSessionQueues,
|
|
731
|
-
getConnState: (connectionId) => perConnectionState.get(connectionId),
|
|
732
|
-
});
|
|
733
|
-
contentPark.registerHandlers(handlers);
|
|
734
|
-
registerInboundSessionHandlers(handlers);
|
|
735
|
-
// CELLO-M7-CONN-001 (DOD-CONN-2): the inbound seal_interrupted_request responder is now
|
|
736
|
-
// wired PER-AGENT (wirePerAgentSessionInbound, below) onto each agent's own signaling
|
|
737
|
-
// manager — not once on the keystone — so every agent (not just the primary) receives it
|
|
738
|
-
// on its own authenticated stream.
|
|
739
|
-
// cello_send + cello_receive — the content path (session-content-handlers.ts). Two halves of one
|
|
740
|
-
// state machine (the read cursor: send writes the tree, receive advances the cursor + watermark),
|
|
741
|
-
// so they move together.
|
|
742
|
-
registerSessionContentHandlers({
|
|
743
|
-
handlers,
|
|
744
|
-
logger,
|
|
745
|
-
sessionNodeManager,
|
|
746
|
-
securityGateway,
|
|
747
|
-
retryQueue,
|
|
748
|
-
sendClaims,
|
|
749
|
-
getConnState: (connectionId) => perConnectionState.get(connectionId),
|
|
750
|
-
resolveCurrentAgent,
|
|
751
|
-
NO_CURRENT_AGENT_RESPONSE,
|
|
752
|
-
getConnectionCursor,
|
|
753
|
-
advanceConnectionCursor,
|
|
754
|
-
clearTelegramRung,
|
|
755
|
-
attendanceCount,
|
|
756
|
-
});
|
|
757
|
-
// cello_check_notifications (notification-handlers.ts): the push-loss reconciler. Notifications are
|
|
758
|
-
// fire-and-forget, so a client that was away can miss one entirely — this is how it finds out, by
|
|
759
|
-
// ASKING from persisted state rather than trusting that a push arrived.
|
|
760
|
-
registerNotificationHandlers({
|
|
761
|
-
handlers,
|
|
762
|
-
logger,
|
|
763
|
-
sessionNodeManager,
|
|
764
|
-
getConnState: (connectionId) => perConnectionState.get(connectionId),
|
|
765
|
-
resolveCurrentAgent,
|
|
766
|
-
loadedAgents,
|
|
767
|
-
agents,
|
|
768
|
-
reapExpiredInboundSessions,
|
|
769
|
-
inboundSessionQueues,
|
|
770
|
-
expiredSessionRequests,
|
|
771
|
-
refusedSessionRequests,
|
|
772
|
-
// §16.5's passive notification, wired 2026-08-08. Both halves existed with no production caller
|
|
773
|
-
// — nothing wrote a notice and nothing read one — so an agent learned a document had changed
|
|
774
|
-
// only by polling, and `cello_doc_read` cleared rows that could never exist.
|
|
775
|
-
// 074-DOCSFLAG: OMITTED with documents off, not passed-and-guarded — `documentSection` already
|
|
776
|
-
// returns `{}` for an absent dep, so the inbox carries no document key at all, the shape it had
|
|
777
|
-
// before the layer existed. A callback returning `[]` would say the same thing twice.
|
|
778
|
-
...(documentsEnabled()
|
|
779
|
-
? { documentNotices: (ownerAgentId) => documentLayer.notifications.pending(ownerAgentId) }
|
|
780
|
-
: {}),
|
|
781
|
-
ownerKeyFor: (agentName) => loadedAgents.find((a) => a.name === agentName)?.pubkey?.toLowerCase() ?? null,
|
|
782
|
-
});
|
|
783
|
-
// The address book — contacts, tiers, monikers, settings, the telegram token. Ten handlers, now
|
|
784
|
-
// in contact-handlers.ts. Extracting them showed the address book closes over almost nothing: it
|
|
785
|
-
// needs the session store, this connection's agent selection, a logger, and one callback to
|
|
786
|
-
// restart the telegram poller. Nothing about sessions, seals, transport or ceremonies.
|
|
787
|
-
registerContactHandlers({
|
|
788
|
-
handlers,
|
|
789
|
-
sessionNodeManager,
|
|
790
|
-
getConnState: (connectionId) => perConnectionState.get(connectionId),
|
|
791
|
-
resolveCurrentAgent,
|
|
792
|
-
agents,
|
|
793
|
-
// cello_set_moniker was the one address-book handler reaching past the store for the raw SQLite
|
|
794
|
-
// handle. Same construction, same behavior — the daemon owns the DB, so the daemon builds it.
|
|
795
|
-
setAgentMoniker: (agentName, moniker) => new DbIdentityStore(sessionNodeManager.getDb(), logger).setMoniker(agentName, moniker),
|
|
796
|
-
logger,
|
|
797
|
-
startTelegramPollerIfConfigured,
|
|
798
|
-
});
|
|
799
|
-
// 040-DAEMONROOT unit 16: the handler map as the IPC server sees it, and the server itself →
|
|
800
|
-
// ipc-surface.ts.
|
|
801
|
-
const { ipcServer } = createIpcSurface({
|
|
802
|
-
logger, socketPath, maxConnections, handlers, perConnectionState, fallbackNoticeStore,
|
|
803
|
-
// A GETTER: `stop` is defined below this surface and the `shutdown` verb calls it.
|
|
804
|
-
getStop: () => stop,
|
|
805
|
-
});
|
|
806
|
-
// THE SOCKET OPENS LAST — see the deferred start below. Accepting clients here would accept
|
|
807
|
-
// `cello_start_agent`, which brings an agent online, creates its standing receiver, and drains
|
|
808
|
-
// parked content — all of it arriving before the document frame hook exists.
|
|
809
|
-
// MCP-002: Instantiate NotificationDispatcher (wired to IPC server)
|
|
810
|
-
const notificationDispatcher = new NotificationDispatcher({
|
|
811
|
-
logger,
|
|
812
|
-
sendNotification: (connectionId, notification) => ipcServer.sendNotification(connectionId, notification),
|
|
813
|
-
getConnectionIds: () => ipcServer.getConnectionIds(),
|
|
814
|
-
});
|
|
815
|
-
// M7-SESSION-001 (M-1 PUSH): now that the dispatcher exists, wire the session
|
|
816
|
-
// node manager so that an active→interrupted transition pushes a
|
|
817
|
-
// session_state_changed notification to live MCP clients. Setter injection is
|
|
818
|
-
// used because the dispatcher is constructed AFTER the SessionNodeManager
|
|
819
|
-
// (it depends on the IPC server), so constructor injection would be circular.
|
|
820
|
-
sessionNodeManager.setOnSessionStateChanged((agentName, sessionId, state, counterpartyPubkey) => {
|
|
821
|
-
dispatchSessionStateChangedWithTelegram(agentName, sessionId, state, counterpartyPubkey);
|
|
822
|
-
});
|
|
823
|
-
// M8C-MSGWAKE-1 (channel stage 2): per-message wake — a verified inbound message fires a
|
|
824
|
-
// content-free `cello_message` doorbell to the current-agent connection(s). The shim's generic
|
|
825
|
-
// bridge (WAKE) forwards it to a live --channels session as notifications/claude/channel.
|
|
826
|
-
sessionNodeManager.setOnContentArrived((agentName, sessionId, senderPubkey) => {
|
|
827
|
-
// MONIKER-4 AC2: the message doorbell names the sender the same way the session doorbell does.
|
|
828
|
-
notificationDispatcher.dispatchCelloMessage(agentName, sessionId, senderPubkey, resolveWho(agentName, senderPubkey, sessionId));
|
|
829
|
-
// DOD-M15-AWAYSCOPE-1 — THE AWAY GREETING FIRED HERE and took a leaf no seal could certify; it is
|
|
830
|
-
// NOT coming back. DOD-INBOX-ONESHOT-1 is the half deleted with it. See away-inbox-oneshot.ts.
|
|
831
|
-
void closeInboxIfIgnored(agentName, sessionId);
|
|
832
|
-
// M8C-TGDOOR-1: message-waiting — coalesced (ring-once-until-read) inside sendTelegramDoorbell.
|
|
833
|
-
void sendTelegramDoorbell(agentName, sessionId, "message_waiting", "New message waiting");
|
|
834
|
-
});
|
|
835
|
-
// 074-DOCSFLAG: the document layer exists in this process, or it does not → document-gate-wiring.ts.
|
|
836
|
-
// ONE value, default off, gating CONSTRUCTION — with it off the fourteen IPC verbs are never
|
|
837
|
-
// registered and the sweep timer is never created. That module carries the reasoning.
|
|
838
|
-
const { documentLayer, reconcileSweepTimer, reconcileScheduler: builtReconcileScheduler, documentOwnerKeyFor, } = wireDocumentGate({
|
|
839
|
-
logger, sessionNodeManager, loadedAgents, keyProviders,
|
|
840
|
-
securityGateway, celloDir: config.celloDir,
|
|
841
|
-
deliveryOpens, pubkeyOfAgent, openSessionFor, perAgentSignaling, runDiscoveryLookup,
|
|
842
|
-
getReconcileScheduler: () => reconcileScheduler,
|
|
843
|
-
notificationDispatcher,
|
|
844
|
-
getCloseSessionHandler: () => handlers.get("cello_close_session"),
|
|
845
|
-
handlers, perConnectionState, resolveCurrentAgent,
|
|
846
|
-
});
|
|
847
|
-
// The scheduler is produced by the surface and assigned back here, because two modules built
|
|
848
|
-
// EARLIER hold getters over this binding. They read at call time, which is always after this.
|
|
849
|
-
reconcileScheduler = builtReconcileScheduler;
|
|
850
|
-
documentOwnerKeyForHook = documentOwnerKeyFor;
|
|
851
|
-
// ── THE SOCKET OPENS ONLY NOW, and the ordering is load-bearing (2026-08-16). ──
|
|
852
|
-
//
|
|
853
|
-
// This used to run ~120 lines earlier, immediately after the server was created — before
|
|
854
|
-
// `setOnDocumentFrame` above. That opened a window on every daemon start: a client connects,
|
|
855
|
-
// calls `cello_start_agent`, the agent comes online, its standing receiver drains whatever the
|
|
856
|
-
// relay parked — and any DOCUMENT frame in that drain found `#onDocumentFrame` still unset. The
|
|
857
|
-
// routing fork in session-node-manager treats an unconsumed frame as conversation, so those
|
|
858
|
-
// frames were appended as `msg` leaves, written to the durable transcript, rang the doorbell,
|
|
859
|
-
// and were handed to the agent by `cello_receive` as raw canonical CBOR.
|
|
860
|
-
//
|
|
861
|
-
// Reported from the live fleet by a counterparty who pasted the bytes back
|
|
862
|
-
// (`dtyperdocument_reconcile…`), reproduced in `j-stale-session.spine.test.ts`, and it is why
|
|
863
|
-
// documents accumulated unaccepted: the frames were not lost in transit, they were EATEN as
|
|
864
|
-
// messages, so the document layer never saw them while the sender was told they were delivered.
|
|
865
|
-
//
|
|
866
|
-
// The comment at that fork claimed an unwired hook "cannot change the conversation path". It
|
|
867
|
-
// can, and did. Nothing between here and the server's creation needs a live socket, so the
|
|
868
|
-
// honest fix is to finish wiring before anyone can knock.
|
|
869
|
-
try {
|
|
870
|
-
await ipcServer.start();
|
|
871
|
-
}
|
|
872
|
-
catch (err) {
|
|
873
|
-
// As above: startDaemon's catch releases the singleton lock for us.
|
|
874
|
-
await removeLockIfOwned(lockFilePath, process.pid, logger);
|
|
875
|
-
throw err;
|
|
876
|
-
}
|
|
877
|
-
// 040-DAEMONROOT unit 20: what the daemon forgets, and what it says, when a connection closes →
|
|
878
|
-
// disconnect-cleanup.ts.
|
|
879
|
-
wireDisconnectCleanup({
|
|
880
|
-
ipcServer,
|
|
881
|
-
getConnState: (connectionId) => perConnectionState.get(connectionId),
|
|
882
|
-
countAttendanceFor: (agentName) => countAttendance(perConnectionState, agentName),
|
|
883
|
-
forgetConnection,
|
|
884
|
-
announceAttendance: (agentName, attendance) => sessionNodeManager.announceAttendance(agentName, attendance),
|
|
885
|
-
inboundSessionWaiters,
|
|
886
|
-
// A GETTER, though the dispatcher is a const 82 lines ABOVE — so that moving its construction
|
|
887
|
-
// below this line cannot break the disconnect path silently. Reason in full at the dep.
|
|
888
|
-
getNotificationDispatcher: () => notificationDispatcher,
|
|
889
|
-
});
|
|
890
|
-
// Log daemon.login.validation.complete (stub — all unverified until SIGNAL-001)
|
|
891
|
-
logger.info("daemon.login.validation.complete", {
|
|
892
|
-
verifiedCount: 0,
|
|
893
|
-
staleCount: 0,
|
|
894
|
-
goneCount: 0,
|
|
895
|
-
});
|
|
896
|
-
// DOD-M15-CONSORTIUM-FINGERPRINT-1 — which consortium this binary can accept; see its header.
|
|
897
|
-
logConsortiumAnchor(logger, enforcedConsortium);
|
|
898
|
-
// Log daemon.started
|
|
899
|
-
logger.info("daemon.started", {
|
|
900
|
-
pid: process.pid,
|
|
901
|
-
ipcSocketPath: socketPath,
|
|
902
|
-
agentCount: loadedAgents.length,
|
|
903
|
-
manifestVerified,
|
|
904
|
-
});
|
|
905
|
-
// CELLO-M7-CONN-001 (DOD-CONN-3): background manifest polling runs daemon-level over
|
|
906
|
-
// unauthenticated HTTP (startHttpManifestPoll above), NOT over a signaling stream. Its
|
|
907
|
-
// lifecycle is the daemon's, not any agent connection's — so it polls even with zero agents.
|
|
908
|
-
// Graceful shutdown
|
|
909
|
-
// DOD-LOGOUT-EXIT-1: the onStopped hook ends the process in the binary, so it fires at most once
|
|
910
|
-
// per daemon no matter how many times stop() is called.
|
|
911
|
-
let stoppedHookFired = false;
|
|
912
|
-
async function stop(reason) {
|
|
913
|
-
// 074-DOCSFLAG: `undefined` when documents are gated off — there is then no sweep to stop.
|
|
914
|
-
if (reconcileSweepTimer !== undefined)
|
|
915
|
-
clearInterval(reconcileSweepTimer);
|
|
916
|
-
clearInterval(revivalBoundSweepTimer);
|
|
917
|
-
// DOD-M15-RELAYABUSE-1: scheduled park retries. Unref'd, so they never held the process open —
|
|
918
|
-
// cleared so an in-process restart cannot leave one draining into a torn-down manager.
|
|
919
|
-
for (const t of parkRetryTimers)
|
|
920
|
-
clearTimeout(t);
|
|
921
|
-
parkRetryTimers.clear();
|
|
922
|
-
// DOD-M12B-SHUTDOWN-1: clearing the timer only stops the NEXT tick. The pass already running
|
|
923
|
-
// walks every agent, and each step dials a peer and opens a session — which is why a daemon
|
|
924
|
-
// reported down, with its socket already removed, was still logging `document.reconcile.sweep`
|
|
925
|
-
// 30 seconds later and had to be signalled to exit. This is what stops the pass in flight, and
|
|
926
|
-
// it also blocks `onReachable`, so a session tearing down during shutdown cannot hand the
|
|
927
|
-
// sweeper a fresh reason to dial on the way out.
|
|
928
|
-
// `?.` is a TYPE requirement, not a runtime one: TypeScript discards the narrowing of a
|
|
929
|
-
// captured `let` inside a hoisted function declaration, though it keeps it in the arrow a few
|
|
930
|
-
// lines up. The scheduler is in fact always wired by the time this can run — the IPC socket,
|
|
931
|
-
// the only route to `stop` besides the returned handle, opens after it.
|
|
932
|
-
reconcileScheduler?.stop();
|
|
933
|
-
// DOD-M12B-SHUTDOWN-1: the scheduler is one of FOUR callers of initiateReconcile. `nudgeSeats`
|
|
934
|
-
// and the two invite notices reach it directly, and every document verb is still served while
|
|
935
|
-
// the rest of this function runs — the IPC server is the last thing stopped. Refusing at the
|
|
936
|
-
// choke point is what actually closes "no new outbound work".
|
|
937
|
-
documentLayer?.stopReconciling();
|
|
938
|
-
// M8C-TGDOOR-1: stop the single long-lived getUpdates poller (no-op if never started) — bump
|
|
939
|
-
// the generation so the running loop's while-condition fails on its next check.
|
|
940
|
-
stopTelegramPoller(); // M8C-TGDOOR-1: invalidate the poll loop; it exits on its next generation check
|
|
941
|
-
// CELLO-M7-CONN-001: stop the HTTP manifest poll (sets the stopped flag so an in-flight
|
|
942
|
-
// tick cannot re-arm, and cancels the scheduler). Belt-and-suspenders cancel for the
|
|
943
|
-
// no-poll case (scheduler present but poll not started).
|
|
944
|
-
stopHttpManifestPoll?.();
|
|
945
|
-
if (manifestPollScheduler) {
|
|
946
|
-
manifestPollScheduler.cancel();
|
|
947
|
-
}
|
|
948
|
-
// DOD-M15-STALEROSTER-1: same discipline as the manifest poll — the stop function sets the
|
|
949
|
-
// flag so an in-flight sweep cannot re-arm, and the belt-and-suspenders cancel covers the
|
|
950
|
-
// scheduler-without-sweep case.
|
|
951
|
-
stopRosterSweep?.();
|
|
952
|
-
rosterSweepScheduler?.cancel();
|
|
953
|
-
stopRegistryPoll?.();
|
|
954
|
-
if (config.registryPollScheduler) {
|
|
955
|
-
config.registryPollScheduler.cancel();
|
|
956
|
-
}
|
|
957
|
-
// DOD-M12B-RESTART-SEAL-1: stop opening directory ceremonies. A seal is the most outbound thing
|
|
958
|
-
// this daemon does, and DOD-M12B-SHUTDOWN-1's rule is that a shutdown which keeps starting new
|
|
959
|
-
// outbound work is not draining. Above the `daemon.stopped` log with the other cancels, because
|
|
960
|
-
// this is "stop making new work", not "tear down transports".
|
|
961
|
-
await restartSealResolver?.stop();
|
|
962
|
-
// DOD-M15-ENDORSE-RETRY-1: same rule, same place — stop making new outbound work. Nothing is
|
|
963
|
-
// awaited: a submission send is one frame with an ack, not a ceremony, so cutting it leaves no
|
|
964
|
-
// counterparty holding a half-finished exchange. What IS lost is the pending queue itself,
|
|
965
|
-
// which is in memory by design (see submission-retry.ts) — re-sending is safe by the same
|
|
966
|
-
// content-derived id.
|
|
967
|
-
submissionRetries.stop();
|
|
968
|
-
/**
|
|
969
|
-
* DRAIN THE DETACHED SEAL TAILS — review MEDIUM-6, and it sits HERE for the same reason
|
|
970
|
-
* `restartSealResolver.stop()` does: both are directory ceremonies that must not be cut with
|
|
971
|
-
* the counterparty holding a commitment this side never acknowledged. Before
|
|
972
|
-
* `stopAllSignaling()`, because that is what severs the transport underneath them.
|
|
973
|
-
*
|
|
974
|
-
* BOUNDED. A ceremony can legitimately wait eleven minutes for a counterparty, and a shutdown
|
|
975
|
-
* must not. Past the bound they are abandoned deliberately and said out loud — the next boot
|
|
976
|
-
* resolves them, which is exactly what the restart seal resolver is for.
|
|
977
|
-
*/
|
|
978
|
-
if (backgroundSeals.size > 0) {
|
|
979
|
-
const SHUTDOWN_SEAL_DRAIN_MS = 5_000;
|
|
980
|
-
logger.info("session.seal.background.draining", { count: backgroundSeals.size, budgetMs: SHUTDOWN_SEAL_DRAIN_MS });
|
|
981
|
-
const drained = await Promise.race([
|
|
982
|
-
Promise.allSettled([...backgroundSeals]).then(() => true),
|
|
983
|
-
new Promise((r) => { const t = setTimeout(() => r(false), SHUTDOWN_SEAL_DRAIN_MS); t.unref?.(); }),
|
|
984
|
-
]);
|
|
985
|
-
if (!drained) {
|
|
986
|
-
logger.warn("session.seal.background.abandoned", {
|
|
987
|
-
count: backgroundSeals.size,
|
|
988
|
-
impact: "shutdown did not wait for these seal ceremonies. Each session holds a durable commitment " +
|
|
989
|
-
"but no receipt yet, and the counterparty may hold a commitment this side never acknowledged.",
|
|
990
|
-
guidance: "The next daemon start resolves them via the restart seal resolver; no operator action is needed.",
|
|
991
|
-
});
|
|
992
|
-
}
|
|
993
|
-
}
|
|
994
|
-
logger.info("daemon.stopped", { pid: process.pid, reason });
|
|
995
|
-
// DOD-LOGOUT-EXIT-1: what the teardown actually DID, carried to onStopped so the binary can
|
|
996
|
-
// exit non-zero on a dirty stop. Without it a shutdown that threw halfway — sessions never
|
|
997
|
-
// marked interrupted, database never checkpointed — would exit 0 and `cello logout` would
|
|
998
|
-
// print "Daemon stopped.", which is this unit's own defect one level up.
|
|
999
|
-
let teardownError;
|
|
1000
|
-
try {
|
|
1001
|
-
// stopAllSignaling() stops the shared manager AND every per-agent manager (best-effort). Do
|
|
1002
|
-
// not add a separate per-agent stop loop beside it: it would be redundant, and an unguarded
|
|
1003
|
-
// second stop() that throws would abort the rest of shutdown.
|
|
1004
|
-
trustSignalSweepTicker.stopAll();
|
|
1005
|
-
await stopAllSignaling();
|
|
1006
|
-
// Gracefully mark active sessions interrupted (AC-009) before stopping IPC
|
|
1007
|
-
await sessionNodeManager.gracefulShutdown();
|
|
1008
|
-
await ipcServer.stop();
|
|
1009
|
-
}
|
|
1010
|
-
catch (err) {
|
|
1011
|
-
// Recorded, then RE-THROWN below by the bare `throw` — the existing contract that a failed
|
|
1012
|
-
// stop() rejects is unchanged. This only makes the failure visible to onStopped as well.
|
|
1013
|
-
teardownError = err instanceof Error ? err : new Error(String(err));
|
|
1014
|
-
throw err;
|
|
1015
|
-
}
|
|
1016
|
-
finally {
|
|
1017
|
-
// DOD-M9B-WIRE-1: tear down whatever the composition root started alongside us — today the
|
|
1018
|
-
// screening sidecar. Two reasons it is HERE and not only in the bin's signal handler:
|
|
1019
|
-
// `cello logout` stops the daemon through the IPC `shutdown` verb, which reaches this
|
|
1020
|
-
// function and never touches the signal path; and a spawned child's stdio pipes keep this
|
|
1021
|
-
// process's event loop alive, so a daemon stopped that way would never actually exit.
|
|
1022
|
-
//
|
|
1023
|
-
// FIRST in the finally, BEFORE the singleton lock is released (review F4). The comment below
|
|
1024
|
-
// states the property the lock provides — "while we hold it, no successor daemon can start"
|
|
1025
|
-
// — and the sidecar teardown needs exactly that property: the `shutdown` verb acknowledges
|
|
1026
|
-
// immediately without awaiting this drain, so `cello logout && cello login` can race a new
|
|
1027
|
-
// daemon into existence. Releasing the lock first would let its gateway spawn while ours
|
|
1028
|
-
// still holds gateway.db's write lock, which the 3s busy_timeout usually hides — making the
|
|
1029
|
-
// failure intermittent rather than absent.
|
|
1030
|
-
if (config.onShutdown) {
|
|
1031
|
-
await config.onShutdown().catch((err) => {
|
|
1032
|
-
logger.error("daemon.shutdown.hook_failed", {
|
|
1033
|
-
error: extractErrorMessage(err),
|
|
1034
|
-
});
|
|
1035
|
-
});
|
|
1036
|
-
}
|
|
1037
|
-
// AFTER onShutdown, never before (review F9). onShutdown is `stopSecurityLayer`, which awaits
|
|
1038
|
-
// the sidecar's exit — so by here we ARE the last holder, and the last closer is the one that
|
|
1039
|
-
// may safely checkpoint and unlink (measured, review M1). Reversed, these handles would close
|
|
1040
|
-
// while the sidecar is still writing, which is the F1/F2 defect exactly.
|
|
1041
|
-
disposeGatewayConfigStores();
|
|
1042
|
-
// DOD-SINGLE-DAEMON-1: in a `finally`, because a throw anywhere above must not leave the lock
|
|
1043
|
-
// held. In the real binary the process exits and the kernel reclaims it — but an in-process
|
|
1044
|
-
// caller (vitest, an embedder) whose shutdown throws would otherwise find every subsequent
|
|
1045
|
-
// startDaemon in that process reporting "another daemon is already running", with the real
|
|
1046
|
-
// cause thrown away. That is the same leak F2 fixed on the startup path.
|
|
1047
|
-
//
|
|
1048
|
-
// DOD-DAEMON-CLEANUP-1 (AC1): the lock file goes only if it is still OURS. Another daemon may
|
|
1049
|
-
// have taken it over while we ran, and deleting a live daemon's lock is what makes `cello
|
|
1050
|
-
// logout` say "No daemon running" and the next `cello login` spawn a third one.
|
|
1051
|
-
await removeLockIfOwned(lockFilePath, process.pid, logger).catch(() => { });
|
|
1052
|
-
// Released LAST: while we hold it, no successor daemon can start, which is what lets
|
|
1053
|
-
// ipcServer.stop()'s socket re-check above be race-free.
|
|
1054
|
-
singletonLock.release();
|
|
1055
|
-
// DOD-LOGOUT-EXIT-1: signal that this daemon is DONE — the binary's handler is
|
|
1056
|
-
// `process.exit(0)`, so nothing may be sequenced after this line.
|
|
1057
|
-
//
|
|
1058
|
-
// AFTER singletonLock.release(), never before: the process is about to end, and dying while
|
|
1059
|
-
// still holding the kernel lock would make the next `cello login` refuse to start beside a
|
|
1060
|
-
// daemon that no longer exists.
|
|
1061
|
-
//
|
|
1062
|
-
// Inside the `finally` so a throw anywhere above still ends the process. A shutdown that
|
|
1063
|
-
// fails halfway and leaves the daemon alive and on the network is the exact defect this line
|
|
1064
|
-
// closes — "it threw" is not a reason to keep talking to a directory.
|
|
1065
|
-
//
|
|
1066
|
-
// Guarded: `stop()` has no idempotence of its own, and a caller that stops twice (an IPC
|
|
1067
|
-
// shutdown followed by an embedder's own stop) must not exit twice.
|
|
1068
|
-
// The hook's own failure is NOT caught. It is the only call that ends the process, so
|
|
1069
|
-
// swallowing a throw here would leave the daemon alive and handle-free while every check
|
|
1070
|
-
// logout makes agrees it is gone — the original defect, reached through the new code. Letting
|
|
1071
|
-
// it propagate makes stop() reject, which is what lets logout time out and say so.
|
|
1072
|
-
if (!stoppedHookFired) {
|
|
1073
|
-
stoppedHookFired = true;
|
|
1074
|
-
await config.onStopped?.({ ok: teardownError === undefined, error: teardownError });
|
|
1075
|
-
}
|
|
1076
|
-
}
|
|
1077
|
-
}
|
|
1078
|
-
function getSessionNodeManager() {
|
|
1079
|
-
return sessionNodeManager;
|
|
1080
|
-
}
|
|
1081
|
-
function getTransportSelector() {
|
|
1082
|
-
return transportSelector;
|
|
1083
|
-
}
|
|
1084
|
-
function getAutoNatService() {
|
|
1085
|
-
return autoNatService;
|
|
1086
|
-
}
|
|
1087
|
-
function getTypeRegistry() {
|
|
1088
|
-
return typeRegistry;
|
|
1089
|
-
}
|
|
1090
|
-
// M8C-TGDOOR-1: cold-capable — start the poller if a token was already configured from a
|
|
1091
|
-
// prior run, without waiting for any agent to come online or any client to attach.
|
|
1092
|
-
startTelegramPollerIfConfigured();
|
|
1093
|
-
// DOD-M12B-RESTART-SEAL-1: seal the sessions the LAST shutdown orphaned.
|
|
1094
|
-
//
|
|
1095
|
-
// 114 of 118 interrupted sessions on one operator's machine were flipped by our own shutdown
|
|
1096
|
-
// sweep and then sat there, because nothing has ever moved a session out of `interrupted`. Their
|
|
1097
|
-
// only exit was a force-abandon, which forfeits the notarized receipt.
|
|
1098
|
-
//
|
|
1099
|
-
// Started last, like the Telegram poller, and resolved LAZILY out of the live `handlers` map: the
|
|
1100
|
-
// close handler is registered far earlier, but reading it inside the callback is what lets a test
|
|
1101
|
-
// swap it after boot and prove this wiring exists rather than assume it.
|
|
1102
|
-
restartSealResolver = new RestartSealResolver({
|
|
1103
|
-
logger,
|
|
1104
|
-
listRestartOrphans: () => sessionNodeManager.listRestartOrphanedSessions(),
|
|
1105
|
-
...(config.restartSealInitialDelayMs !== undefined
|
|
1106
|
-
? { initialDelayMs: config.restartSealInitialDelayMs }
|
|
1107
|
-
: {}),
|
|
1108
|
-
...(config.restartSealStaggerMs !== undefined ? { staggerMs: config.restartSealStaggerMs } : {}),
|
|
1109
|
-
sealSession: async (agentName, sessionId) => {
|
|
1110
|
-
const close = handlers.get("cello_close_session");
|
|
1111
|
-
if (!close)
|
|
1112
|
-
return { ok: false, reason: "close_handler_missing" };
|
|
1113
|
-
const res = (await close({ session_id: sessionId, agent: agentName }, `restart-seal-${sessionId}`));
|
|
1114
|
-
// SUCCESS IS A RECEIPT, NOT AN `ok`. The interrupted close answers `ok: true` for a bilateral
|
|
1115
|
-
// COMMITMENT that nobody has notarized — `seal_interrupted_pending`, the status this resolver
|
|
1116
|
-
// exists to stop producing. Reading `ok` as success logged "resolved" for 137 sessions that
|
|
1117
|
-
// got no receipt at all. `sealed_root` is present only when a notarization actually happened.
|
|
1118
|
-
if (typeof res?.["sealed_root"] === "string" && res["sealed_root"].length > 0) {
|
|
1119
|
-
return { ok: true };
|
|
1120
|
-
}
|
|
1121
|
-
// Everything the close computed about WHY, carried instead of collapsed. `reason` is an exit
|
|
1122
|
-
// point — `seal_interrupted_rejected_by_counterparty` alone stands for six distinct causes,
|
|
1123
|
-
// and the close already put the discriminating detail on the response.
|
|
1124
|
-
const detail = {};
|
|
1125
|
-
for (const k of ["rejection_reason", "your_leaf_count", "their_leaf_count", "diverging_leaf_index",
|
|
1126
|
-
"seal_pending_reason", "seal_receipt", "missing_leaves", "held_messages", "status"]) {
|
|
1127
|
-
if (res?.[k] !== undefined)
|
|
1128
|
-
detail[k] = res[k];
|
|
1129
|
-
}
|
|
1130
|
-
const retry = res?.["retry_after_seconds"];
|
|
1131
|
-
return {
|
|
1132
|
-
ok: false,
|
|
1133
|
-
reason: (typeof res?.["seal_pending_reason"] === "string" ? res["seal_pending_reason"] : undefined)
|
|
1134
|
-
?? (typeof res?.["reason"] === "string" ? res["reason"] : undefined)
|
|
1135
|
-
?? "close_returned_no_receipt",
|
|
1136
|
-
...(typeof retry === "number" ? { retryAfterSeconds: retry } : {}),
|
|
1137
|
-
...(typeof res?.["guidance"] === "string" ? { guidance: res["guidance"] } : {}),
|
|
1138
|
-
...(Object.keys(detail).length > 0 ? { detail } : {}),
|
|
1139
|
-
};
|
|
1140
|
-
},
|
|
1141
|
-
markGaveUp: (agentName, sessionId, reason) => sessionNodeManager.markRestartSealGaveUp(agentName, sessionId, reason),
|
|
1142
|
-
});
|
|
1143
|
-
restartSealResolver.start();
|
|
1144
|
-
// 040-DAEMONROOT unit 9: the revival-bound sweep and its re-arming timer → boot-sweeps.ts.
|
|
1145
|
-
const { revivalBoundSweepTimer } = startBootSweeps({ logger, sessionNodeManager });
|
|
1146
|
-
/**
|
|
1147
|
-
* The live handler map.
|
|
1148
|
-
*
|
|
1149
|
-
* Exposed so the LATE-BINDING property can be asserted rather than assumed: dispatch resolves
|
|
1150
|
-
* from this map when a request arrives, and the only way to prove that is to register something
|
|
1151
|
-
* after `start()` has resolved and call it. The property is not decorative — a snapshot copy here
|
|
1152
|
-
* once made every `cello_doc_*` verb unreachable while the whole suite stayed green.
|
|
1153
|
-
*
|
|
1154
|
-
* Sits alongside `getSessionNodeManager` and `getTypeRegistry`, which are exposed for the same
|
|
1155
|
-
* reason. Production code has no business mutating it after boot.
|
|
1156
|
-
*/
|
|
1157
|
-
const getHandlers = () => handlers;
|
|
1158
|
-
return {
|
|
1159
|
-
/**
|
|
1160
|
-
* DOD-M12B-CLOSE-SILENT-WAIT-1 test seam: put a session into the state a normal close sits in
|
|
1161
|
-
* for up to eleven minutes, and emit the same start-of-wait line the close emits. Marks the
|
|
1162
|
-
* REAL waiter map the status surface reads, so a test cannot pass against a flag production
|
|
1163
|
-
* never sets.
|
|
1164
|
-
*/
|
|
1165
|
-
markSealInFlightForTest(agentName, sessionId) {
|
|
1166
|
-
const deadlineMs = Number(process.env["CELLO_SEAL_BILATERAL_TIMEOUT_MS"]) || 660_000;
|
|
1167
|
-
pendingSealWaiters.set(sealKey(agentName, sessionId), () => { });
|
|
1168
|
-
logger.warn("session.seal.awaiting_counterparty", {
|
|
1169
|
-
sessionId, agentName, deadlineMs,
|
|
1170
|
-
impact: `this close will not answer for up to ${Math.round(deadlineMs / 60_000)} minutes while it waits for the counterparty, then it escalates to a unilateral seal and produces a real receipt. It is working. Do NOT force-abandon it — that forfeits the receipt this wait is earning.`,
|
|
1171
|
-
});
|
|
1172
|
-
},
|
|
1173
|
-
stop, getStatus, getSessionNodeManager, getTransportSelector, getAutoNatService, getTypeRegistry,
|
|
1174
|
-
getHandlers,
|
|
1175
|
-
};
|
|
1176
|
-
}
|
|
1177
|
-
//# sourceMappingURL=daemon.js.map
|