@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
|
@@ -6,19 +6,37 @@ import assert from 'node:assert/strict';
|
|
|
6
6
|
import { mkdtempSync, rmSync } from 'node:fs';
|
|
7
7
|
import { tmpdir } from 'node:os';
|
|
8
8
|
import { join } from 'node:path';
|
|
9
|
-
import {
|
|
9
|
+
import { createNode } from '../canvas/canvas.js';
|
|
10
|
+
import { closeDb, migrate, openDb } from '../canvas/db.js';
|
|
11
|
+
import { beginBootFaultAttempt, recordFault } from '../canvas/recovery.js';
|
|
10
12
|
let home;
|
|
11
13
|
before(() => {
|
|
12
14
|
home = mkdtempSync(join(tmpdir(), 'crtr-boot-fault-attempt-'));
|
|
13
15
|
process.env['CRTR_HOME'] = home;
|
|
14
16
|
});
|
|
15
17
|
beforeEach(() => {
|
|
18
|
+
closeDb();
|
|
16
19
|
rmSync(home, { recursive: true, force: true });
|
|
20
|
+
migrate(openDb());
|
|
17
21
|
});
|
|
18
22
|
after(() => {
|
|
23
|
+
closeDb();
|
|
19
24
|
rmSync(home, { recursive: true, force: true });
|
|
20
25
|
});
|
|
26
|
+
function node(nodeId) {
|
|
27
|
+
return {
|
|
28
|
+
node_id: nodeId,
|
|
29
|
+
name: nodeId,
|
|
30
|
+
created: new Date().toISOString(),
|
|
31
|
+
cwd: home,
|
|
32
|
+
kind: 'general',
|
|
33
|
+
mode: 'base',
|
|
34
|
+
lifecycle: 'terminal',
|
|
35
|
+
status: 'active',
|
|
36
|
+
};
|
|
37
|
+
}
|
|
21
38
|
test('a fatal crtr→pi fault recorded after the snapshot is surfaced', { timeout: 1_000 }, () => {
|
|
39
|
+
createNode(node('node-a'));
|
|
22
40
|
const attempt = beginBootFaultAttempt('node-a');
|
|
23
41
|
recordFault('node-a', {
|
|
24
42
|
link: 'crtr→pi',
|
|
@@ -30,6 +48,7 @@ test('a fatal crtr→pi fault recorded after the snapshot is surfaced', { timeou
|
|
|
30
48
|
assert.equal(attempt.explanation(), "model resolution at launch: model 'bogus' has no 'provider/id' form and cannot be resolved");
|
|
31
49
|
});
|
|
32
50
|
test('a stale fault already present at snapshot time is never surfaced, even if a matching-shape fault is written afterward (fail closed)', { timeout: 1_000 }, () => {
|
|
51
|
+
createNode(node('node-b'));
|
|
33
52
|
// A prior attempt's fault survives clearFault's best-effort removal (its own
|
|
34
53
|
// errors are swallowed and unchecked by callers) — the exact failure mode
|
|
35
54
|
// the diagnostic must not be fooled by.
|
|
@@ -56,10 +75,12 @@ test('a stale fault already present at snapshot time is never surfaced, even if
|
|
|
56
75
|
assert.equal(attempt.explanation(), null, 'a fault present before this attempt began must fail closed, not surface any cause');
|
|
57
76
|
});
|
|
58
77
|
test('no fault recorded at all yields no explanation', { timeout: 1_000 }, () => {
|
|
78
|
+
createNode(node('node-c'));
|
|
59
79
|
const attempt = beginBootFaultAttempt('node-c');
|
|
60
80
|
assert.equal(attempt.explanation(), null);
|
|
61
81
|
});
|
|
62
82
|
test('an unrelated fault (wrong link, or non-fatal) is never surfaced as a boot cause', { timeout: 1_000 }, () => {
|
|
83
|
+
createNode(node('node-d'));
|
|
63
84
|
const attempt = beginBootFaultAttempt('node-d');
|
|
64
85
|
recordFault('node-d', {
|
|
65
86
|
link: 'viewer↔broker',
|
|
@@ -71,6 +92,7 @@ test('an unrelated fault (wrong link, or non-fatal) is never surfaced as a boot
|
|
|
71
92
|
assert.equal(attempt.explanation(), null);
|
|
72
93
|
});
|
|
73
94
|
test('a fault with an empty operation or message falls back to null rather than an empty diagnosis', { timeout: 1_000 }, () => {
|
|
95
|
+
createNode(node('node-e'));
|
|
74
96
|
const attempt = beginBootFaultAttempt('node-e');
|
|
75
97
|
recordFault('node-e', {
|
|
76
98
|
link: 'crtr→pi',
|
|
@@ -17,8 +17,9 @@ import assert from 'node:assert/strict';
|
|
|
17
17
|
import { mkdtempSync, rmSync } from 'node:fs';
|
|
18
18
|
import { tmpdir } from 'node:os';
|
|
19
19
|
import { join } from 'node:path';
|
|
20
|
-
import { createNode, getRow
|
|
21
|
-
import { closeDb, openDb } from '../canvas/db.js';
|
|
20
|
+
import { createNode, getRow } from '../canvas/canvas.js';
|
|
21
|
+
import { closeDb, migrate, openDb } from '../canvas/db.js';
|
|
22
|
+
import { beginExecution, migrateLegacyExecutionIdentities, recordExecutionPid } from '../canvas/executions.js';
|
|
22
23
|
import { bootChanged, bootProvenSame, reconcileBootLiveness, reconcileAndMigrateBoot, } from '../canvas/boot.js';
|
|
23
24
|
let home;
|
|
24
25
|
/** Build a BootIdentity for injection. `bootId` null models the non-Linux
|
|
@@ -27,11 +28,16 @@ function ident(bootId, bootEpochMs) {
|
|
|
27
28
|
return { bootId, bootEpochMs };
|
|
28
29
|
}
|
|
29
30
|
const BOOT_A = '4b0c1d2e-3f40-4152-8637-a1b2c3d4e5f6';
|
|
30
|
-
/**
|
|
31
|
-
* the identity from the real `ps`, which can't produce a controlled legacy
|
|
32
|
-
* `lstart#ticks` value on a non-Linux test host). */
|
|
31
|
+
/** Create a running execution with a controlled legacy identity. */
|
|
33
32
|
function setPidIdentity(id, pid, identity) {
|
|
34
|
-
|
|
33
|
+
const executionId = beginExecution(id, { daemonEpoch: 'test' });
|
|
34
|
+
recordExecutionPid(executionId, id, pid);
|
|
35
|
+
openDb().prepare('UPDATE executions SET process_identity = ? WHERE execution_id = ?').run(identity, executionId);
|
|
36
|
+
return executionId;
|
|
37
|
+
}
|
|
38
|
+
function recordExecution(id, pid) {
|
|
39
|
+
const executionId = beginExecution(id, { daemonEpoch: 'test' });
|
|
40
|
+
recordExecutionPid(executionId, id, pid);
|
|
35
41
|
}
|
|
36
42
|
function node(id, over = {}) {
|
|
37
43
|
return {
|
|
@@ -53,6 +59,7 @@ before(() => {
|
|
|
53
59
|
beforeEach(() => {
|
|
54
60
|
closeDb();
|
|
55
61
|
rmSync(home, { recursive: true, force: true });
|
|
62
|
+
migrate(openDb());
|
|
56
63
|
});
|
|
57
64
|
after(() => {
|
|
58
65
|
closeDb();
|
|
@@ -86,18 +93,18 @@ test('bootChanged: wall-clock fallback (no boot_id) — epochs far apart are a D
|
|
|
86
93
|
// migrateLegacyPidIdentities — one-time in-place format migration at startup
|
|
87
94
|
test('migrateLegacyPidIdentities: a live legacy lstart#ticks broker is re-recorded to <bootId>#<ticks>', () => {
|
|
88
95
|
createNode(node('n1'));
|
|
89
|
-
setPidIdentity('n1', 111, 'Sat Jul 11 17:51:45 2026#53459'); // legacy baseline
|
|
96
|
+
const executionId = setPidIdentity('n1', 111, 'Sat Jul 11 17:51:45 2026#53459'); // legacy baseline
|
|
90
97
|
// The pid still names the same live process; its CURRENT identity on this
|
|
91
98
|
// (now boot_id-capable) platform reads bootId#ticks with the SAME ticks.
|
|
92
|
-
const result =
|
|
93
|
-
assert.deepEqual(result.migrated, [
|
|
99
|
+
const result = migrateLegacyExecutionIdentities((pid) => (pid === 111 ? `${BOOT_A}#53459` : undefined));
|
|
100
|
+
assert.deepEqual(result.migrated, [executionId]);
|
|
94
101
|
assert.equal(getRow('n1')?.pi_pid_identity, `${BOOT_A}#53459`, 'legacy row completed to boot-scoped format');
|
|
95
102
|
assert.equal(getRow('n1')?.pi_pid, 111, 'the pid itself is untouched');
|
|
96
103
|
});
|
|
97
104
|
test('migrateLegacyPidIdentities: a legacy row whose pid is GONE is left to normal liveness handling', () => {
|
|
98
105
|
createNode(node('n1'));
|
|
99
106
|
setPidIdentity('n1', 111, 'Sat Jul 11 17:51:45 2026#53459');
|
|
100
|
-
const result =
|
|
107
|
+
const result = migrateLegacyExecutionIdentities(() => undefined); // pid gone / probe failed
|
|
101
108
|
assert.deepEqual(result.migrated, []);
|
|
102
109
|
assert.equal(getRow('n1')?.pi_pid_identity, 'Sat Jul 11 17:51:45 2026#53459', 'untouched — liveness handles it');
|
|
103
110
|
});
|
|
@@ -105,7 +112,7 @@ test('migrateLegacyPidIdentities: a REUSED pid (different ticks) is NOT re-recor
|
|
|
105
112
|
createNode(node('n1'));
|
|
106
113
|
setPidIdentity('n1', 111, 'Sat Jul 11 17:51:45 2026#53459');
|
|
107
114
|
// The pid now names a DIFFERENT process (different jiffies) — no match.
|
|
108
|
-
const result =
|
|
115
|
+
const result = migrateLegacyExecutionIdentities(() => `${BOOT_A}#99999`);
|
|
109
116
|
assert.deepEqual(result.migrated, []);
|
|
110
117
|
assert.equal(getRow('n1')?.pi_pid_identity, 'Sat Jul 11 17:51:45 2026#53459', 'reused pid left for liveness to clear');
|
|
111
118
|
});
|
|
@@ -113,7 +120,7 @@ test('migrateLegacyPidIdentities: an already boot-scoped row is skipped (not leg
|
|
|
113
120
|
createNode(node('n1'));
|
|
114
121
|
setPidIdentity('n1', 111, `${BOOT_A}#53459`); // already new-format
|
|
115
122
|
let captured = false;
|
|
116
|
-
const result =
|
|
123
|
+
const result = migrateLegacyExecutionIdentities(() => {
|
|
117
124
|
captured = true;
|
|
118
125
|
return `${BOOT_A}#53459`;
|
|
119
126
|
});
|
|
@@ -125,14 +132,14 @@ test('migrateLegacyPidIdentities: no readable boot_id (current identity still le
|
|
|
125
132
|
setPidIdentity('n1', 111, 'Sat Jul 11 17:51:45 2026#53459');
|
|
126
133
|
// Platform still composes legacy-shaped identities (no boot_id) — nothing to
|
|
127
134
|
// upgrade to; the legacy compare lane legitimately stays in play.
|
|
128
|
-
const result =
|
|
135
|
+
const result = migrateLegacyExecutionIdentities(() => 'Sun Jul 12 09:00:00 2026#53459');
|
|
129
136
|
assert.deepEqual(result.migrated, []);
|
|
130
137
|
assert.equal(getRow('n1')?.pi_pid_identity, 'Sat Jul 11 17:51:45 2026#53459', 'no boot_id → not migrated');
|
|
131
138
|
});
|
|
132
139
|
test('reconcileBootLiveness: first-ever call seeds the marker and clears nothing', () => {
|
|
133
140
|
const m = node('n1');
|
|
134
141
|
createNode(m);
|
|
135
|
-
|
|
142
|
+
recordExecution('n1', 12345);
|
|
136
143
|
const result = reconcileBootLiveness(ident('boot-A', 1_000_000));
|
|
137
144
|
assert.deepEqual(result, { changed: false, cleared: [], sameBootProven: false });
|
|
138
145
|
assert.equal(getRow('n1')?.pi_pid, 12345, 'a first-ever run never clears an existing pid');
|
|
@@ -140,7 +147,7 @@ test('reconcileBootLiveness: first-ever call seeds the marker and clears nothing
|
|
|
140
147
|
test('reconcileBootLiveness: same boot (same boot_id) leaves pids untouched — MUST NOT weaken the normal daemon-restart case', () => {
|
|
141
148
|
const m = node('n1');
|
|
142
149
|
createNode(m);
|
|
143
|
-
|
|
150
|
+
recordExecution('n1', 12345);
|
|
144
151
|
reconcileBootLiveness(ident('boot-A', 1_000_000)); // seed
|
|
145
152
|
const result = reconcileBootLiveness(ident('boot-A', 1_000_000 + 3_000)); // 3s later, same boot
|
|
146
153
|
assert.deepEqual(result, { changed: false, cleared: [], sameBootProven: true });
|
|
@@ -153,9 +160,9 @@ test('reconcileBootLiveness: a boot change clears every recorded pid, regardless
|
|
|
153
160
|
const noPid = node('no-pid-1', { status: 'active' });
|
|
154
161
|
for (const m of [active, idle, dead, noPid])
|
|
155
162
|
createNode(m);
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
163
|
+
recordExecution('active-1', 111);
|
|
164
|
+
recordExecution('idle-1', 222);
|
|
165
|
+
recordExecution('dead-1', 333);
|
|
159
166
|
// no-pid-1 deliberately left without a recorded pid.
|
|
160
167
|
reconcileBootLiveness(ident('boot-A', 1_000_000)); // seed boot A
|
|
161
168
|
const result = reconcileBootLiveness(ident('boot-B', 1_000_000 + 60 * 60_000)); // boot B
|
|
@@ -169,7 +176,7 @@ test('reconcileBootLiveness: a boot change clears every recorded pid, regardless
|
|
|
169
176
|
test('reconcileBootLiveness: a fast recreate (distinct boot_id, 42s wall) still sweeps (Major-2 regression)', () => {
|
|
170
177
|
const m = node('n1');
|
|
171
178
|
createNode(m);
|
|
172
|
-
|
|
179
|
+
recordExecution('n1', 111);
|
|
173
180
|
reconcileBootLiveness(ident('boot-A', 1_000_000)); // seed boot A
|
|
174
181
|
const result = reconcileBootLiveness(ident('boot-B', 1_000_000 + 42_000)); // 42s later — inside the wall window, but new boot_id
|
|
175
182
|
assert.equal(result.changed, true, 'distinct boot_id detected even 42s apart');
|
|
@@ -179,10 +186,10 @@ test('reconcileBootLiveness: a fast recreate (distinct boot_id, 42s wall) still
|
|
|
179
186
|
test('reconcileBootLiveness: after reconciling, the SAME boot no longer re-triggers (idempotent)', () => {
|
|
180
187
|
const m = node('n1');
|
|
181
188
|
createNode(m);
|
|
182
|
-
|
|
189
|
+
recordExecution('n1', 111);
|
|
183
190
|
reconcileBootLiveness(ident('boot-A', 1_000_000)); // seed boot A
|
|
184
191
|
reconcileBootLiveness(ident('boot-B', 1_000_000 + 60 * 60_000)); // boot change → clears + persists boot B
|
|
185
|
-
|
|
192
|
+
recordExecution('n1', 999); // a fresh broker re-records its pid post-revive
|
|
186
193
|
const result = reconcileBootLiveness(ident('boot-B', 1_000_000 + 60 * 60_000 + 2_000)); // still boot B, 2s later
|
|
187
194
|
assert.deepEqual(result, { changed: false, cleared: [], sameBootProven: true });
|
|
188
195
|
assert.equal(getRow('n1')?.pi_pid, 999, 'a pid recorded AFTER reconciliation, within the same boot, is never touched');
|
|
@@ -214,7 +221,7 @@ test('bootProvenSame: a different boot_id is not proof (it is a change)', () =>
|
|
|
214
221
|
// revert that inverts/drops the gate or reorders migration ahead of
|
|
215
222
|
// reconciliation is caught here. `runDaemon` calls this same helper.
|
|
216
223
|
function daemonBootStartup(current, captureIdentity) {
|
|
217
|
-
return reconcileAndMigrateBoot(
|
|
224
|
+
return reconcileAndMigrateBoot(migrateLegacyExecutionIdentities, current, captureIdentity);
|
|
218
225
|
}
|
|
219
226
|
const LEGACY = 'Sat Jul 11 17:51:45 2026#53459';
|
|
220
227
|
test('migration gate: a cross-boot equal-ticks legacy row is NOT migrated when the marker is ABSENT (first-ever startup)', () => {
|
|
@@ -240,12 +247,12 @@ test('migration gate: a cross-boot equal-ticks legacy row is NOT migrated under
|
|
|
240
247
|
});
|
|
241
248
|
test('migration gate: a legacy row IS migrated when same-boot provenance is PROVEN (exact boot_id match)', () => {
|
|
242
249
|
createNode(node('n1'));
|
|
243
|
-
setPidIdentity('n1', 111, LEGACY);
|
|
250
|
+
const executionId = setPidIdentity('n1', 111, LEGACY);
|
|
244
251
|
reconcileBootLiveness(ident(BOOT_A, 1_000_000)); // seed an exact-boot_id marker
|
|
245
252
|
// Same boot proven (boot_id equal on both sides); pid 111 still names the same
|
|
246
253
|
// live process (matching ticks) — the in-place upgrade completes.
|
|
247
254
|
const result = daemonBootStartup(ident(BOOT_A, 1_000_000 + 3_000), (pid) => pid === 111 ? `${BOOT_A}#53459` : undefined);
|
|
248
|
-
assert.deepEqual(result.migrated, [
|
|
255
|
+
assert.deepEqual(result.migrated, [executionId]);
|
|
249
256
|
assert.equal(getRow('n1')?.pi_pid_identity, `${BOOT_A}#53459`, 'proven same boot → migrated in place');
|
|
250
257
|
});
|
|
251
258
|
test('migrateLegacyPidIdentities CAS: a concurrent re-record between probe and update is not clobbered', () => {
|
|
@@ -254,7 +261,7 @@ test('migrateLegacyPidIdentities CAS: a concurrent re-record between probe and u
|
|
|
254
261
|
// The capture models the old broker still probing as its live legacy self,
|
|
255
262
|
// but a concurrent revive atomically re-records a FRESH (pid, identity) pair
|
|
256
263
|
// before the sweep's compare-and-swap update lands.
|
|
257
|
-
const result =
|
|
264
|
+
const result = migrateLegacyExecutionIdentities((pid) => {
|
|
258
265
|
if (pid === 111) {
|
|
259
266
|
setPidIdentity('n1', 222, `${BOOT_A}#77777`); // concurrent revive wins the row
|
|
260
267
|
return `${BOOT_A}#53459`; // stale probe result for the OLD pid
|
|
@@ -6,20 +6,43 @@ import { dirname, join } from 'node:path';
|
|
|
6
6
|
import { fileURLToPath } from 'node:url';
|
|
7
7
|
import { createAgentSessionFromServices, createAgentSessionServices, SessionManager, VERSION } from '../runtime/broker-sdk.js';
|
|
8
8
|
import { buildBrokerSession } from '../runtime/broker.js';
|
|
9
|
+
import { createNode } from '../canvas/canvas.js';
|
|
10
|
+
import { beginExecution } from '../canvas/executions.js';
|
|
11
|
+
import { closeDb, migrate, openDb } from '../canvas/db.js';
|
|
12
|
+
import { ensureScopeInitialized } from '../config.js';
|
|
9
13
|
import { unregisteredConcreteModel } from '../model-routes.js';
|
|
14
|
+
import { closeScopedStores } from '../scoped-state/db.js';
|
|
15
|
+
import { initializeFreshScopedStore } from '../scoped-state/migrate.js';
|
|
16
|
+
import { resetScopeCache } from '../scope.js';
|
|
17
|
+
import { piAgentDir } from '../runtime/package-health.js';
|
|
18
|
+
import { createApiServer } from '../../daemon/api/server.js';
|
|
10
19
|
import { isUnknownModel } from '../runtime/model-selection.js';
|
|
11
20
|
import { resolveProviderCandidates } from '../subscription-state.js';
|
|
12
21
|
const realEngine = { createAgentSessionServices, createAgentSessionFromServices, SessionManager, VERSION };
|
|
13
22
|
const C3_EXT = join(dirname(fileURLToPath(import.meta.url)), 'fixtures', 'c3-custom-provider-ext.ts');
|
|
14
23
|
const previousModelIntent = process.env['CRTR_MODEL_INTENT'];
|
|
24
|
+
const previousHome = process.env['HOME'];
|
|
25
|
+
let home;
|
|
15
26
|
before(() => {
|
|
16
27
|
delete process.env['CRTR_MODEL_INTENT'];
|
|
28
|
+
home = mkdtempSync(join(tmpdir(), 'crtr-launch-candidate-home-'));
|
|
29
|
+
process.env['HOME'] = home;
|
|
30
|
+
resetScopeCache();
|
|
31
|
+
ensureScopeInitialized('user', join(home, '.crouter'));
|
|
32
|
+
initializeFreshScopedStore({ kind: 'provider', root: piAgentDir() });
|
|
17
33
|
});
|
|
18
34
|
after(() => {
|
|
35
|
+
closeScopedStores();
|
|
36
|
+
rmSync(home, { recursive: true, force: true });
|
|
19
37
|
if (previousModelIntent === undefined)
|
|
20
38
|
delete process.env['CRTR_MODEL_INTENT'];
|
|
21
39
|
else
|
|
22
40
|
process.env['CRTR_MODEL_INTENT'] = previousModelIntent;
|
|
41
|
+
if (previousHome === undefined)
|
|
42
|
+
delete process.env['HOME'];
|
|
43
|
+
else
|
|
44
|
+
process.env['HOME'] = previousHome;
|
|
45
|
+
resetScopeCache();
|
|
23
46
|
});
|
|
24
47
|
const requested = { provider: 'anthropic', id: 'requested' };
|
|
25
48
|
const alternative = { provider: 'openai-codex', id: 'alternative' };
|
|
@@ -121,6 +144,18 @@ test('launch candidate resolver selects a non-managed candidate as automatic fal
|
|
|
121
144
|
});
|
|
122
145
|
test('broker launch rejects an unregistered concrete model even when a non-managed provider is available', async () => {
|
|
123
146
|
const cwd = mkdtempSync(join(tmpdir(), 'crtr-launch-candidate-'));
|
|
147
|
+
const priorCanvasHome = process.env['CRTR_HOME'];
|
|
148
|
+
const priorNodeId = process.env['CRTR_NODE_ID'];
|
|
149
|
+
const priorExecutionId = process.env['CRTR_EXECUTION_ID'];
|
|
150
|
+
const nodeId = 'launch-candidate';
|
|
151
|
+
closeDb();
|
|
152
|
+
process.env['CRTR_HOME'] = home;
|
|
153
|
+
process.env['CRTR_NODE_ID'] = nodeId;
|
|
154
|
+
migrate(openDb());
|
|
155
|
+
createNode({ node_id: nodeId, name: nodeId, created: new Date().toISOString(), cwd, kind: 'developer', mode: 'base', lifecycle: 'resident', status: 'active' });
|
|
156
|
+
process.env['CRTR_EXECUTION_ID'] = beginExecution(nodeId, { daemonEpoch: 'test' });
|
|
157
|
+
const server = createApiServer();
|
|
158
|
+
await server.ready;
|
|
124
159
|
try {
|
|
125
160
|
const engine = {
|
|
126
161
|
...realEngine,
|
|
@@ -139,6 +174,20 @@ test('broker launch rejects an unregistered concrete model even when a non-manag
|
|
|
139
174
|
await assert.rejects(buildBrokerSession(engine, { cwd, extensionPaths: [C3_EXT], model: 'missing/missing' }), /FATAL: model 'missing\/missing' is not registered/);
|
|
140
175
|
}
|
|
141
176
|
finally {
|
|
177
|
+
await server.close();
|
|
178
|
+
closeDb();
|
|
179
|
+
if (priorCanvasHome === undefined)
|
|
180
|
+
delete process.env['CRTR_HOME'];
|
|
181
|
+
else
|
|
182
|
+
process.env['CRTR_HOME'] = priorCanvasHome;
|
|
183
|
+
if (priorNodeId === undefined)
|
|
184
|
+
delete process.env['CRTR_NODE_ID'];
|
|
185
|
+
else
|
|
186
|
+
process.env['CRTR_NODE_ID'] = priorNodeId;
|
|
187
|
+
if (priorExecutionId === undefined)
|
|
188
|
+
delete process.env['CRTR_EXECUTION_ID'];
|
|
189
|
+
else
|
|
190
|
+
process.env['CRTR_EXECUTION_ID'] = priorExecutionId;
|
|
142
191
|
rmSync(cwd, { recursive: true, force: true });
|
|
143
192
|
}
|
|
144
193
|
});
|