@north-light/crouter 0.3.312 → 0.3.313
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/client.d.ts +27 -30
- package/dist/api/client.js +80 -67
- package/dist/api/dto/broker-ops.d.ts +10 -20
- package/dist/api/dto/canvas.d.ts +1 -10
- package/dist/api/dto/health.d.ts +113 -0
- package/dist/api/dto/human-requests.d.ts +14 -3
- package/dist/api/dto/human.d.ts +2 -48
- package/dist/api/dto/human.js +3 -2
- package/dist/api/dto/inbox.d.ts +14 -0
- package/dist/api/dto/mail.d.ts +43 -0
- package/dist/api/dto/nodes.d.ts +11 -8
- package/dist/api/dto/recovery.d.ts +96 -0
- package/dist/api/dto/reviews.d.ts +2 -2
- package/dist/api/routes.d.ts +9 -6
- package/dist/api/routes.js +11 -11
- package/dist/build-root.d.ts +4 -0
- package/dist/build-root.js +11 -1
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/integration/provider-rotation.test.ts +35 -47
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +1 -1
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +12 -5
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +12 -5
- package/dist/cli.js +10 -1
- package/dist/clients/__tests__/helpers/human-daemon.d.ts +11 -0
- package/dist/clients/__tests__/helpers/human-daemon.js +60 -0
- package/dist/clients/attach/chrome/canvas-panels.js +1 -1
- package/dist/clients/attach/chrome/inbox-strip.d.ts +3 -3
- package/dist/clients/attach/chrome/inbox-strip.js +17 -9
- package/dist/clients/attach/chrome/ticket-panel.d.ts +2 -2
- package/dist/clients/attach/chrome/ticket-panel.js +77 -46
- package/dist/clients/attach/overlays/graph.js +6 -9
- package/dist/clients/attach/render/chat-view.d.ts +5 -4
- package/dist/clients/attach/render/chat-view.js +22 -13
- package/dist/clients/attach/render/page-block.d.ts +11 -7
- package/dist/clients/attach/render/page-block.js +64 -55
- package/dist/clients/attach/viewer.js +746 -735
- package/dist/clients/inbox/__tests__/integration/inbox-controller.test.js +56 -56
- package/dist/clients/inbox/__tests__/integration/stale-row-activation.test.js +45 -32
- package/dist/clients/inbox/controller.d.ts +42 -14
- package/dist/clients/inbox/controller.js +240 -124
- package/dist/clients/inbox/dto-adapt.d.ts +28 -0
- package/dist/clients/inbox/dto-adapt.js +93 -0
- package/dist/clients/inbox/page-adapter.d.ts +5 -4
- package/dist/clients/inbox/page-adapter.js +12 -12
- package/dist/clients/inbox/resolve.d.ts +10 -5
- package/dist/clients/inbox/resolve.js +13 -12
- package/dist/clients/inbox/review/review-client.d.ts +0 -1
- package/dist/clients/inbox/review/review-client.js +0 -4
- package/dist/clients/inbox/review-adapter.d.ts +2 -1
- package/dist/clients/inbox/review-adapter.js +3 -5
- package/dist/clients/inbox/surface.d.ts +2 -2
- package/dist/clients/inbox/surface.js +19 -8
- package/dist/clients/inbox/tui.d.ts +3 -3
- package/dist/commands/__tests__/human.test.js +31 -15
- package/dist/commands/__tests__/integration/dashboard-snapshot.test.js +36 -11
- package/dist/commands/{sys/__tests__ → __tests__/integration}/migrate.test.js +142 -36
- package/dist/commands/__tests__/revive-now-gate.test.js +2 -0
- package/dist/commands/api-client.d.ts +5 -4
- package/dist/commands/api-client.js +13 -7
- package/dist/commands/canvas-history/shared.js +1 -1
- package/dist/commands/canvas-history.js +1 -1
- package/dist/commands/canvas-roster.js +1 -1
- package/dist/commands/canvas.js +1 -2
- package/dist/commands/human/feedback.js +20 -17
- package/dist/commands/human/prompts.js +45 -36
- package/dist/commands/human/queue.js +73 -123
- package/dist/commands/human/review.js +6 -16
- package/dist/commands/memory/__tests__/command-selector-and-mutation-guards.test.js +2 -0
- package/dist/commands/memory/__tests__/memory-list-and-lint-ignore.test.js +2 -0
- package/dist/commands/memory/__tests__/repository-root-lint.test.js +2 -0
- package/dist/commands/node-inspect-artifacts.js +1 -1
- package/dist/commands/node-lifecycle-revive.d.ts +2 -2
- package/dist/commands/node-lifecycle-revive.js +9 -19
- package/dist/commands/pkg/plugin-manage.js +0 -1
- package/dist/commands/profile/show.js +4 -12
- package/dist/commands/surface-tmux-spread.js +1 -5
- package/dist/commands/sys/__tests__/config-model-ladders.test.js +23 -30
- package/dist/commands/sys/__tests__/sync-project-guidance.test.js +37 -11
- package/dist/commands/sys/branch.d.ts +2 -0
- package/dist/commands/sys/branch.js +19 -0
- package/dist/commands/sys/config.js +106 -33
- package/dist/commands/sys/daemon.d.ts +2 -0
- package/dist/commands/sys/daemon.js +130 -7
- package/dist/commands/sys/doctor.js +5 -15
- package/dist/commands/sys/migrate.js +21 -92
- package/dist/commands/sys/setup-settings-runner.js +4 -2
- package/dist/commands/sys.js +2 -15
- package/dist/core/__tests__/boot-fault-attempt.test.js +23 -1
- package/dist/core/__tests__/boot.test.js +32 -25
- package/dist/core/__tests__/broker-launch-candidates.test.js +49 -0
- package/dist/core/__tests__/canvas-inbox-watcher-hold.test.js +149 -176
- package/dist/core/__tests__/canvas-inbox-watcher-naming.test.js +59 -10
- package/dist/core/__tests__/canvas-inbox-watcher.test.js +76 -20
- package/dist/core/__tests__/canvas.test.js +18 -47
- package/dist/core/__tests__/child-death-wake.test.js +29 -7
- package/dist/core/__tests__/cli-help-contract.test.js +2 -0
- package/dist/core/__tests__/close.test.js +29 -10
- package/dist/core/__tests__/collectible.test.js +2 -1
- package/dist/core/__tests__/config-change-delta.test.js +2 -0
- package/dist/core/__tests__/context-intro.test.js +13 -1
- package/dist/core/__tests__/cron-armed-context-failure.test.js +17 -12
- package/dist/core/__tests__/cron-held-settlement.test.js +21 -3
- package/dist/core/__tests__/cron-node-sink-parked-root.test.js +29 -10
- package/dist/core/__tests__/cron-self-cancel-delivery.test.js +14 -2
- package/dist/core/__tests__/cron-timeout-descendants.test.js +13 -1
- package/dist/core/__tests__/daemon-boot.test.js +51 -14
- package/dist/core/__tests__/fixtures/fake-engine.d.ts +1 -1
- package/dist/core/__tests__/fixtures/fake-engine.js +8 -3
- package/dist/core/__tests__/focuses.test.js +10 -5
- package/dist/core/__tests__/helpers/harness.js +50 -18
- package/dist/core/__tests__/history-inbox.test.js +12 -16
- package/dist/core/__tests__/human-action-delivery.test.js +48 -28
- package/dist/core/__tests__/human-actions.test.js +7 -3
- package/dist/core/__tests__/inline-memory-refs.test.js +7 -2
- package/dist/core/__tests__/integration/broker-fork-seam.test.js +37 -10
- package/dist/core/__tests__/integration/broker-sdk-wiring.test.js +42 -0
- package/dist/core/__tests__/integration/broker-snapshot-history.test.js +42 -29
- package/dist/core/__tests__/integration/broker-wedge-supervision.test.js +36 -35
- package/dist/core/__tests__/integration/command-plugins.test.js +15 -6
- package/dist/core/__tests__/integration/deferred-no-wake.test.js +113 -92
- package/dist/core/__tests__/integration/host-teardown-process-group.test.js +9 -5
- package/dist/core/__tests__/integration/lifecycle-hooks.test.js +16 -3
- package/dist/core/__tests__/integration/plugin-revalidate.test.js +4 -0
- package/dist/core/__tests__/integration/profile-pause.test.js +4 -4
- package/dist/core/__tests__/integration/refresh-stall-recycle.test.js +9 -12
- package/dist/core/__tests__/integration/revive.test.js +67 -21
- package/dist/core/__tests__/integration/spawn-root.test.js +51 -8
- package/dist/core/__tests__/integration/subscription-delivery.test.js +33 -21
- package/dist/core/__tests__/integration/worktree-land.test.js +5 -2
- package/dist/core/__tests__/integration/worktree-reap.test.js +15 -1
- package/dist/core/__tests__/kickoff.test.js +36 -39
- package/dist/core/__tests__/lifecycle-terminal-reasons.test.js +2 -1
- package/dist/core/__tests__/lifecycle.test.js +2 -1
- package/dist/core/__tests__/live-lifecycle-prompt.test.js +13 -1
- package/dist/core/__tests__/memory-resolver-precedence.test.js +2 -0
- package/dist/core/__tests__/migration.test.js +145 -31
- package/dist/core/__tests__/model-pin-durability.test.js +4 -1
- package/dist/core/__tests__/model-routes-config.test.js +13 -5
- package/dist/core/__tests__/node-outcome.test.js +93 -26
- package/dist/core/__tests__/on-read-crouter-home-fence.test.js +2 -1
- package/dist/core/__tests__/on-read-dedup-resume.test.js +2 -1
- package/dist/core/__tests__/on-read-nested-store.test.js +2 -1
- package/dist/core/__tests__/passive-subscription.test.js +50 -157
- package/dist/core/__tests__/plugin-kinds.test.js +6 -4
- package/dist/core/__tests__/plugin-link-symlinked-scope-root.test.js +6 -1
- package/dist/core/__tests__/plugin-page-components.test.js +6 -4
- package/dist/core/__tests__/preview-registry-sync.test.js +2 -0
- package/dist/core/__tests__/profile-project-memory-delivery.test.js +4 -1
- package/dist/core/__tests__/prune.test.js +11 -5
- package/dist/core/__tests__/push-final-guard.test.js +14 -7
- package/dist/core/__tests__/relaunch-root.test.js +30 -2
- package/dist/core/__tests__/remote-canvas-target.test.js +7 -1
- package/dist/core/__tests__/repository-root-identity.test.js +4 -0
- package/dist/core/__tests__/review-model-floor.test.js +6 -3
- package/dist/core/__tests__/revive-all.test.js +13 -3
- package/dist/core/__tests__/revive-capacity.test.js +26 -4
- package/dist/core/__tests__/revive-parked-fresh.test.js +31 -8
- package/dist/core/__tests__/seam/broker-attach-stream.test.js +1 -1
- package/dist/core/__tests__/seam/broker-cap-freeze.test.js +4 -3
- package/dist/core/__tests__/seam/broker-crash-teardown.test.js +11 -14
- package/dist/core/__tests__/seam/broker-provider-retry.test.js +85 -71
- package/dist/core/__tests__/seam/dormancy-release.test.js +33 -19
- package/dist/core/__tests__/seam/held-deferred-human-prompt.test.js +7 -5
- package/dist/core/__tests__/seam/inbox-reference-guidance.test.js +20 -6
- package/dist/core/__tests__/seam/node-outcome-delivery.test.js +27 -3
- package/dist/core/__tests__/spawn-worktree-id-conflict.test.js +2 -1
- package/dist/core/__tests__/stop-guard.test.js +2 -1
- package/dist/core/__tests__/subscription-pool-credential-guard.test.js +4 -3
- package/dist/core/__tests__/warm-claim-preference-snapshot.test.js +18 -4
- package/dist/core/__tests__/yield-ensures-daemon.test.js +2 -1
- package/dist/core/bootstrap.js +2 -0
- package/dist/core/broker-client/__tests__/transport-socket.test.js +51 -6
- package/dist/core/broker-client/transport-socket.d.ts +1 -0
- package/dist/core/broker-client/transport-socket.js +13 -5
- package/dist/core/canvas/__tests__/attention.test.js +29 -35
- package/dist/core/canvas/__tests__/history-transcript.test.js +6 -6
- package/dist/core/canvas/__tests__/render-remote.test.js +25 -9
- package/dist/core/canvas/attention.d.ts +2 -5
- package/dist/core/canvas/attention.js +15 -64
- package/dist/core/canvas/boot.d.ts +6 -7
- package/dist/core/canvas/boot.js +5 -9
- package/dist/core/canvas/canvas.d.ts +13 -109
- package/dist/core/canvas/canvas.js +140 -401
- package/dist/core/canvas/crons.d.ts +2 -0
- package/dist/core/canvas/crons.js +16 -15
- package/dist/core/canvas/daemon-owner.js +10 -0
- package/dist/core/canvas/db.d.ts +2 -2
- package/dist/core/canvas/db.js +2 -18
- package/dist/core/canvas/deliveries.d.ts +104 -0
- package/dist/core/canvas/deliveries.js +354 -0
- package/dist/core/canvas/executions.d.ts +29 -0
- package/dist/core/canvas/executions.js +68 -0
- package/dist/core/canvas/history.js +35 -35
- package/dist/core/canvas/index.d.ts +3 -1
- package/dist/core/canvas/index.js +3 -1
- package/dist/core/canvas/migrations.js +20 -12
- package/dist/core/canvas/nav-model.js +1 -3
- package/dist/core/canvas/nav-render.d.ts +4 -4
- package/dist/core/canvas/nav-render.js +11 -21
- package/dist/core/canvas/node-sql-migration.d.ts +3 -0
- package/dist/core/canvas/node-sql-migration.js +261 -0
- package/dist/core/canvas/paths.d.ts +2 -16
- package/dist/core/canvas/paths.js +2 -31
- package/dist/core/canvas/recovery.d.ts +76 -0
- package/dist/core/canvas/recovery.js +588 -0
- package/dist/core/canvas/remote-canvas-source.js +4 -0
- package/dist/core/canvas/render-source.d.ts +16 -27
- package/dist/core/canvas/render-source.js +16 -45
- package/dist/core/canvas/sessions.d.ts +33 -0
- package/dist/core/canvas/sessions.js +78 -0
- package/dist/core/canvas/types.d.ts +33 -33
- package/dist/core/canvas/types.js +2 -5
- package/dist/core/canvas/waits.d.ts +18 -0
- package/dist/core/canvas/waits.js +70 -0
- package/dist/core/canvas/worktrees.d.ts +40 -0
- package/dist/core/canvas/worktrees.js +93 -0
- package/dist/core/config.d.ts +17 -12
- package/dist/core/config.js +106 -155
- package/dist/core/feed/__tests__/inbox-migrate.test.js +27 -31
- package/dist/core/feed/feed.d.ts +0 -6
- package/dist/core/feed/feed.js +68 -56
- package/dist/core/feed/inbox.d.ts +7 -81
- package/dist/core/feed/inbox.js +46 -378
- package/dist/core/feed/messages.d.ts +58 -0
- package/dist/core/feed/messages.js +217 -0
- package/dist/core/fs-utils.d.ts +4 -0
- package/dist/core/fs-utils.js +21 -1
- package/dist/core/human/answer.d.ts +1 -1
- package/dist/core/human/answer.js +1 -1
- package/dist/core/human/claim.d.ts +1 -1
- package/dist/core/human/claim.js +2 -4
- package/dist/core/human/component-docs.js +1 -1
- package/dist/core/human/feedback-companion.js +3 -2
- package/dist/core/human/feedback.d.ts +5 -8
- package/dist/core/human/feedback.js +57 -85
- package/dist/core/human/page-authoring.d.ts +30 -0
- package/dist/core/human/page-authoring.js +19 -0
- package/dist/core/human/requests.d.ts +136 -0
- package/dist/core/human/requests.js +515 -0
- package/dist/core/human/root.d.ts +0 -7
- package/dist/core/human/root.js +0 -17
- package/dist/core/human/scan.d.ts +2 -7
- package/dist/core/human/scan.js +48 -132
- package/dist/core/human/summary.d.ts +1 -1
- package/dist/core/human/summary.js +1 -1
- package/dist/core/human/tickets.d.ts +23 -83
- package/dist/core/human/tickets.js +92 -243
- package/dist/core/human/types.d.ts +5 -1
- package/dist/core/installed-plugins.js +8 -3
- package/dist/core/keybindings/__tests__/resolve.test.js +19 -17
- package/dist/core/locked-file.d.ts +6 -3
- package/dist/core/locked-file.js +36 -9
- package/dist/core/memory/extensions.js +2 -0
- package/dist/core/preview-registry.js +0 -1
- package/dist/core/profiles/__tests__/env-store.test.js +2 -0
- package/dist/core/profiles/default-binding.d.ts +0 -4
- package/dist/core/profiles/default-binding.js +12 -58
- package/dist/core/profiles/env-store.js +8 -3
- package/dist/core/profiles/manifest.d.ts +2 -37
- package/dist/core/profiles/manifest.js +35 -161
- package/dist/core/profiles/select.js +3 -0
- package/dist/core/review/__tests__/capture-origin.test.js +13 -2
- package/dist/core/review/__tests__/comments.test.js +28 -10
- package/dist/core/review/__tests__/remap.test.js +28 -10
- package/dist/core/review/__tests__/stage-identity.test.js +17 -7
- package/dist/core/review/birth.d.ts +1 -1
- package/dist/core/review/birth.js +34 -5
- package/dist/core/review/comments.js +1 -1
- package/dist/core/review/document.js +1 -1
- package/dist/core/review/project.d.ts +5 -1
- package/dist/core/review/project.js +14 -36
- package/dist/core/review/realize.d.ts +3 -6
- package/dist/core/review/realize.js +51 -168
- package/dist/core/review/remap.js +1 -1
- package/dist/core/review/stage.d.ts +3 -2
- package/dist/core/review/stage.js +2 -3
- package/dist/core/review/store.d.ts +3 -21
- package/dist/core/review/store.js +140 -186
- package/dist/core/review/types.d.ts +0 -1
- package/dist/core/runtime/__tests__/install-id-cache-scoping.test.js +9 -5
- package/dist/core/runtime/__tests__/spawn-env.test.js +8 -9
- package/dist/core/runtime/broker/auth-reload.js +9 -10
- package/dist/core/runtime/broker/daemon-ops.d.ts +25 -8
- package/dist/core/runtime/broker/daemon-ops.js +42 -9
- package/dist/core/runtime/broker/extension-abort.d.ts +3 -0
- package/dist/core/runtime/broker/extension-abort.js +11 -0
- package/dist/core/runtime/broker/fault-retry.d.ts +15 -6
- package/dist/core/runtime/broker/fault-retry.js +142 -95
- package/dist/core/runtime/broker/inbox.d.ts +4 -32
- package/dist/core/runtime/broker/inbox.js +4 -92
- package/dist/core/runtime/broker/rebind.d.ts +1 -0
- package/dist/core/runtime/broker/rebind.js +21 -12
- package/dist/core/runtime/broker-persona-guidance.d.ts +1 -1
- package/dist/core/runtime/broker-persona-guidance.js +2 -13
- package/dist/core/runtime/broker.js +28 -22
- package/dist/core/runtime/close.d.ts +3 -9
- package/dist/core/runtime/close.js +16 -27
- package/dist/core/runtime/fault.d.ts +3 -93
- package/dist/core/runtime/fault.js +9 -419
- package/dist/core/runtime/kickoff.d.ts +3 -6
- package/dist/core/runtime/kickoff.js +12 -18
- package/dist/core/runtime/launch.js +1 -1
- package/dist/core/runtime/lifecycle.js +40 -7
- package/dist/core/runtime/placement.js +2 -2
- package/dist/core/runtime/recycle.js +8 -2
- package/dist/core/runtime/reset.js +22 -6
- package/dist/core/runtime/revive.js +226 -218
- package/dist/core/runtime/spawn.js +14 -3
- package/dist/core/scoped-state/db.d.ts +7 -0
- package/dist/core/scoped-state/db.js +92 -0
- package/dist/core/scoped-state/migrate.d.ts +11 -0
- package/dist/core/scoped-state/migrate.js +198 -0
- package/dist/core/scoped-state/paths.d.ts +9 -0
- package/dist/core/scoped-state/paths.js +27 -0
- package/dist/core/scoped-state/profiles.d.ts +12 -0
- package/dist/core/scoped-state/profiles.js +62 -0
- package/dist/core/scoped-state/providers.d.ts +16 -0
- package/dist/core/scoped-state/providers.js +8 -0
- package/dist/core/scoped-state/schema.d.ts +3 -0
- package/dist/core/scoped-state/schema.js +26 -0
- package/dist/core/scoped-state/settings.d.ts +28 -0
- package/dist/core/scoped-state/settings.js +82 -0
- package/dist/core/subscription-state.d.ts +29 -48
- package/dist/core/subscription-state.js +176 -712
- package/dist/core/worktree-close.js +4 -4
- package/dist/core/worktree-mutation-async.js +2 -2
- package/dist/core/worktree-sweep.js +11 -16
- package/dist/core/worktree.js +6 -12
- package/dist/daemon/__tests__/autostart-storm.test.js +1 -39
- package/dist/daemon/__tests__/helpers/source-daemon.d.ts +2 -2
- package/dist/daemon/__tests__/helpers/source-daemon.js +7 -6
- package/dist/daemon/__tests__/integration/migration-startup.test.js +59 -26
- package/dist/daemon/__tests__/node-deadline-lane.test.js +2 -1
- package/dist/daemon/__tests__/node-outcome-birth-invariants.test.js +39 -15
- package/dist/daemon/__tests__/node-outcome-delivery.test.js +39 -10
- package/dist/daemon/__tests__/reconciler-signature.test.js +2 -2
- package/dist/daemon/__tests__/subtree-filter-freshness.test.js +2 -2
- package/dist/daemon/api/__tests__/broker-settle-park.test.js +17 -12
- package/dist/daemon/api/__tests__/canvas-snapshot-fields.test.js +27 -5
- package/dist/daemon/api/__tests__/model-config.test.js +8 -8
- package/dist/daemon/api/__tests__/node-create-description.test.js +22 -5
- package/dist/daemon/api/__tests__/node-model-validation.test.js +21 -1
- package/dist/daemon/api/__tests__/nodes-activity-query.test.js +10 -12
- package/dist/daemon/api/__tests__/profile-launch-gates.test.js +4 -1
- package/dist/daemon/api/__tests__/profile-metadata-route.test.js +4 -1
- package/dist/daemon/api/__tests__/reopen-delivery.test.js +26 -8
- package/dist/daemon/api/__tests__/seam/api-server.test.js +24 -32
- package/dist/daemon/api/__tests__/seam/b10-attach-modelauth.test.js +4 -1
- package/dist/daemon/api/__tests__/seam/leaf-api-parity.test.js +5 -4
- package/dist/daemon/api/__tests__/seam/profile-delete.test.js +27 -41
- package/dist/daemon/api/__tests__/submit-result.test.js +3 -2
- package/dist/daemon/api/bridge.js +1 -1
- package/dist/daemon/api/handlers/bash-jobs.js +6 -7
- package/dist/daemon/api/handlers/broker-ops.js +47 -84
- package/dist/daemon/api/handlers/broker-recovery.d.ts +4 -0
- package/dist/daemon/api/handlers/broker-recovery.js +251 -0
- package/dist/daemon/api/handlers/canvas.js +2 -44
- package/dist/daemon/api/handlers/daemon.js +41 -0
- package/dist/daemon/api/handlers/feedback-comments.js +2 -2
- package/dist/daemon/api/handlers/health.js +10 -5
- package/dist/daemon/api/handlers/human-requests.js +168 -188
- package/dist/daemon/api/handlers/human.js +3 -151
- package/dist/daemon/api/handlers/inbox-page.d.ts +4 -0
- package/dist/daemon/api/handlers/inbox-page.js +89 -0
- package/dist/daemon/api/handlers/inbox.js +21 -120
- package/dist/daemon/api/handlers/messages.d.ts +1 -0
- package/dist/daemon/api/handlers/messages.js +73 -15
- package/dist/daemon/api/handlers/node-outcomes.js +58 -13
- package/dist/daemon/api/handlers/nodes.js +7 -13
- package/dist/daemon/api/handlers/reviews.js +4 -29
- package/dist/daemon/api/map.d.ts +25 -3
- package/dist/daemon/api/map.js +84 -14
- package/dist/daemon/api/server.js +68 -9
- package/dist/daemon/control.d.ts +18 -0
- package/dist/daemon/cron/disposition.d.ts +2 -0
- package/dist/daemon/cron/disposition.js +8 -5
- package/dist/daemon/cron/settle.js +37 -13
- package/dist/daemon/cron/sinks.d.ts +18 -1
- package/dist/daemon/cron/sinks.js +47 -93
- package/dist/daemon/crtrd-cli.js +4 -19
- package/dist/daemon/crtrd.d.ts +2 -0
- package/dist/daemon/crtrd.js +206 -81
- package/dist/daemon/fleet.js +5 -6
- package/dist/daemon/human/finish.d.ts +12 -24
- package/dist/daemon/human/finish.js +88 -285
- package/dist/daemon/human/settle.d.ts +40 -0
- package/dist/daemon/human/settle.js +89 -0
- package/dist/daemon/human/sweep.d.ts +20 -5
- package/dist/daemon/human/sweep.js +56 -60
- package/dist/daemon/manage.d.ts +21 -16
- package/dist/daemon/manage.js +85 -51
- package/dist/daemon/messaging/node-message.d.ts +1 -1
- package/dist/daemon/messaging/node-message.js +9 -12
- package/dist/daemon/park-activity.js +3 -3
- package/dist/daemon/reconcilers/bash-deadline.js +6 -7
- package/dist/daemon/reconcilers/broker-supervision.d.ts +1 -1
- package/dist/daemon/reconcilers/broker-supervision.js +41 -19
- package/dist/daemon/reconcilers/controller-death.js +6 -18
- package/dist/daemon/reconcilers/delivery-lane.d.ts +9 -0
- package/dist/daemon/reconcilers/delivery-lane.js +130 -0
- package/dist/daemon/reconcilers/live-obligation.js +3 -3
- package/dist/daemon/reconcilers/node-deadline.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.d.ts +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +10 -12
- package/dist/daemon/reconcilers/node-lifecycle/tick.js +5 -5
- package/dist/daemon/reconcilers/node-lifecycle/wants-execution.js +1 -1
- package/dist/daemon/reconcilers/pending-review-submit.js +3 -3
- package/dist/daemon/reconcilers/storage-maintenance.d.ts +2 -8
- package/dist/daemon/reconcilers/storage-maintenance.js +13 -43
- package/dist/daemon/review/companion.js +5 -11
- package/dist/daemon/review/deliver.d.ts +1 -5
- package/dist/daemon/review/deliver.js +3 -52
- package/dist/daemon/review/finish.d.ts +2 -27
- package/dist/daemon/review/finish.js +79 -263
- package/dist/daemon/review/sweep.d.ts +3 -10
- package/dist/daemon/review/sweep.js +13 -131
- package/dist/daemon/startup-policy.d.ts +0 -5
- package/dist/daemon/startup-policy.js +0 -5
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -1
- package/dist/migrations/__tests__/activation-concurrency.test.js +3 -2
- package/dist/migrations/__tests__/activation.test.js +9 -6
- package/dist/migrations/activation.d.ts +3 -2
- package/dist/migrations/activation.js +2 -4
- package/dist/migrations/corpus.d.ts +2 -5
- package/dist/migrations/corpus.js +9 -20
- package/dist/migrations/runner.d.ts +3 -1
- package/dist/migrations/runner.js +6 -2
- package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +21 -89
- package/dist/pi-extensions/__tests__/canvas-goal-capture-envelope.test.js +4 -2
- package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +51 -33
- package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.js +16 -2
- package/dist/pi-extensions/__tests__/pre-command-gate.test.js +13 -1
- package/dist/pi-extensions/canvas-inbox-watcher.js +98 -244
- package/dist/pi-extensions/canvas-passive-context.d.ts +4 -8
- package/dist/pi-extensions/canvas-passive-context.js +85 -37
- package/dist/pi-extensions/canvas-stophook.js +47 -31
- package/dist/shared/env.d.ts +1 -0
- package/dist/shared/env.js +3 -0
- package/package.json +1 -1
- package/runtime.lock.json +5 -5
- package/dist/clients/attach/__tests__/page-block.test.js +0 -54
- package/dist/clients/inbox/review-visibility.d.ts +0 -5
- package/dist/clients/inbox/review-visibility.js +0 -19
- package/dist/commands/canvas-rebuild-index.d.ts +0 -2
- package/dist/commands/canvas-rebuild-index.js +0 -46
- package/dist/core/__tests__/human-cancel-guard.test.js +0 -110
- package/dist/core/__tests__/human-deliver.test.d.ts +0 -1
- package/dist/core/__tests__/human-deliver.test.js +0 -256
- package/dist/core/__tests__/human-node-not-supervised.test.d.ts +0 -1
- package/dist/core/__tests__/human-node-not-supervised.test.js +0 -89
- package/dist/core/__tests__/integration/human-deliver-e2e.test.d.ts +0 -1
- package/dist/core/__tests__/integration/human-deliver-e2e.test.js +0 -131
- package/dist/core/__tests__/phase4-review-store.test.d.ts +0 -1
- package/dist/core/__tests__/phase4-review-store.test.js +0 -144
- package/dist/core/__tests__/watchdog-abort-arms-retry.test.d.ts +0 -1
- package/dist/core/__tests__/watchdog-abort-arms-retry.test.js +0 -110
- package/dist/core/canvas/human-deliveries.d.ts +0 -39
- package/dist/core/canvas/human-deliveries.js +0 -75
- package/dist/core/canvas/node-outcome-deliveries.d.ts +0 -64
- package/dist/core/canvas/node-outcome-deliveries.js +0 -159
- package/dist/core/feed/passive.d.ts +0 -3
- package/dist/core/feed/passive.js +0 -53
- package/dist/core/human/__tests__/inbox-cancel-worker.d.ts +0 -1
- package/dist/core/human/__tests__/inbox-cancel-worker.js +0 -7
- package/dist/core/human/__tests__/inbox-claim-worker.d.ts +0 -1
- package/dist/core/human/__tests__/inbox-claim-worker.js +0 -17
- package/dist/core/human/__tests__/inbox-stale-claim-worker.d.ts +0 -1
- package/dist/core/human/__tests__/inbox-stale-claim-worker.js +0 -8
- package/dist/core/human/__tests__/integration/inbox-core.test.d.ts +0 -1
- package/dist/core/human/__tests__/integration/inbox-core.test.js +0 -145
- package/dist/core/human/__tests__/page-tickets.test.d.ts +0 -1
- package/dist/core/human/__tests__/page-tickets.test.js +0 -161
- package/dist/core/review/ticket-filter.d.ts +0 -17
- package/dist/core/review/ticket-filter.js +0 -21
- package/dist/core/runtime/broker/passive.d.ts +0 -17
- package/dist/core/runtime/broker/passive.js +0 -44
- package/dist/core/runtime/busy.d.ts +0 -46
- package/dist/core/runtime/busy.js +0 -150
- package/dist/daemon/__tests__/startup-block-marker.test.d.ts +0 -1
- package/dist/daemon/__tests__/startup-block-marker.test.js +0 -86
- package/dist/daemon/api/__tests__/review-terminal-conflict.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/review-terminal-conflict.test.js +0 -98
- package/dist/daemon/human/deliver-action.d.ts +0 -3
- package/dist/daemon/human/deliver-action.js +0 -9
- package/dist/daemon/node-outcome/deliver-outcome.d.ts +0 -3
- package/dist/daemon/node-outcome/deliver-outcome.js +0 -9
- package/dist/daemon/reconcilers/human-delivery-lane.d.ts +0 -10
- package/dist/daemon/reconcilers/human-delivery-lane.js +0 -41
- package/dist/daemon/reconcilers/node-outcome-delivery-lane.d.ts +0 -10
- package/dist/daemon/reconcilers/node-outcome-delivery-lane.js +0 -41
- package/dist/daemon/startup-block-marker.d.ts +0 -25
- package/dist/daemon/startup-block-marker.js +0 -99
- /package/dist/{clients/attach/__tests__/page-block.test.d.ts → api/dto/mail.js} +0 -0
- /package/dist/{commands/sys/__tests__/migrate.test.d.ts → api/dto/recovery.js} +0 -0
- /package/dist/{core/__tests__/human-cancel-guard.test.d.ts → commands/__tests__/integration/migrate.test.d.ts} +0 -0
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import { after, before, test } from 'node:test';
|
|
2
|
-
import assert from 'node:assert/strict';
|
|
3
|
-
import { mkdtempSync, rmSync } from 'node:fs';
|
|
4
|
-
import { tmpdir } from 'node:os';
|
|
5
|
-
import { join } from 'node:path';
|
|
6
|
-
import { FaultRetry } from '../runtime/broker/fault-retry.js';
|
|
7
|
-
import { admitProviderRetryEpisode, clearFault, readFault, readProviderRetryEpisode, recordPendingProviderRetryFault, } from '../runtime/fault.js';
|
|
8
|
-
let home;
|
|
9
|
-
before(() => {
|
|
10
|
-
home = mkdtempSync(join(tmpdir(), 'crtr-watchdog-abort-retry-'));
|
|
11
|
-
process.env['CRTR_HOME'] = home;
|
|
12
|
-
});
|
|
13
|
-
after(() => {
|
|
14
|
-
rmSync(home, { recursive: true, force: true });
|
|
15
|
-
});
|
|
16
|
-
test('only a watchdog-stamped aborted settlement records an automatic connection fault', () => {
|
|
17
|
-
const settleAbort = (nodeId, stagedWatchdogAbort, stagedRefreshAbort, stopReason = 'aborted', errorText) => {
|
|
18
|
-
const session = {
|
|
19
|
-
sessionManager: { getLeafId: () => 'leaf-entry' },
|
|
20
|
-
model: undefined,
|
|
21
|
-
};
|
|
22
|
-
const generation = {
|
|
23
|
-
id: 1,
|
|
24
|
-
session,
|
|
25
|
-
fallback: { blocked: false },
|
|
26
|
-
stagedProviderAgentEnd: {
|
|
27
|
-
messages: [{
|
|
28
|
-
role: 'assistant',
|
|
29
|
-
stopReason,
|
|
30
|
-
errorMessage: errorText ?? (stopReason === 'error' ? 'This operation was aborted' : 'Request was aborted'),
|
|
31
|
-
}],
|
|
32
|
-
},
|
|
33
|
-
stagedWatchdogAbort,
|
|
34
|
-
stagedRefreshAbort,
|
|
35
|
-
stagedOverflowFailure: null,
|
|
36
|
-
executingTools: new Set(),
|
|
37
|
-
};
|
|
38
|
-
const retry = new FaultRetry({
|
|
39
|
-
nodeId,
|
|
40
|
-
currentSession: () => session,
|
|
41
|
-
installedGeneration: () => generation,
|
|
42
|
-
});
|
|
43
|
-
retry.publishSettledProviderFault(generation);
|
|
44
|
-
return { retry, generation };
|
|
45
|
-
};
|
|
46
|
-
const watchdog = settleAbort('watchdog-node', true, false);
|
|
47
|
-
const fault = readFault('watchdog-node');
|
|
48
|
-
assert.equal(fault?.link, 'pi→provider');
|
|
49
|
-
assert.equal(fault?.kind, 'connection');
|
|
50
|
-
assert.deepEqual(fault?.retry, { disposition: 'auto', by: 'daemon' });
|
|
51
|
-
assert.equal(watchdog.retry.isActiveAutoFault(fault), true);
|
|
52
|
-
assert.equal(watchdog.generation.stagedWatchdogAbort, false, 'settlement consumes the one-shot provenance');
|
|
53
|
-
settleAbort('human-node', false, false);
|
|
54
|
-
assert.equal(readFault('human-node'), null, 'an otherwise-identical human abort must not arm recovery');
|
|
55
|
-
// Pi 0.84 currently serializes a host abort from `node yield` as an `error`
|
|
56
|
-
// settlement.
|
|
57
|
-
const refresh = settleAbort('refresh-node', false, true, 'error');
|
|
58
|
-
assert.equal(readFault('refresh-node'), null, 'a refresh-aborted error settlement must not enter provider fault recovery');
|
|
59
|
-
assert.equal(refresh.generation.stagedRefreshAbort, false, 'settlement consumes the one-shot refresh provenance');
|
|
60
|
-
// #683 — an abort that lands between requests settles as an error carrying
|
|
61
|
-
// AbortError text. It stopped because something asked it to; a fatal fault
|
|
62
|
-
// here parks the node and fans a false permanent-failure notice.
|
|
63
|
-
settleAbort('aborted-node', false, false, 'error');
|
|
64
|
-
assert.equal(readFault('aborted-node'), null, 'an abort-shaped error settlement must not record a provider fault');
|
|
65
|
-
settleAbort('provider-node', false, false, 'error', 'connection reset by peer');
|
|
66
|
-
const providerFault = readFault('provider-node');
|
|
67
|
-
assert.equal(providerFault?.kind, 'connection', 'a real provider error still classifies');
|
|
68
|
-
assert.equal(providerFault?.retry.disposition, 'auto', 'a real provider error still records its fault');
|
|
69
|
-
});
|
|
70
|
-
test('a failed retry settlement carries the episode forward instead of restarting it', () => {
|
|
71
|
-
// The episode marker a daemon retry records before re-prompting: original
|
|
72
|
-
// anchor, start time, and the attempt just consumed.
|
|
73
|
-
const sessionFile = 'retry-episode-session';
|
|
74
|
-
const admittedFault = recordPendingProviderRetryFault('retry-episode-node', sessionFile, {
|
|
75
|
-
link: 'pi→provider', op: 'generation turn', kind: 'connection',
|
|
76
|
-
retry: { disposition: 'auto', by: 'daemon', attempt: 2, max: 8 },
|
|
77
|
-
message: 'connection reset', since: '2026-01-01T00:00:00.000Z', anchorEntryId: 'original-anchor',
|
|
78
|
-
});
|
|
79
|
-
assert.ok(admittedFault, 'the pre-prompt retry fault persists');
|
|
80
|
-
assert.equal(admitProviderRetryEpisode('retry-episode-node', sessionFile, admittedFault), true, 'the retry is durably admitted before prompt');
|
|
81
|
-
clearFault('retry-episode-node', { link: 'pi→provider' }); // error turn_end clears its ordinary marker
|
|
82
|
-
assert.equal(readProviderRetryEpisode('retry-episode-node')?.state, 'admitted', 'error turn_end preserves the admitted retry for settlement');
|
|
83
|
-
const session = {
|
|
84
|
-
sessionFile,
|
|
85
|
-
sessionManager: { getLeafId: () => 'leaf-after-failed-retry' },
|
|
86
|
-
model: undefined,
|
|
87
|
-
};
|
|
88
|
-
const generation = {
|
|
89
|
-
id: 1,
|
|
90
|
-
session,
|
|
91
|
-
fallback: { blocked: false },
|
|
92
|
-
stagedProviderAgentEnd: {
|
|
93
|
-
messages: [{ role: 'assistant', stopReason: 'error', errorMessage: 'fetch failed' }],
|
|
94
|
-
},
|
|
95
|
-
stagedWatchdogAbort: false,
|
|
96
|
-
stagedRefreshAbort: false,
|
|
97
|
-
stagedOverflowFailure: null,
|
|
98
|
-
executingTools: new Set(),
|
|
99
|
-
};
|
|
100
|
-
new FaultRetry({
|
|
101
|
-
nodeId: 'retry-episode-node',
|
|
102
|
-
currentSession: () => session,
|
|
103
|
-
installedGeneration: () => generation,
|
|
104
|
-
}).publishSettledProviderFault(generation);
|
|
105
|
-
const fault = readFault('retry-episode-node');
|
|
106
|
-
assert.equal(fault?.anchorEntryId, 'original-anchor', 'each retry must rewind to the original fork point, not stack prompts');
|
|
107
|
-
assert.equal(fault?.since, '2026-01-01T00:00:00.000Z', 'the episode start survives a failed retry');
|
|
108
|
-
assert.equal(fault?.retry.attempt, 2, 'the attempt count accumulates toward exhaustion');
|
|
109
|
-
assert.equal(readProviderRetryEpisode('retry-episode-node')?.state, 'pending', 'the failed admitted retry becomes the next durable pending attempt');
|
|
110
|
-
});
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import type { DeliveryFailure, DeliverySettlement } from './delivery-contract.js';
|
|
2
|
-
export type ActionDeliveryState = 'pending' | 'running' | 'accepted' | 'permanent_failed';
|
|
3
|
-
export type ActionDeliveryFailure = DeliveryFailure;
|
|
4
|
-
export interface ActionDeliveryRecord {
|
|
5
|
-
requestId: string;
|
|
6
|
-
state: ActionDeliveryState;
|
|
7
|
-
attempt: number;
|
|
8
|
-
argv: string[];
|
|
9
|
-
cwd: string;
|
|
10
|
-
completion: unknown;
|
|
11
|
-
nextAttemptAt: number;
|
|
12
|
-
claimedAt: number | null;
|
|
13
|
-
claimOwner: string | null;
|
|
14
|
-
acceptedAt: number | null;
|
|
15
|
-
permanentFailedAt: number | null;
|
|
16
|
-
lastFailure: ActionDeliveryFailure | null;
|
|
17
|
-
createdAt: number;
|
|
18
|
-
updatedAt: number;
|
|
19
|
-
}
|
|
20
|
-
/** Insert the one delivery row for a settled action-bound request. Idempotent
|
|
21
|
-
* on requestId: a replayed settlement must not create a second row. */
|
|
22
|
-
export declare function enqueueActionDelivery(row: {
|
|
23
|
-
requestId: string;
|
|
24
|
-
argv: string[];
|
|
25
|
-
cwd: string;
|
|
26
|
-
/** Complete HumanCompletionV1 with delivery.attempt set to 0. */
|
|
27
|
-
completion: unknown;
|
|
28
|
-
}): void;
|
|
29
|
-
/** Delivery state for `GET /v1/human/requests/:id`; null when no row exists. */
|
|
30
|
-
export declare function readActionDelivery(requestId: string): ActionDeliveryRecord | null;
|
|
31
|
-
/** Due pending records in deterministic order for the daemon's serial tick. */
|
|
32
|
-
export declare function dueActionDeliveries(now: number): ActionDeliveryRecord[];
|
|
33
|
-
/** Atomically start one due delivery attempt. A null result lost the claim. */
|
|
34
|
-
export declare function claimActionDelivery(requestId: string, now: number, claimOwner: string): ActionDeliveryRecord | null;
|
|
35
|
-
export type ActionDeliverySettlement = DeliverySettlement;
|
|
36
|
-
/** Settle only the still-owned running attempt, so a stale process cannot overwrite a newer claim. */
|
|
37
|
-
export declare function settleActionDelivery(requestId: string, attempt: number, claimOwner: string, settlement: ActionDeliverySettlement, now: number): boolean;
|
|
38
|
-
/** A new daemon deliberately redelivers interrupted completions at least once. */
|
|
39
|
-
export declare function recoverRunningActionDeliveries(now: number): number;
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
// Durable action-completion delivery state. The terminal ticket is composed
|
|
2
|
-
// before this row exists; this module schedules its already-complete document.
|
|
3
|
-
import { openDb, withCanvasWrite } from './db.js';
|
|
4
|
-
function actionDeliveryFrom(row) {
|
|
5
|
-
return {
|
|
6
|
-
requestId: row.request_id,
|
|
7
|
-
state: row.state,
|
|
8
|
-
attempt: row.attempt,
|
|
9
|
-
argv: JSON.parse(row.argv_json),
|
|
10
|
-
cwd: row.cwd,
|
|
11
|
-
completion: JSON.parse(row.completion_json),
|
|
12
|
-
nextAttemptAt: row.next_attempt_at,
|
|
13
|
-
claimedAt: row.claimed_at,
|
|
14
|
-
claimOwner: row.claim_owner,
|
|
15
|
-
acceptedAt: row.accepted_at,
|
|
16
|
-
permanentFailedAt: row.permanent_failed_at,
|
|
17
|
-
lastFailure: row.last_failure_json === null ? null : JSON.parse(row.last_failure_json),
|
|
18
|
-
createdAt: row.created_at,
|
|
19
|
-
updatedAt: row.updated_at,
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
/** Insert the one delivery row for a settled action-bound request. Idempotent
|
|
23
|
-
* on requestId: a replayed settlement must not create a second row. */
|
|
24
|
-
export function enqueueActionDelivery(row) {
|
|
25
|
-
const now = Date.now();
|
|
26
|
-
withCanvasWrite((db) => {
|
|
27
|
-
db.prepare(`INSERT INTO human_action_deliveries
|
|
28
|
-
(request_id, state, attempt, argv_json, cwd, completion_json, next_attempt_at, created_at, updated_at)
|
|
29
|
-
VALUES (?, 'pending', 0, ?, ?, ?, ?, ?, ?)
|
|
30
|
-
ON CONFLICT(request_id) DO NOTHING`).run(row.requestId, JSON.stringify(row.argv), row.cwd, JSON.stringify(row.completion), now, now, now);
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
/** Delivery state for `GET /v1/human/requests/:id`; null when no row exists. */
|
|
34
|
-
export function readActionDelivery(requestId) {
|
|
35
|
-
const row = openDb()
|
|
36
|
-
.prepare('SELECT * FROM human_action_deliveries WHERE request_id = ?')
|
|
37
|
-
.get(requestId);
|
|
38
|
-
return row === undefined ? null : actionDeliveryFrom(row);
|
|
39
|
-
}
|
|
40
|
-
/** Due pending records in deterministic order for the daemon's serial tick. */
|
|
41
|
-
export function dueActionDeliveries(now) {
|
|
42
|
-
return openDb()
|
|
43
|
-
.prepare(`SELECT * FROM human_action_deliveries
|
|
44
|
-
WHERE state = 'pending' AND next_attempt_at <= ?
|
|
45
|
-
ORDER BY next_attempt_at, created_at, request_id`)
|
|
46
|
-
.all(now).map(actionDeliveryFrom);
|
|
47
|
-
}
|
|
48
|
-
/** Atomically start one due delivery attempt. A null result lost the claim. */
|
|
49
|
-
export function claimActionDelivery(requestId, now, claimOwner) {
|
|
50
|
-
return withCanvasWrite((db) => {
|
|
51
|
-
const claimed = db.prepare(`UPDATE human_action_deliveries
|
|
52
|
-
SET state = 'running', attempt = attempt + 1, claimed_at = ?, claim_owner = ?, updated_at = ?
|
|
53
|
-
WHERE request_id = ? AND state = 'pending' AND next_attempt_at <= ?`).run(now, claimOwner, now, requestId, now);
|
|
54
|
-
if (Number(claimed.changes) === 0)
|
|
55
|
-
return null;
|
|
56
|
-
const row = db.prepare('SELECT * FROM human_action_deliveries WHERE request_id = ?').get(requestId);
|
|
57
|
-
return actionDeliveryFrom(row);
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
/** Settle only the still-owned running attempt, so a stale process cannot overwrite a newer claim. */
|
|
61
|
-
export function settleActionDelivery(requestId, attempt, claimOwner, settlement, now) {
|
|
62
|
-
const failure = settlement.state === 'accepted' ? null : JSON.stringify(settlement.failure);
|
|
63
|
-
const result = withCanvasWrite((db) => db.prepare(`UPDATE human_action_deliveries
|
|
64
|
-
SET state = ?, next_attempt_at = ?, claimed_at = NULL, claim_owner = NULL,
|
|
65
|
-
accepted_at = ?, permanent_failed_at = ?, last_failure_json = ?, updated_at = ?
|
|
66
|
-
WHERE request_id = ? AND state = 'running' AND attempt = ? AND claim_owner = ?`).run(settlement.state, settlement.state === 'pending' ? settlement.nextAttemptAt : now, settlement.state === 'accepted' ? now : null, settlement.state === 'permanent_failed' ? now : null, failure, now, requestId, attempt, claimOwner));
|
|
67
|
-
return Number(result.changes) === 1;
|
|
68
|
-
}
|
|
69
|
-
/** A new daemon deliberately redelivers interrupted completions at least once. */
|
|
70
|
-
export function recoverRunningActionDeliveries(now) {
|
|
71
|
-
const result = withCanvasWrite((db) => db.prepare(`UPDATE human_action_deliveries
|
|
72
|
-
SET state = 'pending', next_attempt_at = ?, claimed_at = NULL, claim_owner = NULL, updated_at = ?
|
|
73
|
-
WHERE state = 'running'`).run(now, now));
|
|
74
|
-
return Number(result.changes);
|
|
75
|
-
}
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import type { DeliveryFailure, DeliverySettlement } from './delivery-contract.js';
|
|
2
|
-
import { type NodeOutcomeKind, type TerminalReason } from './types.js';
|
|
3
|
-
export type OutcomeDeliveryState = 'armed' | 'pending' | 'running' | 'accepted' | 'permanent_failed';
|
|
4
|
-
export type OutcomeDeliveryFailure = DeliveryFailure;
|
|
5
|
-
export interface OutcomeDeliveryRecord {
|
|
6
|
-
nodeId: string;
|
|
7
|
-
state: OutcomeDeliveryState;
|
|
8
|
-
attempt: number;
|
|
9
|
-
actionName: string;
|
|
10
|
-
argv: string[];
|
|
11
|
-
cwd: string;
|
|
12
|
-
configOrigin: string;
|
|
13
|
-
payload: unknown | null;
|
|
14
|
-
document: unknown | null;
|
|
15
|
-
nextAttemptAt: number;
|
|
16
|
-
claimedAt: number | null;
|
|
17
|
-
claimOwner: string | null;
|
|
18
|
-
acceptedAt: number | null;
|
|
19
|
-
permanentFailedAt: number | null;
|
|
20
|
-
lastFailure: OutcomeDeliveryFailure | null;
|
|
21
|
-
createdAt: number;
|
|
22
|
-
updatedAt: number;
|
|
23
|
-
}
|
|
24
|
-
export interface OutcomeDocumentSnapshot {
|
|
25
|
-
kind: NodeOutcomeKind;
|
|
26
|
-
reason: TerminalReason;
|
|
27
|
-
at: string;
|
|
28
|
-
revision: number;
|
|
29
|
-
detailJson: string | null;
|
|
30
|
-
}
|
|
31
|
-
/** Compose every delivery document from the hydrated identity and the immutable outcome latch. */
|
|
32
|
-
export declare function composeOutcomeDeliveryDocument(args: {
|
|
33
|
-
nodeId: string;
|
|
34
|
-
outcome: OutcomeDocumentSnapshot;
|
|
35
|
-
action: {
|
|
36
|
-
name: string;
|
|
37
|
-
payload: unknown;
|
|
38
|
-
};
|
|
39
|
-
finalReport?: string | null;
|
|
40
|
-
structuredResult?: unknown;
|
|
41
|
-
}): string;
|
|
42
|
-
/** Register a target atomically against the outcome latch. A still-armed target
|
|
43
|
-
* is replaceable; a settled registration is not. When the outcome already
|
|
44
|
-
* exists, the row is born pending with its complete immutable document. */
|
|
45
|
-
export declare function armOutcomeDelivery(row: {
|
|
46
|
-
nodeId: string;
|
|
47
|
-
actionName: string;
|
|
48
|
-
argv: string[];
|
|
49
|
-
cwd: string;
|
|
50
|
-
configOrigin: string;
|
|
51
|
-
payload?: unknown;
|
|
52
|
-
now?: number;
|
|
53
|
-
}): OutcomeDeliveryRecord | null;
|
|
54
|
-
export declare function readOutcomeDelivery(nodeId: string): OutcomeDeliveryRecord | null;
|
|
55
|
-
export declare function dueOutcomeDeliveries(now: number): OutcomeDeliveryRecord[];
|
|
56
|
-
export declare function claimOutcomeDelivery(nodeId: string, now: number, claimOwner: string): OutcomeDeliveryRecord | null;
|
|
57
|
-
export type OutcomeDeliverySettlement = DeliverySettlement;
|
|
58
|
-
/** Settle only the still-owned running attempt, fencing stale delivery processes. */
|
|
59
|
-
export declare function settleOutcomeDelivery(nodeId: string, attempt: number, claimOwner: string, settlement: OutcomeDeliverySettlement, now: number): boolean;
|
|
60
|
-
export declare function recoverRunningOutcomeDeliveries(now: number): number;
|
|
61
|
-
/** Disarming is deliberately limited to registrations that have not started delivery. */
|
|
62
|
-
export declare function disarmOutcomeDelivery(nodeId: string): boolean;
|
|
63
|
-
/** A canonical final is the one allowed outcome supersede: discard any old claim and retry state. */
|
|
64
|
-
export declare function resetOutcomeDeliveryForSupersede(nodeId: string, documentJson: string | null, now: number): boolean;
|
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
// Durable delivery registration and attempt state for a node's terminal outcome.
|
|
2
|
-
import { openDb, withCanvasWrite } from './db.js';
|
|
3
|
-
import { getNode } from './canvas.js';
|
|
4
|
-
import { OUTCOME_PAYLOAD_MAX_BYTES } from './types.js';
|
|
5
|
-
import { composeNodeOutcomeDocument } from '../runtime/outcome-document.js';
|
|
6
|
-
function serializedPayload(payload) {
|
|
7
|
-
if (payload === undefined)
|
|
8
|
-
return null;
|
|
9
|
-
const json = JSON.stringify(payload);
|
|
10
|
-
if (json === undefined)
|
|
11
|
-
throw new TypeError('outcome delivery payload must be JSON-serializable');
|
|
12
|
-
if (Buffer.byteLength(json, 'utf8') > OUTCOME_PAYLOAD_MAX_BYTES) {
|
|
13
|
-
throw new RangeError(`outcome delivery payload exceeds ${OUTCOME_PAYLOAD_MAX_BYTES} bytes`);
|
|
14
|
-
}
|
|
15
|
-
return json;
|
|
16
|
-
}
|
|
17
|
-
function outcomeDeliveryFrom(row) {
|
|
18
|
-
return {
|
|
19
|
-
nodeId: row.node_id,
|
|
20
|
-
state: row.state,
|
|
21
|
-
attempt: row.attempt,
|
|
22
|
-
actionName: row.action_name,
|
|
23
|
-
argv: JSON.parse(row.argv_json),
|
|
24
|
-
cwd: row.cwd,
|
|
25
|
-
configOrigin: row.config_origin,
|
|
26
|
-
payload: row.payload_json === null ? null : JSON.parse(row.payload_json),
|
|
27
|
-
document: row.document_json === null ? null : JSON.parse(row.document_json),
|
|
28
|
-
nextAttemptAt: row.next_attempt_at,
|
|
29
|
-
claimedAt: row.claimed_at,
|
|
30
|
-
claimOwner: row.claim_owner,
|
|
31
|
-
acceptedAt: row.accepted_at,
|
|
32
|
-
permanentFailedAt: row.permanent_failed_at,
|
|
33
|
-
lastFailure: row.last_failure_json === null ? null : JSON.parse(row.last_failure_json),
|
|
34
|
-
createdAt: row.created_at,
|
|
35
|
-
updatedAt: row.updated_at,
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
/** The latch, rather than a later mutable row, defines the terminal view in a delivery document. */
|
|
39
|
-
function nodeAtOutcome(node, outcome) {
|
|
40
|
-
let status;
|
|
41
|
-
let intent;
|
|
42
|
-
if (outcome.kind === 'result' || outcome.reason === 'finished' || outcome.reason === 'declined') {
|
|
43
|
-
status = 'done';
|
|
44
|
-
intent = 'done';
|
|
45
|
-
}
|
|
46
|
-
else if (outcome.reason === 'parked') {
|
|
47
|
-
status = 'done';
|
|
48
|
-
intent = 'parked';
|
|
49
|
-
}
|
|
50
|
-
else if (outcome.reason === 'closed' || outcome.reason === 'retired' || outcome.reason === 'stranded' || outcome.reason === 'deadline_exceeded') {
|
|
51
|
-
status = 'canceled';
|
|
52
|
-
intent = null;
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
status = 'dead';
|
|
56
|
-
intent = null;
|
|
57
|
-
}
|
|
58
|
-
return { ...node, status, intent, terminal_reason: outcome.reason };
|
|
59
|
-
}
|
|
60
|
-
/** Compose every delivery document from the hydrated identity and the immutable outcome latch. */
|
|
61
|
-
export function composeOutcomeDeliveryDocument(args) {
|
|
62
|
-
const node = getNode(args.nodeId);
|
|
63
|
-
if (node === null)
|
|
64
|
-
throw new Error(`unknown node ${args.nodeId}`);
|
|
65
|
-
return JSON.stringify(composeNodeOutcomeDocument({
|
|
66
|
-
node: nodeAtOutcome(node, args.outcome),
|
|
67
|
-
outcome: args.outcome,
|
|
68
|
-
action: args.action,
|
|
69
|
-
...(args.finalReport === undefined ? {} : { finalReport: args.finalReport }),
|
|
70
|
-
...(args.structuredResult === undefined ? {} : { structuredResult: args.structuredResult }),
|
|
71
|
-
}));
|
|
72
|
-
}
|
|
73
|
-
/** Register a target atomically against the outcome latch. A still-armed target
|
|
74
|
-
* is replaceable; a settled registration is not. When the outcome already
|
|
75
|
-
* exists, the row is born pending with its complete immutable document. */
|
|
76
|
-
export function armOutcomeDelivery(row) {
|
|
77
|
-
const now = row.now ?? Date.now();
|
|
78
|
-
const payloadJson = serializedPayload(row.payload);
|
|
79
|
-
return withCanvasWrite((db) => {
|
|
80
|
-
const node = db.prepare('SELECT * FROM nodes WHERE node_id = ?').get(row.nodeId);
|
|
81
|
-
if (node === undefined)
|
|
82
|
-
throw new Error(`unknown node ${row.nodeId}`);
|
|
83
|
-
const settled = node.outcome_at !== null;
|
|
84
|
-
if (settled && (node.outcome_kind === null || node.outcome_reason === null)) {
|
|
85
|
-
throw new Error(`outcome latch is incomplete for node ${row.nodeId}`);
|
|
86
|
-
}
|
|
87
|
-
const documentJson = !settled
|
|
88
|
-
? null
|
|
89
|
-
: composeOutcomeDeliveryDocument({
|
|
90
|
-
nodeId: row.nodeId,
|
|
91
|
-
outcome: {
|
|
92
|
-
kind: node.outcome_kind,
|
|
93
|
-
reason: node.outcome_reason,
|
|
94
|
-
at: node.outcome_at,
|
|
95
|
-
revision: node.outcome_revision,
|
|
96
|
-
detailJson: node.outcome_detail_json,
|
|
97
|
-
},
|
|
98
|
-
action: { name: row.actionName, payload: row.payload ?? null },
|
|
99
|
-
finalReport: node.final_report,
|
|
100
|
-
});
|
|
101
|
-
const state = settled ? 'pending' : 'armed';
|
|
102
|
-
const inserted = db.prepare(`INSERT INTO node_outcome_deliveries
|
|
103
|
-
(node_id, state, action_name, argv_json, cwd, config_origin, payload_json, document_json, next_attempt_at, created_at, updated_at)
|
|
104
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
105
|
-
ON CONFLICT(node_id) DO UPDATE SET
|
|
106
|
-
state = excluded.state, action_name = excluded.action_name, argv_json = excluded.argv_json,
|
|
107
|
-
cwd = excluded.cwd, config_origin = excluded.config_origin, payload_json = excluded.payload_json,
|
|
108
|
-
document_json = excluded.document_json, next_attempt_at = excluded.next_attempt_at,
|
|
109
|
-
updated_at = excluded.updated_at
|
|
110
|
-
WHERE node_outcome_deliveries.state = 'armed'`).run(row.nodeId, state, row.actionName, JSON.stringify(row.argv), row.cwd, row.configOrigin, payloadJson, documentJson, settled ? now : 0, now, now);
|
|
111
|
-
if (Number(inserted.changes) === 0)
|
|
112
|
-
return null;
|
|
113
|
-
return outcomeDeliveryFrom(db.prepare('SELECT * FROM node_outcome_deliveries WHERE node_id = ?').get(row.nodeId));
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
export function readOutcomeDelivery(nodeId) {
|
|
117
|
-
const row = openDb().prepare('SELECT * FROM node_outcome_deliveries WHERE node_id = ?').get(nodeId);
|
|
118
|
-
return row === undefined ? null : outcomeDeliveryFrom(row);
|
|
119
|
-
}
|
|
120
|
-
export function dueOutcomeDeliveries(now) {
|
|
121
|
-
return openDb().prepare(`SELECT * FROM node_outcome_deliveries
|
|
122
|
-
WHERE state = 'pending' AND next_attempt_at <= ?
|
|
123
|
-
ORDER BY next_attempt_at, created_at, node_id`).all(now).map(outcomeDeliveryFrom);
|
|
124
|
-
}
|
|
125
|
-
export function claimOutcomeDelivery(nodeId, now, claimOwner) {
|
|
126
|
-
return withCanvasWrite((db) => {
|
|
127
|
-
const claimed = db.prepare(`UPDATE node_outcome_deliveries
|
|
128
|
-
SET state = 'running', attempt = attempt + 1, claimed_at = ?, claim_owner = ?, updated_at = ?
|
|
129
|
-
WHERE node_id = ? AND state = 'pending' AND next_attempt_at <= ?`).run(now, claimOwner, now, nodeId, now);
|
|
130
|
-
if (Number(claimed.changes) === 0)
|
|
131
|
-
return null;
|
|
132
|
-
return outcomeDeliveryFrom(db.prepare('SELECT * FROM node_outcome_deliveries WHERE node_id = ?').get(nodeId));
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
/** Settle only the still-owned running attempt, fencing stale delivery processes. */
|
|
136
|
-
export function settleOutcomeDelivery(nodeId, attempt, claimOwner, settlement, now) {
|
|
137
|
-
const failure = settlement.state === 'accepted' ? null : JSON.stringify(settlement.failure);
|
|
138
|
-
return withCanvasWrite((db) => Number(db.prepare(`UPDATE node_outcome_deliveries
|
|
139
|
-
SET state = ?, next_attempt_at = ?, claimed_at = NULL, claim_owner = NULL,
|
|
140
|
-
accepted_at = ?, permanent_failed_at = ?, last_failure_json = ?, updated_at = ?
|
|
141
|
-
WHERE node_id = ? AND state = 'running' AND attempt = ? AND claim_owner = ?`).run(settlement.state, settlement.state === 'pending' ? settlement.nextAttemptAt : now, settlement.state === 'accepted' ? now : null, settlement.state === 'permanent_failed' ? now : null, failure, now, nodeId, attempt, claimOwner).changes) === 1);
|
|
142
|
-
}
|
|
143
|
-
export function recoverRunningOutcomeDeliveries(now) {
|
|
144
|
-
return withCanvasWrite((db) => Number(db.prepare(`UPDATE node_outcome_deliveries
|
|
145
|
-
SET state = 'pending', next_attempt_at = ?, claimed_at = NULL, claim_owner = NULL, updated_at = ?
|
|
146
|
-
WHERE state = 'running'`).run(now, now).changes));
|
|
147
|
-
}
|
|
148
|
-
/** Disarming is deliberately limited to registrations that have not started delivery. */
|
|
149
|
-
export function disarmOutcomeDelivery(nodeId) {
|
|
150
|
-
return withCanvasWrite((db) => Number(db.prepare("DELETE FROM node_outcome_deliveries WHERE node_id = ? AND state = 'armed'").run(nodeId).changes) === 1);
|
|
151
|
-
}
|
|
152
|
-
/** A canonical final is the one allowed outcome supersede: discard any old claim and retry state. */
|
|
153
|
-
export function resetOutcomeDeliveryForSupersede(nodeId, documentJson, now) {
|
|
154
|
-
return withCanvasWrite((db) => Number(db.prepare(`UPDATE node_outcome_deliveries
|
|
155
|
-
SET state = 'pending', attempt = 0, document_json = ?, next_attempt_at = ?,
|
|
156
|
-
claimed_at = NULL, claim_owner = NULL, accepted_at = NULL, permanent_failed_at = NULL,
|
|
157
|
-
last_failure_json = NULL, updated_at = ?
|
|
158
|
-
WHERE node_id = ?`).run(documentJson, now, now, nodeId).changes) === 1);
|
|
159
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
// Per-node passive-subscription accumulator for the pi-native canvas runtime.
|
|
2
|
-
//
|
|
3
|
-
// A PASSIVE subscription (the `active=false` flavor of a subscribes_to edge)
|
|
4
|
-
// must never WAKE its subscriber. So when `push` fans out, a passive
|
|
5
|
-
// subscriber's pointer is written here — to nodes/<id>/passive.jsonl — instead
|
|
6
|
-
// of inbox.jsonl. The inbox-watcher polls only inbox.jsonl, so nothing here
|
|
7
|
-
// triggers a turn.
|
|
8
|
-
//
|
|
9
|
-
// The accumulator is drained the moment the node is next MESSAGED: the
|
|
10
|
-
// canvas-passive-context extension reads + clears this file on pi's `input`
|
|
11
|
-
// event and injects every entry as timestamped XML pre-text before the message
|
|
12
|
-
// reaches the LLM. Until then entries simply pile up, oldest first.
|
|
13
|
-
//
|
|
14
|
-
// Same entry shape as the inbox (InboxEntry) so the two stores stay symmetric
|
|
15
|
-
// and a passive edge can be flipped active without reshaping data.
|
|
16
|
-
import { appendFileSync, existsSync, mkdirSync } from 'node:fs';
|
|
17
|
-
import { dirname } from 'node:path';
|
|
18
|
-
import { passivePath } from '../canvas/index.js';
|
|
19
|
-
import { emitEvent } from '../events/emit.js';
|
|
20
|
-
import { errorClassFromError } from '../events/errors.js';
|
|
21
|
-
import { finalizeInboxEntry } from './inbox.js';
|
|
22
|
-
/** Atomically append one finalized entry to `nodes/<nodeId>/passive.jsonl`. */
|
|
23
|
-
export function appendPassive(nodeId, entry) {
|
|
24
|
-
const full = finalizeInboxEntry(entry);
|
|
25
|
-
try {
|
|
26
|
-
const line = JSON.stringify(full) + '\n';
|
|
27
|
-
const dir = dirname(passivePath(nodeId));
|
|
28
|
-
if (!existsSync(dir))
|
|
29
|
-
mkdirSync(dir, { recursive: true });
|
|
30
|
-
appendFileSync(passivePath(nodeId), line, { encoding: 'utf8', flag: 'a' });
|
|
31
|
-
return full;
|
|
32
|
-
}
|
|
33
|
-
catch (error) {
|
|
34
|
-
emitPassiveAppendFailure(nodeId, full, error);
|
|
35
|
-
throw error;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
function emitPassiveAppendFailure(nodeId, entry, error) {
|
|
39
|
-
try {
|
|
40
|
-
emitEvent({
|
|
41
|
-
level: 'error',
|
|
42
|
-
event: 'inbox.delivery.failed',
|
|
43
|
-
operation_id: entry.operation_id,
|
|
44
|
-
outcome: 'failed',
|
|
45
|
-
error,
|
|
46
|
-
error_class: errorClassFromError(error),
|
|
47
|
-
fields: { stage: 'append', channel: 'passive', target_node_id: nodeId },
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
catch {
|
|
51
|
-
// Event emission is observational; the original append failure remains authoritative.
|
|
52
|
-
}
|
|
53
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { existsSync, writeFileSync } from 'node:fs';
|
|
2
|
-
import { cancelTicket } from '../tickets.js';
|
|
3
|
-
const [dir, barrier, ready] = process.argv.slice(2);
|
|
4
|
-
writeFileSync(ready, 'ready');
|
|
5
|
-
while (!existsSync(barrier))
|
|
6
|
-
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 1);
|
|
7
|
-
process.stdout.write(JSON.stringify(cancelTicket(dir)));
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { existsSync, writeFileSync } from 'node:fs';
|
|
2
|
-
import { claimTicket } from '../claim.js';
|
|
3
|
-
const [dir, barrier, ready, result, release] = process.argv.slice(2);
|
|
4
|
-
const spin = (path) => { while (!existsSync(path))
|
|
5
|
-
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 1); };
|
|
6
|
-
writeFileSync(ready, 'ready');
|
|
7
|
-
spin(barrier);
|
|
8
|
-
const claim = claimTicket(dir);
|
|
9
|
-
writeFileSync(result, JSON.stringify(claim));
|
|
10
|
-
process.stdout.write(JSON.stringify(claim));
|
|
11
|
-
// Stay alive until the parent has read BOTH results and releases us. A same-host
|
|
12
|
-
// claim is reclaimable the instant its holder's pid dies, so a winner that exited
|
|
13
|
-
// early would legitimately free its claim for the peer — that is designed
|
|
14
|
-
// stale-recovery, not a double-claim. Blocking here keeps both pids live across
|
|
15
|
-
// the peer's attempt, so the assertion tests exclusion, not exit timing.
|
|
16
|
-
if (release !== undefined)
|
|
17
|
-
spin(release);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { writeFileSync } from 'node:fs';
|
|
2
|
-
import { claimTicket } from '../claim.js';
|
|
3
|
-
// Writes a genuine claim from a SEPARATE process, as a remote host whose
|
|
4
|
-
// heartbeat is already older than the remote-stale window, then exits. The
|
|
5
|
-
// parent process then recovers the ticket, proving cross-process stale recovery.
|
|
6
|
-
const [dir, ready] = process.argv.slice(2);
|
|
7
|
-
const claim = claimTicket(dir, { host: 'other-host', pid: 1, now: new Date(Date.now() - 31_000) });
|
|
8
|
-
writeFileSync(ready, JSON.stringify(claim));
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|