@north-light/crouter 0.3.311 → 0.3.313
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/client.d.ts +27 -30
- package/dist/api/client.js +80 -67
- package/dist/api/dto/broker-ops.d.ts +10 -20
- package/dist/api/dto/canvas.d.ts +1 -10
- package/dist/api/dto/health.d.ts +113 -0
- package/dist/api/dto/human-requests.d.ts +14 -3
- package/dist/api/dto/human.d.ts +2 -48
- package/dist/api/dto/human.js +3 -2
- package/dist/api/dto/inbox.d.ts +14 -0
- package/dist/api/dto/mail.d.ts +43 -0
- package/dist/api/dto/nodes.d.ts +11 -8
- package/dist/api/dto/recovery.d.ts +96 -0
- package/dist/api/dto/reviews.d.ts +2 -2
- package/dist/api/routes.d.ts +9 -6
- package/dist/api/routes.js +11 -11
- package/dist/build-root.d.ts +4 -0
- package/dist/build-root.js +11 -1
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/integration/provider-rotation.test.ts +35 -47
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +1 -1
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +12 -5
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +12 -5
- package/dist/cli.js +10 -1
- package/dist/clients/__tests__/helpers/human-daemon.d.ts +11 -0
- package/dist/clients/__tests__/helpers/human-daemon.js +60 -0
- package/dist/clients/attach/chrome/canvas-panels.js +1 -1
- package/dist/clients/attach/chrome/inbox-strip.d.ts +3 -3
- package/dist/clients/attach/chrome/inbox-strip.js +17 -9
- package/dist/clients/attach/chrome/ticket-panel.d.ts +2 -2
- package/dist/clients/attach/chrome/ticket-panel.js +77 -46
- package/dist/clients/attach/overlays/graph.js +6 -9
- package/dist/clients/attach/render/chat-view.d.ts +5 -4
- package/dist/clients/attach/render/chat-view.js +22 -13
- package/dist/clients/attach/render/page-block.d.ts +11 -7
- package/dist/clients/attach/render/page-block.js +64 -55
- package/dist/clients/attach/viewer.js +746 -735
- package/dist/clients/inbox/__tests__/integration/inbox-controller.test.js +56 -56
- package/dist/clients/inbox/__tests__/integration/stale-row-activation.test.js +45 -32
- package/dist/clients/inbox/controller.d.ts +42 -14
- package/dist/clients/inbox/controller.js +240 -124
- package/dist/clients/inbox/dto-adapt.d.ts +28 -0
- package/dist/clients/inbox/dto-adapt.js +93 -0
- package/dist/clients/inbox/page-adapter.d.ts +5 -4
- package/dist/clients/inbox/page-adapter.js +12 -12
- package/dist/clients/inbox/resolve.d.ts +10 -5
- package/dist/clients/inbox/resolve.js +13 -12
- package/dist/clients/inbox/review/review-client.d.ts +0 -1
- package/dist/clients/inbox/review/review-client.js +0 -4
- package/dist/clients/inbox/review-adapter.d.ts +2 -1
- package/dist/clients/inbox/review-adapter.js +3 -5
- package/dist/clients/inbox/surface.d.ts +2 -2
- package/dist/clients/inbox/surface.js +19 -8
- package/dist/clients/inbox/tui.d.ts +3 -3
- package/dist/commands/__tests__/human.test.js +31 -15
- package/dist/commands/__tests__/integration/dashboard-snapshot.test.js +36 -11
- package/dist/commands/{sys/__tests__ → __tests__/integration}/migrate.test.js +142 -36
- package/dist/commands/__tests__/revive-now-gate.test.js +2 -0
- package/dist/commands/api-client.d.ts +5 -4
- package/dist/commands/api-client.js +13 -7
- package/dist/commands/canvas-history/shared.js +1 -1
- package/dist/commands/canvas-history.js +1 -1
- package/dist/commands/canvas-roster.js +1 -1
- package/dist/commands/canvas.js +1 -2
- package/dist/commands/human/feedback.js +20 -17
- package/dist/commands/human/prompts.js +45 -36
- package/dist/commands/human/queue.js +73 -123
- package/dist/commands/human/review.js +6 -16
- package/dist/commands/memory/__tests__/command-selector-and-mutation-guards.test.js +2 -0
- package/dist/commands/memory/__tests__/memory-list-and-lint-ignore.test.js +2 -0
- package/dist/commands/memory/__tests__/repository-root-lint.test.js +2 -0
- package/dist/commands/node-inspect-artifacts.js +1 -1
- package/dist/commands/node-lifecycle-revive.d.ts +2 -2
- package/dist/commands/node-lifecycle-revive.js +9 -19
- package/dist/commands/pkg/plugin-manage.js +0 -1
- package/dist/commands/profile/show.js +4 -12
- package/dist/commands/surface-tmux-spread.js +1 -5
- package/dist/commands/sys/__tests__/config-model-ladders.test.js +23 -30
- package/dist/commands/sys/__tests__/sync-project-guidance.test.js +37 -11
- package/dist/commands/sys/branch.d.ts +2 -0
- package/dist/commands/sys/branch.js +19 -0
- package/dist/commands/sys/config.js +106 -33
- package/dist/commands/sys/daemon.d.ts +2 -0
- package/dist/commands/sys/daemon.js +130 -7
- package/dist/commands/sys/doctor.js +5 -15
- package/dist/commands/sys/migrate.js +21 -92
- package/dist/commands/sys/setup-settings-runner.js +4 -2
- package/dist/commands/sys.js +2 -15
- package/dist/core/__tests__/boot-fault-attempt.test.js +23 -1
- package/dist/core/__tests__/boot.test.js +32 -25
- package/dist/core/__tests__/broker-launch-candidates.test.js +49 -0
- package/dist/core/__tests__/canvas-inbox-watcher-hold.test.js +149 -176
- package/dist/core/__tests__/canvas-inbox-watcher-naming.test.js +59 -10
- package/dist/core/__tests__/canvas-inbox-watcher.test.js +76 -20
- package/dist/core/__tests__/canvas.test.js +18 -47
- package/dist/core/__tests__/child-death-wake.test.js +29 -7
- package/dist/core/__tests__/cli-help-contract.test.js +2 -0
- package/dist/core/__tests__/close.test.js +29 -10
- package/dist/core/__tests__/collectible.test.js +2 -1
- package/dist/core/__tests__/config-change-delta.test.js +2 -0
- package/dist/core/__tests__/context-intro.test.js +17 -5
- package/dist/core/__tests__/cron-armed-context-failure.test.js +17 -12
- package/dist/core/__tests__/cron-held-settlement.test.js +21 -3
- package/dist/core/__tests__/cron-node-sink-parked-root.test.js +29 -10
- package/dist/core/__tests__/cron-self-cancel-delivery.test.js +14 -2
- package/dist/core/__tests__/cron-timeout-descendants.test.js +13 -1
- package/dist/core/__tests__/daemon-boot.test.js +51 -14
- package/dist/core/__tests__/fixtures/fake-engine.d.ts +1 -1
- package/dist/core/__tests__/fixtures/fake-engine.js +8 -3
- package/dist/core/__tests__/focuses.test.js +10 -5
- package/dist/core/__tests__/helpers/harness.js +50 -18
- package/dist/core/__tests__/history-inbox.test.js +12 -16
- package/dist/core/__tests__/human-action-delivery.test.js +48 -28
- package/dist/core/__tests__/human-actions.test.js +7 -3
- package/dist/core/__tests__/inline-memory-refs.test.js +7 -2
- package/dist/core/__tests__/integration/broker-fork-seam.test.js +37 -10
- package/dist/core/__tests__/integration/broker-sdk-wiring.test.js +42 -0
- package/dist/core/__tests__/integration/broker-snapshot-history.test.js +42 -29
- package/dist/core/__tests__/integration/broker-wedge-supervision.test.js +36 -35
- package/dist/core/__tests__/integration/command-plugins.test.js +15 -6
- package/dist/core/__tests__/integration/deferred-no-wake.test.js +113 -92
- package/dist/core/__tests__/integration/host-teardown-process-group.test.js +9 -5
- package/dist/core/__tests__/integration/lifecycle-hooks.test.js +312 -1
- package/dist/core/__tests__/integration/plugin-revalidate.test.js +4 -0
- package/dist/core/__tests__/integration/profile-pause.test.js +4 -4
- package/dist/core/__tests__/integration/refresh-stall-recycle.test.js +9 -12
- package/dist/core/__tests__/integration/revive.test.js +67 -21
- package/dist/core/__tests__/integration/spawn-root.test.js +62 -19
- package/dist/core/__tests__/integration/subscription-delivery.test.js +33 -21
- package/dist/core/__tests__/integration/worktree-land.test.js +5 -2
- package/dist/core/__tests__/integration/worktree-reap.test.js +15 -1
- package/dist/core/__tests__/kickoff.test.js +36 -39
- package/dist/core/__tests__/lifecycle-terminal-reasons.test.js +2 -1
- package/dist/core/__tests__/lifecycle.test.js +2 -1
- package/dist/core/__tests__/live-lifecycle-prompt.test.js +13 -1
- package/dist/core/__tests__/memory-resolver-precedence.test.js +2 -0
- package/dist/core/__tests__/migration.test.js +145 -31
- package/dist/core/__tests__/model-pin-durability.test.js +4 -1
- package/dist/core/__tests__/model-routes-config.test.js +13 -5
- package/dist/core/__tests__/node-outcome.test.js +93 -26
- package/dist/core/__tests__/on-read-crouter-home-fence.test.js +4 -3
- package/dist/core/__tests__/on-read-dedup-resume.test.js +8 -7
- package/dist/core/__tests__/on-read-nested-store.test.js +8 -7
- package/dist/core/__tests__/passive-subscription.test.js +50 -157
- package/dist/core/__tests__/plugin-kinds.test.js +6 -4
- package/dist/core/__tests__/plugin-link-symlinked-scope-root.test.js +6 -1
- package/dist/core/__tests__/plugin-page-components.test.js +6 -4
- package/dist/core/__tests__/preview-registry-sync.test.js +2 -0
- package/dist/core/__tests__/profile-project-memory-delivery.test.js +35 -32
- package/dist/core/__tests__/prune.test.js +11 -5
- package/dist/core/__tests__/push-final-guard.test.js +14 -7
- package/dist/core/__tests__/relaunch-root.test.js +30 -2
- package/dist/core/__tests__/remote-canvas-target.test.js +7 -1
- package/dist/core/__tests__/repository-root-identity.test.js +4 -0
- package/dist/core/__tests__/review-model-floor.test.js +6 -3
- package/dist/core/__tests__/revive-all.test.js +13 -3
- package/dist/core/__tests__/revive-capacity.test.js +26 -4
- package/dist/core/__tests__/revive-parked-fresh.test.js +31 -8
- package/dist/core/__tests__/seam/broker-attach-stream.test.js +1 -1
- package/dist/core/__tests__/seam/broker-cap-freeze.test.js +4 -3
- package/dist/core/__tests__/seam/broker-crash-teardown.test.js +11 -14
- package/dist/core/__tests__/seam/broker-provider-retry.test.js +85 -71
- package/dist/core/__tests__/seam/dormancy-release.test.js +33 -19
- package/dist/core/__tests__/seam/held-deferred-human-prompt.test.js +7 -5
- package/dist/core/__tests__/seam/inbox-reference-guidance.test.js +20 -6
- package/dist/core/__tests__/seam/node-outcome-delivery.test.js +27 -3
- package/dist/core/__tests__/spawn-worktree-id-conflict.test.js +5 -4
- package/dist/core/__tests__/stop-guard.test.js +2 -1
- package/dist/core/__tests__/subscription-pool-credential-guard.test.js +4 -3
- package/dist/core/__tests__/warm-claim-preference-snapshot.test.js +19 -5
- package/dist/core/__tests__/yield-ensures-daemon.test.js +2 -1
- package/dist/core/bootstrap.js +2 -0
- package/dist/core/broker-client/__tests__/transport-socket.test.js +51 -6
- package/dist/core/broker-client/transport-socket.d.ts +1 -0
- package/dist/core/broker-client/transport-socket.js +13 -5
- package/dist/core/canvas/__tests__/attention.test.js +29 -35
- package/dist/core/canvas/__tests__/history-transcript.test.js +6 -6
- package/dist/core/canvas/__tests__/render-remote.test.js +25 -9
- package/dist/core/canvas/attention.d.ts +2 -5
- package/dist/core/canvas/attention.js +15 -64
- package/dist/core/canvas/boot.d.ts +6 -7
- package/dist/core/canvas/boot.js +5 -9
- package/dist/core/canvas/canvas.d.ts +13 -109
- package/dist/core/canvas/canvas.js +140 -401
- package/dist/core/canvas/crons.d.ts +2 -0
- package/dist/core/canvas/crons.js +16 -15
- package/dist/core/canvas/daemon-owner.js +10 -0
- package/dist/core/canvas/db.d.ts +2 -2
- package/dist/core/canvas/db.js +2 -18
- package/dist/core/canvas/deliveries.d.ts +104 -0
- package/dist/core/canvas/deliveries.js +354 -0
- package/dist/core/canvas/executions.d.ts +29 -0
- package/dist/core/canvas/executions.js +68 -0
- package/dist/core/canvas/history.js +35 -35
- package/dist/core/canvas/index.d.ts +3 -1
- package/dist/core/canvas/index.js +3 -1
- package/dist/core/canvas/migrations.js +20 -12
- package/dist/core/canvas/nav-model.js +1 -3
- package/dist/core/canvas/nav-render.d.ts +4 -4
- package/dist/core/canvas/nav-render.js +11 -21
- package/dist/core/canvas/node-sql-migration.d.ts +3 -0
- package/dist/core/canvas/node-sql-migration.js +261 -0
- package/dist/core/canvas/paths.d.ts +2 -16
- package/dist/core/canvas/paths.js +2 -31
- package/dist/core/canvas/recovery.d.ts +76 -0
- package/dist/core/canvas/recovery.js +588 -0
- package/dist/core/canvas/remote-canvas-source.js +4 -0
- package/dist/core/canvas/render-source.d.ts +16 -27
- package/dist/core/canvas/render-source.js +16 -45
- package/dist/core/canvas/sessions.d.ts +33 -0
- package/dist/core/canvas/sessions.js +78 -0
- package/dist/core/canvas/types.d.ts +33 -33
- package/dist/core/canvas/types.js +2 -5
- package/dist/core/canvas/waits.d.ts +18 -0
- package/dist/core/canvas/waits.js +70 -0
- package/dist/core/canvas/worktrees.d.ts +40 -0
- package/dist/core/canvas/worktrees.js +93 -0
- package/dist/core/command-hooks/artifact.d.ts +6 -0
- package/dist/core/command-hooks/artifact.js +22 -6
- package/dist/core/command-hooks/discovery.d.ts +2 -0
- package/dist/core/command-hooks/discovery.js +2 -0
- package/dist/core/command-hooks/lifecycle-catalog.d.ts +20 -2
- package/dist/core/command-hooks/lifecycle-catalog.js +7 -2
- package/dist/core/command-hooks/lifecycle-create.d.ts +4 -0
- package/dist/core/command-hooks/lifecycle-create.js +51 -0
- package/dist/core/command-hooks/schema.d.ts +2 -2
- package/dist/core/command-hooks/schema.js +5 -4
- package/dist/core/command-hooks/transport/exec-invoke.js +3 -1
- package/dist/core/command-hooks/transport/exec-lifecycle.d.ts +18 -8
- package/dist/core/command-hooks/transport/exec-lifecycle.js +89 -30
- package/dist/core/config.d.ts +17 -12
- package/dist/core/config.js +106 -155
- package/dist/core/errors.d.ts +1 -0
- package/dist/core/errors.js +4 -0
- package/dist/core/feed/__tests__/inbox-migrate.test.js +27 -31
- package/dist/core/feed/feed.d.ts +0 -6
- package/dist/core/feed/feed.js +68 -56
- package/dist/core/feed/inbox.d.ts +7 -81
- package/dist/core/feed/inbox.js +46 -378
- package/dist/core/feed/messages.d.ts +58 -0
- package/dist/core/feed/messages.js +217 -0
- package/dist/core/fs-utils.d.ts +4 -0
- package/dist/core/fs-utils.js +21 -1
- package/dist/core/human/answer.d.ts +1 -1
- package/dist/core/human/answer.js +1 -1
- package/dist/core/human/claim.d.ts +1 -1
- package/dist/core/human/claim.js +2 -4
- package/dist/core/human/component-docs.js +1 -1
- package/dist/core/human/feedback-companion.js +4 -3
- package/dist/core/human/feedback.d.ts +5 -8
- package/dist/core/human/feedback.js +57 -85
- package/dist/core/human/page-authoring.d.ts +30 -0
- package/dist/core/human/page-authoring.js +19 -0
- package/dist/core/human/requests.d.ts +136 -0
- package/dist/core/human/requests.js +515 -0
- package/dist/core/human/root.d.ts +0 -7
- package/dist/core/human/root.js +0 -17
- package/dist/core/human/scan.d.ts +2 -7
- package/dist/core/human/scan.js +48 -132
- package/dist/core/human/summary.d.ts +1 -1
- package/dist/core/human/summary.js +1 -1
- package/dist/core/human/tickets.d.ts +23 -83
- package/dist/core/human/tickets.js +92 -243
- package/dist/core/human/types.d.ts +5 -1
- package/dist/core/installed-plugins.js +8 -3
- package/dist/core/keybindings/__tests__/resolve.test.js +19 -17
- package/dist/core/locked-file.d.ts +6 -3
- package/dist/core/locked-file.js +36 -9
- package/dist/core/memory/extensions.js +2 -0
- package/dist/core/preview-registry.js +0 -1
- package/dist/core/profiles/__tests__/env-store.test.js +2 -0
- package/dist/core/profiles/default-binding.d.ts +0 -4
- package/dist/core/profiles/default-binding.js +12 -58
- package/dist/core/profiles/env-store.js +8 -3
- package/dist/core/profiles/manifest.d.ts +2 -37
- package/dist/core/profiles/manifest.js +35 -161
- package/dist/core/profiles/select.js +3 -0
- package/dist/core/review/__tests__/capture-origin.test.js +13 -2
- package/dist/core/review/__tests__/comments.test.js +28 -10
- package/dist/core/review/__tests__/remap.test.js +28 -10
- package/dist/core/review/__tests__/stage-identity.test.js +17 -7
- package/dist/core/review/birth.d.ts +1 -1
- package/dist/core/review/birth.js +34 -5
- package/dist/core/review/comments.js +1 -1
- package/dist/core/review/companion.d.ts +1 -1
- package/dist/core/review/companion.js +2 -2
- package/dist/core/review/document.js +1 -1
- package/dist/core/review/project.d.ts +5 -1
- package/dist/core/review/project.js +14 -36
- package/dist/core/review/realize.d.ts +3 -6
- package/dist/core/review/realize.js +51 -168
- package/dist/core/review/remap.js +1 -1
- package/dist/core/review/stage.d.ts +3 -2
- package/dist/core/review/stage.js +2 -3
- package/dist/core/review/store.d.ts +3 -21
- package/dist/core/review/store.js +140 -186
- package/dist/core/review/types.d.ts +0 -1
- package/dist/core/runtime/__tests__/install-id-cache-scoping.test.js +9 -5
- package/dist/core/runtime/__tests__/spawn-env.test.js +8 -9
- package/dist/core/runtime/broker/auth-reload.js +9 -10
- package/dist/core/runtime/broker/daemon-ops.d.ts +25 -8
- package/dist/core/runtime/broker/daemon-ops.js +42 -9
- package/dist/core/runtime/broker/extension-abort.d.ts +3 -0
- package/dist/core/runtime/broker/extension-abort.js +11 -0
- package/dist/core/runtime/broker/fault-retry.d.ts +15 -6
- package/dist/core/runtime/broker/fault-retry.js +142 -95
- package/dist/core/runtime/broker/inbox.d.ts +4 -32
- package/dist/core/runtime/broker/inbox.js +4 -92
- package/dist/core/runtime/broker/rebind.d.ts +1 -0
- package/dist/core/runtime/broker/rebind.js +21 -12
- package/dist/core/runtime/broker-persona-guidance.d.ts +1 -1
- package/dist/core/runtime/broker-persona-guidance.js +2 -13
- package/dist/core/runtime/broker.js +28 -22
- package/dist/core/runtime/close.d.ts +3 -9
- package/dist/core/runtime/close.js +16 -27
- package/dist/core/runtime/fault.d.ts +3 -93
- package/dist/core/runtime/fault.js +9 -419
- package/dist/core/runtime/kickoff.d.ts +3 -6
- package/dist/core/runtime/kickoff.js +12 -18
- package/dist/core/runtime/launch.js +1 -1
- package/dist/core/runtime/lifecycle.js +40 -7
- package/dist/core/runtime/nodes.d.ts +5 -1
- package/dist/core/runtime/nodes.js +26 -11
- package/dist/core/runtime/placement.js +2 -2
- package/dist/core/runtime/recycle.js +24 -14
- package/dist/core/runtime/reset.js +26 -7
- package/dist/core/runtime/revive.js +226 -217
- package/dist/core/runtime/spawn.d.ts +4 -1
- package/dist/core/runtime/spawn.js +43 -5
- package/dist/core/runtime/warm-pool.d.ts +2 -2
- package/dist/core/runtime/warm-pool.js +23 -3
- package/dist/core/scoped-state/db.d.ts +7 -0
- package/dist/core/scoped-state/db.js +92 -0
- package/dist/core/scoped-state/migrate.d.ts +11 -0
- package/dist/core/scoped-state/migrate.js +198 -0
- package/dist/core/scoped-state/paths.d.ts +9 -0
- package/dist/core/scoped-state/paths.js +27 -0
- package/dist/core/scoped-state/profiles.d.ts +12 -0
- package/dist/core/scoped-state/profiles.js +62 -0
- package/dist/core/scoped-state/providers.d.ts +16 -0
- package/dist/core/scoped-state/providers.js +8 -0
- package/dist/core/scoped-state/schema.d.ts +3 -0
- package/dist/core/scoped-state/schema.js +26 -0
- package/dist/core/scoped-state/settings.d.ts +28 -0
- package/dist/core/scoped-state/settings.js +82 -0
- package/dist/core/subscription-state.d.ts +29 -48
- package/dist/core/subscription-state.js +176 -712
- package/dist/core/worktree-close.js +4 -4
- package/dist/core/worktree-mutation-async.js +2 -2
- package/dist/core/worktree-sweep.js +11 -16
- package/dist/core/worktree.js +6 -12
- package/dist/daemon/__tests__/autostart-storm.test.js +1 -39
- package/dist/daemon/__tests__/helpers/source-daemon.d.ts +2 -2
- package/dist/daemon/__tests__/helpers/source-daemon.js +7 -6
- package/dist/daemon/__tests__/integration/migration-startup.test.js +59 -26
- package/dist/daemon/__tests__/node-deadline-lane.test.js +2 -1
- package/dist/daemon/__tests__/node-outcome-birth-invariants.test.js +41 -17
- package/dist/daemon/__tests__/node-outcome-delivery.test.js +39 -10
- package/dist/daemon/__tests__/reconciler-signature.test.js +2 -2
- package/dist/daemon/__tests__/subtree-filter-freshness.test.js +2 -2
- package/dist/daemon/api/__tests__/broker-settle-park.test.js +17 -12
- package/dist/daemon/api/__tests__/canvas-snapshot-fields.test.js +27 -5
- package/dist/daemon/api/__tests__/model-config.test.js +8 -8
- package/dist/daemon/api/__tests__/node-create-description.test.js +22 -5
- package/dist/daemon/api/__tests__/node-model-validation.test.js +21 -1
- package/dist/daemon/api/__tests__/nodes-activity-query.test.js +10 -12
- package/dist/daemon/api/__tests__/profile-launch-gates.test.js +6 -3
- package/dist/daemon/api/__tests__/profile-metadata-route.test.js +4 -1
- package/dist/daemon/api/__tests__/reopen-delivery.test.js +26 -8
- package/dist/daemon/api/__tests__/seam/api-server.test.js +24 -32
- package/dist/daemon/api/__tests__/seam/b10-attach-modelauth.test.js +4 -1
- package/dist/daemon/api/__tests__/seam/leaf-api-parity.test.js +5 -4
- package/dist/daemon/api/__tests__/seam/profile-delete.test.js +29 -43
- package/dist/daemon/api/__tests__/submit-result.test.js +3 -2
- package/dist/daemon/api/bridge.js +1 -1
- package/dist/daemon/api/handlers/bash-jobs.js +6 -7
- package/dist/daemon/api/handlers/broker-ops.js +47 -84
- package/dist/daemon/api/handlers/broker-recovery.d.ts +4 -0
- package/dist/daemon/api/handlers/broker-recovery.js +251 -0
- package/dist/daemon/api/handlers/canvas.js +2 -44
- package/dist/daemon/api/handlers/daemon.js +41 -0
- package/dist/daemon/api/handlers/feedback-comments.js +2 -2
- package/dist/daemon/api/handlers/health.js +10 -5
- package/dist/daemon/api/handlers/human-requests.js +168 -188
- package/dist/daemon/api/handlers/human.js +3 -148
- package/dist/daemon/api/handlers/inbox-page.d.ts +4 -0
- package/dist/daemon/api/handlers/inbox-page.js +89 -0
- package/dist/daemon/api/handlers/inbox.js +21 -120
- package/dist/daemon/api/handlers/messages.d.ts +1 -0
- package/dist/daemon/api/handlers/messages.js +73 -15
- package/dist/daemon/api/handlers/node-outcomes.js +58 -13
- package/dist/daemon/api/handlers/nodes.d.ts +1 -0
- package/dist/daemon/api/handlers/nodes.js +41 -42
- package/dist/daemon/api/handlers/reviews.js +4 -29
- package/dist/daemon/api/map.d.ts +25 -3
- package/dist/daemon/api/map.js +84 -14
- package/dist/daemon/api/server.js +68 -9
- package/dist/daemon/control.d.ts +18 -0
- package/dist/daemon/cron/disposition.d.ts +2 -0
- package/dist/daemon/cron/disposition.js +8 -5
- package/dist/daemon/cron/settle.js +37 -13
- package/dist/daemon/cron/sinks.d.ts +18 -1
- package/dist/daemon/cron/sinks.js +47 -93
- package/dist/daemon/crtrd-cli.js +4 -19
- package/dist/daemon/crtrd.d.ts +2 -0
- package/dist/daemon/crtrd.js +206 -81
- package/dist/daemon/fleet.js +5 -6
- package/dist/daemon/human/finish.d.ts +12 -24
- package/dist/daemon/human/finish.js +88 -285
- package/dist/daemon/human/settle.d.ts +40 -0
- package/dist/daemon/human/settle.js +89 -0
- package/dist/daemon/human/sweep.d.ts +20 -5
- package/dist/daemon/human/sweep.js +56 -60
- package/dist/daemon/manage.d.ts +21 -16
- package/dist/daemon/manage.js +85 -51
- package/dist/daemon/messaging/node-message.d.ts +1 -1
- package/dist/daemon/messaging/node-message.js +9 -12
- package/dist/daemon/park-activity.js +3 -3
- package/dist/daemon/reconcilers/bash-deadline.js +6 -7
- package/dist/daemon/reconcilers/broker-supervision.d.ts +1 -1
- package/dist/daemon/reconcilers/broker-supervision.js +41 -19
- package/dist/daemon/reconcilers/controller-death.js +6 -18
- package/dist/daemon/reconcilers/delivery-lane.d.ts +9 -0
- package/dist/daemon/reconcilers/delivery-lane.js +130 -0
- package/dist/daemon/reconcilers/live-obligation.js +3 -3
- package/dist/daemon/reconcilers/node-deadline.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.d.ts +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +10 -12
- package/dist/daemon/reconcilers/node-lifecycle/tick.js +5 -5
- package/dist/daemon/reconcilers/node-lifecycle/wants-execution.js +1 -1
- package/dist/daemon/reconcilers/pending-review-submit.js +3 -3
- package/dist/daemon/reconcilers/storage-maintenance.d.ts +2 -8
- package/dist/daemon/reconcilers/storage-maintenance.js +13 -43
- package/dist/daemon/review/companion.js +5 -11
- package/dist/daemon/review/deliver.d.ts +1 -5
- package/dist/daemon/review/deliver.js +3 -52
- package/dist/daemon/review/finish.d.ts +2 -27
- package/dist/daemon/review/finish.js +79 -263
- package/dist/daemon/review/sweep.d.ts +3 -10
- package/dist/daemon/review/sweep.js +13 -131
- package/dist/daemon/startup-policy.d.ts +0 -5
- package/dist/daemon/startup-policy.js +0 -5
- package/dist/hook-authoring.d.ts +28 -2
- package/dist/hook-authoring.js +53 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1 -1
- package/dist/migrations/__tests__/activation-concurrency.test.js +3 -2
- package/dist/migrations/__tests__/activation.test.js +9 -6
- package/dist/migrations/activation.d.ts +3 -2
- package/dist/migrations/activation.js +2 -4
- package/dist/migrations/corpus.d.ts +2 -5
- package/dist/migrations/corpus.js +9 -20
- package/dist/migrations/runner.d.ts +3 -1
- package/dist/migrations/runner.js +6 -2
- package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +21 -89
- package/dist/pi-extensions/__tests__/canvas-goal-capture-envelope.test.js +4 -2
- package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +51 -33
- package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.js +16 -2
- package/dist/pi-extensions/__tests__/pre-command-gate.test.js +13 -1
- package/dist/pi-extensions/canvas-inbox-watcher.js +98 -244
- package/dist/pi-extensions/canvas-passive-context.d.ts +4 -8
- package/dist/pi-extensions/canvas-passive-context.js +85 -37
- package/dist/pi-extensions/canvas-stophook.js +47 -31
- package/dist/shared/env.d.ts +1 -0
- package/dist/shared/env.js +3 -0
- package/package.json +1 -1
- package/runtime.lock.json +5 -5
- package/dist/clients/attach/__tests__/page-block.test.js +0 -54
- package/dist/clients/inbox/review-visibility.d.ts +0 -5
- package/dist/clients/inbox/review-visibility.js +0 -19
- package/dist/commands/canvas-rebuild-index.d.ts +0 -2
- package/dist/commands/canvas-rebuild-index.js +0 -46
- package/dist/core/__tests__/human-cancel-guard.test.js +0 -110
- package/dist/core/__tests__/human-deliver.test.d.ts +0 -1
- package/dist/core/__tests__/human-deliver.test.js +0 -256
- package/dist/core/__tests__/human-node-not-supervised.test.d.ts +0 -1
- package/dist/core/__tests__/human-node-not-supervised.test.js +0 -89
- package/dist/core/__tests__/integration/human-deliver-e2e.test.d.ts +0 -1
- package/dist/core/__tests__/integration/human-deliver-e2e.test.js +0 -131
- package/dist/core/__tests__/phase4-review-store.test.d.ts +0 -1
- package/dist/core/__tests__/phase4-review-store.test.js +0 -144
- package/dist/core/__tests__/watchdog-abort-arms-retry.test.d.ts +0 -1
- package/dist/core/__tests__/watchdog-abort-arms-retry.test.js +0 -110
- package/dist/core/canvas/human-deliveries.d.ts +0 -39
- package/dist/core/canvas/human-deliveries.js +0 -75
- package/dist/core/canvas/node-outcome-deliveries.d.ts +0 -64
- package/dist/core/canvas/node-outcome-deliveries.js +0 -159
- package/dist/core/feed/passive.d.ts +0 -3
- package/dist/core/feed/passive.js +0 -53
- package/dist/core/human/__tests__/inbox-cancel-worker.d.ts +0 -1
- package/dist/core/human/__tests__/inbox-cancel-worker.js +0 -7
- package/dist/core/human/__tests__/inbox-claim-worker.d.ts +0 -1
- package/dist/core/human/__tests__/inbox-claim-worker.js +0 -17
- package/dist/core/human/__tests__/inbox-stale-claim-worker.d.ts +0 -1
- package/dist/core/human/__tests__/inbox-stale-claim-worker.js +0 -8
- package/dist/core/human/__tests__/integration/inbox-core.test.d.ts +0 -1
- package/dist/core/human/__tests__/integration/inbox-core.test.js +0 -145
- package/dist/core/human/__tests__/page-tickets.test.d.ts +0 -1
- package/dist/core/human/__tests__/page-tickets.test.js +0 -161
- package/dist/core/review/ticket-filter.d.ts +0 -17
- package/dist/core/review/ticket-filter.js +0 -21
- package/dist/core/runtime/broker/passive.d.ts +0 -17
- package/dist/core/runtime/broker/passive.js +0 -44
- package/dist/core/runtime/busy.d.ts +0 -46
- package/dist/core/runtime/busy.js +0 -150
- package/dist/daemon/__tests__/startup-block-marker.test.d.ts +0 -1
- package/dist/daemon/__tests__/startup-block-marker.test.js +0 -86
- package/dist/daemon/api/__tests__/review-terminal-conflict.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/review-terminal-conflict.test.js +0 -98
- package/dist/daemon/human/deliver-action.d.ts +0 -3
- package/dist/daemon/human/deliver-action.js +0 -9
- package/dist/daemon/node-outcome/deliver-outcome.d.ts +0 -3
- package/dist/daemon/node-outcome/deliver-outcome.js +0 -9
- package/dist/daemon/reconcilers/human-delivery-lane.d.ts +0 -10
- package/dist/daemon/reconcilers/human-delivery-lane.js +0 -41
- package/dist/daemon/reconcilers/node-outcome-delivery-lane.d.ts +0 -10
- package/dist/daemon/reconcilers/node-outcome-delivery-lane.js +0 -41
- package/dist/daemon/startup-block-marker.d.ts +0 -25
- package/dist/daemon/startup-block-marker.js +0 -99
- /package/dist/{clients/attach/__tests__/page-block.test.d.ts → api/dto/mail.js} +0 -0
- /package/dist/{commands/sys/__tests__/migrate.test.d.ts → api/dto/recovery.js} +0 -0
- /package/dist/{core/__tests__/human-cancel-guard.test.d.ts → commands/__tests__/integration/migrate.test.d.ts} +0 -0
package/dist/daemon/crtrd.js
CHANGED
|
@@ -46,11 +46,10 @@ import { writeFileSync, readFileSync, rmSync, mkdirSync, } from 'node:fs';
|
|
|
46
46
|
import { dirname } from 'node:path';
|
|
47
47
|
import { randomBytes } from 'node:crypto';
|
|
48
48
|
import { crtrHome } from '../core/canvas/paths.js';
|
|
49
|
-
import {
|
|
49
|
+
import { listNodeMemoryTargets, listNodes, } from '../core/canvas/index.js';
|
|
50
50
|
import { createApiServer } from './api/server.js';
|
|
51
51
|
import { reconcileUndeliveredTickets } from './human/sweep.js';
|
|
52
|
-
import {
|
|
53
|
-
import { recoverRunningOutcomeDeliveries } from '../core/canvas/node-outcome-deliveries.js';
|
|
52
|
+
import { resetHandedOffDeliveries } from '../core/canvas/deliveries.js';
|
|
54
53
|
import { sweepReviews } from './review/sweep.js';
|
|
55
54
|
import { pidfilePath } from './pidfile.js';
|
|
56
55
|
import { rendererWarning } from '../core/runtime/package-health.js';
|
|
@@ -60,12 +59,12 @@ import { ControllerDeathReconciler } from './reconcilers/controller-death.js';
|
|
|
60
59
|
import { NodeLifecycleReconciler } from './reconcilers/node-lifecycle/tick.js';
|
|
61
60
|
import { NodeDeadlineReconciler } from './reconcilers/node-deadline.js';
|
|
62
61
|
import { CronLaneReconciler } from './reconcilers/cron-lane.js';
|
|
63
|
-
import {
|
|
64
|
-
import {
|
|
62
|
+
import { DeliveryLaneReconciler } from './reconcilers/delivery-lane.js';
|
|
63
|
+
import { migrateLegacyExecutionIdentities } from '../core/canvas/executions.js';
|
|
65
64
|
import { PendingReviewSubmitReconciler } from './reconcilers/pending-review-submit.js';
|
|
66
65
|
import { StorageMaintenanceReconciler } from './reconcilers/storage-maintenance.js';
|
|
67
66
|
import { BashDeadlineReconciler } from './reconcilers/bash-deadline.js';
|
|
68
|
-
import { captureLivenessSnapshot, capturePidCommand, captureTeardownSnapshot, isPidAlive, killProcessTreePids, } from '../core/canvas/pid.js';
|
|
67
|
+
import { captureLivenessSnapshot, capturePidCommand, captureTeardownSnapshot, isPidAlive, isAnyPidAlive, killProcessTreePids, } from '../core/canvas/pid.js';
|
|
69
68
|
import { bindFleet, boundFleet } from '../core/runtime/fleet.js';
|
|
70
69
|
import { bindDaemonControl, clearDaemonControl } from './control.js';
|
|
71
70
|
import { execDaemon, spawnDaemon } from './manage.js';
|
|
@@ -73,14 +72,19 @@ import { reconcileAndMigrateBoot } from '../core/canvas/boot.js';
|
|
|
73
72
|
import { resolveInstallId } from '../core/canvas/install-id.js';
|
|
74
73
|
import { setInstallId } from '../core/runtime/nodes.js';
|
|
75
74
|
import { claimDaemonOwnership, releaseDaemonOwnership } from '../core/canvas/daemon-owner.js';
|
|
75
|
+
import { migrate, openDb } from '../core/canvas/db.js';
|
|
76
76
|
import { prewarmRecentRecipes, reapStaleSpares } from '../core/runtime/warm-pool.js';
|
|
77
77
|
import { DaemonFleet } from './fleet.js';
|
|
78
78
|
import { BOOT_MIGRATIONS } from './boot-migrations.js';
|
|
79
79
|
import { emitEvent } from '../core/events/emit.js';
|
|
80
80
|
import { operationIdContext } from '../core/events/operation-id.js';
|
|
81
81
|
import { bindDaemonEventSource } from '../core/events/source.js';
|
|
82
|
-
import {
|
|
83
|
-
import {
|
|
82
|
+
import { activateOnDiskMigrations, MigrationBlockedError, runForcedOnDiskMigrations } from '../migrations/activation.js';
|
|
83
|
+
import { profilesRoot, withProfileManifestLock } from '../core/profiles/manifest.js';
|
|
84
|
+
import { runProfileManifestMigrations } from '../migrations/profile-manifests.js';
|
|
85
|
+
import { convertLegacyProviderStore, convertLegacyScopedStore } from '../core/scoped-state/migrate.js';
|
|
86
|
+
import { userScopeRoot } from '../core/scope.js';
|
|
87
|
+
import { piAgentDir } from '../core/runtime/package-health.js';
|
|
84
88
|
// A broker DECLARES its owning canvas in argv at spawn (host.ts launch:
|
|
85
89
|
// `broker-cli.js --canvas-home <home> --epoch <id> <nodeId>`), so ownership is
|
|
86
90
|
// an exact match on this daemon's own canvas home — no path inference. An
|
|
@@ -113,15 +117,12 @@ const CENSUS_POLL_MS = 150;
|
|
|
113
117
|
async function reapPriorEpochBrokers(epoch) {
|
|
114
118
|
const snapshot = captureLivenessSnapshot();
|
|
115
119
|
if (snapshot === null) {
|
|
116
|
-
// No process table — the census cannot run. The supervision tick still
|
|
117
|
-
// classifies rows; a surviving prior-epoch broker is at worst a duplicate
|
|
118
|
-
// engine risk the next daemon boot's census retries.
|
|
119
120
|
emitEvent({
|
|
120
121
|
level: 'error',
|
|
121
122
|
event: 'daemon.census.snapshot_failed',
|
|
122
123
|
fields: { invariant: 'prior-epoch brokers are reaped before readiness' },
|
|
123
124
|
});
|
|
124
|
-
|
|
125
|
+
throw new Error('prior-epoch broker census could not capture the process table');
|
|
125
126
|
}
|
|
126
127
|
const home = crtrHome();
|
|
127
128
|
const victims = [];
|
|
@@ -168,16 +169,43 @@ async function reapPriorEpochBrokers(epoch) {
|
|
|
168
169
|
}
|
|
169
170
|
// Bounded graceful wait, then SIGKILL each survivor's captured tree.
|
|
170
171
|
const deadline = Date.now() + PRIOR_EPOCH_TERM_GRACE_MS;
|
|
171
|
-
while (Date.now() < deadline && signaled.some((s) =>
|
|
172
|
+
while (Date.now() < deadline && signaled.some((s) => isAnyPidAlive(s.snap.tree.length > 0 ? s.snap.tree : [s.pid]))) {
|
|
172
173
|
await new Promise((resolve) => setTimeout(resolve, CENSUS_POLL_MS));
|
|
173
174
|
}
|
|
174
175
|
let sigkilled = 0;
|
|
175
176
|
for (const s of signaled) {
|
|
176
|
-
|
|
177
|
+
const tree = s.snap.tree.length > 0 ? s.snap.tree : [s.pid];
|
|
178
|
+
if (!isAnyPidAlive(tree))
|
|
177
179
|
continue;
|
|
178
|
-
killProcessTreePids(
|
|
180
|
+
killProcessTreePids(tree, 'SIGKILL', s.snap.identities);
|
|
179
181
|
sigkilled++;
|
|
180
182
|
}
|
|
183
|
+
if (sigkilled > 0)
|
|
184
|
+
await new Promise((resolve) => setTimeout(resolve, CENSUS_POLL_MS));
|
|
185
|
+
// Only a fresh full table sample proves a prior writer is gone.
|
|
186
|
+
const finalSnapshot = captureLivenessSnapshot();
|
|
187
|
+
if (finalSnapshot === null) {
|
|
188
|
+
emitEvent({
|
|
189
|
+
level: 'error',
|
|
190
|
+
event: 'daemon.census.snapshot_failed',
|
|
191
|
+
fields: { invariant: 'prior-epoch brokers are reaped before readiness', stage: 'final' },
|
|
192
|
+
});
|
|
193
|
+
throw new Error('prior-epoch broker census could not capture the final process table');
|
|
194
|
+
}
|
|
195
|
+
const survivors = [];
|
|
196
|
+
for (const [pid, processInfo] of finalSnapshot.processes) {
|
|
197
|
+
const command = processInfo.command;
|
|
198
|
+
if (processInfo.zombie || !command.includes('broker-cli.js'))
|
|
199
|
+
continue;
|
|
200
|
+
if (!brokerCommandDeclaresCanvasHome(command, home))
|
|
201
|
+
continue;
|
|
202
|
+
if (brokerCommandEpoch(command) === epoch)
|
|
203
|
+
continue;
|
|
204
|
+
survivors.push(pid);
|
|
205
|
+
}
|
|
206
|
+
if (survivors.length > 0) {
|
|
207
|
+
throw new Error(`prior-epoch broker census could not prove termination of pid(s): ${survivors.join(', ')}`);
|
|
208
|
+
}
|
|
181
209
|
emitEvent({
|
|
182
210
|
level: 'info',
|
|
183
211
|
event: 'daemon.census.completed',
|
|
@@ -220,17 +248,21 @@ async function teardownFleet(fleet) {
|
|
|
220
248
|
t.unref();
|
|
221
249
|
});
|
|
222
250
|
await Promise.allSettled(items.map((item) => Promise.race([item.exited.then(() => { }), timeout])));
|
|
223
|
-
|
|
251
|
+
const sigkilled = [];
|
|
224
252
|
for (const item of items) {
|
|
225
253
|
if (!isPidAlive(item.pid))
|
|
226
254
|
continue;
|
|
227
255
|
killProcessTreePids(item.snap.tree.length > 0 ? item.snap.tree : [item.pid], 'SIGKILL', item.snap.identities);
|
|
228
|
-
sigkilled
|
|
256
|
+
sigkilled.push(item);
|
|
229
257
|
}
|
|
258
|
+
// A signal only requests termination. The handle's exit promise is the
|
|
259
|
+
// authoritative proof that each escalated broker has exited, so cleanup must
|
|
260
|
+
// not release its daemon ownership claim before these promises settle.
|
|
261
|
+
await Promise.all(sigkilled.map((item) => item.exited));
|
|
230
262
|
emitEvent({
|
|
231
263
|
level: 'info',
|
|
232
264
|
event: 'daemon.fleet_teardown.completed',
|
|
233
|
-
fields: { brokers: items.length, sigkilled },
|
|
265
|
+
fields: { brokers: items.length, sigkilled: sigkilled.length },
|
|
234
266
|
});
|
|
235
267
|
}
|
|
236
268
|
// Pidfile
|
|
@@ -277,8 +309,7 @@ const controllerDeath = new ControllerDeathReconciler();
|
|
|
277
309
|
const nodeLifecycle = new NodeLifecycleReconciler();
|
|
278
310
|
const nodeDeadline = new NodeDeadlineReconciler();
|
|
279
311
|
const cronLane = new CronLaneReconciler();
|
|
280
|
-
const
|
|
281
|
-
const nodeOutcomeDeliveryLane = new NodeOutcomeDeliveryLaneReconciler();
|
|
312
|
+
const deliveryLane = new DeliveryLaneReconciler();
|
|
282
313
|
const pendingReviewSubmit = new PendingReviewSubmitReconciler();
|
|
283
314
|
const storageMaintenance = new StorageMaintenanceReconciler();
|
|
284
315
|
const bashDeadline = new BashDeadlineReconciler();
|
|
@@ -310,8 +341,7 @@ export async function superviseTick(now = Date.now(), lifecycle = directTickLife
|
|
|
310
341
|
// canceled and terminalized here, after the lifecycle pass has had its say.
|
|
311
342
|
nodeDeadline.run(now);
|
|
312
343
|
cronLane.run(now, { lifecycle });
|
|
313
|
-
|
|
314
|
-
nodeOutcomeDeliveryLane.run(now, { lifecycle });
|
|
344
|
+
deliveryLane.run(now, { lifecycle });
|
|
315
345
|
pendingReviewSubmit.run(now, { lifecycle });
|
|
316
346
|
storageMaintenance.run(now, { lifecycle, fleet });
|
|
317
347
|
await bashDeadline.run(now, { rows });
|
|
@@ -348,11 +378,11 @@ export async function runDaemon(opts = {}) {
|
|
|
348
378
|
}
|
|
349
379
|
const claim = ownership.claim;
|
|
350
380
|
try {
|
|
351
|
-
await
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
381
|
+
await reapPriorEpochBrokers(claim.token);
|
|
382
|
+
runProfileManifestMigrations(profilesRoot(), { dryRun: false, withLock: withProfileManifestLock });
|
|
383
|
+
convertLegacyScopedStore({ kind: 'user', root: userScopeRoot() });
|
|
384
|
+
await convertLegacyProviderStore(piAgentDir());
|
|
385
|
+
migrate(openDb());
|
|
356
386
|
}
|
|
357
387
|
catch (migrationError) {
|
|
358
388
|
try {
|
|
@@ -377,6 +407,18 @@ export async function runDaemon(opts = {}) {
|
|
|
377
407
|
let cleanupInFlight;
|
|
378
408
|
let apiServer;
|
|
379
409
|
let apiServerClosed = false;
|
|
410
|
+
let startup = {
|
|
411
|
+
phase: 'initializing',
|
|
412
|
+
message: 'daemon startup is initializing its on-disk memory migration and normal services are unavailable',
|
|
413
|
+
blockerPaths: [],
|
|
414
|
+
};
|
|
415
|
+
// This slot is occupied before the repair socket binds, and remains occupied
|
|
416
|
+
// through normal startup. A request never receives another request's report.
|
|
417
|
+
let migrationInFlight = 'initial startup activation';
|
|
418
|
+
let resume = null;
|
|
419
|
+
function startupBlock() {
|
|
420
|
+
return startup.phase === 'ready' ? null : { phase: startup.phase, message: startup.message, blockerPaths: startup.blockerPaths };
|
|
421
|
+
}
|
|
380
422
|
function registerDetached(work) {
|
|
381
423
|
detached.add(work);
|
|
382
424
|
void work.finally(() => {
|
|
@@ -591,23 +633,88 @@ export async function runDaemon(opts = {}) {
|
|
|
591
633
|
}
|
|
592
634
|
});
|
|
593
635
|
}
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
636
|
+
let admissionFailure = null;
|
|
637
|
+
async function admitStartup() {
|
|
638
|
+
if (admissionFailure !== null) {
|
|
639
|
+
const message = admissionFailure instanceof Error ? admissionFailure.message : String(admissionFailure);
|
|
640
|
+
throw { status: 500, code: 'admission_failed', message: `daemon admission previously failed: ${message}` };
|
|
641
|
+
}
|
|
642
|
+
if (startup.phase === 'ready') {
|
|
643
|
+
return { admitted: false, already_admitted: true, startup_phase: 'ready' };
|
|
644
|
+
}
|
|
645
|
+
if (startup.phase !== 'prepared' && startup.phase !== 'recovering') {
|
|
646
|
+
throw {
|
|
647
|
+
status: 409,
|
|
648
|
+
code: 'not_prepared',
|
|
649
|
+
message: startup.message,
|
|
650
|
+
};
|
|
651
|
+
}
|
|
652
|
+
const admitted = startup.phase === 'prepared';
|
|
653
|
+
try {
|
|
654
|
+
await resumeStartup();
|
|
655
|
+
startup = { phase: 'ready', message: '', blockerPaths: [] };
|
|
656
|
+
return admitted
|
|
657
|
+
? { admitted: true, already_admitted: false, startup_phase: 'ready' }
|
|
658
|
+
: { admitted: false, already_admitted: true, startup_phase: 'ready' };
|
|
659
|
+
}
|
|
660
|
+
catch (error) {
|
|
661
|
+
admissionFailure = error;
|
|
662
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
663
|
+
throw { status: 500, code: 'admission_failed', message: `daemon admission failed: ${message}` };
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
async function repairMigrations(req) {
|
|
667
|
+
if (migrationInFlight !== null) {
|
|
668
|
+
throw {
|
|
669
|
+
status: 409,
|
|
670
|
+
code: 'migration_in_progress',
|
|
671
|
+
message: `on-disk migration is already running (${migrationInFlight})`,
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
migrationInFlight = 'repair';
|
|
675
|
+
try {
|
|
676
|
+
const result = await runForcedOnDiskMigrations({
|
|
677
|
+
dryRun: req.dryRun,
|
|
678
|
+
explicitDirs: req.dirs,
|
|
679
|
+
nodes: listNodeMemoryTargets(),
|
|
680
|
+
});
|
|
681
|
+
if (req.dryRun || !result.finalVerificationSucceeded || startup.phase !== 'blocked') {
|
|
682
|
+
return { result, resumed: false };
|
|
683
|
+
}
|
|
684
|
+
if (opts.prepare) {
|
|
685
|
+
startup = {
|
|
686
|
+
phase: 'prepared',
|
|
687
|
+
message: 'daemon storage is prepared and normal services are unavailable until admission',
|
|
688
|
+
blockerPaths: [],
|
|
689
|
+
};
|
|
690
|
+
return { result, resumed: false };
|
|
691
|
+
}
|
|
692
|
+
try {
|
|
693
|
+
await resumeStartup();
|
|
694
|
+
startup = { phase: 'ready', message: '', blockerPaths: [] };
|
|
695
|
+
return { result, resumed: true };
|
|
696
|
+
}
|
|
697
|
+
catch (error) {
|
|
698
|
+
const resumeError = error instanceof Error ? error.message : String(error);
|
|
699
|
+
// The route must flush this result before cleanup closes its connection.
|
|
700
|
+
setTimeout(() => { void requestCleanup().catch(() => { }); }, 1_000);
|
|
701
|
+
return { result, resumed: false, resumeError };
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
finally {
|
|
705
|
+
migrationInFlight = null;
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
async function completeStartup() {
|
|
599
709
|
interval = opts.intervalMs ?? DEFAULT_INTERVAL_MS;
|
|
600
|
-
|
|
601
|
-
// BEFORE anything can launch a broker (the API server or any tick): every
|
|
602
|
-
// launch funnels through headlessBrokerHost.launch, which
|
|
603
|
-
// registers with the bound fleet — an unbound launch throws (design D-2).
|
|
604
|
-
const epoch = randomBytes(8).toString('hex');
|
|
710
|
+
const epoch = claim.token;
|
|
605
711
|
fleet = new DaemonFleet({ epoch, enqueue });
|
|
606
712
|
bindFleet(fleet);
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
713
|
+
startup = {
|
|
714
|
+
phase: 'recovering',
|
|
715
|
+
message: 'daemon startup recovery is running and normal services are unavailable',
|
|
716
|
+
blockerPaths: [],
|
|
717
|
+
};
|
|
611
718
|
operationIdContext.fresh(() => {
|
|
612
719
|
emitEvent({
|
|
613
720
|
level: 'info',
|
|
@@ -615,18 +722,11 @@ export async function runDaemon(opts = {}) {
|
|
|
615
722
|
fields: { pid: process.pid, interval_ms: interval },
|
|
616
723
|
});
|
|
617
724
|
});
|
|
618
|
-
// Resolve the canvas-install id EARLY — before any other startup work
|
|
619
|
-
// that might mint a node id. A thrown error here (invalid CRTR_INSTALL_ID,
|
|
620
|
-
// or a stored/env mismatch) propagates out of this try block into the
|
|
621
|
-
// existing `catch (startupError)` below, which is exactly the "hard fail
|
|
622
|
-
// daemon boot" requirement — no separate catch/rethrow needed.
|
|
623
725
|
const installId = resolveInstallId();
|
|
624
726
|
setInstallId(installId);
|
|
625
727
|
operationIdContext.fresh(() => {
|
|
626
728
|
emitEvent({ level: 'info', event: 'daemon.install_id.resolved', fields: { install_id: installId } });
|
|
627
729
|
});
|
|
628
|
-
// The pinned termrender renderer is an advisory dependency; setup repairs
|
|
629
|
-
// an unprovisioned venv without blocking supervision.
|
|
630
730
|
operationIdContext.fresh(() => {
|
|
631
731
|
let warning;
|
|
632
732
|
try {
|
|
@@ -643,21 +743,13 @@ export async function runDaemon(opts = {}) {
|
|
|
643
743
|
});
|
|
644
744
|
}
|
|
645
745
|
});
|
|
646
|
-
// Complete ticket delivery before API traffic can observe terminal answers.
|
|
647
746
|
await operationIdContext.fresh(async () => {
|
|
648
747
|
await sweepReviews();
|
|
649
748
|
await reconcileUndeliveredTickets();
|
|
650
|
-
|
|
651
|
-
recoverRunningActionDeliveries(Date.now());
|
|
652
|
-
// Same at-least-once contract for node outcome deliveries: a delivery the
|
|
653
|
-
// dead daemon had marked running is re-queued rather than stranded.
|
|
654
|
-
recoverRunningOutcomeDeliveries(Date.now());
|
|
749
|
+
resetHandedOffDeliveries(Date.now());
|
|
655
750
|
});
|
|
656
|
-
// Boot reconciliation clears stale process identities before any tick can
|
|
657
|
-
// inspect them, then migrates legacy identities only with proven same-boot
|
|
658
|
-
// provenance.
|
|
659
751
|
operationIdContext.fresh(() => {
|
|
660
|
-
const { reconcile, migrated } = reconcileAndMigrateBoot(
|
|
752
|
+
const { reconcile, migrated } = reconcileAndMigrateBoot(migrateLegacyExecutionIdentities);
|
|
661
753
|
if (reconcile.changed) {
|
|
662
754
|
emitEvent({
|
|
663
755
|
level: 'info',
|
|
@@ -676,11 +768,6 @@ export async function runDaemon(opts = {}) {
|
|
|
676
768
|
});
|
|
677
769
|
}
|
|
678
770
|
});
|
|
679
|
-
// Boot-time filesystem repairs (design: src/daemon/boot-migrations.ts) run
|
|
680
|
-
// unconditionally, in order, before supervision can revive anything.
|
|
681
|
-
// Today's one entry is the pre-cutover inbox-identity migration: rows
|
|
682
|
-
// without identities or ISO-timestamp cursors are fatal to the strict
|
|
683
|
-
// reader and crash-loop every legacy broker at inbox seed.
|
|
684
771
|
operationIdContext.fresh(() => {
|
|
685
772
|
for (const migration of BOOT_MIGRATIONS) {
|
|
686
773
|
const result = migration.apply();
|
|
@@ -693,27 +780,65 @@ export async function runDaemon(opts = {}) {
|
|
|
693
780
|
}
|
|
694
781
|
}
|
|
695
782
|
});
|
|
696
|
-
// Startup epoch census (design flow C step 1): reap every prior-epoch
|
|
697
|
-
// broker on this canvas BEFORE the readiness mirror invites API traffic —
|
|
698
|
-
// no adoption across epochs, ever.
|
|
699
|
-
await operationIdContext.fresh(() => reapPriorEpochBrokers(epoch));
|
|
700
|
-
writePidfile();
|
|
701
|
-
// The Unix API socket is the daemon's readiness boundary. A rejected bind
|
|
702
|
-
// enters the existing startup catch, which closes resources and releases
|
|
703
|
-
// this invocation's pidfile mirror and ownership claim before propagating.
|
|
704
|
-
apiServer = createApiServer({ tcp: opts.tcp });
|
|
705
|
-
await apiServer.ready;
|
|
706
|
-
// Pre-warm the node pool for the most recent project recipes, so the first
|
|
707
|
-
// create after a boot is warm too. Fire-and-forget (the mints run off the
|
|
708
|
-
// work lane), so it never delays supervision. Boot-time dead rows are the
|
|
709
|
-
// node-lifecycle tick's business: the first tick classifies every one of
|
|
710
|
-
// them through the same policy table exit events use, under the same cap.
|
|
711
|
-
// Collect the spares this daemon's predecessor left behind BEFORE minting
|
|
712
|
-
// new ones: every broker of the prior epoch was torn down, and no sweep
|
|
713
|
-
// resumes a spare, so each is a dead row holding a node dir.
|
|
714
783
|
enqueue(() => { reapStaleSpares(); prewarmRecentRecipes(); });
|
|
715
784
|
intervalTimer = setInterval(enqueueTick, interval);
|
|
716
785
|
enqueueTick();
|
|
786
|
+
}
|
|
787
|
+
function resumeStartup() {
|
|
788
|
+
return resume ??= completeStartup().catch((error) => {
|
|
789
|
+
startup = {
|
|
790
|
+
phase: 'initializing',
|
|
791
|
+
message: 'daemon startup recovery failed and normal services are unavailable',
|
|
792
|
+
blockerPaths: [],
|
|
793
|
+
};
|
|
794
|
+
throw error;
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
try {
|
|
798
|
+
process.on('SIGINT', onSigint);
|
|
799
|
+
process.on('SIGTERM', onSigterm);
|
|
800
|
+
process.on('exit', onExit);
|
|
801
|
+
// Bind restricted diagnostics and repair before the socket can accept a
|
|
802
|
+
// request. No normal route is admitted until `startup` becomes ready.
|
|
803
|
+
bindDaemonEventSource();
|
|
804
|
+
const epoch = claim.token;
|
|
805
|
+
bindDaemonControl({ epoch, requestHandover, registerDetached, startupBlock, admitStartup, repairMigrations });
|
|
806
|
+
writePidfile();
|
|
807
|
+
// The socket is the repair boundary, not readiness. A rejected bind still
|
|
808
|
+
// enters this catch and releases this invocation's pidfile and ownership.
|
|
809
|
+
apiServer = createApiServer({ tcp: opts.tcp });
|
|
810
|
+
await apiServer.ready;
|
|
811
|
+
try {
|
|
812
|
+
await activateOnDiskMigrations({ nodes: listNodeMemoryTargets() });
|
|
813
|
+
}
|
|
814
|
+
catch (error) {
|
|
815
|
+
migrationInFlight = null;
|
|
816
|
+
if (error instanceof MigrationBlockedError) {
|
|
817
|
+
startup = {
|
|
818
|
+
phase: 'blocked',
|
|
819
|
+
message: error.message,
|
|
820
|
+
blockerPaths: error.blockerPaths,
|
|
821
|
+
};
|
|
822
|
+
return requestCleanup;
|
|
823
|
+
}
|
|
824
|
+
throw error;
|
|
825
|
+
}
|
|
826
|
+
try {
|
|
827
|
+
if (opts.prepare) {
|
|
828
|
+
startup = {
|
|
829
|
+
phase: 'prepared',
|
|
830
|
+
message: 'daemon storage is prepared and normal services are unavailable until admission',
|
|
831
|
+
blockerPaths: [],
|
|
832
|
+
};
|
|
833
|
+
}
|
|
834
|
+
else {
|
|
835
|
+
await resumeStartup();
|
|
836
|
+
startup = { phase: 'ready', message: '', blockerPaths: [] };
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
finally {
|
|
840
|
+
migrationInFlight = null;
|
|
841
|
+
}
|
|
717
842
|
return requestCleanup;
|
|
718
843
|
}
|
|
719
844
|
catch (startupError) {
|
package/dist/daemon/fleet.js
CHANGED
|
@@ -17,7 +17,7 @@ import { fullName } from '../core/canvas/labels.js';
|
|
|
17
17
|
import { isSafeNodeId } from '../core/canvas/paths.js';
|
|
18
18
|
import { transition } from '../core/runtime/lifecycle.js';
|
|
19
19
|
import { fanDoctrineWake } from '../core/runtime/close.js';
|
|
20
|
-
import {
|
|
20
|
+
import { readInterruptedTurn, readTransportPoisonVerdict } from '../core/canvas/recovery.js';
|
|
21
21
|
import { hasPendingWake } from './reconcilers/live-obligation.js';
|
|
22
22
|
import { clearRespawnPolicy, deferRespawnWhileOffline, MAX_RESPAWN_ATTEMPTS, OFFLINE_RESPAWN_RETRY_MS, recordRespawnPolicy, respawnBackoffMs, } from './reconcilers/node-lifecycle/respawn-policy.js';
|
|
23
23
|
import { probeOnline as probeOnlineReal } from '../core/runtime/connectivity.js';
|
|
@@ -300,11 +300,10 @@ export class DaemonFleet {
|
|
|
300
300
|
clearRespawnPolicy(nodeId);
|
|
301
301
|
return 'forget';
|
|
302
302
|
}
|
|
303
|
-
//
|
|
304
|
-
//
|
|
305
|
-
//
|
|
306
|
-
|
|
307
|
-
const interruptedTurn = isBusy(nodeId) || hasCleanAbort(nodeId);
|
|
303
|
+
// The execution-scoped turn witness survives either a dirty death or a
|
|
304
|
+
// broker-certified abort. Both need the same recovery: resume the saved
|
|
305
|
+
// transcript and re-drive the stopped turn.
|
|
306
|
+
const interruptedTurn = readInterruptedTurn(nodeId)?.interrupted === true;
|
|
308
307
|
const action = classifyDeadNode(meta, interruptedTurn, hasPendingWake(nodeId));
|
|
309
308
|
switch (action) {
|
|
310
309
|
case 'forget':
|
|
@@ -1,28 +1,16 @@
|
|
|
1
|
-
import { type CancelTicketOptions, type CompletePageOptions } from '../../core/human/tickets.js';
|
|
2
1
|
import type { TicketResult } from '../../core/human/types.js';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
* on whether completion reaches a bridge.
|
|
14
|
-
*/
|
|
2
|
+
export interface CompletePageOptions {
|
|
3
|
+
completedAt?: string;
|
|
4
|
+
actor?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface CancelTicketOptions {
|
|
7
|
+
reason?: string;
|
|
8
|
+
actor?: string;
|
|
9
|
+
disposition?: 'canceled' | 'dismissed';
|
|
10
|
+
}
|
|
11
|
+
/** Settle a page request directly in human_requests; result files and bridge nodes are not part of this path. */
|
|
15
12
|
export declare function resolvePageTicket(ticketId: string, responses: unknown, opts?: CompletePageOptions): Promise<TicketResult>;
|
|
16
|
-
/** Cancel a ticket with the store's first-writer-wins publication. */
|
|
17
13
|
export declare function cancelHumanTicket(ticketId: string, opts: CancelTicketOptions): Promise<TicketResult>;
|
|
18
|
-
/**
|
|
19
|
-
* settlement winner calls this; the daemon-start sweep replays it for a
|
|
20
|
-
* settlement that died before enqueueing, and the insert is idempotent on the
|
|
21
|
-
* request id so neither path can create a second delivery. */
|
|
22
|
-
export declare function releaseActionDelivery(ticketId: string): void;
|
|
23
|
-
/**
|
|
24
|
-
* Deliver a terminal ticket result to its bridge. The canonical response is the
|
|
25
|
-
* receipt: every action below is replay-safe, so lost delivery can be retried
|
|
26
|
-
* by a later resolve/cancel attempt or the daemon-start sweep.
|
|
27
|
-
*/
|
|
14
|
+
/** Legacy callers use this as a replay hook. Settlement effects are repaired by sweepHumanRequests. */
|
|
28
15
|
export declare function deliverTerminalResult(ticketId: string): Promise<boolean>;
|
|
16
|
+
export declare function settleFeedbackCompanion(ticketId: string, outcome: 'approved' | 'canceled'): Promise<void>;
|