@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
|
@@ -3,12 +3,22 @@ import assert from 'node:assert/strict';
|
|
|
3
3
|
import { mkdtempSync, rmSync, mkdirSync, writeFileSync, existsSync, readdirSync } from 'node:fs';
|
|
4
4
|
import { tmpdir } from 'node:os';
|
|
5
5
|
import { join } from 'node:path';
|
|
6
|
-
import { createNode, getNode, subscribe, subscriptionsOf } from '../canvas/canvas.js';
|
|
6
|
+
import { createNode as createRawNode, getNode, subscribe, subscriptionsOf } from '../canvas/canvas.js';
|
|
7
7
|
import { nodeDir } from '../canvas/paths.js';
|
|
8
|
-
import { closeDb } from '../canvas/db.js';
|
|
8
|
+
import { closeDb, openDb, migrate } from '../canvas/db.js';
|
|
9
|
+
import { beginExecution } from '../canvas/executions.js';
|
|
10
|
+
import { bindSession } from '../canvas/sessions.js';
|
|
9
11
|
import { closeNode } from '../runtime/close.js';
|
|
10
12
|
import { reapEmptyNodes } from '../runtime/placement.js';
|
|
11
|
-
|
|
13
|
+
function nodeMail(nodeId) {
|
|
14
|
+
return openDb().prepare(`SELECT m.sender_node_id AS "from", m.kind, m.label, m.body_ref AS ref, m.body_json AS data
|
|
15
|
+
FROM deliveries d JOIN messages m ON m.message_id = d.message_id
|
|
16
|
+
WHERE d.destination_kind = 'node_inbox' AND d.destination_id = ?
|
|
17
|
+
ORDER BY m.seq`).all(nodeId).map((row) => ({
|
|
18
|
+
...row,
|
|
19
|
+
data: row.data === null ? null : JSON.parse(row.data),
|
|
20
|
+
}));
|
|
21
|
+
}
|
|
12
22
|
import { FinalizationError, pushFinal } from '../feed/feed.js';
|
|
13
23
|
let home;
|
|
14
24
|
/** Write a minimal pi session containing one assistant message, so the node
|
|
@@ -22,6 +32,14 @@ function withSession(id) {
|
|
|
22
32
|
writeFileSync(f, JSON.stringify({ type: 'message', message: { role: 'assistant', content: [{ type: 'text', text: 'hi' }] } }) + '\n');
|
|
23
33
|
return f;
|
|
24
34
|
}
|
|
35
|
+
function createNode(meta) {
|
|
36
|
+
const created = createRawNode(meta);
|
|
37
|
+
if (meta.pi_session_file !== null && meta.pi_session_file !== undefined) {
|
|
38
|
+
const executionId = beginExecution(meta.node_id, { daemonEpoch: 'test' });
|
|
39
|
+
assert.equal(bindSession(meta.node_id, { executionId, sessionId: meta.pi_session_id ?? meta.node_id, transcriptPath: meta.pi_session_file }), 'bound');
|
|
40
|
+
}
|
|
41
|
+
return created;
|
|
42
|
+
}
|
|
25
43
|
function node(id, over = {}) {
|
|
26
44
|
return {
|
|
27
45
|
node_id: id,
|
|
@@ -48,6 +66,7 @@ before(() => {
|
|
|
48
66
|
beforeEach(() => {
|
|
49
67
|
closeDb();
|
|
50
68
|
rmSync(home, { recursive: true, force: true });
|
|
69
|
+
migrate(openDb());
|
|
51
70
|
});
|
|
52
71
|
after(() => {
|
|
53
72
|
closeDb();
|
|
@@ -105,18 +124,18 @@ test('appends a resume notice naming the dead children to each closed node', ()
|
|
|
105
124
|
spawnEdge('N', 'A');
|
|
106
125
|
spawnEdge('A', 'C');
|
|
107
126
|
closeNode('N');
|
|
108
|
-
const nNotice =
|
|
127
|
+
const nNotice = nodeMail('N').at(-1);
|
|
109
128
|
assert.equal(nNotice.from, null);
|
|
110
129
|
assert.equal(nNotice.kind, 'message');
|
|
111
130
|
assert.match(nNotice.label, /CLOSED by the user/);
|
|
112
131
|
assert.match(nNotice.label, /A \(A\)/); // dead child named
|
|
113
132
|
assert.deepEqual(nNotice.data?.['canceled_children'], ['A']);
|
|
114
133
|
assert.equal(nNotice.data?.['cascade_root'], 'N');
|
|
115
|
-
const aNotice =
|
|
134
|
+
const aNotice = nodeMail('A').at(-1);
|
|
116
135
|
assert.match(aNotice.label, /CANCELED/);
|
|
117
136
|
assert.match(aNotice.label, /C \(C\)/);
|
|
118
137
|
// A leaf has no dead children — gets the short "session preserved" notice.
|
|
119
|
-
const cNotice =
|
|
138
|
+
const cNotice = nodeMail('C').at(-1);
|
|
120
139
|
assert.match(cNotice.label, /session is preserved/);
|
|
121
140
|
assert.deepEqual(cNotice.data?.['canceled_children'], []);
|
|
122
141
|
});
|
|
@@ -169,7 +188,7 @@ test('close first suppresses a later final publication and its subscriber pointe
|
|
|
169
188
|
await assert.rejects(() => pushFinal('child', 'too late'), (error) => error instanceof FinalizationError && error.code === 'finalization_forbidden');
|
|
170
189
|
assert.equal(getNode('child')?.final_report, null, 'close owns the terminal outcome');
|
|
171
190
|
assert.deepEqual(readdirSync(join(nodeDir('child'), 'reports')).filter((name) => name.endsWith('-final.md')), [], 'a rejected final leaves no canonical report');
|
|
172
|
-
assert.equal(
|
|
191
|
+
assert.equal(nodeMail('manager').filter((entry) => entry.kind === 'final').length, 0, 'a rejected final never wakes a subscriber with a final pointer');
|
|
173
192
|
});
|
|
174
193
|
test('final publication first remains the one canonical final after close', async () => {
|
|
175
194
|
createNode(node('child'));
|
|
@@ -184,7 +203,7 @@ test('final publication first remains the one canonical final after close', asyn
|
|
|
184
203
|
assert.equal(child.intent, 'done');
|
|
185
204
|
assert.equal(child.final_report, canonical, 'close preserves the original canonical marker');
|
|
186
205
|
assert.ok(existsSync(publication.reportPath), 'the canonical report remains on disk');
|
|
187
|
-
const finalPointers =
|
|
206
|
+
const finalPointers = nodeMail('manager').filter((entry) => entry.kind === 'final');
|
|
188
207
|
assert.equal(finalPointers.length, 1, 'the manager receives exactly one final pointer');
|
|
189
208
|
assert.equal(finalPointers[0]?.ref, `child:reports/${canonical}`);
|
|
190
209
|
});
|
|
@@ -239,7 +258,7 @@ test('closing an EMPTY node with an open managed worktree cancels it without rea
|
|
|
239
258
|
assert.equal(meta?.managed_worktree?.state, 'open', 'node retains worktree ownership');
|
|
240
259
|
assert.ok(existsSync(dir), 'node dir remains');
|
|
241
260
|
assert.ok(existsSync(worktreePath), 'managed checkout remains reachable through its node');
|
|
242
|
-
assert.match(
|
|
261
|
+
assert.match(nodeMail(id).at(-1)?.label ?? '', /session is preserved/);
|
|
243
262
|
assert.deepEqual(reapEmptyNodes(), [], 'bulk empty reap also preserves the open managed worktree node');
|
|
244
263
|
assert.equal(getNode(id)?.managed_worktree?.state, 'open', 'bulk reap retains worktree ownership');
|
|
245
264
|
});
|
|
@@ -251,7 +270,7 @@ test('reaping an empty child still notifies a surviving external manager', () =>
|
|
|
251
270
|
spawnEdge('mgr', 'child');
|
|
252
271
|
closeNode('child');
|
|
253
272
|
assert.equal(getNode('child'), null, 'empty child reaped');
|
|
254
|
-
const note =
|
|
273
|
+
const note = nodeMail('mgr').at(-1);
|
|
255
274
|
assert.match(note.label, /Child closed/);
|
|
256
275
|
assert.equal(note.data?.['child'], 'child');
|
|
257
276
|
});
|
|
@@ -4,7 +4,7 @@ import { mkdtempSync, rmSync } from 'node:fs';
|
|
|
4
4
|
import { tmpdir } from 'node:os';
|
|
5
5
|
import { join } from 'node:path';
|
|
6
6
|
import { createNode, getRow, isCollectible, setFrozen, transitionStatusIntent, } from '../canvas/canvas.js';
|
|
7
|
-
import { closeDb } from '../canvas/db.js';
|
|
7
|
+
import { closeDb, migrate, openDb } from '../canvas/db.js';
|
|
8
8
|
let home;
|
|
9
9
|
function node(id, over = {}) {
|
|
10
10
|
return {
|
|
@@ -31,6 +31,7 @@ before(() => {
|
|
|
31
31
|
beforeEach(() => {
|
|
32
32
|
closeDb();
|
|
33
33
|
rmSync(home, { recursive: true, force: true });
|
|
34
|
+
migrate(openDb());
|
|
34
35
|
});
|
|
35
36
|
after(() => {
|
|
36
37
|
closeDb();
|
|
@@ -11,6 +11,7 @@ import assert from 'node:assert/strict';
|
|
|
11
11
|
import { mkdtempSync, mkdirSync, realpathSync, rmSync, writeFileSync } from 'node:fs';
|
|
12
12
|
import { tmpdir } from 'node:os';
|
|
13
13
|
import { join } from 'node:path';
|
|
14
|
+
import { ensureScopeInitialized } from '../config.js';
|
|
14
15
|
import { resetScopeCache } from '../scope.js';
|
|
15
16
|
import { clearSessionCache } from '../substrate/session-cache.js';
|
|
16
17
|
import { renderConfigChangeDelta, renderKnowledgeForSubject, renderPreferencesForSubject, } from '../substrate/render.js';
|
|
@@ -60,6 +61,7 @@ before(() => {
|
|
|
60
61
|
writeFileSync(join(user, 'delta-dev-knowledge.md'), ['---', 'kind: knowledge', `when-and-why-to-read: "${DEV_KNOWLEDGE_WHEN}"`, 'gate: {kind: developer}', 'surfaces:', ' - {on: boot, at: preview}', '---', '', 'ignored body', ''].join('\n'));
|
|
61
62
|
process.chdir(work);
|
|
62
63
|
resetScopeCache();
|
|
64
|
+
ensureScopeInitialized('user', join(home, '.crouter'));
|
|
63
65
|
clearSessionCache();
|
|
64
66
|
});
|
|
65
67
|
after(() => {
|
|
@@ -11,7 +11,9 @@ import assert from 'node:assert/strict';
|
|
|
11
11
|
import { existsSync, mkdtempSync, mkdirSync, rmSync } from 'node:fs';
|
|
12
12
|
import { tmpdir } from 'node:os';
|
|
13
13
|
import { join } from 'node:path';
|
|
14
|
-
import { closeDb } from '../canvas/db.js';
|
|
14
|
+
import { closeDb, migrate, openDb } from '../canvas/db.js';
|
|
15
|
+
import { ensureScopeInitialized } from '../config.js';
|
|
16
|
+
import { closeScopedStores } from '../scoped-state/db.js';
|
|
15
17
|
import { apiSocketPath } from '../canvas/paths.js';
|
|
16
18
|
import { spawnNode } from '../runtime/nodes.js';
|
|
17
19
|
import { appendSituationalContext, formatSituationalProse, situationalContextEnvelope, } from '../runtime/situational-context.js';
|
|
@@ -19,6 +21,7 @@ import registerCanvasContextIntro, { CONTEXT_INTRO_CUSTOM_TYPE, } from '../../pi
|
|
|
19
21
|
import { buildContextBearings as buildContextIntro } from '../runtime/bearings.js';
|
|
20
22
|
import { createApiServer } from '../../daemon/api/server.js';
|
|
21
23
|
let home;
|
|
24
|
+
let priorUserHome;
|
|
22
25
|
let server;
|
|
23
26
|
async function waitForSocket(path) {
|
|
24
27
|
for (let i = 0; i < 200; i++) {
|
|
@@ -30,26 +33,35 @@ async function waitForSocket(path) {
|
|
|
30
33
|
}
|
|
31
34
|
before(() => {
|
|
32
35
|
home = mkdtempSync(join(tmpdir(), 'crtr-ctxintro-'));
|
|
36
|
+
priorUserHome = process.env['HOME'];
|
|
37
|
+
process.env['HOME'] = home;
|
|
33
38
|
process.env['CRTR_HOME'] = home;
|
|
34
39
|
});
|
|
35
40
|
beforeEach(async () => {
|
|
36
41
|
closeDb();
|
|
37
42
|
rmSync(home, { recursive: true, force: true });
|
|
38
43
|
mkdirSync(home, { recursive: true });
|
|
44
|
+
ensureScopeInitialized('user', join(home, '.crouter'));
|
|
45
|
+
migrate(openDb());
|
|
39
46
|
server = createApiServer();
|
|
40
47
|
await waitForSocket(apiSocketPath());
|
|
41
48
|
});
|
|
42
49
|
afterEach(async () => {
|
|
43
50
|
await server.close();
|
|
51
|
+
closeScopedStores();
|
|
44
52
|
});
|
|
45
53
|
after(() => {
|
|
46
54
|
closeDb();
|
|
47
55
|
rmSync(home, { recursive: true, force: true });
|
|
48
56
|
delete process.env['CRTR_HOME'];
|
|
49
57
|
delete process.env['CRTR_NODE_ID'];
|
|
58
|
+
if (priorUserHome === undefined)
|
|
59
|
+
delete process.env['HOME'];
|
|
60
|
+
else
|
|
61
|
+
process.env['HOME'] = priorUserHome;
|
|
50
62
|
});
|
|
51
|
-
test('the stored situational card rides the bearings body; absent when unset', () => {
|
|
52
|
-
const meta = spawnNode({ kind: 'general', cwd: '/tmp/work', parent: null });
|
|
63
|
+
test('the stored situational card rides the bearings body; absent when unset', async () => {
|
|
64
|
+
const meta = await spawnNode({ kind: 'general', cwd: '/tmp/work', parent: null });
|
|
53
65
|
assert.equal(situationalContextEnvelope(meta.node_id), null, 'no card until something is set');
|
|
54
66
|
assert.doesNotMatch(buildContextIntro(meta.node_id), /kind="situational"/, 'bearings carry no card when unset');
|
|
55
67
|
appendSituationalContext(meta.node_id, formatSituationalProse('user is looking at the billing applet'));
|
|
@@ -73,7 +85,7 @@ function fakeCtx(pi) {
|
|
|
73
85
|
return { sessionManager: { getBranch: () => pi.entries } };
|
|
74
86
|
}
|
|
75
87
|
test('session_start injects the block as the first message of an empty session', async () => {
|
|
76
|
-
const meta = spawnNode({ kind: 'general', cwd: '/tmp/work', parent: null });
|
|
88
|
+
const meta = await spawnNode({ kind: 'general', cwd: '/tmp/work', parent: null });
|
|
77
89
|
process.env['CRTR_NODE_ID'] = meta.node_id;
|
|
78
90
|
const pi = makeFakePi();
|
|
79
91
|
registerCanvasContextIntro(pi);
|
|
@@ -87,7 +99,7 @@ test('session_start injects the block as the first message of an empty session',
|
|
|
87
99
|
assert.match(pi.sent[0].content, /<crtr-bearings>/);
|
|
88
100
|
});
|
|
89
101
|
test('session_start is idempotent across resume (skips if already in history)', async () => {
|
|
90
|
-
const meta = spawnNode({ kind: 'general', cwd: '/tmp/work', parent: null });
|
|
102
|
+
const meta = await spawnNode({ kind: 'general', cwd: '/tmp/work', parent: null });
|
|
91
103
|
process.env['CRTR_NODE_ID'] = meta.node_id;
|
|
92
104
|
// Restored session already carries OUR block (which names this node id) → no
|
|
93
105
|
// duplicate injection. The content matters: the guard is fork-aware and only
|
|
@@ -12,8 +12,10 @@ import { tmpdir } from 'node:os';
|
|
|
12
12
|
import { join } from 'node:path';
|
|
13
13
|
import { listNodes } from '../canvas/canvas.js';
|
|
14
14
|
import { armCron, getCron, listCronRuns } from '../canvas/crons.js';
|
|
15
|
-
import { closeDb } from '../canvas/db.js';
|
|
16
|
-
import {
|
|
15
|
+
import { closeDb, migrate, openDb } from '../canvas/db.js';
|
|
16
|
+
import { ensureScopeInitialized } from '../config.js';
|
|
17
|
+
import { closeScopedStores } from '../scoped-state/db.js';
|
|
18
|
+
import { createProfile, deleteProfile, profileManifestPath } from '../profiles/manifest.js';
|
|
17
19
|
import { resetScopeCache } from '../scope.js';
|
|
18
20
|
import { headlessBrokerHost } from '../runtime/host.js';
|
|
19
21
|
import { resetFleetForTests } from '../runtime/fleet.js';
|
|
@@ -78,10 +80,13 @@ beforeEach(() => {
|
|
|
78
80
|
fleet.fleet.register(nodeId, handle);
|
|
79
81
|
return handle;
|
|
80
82
|
});
|
|
83
|
+
ensureScopeInitialized('user', join(userHome, '.crouter'));
|
|
84
|
+
migrate(openDb());
|
|
81
85
|
});
|
|
82
86
|
afterEach(() => {
|
|
83
87
|
headlessBrokerHost.launch = originalLaunch;
|
|
84
88
|
closeDb();
|
|
89
|
+
closeScopedStores();
|
|
85
90
|
resetFleetForTests();
|
|
86
91
|
});
|
|
87
92
|
after(() => {
|
|
@@ -126,17 +131,17 @@ test('a corrupt armed env snapshot fails the run instead of silently dropping th
|
|
|
126
131
|
assertSettledAsArmingFailure(id, record, /run could not be armed: the armed env snapshot/, nodesBefore);
|
|
127
132
|
}
|
|
128
133
|
});
|
|
129
|
-
test('
|
|
130
|
-
const
|
|
134
|
+
test('a profile artifact is ignored while a deleted SQL profile runs as root', async () => {
|
|
135
|
+
const existing = createProfile('cron-existing').profileId;
|
|
131
136
|
const deleted = createProfile('cron-deleted').profileId;
|
|
132
|
-
//
|
|
133
|
-
//
|
|
134
|
-
writeFileSync(profileManifestPath(
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
137
|
+
// Profile identity is SQL-authoritative. The legacy artifact cannot change
|
|
138
|
+
// the context an already-armed run uses.
|
|
139
|
+
writeFileSync(profileManifestPath(existing), '{ not json', 'utf8');
|
|
140
|
+
arm({ cron_id: 'profile-existing', profile: existing });
|
|
141
|
+
const ranExisting = await executeCron(getCron('profile-existing'), { outOfBand: false });
|
|
142
|
+
assert.equal(ranExisting?.exit_code, 0, 'a corrupt profile artifact does not alter the SQL profile context');
|
|
143
|
+
assert.equal(readFileSync(marker('profile-existing'), 'utf8'), existing, 'the run retains the SQL-backed profile identity');
|
|
144
|
+
deleteProfile(deleted);
|
|
140
145
|
arm({ cron_id: 'profile-deleted', profile: deleted });
|
|
141
146
|
const ran = await executeCron(getCron('profile-deleted'), { outOfBand: false });
|
|
142
147
|
assert.equal(ran?.exit_code, 0, 'a deleted profile is the spec root fallback — the run proceeds');
|
|
@@ -7,19 +7,22 @@
|
|
|
7
7
|
// consumption — and a poke (`pokeHeldCrons`) re-dues every held active row
|
|
8
8
|
// now. These pin the branch's truth table: the exact class of scheduling
|
|
9
9
|
// defect that otherwise fails silently weeks later.
|
|
10
|
-
import { after, afterEach, before, test } from 'node:test';
|
|
10
|
+
import { after, afterEach, before, beforeEach, test } from 'node:test';
|
|
11
11
|
import assert from 'node:assert/strict';
|
|
12
|
-
import { mkdtempSync, rmSync } from 'node:fs';
|
|
12
|
+
import { mkdtempSync, mkdirSync, rmSync } from 'node:fs';
|
|
13
13
|
import { tmpdir } from 'node:os';
|
|
14
14
|
import { join } from 'node:path';
|
|
15
15
|
import { setTimeout as delay } from 'node:timers/promises';
|
|
16
|
-
import { closeDb, openDb } from '../canvas/db.js';
|
|
16
|
+
import { closeDb, migrate, openDb } from '../canvas/db.js';
|
|
17
|
+
import { ensureScopeInitialized } from '../config.js';
|
|
18
|
+
import { closeScopedStores } from '../scoped-state/db.js';
|
|
17
19
|
import { armCron, cancelCron, getCron, listCronRuns, pokeHeldCrons, setCronState, } from '../canvas/crons.js';
|
|
18
20
|
import { executeCron, runDueCrons } from '../../daemon/cron-run.js';
|
|
19
21
|
const HELD_DELIVERED = 'deferred (exit 75) — held for poke';
|
|
20
22
|
const HELD_FAR_FUTURE = '9999-12-31T23:59:59.999Z';
|
|
21
23
|
let home;
|
|
22
24
|
let realHome;
|
|
25
|
+
let realUserHome;
|
|
23
26
|
function arm(overrides) {
|
|
24
27
|
armCron({
|
|
25
28
|
name: overrides.cron_id,
|
|
@@ -45,10 +48,21 @@ function arm(overrides) {
|
|
|
45
48
|
before(() => {
|
|
46
49
|
home = mkdtempSync(join(tmpdir(), 'crtr-cron-held-'));
|
|
47
50
|
realHome = process.env['CRTR_HOME'];
|
|
51
|
+
realUserHome = process.env['HOME'];
|
|
52
|
+
process.env['HOME'] = home;
|
|
48
53
|
process.env['CRTR_HOME'] = home;
|
|
49
54
|
});
|
|
55
|
+
beforeEach(() => {
|
|
56
|
+
closeDb();
|
|
57
|
+
closeScopedStores();
|
|
58
|
+
rmSync(home, { recursive: true, force: true });
|
|
59
|
+
mkdirSync(home, { recursive: true });
|
|
60
|
+
ensureScopeInitialized('user', join(home, '.crouter'));
|
|
61
|
+
migrate(openDb());
|
|
62
|
+
});
|
|
50
63
|
afterEach(() => {
|
|
51
64
|
closeDb();
|
|
65
|
+
closeScopedStores();
|
|
52
66
|
});
|
|
53
67
|
after(() => {
|
|
54
68
|
closeDb();
|
|
@@ -57,6 +71,10 @@ after(() => {
|
|
|
57
71
|
delete process.env['CRTR_HOME'];
|
|
58
72
|
else
|
|
59
73
|
process.env['CRTR_HOME'] = realHome;
|
|
74
|
+
if (realUserHome === undefined)
|
|
75
|
+
delete process.env['HOME'];
|
|
76
|
+
else
|
|
77
|
+
process.env['HOME'] = realUserHome;
|
|
60
78
|
});
|
|
61
79
|
test('a recurring exit-75 run parks: held, backstop untouched, no disposition', async () => {
|
|
62
80
|
// on-change makes the skipped disposition observable: were the branch to
|
|
@@ -10,9 +10,10 @@ import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
|
|
|
10
10
|
import { tmpdir } from 'node:os';
|
|
11
11
|
import { join } from 'node:path';
|
|
12
12
|
import { createNode, getNode, listNodes } from '../canvas/canvas.js';
|
|
13
|
+
import { ensureScopeInitialized } from '../config.js';
|
|
14
|
+
import { closeScopedStores } from '../scoped-state/db.js';
|
|
13
15
|
import { armCron, getCron } from '../canvas/crons.js';
|
|
14
|
-
import { closeDb } from '../canvas/db.js';
|
|
15
|
-
import { readInboxSince } from '../feed/inbox.js';
|
|
16
|
+
import { closeDb, migrate, openDb } from '../canvas/db.js';
|
|
16
17
|
import { headlessBrokerHost } from '../runtime/host.js';
|
|
17
18
|
import { resetFleetForTests } from '../runtime/fleet.js';
|
|
18
19
|
import { applyParkEvent, parkEvent } from '../../daemon/reconcilers/live-obligation.js';
|
|
@@ -20,6 +21,7 @@ import { executeCron } from '../../daemon/cron-run.js';
|
|
|
20
21
|
import { bindTestFleet } from './helpers/fleet.js';
|
|
21
22
|
let home;
|
|
22
23
|
let priorHome;
|
|
24
|
+
let priorUserHome;
|
|
23
25
|
let fleet;
|
|
24
26
|
let launches;
|
|
25
27
|
let originalLaunch;
|
|
@@ -36,6 +38,14 @@ function node(id, over = {}) {
|
|
|
36
38
|
...over,
|
|
37
39
|
};
|
|
38
40
|
}
|
|
41
|
+
function nodeMail(nodeId) {
|
|
42
|
+
return openDb().prepare(`SELECT m.body_json, d.urgency FROM deliveries d JOIN messages m ON m.message_id = d.message_id
|
|
43
|
+
WHERE d.destination_kind = 'node_inbox' AND d.destination_id = ? ORDER BY m.seq`).all(nodeId).map((row) => {
|
|
44
|
+
const data = row;
|
|
45
|
+
const value = data.body_json === null ? null : JSON.parse(data.body_json);
|
|
46
|
+
return { body: typeof value?.body === 'string' ? value.body : null, urgency: data.urgency };
|
|
47
|
+
});
|
|
48
|
+
}
|
|
39
49
|
function arm({ cron_id, ...overrides }) {
|
|
40
50
|
armCron({
|
|
41
51
|
cron_id,
|
|
@@ -79,12 +89,16 @@ function parkResidentRoot(id) {
|
|
|
79
89
|
before(() => {
|
|
80
90
|
home = mkdtempSync(join(tmpdir(), 'crtr-cron-node-sink-parked-root-'));
|
|
81
91
|
priorHome = process.env['CRTR_HOME'];
|
|
92
|
+
priorUserHome = process.env['HOME'];
|
|
82
93
|
process.env['CRTR_HOME'] = home;
|
|
94
|
+
process.env['HOME'] = home;
|
|
83
95
|
});
|
|
84
96
|
beforeEach(() => {
|
|
85
97
|
closeDb();
|
|
86
98
|
rmSync(home, { recursive: true, force: true });
|
|
87
99
|
mkdirSync(home, { recursive: true });
|
|
100
|
+
ensureScopeInitialized('user', join(home, '.crouter'));
|
|
101
|
+
migrate(openDb());
|
|
88
102
|
resetFleetForTests();
|
|
89
103
|
fleet = bindTestFleet();
|
|
90
104
|
launches = [];
|
|
@@ -99,6 +113,7 @@ beforeEach(() => {
|
|
|
99
113
|
afterEach(() => {
|
|
100
114
|
headlessBrokerHost.launch = originalLaunch;
|
|
101
115
|
closeDb();
|
|
116
|
+
closeScopedStores();
|
|
102
117
|
resetFleetForTests();
|
|
103
118
|
});
|
|
104
119
|
after(() => {
|
|
@@ -107,16 +122,20 @@ after(() => {
|
|
|
107
122
|
delete process.env['CRTR_HOME'];
|
|
108
123
|
else
|
|
109
124
|
process.env['CRTR_HOME'] = priorHome;
|
|
125
|
+
if (priorUserHome === undefined)
|
|
126
|
+
delete process.env['HOME'];
|
|
127
|
+
else
|
|
128
|
+
process.env['HOME'] = priorUserHome;
|
|
110
129
|
});
|
|
111
|
-
test('cron node sink
|
|
130
|
+
test('cron node sink creates a durable delivery for a parked resident root without escalation', async () => {
|
|
112
131
|
parkResidentRoot('parked-root');
|
|
113
132
|
arm({ cron_id: 'parked-root-cron', sink: JSON.stringify({ node: 'parked-root' }), anchor_node: 'parked-root' });
|
|
114
133
|
const record = await executeCron(getCron('parked-root-cron'), { outOfBand: false });
|
|
115
|
-
assert.
|
|
134
|
+
assert.match(record?.delivered ?? '', /^delivered: /);
|
|
116
135
|
assert.equal(getCron('parked-root-cron').state, 'active', 'delivery does not pause the cron');
|
|
117
|
-
assert.deepEqual(
|
|
118
|
-
assert.deepEqual(launches, [
|
|
119
|
-
assert.equal(getNode('parked-root').status, '
|
|
136
|
+
assert.deepEqual(nodeMail('parked-root').map((entry) => entry.body), ['cron output']);
|
|
137
|
+
assert.deepEqual(launches, [], 'the delivery lane wakes the destination after it claims mail');
|
|
138
|
+
assert.equal(getNode('parked-root').status, 'done', 'the parked root remains parked until delivery claims the row');
|
|
120
139
|
assert.deepEqual(listNodes().map((entry) => entry.node_id), ['parked-root'], 'no escalation node was created');
|
|
121
140
|
});
|
|
122
141
|
test('finalized and canceled node-sink targets still pause and escalate without delivery', async () => {
|
|
@@ -131,7 +150,7 @@ test('finalized and canceled node-sink targets still pause and escalate without
|
|
|
131
150
|
const record = await executeCron(getCron(`${id}-cron`), { outOfBand: false });
|
|
132
151
|
assert.match(record?.delivered ?? '', /^failure: cron paused, escalation node /, `${id}: failure is escalated`);
|
|
133
152
|
assert.equal(getCron(`${id}-cron`).state, 'paused', `${id}: cron is paused`);
|
|
134
|
-
assert.equal(
|
|
153
|
+
assert.equal(nodeMail(id).length, 0, `${id}: no message was appended`);
|
|
135
154
|
assert.equal(listNodes().length, before + 1, `${id}: exactly one escalation node was created`);
|
|
136
155
|
}
|
|
137
156
|
});
|
|
@@ -139,9 +158,9 @@ test('a deferred node-sink entry reaches the parked root durably but never reviv
|
|
|
139
158
|
parkResidentRoot('deferred-root');
|
|
140
159
|
arm({ cron_id: 'deferred-root-cron', sink: JSON.stringify({ node: 'deferred-root' }), tier: 'deferred' });
|
|
141
160
|
const record = await executeCron(getCron('deferred-root-cron'), { outOfBand: false });
|
|
142
|
-
assert.
|
|
161
|
+
assert.match(record?.delivered ?? '', /^delivered: /);
|
|
143
162
|
assert.equal(getCron('deferred-root-cron').state, 'active');
|
|
144
|
-
assert.deepEqual(
|
|
163
|
+
assert.deepEqual(nodeMail('deferred-root').map((entry) => entry.urgency), ['deferred']);
|
|
145
164
|
assert.deepEqual(launches, [], 'deferred delivery never launches a dormant target');
|
|
146
165
|
assert.equal(getNode('deferred-root').status, 'done', 'the parked target remains parked');
|
|
147
166
|
});
|
|
@@ -9,11 +9,14 @@ import { existsSync, mkdtempSync, readFileSync, rmSync } from 'node:fs';
|
|
|
9
9
|
import { tmpdir } from 'node:os';
|
|
10
10
|
import { join } from 'node:path';
|
|
11
11
|
import { setTimeout as delay } from 'node:timers/promises';
|
|
12
|
-
import { closeDb } from '../canvas/db.js';
|
|
12
|
+
import { closeDb, migrate, openDb } from '../canvas/db.js';
|
|
13
|
+
import { ensureScopeInitialized } from '../config.js';
|
|
14
|
+
import { closeScopedStores } from '../scoped-state/db.js';
|
|
13
15
|
import { armCron, cancelCron, getCron } from '../canvas/crons.js';
|
|
14
16
|
import { executeCron, markSelfCanceledCronRun } from '../../daemon/cron-run.js';
|
|
15
17
|
let home;
|
|
16
18
|
let realHome;
|
|
19
|
+
let realUserHome;
|
|
17
20
|
function arm(overrides) {
|
|
18
21
|
armCron({
|
|
19
22
|
name: overrides.cron_id,
|
|
@@ -39,10 +42,15 @@ function arm(overrides) {
|
|
|
39
42
|
before(() => {
|
|
40
43
|
home = mkdtempSync(join(tmpdir(), 'crtr-cron-broker-capacity-'));
|
|
41
44
|
realHome = process.env['CRTR_HOME'];
|
|
45
|
+
realUserHome = process.env['HOME'];
|
|
46
|
+
process.env['HOME'] = home;
|
|
42
47
|
process.env['CRTR_HOME'] = home;
|
|
48
|
+
ensureScopeInitialized('user', join(home, '.crouter'));
|
|
49
|
+
migrate(openDb());
|
|
43
50
|
});
|
|
44
51
|
afterEach(() => {
|
|
45
52
|
closeDb();
|
|
53
|
+
closeScopedStores();
|
|
46
54
|
});
|
|
47
55
|
after(() => {
|
|
48
56
|
closeDb();
|
|
@@ -51,6 +59,10 @@ after(() => {
|
|
|
51
59
|
delete process.env['CRTR_HOME'];
|
|
52
60
|
else
|
|
53
61
|
process.env['CRTR_HOME'] = realHome;
|
|
62
|
+
if (realUserHome === undefined)
|
|
63
|
+
delete process.env['HOME'];
|
|
64
|
+
else
|
|
65
|
+
process.env['HOME'] = realUserHome;
|
|
54
66
|
});
|
|
55
67
|
test('an on-change cron that cancels itself still delivers its final output', async () => {
|
|
56
68
|
const runIdPath = join(home, 'self-cancel-run-id');
|
|
@@ -68,5 +80,5 @@ test('an on-change cron that cancels itself still delivers its final output', as
|
|
|
68
80
|
assert.equal(markSelfCanceledCronRun('self-cancel-delivery', readFileSync(runIdPath, 'utf8')), true);
|
|
69
81
|
assert.equal(cancelCron('self-cancel-delivery', { preserveRunningProcess: true }), true);
|
|
70
82
|
const record = await run;
|
|
71
|
-
assert.
|
|
83
|
+
assert.match(record?.delivered ?? '', /^delivered: [0-9a-f]{32}$/, 'the durable human delivery was created after self-cancel');
|
|
72
84
|
});
|
|
@@ -15,7 +15,9 @@ import assert from 'node:assert/strict';
|
|
|
15
15
|
import { existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
16
16
|
import { tmpdir } from 'node:os';
|
|
17
17
|
import { join } from 'node:path';
|
|
18
|
-
import { closeDb } from '../canvas/db.js';
|
|
18
|
+
import { closeDb, migrate, openDb } from '../canvas/db.js';
|
|
19
|
+
import { ensureScopeInitialized } from '../config.js';
|
|
20
|
+
import { closeScopedStores } from '../scoped-state/db.js';
|
|
19
21
|
import { armCron, getCron } from '../canvas/crons.js';
|
|
20
22
|
import { isPidAlive } from '../canvas/pid.js';
|
|
21
23
|
import { executeCron } from '../../daemon/cron-run.js';
|
|
@@ -34,6 +36,7 @@ setInterval(() => {}, 1000);
|
|
|
34
36
|
`;
|
|
35
37
|
let home;
|
|
36
38
|
let realHome;
|
|
39
|
+
let realUserHome;
|
|
37
40
|
let marker;
|
|
38
41
|
let command;
|
|
39
42
|
function arm(overrides) {
|
|
@@ -61,7 +64,11 @@ function arm(overrides) {
|
|
|
61
64
|
before(() => {
|
|
62
65
|
home = mkdtempSync(join(tmpdir(), 'crtr-cron-timeout-descendants-'));
|
|
63
66
|
realHome = process.env['CRTR_HOME'];
|
|
67
|
+
realUserHome = process.env['HOME'];
|
|
68
|
+
process.env['HOME'] = home;
|
|
64
69
|
process.env['CRTR_HOME'] = home;
|
|
70
|
+
ensureScopeInitialized('user', join(home, '.crouter'));
|
|
71
|
+
migrate(openDb());
|
|
65
72
|
marker = join(home, 'descendant.pid');
|
|
66
73
|
const intermediate = join(home, 'intermediate.cjs');
|
|
67
74
|
const descendant = join(home, 'descendant.cjs');
|
|
@@ -84,11 +91,16 @@ after(() => {
|
|
|
84
91
|
}
|
|
85
92
|
}
|
|
86
93
|
closeDb();
|
|
94
|
+
closeScopedStores();
|
|
87
95
|
rmSync(home, { recursive: true, force: true });
|
|
88
96
|
if (realHome === undefined)
|
|
89
97
|
delete process.env['CRTR_HOME'];
|
|
90
98
|
else
|
|
91
99
|
process.env['CRTR_HOME'] = realHome;
|
|
100
|
+
if (realUserHome === undefined)
|
|
101
|
+
delete process.env['HOME'];
|
|
102
|
+
else
|
|
103
|
+
process.env['HOME'] = realUserHome;
|
|
92
104
|
});
|
|
93
105
|
test('a TERM-ignoring descendant outside the shell process group is reaped before the timeout is recorded', async () => {
|
|
94
106
|
arm({ cron_id: 'timeout-descendants', command });
|