@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
|
@@ -17,7 +17,8 @@ import { tmpdir } from 'node:os';
|
|
|
17
17
|
import { join } from 'node:path';
|
|
18
18
|
import * as tar from 'tar';
|
|
19
19
|
import { resetScopeCache } from '../scope.js';
|
|
20
|
-
import { readMergedLaunchConfig } from '../config.js';
|
|
20
|
+
import { readMergedLaunchConfig, updateRawConfigAtomically, writeRawConfig } from '../config.js';
|
|
21
|
+
import { initializeFreshScopedStore } from '../scoped-state/migrate.js';
|
|
21
22
|
import { validatePluginBundle } from '../command-plugins/bundle.js';
|
|
22
23
|
let isolatedHome;
|
|
23
24
|
let isolatedCwd;
|
|
@@ -32,6 +33,7 @@ beforeEach(() => {
|
|
|
32
33
|
isolatedCwd = realpathSync(mkdtempSync(join(tmpdir(), 'crtr-plugin-kinds-cwd-')));
|
|
33
34
|
process.env.HOME = isolatedHome;
|
|
34
35
|
process.chdir(isolatedCwd);
|
|
36
|
+
initializeFreshScopedStore({ kind: 'user', root: join(isolatedHome, '.crouter') });
|
|
35
37
|
resetScopeCache();
|
|
36
38
|
});
|
|
37
39
|
afterEach(() => {
|
|
@@ -76,7 +78,7 @@ test('the scope\u2019s own config.json overrides its plugins; a disabled plugin
|
|
|
76
78
|
const root = userRoot();
|
|
77
79
|
plantPlugin(root, 'northlight', { 'applet-builder': { whenToUse: 'plugin gloss', model: 'anthropic/strong' } });
|
|
78
80
|
plantPlugin(root, 'zzz-disabled', { ghost: { whenToUse: 'never registers' } });
|
|
79
|
-
|
|
81
|
+
updateRawConfigAtomically('user', () => ({
|
|
80
82
|
plugins: { 'zzz-disabled': { enabled: false } },
|
|
81
83
|
kinds: { 'applet-builder': { model: 'openai/medium' } },
|
|
82
84
|
}));
|
|
@@ -91,7 +93,7 @@ test('a whenToUse-only entry re-glosses an existing kind without stripping its m
|
|
|
91
93
|
// Now every entry field-merges over an existing kind; only a NEW kind
|
|
92
94
|
// requires whenToUse (a whenToUse-less new kind is dropped).
|
|
93
95
|
const root = userRoot();
|
|
94
|
-
|
|
96
|
+
updateRawConfigAtomically('user', () => ({ kinds: { explore: { whenToUse: 'custom explore gloss' }, 'new-glossless': { model: 'openai/light' } } }));
|
|
95
97
|
const kinds = readMergedLaunchConfig().kinds;
|
|
96
98
|
assert.equal(kinds['explore']?.whenToUse, 'custom explore gloss');
|
|
97
99
|
assert.equal(kinds['explore']?.model, 'openai/light'); // builtin tier survives
|
|
@@ -100,7 +102,7 @@ test('a whenToUse-only entry re-glosses an existing kind without stripping its m
|
|
|
100
102
|
});
|
|
101
103
|
test('a project-root plugin layers above user config, and the project config above the plugin', () => {
|
|
102
104
|
const uRoot = userRoot();
|
|
103
|
-
|
|
105
|
+
writeRawConfig('user', { kinds: { shared: { whenToUse: 'user gloss', model: 'openai/light' } } });
|
|
104
106
|
const pRoot = projectRoot();
|
|
105
107
|
plantPlugin(pRoot, 'proj-plugin', { shared: { model: 'anthropic/strong' }, 'proj-kind': { whenToUse: 'project plugin kind' } });
|
|
106
108
|
writeFileSync(join(pRoot, 'config.json'), JSON.stringify({ kinds: { 'proj-kind': { model: 'openai/medium' } } }));
|
|
@@ -11,8 +11,11 @@ import assert from 'node:assert/strict';
|
|
|
11
11
|
import { mkdtempSync, mkdirSync, rmSync, symlinkSync, writeFileSync } from 'node:fs';
|
|
12
12
|
import { tmpdir } from 'node:os';
|
|
13
13
|
import { join } from 'node:path';
|
|
14
|
+
import { realpathSync } from 'node:fs';
|
|
14
15
|
import { linkOrCopy } from '../fs-utils.js';
|
|
15
16
|
import { listInstalledPluginsInRoot } from '../resolver.js';
|
|
17
|
+
import { closeScopedStores } from '../scoped-state/db.js';
|
|
18
|
+
import { initializeFreshScopedStore } from '../scoped-state/migrate.js';
|
|
16
19
|
describe('plugin link through a symlinked scope-root ancestor', () => {
|
|
17
20
|
test('the installed plugin resolves on the next invocation', () => {
|
|
18
21
|
const base = mkdtempSync(join(tmpdir(), 'crtr-plugin-link-'));
|
|
@@ -28,10 +31,12 @@ describe('plugin link through a symlinked scope-root ancestor', () => {
|
|
|
28
31
|
symlinkSync(join('physical', 'home'), join(base, 'home'), 'dir');
|
|
29
32
|
const scopeRootPath = join(base, 'home', '.crouter');
|
|
30
33
|
mkdirSync(join(scopeRootPath, 'plugins'), { recursive: true });
|
|
34
|
+
initializeFreshScopedStore({ kind: 'user', root: scopeRootPath });
|
|
31
35
|
linkOrCopy(source, join(scopeRootPath, 'plugins', 'search'));
|
|
32
|
-
assert.deepEqual(listInstalledPluginsInRoot('user', scopeRootPath).map((p) => p.name), ['search']);
|
|
36
|
+
assert.deepEqual(listInstalledPluginsInRoot('user', realpathSync(scopeRootPath)).map((p) => p.name), ['search']);
|
|
33
37
|
}
|
|
34
38
|
finally {
|
|
39
|
+
closeScopedStores();
|
|
35
40
|
rmSync(base, { recursive: true, force: true });
|
|
36
41
|
}
|
|
37
42
|
});
|
|
@@ -15,7 +15,8 @@ import { tmpdir } from 'node:os';
|
|
|
15
15
|
import { join } from 'node:path';
|
|
16
16
|
import * as tar from 'tar';
|
|
17
17
|
import { resetScopeCache } from '../scope.js';
|
|
18
|
-
import { resolvePageComponents } from '../config.js';
|
|
18
|
+
import { resolvePageComponents, updateRawConfigAtomically, writeRawConfig } from '../config.js';
|
|
19
|
+
import { initializeFreshScopedStore } from '../scoped-state/migrate.js';
|
|
19
20
|
import { validatePluginBundle } from '../command-plugins/bundle.js';
|
|
20
21
|
let isolatedHome;
|
|
21
22
|
let isolatedCwd;
|
|
@@ -30,6 +31,7 @@ beforeEach(() => {
|
|
|
30
31
|
isolatedCwd = realpathSync(mkdtempSync(join(tmpdir(), 'crtr-page-components-cwd-')));
|
|
31
32
|
process.env.HOME = isolatedHome;
|
|
32
33
|
process.chdir(isolatedCwd);
|
|
34
|
+
initializeFreshScopedStore({ kind: 'user', root: join(isolatedHome, '.crouter') });
|
|
33
35
|
resetScopeCache();
|
|
34
36
|
});
|
|
35
37
|
afterEach(() => {
|
|
@@ -60,7 +62,7 @@ test('an enabled user-scope plugin contributes its page components; a disabled o
|
|
|
60
62
|
{ kind: 'applet-card', display: true },
|
|
61
63
|
]);
|
|
62
64
|
plantPlugin(root, 'zzz-disabled', ['ghost']);
|
|
63
|
-
|
|
65
|
+
writeRawConfig('user', { plugins: { 'zzz-disabled': { enabled: false } } });
|
|
64
66
|
const components = resolvePageComponents();
|
|
65
67
|
assert.deepEqual(components, [
|
|
66
68
|
{ kind: 'connector', description: 'Connector decision', useWhen: 'Use for a connector decision.', doc: 'Product contract.' },
|
|
@@ -70,9 +72,9 @@ test('an enabled user-scope plugin contributes its page components; a disabled o
|
|
|
70
72
|
test('user config entries and plugin contributions resolve together, and a colliding kind is rejected', () => {
|
|
71
73
|
const root = userRoot();
|
|
72
74
|
plantPlugin(root, 'northlight', ['connector']);
|
|
73
|
-
|
|
75
|
+
updateRawConfigAtomically('user', () => ({ page_components: ['approval'] }));
|
|
74
76
|
assert.deepEqual(resolvePageComponents().map((component) => component.kind), ['approval', 'connector']);
|
|
75
|
-
|
|
77
|
+
updateRawConfigAtomically('user', () => ({ page_components: ['connector'] }));
|
|
76
78
|
assert.throws(() => resolvePageComponents(), /page component kind "connector" is registered by both config.json and plugin "northlight"/);
|
|
77
79
|
});
|
|
78
80
|
test('two plugins whose kinds derive one JSX tag are rejected, naming both sources', () => {
|
|
@@ -16,6 +16,7 @@ import { tmpdir } from 'node:os';
|
|
|
16
16
|
import { join } from 'node:path';
|
|
17
17
|
import { buildRoot } from '../../build-root.js';
|
|
18
18
|
import { SUPPRESS_OUTPUT_LEAVES, LEAF_ICON_CP, SUMMARIZERS } from '../preview-registry.js';
|
|
19
|
+
import { ensureScopeInitialized } from '../config.js';
|
|
19
20
|
import { resetScopeCache } from '../scope.js';
|
|
20
21
|
// buildRoot() composes external command-plugin branches from the effective
|
|
21
22
|
// enabled plugins (user scope + project ancestors). Pin HOME + profile to an
|
|
@@ -31,6 +32,7 @@ before(() => {
|
|
|
31
32
|
process.env['HOME'] = home;
|
|
32
33
|
delete process.env['CRTR_PROFILE_ID'];
|
|
33
34
|
resetScopeCache();
|
|
35
|
+
ensureScopeInitialized('user', join(home, '.crouter'));
|
|
34
36
|
});
|
|
35
37
|
after(() => {
|
|
36
38
|
if (realHome !== undefined)
|
|
@@ -18,9 +18,10 @@ import assert from 'node:assert/strict';
|
|
|
18
18
|
import { mkdtempSync, mkdirSync, realpathSync, rmSync, writeFileSync } from 'node:fs';
|
|
19
19
|
import { tmpdir } from 'node:os';
|
|
20
20
|
import { dirname, join } from 'node:path';
|
|
21
|
-
import { closeDb } from '../canvas/db.js';
|
|
21
|
+
import { closeDb, migrate, openDb } from '../canvas/db.js';
|
|
22
22
|
import { resetScopeCache } from '../scope.js';
|
|
23
23
|
import { createProfile } from '../profiles/manifest.js';
|
|
24
|
+
import { initializeFreshScopedStore } from '../scoped-state/migrate.js';
|
|
24
25
|
import { spawnNode } from '../runtime/nodes.js';
|
|
25
26
|
import { memoryDir } from '../runtime/memory.js';
|
|
26
27
|
import { clearSessionCache } from '../substrate/session-cache.js';
|
|
@@ -115,6 +116,8 @@ before(() => {
|
|
|
115
116
|
canvasHome = realpathSync(mkdtempSync(join(tmpdir(), 'crtr-ppm-canvas-')));
|
|
116
117
|
process.env['HOME'] = home;
|
|
117
118
|
process.env['CRTR_HOME'] = canvasHome;
|
|
119
|
+
initializeFreshScopedStore({ kind: 'user', root: join(home, '.crouter') });
|
|
120
|
+
migrate(openDb());
|
|
118
121
|
// A project store answers only under the namespace its root INDEX.md
|
|
119
122
|
// declares; without that declaration the store does not mount at all.
|
|
120
123
|
const store = (slug, namespace) => {
|
|
@@ -350,11 +353,11 @@ after(() => {
|
|
|
350
353
|
restore('CRTR_PROFILE_ID', prevProfile);
|
|
351
354
|
restore('CRTR_NODE_ID', prevNode);
|
|
352
355
|
});
|
|
353
|
-
function newNode(kind = 'general') {
|
|
354
|
-
return spawnNode({ kind, cwd: cwdProject, parent: null, profile_id: profileId }).node_id;
|
|
356
|
+
async function newNode(kind = 'general') {
|
|
357
|
+
return (await spawnNode({ kind, cwd: cwdProject, parent: null, profile_id: profileId })).node_id;
|
|
355
358
|
}
|
|
356
|
-
test('boot delivery caps every profile project at its relationship, including the one used as cwd', () => {
|
|
357
|
-
const boot = renderKnowledgeBlock(newNode(), freshTranscriptTarget());
|
|
359
|
+
test('boot delivery caps every profile project at its relationship, including the one used as cwd', async () => {
|
|
360
|
+
const boot = renderKnowledgeBlock(await newNode(), freshTranscriptTarget());
|
|
358
361
|
// The control: an uncapped relationship still renders its authored content.
|
|
359
362
|
assert.ok(boot.includes(B.pcontent), `the content-capped project renders its body; got:\n${boot}`);
|
|
360
363
|
// The reported failure. cwd reaches this root before the manifest pointer
|
|
@@ -369,22 +372,22 @@ test('boot delivery caps every profile project at its relationship, including th
|
|
|
369
372
|
assert.match(boot, /[├└]─ t9-pname-doc$/m, `the name-capped doc discloses as a bare name; got:\n${boot}`);
|
|
370
373
|
assert.ok(!boot.includes('When the name project delivers'), 'a name-capped doc discloses no preview line');
|
|
371
374
|
});
|
|
372
|
-
test('surface-entry gates select the rung by node kind while the document gate remains absolute', () => {
|
|
375
|
+
test('surface-entry gates select the rung by node kind while the document gate remains absolute', async () => {
|
|
373
376
|
for (const kind of ['design', 'spec', 'plan', 'developer']) {
|
|
374
|
-
const boot = renderKnowledgeBlock(newNode(kind), freshTranscriptTarget());
|
|
377
|
+
const boot = renderKnowledgeBlock(await newNode(kind), freshTranscriptTarget());
|
|
375
378
|
assert.ok(boot.includes(B.kindSplit), `${kind} receives the content rung; got:\n${boot}`);
|
|
376
379
|
}
|
|
377
380
|
for (const kind of ['general', 'review', 'advisor']) {
|
|
378
|
-
const boot = renderKnowledgeBlock(newNode(kind), freshTranscriptTarget());
|
|
381
|
+
const boot = renderKnowledgeBlock(await newNode(kind), freshTranscriptTarget());
|
|
379
382
|
assert.match(boot, /t9-kind-split {2}# read when: When the node needs this kind-specific guide\./, `${kind} receives the preview rung; got:\n${boot}`);
|
|
380
383
|
assert.ok(!boot.includes(B.kindSplit), `${kind} does not receive the body`);
|
|
381
384
|
}
|
|
382
385
|
for (const kind of ['explore', 'personal-assistant']) {
|
|
383
|
-
const boot = renderKnowledgeBlock(newNode(kind), freshTranscriptTarget());
|
|
386
|
+
const boot = renderKnowledgeBlock(await newNode(kind), freshTranscriptTarget());
|
|
384
387
|
assert.ok(!boot.includes('t9-kind-split'), `${kind} receives no kind-split entry; got:\n${boot}`);
|
|
385
388
|
assert.ok(!boot.includes(B.kindSplit), `${kind} receives no kind-split body`);
|
|
386
389
|
}
|
|
387
|
-
const developer = renderKnowledgeBlock(newNode('developer'), freshTranscriptTarget());
|
|
390
|
+
const developer = renderKnowledgeBlock(await newNode('developer'), freshTranscriptTarget());
|
|
388
391
|
assert.ok(!developer.includes('t9-document-gate-wins'), `a failing document gate excludes every entry; got:\n${developer}`);
|
|
389
392
|
assert.ok(!developer.includes(B.documentGateWins), 'a failing document gate excludes its content');
|
|
390
393
|
assert.ok(developer.includes(B.codeCraftIndex), 'the directory document delivers its boot content');
|
|
@@ -394,8 +397,8 @@ test('surface-entry gates select the rung by node kind while the document gate r
|
|
|
394
397
|
// The ancestor listing, not just the doc's own directory.
|
|
395
398
|
assert.match(developer, /sibling {2}# read when: When the dev sibling applies\./, `content delivery exposes the enclosing directory's members too; got:\n${developer}`);
|
|
396
399
|
});
|
|
397
|
-
test('context docs accounting reports content attachment raises from the renderer', () => {
|
|
398
|
-
const node = newNode('developer');
|
|
400
|
+
test('context docs accounting reports content attachment raises from the renderer', async () => {
|
|
401
|
+
const node = await newNode('developer');
|
|
399
402
|
const subject = assembleNodeSubject(node);
|
|
400
403
|
assert.ok(subject !== null, 'the fixture node assembles a subject');
|
|
401
404
|
const target = { cwd: cwdProject, profileId, nodeId: node };
|
|
@@ -431,8 +434,8 @@ test('context docs accounting reports content attachment raises from the rendere
|
|
|
431
434
|
assert.equal(viewerRecord?.deliveryCause, 'directory listing attached to content delivery');
|
|
432
435
|
plans.dispose();
|
|
433
436
|
});
|
|
434
|
-
test('context docs accounting adds full-view workspace content attachments', () => {
|
|
435
|
-
const node = newNode();
|
|
437
|
+
test('context docs accounting adds full-view workspace content attachments', async () => {
|
|
438
|
+
const node = await newNode();
|
|
436
439
|
const subject = assembleNodeSubject(node);
|
|
437
440
|
assert.ok(subject !== null, 'the fixture node assembles a subject');
|
|
438
441
|
const target = { cwd: outsideProject, profileId, nodeId: node };
|
|
@@ -446,8 +449,8 @@ test('context docs accounting adds full-view workspace content attachments', ()
|
|
|
446
449
|
assert.equal(companion?.final_rung, 'content');
|
|
447
450
|
assert.equal(companion?.delivery_cause, 'memory-read companion of content delivery');
|
|
448
451
|
});
|
|
449
|
-
test('boot content triggers memory-read companions to a deduplicated fixpoint', () => {
|
|
450
|
-
const boot = renderKnowledgeBlock(newNode(), freshTranscriptTarget());
|
|
452
|
+
test('boot content triggers memory-read companions to a deduplicated fixpoint', async () => {
|
|
453
|
+
const boot = renderKnowledgeBlock(await newNode(), freshTranscriptTarget());
|
|
451
454
|
for (const body of [B.companionSource, B.companionA, B.companionB]) {
|
|
452
455
|
assert.equal(boot.split(body).length - 1, 1, `content companion ${body} delivers once; got:\n${boot}`);
|
|
453
456
|
}
|
|
@@ -455,8 +458,8 @@ test('boot content triggers memory-read companions to a deduplicated fixpoint',
|
|
|
455
458
|
// discloses its members exactly as the doc that routed to it did.
|
|
456
459
|
assert.match(boot, /member-1 {2}# read when: When the companion member applies\./, `a content companion exposes its own directory's members; got:\n${boot}`);
|
|
457
460
|
});
|
|
458
|
-
test('one body delivered across both boot partitions renders exactly once', () => {
|
|
459
|
-
const node = newNode();
|
|
461
|
+
test('one body delivered across both boot partitions renders exactly once', async () => {
|
|
462
|
+
const node = await newNode();
|
|
460
463
|
const subject = assembleNodeSubject(node);
|
|
461
464
|
assert.ok(subject !== null, 'the fixture node assembles a subject');
|
|
462
465
|
const state = emptyContextExposureState();
|
|
@@ -470,8 +473,8 @@ test('one body delivered across both boot partitions renders exactly once', () =
|
|
|
470
473
|
const occurrences = (preferences.split(B.crossPartition).length - 1) + (knowledge.split(B.crossPartition).length - 1);
|
|
471
474
|
assert.equal(occurrences, 1, `the companion body renders once across both partitions; got:\n${preferences}\n---\n${knowledge}`);
|
|
472
475
|
});
|
|
473
|
-
test('a node-local doc floors to name only without boot entries', () => {
|
|
474
|
-
const node = newNode('explore');
|
|
476
|
+
test('a node-local doc floors to name only without boot entries', async () => {
|
|
477
|
+
const node = await newNode('explore');
|
|
475
478
|
writeDoc(memoryDir(node), 't9-node-local-bootless', bootlessDoc('When the node-local fallback applies', 'BODY-T9-NODE-LOCAL-BOOTLESS'));
|
|
476
479
|
writeDoc(memoryDir(node), 't9-node-local-entry-gated', [
|
|
477
480
|
'---',
|
|
@@ -491,8 +494,8 @@ test('a node-local doc floors to name only without boot entries', () => {
|
|
|
491
494
|
assert.ok(!boot.includes('t9-node-local-entry-gated'), `ineligible boot entries keep a node-local doc absent; got:\n${boot}`);
|
|
492
495
|
assert.ok(!boot.includes('BODY-T9-NODE-LOCAL-ENTRY-GATED'), 'ineligible boot entries disclose no body');
|
|
493
496
|
});
|
|
494
|
-
test('a `none` project contributes nothing to boot — no body, no name, no hidden count, no shadow', () => {
|
|
495
|
-
const boot = renderKnowledgeBlock(newNode(), freshTranscriptTarget());
|
|
497
|
+
test('a `none` project contributes nothing to boot — no body, no name, no hidden count, no shadow', async () => {
|
|
498
|
+
const boot = renderKnowledgeBlock(await newNode(), freshTranscriptTarget());
|
|
496
499
|
assert.ok(!boot.includes(B.pnone), 'a none-capped body must not render');
|
|
497
500
|
assert.ok(!boot.includes('pnone'), 'a none-capped store must not appear as a name either — not even its namespace row');
|
|
498
501
|
// Hidden counts are disclosure too: the control project's namespace row proves
|
|
@@ -512,7 +515,7 @@ test('a capped nearer candidate yields the shared identity instead of suppressin
|
|
|
512
515
|
// physical candidates. Automatic delivery filters candidates by the profile
|
|
513
516
|
// cap BEFORE dedupe, so the `none`-capped nearer one drops out and the farther
|
|
514
517
|
// one delivers; a deliberate read stays winner-only on source order.
|
|
515
|
-
const boot = renderKnowledgeBlock(newNode(), freshTranscriptTarget());
|
|
518
|
+
const boot = renderKnowledgeBlock(await newNode(), freshTranscriptTarget());
|
|
516
519
|
assert.ok(boot.includes(B.dupFar), `the farther uncapped candidate delivers the shared identity; got:\n${boot}`);
|
|
517
520
|
assert.ok(!boot.includes(B.dupNear), 'the none-capped nearer candidate delivers nothing');
|
|
518
521
|
const read = (await readLeaf.run({
|
|
@@ -524,14 +527,14 @@ test('a capped nearer candidate yields the shared identity instead of suppressin
|
|
|
524
527
|
}));
|
|
525
528
|
assert.ok(read.content.includes(B.dupNear) && !read.content.includes(B.dupFar), `a deliberate read resolves the source-order winner; got:\n${read.content}`);
|
|
526
529
|
});
|
|
527
|
-
test('a non-none cap keeps its project precedence and discloses the duplicate at the capped rung', () => {
|
|
528
|
-
const boot = renderKnowledgeBlock(newNode(), freshTranscriptTarget());
|
|
530
|
+
test('a non-none cap keeps its project precedence and discloses the duplicate at the capped rung', async () => {
|
|
531
|
+
const boot = renderKnowledgeBlock(await newNode(), freshTranscriptTarget());
|
|
529
532
|
assert.match(boot, /[├└]─ t9-namedup-doc$/m, `the name-capped project discloses its doc as a bare name; got:\n${boot}`);
|
|
530
533
|
assert.ok(!boot.includes(B.nameFromPname), 'a name-capped doc discloses at `name`, never its body');
|
|
531
534
|
assert.ok(boot.includes(B.nameFromPcontent), 'the content project delivers its own distinct identity in full');
|
|
532
535
|
});
|
|
533
|
-
test('workspace-open clamps each project store the same way boot does', () => {
|
|
534
|
-
const opened = renderWorkspaceOpenDocs(newNode(), freshTranscriptTarget());
|
|
536
|
+
test('workspace-open clamps each project store the same way boot does', async () => {
|
|
537
|
+
const opened = renderWorkspaceOpenDocs(await newNode(), freshTranscriptTarget());
|
|
535
538
|
assert.ok(opened.includes(B.pcontent), `the content-capped project delivers its body; got:\n${opened}`);
|
|
536
539
|
assert.ok(!opened.includes(B.ppreview), `the cwd project must not deliver its body; got:\n${opened}`);
|
|
537
540
|
assert.match(opened, /name="ppreview\/t9-ppreview-doc" readWhen="When the cwd project delivers\./, `the cwd project delivers its preview line under its canonical name; got:\n${opened}`);
|
|
@@ -539,8 +542,8 @@ test('workspace-open clamps each project store the same way boot does', () => {
|
|
|
539
542
|
assert.ok(!opened.includes('t9-pnone-doc'), 'the none-capped project delivers nothing at workspace-open');
|
|
540
543
|
assert.ok(!opened.includes(B.sharedFromPnone), 'nor its side of a name collision');
|
|
541
544
|
});
|
|
542
|
-
test('workspace-open answers its listings from the workspace it opened, not the ambient one', () => {
|
|
543
|
-
const node = newNode();
|
|
545
|
+
test('workspace-open answers its listings from the workspace it opened, not the ambient one', async () => {
|
|
546
|
+
const node = await newNode();
|
|
544
547
|
const subject = assembleNodeSubject(node);
|
|
545
548
|
assert.ok(subject !== null, 'the fixture node assembles a subject');
|
|
546
549
|
// The process cwd is `ppreview`; this workspace is outside the profile
|
|
@@ -551,7 +554,7 @@ test('workspace-open answers its listings from the workspace it opened, not the
|
|
|
551
554
|
assert.match(opened, /\[\[poutside\/t9-ws-guide\/member-1\]\]: When the outside guide member applies\./, `the listing carries that directory's own members; got:\n${opened}`);
|
|
552
555
|
});
|
|
553
556
|
test('memory list and find record synthetic pages without crediting matched documents', async () => {
|
|
554
|
-
const node = newNode();
|
|
557
|
+
const node = await newNode();
|
|
555
558
|
process.env['CRTR_NODE_ID'] = node;
|
|
556
559
|
try {
|
|
557
560
|
const listed = await listLeaf.run({
|
|
@@ -589,7 +592,7 @@ test('memory list and find record synthetic pages without crediting matched docu
|
|
|
589
592
|
}
|
|
590
593
|
});
|
|
591
594
|
test('an explicit read after boot content adds no duplicate directory attachments', async () => {
|
|
592
|
-
const node = newNode('developer');
|
|
595
|
+
const node = await newNode('developer');
|
|
593
596
|
process.env['CRTR_NODE_ID'] = node;
|
|
594
597
|
try {
|
|
595
598
|
const state = loadContextExposureState(node);
|
|
@@ -614,7 +617,7 @@ test('an explicit read after boot content adds no duplicate directory attachment
|
|
|
614
617
|
}
|
|
615
618
|
});
|
|
616
619
|
test('an explicit `crtr memory read` returns and records the full body a cap withheld', async () => {
|
|
617
|
-
const node = newNode();
|
|
620
|
+
const node = await newNode();
|
|
618
621
|
process.env['CRTR_NODE_ID'] = node;
|
|
619
622
|
const state = loadContextExposureState(node);
|
|
620
623
|
const transcript = exposureTarget(state, 'transcript');
|
|
@@ -3,8 +3,9 @@ import assert from 'node:assert/strict';
|
|
|
3
3
|
import { mkdtempSync, rmSync, existsSync } from 'node:fs';
|
|
4
4
|
import { tmpdir } from 'node:os';
|
|
5
5
|
import { join } from 'node:path';
|
|
6
|
-
import { createNode, getRow, subscribe,
|
|
7
|
-
import { closeDb, openDb } from '../canvas/db.js';
|
|
6
|
+
import { createNode, getRow, subscribe, recordSpawn, subscribersOf, subscriptionsOf, pruneNodes, pruneToLimit, transitionStatusIntent, } from '../canvas/canvas.js';
|
|
7
|
+
import { closeDb, migrate, openDb } from '../canvas/db.js';
|
|
8
|
+
import { beginExecution, recordExecutionPid } from '../canvas/executions.js';
|
|
8
9
|
import { nodeDir } from '../canvas/paths.js';
|
|
9
10
|
let home;
|
|
10
11
|
const DAY = 86_400_000;
|
|
@@ -33,6 +34,10 @@ function totalEdges() {
|
|
|
33
34
|
function markCollectibleTerminal(nodeId) {
|
|
34
35
|
transitionStatusIntent(nodeId, { terminal_reason: 'closed' });
|
|
35
36
|
}
|
|
37
|
+
function recordExecution(nodeId, pid) {
|
|
38
|
+
const executionId = beginExecution(nodeId, { daemonEpoch: 'test' });
|
|
39
|
+
recordExecutionPid(executionId, nodeId, pid);
|
|
40
|
+
}
|
|
36
41
|
/** The standard fixture: three prunable terminal nodes (old), three survivors
|
|
37
42
|
* (two old-but-live, one recent-but-dead), and edges that touch a pruned node
|
|
38
43
|
* so cascade is observable. */
|
|
@@ -55,6 +60,7 @@ before(() => {
|
|
|
55
60
|
beforeEach(() => {
|
|
56
61
|
closeDb();
|
|
57
62
|
rmSync(home, { recursive: true, force: true });
|
|
63
|
+
migrate(openDb());
|
|
58
64
|
});
|
|
59
65
|
after(() => {
|
|
60
66
|
closeDb();
|
|
@@ -146,7 +152,7 @@ test('count pruning keeps all live nodes even when liveCount exceeds the cap', (
|
|
|
146
152
|
// fall beyond rank 5 and are pruned.
|
|
147
153
|
for (let i = 0; i < 5; i++) {
|
|
148
154
|
createNode(node(`live-${i}`, { status: 'active', created: at(i) }));
|
|
149
|
-
|
|
155
|
+
recordExecution(`live-${i}`, process.pid); // process.pid is alive → isPidAlive true
|
|
150
156
|
}
|
|
151
157
|
createNode(node('old-a', { status: 'dead', created: at(100) }));
|
|
152
158
|
createNode(node('old-b', { status: 'done', created: at(101) }));
|
|
@@ -164,7 +170,7 @@ test('count pruning deletes the oldest terminal nodes beyond max(cap, liveCount)
|
|
|
164
170
|
// Ranked by recency DESC: live-0, term-0, term-1 (top 3, kept), then
|
|
165
171
|
// term-2, term-3, term-4 (rank >= 3, pruned).
|
|
166
172
|
createNode(node('live-0', { status: 'idle', created: at(0) }));
|
|
167
|
-
|
|
173
|
+
recordExecution('live-0', process.pid);
|
|
168
174
|
for (let i = 0; i < 5; i++) {
|
|
169
175
|
const id = `term-${i}`;
|
|
170
176
|
createNode(node(id, { status: 'dead', created: at(10 + i) }));
|
|
@@ -185,7 +191,7 @@ test('count pruning deletes the oldest terminal nodes beyond max(cap, liveCount)
|
|
|
185
191
|
});
|
|
186
192
|
test('count pruning dry-run reports candidates without deleting rows or dirs', () => {
|
|
187
193
|
createNode(node('live-0', { status: 'idle', created: at(0) }));
|
|
188
|
-
|
|
194
|
+
recordExecution('live-0', process.pid);
|
|
189
195
|
for (let i = 0; i < 5; i++) {
|
|
190
196
|
const id = `term-${i}`;
|
|
191
197
|
createNode(node(id, { status: 'dead', created: at(10 + i) }));
|
|
@@ -4,21 +4,28 @@ import { mkdtempSync, rmSync, mkdirSync } from 'node:fs';
|
|
|
4
4
|
import { tmpdir } from 'node:os';
|
|
5
5
|
import { join } from 'node:path';
|
|
6
6
|
import { createNode, getNode, setStatus } from '../canvas/canvas.js';
|
|
7
|
-
import { closeDb } from '../canvas/db.js';
|
|
7
|
+
import { closeDb, openDb, migrate } from '../canvas/db.js';
|
|
8
8
|
import { InputError } from '../io.js';
|
|
9
9
|
import { messageRoutes } from '../../daemon/api/handlers/messages.js';
|
|
10
10
|
import { pushFinal, FinalizationError } from '../feed/feed.js';
|
|
11
11
|
import { assertNotFinalized, assertFinalizedForReopen, commitReopen } from '../runtime/reopen.js';
|
|
12
12
|
import { reviveNode } from '../runtime/revive.js';
|
|
13
13
|
import { headlessBrokerHost } from '../runtime/host.js';
|
|
14
|
-
|
|
14
|
+
function nodeMailCount(nodeId) {
|
|
15
|
+
return Number(openDb().prepare(`SELECT COUNT(*) AS count FROM deliveries
|
|
16
|
+
WHERE destination_kind = 'node_inbox' AND destination_id = ?`).get(nodeId).count);
|
|
17
|
+
}
|
|
15
18
|
import { writeGoal } from '../runtime/kickoff.js';
|
|
16
19
|
import { situationalContextPath } from '../canvas/paths.js';
|
|
17
20
|
let home;
|
|
18
21
|
const prevNodeId = process.env['CRTR_NODE_ID'];
|
|
19
22
|
function node(id) { return { node_id: id, name: id, created: new Date().toISOString(), cwd: '/tmp/work', kind: 'general', mode: 'base', lifecycle: 'terminal', status: 'active' }; }
|
|
20
23
|
before(() => { home = mkdtempSync(join(tmpdir(), 'crtr-pushfinal-')); process.env['CRTR_HOME'] = home; });
|
|
21
|
-
beforeEach(() => {
|
|
24
|
+
beforeEach(() => {
|
|
25
|
+
closeDb();
|
|
26
|
+
rmSync(home, { recursive: true, force: true });
|
|
27
|
+
migrate(openDb());
|
|
28
|
+
});
|
|
22
29
|
after(() => { closeDb(); rmSync(home, { recursive: true, force: true }); delete process.env['CRTR_HOME']; if (prevNodeId === undefined)
|
|
23
30
|
delete process.env['CRTR_NODE_ID'];
|
|
24
31
|
else
|
|
@@ -66,13 +73,13 @@ test('a finalized node re-tasked via node message send without --reopen is rejec
|
|
|
66
73
|
const firstFinal = getNode(id)?.final_report;
|
|
67
74
|
assert.ok(firstFinal);
|
|
68
75
|
// A message to the now-finalized node, no --reopen: rejected before the
|
|
69
|
-
// handler ever reaches
|
|
76
|
+
// handler ever creates a delivery or reaches reviveNode. Prove BOTH: the latch is
|
|
70
77
|
// untouched, AND (per #340's Minor finding) no side effect landed first —
|
|
71
78
|
// spy on the exact revive seam reviveNode calls (headlessBrokerHost.launch,
|
|
72
79
|
// the same seam revive.test.ts already uses to instrument reviveNode without
|
|
73
80
|
// a real engine) and assert it was never invoked, plus the inbox is
|
|
74
81
|
// unchanged.
|
|
75
|
-
const inboxBefore =
|
|
82
|
+
const inboxBefore = nodeMailCount(id);
|
|
76
83
|
const originalLaunch = headlessBrokerHost.launch;
|
|
77
84
|
let launchCalls = 0;
|
|
78
85
|
headlessBrokerHost.launch = ((...args) => { launchCalls++; return originalLaunch(...args); });
|
|
@@ -84,7 +91,7 @@ test('a finalized node re-tasked via node message send without --reopen is rejec
|
|
|
84
91
|
}
|
|
85
92
|
assert.equal(launchCalls, 0, 'a rejected retask must never attempt a revive');
|
|
86
93
|
assert.equal(getNode(id)?.final_report, firstFinal, 'a rejected retask must not touch the latch');
|
|
87
|
-
assert.equal(
|
|
94
|
+
assert.equal(nodeMailCount(id), inboxBefore, 'a rejected retask must not create a delivery');
|
|
88
95
|
// The successful path, driven through the ACTUAL daemon message handler (the
|
|
89
96
|
// real seam --reopen now lives behind, not a direct call into the gate
|
|
90
97
|
// internals) — stub the revive seam so no real engine process is spawned,
|
|
@@ -105,7 +112,7 @@ test('a finalized node re-tasked via node message send without --reopen is rejec
|
|
|
105
112
|
headlessBrokerHost.launch = originalLaunch;
|
|
106
113
|
}
|
|
107
114
|
assert.equal(getNode(id)?.final_report, null, '--reopen cleared the latch through the real handler seam');
|
|
108
|
-
assert.equal(
|
|
115
|
+
assert.equal(nodeMailCount(id), inboxBefore + 1, 'the re-task message created one durable delivery');
|
|
109
116
|
// The re-tasked node can now finish its new mandate and re-latch cleanly.
|
|
110
117
|
process.env['CRTR_NODE_ID'] = id;
|
|
111
118
|
await pushFinal(id, 'round 2 verdict');
|
|
@@ -15,13 +15,19 @@ import { CrtrClient } from '../../api/client.js';
|
|
|
15
15
|
import { createApiServer } from '../../daemon/api/server.js';
|
|
16
16
|
import registerCanvasStophook from '../../pi-extensions/canvas-stophook.js';
|
|
17
17
|
import { createNode, getNode, subscribe } from '../canvas/canvas.js';
|
|
18
|
-
import {
|
|
18
|
+
import { beginExecution, recordExecutionPid } from '../canvas/executions.js';
|
|
19
|
+
import { closeDb, migrate, openDb } from '../canvas/db.js';
|
|
20
|
+
import { resetScopeCache } from '../scope.js';
|
|
21
|
+
import { closeScopedStores } from '../scoped-state/db.js';
|
|
22
|
+
import { initializeFreshScopedStore } from '../scoped-state/migrate.js';
|
|
19
23
|
import { apiSocketPath } from '../canvas/paths.js';
|
|
20
24
|
import { brokerCapReached, resetFleetForTests } from '../runtime/fleet.js';
|
|
21
25
|
import { buildPiArgv } from '../runtime/launch.js';
|
|
22
26
|
import { relaunchRoot } from '../runtime/reset.js';
|
|
23
27
|
import { bindTestFleet } from './helpers/fleet.js';
|
|
24
28
|
let home;
|
|
29
|
+
let tf;
|
|
30
|
+
const previousHome = process.env['HOME'];
|
|
25
31
|
function node(id, over = {}) {
|
|
26
32
|
return {
|
|
27
33
|
node_id: id,
|
|
@@ -67,16 +73,30 @@ function makeDeps(pid) {
|
|
|
67
73
|
}
|
|
68
74
|
before(() => {
|
|
69
75
|
home = mkdtempSync(join(tmpdir(), 'crtr-relaunch-'));
|
|
70
|
-
process.env['
|
|
76
|
+
process.env['HOME'] = home;
|
|
77
|
+
process.env['CRTR_HOME'] = join(home, 'canvas');
|
|
71
78
|
});
|
|
72
79
|
beforeEach(() => {
|
|
73
80
|
closeDb();
|
|
81
|
+
closeScopedStores();
|
|
74
82
|
rmSync(home, { recursive: true, force: true });
|
|
83
|
+
resetScopeCache();
|
|
84
|
+
initializeFreshScopedStore({ kind: 'user', root: join(home, '.crouter') });
|
|
85
|
+
migrate(openDb());
|
|
86
|
+
tf = bindTestFleet();
|
|
75
87
|
});
|
|
76
88
|
after(() => {
|
|
77
89
|
closeDb();
|
|
90
|
+
closeScopedStores();
|
|
91
|
+
tf.fleet.dispose();
|
|
92
|
+
resetFleetForTests();
|
|
78
93
|
rmSync(home, { recursive: true, force: true });
|
|
79
94
|
delete process.env['CRTR_HOME'];
|
|
95
|
+
if (previousHome === undefined)
|
|
96
|
+
delete process.env['HOME'];
|
|
97
|
+
else
|
|
98
|
+
process.env['HOME'] = previousHome;
|
|
99
|
+
resetScopeCache();
|
|
80
100
|
});
|
|
81
101
|
test('relaunchRoot parks the old root done and mints a fresh active root, reaping descendants', async () => {
|
|
82
102
|
// root → child → grandchild (a parent that subscribes to its workers).
|
|
@@ -169,6 +189,10 @@ test('root /new capacity refusal reaches the attached human through broker UI no
|
|
|
169
189
|
process.env['CRTR_NODE_ID'] = 'root';
|
|
170
190
|
createNode(node('root', { parent: null, lifecycle: 'resident' }));
|
|
171
191
|
const tf = bindTestFleet();
|
|
192
|
+
const executionId = beginExecution('root', { daemonEpoch: tf.fleet.epoch() });
|
|
193
|
+
assert.equal(recordExecutionPid(executionId, 'root', process.pid), 'recorded');
|
|
194
|
+
const previousExecutionId = process.env['CRTR_EXECUTION_ID'];
|
|
195
|
+
process.env['CRTR_EXECUTION_ID'] = executionId;
|
|
172
196
|
const never = new Promise(() => { });
|
|
173
197
|
tf.fleet.register('filler-a', { pid: 700_001, exited: never });
|
|
174
198
|
tf.fleet.register('filler-b', { pid: 700_002, exited: never });
|
|
@@ -207,6 +231,10 @@ test('root /new capacity refusal reaches the attached human through broker UI no
|
|
|
207
231
|
resetFleetForTests();
|
|
208
232
|
delete process.env['CRTR_MAX_LIVE_BROKERS'];
|
|
209
233
|
delete process.env['CRTR_NODE_ID'];
|
|
234
|
+
if (previousExecutionId === undefined)
|
|
235
|
+
delete process.env['CRTR_EXECUTION_ID'];
|
|
236
|
+
else
|
|
237
|
+
process.env['CRTR_EXECUTION_ID'] = previousExecutionId;
|
|
210
238
|
}
|
|
211
239
|
});
|
|
212
240
|
test('relaunchRoot is a no-op for a non-root child and an already-parked root', async () => {
|
|
@@ -11,7 +11,9 @@ import assert from 'node:assert/strict';
|
|
|
11
11
|
import { mkdtempSync, rmSync } from 'node:fs';
|
|
12
12
|
import { tmpdir } from 'node:os';
|
|
13
13
|
import { join } from 'node:path';
|
|
14
|
-
import { readConfig, updateConfig } from '../config.js';
|
|
14
|
+
import { ensureScopeInitialized, readConfig, updateConfig } from '../config.js';
|
|
15
|
+
import { closeScopedStores } from '../scoped-state/db.js';
|
|
16
|
+
import { resetScopeCache } from '../scope.js';
|
|
15
17
|
import { setRelayToken } from '../secrets.js';
|
|
16
18
|
import { getRemoteCanvasTarget, resolveRemoteCanvasTarget } from '../remote-canvas-target.js';
|
|
17
19
|
let home;
|
|
@@ -22,9 +24,13 @@ before(() => {
|
|
|
22
24
|
process.env['HOME'] = home;
|
|
23
25
|
});
|
|
24
26
|
beforeEach(() => {
|
|
27
|
+
closeScopedStores();
|
|
25
28
|
rmSync(home, { recursive: true, force: true });
|
|
29
|
+
resetScopeCache();
|
|
30
|
+
ensureScopeInitialized('user', join(home, '.crouter'));
|
|
26
31
|
});
|
|
27
32
|
after(() => {
|
|
33
|
+
closeScopedStores();
|
|
28
34
|
rmSync(home, { recursive: true, force: true });
|
|
29
35
|
if (realHome !== undefined)
|
|
30
36
|
process.env['HOME'] = realHome;
|
|
@@ -8,9 +8,11 @@ import assert from 'node:assert/strict';
|
|
|
8
8
|
import { mkdtempSync, mkdirSync, realpathSync, rmSync, writeFileSync } from 'node:fs';
|
|
9
9
|
import { tmpdir } from 'node:os';
|
|
10
10
|
import { join } from 'node:path';
|
|
11
|
+
import { ensureScopeInitialized } from '../config.js';
|
|
11
12
|
import { gitSync } from '../git.js';
|
|
12
13
|
import { createProfile } from '../profiles/manifest.js';
|
|
13
14
|
import { loadMemoryStoreView, memoryStoresInPrecedence, openProjectMemoryStore, resolveMemoryDocForTarget, } from '../memory-resolver.js';
|
|
15
|
+
import { closeScopedStores } from '../scoped-state/db.js';
|
|
14
16
|
import { resetScopeCache } from '../scope.js';
|
|
15
17
|
const cleanups = [];
|
|
16
18
|
let previousHome;
|
|
@@ -20,8 +22,10 @@ before(() => {
|
|
|
20
22
|
beforeEach(() => {
|
|
21
23
|
process.env.HOME = fixtureDir('crtr-repository-root-identity-home-');
|
|
22
24
|
resetScopeCache();
|
|
25
|
+
ensureScopeInitialized('user', join(process.env.HOME, '.crouter'));
|
|
23
26
|
});
|
|
24
27
|
after(() => {
|
|
28
|
+
closeScopedStores();
|
|
25
29
|
resetScopeCache();
|
|
26
30
|
for (const path of cleanups)
|
|
27
31
|
rmSync(path, { recursive: true, force: true });
|
|
@@ -5,11 +5,13 @@
|
|
|
5
5
|
// persona keeps the stronger default needed to synthesise a broad review.
|
|
6
6
|
import { after, before, test } from 'node:test';
|
|
7
7
|
import assert from 'node:assert/strict';
|
|
8
|
-
import { mkdirSync, mkdtempSync, rmSync
|
|
8
|
+
import { mkdirSync, mkdtempSync, rmSync } from 'node:fs';
|
|
9
9
|
import { tmpdir } from 'node:os';
|
|
10
10
|
import { join } from 'node:path';
|
|
11
11
|
import { defaultKindsConfig, defaultModelLaddersConfig } from '../../types.js';
|
|
12
12
|
import { buildLaunchSpec, normalizeModel } from '../runtime/launch.js';
|
|
13
|
+
import { writeRawConfig } from '../config.js';
|
|
14
|
+
import { initializeFreshScopedStore } from '../scoped-state/migrate.js';
|
|
13
15
|
const priorHome = process.env['HOME'];
|
|
14
16
|
const ladders = defaultModelLaddersConfig();
|
|
15
17
|
// Review's own kind default IS its floor — an explicit override weaker than
|
|
@@ -20,14 +22,15 @@ before(() => {
|
|
|
20
22
|
home = mkdtempSync(join(tmpdir(), 'crtr-review-model-floor-'));
|
|
21
23
|
process.env['HOME'] = home;
|
|
22
24
|
mkdirSync(join(home, '.crouter'), { recursive: true });
|
|
23
|
-
|
|
25
|
+
initializeFreshScopedStore({ kind: 'user', root: join(home, '.crouter') });
|
|
26
|
+
writeRawConfig('user', {
|
|
24
27
|
kinds: {
|
|
25
28
|
'audit/reviewers/security': {
|
|
26
29
|
whenToUse: 'Review one security surface.',
|
|
27
30
|
model: 'medium',
|
|
28
31
|
},
|
|
29
32
|
},
|
|
30
|
-
})
|
|
33
|
+
});
|
|
31
34
|
});
|
|
32
35
|
after(() => {
|
|
33
36
|
if (priorHome === undefined)
|