@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,7 +1,3 @@
|
|
|
1
1
|
import type { ReviewRecord } from '../../core/review/types.js';
|
|
2
|
-
/** Render the immutable approval fact
|
|
2
|
+
/** Render the immutable approval fact for the direct outbox notification. */
|
|
3
3
|
export declare function renderApprovalMessage(review: ReviewRecord, resultPath: string): string;
|
|
4
|
-
/** Deliver an approval through its origin-specific canonical route. */
|
|
5
|
-
export declare function deliverApproval(review: ReviewRecord, resultPath: string): Promise<{
|
|
6
|
-
receipt: string | null;
|
|
7
|
-
}>;
|
|
@@ -1,57 +1,8 @@
|
|
|
1
|
-
import { FinalizationError, pushFinal, redeliverFinalReport } from '../../core/feed/feed.js';
|
|
2
1
|
import { formatCard } from '../../shared/generated-context.js';
|
|
3
|
-
|
|
4
|
-
function
|
|
2
|
+
/** Render the immutable approval fact for the direct outbox notification. */
|
|
3
|
+
export function renderApprovalMessage(review, resultPath) {
|
|
5
4
|
const summary = review.changed
|
|
6
5
|
? `The user reviewed and approved \`${review.file}\`. The document changed during review; re-read it before continuing. Review conversation: node \`${review.companion_node_id}\`.`
|
|
7
6
|
: `The user reviewed and approved \`${review.file}\`. The document was not modified.`;
|
|
8
|
-
return `${summary}\n\nDurable review result: ${resultPath}
|
|
9
|
-
}
|
|
10
|
-
/** Render the immutable approval fact without replaying comment text. */
|
|
11
|
-
export function renderApprovalMessage(review, resultPath) {
|
|
12
|
-
return formatCard('review-approval', {}, approvalBody(review, resultPath));
|
|
13
|
-
}
|
|
14
|
-
function recordedFailedFanout(review, reportBasename) {
|
|
15
|
-
const error = review.delivery_error;
|
|
16
|
-
if (error === null || !error.includes(reportBasename))
|
|
17
|
-
return false;
|
|
18
|
-
const failed = /delivery failed for (.+)$/.exec(error)?.[1]?.split(', ') ?? [];
|
|
19
|
-
return failed.includes(review.origin_node_id);
|
|
20
|
-
}
|
|
21
|
-
/** Deliver an approval through its origin-specific canonical route. */
|
|
22
|
-
export async function deliverApproval(review, resultPath) {
|
|
23
|
-
const body = renderApprovalMessage(review, resultPath);
|
|
24
|
-
if (review.origin_kind === 'inline') {
|
|
25
|
-
const delivery = await deliverNodeMessage({
|
|
26
|
-
node_id: review.origin_node_id,
|
|
27
|
-
body,
|
|
28
|
-
label: 'review approved by the user',
|
|
29
|
-
from: 'crtrd',
|
|
30
|
-
mode: 'interactive',
|
|
31
|
-
data: { review_id: review.review_id, result_path: resultPath },
|
|
32
|
-
});
|
|
33
|
-
return { receipt: delivery.entry_id };
|
|
34
|
-
}
|
|
35
|
-
if (review.bridge_node_id === null) {
|
|
36
|
-
throw new Error(`ticket review ${review.review_id} has no bridge node`);
|
|
37
|
-
}
|
|
38
|
-
try {
|
|
39
|
-
const result = await pushFinal(review.bridge_node_id, body);
|
|
40
|
-
return { receipt: result.reportPath.split('/').at(-1) ?? null };
|
|
41
|
-
}
|
|
42
|
-
catch (error) {
|
|
43
|
-
if (!(error instanceof FinalizationError) || error.code !== 'already_finalized')
|
|
44
|
-
throw error;
|
|
45
|
-
const reportBasename = error.reportPath;
|
|
46
|
-
if (reportBasename === undefined)
|
|
47
|
-
throw error;
|
|
48
|
-
// A committed final with no failed-delivery ledger is the crash window
|
|
49
|
-
// after a successful fanout and before the review ledger was marked.
|
|
50
|
-
if (review.delivery_error === null)
|
|
51
|
-
return { receipt: reportBasename };
|
|
52
|
-
if (!recordedFailedFanout(review, reportBasename))
|
|
53
|
-
throw error;
|
|
54
|
-
const result = redeliverFinalReport(review.bridge_node_id, review.origin_node_id, reportBasename, body);
|
|
55
|
-
return { receipt: result.reportPath.split('/').at(-1) ?? null };
|
|
56
|
-
}
|
|
7
|
+
return formatCard('review-approval', {}, `${summary}\n\nDurable review result: ${resultPath}`);
|
|
57
8
|
}
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import type { TicketResult } from '../../core/human/types.js';
|
|
2
1
|
import { type ReviewRecord, type ReviewResult } from '../../core/review/types.js';
|
|
3
2
|
export interface ReviewApprovalFinishOutcome {
|
|
4
3
|
outcome: 'settled' | 'already_settled';
|
|
5
4
|
record: ReviewRecord;
|
|
6
5
|
result: ReviewResult;
|
|
7
6
|
}
|
|
8
|
-
/** The human submitted while the companion was still working. The review stays
|
|
9
|
-
* open and the daemon completes the approval once the companion goes quiet. */
|
|
10
7
|
export interface ReviewSubmitDeferredOutcome {
|
|
11
8
|
outcome: 'awaiting_companion';
|
|
12
9
|
record: ReviewRecord;
|
|
@@ -15,38 +12,16 @@ export type ReviewSubmitOutcome = ReviewApprovalFinishOutcome | ReviewSubmitDefe
|
|
|
15
12
|
export interface ReviewCancellationFinishOutcome {
|
|
16
13
|
outcome: 'settled' | 'already_settled';
|
|
17
14
|
record: ReviewRecord;
|
|
18
|
-
ticket_result?: TicketResult;
|
|
19
15
|
}
|
|
20
16
|
export type ReviewFinishOutcome = ReviewApprovalFinishOutcome | ReviewCancellationFinishOutcome;
|
|
21
|
-
/** Approve on the human's behalf, waiting first when the companion is still
|
|
22
|
-
* working. Waiting is the only new outcome: an idle companion approves in the
|
|
23
|
-
* same pass it always did, and the wait never freezes the review — comments
|
|
24
|
-
* added during it are in the snapshot, because the snapshot happens at
|
|
25
|
-
* completion and the review is still open. */
|
|
26
17
|
export declare function submitReviewApproval(reviewId: string): Promise<ReviewSubmitOutcome>;
|
|
27
|
-
/** Complete a submit the human already pressed, once its companion is quiet.
|
|
28
|
-
* Returns null when there is nothing to complete — no pending intent, the
|
|
29
|
-
* review moved on, or the companion is still working. Idempotent: concurrent
|
|
30
|
-
* callers race on the same conditional `state = 'open'` approval write, so
|
|
31
|
-
* only one can win and the loser reports what the winner committed.
|
|
32
|
-
*
|
|
33
|
-
* `atCompanionTurnEnd` marks the one caller that IS the companion's turn end.
|
|
34
|
-
* There the mid-turn marker may not be cleared yet, so it is not consulted;
|
|
35
|
-
* queued work still defers, because an inbox entry means another turn is
|
|
36
|
-
* coming and the wait should outlast it. */
|
|
37
18
|
export declare function completeRequestedSubmit(reviewId: string, opts: {
|
|
38
19
|
atCompanionTurnEnd: boolean;
|
|
39
20
|
}): Promise<ReviewApprovalFinishOutcome | null>;
|
|
40
|
-
|
|
41
|
-
* it. Never throws — a settlement directive must not depend on delivery. */
|
|
42
|
-
export declare function completeCompanionRequestedSubmit(companionNodeId: string): Promise<void>;
|
|
43
|
-
/** `disposition` rides through to the ticket result: the recipient closing a
|
|
44
|
-
* review in their inbox is a dismissal, while the requester withdrawing it
|
|
45
|
-
* stays a cancellation. */
|
|
21
|
+
export declare function completeCompanionRequestedSubmit(companionNodeId: string): Promise<ReviewApprovalFinishOutcome | null>;
|
|
46
22
|
export interface ReviewCancellationArgs {
|
|
47
23
|
reason?: string;
|
|
48
24
|
actor?: string;
|
|
49
25
|
disposition?: 'canceled' | 'dismissed';
|
|
50
26
|
}
|
|
51
|
-
|
|
52
|
-
export declare function cancelReview(reviewId: string, args: ReviewCancellationArgs): Promise<ReviewCancellationFinishOutcome>;
|
|
27
|
+
export declare function cancelReview(reviewId: string, args?: ReviewCancellationArgs): Promise<ReviewCancellationFinishOutcome>;
|
|
@@ -1,265 +1,86 @@
|
|
|
1
1
|
import { withCanvasWrite } from '../../core/canvas/db.js';
|
|
2
|
-
import { responsePath } from '../../core/human/convention.js';
|
|
3
|
-
import { ticketDir } from '../../core/human/root.js';
|
|
4
|
-
import { readTicketResult } from '../../core/human/tickets.js';
|
|
5
|
-
import { projectReviewResult, buildReviewResult } from '../../core/review/project.js';
|
|
6
|
-
import { reviewResultPath } from '../../core/canvas/paths.js';
|
|
7
2
|
import { snapshotCommentsLocked } from '../../core/review/comments.js';
|
|
8
3
|
import { readReviewSource } from '../../core/review/document.js';
|
|
4
|
+
import { projectReviewCancellation, projectReviewResult, buildReviewResult } from '../../core/review/project.js';
|
|
9
5
|
import { signalReviewActivity } from '../../core/review/signal.js';
|
|
10
|
-
import {
|
|
6
|
+
import { getReview, getReviewByCompanion, requestReviewSubmit, requireVisibleReview } from '../../core/review/store.js';
|
|
11
7
|
import { ReviewOperationError } from '../../core/review/types.js';
|
|
12
|
-
import {
|
|
13
|
-
import { emitEvent } from '../../core/events/emit.js';
|
|
8
|
+
import { settleHumanRequest } from '../human/settle.js';
|
|
14
9
|
import { retireCompanion } from '../companion-retire.js';
|
|
15
|
-
import { deliverNodeMessage } from '../messaging/node-message.js';
|
|
16
|
-
import { cancelHumanTicket, deliverTerminalResult } from '../human/finish.js';
|
|
17
10
|
import { companionHasQueuedWork, companionMidTurn, companionStillWorking } from './companion.js';
|
|
18
|
-
import {
|
|
19
|
-
|
|
20
|
-
const finishChains = new Map();
|
|
21
|
-
function now() {
|
|
22
|
-
return new Date().toISOString();
|
|
23
|
-
}
|
|
24
|
-
function errorText(error) {
|
|
25
|
-
return error instanceof Error ? error.message : String(error);
|
|
26
|
-
}
|
|
11
|
+
import { renderApprovalMessage } from './deliver.js';
|
|
12
|
+
function now() { return new Date().toISOString(); }
|
|
27
13
|
function terminalConflict(review, requested) {
|
|
28
|
-
throw new ReviewOperationError('review_terminal', 'review already has a terminal outcome', {
|
|
29
|
-
state: review.state,
|
|
30
|
-
requested,
|
|
31
|
-
review,
|
|
32
|
-
});
|
|
14
|
+
throw new ReviewOperationError('review_terminal', 'review already has a terminal outcome', { state: review.state, requested, review });
|
|
33
15
|
}
|
|
34
16
|
function approvedResult(review) {
|
|
35
17
|
if (review.result_json === null)
|
|
36
18
|
throw new Error(`approved review lacks its immutable result: ${review.review_id}`);
|
|
37
19
|
return JSON.parse(review.result_json);
|
|
38
20
|
}
|
|
39
|
-
function resultPath(review) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
function ticketResult(review) {
|
|
47
|
-
return review.origin_kind === 'ticket' && review.bridge_node_id !== null
|
|
48
|
-
? readTicketResult(ticketDir(review.bridge_node_id)) ?? undefined
|
|
49
|
-
: undefined;
|
|
50
|
-
}
|
|
51
|
-
function isPostReplayAlreadyResolved(error) {
|
|
52
|
-
return error instanceof Error
|
|
53
|
-
&& 'status' in error
|
|
54
|
-
&& error.status === 409
|
|
55
|
-
&& 'code' in error
|
|
56
|
-
&& error.code === 'ticket_already_resolved';
|
|
57
|
-
}
|
|
58
|
-
async function serializedFinish(reviewId, work) {
|
|
59
|
-
const prior = finishChains.get(reviewId) ?? Promise.resolve();
|
|
60
|
-
const run = prior.catch(() => { }).then(work);
|
|
61
|
-
const tail = run.then(() => { }, () => { });
|
|
62
|
-
finishChains.set(reviewId, tail);
|
|
63
|
-
try {
|
|
64
|
-
return await run;
|
|
65
|
-
}
|
|
66
|
-
finally {
|
|
67
|
-
if (finishChains.get(reviewId) === tail)
|
|
68
|
-
finishChains.delete(reviewId);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
async function finishApproved(review, result) {
|
|
72
|
-
retractSubmitQueuedNote(review);
|
|
73
|
-
let current = requireVisibleReview(review.review_id);
|
|
74
|
-
if (current.projected_at === null) {
|
|
75
|
-
try {
|
|
76
|
-
projectReviewResult(current, result);
|
|
77
|
-
markProjected(current.review_id, now());
|
|
78
|
-
}
|
|
79
|
-
catch (error) {
|
|
80
|
-
markProjectionError(current.review_id, errorText(error));
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
current = requireVisibleReview(review.review_id);
|
|
84
|
-
if (current.delivered_at === null) {
|
|
85
|
-
try {
|
|
86
|
-
const delivery = await deliverApproval(current, resultPath(current));
|
|
87
|
-
markDelivered(current.review_id, delivery.receipt, now());
|
|
88
|
-
}
|
|
89
|
-
catch (error) {
|
|
90
|
-
markDeliveryError(current.review_id, errorText(error));
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
current = requireVisibleReview(review.review_id);
|
|
94
|
-
await retireCompanion(current.companion_node_id, 'approved');
|
|
95
|
-
return requireVisibleReview(review.review_id);
|
|
96
|
-
}
|
|
97
|
-
async function finishCanceled(review, winningWrite, args) {
|
|
98
|
-
retractSubmitQueuedNote(review);
|
|
99
|
-
let current = requireVisibleReview(review.review_id);
|
|
100
|
-
let canceledTicket;
|
|
101
|
-
if (current.origin_kind === 'inline') {
|
|
102
|
-
if (current.projected_at === null)
|
|
103
|
-
markProjected(current.review_id, now());
|
|
104
|
-
current = requireVisibleReview(review.review_id);
|
|
105
|
-
if (current.delivered_at === null)
|
|
106
|
-
markDelivered(current.review_id, null, now());
|
|
107
|
-
}
|
|
108
|
-
else if (current.bridge_node_id === null) {
|
|
109
|
-
markProjectionError(current.review_id, `ticket review lacks its bridge node: ${current.review_id}`);
|
|
110
|
-
markDeliveryError(current.review_id, `ticket review lacks its bridge node: ${current.review_id}`);
|
|
111
|
-
}
|
|
112
|
-
else if (current.delivered_at === null) {
|
|
113
|
-
try {
|
|
114
|
-
if (winningWrite) {
|
|
115
|
-
canceledTicket = await cancelHumanTicket(current.bridge_node_id, args);
|
|
116
|
-
}
|
|
117
|
-
else {
|
|
118
|
-
const delivered = await deliverTerminalResult(current.bridge_node_id);
|
|
119
|
-
if (!delivered)
|
|
120
|
-
throw new Error(`ticket cancellation is not available for delivery: ${current.bridge_node_id}`);
|
|
121
|
-
canceledTicket = ticketResult(current);
|
|
122
|
-
}
|
|
123
|
-
if (canceledTicket === undefined)
|
|
124
|
-
throw new Error(`ticket cancellation result is missing: ${current.bridge_node_id}`);
|
|
125
|
-
markProjected(current.review_id, now());
|
|
126
|
-
markDelivered(current.review_id, null, now());
|
|
127
|
-
}
|
|
128
|
-
catch (error) {
|
|
129
|
-
if (winningWrite && isPostReplayAlreadyResolved(error)) {
|
|
130
|
-
try {
|
|
131
|
-
const delivered = await deliverTerminalResult(current.bridge_node_id);
|
|
132
|
-
if (!delivered)
|
|
133
|
-
throw new Error(`ticket cancellation is not available for delivery: ${current.bridge_node_id}`);
|
|
134
|
-
canceledTicket = ticketResult(current);
|
|
135
|
-
if (canceledTicket === undefined)
|
|
136
|
-
throw new Error(`ticket cancellation result is missing: ${current.bridge_node_id}`);
|
|
137
|
-
markProjected(current.review_id, now());
|
|
138
|
-
markDelivered(current.review_id, null, now());
|
|
139
|
-
}
|
|
140
|
-
catch (replayError) {
|
|
141
|
-
markDeliveryError(current.review_id, errorText(replayError));
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
else {
|
|
145
|
-
// cancelHumanTicket publishes response.json before fanout. Preserve that
|
|
146
|
-
// publication ledger even when the retained delivery path reports a failure.
|
|
147
|
-
if (ticketResult(current) !== undefined)
|
|
148
|
-
markProjected(current.review_id, now());
|
|
149
|
-
markDeliveryError(current.review_id, errorText(error));
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
current = requireVisibleReview(review.review_id);
|
|
154
|
-
if (canceledTicket === undefined)
|
|
155
|
-
canceledTicket = ticketResult(current);
|
|
156
|
-
await retireCompanion(current.companion_node_id, 'canceled');
|
|
157
|
-
return { record: requireVisibleReview(review.review_id), ...(canceledTicket === undefined ? {} : { ticket_result: canceledTicket }) };
|
|
158
|
-
}
|
|
159
|
-
const SUBMIT_QUEUED_NOTE = 'review-submit-queued';
|
|
160
|
-
/** Retract an undelivered queued-submit note once the review is settling. The
|
|
161
|
-
* note rides the deferred tier and so does not wake the origin, while the
|
|
162
|
-
* terminal result goes live — without this the origin reads "result to
|
|
163
|
-
* follow" only after it already acted on that result. */
|
|
164
|
-
function retractSubmitQueuedNote(review) {
|
|
165
|
-
try {
|
|
166
|
-
cancelPendingEntries(review.origin_node_id, (entry) => entry.kind === 'message'
|
|
167
|
-
&& entry.data?.['note'] === SUBMIT_QUEUED_NOTE
|
|
168
|
-
&& entry.data?.['review_id'] === review.review_id);
|
|
169
|
-
}
|
|
170
|
-
catch (error) {
|
|
171
|
-
emitEvent({ level: 'warn', event: 'review.submit_queued_note.retract_failed', error });
|
|
172
|
-
}
|
|
21
|
+
function resultPath(review) { return `${review.review_dir}/result.json`; }
|
|
22
|
+
function effects(result) {
|
|
23
|
+
return {
|
|
24
|
+
project: (request) => { projectReviewResult(requireVisibleReview(request.request_id), result); },
|
|
25
|
+
retire: async (nodeId, outcome) => { await retireCompanion(nodeId, outcome); },
|
|
26
|
+
};
|
|
173
27
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
node_id: review.origin_node_id,
|
|
181
|
-
from: 'crtrd',
|
|
182
|
-
mode: 'quiet',
|
|
183
|
-
label: 'human review submitted — result to follow',
|
|
184
|
-
data: { review_id: review.review_id, note: SUBMIT_QUEUED_NOTE },
|
|
185
|
-
runtime: { kind: 'review-queued', facts: {} },
|
|
186
|
-
body: `The human submitted their review of \`${review.file}\`; the document is still being edited. `
|
|
187
|
-
+ "You'll be notified with the result once the review completes. Nothing is needed from you now.",
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
catch (error) {
|
|
191
|
-
emitEvent({ level: 'warn', event: 'review.submit_queued_note.failed', error });
|
|
192
|
-
}
|
|
28
|
+
function approvalNotification(review) {
|
|
29
|
+
return {
|
|
30
|
+
label: 'review approved by the user',
|
|
31
|
+
disposition: 'human-answer',
|
|
32
|
+
body_json: { review_id: review.review_id, result_path: resultPath(review), body: renderApprovalMessage(review, resultPath(review)) },
|
|
33
|
+
};
|
|
193
34
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
if (initial.state === 'canceled')
|
|
202
|
-
return terminalConflict(initial, 'submit');
|
|
203
|
-
if (initial.state === 'open' && companionStillWorking(initial.companion_node_id)) {
|
|
204
|
-
if (requestReviewSubmit(reviewId, now())) {
|
|
205
|
-
signalReviewActivity();
|
|
206
|
-
await noteSubmitQueued(initial);
|
|
207
|
-
}
|
|
208
|
-
return { outcome: 'awaiting_companion', record: requireVisibleReview(reviewId) };
|
|
209
|
-
}
|
|
210
|
-
return await approveReview(initial);
|
|
35
|
+
function cancellationNotification(review, reason, disposition) {
|
|
36
|
+
const dismissed = disposition === 'dismissed';
|
|
37
|
+
return {
|
|
38
|
+
label: dismissed ? 'review dismissed' : 'review canceled',
|
|
39
|
+
disposition: 'human-canceled',
|
|
40
|
+
body_json: { review_id: review.review_id, disposition, body: dismissed ? `The review of \`${review.file}\` was dismissed without approval.` : `The review of \`${review.file}\` was canceled${reason === '' ? '' : ` — ${reason}`}.` },
|
|
41
|
+
};
|
|
211
42
|
}
|
|
212
|
-
/** Commit approval once, then independently finish its projection, delivery, and companion retirement ledgers. */
|
|
213
43
|
async function approveReview(initial) {
|
|
214
|
-
const reviewId = initial.review_id;
|
|
215
44
|
if (initial.state === 'canceled')
|
|
216
45
|
return terminalConflict(initial, 'submit');
|
|
217
|
-
if (initial.state === 'approved')
|
|
218
|
-
|
|
219
|
-
const record = await serializedFinish(reviewId, () => finishApproved(initial, result));
|
|
220
|
-
return { outcome: 'already_settled', record, result };
|
|
221
|
-
}
|
|
46
|
+
if (initial.state === 'approved')
|
|
47
|
+
return { outcome: 'already_settled', record: initial, result: approvedResult(initial) };
|
|
222
48
|
const source = readReviewSource(initial.file, 'submit');
|
|
223
|
-
const
|
|
224
|
-
const review = requireVisibleReview(
|
|
49
|
+
const { result, resultJson } = withCanvasWrite((db) => {
|
|
50
|
+
const review = requireVisibleReview(initial.review_id);
|
|
225
51
|
if (review.state === 'canceled')
|
|
226
52
|
return terminalConflict(review, 'submit');
|
|
227
53
|
if (review.state === 'approved')
|
|
228
|
-
return {
|
|
229
|
-
const snapshot = snapshotCommentsLocked(db,
|
|
230
|
-
const
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
result_json: JSON.stringify(result),
|
|
240
|
-
})) {
|
|
241
|
-
const winner = requireVisibleReview(reviewId);
|
|
242
|
-
if (winner.state === 'approved')
|
|
243
|
-
return { outcome: 'already_settled', review: winner, result: approvedResult(winner) };
|
|
244
|
-
return terminalConflict(winner, 'submit');
|
|
245
|
-
}
|
|
246
|
-
return { outcome: 'settled', review: requireVisibleReview(reviewId), result };
|
|
54
|
+
return { result: approvedResult(review), resultJson: review.result_json };
|
|
55
|
+
const snapshot = snapshotCommentsLocked(db, review.review_id);
|
|
56
|
+
const result = buildReviewResult(review, snapshot, source.sha256, now());
|
|
57
|
+
return { result, resultJson: JSON.stringify(result) };
|
|
58
|
+
});
|
|
59
|
+
const settled = await settleHumanRequest({
|
|
60
|
+
request_id: initial.review_id,
|
|
61
|
+
outcome: 'approved',
|
|
62
|
+
result_json: resultJson,
|
|
63
|
+
notification: approvalNotification({ ...initial, changed: result.changed }),
|
|
64
|
+
post_commit: effects(result),
|
|
247
65
|
});
|
|
248
|
-
if (
|
|
66
|
+
if (settled.outcome === 'settled')
|
|
249
67
|
signalReviewActivity();
|
|
250
|
-
const record =
|
|
251
|
-
|
|
68
|
+
const record = requireVisibleReview(initial.review_id);
|
|
69
|
+
if (settled.outcome === 'already_settled' && record.state !== 'approved')
|
|
70
|
+
return terminalConflict(record, 'submit');
|
|
71
|
+
return { outcome: settled.outcome, record, result: settled.outcome === 'settled' ? result : approvedResult(record) };
|
|
72
|
+
}
|
|
73
|
+
export async function submitReviewApproval(reviewId) {
|
|
74
|
+
const review = requireVisibleReview(reviewId);
|
|
75
|
+
if (review.state === 'canceled')
|
|
76
|
+
return terminalConflict(review, 'submit');
|
|
77
|
+
if (review.state === 'open' && companionStillWorking(review.companion_node_id)) {
|
|
78
|
+
if (requestReviewSubmit(reviewId, now()))
|
|
79
|
+
signalReviewActivity();
|
|
80
|
+
return { outcome: 'awaiting_companion', record: requireVisibleReview(reviewId) };
|
|
81
|
+
}
|
|
82
|
+
return approveReview(review);
|
|
252
83
|
}
|
|
253
|
-
/** Complete a submit the human already pressed, once its companion is quiet.
|
|
254
|
-
* Returns null when there is nothing to complete — no pending intent, the
|
|
255
|
-
* review moved on, or the companion is still working. Idempotent: concurrent
|
|
256
|
-
* callers race on the same conditional `state = 'open'` approval write, so
|
|
257
|
-
* only one can win and the loser reports what the winner committed.
|
|
258
|
-
*
|
|
259
|
-
* `atCompanionTurnEnd` marks the one caller that IS the companion's turn end.
|
|
260
|
-
* There the mid-turn marker may not be cleared yet, so it is not consulted;
|
|
261
|
-
* queued work still defers, because an inbox entry means another turn is
|
|
262
|
-
* coming and the wait should outlast it. */
|
|
263
84
|
export async function completeRequestedSubmit(reviewId, opts) {
|
|
264
85
|
const review = getReview(reviewId);
|
|
265
86
|
if (review === null || review.state !== 'open' || review.submit_requested_at === null)
|
|
@@ -268,39 +89,34 @@ export async function completeRequestedSubmit(reviewId, opts) {
|
|
|
268
89
|
return null;
|
|
269
90
|
if (!opts.atCompanionTurnEnd && companionMidTurn(review.companion_node_id))
|
|
270
91
|
return null;
|
|
271
|
-
return
|
|
92
|
+
return approveReview(review);
|
|
272
93
|
}
|
|
273
|
-
/** The companion's turn ended: complete any submit the human left waiting on
|
|
274
|
-
* it. Never throws — a settlement directive must not depend on delivery. */
|
|
275
94
|
export async function completeCompanionRequestedSubmit(companionNodeId) {
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
if (review === null || review.state !== 'open' || review.submit_requested_at === null)
|
|
279
|
-
return;
|
|
280
|
-
await completeRequestedSubmit(review.review_id, { atCompanionTurnEnd: true });
|
|
281
|
-
}
|
|
282
|
-
catch (error) {
|
|
283
|
-
emitEvent({ level: 'error', event: 'review.deferred_submit.failed', error });
|
|
284
|
-
}
|
|
95
|
+
const review = getReviewByCompanion(companionNodeId);
|
|
96
|
+
return review === null ? null : completeRequestedSubmit(review.review_id, { atCompanionTurnEnd: true });
|
|
285
97
|
}
|
|
286
|
-
|
|
287
|
-
export async function cancelReview(reviewId, args) {
|
|
288
|
-
const initial = requireVisibleReview(reviewId);
|
|
289
|
-
if (initial.state === 'approved')
|
|
290
|
-
return terminalConflict(initial, 'cancel');
|
|
291
|
-
const winningWrite = initial.state === 'open'
|
|
292
|
-
&& cancelReviewRow(reviewId, { at: now(), reason: args.reason ?? '', actor: args.actor ?? null });
|
|
98
|
+
export async function cancelReview(reviewId, args = {}) {
|
|
293
99
|
const review = requireVisibleReview(reviewId);
|
|
294
100
|
if (review.state === 'approved')
|
|
295
101
|
return terminalConflict(review, 'cancel');
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
102
|
+
const at = now();
|
|
103
|
+
const reason = args.reason ?? '';
|
|
104
|
+
const disposition = args.disposition ?? 'canceled';
|
|
105
|
+
const resultJson = JSON.stringify({ schema: 'humanloop.cancel/v1', kind: 'canceled', canceledAt: at, ...(reason === '' ? {} : { reason }), ...(args.actor === undefined ? {} : { actor: args.actor }), ...(disposition === 'dismissed' ? { disposition } : {}) });
|
|
106
|
+
const settled = await settleHumanRequest({
|
|
107
|
+
request_id: reviewId,
|
|
108
|
+
outcome: disposition === 'dismissed' ? 'dismissed' : 'canceled',
|
|
109
|
+
result_json: resultJson,
|
|
110
|
+
notification: cancellationNotification(review, reason, disposition),
|
|
111
|
+
post_commit: {
|
|
112
|
+
project: (request) => { projectReviewCancellation(requireVisibleReview(request.request_id), JSON.parse(resultJson)); },
|
|
113
|
+
retire: async (nodeId, outcome) => { await retireCompanion(nodeId, outcome); },
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
if (settled.outcome === 'settled')
|
|
299
117
|
signalReviewActivity();
|
|
300
|
-
const
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
...(finished.ticket_result === undefined ? {} : { ticket_result: finished.ticket_result }),
|
|
305
|
-
};
|
|
118
|
+
const record = requireVisibleReview(reviewId);
|
|
119
|
+
if (settled.outcome === 'already_settled' && record.state === 'approved')
|
|
120
|
+
return terminalConflict(record, 'cancel');
|
|
121
|
+
return { outcome: settled.outcome, record };
|
|
306
122
|
}
|
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
reprojected: number;
|
|
5
|
-
failed: number;
|
|
6
|
-
}
|
|
7
|
-
/**
|
|
8
|
-
* Recover only pre-exposure review work at daemon startup. Terminal delivery and
|
|
9
|
-
* retirement are intentionally outside this pass and require an explicit repeat.
|
|
10
|
-
*/
|
|
1
|
+
import { type HumanRequestSweepResult } from '../human/sweep.js';
|
|
2
|
+
export type ReviewSweepResult = HumanRequestSweepResult;
|
|
3
|
+
/** Compatibility entry point for daemon boot. All recovery is driven by human_requests. */
|
|
11
4
|
export declare function sweepReviews(): Promise<ReviewSweepResult>;
|