@north-light/crouter 0.3.312 → 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 +13 -1
- 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 +16 -3
- 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 +51 -8
- 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 +2 -1
- package/dist/core/__tests__/on-read-dedup-resume.test.js +2 -1
- package/dist/core/__tests__/on-read-nested-store.test.js +2 -1
- 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 +4 -1
- 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 +2 -1
- 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 +18 -4
- 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/config.d.ts +17 -12
- package/dist/core/config.js +106 -155
- 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 +3 -2
- 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/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/placement.js +2 -2
- package/dist/core/runtime/recycle.js +8 -2
- package/dist/core/runtime/reset.js +22 -6
- package/dist/core/runtime/revive.js +226 -218
- package/dist/core/runtime/spawn.js +14 -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 +39 -15
- 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 +4 -1
- 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 +27 -41
- 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 -151
- 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.js +7 -13
- 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/index.d.ts +2 -1
- 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
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { test, beforeEach, afterEach } from 'node:test';
|
|
2
|
-
import assert from 'node:assert/strict';
|
|
3
|
-
import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
|
4
|
-
import { tmpdir } from 'node:os';
|
|
5
|
-
import { join } from 'node:path';
|
|
6
|
-
import { blockedMigrationIn, clearDaemonStartupBlocked, daemonStartupBlocked, recordDaemonStartupBlocked, } from '../startup-block-marker.js';
|
|
7
|
-
import { exclusiveLockOwnerPid, withExclusiveDirectoryLockAsync } from '../../core/exclusive-lock.js';
|
|
8
|
-
import { MigrationBlockedError } from '../../migrations/activation.js';
|
|
9
|
-
// REGRESSION (daemon respawn storm, cross-process half): the first fix for the
|
|
10
|
-
// storm kept its suppression in module state, which caps exactly ONE process.
|
|
11
|
-
// The storm is made of many — every CLI invocation and every scheduled tick is
|
|
12
|
-
// its own process — so 10 separate invocations against a permanently blocked
|
|
13
|
-
// home still produced 10 spawns. Suppression has to outlive a pid, and it has
|
|
14
|
-
// to retire itself when the corpus is repaired or it wedges a fixed install.
|
|
15
|
-
let home;
|
|
16
|
-
const previousHome = process.env['CRTR_HOME'];
|
|
17
|
-
beforeEach(() => {
|
|
18
|
-
home = mkdtempSync(join(tmpdir(), 'crtr-block-'));
|
|
19
|
-
process.env['CRTR_HOME'] = home;
|
|
20
|
-
});
|
|
21
|
-
afterEach(() => {
|
|
22
|
-
if (previousHome === undefined)
|
|
23
|
-
delete process.env['CRTR_HOME'];
|
|
24
|
-
else
|
|
25
|
-
process.env['CRTR_HOME'] = previousHome;
|
|
26
|
-
rmSync(home, { recursive: true, force: true });
|
|
27
|
-
});
|
|
28
|
-
test('a recorded block is visible to a DIFFERENT process reading the same home', () => {
|
|
29
|
-
const blocker = join(home, 'INDEX.md');
|
|
30
|
-
writeFileSync(blocker, 'front door');
|
|
31
|
-
assert.equal(daemonStartupBlocked(), null, 'nothing recorded yet');
|
|
32
|
-
recordDaemonStartupBlocked('migration blocked\nRepair: crtr sys migrate', [blocker]);
|
|
33
|
-
// A fresh process shares no memory with the recorder — only this file.
|
|
34
|
-
assert.match(daemonStartupBlocked() ?? '', /Repair: crtr sys migrate/);
|
|
35
|
-
});
|
|
36
|
-
test('the marker retires itself once the corpus it named changes', () => {
|
|
37
|
-
const blocker = join(home, 'INDEX.md');
|
|
38
|
-
writeFileSync(blocker, 'front door');
|
|
39
|
-
recordDaemonStartupBlocked('blocked', [blocker]);
|
|
40
|
-
assert.equal(daemonStartupBlocked(), 'blocked');
|
|
41
|
-
// The repair — by `crtr sys migrate`, an editor, or a delete. Whatever did
|
|
42
|
-
// it, the user must never need to know this marker exists.
|
|
43
|
-
writeFileSync(blocker, 'front door removed, plus enough bytes to change size');
|
|
44
|
-
assert.equal(daemonStartupBlocked(), null, 'a changed blocker lifts suppression');
|
|
45
|
-
});
|
|
46
|
-
test('a deleted blocker also retires the marker', () => {
|
|
47
|
-
const blocker = join(home, 'INDEX.md');
|
|
48
|
-
writeFileSync(blocker, 'front door');
|
|
49
|
-
recordDaemonStartupBlocked('blocked', [blocker]);
|
|
50
|
-
rmSync(blocker);
|
|
51
|
-
assert.equal(daemonStartupBlocked(), null);
|
|
52
|
-
});
|
|
53
|
-
test('a marker naming no blockers cannot wedge autostart forever', () => {
|
|
54
|
-
// Nothing about it can be observed to change, so it is advisory only.
|
|
55
|
-
recordDaemonStartupBlocked('blocked with no paths', []);
|
|
56
|
-
assert.equal(daemonStartupBlocked(), null);
|
|
57
|
-
});
|
|
58
|
-
test('clearing is idempotent and safe on a home with no marker', () => {
|
|
59
|
-
clearDaemonStartupBlocked();
|
|
60
|
-
clearDaemonStartupBlocked();
|
|
61
|
-
assert.equal(daemonStartupBlocked(), null);
|
|
62
|
-
});
|
|
63
|
-
// REGRESSION (reap kills a healthy daemon mid-migration): the reap escalates to
|
|
64
|
-
// SIGKILL, so it must be able to tell a child that is DOING the migration from
|
|
65
|
-
// one merely queued behind it. The lock marker already names its owner's pid.
|
|
66
|
-
test('the migration lock names its holder, so a reap can spare the one doing the work', async () => {
|
|
67
|
-
const lock = join(home, 'lock');
|
|
68
|
-
assert.equal(exclusiveLockOwnerPid(lock), null, 'a free lock names nobody');
|
|
69
|
-
await withExclusiveDirectoryLockAsync(lock, async () => {
|
|
70
|
-
assert.equal(exclusiveLockOwnerPid(lock), process.pid, 'the holder is named while held');
|
|
71
|
-
});
|
|
72
|
-
assert.equal(exclusiveLockOwnerPid(lock), null, 'released again');
|
|
73
|
-
});
|
|
74
|
-
// REGRESSION (the aggregate swallows the one error that matters): startup
|
|
75
|
-
// releases its ownership claim before rethrowing a migration failure, and a
|
|
76
|
-
// release that ALSO fails is reported as an AggregateError. The blocked
|
|
77
|
-
// migration must still be recognised through that wrapper, or the daemon exits
|
|
78
|
-
// generically and every downstream suppression stops working.
|
|
79
|
-
test('a blocked migration is still recognised inside a cleanup aggregate', () => {
|
|
80
|
-
const blocked = new MigrationBlockedError('blocked', ['/some/INDEX.md']);
|
|
81
|
-
const aggregate = new AggregateError([blocked, new Error('cleanup also failed')], 'startup failed');
|
|
82
|
-
const found = blockedMigrationIn(aggregate);
|
|
83
|
-
assert.ok(found instanceof MigrationBlockedError, 'found through the wrapper');
|
|
84
|
-
assert.deepEqual(found.blockerPaths, ['/some/INDEX.md']);
|
|
85
|
-
assert.equal(blockedMigrationIn(new Error('unrelated')), null, 'an ordinary failure is not claimed');
|
|
86
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert/strict';
|
|
2
|
-
import { mkdtempSync, rmSync } from 'node:fs';
|
|
3
|
-
import { tmpdir } from 'node:os';
|
|
4
|
-
import { join } from 'node:path';
|
|
5
|
-
import { test } from 'node:test';
|
|
6
|
-
import { closeDb, openDb } from '../../../core/canvas/db.js';
|
|
7
|
-
import { reviewResultPath } from '../../../core/canvas/paths.js';
|
|
8
|
-
import { toErrorBody } from '../map.js';
|
|
9
|
-
import { reviewCommentRoutes } from '../handlers/review-comments.js';
|
|
10
|
-
test('comment create reports the terminal review winner', async () => {
|
|
11
|
-
const home = mkdtempSync(join(tmpdir(), 'crtr-review-terminal-conflict-'));
|
|
12
|
-
const previousHome = process.env['CRTR_HOME'];
|
|
13
|
-
process.env['CRTR_HOME'] = home;
|
|
14
|
-
try {
|
|
15
|
-
const route = reviewCommentRoutes.find((candidate) => candidate.method === 'POST' && candidate.pattern === '/v1/human/reviews/:review_id/comments');
|
|
16
|
-
assert.ok(route, 'the canonical comment-create route is registered');
|
|
17
|
-
for (const terminal of [
|
|
18
|
-
{
|
|
19
|
-
state: 'canceled',
|
|
20
|
-
terminalColumns: ['2026-01-02T00:00:00.000Z', null, null, null, null, 'out of band cancel', 'human'],
|
|
21
|
-
terminalDTO: {
|
|
22
|
-
canceled_at: '2026-01-02T00:00:00.000Z',
|
|
23
|
-
cancel_reason: 'out of band cancel',
|
|
24
|
-
cancel_actor: 'human',
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
state: 'approved',
|
|
29
|
-
terminalColumns: [null, '2026-01-03T00:00:00.000Z', 1, 2, 1, null, null],
|
|
30
|
-
terminalDTO: {
|
|
31
|
-
approved_at: '2026-01-03T00:00:00.000Z',
|
|
32
|
-
changed: true,
|
|
33
|
-
comments_total: 2,
|
|
34
|
-
comments_unresolved: 1,
|
|
35
|
-
},
|
|
36
|
-
},
|
|
37
|
-
]) {
|
|
38
|
-
const reviewId = `${terminal.state}-review`;
|
|
39
|
-
openDb().prepare(`
|
|
40
|
-
INSERT INTO reviews
|
|
41
|
-
(review_id, idempotency_key, origin_kind, origin_node_id, companion_node_id, review_dir,
|
|
42
|
-
file, origin_session_file, origin_session_id, origin_leaf_id, model_spec, branch_file,
|
|
43
|
-
baseline_sha256, baseline_bytes, anchor_base_sha256, anchor_base_bytes, state, created, captured_at,
|
|
44
|
-
canceled_at, approved_at, changed, comments_total, comments_unresolved, cancel_reason, cancel_actor)
|
|
45
|
-
VALUES (?, ?, 'inline', 'origin', ?, '/tmp/review', '/tmp/source.md',
|
|
46
|
-
'/tmp/session.jsonl', 'session', 'leaf', 'anthropic/claude', '/tmp/branch.jsonl',
|
|
47
|
-
'baseline', 4, 'baseline', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
48
|
-
`).run(reviewId, `idempotency-${reviewId}`, `${terminal.state}-companion`, Buffer.from('base'), terminal.state, '2026-01-01T00:00:00.000Z', '2026-01-01T00:00:00.000Z', ...terminal.terminalColumns);
|
|
49
|
-
let thrown;
|
|
50
|
-
try {
|
|
51
|
-
await route.handler({
|
|
52
|
-
method: 'POST',
|
|
53
|
-
path: `/v1/human/reviews/${reviewId}/comments`,
|
|
54
|
-
params: { review_id: reviewId },
|
|
55
|
-
query: new URLSearchParams(),
|
|
56
|
-
body: {
|
|
57
|
-
text: 'late comment',
|
|
58
|
-
anchor: { line: 1, end_line: 1 },
|
|
59
|
-
doc_hash: 'a'.repeat(64),
|
|
60
|
-
actor_node_id: null,
|
|
61
|
-
},
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
catch (error) {
|
|
65
|
-
thrown = error;
|
|
66
|
-
}
|
|
67
|
-
const { status, body } = toErrorBody(thrown);
|
|
68
|
-
assert.equal(status, 409);
|
|
69
|
-
assert.equal(body.error.code, 'review_terminal_conflict');
|
|
70
|
-
assert.deepEqual(body.error.details, {
|
|
71
|
-
state: terminal.state,
|
|
72
|
-
requested: 'comment',
|
|
73
|
-
review: {
|
|
74
|
-
review_id: reviewId,
|
|
75
|
-
origin_kind: 'inline',
|
|
76
|
-
origin_node_id: 'origin',
|
|
77
|
-
bridge_node_id: null,
|
|
78
|
-
companion_node_id: `${terminal.state}-companion`,
|
|
79
|
-
file: '/tmp/source.md',
|
|
80
|
-
state: terminal.state,
|
|
81
|
-
created: '2026-01-01T00:00:00.000Z',
|
|
82
|
-
source_missing: true,
|
|
83
|
-
anchor_base_sha256: 'baseline',
|
|
84
|
-
...terminal.terminalDTO,
|
|
85
|
-
...(terminal.state === 'approved' ? { result_path: reviewResultPath(reviewId) } : {}),
|
|
86
|
-
},
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
finally {
|
|
91
|
-
closeDb();
|
|
92
|
-
rmSync(home, { recursive: true, force: true });
|
|
93
|
-
if (previousHome === undefined)
|
|
94
|
-
delete process.env['CRTR_HOME'];
|
|
95
|
-
else
|
|
96
|
-
process.env['CRTR_HOME'] = previousHome;
|
|
97
|
-
}
|
|
98
|
-
});
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
// Delivery of one settled human request to its declared completion action.
|
|
2
|
-
// The process contract lives in `daemon/delivery/run-delivery.ts`; this file
|
|
3
|
-
// binds it to the action-delivery row.
|
|
4
|
-
import { settleActionDelivery, } from '../../core/canvas/human-deliveries.js';
|
|
5
|
-
import { runDelivery } from '../delivery/run-delivery.js';
|
|
6
|
-
/** Spawn and settle one already-claimed action delivery. */
|
|
7
|
-
export async function deliverAction(delivery, claimOwner) {
|
|
8
|
-
await runDelivery({ argv: delivery.argv, cwd: delivery.cwd, document: delivery.completion, attempt: delivery.attempt }, (settlement) => settleActionDelivery(delivery.requestId, delivery.attempt, claimOwner, settlement, Date.now()));
|
|
9
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
// Delivery of one node's terminal outcome to its registered action target.
|
|
2
|
-
// The process contract lives in `daemon/delivery/run-delivery.ts`; this file
|
|
3
|
-
// binds it to the outcome-delivery row.
|
|
4
|
-
import { settleOutcomeDelivery, } from '../../core/canvas/node-outcome-deliveries.js';
|
|
5
|
-
import { runDelivery } from '../delivery/run-delivery.js';
|
|
6
|
-
/** Spawn and settle one already-claimed outcome delivery. */
|
|
7
|
-
export async function deliverOutcome(delivery, claimOwner) {
|
|
8
|
-
await runDelivery({ argv: delivery.argv, cwd: delivery.cwd, document: delivery.document, attempt: delivery.attempt }, (settlement) => settleOutcomeDelivery(delivery.nodeId, delivery.attempt, claimOwner, settlement, Date.now()));
|
|
9
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { DetachedWorkLifecycle } from './broker-supervision.js';
|
|
2
|
-
/** One daemon-life identity for guarded action-delivery claims. */
|
|
3
|
-
export declare const humanDeliveryDaemonInstanceId: `${string}-${string}-${string}-${string}-${string}`;
|
|
4
|
-
export interface HumanDeliveryLaneContext {
|
|
5
|
-
lifecycle: DetachedWorkLifecycle;
|
|
6
|
-
}
|
|
7
|
-
/** Admit due action deliveries without making the daemon's serial tick await subprocesses. */
|
|
8
|
-
export declare class HumanDeliveryLaneReconciler {
|
|
9
|
-
run(now: number, ctx: HumanDeliveryLaneContext): void;
|
|
10
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { randomUUID } from 'node:crypto';
|
|
2
|
-
import { claimActionDelivery, dueActionDeliveries } from '../../core/canvas/human-deliveries.js';
|
|
3
|
-
import { emitEvent } from '../../core/events/emit.js';
|
|
4
|
-
import { operationIdContext } from '../../core/events/operation-id.js';
|
|
5
|
-
import { deliverAction } from '../human/deliver-action.js';
|
|
6
|
-
/** One daemon-life identity for guarded action-delivery claims. */
|
|
7
|
-
export const humanDeliveryDaemonInstanceId = randomUUID();
|
|
8
|
-
/** Admit due action deliveries without making the daemon's serial tick await subprocesses. */
|
|
9
|
-
export class HumanDeliveryLaneReconciler {
|
|
10
|
-
run(now, ctx) {
|
|
11
|
-
if (!ctx.lifecycle.acceptsDetachedWork())
|
|
12
|
-
return;
|
|
13
|
-
let due;
|
|
14
|
-
try {
|
|
15
|
-
due = dueActionDeliveries(now);
|
|
16
|
-
}
|
|
17
|
-
catch (error) {
|
|
18
|
-
operationIdContext.fresh(() => {
|
|
19
|
-
emitEvent({ level: 'error', event: 'human.action_delivery.scan_failed', error });
|
|
20
|
-
});
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
for (const candidate of due) {
|
|
24
|
-
try {
|
|
25
|
-
const claimed = claimActionDelivery(candidate.requestId, now, humanDeliveryDaemonInstanceId);
|
|
26
|
-
if (claimed === null)
|
|
27
|
-
continue;
|
|
28
|
-
ctx.lifecycle.registerDetached(deliverAction(claimed, humanDeliveryDaemonInstanceId).catch((error) => {
|
|
29
|
-
operationIdContext.fresh(() => {
|
|
30
|
-
emitEvent({ level: 'error', event: 'human.action_delivery.failed', error, fields: { request_id: claimed.requestId } });
|
|
31
|
-
});
|
|
32
|
-
}));
|
|
33
|
-
}
|
|
34
|
-
catch (error) {
|
|
35
|
-
operationIdContext.fresh(() => {
|
|
36
|
-
emitEvent({ level: 'error', event: 'human.action_delivery.claim_failed', error, fields: { request_id: candidate.requestId } });
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { DetachedWorkLifecycle } from './broker-supervision.js';
|
|
2
|
-
/** One daemon-life identity for guarded outcome-delivery claims. */
|
|
3
|
-
export declare const outcomeDeliveryDaemonInstanceId: `${string}-${string}-${string}-${string}-${string}`;
|
|
4
|
-
export interface NodeOutcomeDeliveryLaneContext {
|
|
5
|
-
lifecycle: DetachedWorkLifecycle;
|
|
6
|
-
}
|
|
7
|
-
/** Admit due outcome deliveries without making the daemon's serial tick await subprocesses. */
|
|
8
|
-
export declare class NodeOutcomeDeliveryLaneReconciler {
|
|
9
|
-
run(now: number, ctx: NodeOutcomeDeliveryLaneContext): void;
|
|
10
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { randomUUID } from 'node:crypto';
|
|
2
|
-
import { claimOutcomeDelivery, dueOutcomeDeliveries } from '../../core/canvas/node-outcome-deliveries.js';
|
|
3
|
-
import { emitEvent } from '../../core/events/emit.js';
|
|
4
|
-
import { operationIdContext } from '../../core/events/operation-id.js';
|
|
5
|
-
import { deliverOutcome } from '../node-outcome/deliver-outcome.js';
|
|
6
|
-
/** One daemon-life identity for guarded outcome-delivery claims. */
|
|
7
|
-
export const outcomeDeliveryDaemonInstanceId = randomUUID();
|
|
8
|
-
/** Admit due outcome deliveries without making the daemon's serial tick await subprocesses. */
|
|
9
|
-
export class NodeOutcomeDeliveryLaneReconciler {
|
|
10
|
-
run(now, ctx) {
|
|
11
|
-
if (!ctx.lifecycle.acceptsDetachedWork())
|
|
12
|
-
return;
|
|
13
|
-
let due;
|
|
14
|
-
try {
|
|
15
|
-
due = dueOutcomeDeliveries(now);
|
|
16
|
-
}
|
|
17
|
-
catch (error) {
|
|
18
|
-
operationIdContext.fresh(() => {
|
|
19
|
-
emitEvent({ level: 'error', event: 'node_outcome.delivery.scan_failed', error });
|
|
20
|
-
});
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
for (const candidate of due) {
|
|
24
|
-
try {
|
|
25
|
-
const claimed = claimOutcomeDelivery(candidate.nodeId, now, outcomeDeliveryDaemonInstanceId);
|
|
26
|
-
if (claimed === null)
|
|
27
|
-
continue;
|
|
28
|
-
ctx.lifecycle.registerDetached(deliverOutcome(claimed, outcomeDeliveryDaemonInstanceId).catch((error) => {
|
|
29
|
-
operationIdContext.fresh(() => {
|
|
30
|
-
emitEvent({ level: 'error', event: 'node_outcome.delivery.failed', error, fields: { node_id: claimed.nodeId } });
|
|
31
|
-
});
|
|
32
|
-
}));
|
|
33
|
-
}
|
|
34
|
-
catch (error) {
|
|
35
|
-
operationIdContext.fresh(() => {
|
|
36
|
-
emitEvent({ level: 'error', event: 'node_outcome.delivery.claim_failed', error, fields: { node_id: candidate.nodeId } });
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { MigrationBlockedError } from '../migrations/activation.js';
|
|
2
|
-
export declare function daemonStartupBlockMarkerPath(): string;
|
|
3
|
-
/** Record that startup is blocked, so no OTHER process spawns into the same
|
|
4
|
-
* wall. Best-effort: a home we cannot write to still gets in-process
|
|
5
|
-
* suppression, which is strictly better than nothing. */
|
|
6
|
-
export declare function recordDaemonStartupBlocked(message: string, blockerPaths: readonly string[]): void;
|
|
7
|
-
/** Clear the marker — for a repair path that knows startup should be retried
|
|
8
|
-
* (a successful migration, a successful daemon start, an explicit reset). */
|
|
9
|
-
export declare function clearDaemonStartupBlocked(): void;
|
|
10
|
-
/** The recorded block message when startup is still blocked by the SAME corpus
|
|
11
|
-
* that produced it, or null when nothing is recorded or the corpus has since
|
|
12
|
-
* changed. A changed corpus retires the marker as a side effect of the read,
|
|
13
|
-
* so the very next spawner is free to try again.
|
|
14
|
-
*
|
|
15
|
-
* A marker naming no blocker paths at all is not self-healing — nothing about
|
|
16
|
-
* it can be observed to change — so it is treated as advisory only and
|
|
17
|
-
* retired on read rather than left to wedge autostart forever. */
|
|
18
|
-
export declare function daemonStartupBlocked(): string | null;
|
|
19
|
-
/** The blocked-migration failure, wherever it ended up in a thrown value.
|
|
20
|
-
* Startup releases its ownership claim before rethrowing, and a claim release
|
|
21
|
-
* that ALSO fails is reported as an aggregate — so the one error the spawner
|
|
22
|
-
* must react to can arrive nested. Matching only the bare instance would let
|
|
23
|
-
* the aggregate path fall through to a generic exit, and every suppression
|
|
24
|
-
* downstream is keyed on getting that exit code right. */
|
|
25
|
-
export declare function blockedMigrationIn(error: unknown): MigrationBlockedError | null;
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
// A blocked daemon startup is a STANDING condition, and the processes that
|
|
2
|
-
// keep retrying it are not one process. Every CLI invocation, every scheduled
|
|
3
|
-
// job tick, and every long-lived client is its own process with its own module
|
|
4
|
-
// state, so an in-memory suppression flag caps exactly one of them and lets the
|
|
5
|
-
// rest storm unchanged. This marker is that suppression made durable: one file
|
|
6
|
-
// in the canvas home, written by whoever first proved startup is blocked, and
|
|
7
|
-
// read by every would-be spawner before it spawns.
|
|
8
|
-
//
|
|
9
|
-
// The hazard of a durable "stop trying" record is that it outlives the problem
|
|
10
|
-
// and wedges a repaired install. So the marker is self-healing rather than
|
|
11
|
-
// permanent: it records the identity (path + size + mtime) of each blocker the
|
|
12
|
-
// daemon named, and any change to any of them retires the marker on the next
|
|
13
|
-
// read. Repairing the corpus — by `crtr sys migrate`, an editor, or deleting
|
|
14
|
-
// the offending file — is itself the thing that lifts the suppression, so no
|
|
15
|
-
// user is ever required to know this file exists.
|
|
16
|
-
import { rmSync } from 'node:fs';
|
|
17
|
-
import { statSync } from 'node:fs';
|
|
18
|
-
import { join } from 'node:path';
|
|
19
|
-
import { crtrHome } from '../core/canvas/paths.js';
|
|
20
|
-
import { MigrationBlockedError } from '../migrations/activation.js';
|
|
21
|
-
import { atomicWriteJson, readJsonOrNull } from '../core/fs-utils.js';
|
|
22
|
-
export function daemonStartupBlockMarkerPath() {
|
|
23
|
-
return join(crtrHome(), 'daemon-startup-blocked.json');
|
|
24
|
-
}
|
|
25
|
-
function fingerprint(path) {
|
|
26
|
-
try {
|
|
27
|
-
const stat = statSync(path);
|
|
28
|
-
return { path, sizeBytes: stat.size, mtimeMs: stat.mtimeMs };
|
|
29
|
-
}
|
|
30
|
-
catch {
|
|
31
|
-
return { path, sizeBytes: null, mtimeMs: null };
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
function sameFingerprint(a, b) {
|
|
35
|
-
return a.sizeBytes === b.sizeBytes && a.mtimeMs === b.mtimeMs;
|
|
36
|
-
}
|
|
37
|
-
/** Record that startup is blocked, so no OTHER process spawns into the same
|
|
38
|
-
* wall. Best-effort: a home we cannot write to still gets in-process
|
|
39
|
-
* suppression, which is strictly better than nothing. */
|
|
40
|
-
export function recordDaemonStartupBlocked(message, blockerPaths) {
|
|
41
|
-
const marker = {
|
|
42
|
-
recordedAt: Date.now(),
|
|
43
|
-
message,
|
|
44
|
-
blockers: blockerPaths.map(fingerprint),
|
|
45
|
-
};
|
|
46
|
-
try {
|
|
47
|
-
atomicWriteJson(daemonStartupBlockMarkerPath(), marker);
|
|
48
|
-
}
|
|
49
|
-
catch { /* best effort */ }
|
|
50
|
-
}
|
|
51
|
-
/** Clear the marker — for a repair path that knows startup should be retried
|
|
52
|
-
* (a successful migration, a successful daemon start, an explicit reset). */
|
|
53
|
-
export function clearDaemonStartupBlocked() {
|
|
54
|
-
try {
|
|
55
|
-
rmSync(daemonStartupBlockMarkerPath(), { force: true });
|
|
56
|
-
}
|
|
57
|
-
catch { /* best effort */ }
|
|
58
|
-
}
|
|
59
|
-
/** The recorded block message when startup is still blocked by the SAME corpus
|
|
60
|
-
* that produced it, or null when nothing is recorded or the corpus has since
|
|
61
|
-
* changed. A changed corpus retires the marker as a side effect of the read,
|
|
62
|
-
* so the very next spawner is free to try again.
|
|
63
|
-
*
|
|
64
|
-
* A marker naming no blocker paths at all is not self-healing — nothing about
|
|
65
|
-
* it can be observed to change — so it is treated as advisory only and
|
|
66
|
-
* retired on read rather than left to wedge autostart forever. */
|
|
67
|
-
export function daemonStartupBlocked() {
|
|
68
|
-
const marker = readJsonOrNull(daemonStartupBlockMarkerPath());
|
|
69
|
-
if (marker === null || typeof marker.message !== 'string' || !Array.isArray(marker.blockers))
|
|
70
|
-
return null;
|
|
71
|
-
if (marker.blockers.length === 0) {
|
|
72
|
-
clearDaemonStartupBlocked();
|
|
73
|
-
return null;
|
|
74
|
-
}
|
|
75
|
-
const changed = marker.blockers.some((recorded) => !sameFingerprint(recorded, fingerprint(recorded.path)));
|
|
76
|
-
if (changed) {
|
|
77
|
-
clearDaemonStartupBlocked();
|
|
78
|
-
return null;
|
|
79
|
-
}
|
|
80
|
-
return marker.message;
|
|
81
|
-
}
|
|
82
|
-
/** The blocked-migration failure, wherever it ended up in a thrown value.
|
|
83
|
-
* Startup releases its ownership claim before rethrowing, and a claim release
|
|
84
|
-
* that ALSO fails is reported as an aggregate — so the one error the spawner
|
|
85
|
-
* must react to can arrive nested. Matching only the bare instance would let
|
|
86
|
-
* the aggregate path fall through to a generic exit, and every suppression
|
|
87
|
-
* downstream is keyed on getting that exit code right. */
|
|
88
|
-
export function blockedMigrationIn(error) {
|
|
89
|
-
if (error instanceof MigrationBlockedError)
|
|
90
|
-
return error;
|
|
91
|
-
if (error instanceof AggregateError) {
|
|
92
|
-
for (const nested of error.errors) {
|
|
93
|
-
const found = blockedMigrationIn(nested);
|
|
94
|
-
if (found !== null)
|
|
95
|
-
return found;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
return null;
|
|
99
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|