cloving 1.3.0 → 1.5.0
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/README.md +329 -215
- package/dist/src/agent-harness-shell.d.ts +2 -1
- package/dist/src/agent-harness-shell.js +8 -5
- package/dist/src/authority/command-wait-checks.d.ts +8 -0
- package/dist/src/authority/command-wait-checks.js +88 -0
- package/dist/src/authority/command-wait-results.d.ts +15 -0
- package/dist/src/authority/command-wait-results.js +73 -0
- package/dist/src/authority/command-wait-view.d.ts +21 -0
- package/dist/src/authority/command-wait-view.js +34 -0
- package/dist/src/authority/command-waits.d.ts +39 -0
- package/dist/src/authority/command-waits.js +97 -0
- package/dist/src/authority/commands.js +22 -1
- package/dist/src/authority/dispatch-decision.d.ts +8 -0
- package/dist/src/authority/dispatch-decision.js +26 -1
- package/dist/src/authority/effect-requests.js +6 -3
- package/dist/src/authority/effect-results.js +4 -2
- package/dist/src/authority/history-state.d.ts +2 -0
- package/dist/src/authority/history-state.js +13 -1
- package/dist/src/authority/instants.d.ts +1 -0
- package/dist/src/authority/instants.js +21 -0
- package/dist/src/authority/reduction-state.d.ts +2 -0
- package/dist/src/authority/reduction-state.js +5 -0
- package/dist/src/authority/reduction.js +24 -0
- package/dist/src/authority/status-input.d.ts +2 -0
- package/dist/src/authority/status.d.ts +2 -0
- package/dist/src/authority/status.js +1 -0
- package/dist/src/authority/stop-sequence.d.ts +1 -0
- package/dist/src/authority/stop-sequence.js +2 -1
- package/dist/src/authority/transitions.d.ts +6 -4
- package/dist/src/authority/transitions.js +7 -0
- package/dist/src/broker/actor/authority-health.d.ts +9 -0
- package/dist/src/broker/actor/authority-health.js +24 -0
- package/dist/src/broker/actor/authority-queries.d.ts +2 -1
- package/dist/src/broker/actor/authority-queries.js +14 -5
- package/dist/src/broker/actor/authority-receipts.js +1 -1
- package/dist/src/broker/actor/authority-runtime.d.ts +4 -2
- package/dist/src/broker/actor/authority-runtime.js +29 -20
- package/dist/src/broker/actor/authority-session.d.ts +6 -19
- package/dist/src/broker/actor/authority-session.js +66 -88
- package/dist/src/broker/actor/authority-settings.d.ts +2 -1
- package/dist/src/broker/actor/authority-settings.js +6 -3
- package/dist/src/broker/actor/authority-upgrades.d.ts +23 -2
- package/dist/src/broker/actor/authority-upgrades.js +8 -2
- package/dist/src/broker/actor/authority-watchdog.d.ts +6 -2
- package/dist/src/broker/actor/authority-watchdog.js +31 -9
- package/dist/src/broker/actor/authority.js +3 -1
- package/dist/src/broker/actor/delivery-intents.js +2 -0
- package/dist/src/broker/actor/effect-delivery.d.ts +1 -1
- package/dist/src/broker/actor/effect-delivery.js +15 -2
- package/dist/src/broker/actor/effect-plan.js +11 -2
- package/dist/src/broker/actor/effect-queries.d.ts +4 -0
- package/dist/src/broker/actor/effect-queries.js +9 -1
- package/dist/src/broker/actor/effect-turn.js +2 -0
- package/dist/src/broker/actor/projection-memory.d.ts +43 -0
- package/dist/src/broker/actor/projection-memory.js +207 -0
- package/dist/src/broker/actor/runtime-parts.d.ts +5 -0
- package/dist/src/broker/actor/runtime-parts.js +8 -3
- package/dist/src/broker/actor/stop-plan.js +9 -3
- package/dist/src/broker/actor/stop-turn.d.ts +2 -0
- package/dist/src/broker/actor/stop-turn.js +24 -11
- package/dist/src/broker/actor/turn-draft.d.ts +1 -0
- package/dist/src/broker/actor/turn-draft.js +4 -0
- package/dist/src/broker/actor/turn-state.js +5 -1
- package/dist/src/broker/authority-admission.js +60 -0
- package/dist/src/broker/authority-restore.d.ts +2 -0
- package/dist/src/broker/authority-restore.js +35 -1
- package/dist/src/broker/command-wait-restore.d.ts +31 -0
- package/dist/src/broker/command-wait-restore.js +86 -0
- package/dist/src/broker/decision-restore.d.ts +1 -1
- package/dist/src/broker/decision-restore.js +1 -0
- package/dist/src/broker/effect-upgrade.d.ts +3 -0
- package/dist/src/broker/effect-upgrade.js +11 -2
- package/dist/src/cli/arguments.d.ts +13 -0
- package/dist/src/cli/arguments.js +43 -3
- package/dist/src/cli/chat-stores.d.ts +2 -0
- package/dist/src/cli/chat-stores.js +113 -0
- package/dist/src/cli/client.d.ts +7 -2
- package/dist/src/cli/client.js +13 -7
- package/dist/src/cli/command-requests.d.ts +46 -0
- package/dist/src/cli/command-requests.js +84 -0
- package/dist/src/cli/command-waits.d.ts +9 -0
- package/dist/src/cli/command-waits.js +51 -0
- package/dist/src/cli/commands.js +70 -88
- package/dist/src/cli/config-file.d.ts +2 -2
- package/dist/src/cli/config-file.js +4 -2
- package/dist/src/cli/config-notice.js +5 -2
- package/dist/src/cli/doctor-retention.d.ts +2 -0
- package/dist/src/cli/doctor-retention.js +93 -0
- package/dist/src/cli/doctor-workflows.d.ts +5 -2
- package/dist/src/cli/doctor-workflows.js +12 -7
- package/dist/src/cli/doctor.js +11 -9
- package/dist/src/cli/harness-probes.d.ts +2 -0
- package/dist/src/cli/harness-probes.js +1 -1
- package/dist/src/cli/harness-processes.d.ts +6 -0
- package/dist/src/cli/harness-processes.js +36 -0
- package/dist/src/cli/init-command.d.ts +9 -0
- package/dist/src/cli/init-command.js +52 -0
- package/dist/src/cli/init-prompt-command.d.ts +10 -0
- package/dist/src/cli/init-prompt-command.js +145 -0
- package/dist/src/cli/init-prompt.d.ts +35 -0
- package/dist/src/cli/init-prompt.js +74 -0
- package/dist/src/cli/init-selection.d.ts +13 -0
- package/dist/src/cli/init-selection.js +75 -0
- package/dist/src/cli/main.d.ts +2 -0
- package/dist/src/cli/main.js +37 -7
- package/dist/src/cli/mcp-server.d.ts +1 -0
- package/dist/src/cli/mcp-server.js +156 -0
- package/dist/src/cli/mcp-tools.d.ts +15 -0
- package/dist/src/cli/mcp-tools.js +242 -0
- package/dist/src/cli/queue-arguments.d.ts +15 -0
- package/dist/src/cli/queue-arguments.js +31 -0
- package/dist/src/cli/queue-render.d.ts +3 -0
- package/dist/src/cli/queue-render.js +26 -0
- package/dist/src/cli/reload-render.d.ts +2 -0
- package/dist/src/cli/reload-render.js +12 -0
- package/dist/src/cli/render.d.ts +1 -1
- package/dist/src/cli/render.js +54 -38
- package/dist/src/cli/report-ci-jobs.d.ts +23 -0
- package/dist/src/cli/report-ci-jobs.js +103 -0
- package/dist/src/cli/report-ci-usage.d.ts +9 -0
- package/dist/src/cli/report-ci-usage.js +185 -0
- package/dist/src/cli/report-ci.d.ts +13 -0
- package/dist/src/cli/report-ci.js +74 -0
- package/dist/src/cli/report-closures.d.ts +6 -0
- package/dist/src/cli/report-closures.js +97 -0
- package/dist/src/cli/report-flow.d.ts +7 -0
- package/dist/src/cli/report-flow.js +122 -0
- package/dist/src/cli/report-github-reader.d.ts +29 -0
- package/dist/src/cli/report-github-reader.js +157 -0
- package/dist/src/cli/report-github.d.ts +15 -8
- package/dist/src/cli/report-github.js +131 -150
- package/dist/src/cli/report-operator.d.ts +3 -0
- package/dist/src/cli/report-operator.js +40 -0
- package/dist/src/cli/report-ready.d.ts +3 -0
- package/dist/src/cli/report-ready.js +96 -0
- package/dist/src/cli/report-text.d.ts +9 -0
- package/dist/src/cli/report-text.js +33 -0
- package/dist/src/cli/report.d.ts +1 -0
- package/dist/src/cli/report.js +104 -27
- package/dist/src/cli/runtime-arguments.d.ts +18 -3
- package/dist/src/cli/runtime-arguments.js +29 -20
- package/dist/src/cli/schedule-arguments.d.ts +14 -0
- package/dist/src/cli/schedule-arguments.js +26 -0
- package/dist/src/cli/schedule-render.d.ts +22 -0
- package/dist/src/cli/schedule-render.js +73 -0
- package/dist/src/cli/terminal-text.d.ts +3 -0
- package/dist/src/cli/terminal-text.js +28 -0
- package/dist/src/cli/toolchain.d.ts +1 -0
- package/dist/src/cli/toolchain.js +1 -0
- package/dist/src/cli/usage-render.d.ts +1 -0
- package/dist/src/cli/usage-render.js +28 -1
- package/dist/src/cli/usage.d.ts +2 -2
- package/dist/src/cli/usage.js +89 -11
- package/dist/src/cli/watch-actions.js +2 -2
- package/dist/src/cli/watch-api-document.d.ts +430 -0
- package/dist/src/cli/watch-api-document.js +291 -0
- package/dist/src/cli/watch-api-run.d.ts +56 -0
- package/dist/src/cli/watch-api-run.js +112 -0
- package/dist/src/cli/watch-api.d.ts +17 -0
- package/dist/src/cli/watch-api.js +230 -0
- package/dist/src/cli/watch-board-view.js +19 -2
- package/dist/src/cli/watch-board.d.ts +4 -2
- package/dist/src/cli/watch-board.js +53 -43
- package/dist/src/cli/watch-card-forms.d.ts +1 -1
- package/dist/src/cli/watch-card-forms.js +11 -10
- package/dist/src/cli/watch-client.d.ts +1 -1
- package/dist/src/cli/watch-client.js +2 -11
- package/dist/src/cli/watch-header-view.d.ts +1 -5
- package/dist/src/cli/watch-header-view.js +17 -21
- package/dist/src/cli/watch-model.d.ts +5 -1
- package/dist/src/cli/watch-model.js +20 -11
- package/dist/src/cli/watch-page.js +15 -15
- package/dist/src/cli/watch-phases.d.ts +12 -3
- package/dist/src/cli/watch-phases.js +68 -11
- package/dist/src/cli/watch-pr-board.js +1 -1
- package/dist/src/cli/watch-pr-command.d.ts +1 -0
- package/dist/src/cli/watch-pull-request.js +18 -8
- package/dist/src/cli/watch-reads.d.ts +3 -0
- package/dist/src/cli/watch-reads.js +22 -20
- package/dist/src/cli/watch-render.d.ts +15 -0
- package/dist/src/cli/watch-run-input.d.ts +0 -1
- package/dist/src/cli/watch-run-input.js +0 -13
- package/dist/src/cli/watch-server.js +24 -10
- package/dist/src/cli/watch-view.d.ts +0 -3
- package/dist/src/cli/watch-view.js +13 -13
- package/dist/src/cli.js +73 -12
- package/dist/src/command-wait.d.ts +4 -0
- package/dist/src/command-wait.js +45 -0
- package/dist/src/configuration-change.d.ts +7 -0
- package/dist/src/configuration-change.js +14 -0
- package/dist/src/configuration-display.js +2 -0
- package/dist/src/configuration-schema.d.ts +14 -0
- package/dist/src/configuration-schema.js +6 -2
- package/dist/src/daemon/attachment-file.d.ts +6 -0
- package/dist/src/daemon/attachment-file.js +86 -0
- package/dist/src/daemon/attachments.d.ts +14 -0
- package/dist/src/daemon/attachments.js +17 -0
- package/dist/src/daemon/claude-recovery.d.ts +50 -0
- package/dist/src/daemon/claude-recovery.js +208 -0
- package/dist/src/daemon/claude-stream.d.ts +27 -0
- package/dist/src/daemon/claude-stream.js +63 -0
- package/dist/src/daemon/claude-turn.d.ts +11 -25
- package/dist/src/daemon/claude-turn.js +64 -81
- package/dist/src/daemon/claude-worker.d.ts +5 -4
- package/dist/src/daemon/claude-worker.js +127 -126
- package/dist/src/daemon/daemon-adapters.d.ts +9 -0
- package/dist/src/daemon/daemon-adapters.js +33 -5
- package/dist/src/daemon/daemon-loops.d.ts +5 -1
- package/dist/src/daemon/daemon-loops.js +18 -10
- package/dist/src/daemon/daemon.js +80 -61
- package/dist/src/daemon/github-attach.d.ts +2 -0
- package/dist/src/daemon/github-attach.js +222 -0
- package/dist/src/daemon/github-calls.js +1 -1
- package/dist/src/daemon/github-ci-filters.d.ts +6 -0
- package/dist/src/daemon/github-ci-filters.js +138 -0
- package/dist/src/daemon/github-ci-workflows.d.ts +10 -0
- package/dist/src/daemon/github-ci-workflows.js +148 -0
- package/dist/src/daemon/github-ci.js +22 -4
- package/dist/src/daemon/github-issue-methods.d.ts +2 -0
- package/dist/src/daemon/github-issue-methods.js +37 -2
- package/dist/src/daemon/github-merge-call.d.ts +2 -1
- package/dist/src/daemon/github-merge-call.js +10 -3
- package/dist/src/daemon/github-merge.js +52 -24
- package/dist/src/daemon/github-methods.js +18 -4
- package/dist/src/daemon/github-operation.d.ts +4 -0
- package/dist/src/daemon/github-operation.js +6 -0
- package/dist/src/daemon/github-worker.d.ts +4 -0
- package/dist/src/daemon/github-worker.js +6 -0
- package/dist/src/daemon/issue-queue.d.ts +4 -1
- package/dist/src/daemon/issue-queue.js +76 -78
- package/dist/src/daemon/merge-turns.d.ts +10 -0
- package/dist/src/daemon/merge-turns.js +37 -0
- package/dist/src/daemon/notify-events.d.ts +6 -0
- package/dist/src/daemon/notify-events.js +84 -0
- package/dist/src/daemon/notify-journal.js +1 -1
- package/dist/src/daemon/notify-message.d.ts +4 -1
- package/dist/src/daemon/notify-message.js +36 -0
- package/dist/src/daemon/notify.d.ts +1 -1
- package/dist/src/daemon/notify.js +5 -77
- package/dist/src/daemon/operation-journal.d.ts +1 -0
- package/dist/src/daemon/queue-control.d.ts +13 -0
- package/dist/src/daemon/queue-control.js +86 -0
- package/dist/src/daemon/queue-journal.d.ts +20 -0
- package/dist/src/daemon/queue-journal.js +89 -0
- package/dist/src/daemon/queue-status.d.ts +9 -3
- package/dist/src/daemon/queue-status.js +17 -4
- package/dist/src/daemon/record-archive.d.ts +19 -0
- package/dist/src/daemon/record-archive.js +82 -0
- package/dist/src/daemon/record-sweep.d.ts +24 -0
- package/dist/src/daemon/record-sweep.js +147 -0
- package/dist/src/daemon/resume-index-lock.d.ts +13 -0
- package/dist/src/daemon/resume-index-lock.js +160 -0
- package/dist/src/daemon/resume-worktree.d.ts +7 -0
- package/dist/src/daemon/resume-worktree.js +29 -0
- package/dist/src/daemon/retrying-turn.d.ts +2 -12
- package/dist/src/daemon/retrying-turn.js +98 -172
- package/dist/src/daemon/schedule-control.d.ts +26 -0
- package/dist/src/daemon/schedule-control.js +110 -0
- package/dist/src/daemon/schedule-journal.d.ts +2 -15
- package/dist/src/daemon/schedule-journal.js +67 -4
- package/dist/src/daemon/settings-reload.d.ts +26 -0
- package/dist/src/daemon/settings-reload.js +82 -0
- package/dist/src/daemon/ticket-registration.d.ts +2 -7
- package/dist/src/daemon/ticket-registration.js +15 -81
- package/dist/src/daemon/turn-attempt-journal.d.ts +38 -0
- package/dist/src/daemon/turn-attempt-journal.js +136 -0
- package/dist/src/daemon/turn-attempts.d.ts +47 -0
- package/dist/src/daemon/turn-attempts.js +166 -0
- package/dist/src/daemon/turn-details.d.ts +4 -0
- package/dist/src/daemon/turn-details.js +33 -0
- package/dist/src/daemon/turn-report.d.ts +8 -1
- package/dist/src/daemon/turn-report.js +39 -0
- package/dist/src/daemon/work-tree.d.ts +9 -0
- package/dist/src/daemon/work-tree.js +20 -0
- package/dist/src/daemon/worker-profile.d.ts +9 -0
- package/dist/src/daemon/worker-profile.js +44 -0
- package/dist/src/daemon/workflow-generations.d.ts +7 -4
- package/dist/src/daemon/workflow-generations.js +22 -14
- package/dist/src/daemon/workflow-reload.d.ts +41 -0
- package/dist/src/daemon/workflow-reload.js +244 -0
- package/dist/src/daemon/workflow-replay.d.ts +2 -1
- package/dist/src/daemon/workflow-replay.js +7 -3
- package/dist/src/daemon/workflow-schedules.d.ts +3 -0
- package/dist/src/daemon/workflow-schedules.js +98 -45
- package/dist/src/daemon/worktree-processes.d.ts +9 -0
- package/dist/src/daemon/worktree-processes.js +151 -0
- package/dist/src/doctor-report.d.ts +4 -6
- package/dist/src/doctor-report.js +8 -13
- package/dist/src/harness-start.d.ts +15 -0
- package/dist/src/harness-start.js +37 -0
- package/dist/src/host/command-wait.d.ts +38 -0
- package/dist/src/host/command-wait.js +115 -0
- package/dist/src/host/start-delivery.d.ts +5 -7
- package/dist/src/host/start-delivery.js +3 -15
- package/dist/src/host/step-bridge-host.d.ts +2 -0
- package/dist/src/host/step-bridge-host.js +21 -0
- package/dist/src/operation-identity.d.ts +1 -0
- package/dist/src/operation-identity.js +4 -0
- package/dist/src/private-config.schema.json +71 -0
- package/dist/src/project-config.schema.json +40 -0
- package/dist/src/project-settings.d.ts +16 -2
- package/dist/src/project-settings.js +35 -1
- package/dist/src/queue-spend.d.ts +4 -0
- package/dist/src/queue-spend.js +21 -0
- package/dist/src/queue-state.d.ts +26 -0
- package/dist/src/queue-state.js +34 -0
- package/dist/src/record-retention.d.ts +46 -0
- package/dist/src/record-retention.js +81 -0
- package/dist/src/relay/relay-service.d.ts +3 -0
- package/dist/src/relay/relay-service.js +5 -3
- package/dist/src/report-ci.d.ts +164 -0
- package/dist/src/report-ci.js +32 -0
- package/dist/src/report-effects.d.ts +15 -0
- package/dist/src/report-effects.js +212 -0
- package/dist/src/report-flow-types.d.ts +38 -0
- package/dist/src/report-flow-types.js +7 -0
- package/dist/src/report-flow.d.ts +43 -0
- package/dist/src/report-flow.js +193 -0
- package/dist/src/report-operator.d.ts +67 -0
- package/dist/src/report-operator.js +25 -0
- package/dist/src/report-quality.d.ts +221 -0
- package/dist/src/report-quality.js +94 -0
- package/dist/src/report-ready.d.ts +23 -0
- package/dist/src/report-ready.js +117 -0
- package/dist/src/report-statistics.d.ts +2 -1
- package/dist/src/report-statistics.js +40 -4
- package/dist/src/report.d.ts +588 -47
- package/dist/src/report.js +156 -41
- package/dist/src/schedule-progress.d.ts +33 -0
- package/dist/src/schedule-progress.js +45 -0
- package/dist/src/service/active-tickets.js +11 -6
- package/dist/src/service/command-waits.d.ts +34 -0
- package/dist/src/service/command-waits.js +86 -0
- package/dist/src/service/dispatcher.d.ts +4 -0
- package/dist/src/service/dispatcher.js +33 -0
- package/dist/src/service/expiry.js +2 -0
- package/dist/src/service/gateway.js +3 -1
- package/dist/src/service/queue-handlers.d.ts +4 -0
- package/dist/src/service/queue-handlers.js +32 -0
- package/dist/src/service/queue-spend.d.ts +6 -0
- package/dist/src/service/queue-spend.js +68 -0
- package/dist/src/service/registry.d.ts +28 -2
- package/dist/src/service/registry.js +48 -0
- package/dist/src/service/replies.d.ts +22 -8
- package/dist/src/service/replies.js +16 -2
- package/dist/src/service/run-handlers.js +37 -12
- package/dist/src/service/run-metadata.d.ts +15 -1
- package/dist/src/service/run-metadata.js +93 -8
- package/dist/src/service/service.d.ts +11 -3
- package/dist/src/service/service.js +22 -37
- package/dist/src/service/submission-handler.js +18 -4
- package/dist/src/service/worker-port.js +9 -1
- package/dist/src/service/worker-totals.d.ts +6 -0
- package/dist/src/service/worker-totals.js +8 -1
- package/dist/src/service/workflow-reload.d.ts +35 -0
- package/dist/src/service/workflow-reload.js +52 -0
- package/dist/src/step-bridge.d.ts +20 -0
- package/dist/src/steps/command-wait.d.ts +12 -0
- package/dist/src/steps/command-wait.js +26 -0
- package/dist/src/steps/open-decision-wait.d.ts +2 -0
- package/dist/src/steps/{decision-gate.js → open-decision-wait.js} +0 -7
- package/dist/src/steps/review-by-person.js +4 -1
- package/dist/src/steps/wait-for-command.d.ts +3 -0
- package/dist/src/steps/wait-for-command.js +17 -0
- package/dist/src/steps/wait-for-decision.js +1 -1
- package/dist/src/storage/command-wait-rows.d.ts +30 -0
- package/dist/src/storage/command-wait-rows.js +96 -0
- package/dist/src/storage/decision-snapshots.d.ts +8 -2
- package/dist/src/storage/decision-snapshots.js +16 -8
- package/dist/src/storage/domain-changes.d.ts +3 -1
- package/dist/src/storage/domain-changes.js +4 -0
- package/dist/src/storage/domain-schema.d.ts +16 -1
- package/dist/src/storage/domain-schema.js +35 -4
- package/dist/src/storage/effect-schema.d.ts +2 -0
- package/dist/src/storage/effect-schema.js +9 -0
- package/dist/src/storage/projection-changes.d.ts +12 -0
- package/dist/src/storage/projection-changes.js +194 -0
- package/dist/src/storage/projection-lookups.d.ts +7 -0
- package/dist/src/storage/projection-lookups.js +30 -0
- package/dist/src/testing-requests.d.ts +15 -0
- package/dist/src/testing-requests.js +93 -0
- package/dist/src/testing.d.ts +4 -10
- package/dist/src/testing.js +33 -86
- package/dist/src/worker-usage.d.ts +1 -0
- package/dist/src/worker-usage.js +3 -0
- package/dist/src/workflow-candidate.d.ts +1 -0
- package/dist/src/workflow-candidate.js +12 -1
- package/dist/src/workflow-contracts.d.ts +1 -0
- package/dist/src/workflow-contracts.js +9 -2
- package/dist/src/workflow-declaration.d.ts +1 -0
- package/dist/src/workflow-declaration.js +3 -0
- package/dist/src/workflow-discovery.d.ts +2 -13
- package/dist/src/workflow-discovery.js +1 -13
- package/dist/src/workflow-refusals.js +0 -1
- package/dist/src/workflows.d.ts +1 -1
- package/dist/src/workflows.js +1 -1
- package/dist/tools/compile-workflows.js +3 -0
- package/dist/tools/project-configuration.d.ts +7 -2
- package/dist/tools/project-configuration.js +30 -1
- package/dist/tools/red-green-command.d.ts +1 -0
- package/dist/tools/red-green-command.js +174 -0
- package/dist/tools/red-green-process.d.ts +10 -0
- package/dist/tools/red-green-process.js +59 -0
- package/dist/tools/self-host-processes.d.ts +2 -0
- package/dist/tools/self-host-processes.js +69 -26
- package/dist/tools/self-host-project.d.ts +2 -0
- package/dist/tools/self-host-project.js +30 -77
- package/dist/tools/self-host-runtime.js +1 -1
- package/dist/tools/self-host.js +76 -34
- package/dist/tools/template-command.d.ts +1 -0
- package/dist/tools/template-command.js +160 -0
- package/dist/tools/template-copy.d.ts +11 -0
- package/dist/tools/template-copy.js +130 -0
- package/dist/tools/template-files.d.ts +17 -0
- package/dist/tools/template-files.js +74 -0
- package/dist/tools/workflow-bundles.js +1 -0
- package/dist/tools/workflow-candidate-counts.js +2 -2
- package/dist/tools/workflow-candidate-program.d.ts +4 -2
- package/dist/tools/workflow-candidate-program.js +30 -11
- package/dist/tools/workflow-candidate-shape.d.ts +3 -0
- package/dist/tools/workflow-candidate-shape.js +90 -0
- package/dist/tools/workflow-candidate-source.d.ts +1 -0
- package/dist/tools/workflow-candidate-source.js +26 -4
- package/dist/tools/workflow-candidate-syntax.d.ts +2 -2
- package/dist/tools/workflow-candidate-syntax.js +24 -94
- package/dist/tools/workflow-command.js +1 -2
- package/dist/tools/workflow-folders.d.ts +2 -3
- package/dist/tools/workflow-folders.js +1 -1
- package/package.json +17 -9
- package/templates/develop/README.md +93 -4
- package/templates/develop/develop/flow-tests.ts +38 -1
- package/templates/develop/develop/interruption-tests.ts +157 -0
- package/templates/develop/develop/local.ts +1 -0
- package/templates/develop/develop/option-tests.ts +138 -9
- package/templates/develop/develop/pull.ts +5 -1
- package/templates/develop/develop/red-green.ts +55 -0
- package/templates/develop/develop/refusal-tests.ts +77 -0
- package/templates/develop/develop/report.ts +31 -11
- package/templates/develop/develop/round.ts +1 -0
- package/templates/develop/develop/scenarios.ts +27 -0
- package/templates/develop/develop/turn.ts +28 -7
- package/templates/develop/develop.declaration.json +1 -1
- package/templates/develop/develop.test.ts +4 -0
- package/templates/develop/template.json +29 -2
- package/templates/idea-to-issue/README.md +27 -0
- package/templates/idea-to-issue/idea-to-issue/effects.ts +52 -0
- package/templates/idea-to-issue/idea-to-issue/leave.ts +10 -0
- package/templates/idea-to-issue/idea-to-issue/next.ts +29 -0
- package/templates/idea-to-issue/idea-to-issue/post-person.ts +18 -0
- package/templates/idea-to-issue/idea-to-issue/post.ts +50 -0
- package/templates/idea-to-issue/idea-to-issue/queue.ts +27 -0
- package/templates/idea-to-issue/idea-to-issue/review.ts +42 -0
- package/templates/idea-to-issue/idea-to-issue/scenarios.ts +50 -0
- package/templates/idea-to-issue/idea-to-issue/turn.ts +40 -0
- package/templates/idea-to-issue/idea-to-issue.declaration.json +16 -0
- package/templates/idea-to-issue/idea-to-issue.test.ts +79 -0
- package/templates/idea-to-issue/idea-to-issue.ts +49 -0
- package/templates/idea-to-issue/template.json +81 -0
- package/templates/review-day/README.md +97 -0
- package/templates/review-day/review-day/critique.ts +58 -0
- package/templates/review-day/review-day/decision.ts +29 -0
- package/templates/review-day/review-day/facts.ts +69 -0
- package/templates/review-day/review-day/label.ts +29 -0
- package/templates/review-day/review-day/next.ts +28 -0
- package/templates/review-day/review-day/post.ts +27 -0
- package/templates/review-day/review-day/report.ts +98 -0
- package/templates/review-day/review-day/rules.ts +12 -0
- package/templates/review-day/review-day/scenarios.ts +76 -0
- package/templates/review-day/review-day/turn.ts +73 -0
- package/templates/review-day/review-day.declaration.json +16 -0
- package/templates/review-day/review-day.test.ts +362 -0
- package/templates/review-day/review-day.ts +37 -0
- package/templates/review-day/template.json +56 -0
- package/dist/src/cli/watch-start-view.d.ts +0 -18
- package/dist/src/cli/watch-start-view.js +0 -77
- package/dist/src/steps/decision-gate.d.ts +0 -3
- package/dist/workflows/develop-prd.d.ts +0 -7
- package/dist/workflows/develop-prd.js +0 -165
- package/dist/workflows/develop-ticket.d.ts +0 -9
- package/dist/workflows/develop-ticket.js +0 -207
- package/dist/workflows/issue-labels.d.ts +0 -16
- package/dist/workflows/issue-labels.js +0 -70
- package/dist/workflows/ticket-prompts.d.ts +0 -35
- package/dist/workflows/ticket-prompts.js +0 -147
|
@@ -1,23 +1,22 @@
|
|
|
1
|
-
import { eligibleIntents, } from "../../authority/reducer.js";
|
|
2
|
-
import { loadOperationSnapshot, loadProjections, } from "../../storage/decision-snapshots.js";
|
|
3
1
|
import { loadEvents } from "../../storage/domain-rows.js";
|
|
4
2
|
import { pinnedResumption } from "../authority-admission.js";
|
|
5
|
-
import {
|
|
3
|
+
import { storedDefinitions, storedEvents, } from "../authority-restore.js";
|
|
6
4
|
import { checkedRequest } from "./authority-actor.js";
|
|
7
5
|
import { subscriptions, } from "./authority-changes.js";
|
|
8
6
|
import { authorityQueries, guardedRead, } from "./authority-queries.js";
|
|
9
7
|
import { effectQueries } from "./effect-queries.js";
|
|
10
8
|
import { backupInto } from "../../storage/domain-schema.js";
|
|
11
9
|
import { observeSettings, } from "./authority-connection.js";
|
|
10
|
+
import { authorityHealth } from "./authority-health.js";
|
|
12
11
|
import { failed, serializable, storeReceipt, invalidCommand, oversized, tooLarge, unserializable, } from "./authority-receipts.js";
|
|
12
|
+
export { operationRecords } from "./projection-memory.js";
|
|
13
13
|
export function authoritySession(parts) {
|
|
14
14
|
const session = {
|
|
15
15
|
parts,
|
|
16
16
|
stopping: new AbortController(),
|
|
17
17
|
delivering: false,
|
|
18
18
|
failure: null,
|
|
19
|
-
|
|
20
|
-
describing: null,
|
|
19
|
+
health: authorityHealth(parts),
|
|
21
20
|
closed: false,
|
|
22
21
|
running: Promise.resolve(),
|
|
23
22
|
invocations: new Set(),
|
|
@@ -33,18 +32,18 @@ export function authoritySession(parts) {
|
|
|
33
32
|
});
|
|
34
33
|
return {
|
|
35
34
|
execute: (command, context) => executeCommand(session, { command, context }),
|
|
36
|
-
state: async () =>
|
|
35
|
+
state: async () => (await projected(session)).state(),
|
|
37
36
|
events: async () => {
|
|
38
37
|
await refreshed(session);
|
|
39
38
|
available(session);
|
|
40
39
|
return storedEvents(await parts.reader.connection(loadEvents));
|
|
41
40
|
},
|
|
42
|
-
eligibleIntents: async () =>
|
|
43
|
-
operations: async () =>
|
|
41
|
+
eligibleIntents: async () => (await projected(session)).eligible(),
|
|
42
|
+
operations: async () => (await projected(session)).operations(),
|
|
44
43
|
resumePinned: async (runId, manifest) => {
|
|
45
|
-
const
|
|
46
|
-
return pinnedResumption(
|
|
47
|
-
definitions: storedDefinitions(snapshot),
|
|
44
|
+
const current = await projected(session);
|
|
45
|
+
return pinnedResumption(current.state(), {
|
|
46
|
+
definitions: storedDefinitions(current.snapshot),
|
|
48
47
|
runId,
|
|
49
48
|
available: manifest,
|
|
50
49
|
});
|
|
@@ -56,7 +55,11 @@ export function authoritySession(parts) {
|
|
|
56
55
|
},
|
|
57
56
|
epoch: parts.epoch,
|
|
58
57
|
recoveryLimit: parts.recoveryLimit,
|
|
59
|
-
queries:
|
|
58
|
+
queries: {
|
|
59
|
+
...authorityQueries(read),
|
|
60
|
+
sequences: async () => (await projected(session)).sequences(),
|
|
61
|
+
workflowIds: async (runIds) => (await projected(session)).workflowIds(runIds),
|
|
62
|
+
},
|
|
60
63
|
effects: effectQueries(read, { stopLimit: parts.stopLimit }),
|
|
61
64
|
deliver: (signal) => deliver(session, signal),
|
|
62
65
|
changes: { subscribe: session.changes.add },
|
|
@@ -82,29 +85,16 @@ async function stopped(session) {
|
|
|
82
85
|
}
|
|
83
86
|
}
|
|
84
87
|
async function refreshed(session) {
|
|
85
|
-
if (session.
|
|
88
|
+
if (session.failure !== null || session.closed)
|
|
86
89
|
return;
|
|
87
|
-
await
|
|
90
|
+
await session.health.refresh();
|
|
88
91
|
}
|
|
89
|
-
|
|
92
|
+
function failClosed(session, failure) {
|
|
90
93
|
session.failure ??= failure;
|
|
91
|
-
|
|
92
|
-
close(session).catch(() => undefined);
|
|
93
|
-
}
|
|
94
|
-
async function conditionRead(session) {
|
|
95
|
-
if (session.condition !== null && session.describing === null)
|
|
96
|
-
return;
|
|
97
|
-
session.describing ??= described(session).finally(() => {
|
|
98
|
-
session.describing = null;
|
|
99
|
-
});
|
|
100
|
-
await session.describing;
|
|
94
|
+
close(session).catch(ignored);
|
|
101
95
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
if (detected === undefined)
|
|
105
|
-
return;
|
|
106
|
-
session.condition = detected;
|
|
107
|
-
session.condition = (await session.parts.condition()) ?? detected;
|
|
96
|
+
function ignored() {
|
|
97
|
+
return undefined;
|
|
108
98
|
}
|
|
109
99
|
async function backup(session, target) {
|
|
110
100
|
await refreshed(session);
|
|
@@ -116,36 +106,43 @@ async function backup(session, target) {
|
|
|
116
106
|
throw new Error(`backup-failed: ${String(Reflect.get(Object(error), "message"))}`, { cause: error });
|
|
117
107
|
}
|
|
118
108
|
}
|
|
119
|
-
function
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
throw new Error(`authority-unavailable: ${failure}`);
|
|
109
|
+
function opened(session) {
|
|
110
|
+
if (session.failure !== null)
|
|
111
|
+
throw new Error(`authority-unavailable: ${session.failure}`);
|
|
123
112
|
if (session.closed)
|
|
124
113
|
throw new Error("authority-unavailable: closed");
|
|
125
114
|
}
|
|
115
|
+
function available(session) {
|
|
116
|
+
opened(session);
|
|
117
|
+
const condition = session.health.condition();
|
|
118
|
+
if (condition !== null)
|
|
119
|
+
throw new Error(`authority-unavailable: ${condition}`);
|
|
120
|
+
}
|
|
126
121
|
function unavailableReceipt(session) {
|
|
127
|
-
|
|
128
|
-
if (failure !== null)
|
|
122
|
+
if (session.failure !== null)
|
|
129
123
|
return {
|
|
130
124
|
kind: "failed",
|
|
131
125
|
reason: "storage-unavailable",
|
|
132
|
-
detail: `closed after ${failure}`,
|
|
126
|
+
detail: `closed after ${session.failure}`,
|
|
133
127
|
};
|
|
134
128
|
if (session.closed)
|
|
135
129
|
return { kind: "failed", reason: "storage-unavailable", detail: "closed" };
|
|
136
|
-
|
|
130
|
+
const condition = session.health.condition();
|
|
131
|
+
return condition === null
|
|
132
|
+
? undefined
|
|
133
|
+
: { kind: "failed", reason: "authority-unavailable", detail: condition };
|
|
137
134
|
}
|
|
138
135
|
async function projected(session) {
|
|
139
136
|
await refreshed(session);
|
|
140
137
|
available(session);
|
|
141
|
-
return session.parts.
|
|
138
|
+
return session.parts.memory.read(session.parts.database);
|
|
142
139
|
}
|
|
143
140
|
async function deliver(session, signal) {
|
|
144
141
|
if (!session.parts.deliveryConfigured)
|
|
145
142
|
throw new Error("delivery-unconfigured");
|
|
146
143
|
if (session.delivering)
|
|
147
144
|
throw new Error("delivery-already-running");
|
|
148
|
-
|
|
145
|
+
opened(session);
|
|
149
146
|
session.delivering = true;
|
|
150
147
|
try {
|
|
151
148
|
await delivered(session, signal);
|
|
@@ -154,21 +151,19 @@ async function deliver(session, signal) {
|
|
|
154
151
|
session.delivering = false;
|
|
155
152
|
}
|
|
156
153
|
await refreshed(session);
|
|
157
|
-
const failure = session.
|
|
154
|
+
const failure = session.failure ?? session.health.condition();
|
|
158
155
|
if (failure !== null)
|
|
159
156
|
throw new Error(`authority-unavailable: ${failure}`);
|
|
160
157
|
}
|
|
161
158
|
async function delivered(session, signal) {
|
|
162
159
|
if (!(await session.parts.handlersSettled()))
|
|
163
160
|
throw new Error("delivery-handler-in-flight");
|
|
164
|
-
|
|
165
|
-
const watch = new AbortController();
|
|
161
|
+
opened(session);
|
|
166
162
|
const timer = setInterval(() => {
|
|
167
|
-
|
|
168
|
-
watch.abort();
|
|
163
|
+
refreshed(session).catch(ignored);
|
|
169
164
|
}, session.parts.watchMilliseconds);
|
|
170
165
|
try {
|
|
171
|
-
session.running = session.parts.run(AbortSignal.any([signal, session.stopping.signal
|
|
166
|
+
session.running = session.parts.run(AbortSignal.any([signal, session.stopping.signal]));
|
|
172
167
|
await session.running;
|
|
173
168
|
}
|
|
174
169
|
finally {
|
|
@@ -177,8 +172,7 @@ async function delivered(session, signal) {
|
|
|
177
172
|
}
|
|
178
173
|
async function executeCommand(session, input) {
|
|
179
174
|
const { command, context } = input;
|
|
180
|
-
await
|
|
181
|
-
const unavailable = unavailableReceipt(session);
|
|
175
|
+
const unavailable = await refusal(session);
|
|
182
176
|
if (unavailable !== undefined)
|
|
183
177
|
return unavailable;
|
|
184
178
|
const given = serializable({
|
|
@@ -196,15 +190,32 @@ async function executeCommand(session, input) {
|
|
|
196
190
|
if (oversized(request))
|
|
197
191
|
return tooLarge;
|
|
198
192
|
try {
|
|
199
|
-
return
|
|
193
|
+
return storeReceipt(await invoked(session, request));
|
|
200
194
|
}
|
|
201
195
|
catch (error) {
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
196
|
+
return failedReceipt(session, error);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
async function refusal(session) {
|
|
200
|
+
try {
|
|
201
|
+
await refreshed(session);
|
|
207
202
|
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
return failed(error);
|
|
205
|
+
}
|
|
206
|
+
return unavailableReceipt(session);
|
|
207
|
+
}
|
|
208
|
+
function failedReceipt(session, error) {
|
|
209
|
+
const receipt = failed(error);
|
|
210
|
+
if (timedOut(error))
|
|
211
|
+
return receipt;
|
|
212
|
+
failClosed(session, receipt.reason === "storage-failure"
|
|
213
|
+
? "storage failure"
|
|
214
|
+
: "authority failure");
|
|
215
|
+
return receipt;
|
|
216
|
+
}
|
|
217
|
+
function timedOut(error) {
|
|
218
|
+
return error instanceof Error && error.name === "SyncTimeout";
|
|
208
219
|
}
|
|
209
220
|
async function invoked(session, request) {
|
|
210
221
|
const invocation = session.parts.execute(request);
|
|
@@ -216,36 +227,3 @@ async function invoked(session, request) {
|
|
|
216
227
|
session.invocations.delete(invocation);
|
|
217
228
|
}
|
|
218
229
|
}
|
|
219
|
-
async function healthyReceipt(session, value) {
|
|
220
|
-
const receipt = storeReceipt(value);
|
|
221
|
-
await refreshed(session);
|
|
222
|
-
return receipt;
|
|
223
|
-
}
|
|
224
|
-
export function operationRecords(snapshot) {
|
|
225
|
-
const deliveries = Map.groupBy(snapshot.deliveries, (row) => row.operationId);
|
|
226
|
-
return snapshot.outbox.map((row) => ({
|
|
227
|
-
operationId: row.operationId,
|
|
228
|
-
kind: intentKind(row.kind),
|
|
229
|
-
runId: row.runId,
|
|
230
|
-
createdSequence: row.createdSequence,
|
|
231
|
-
releasedSequence: row.releasedSequence,
|
|
232
|
-
deliveries: (deliveries.get(row.operationId) ?? []).map(({ effectId, outcome, receipt, purpose, epoch }) => ({
|
|
233
|
-
effectId,
|
|
234
|
-
outcome,
|
|
235
|
-
receipt,
|
|
236
|
-
purpose,
|
|
237
|
-
epoch,
|
|
238
|
-
})),
|
|
239
|
-
}));
|
|
240
|
-
}
|
|
241
|
-
function eligible(snapshot) {
|
|
242
|
-
return eligibleIntents({
|
|
243
|
-
...currentState(snapshot),
|
|
244
|
-
effects: {
|
|
245
|
-
operations: Object.fromEntries(snapshot.pending.map((operationId) => [
|
|
246
|
-
operationId,
|
|
247
|
-
{ status: "dispatch-pending" },
|
|
248
|
-
])),
|
|
249
|
-
},
|
|
250
|
-
});
|
|
251
|
-
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { SolidObjectsConfiguration } from "solid-objects";
|
|
1
|
+
import type { Logger, SolidObjectsConfiguration } from "solid-objects";
|
|
2
2
|
export interface AuthorityTiming {
|
|
3
3
|
readonly leaseMilliseconds: number;
|
|
4
4
|
readonly renewalMilliseconds: number;
|
|
@@ -30,4 +30,5 @@ export declare function effectConfiguration(options: {
|
|
|
30
30
|
readonly stop?: unknown;
|
|
31
31
|
};
|
|
32
32
|
}): PlanSettings;
|
|
33
|
+
export declare function authorityLogger(log: ((line: string) => void) | undefined): Logger;
|
|
33
34
|
export declare function librarySettings(timing: AuthorityTiming, log: ((line: string) => void) | undefined): Partial<SolidObjectsConfiguration>;
|
|
@@ -47,14 +47,17 @@ export function effectConfiguration(options) {
|
|
|
47
47
|
function standardError(line) {
|
|
48
48
|
process.stderr.write(line);
|
|
49
49
|
}
|
|
50
|
+
export function authorityLogger(log) {
|
|
51
|
+
return lineLogger(log ?? standardError);
|
|
52
|
+
}
|
|
50
53
|
export function librarySettings(timing, log) {
|
|
51
54
|
return {
|
|
52
55
|
tableNamePrefix: "solid_",
|
|
53
56
|
maxAttempts: 1,
|
|
54
57
|
maxActivationDurationMilliseconds: 50,
|
|
55
|
-
maxPayloadBytes: 900_000 + commandLimits.stdoutBytes *
|
|
56
|
-
maxResultBytes: 900_000 + commandLimits.stdoutBytes *
|
|
57
|
-
logger:
|
|
58
|
+
maxPayloadBytes: 900_000 + commandLimits.stdoutBytes * 12,
|
|
59
|
+
maxResultBytes: 900_000 + commandLimits.stdoutBytes * 12,
|
|
60
|
+
logger: authorityLogger(log),
|
|
58
61
|
leaseDurationMilliseconds: timing.leaseMilliseconds,
|
|
59
62
|
leaseRenewalIntervalMilliseconds: timing.renewalMilliseconds,
|
|
60
63
|
processHeartbeatIntervalMilliseconds: timing.heartbeatMilliseconds,
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { upgradeCommandWaits, upgradeCommandWaitChecks } from "../command-wait-restore.ts";
|
|
2
|
+
import { loadDecided, loadEffected, loadWaiting, loadCurrent } from "../../storage/decision-snapshots.ts";
|
|
2
3
|
import { loadSnapshot } from "../../storage/domain-rows.ts";
|
|
3
4
|
import { upgradeDecisions } from "../decision-upgrade.ts";
|
|
4
|
-
import { upgradeEffects } from "../effect-upgrade.ts";
|
|
5
|
+
import { upgradeEffects, upgradeEventIndexes, upgradeRunIndexes, upgradeSpendingIndexes } from "../effect-upgrade.ts";
|
|
5
6
|
declare const upgrades: readonly [{
|
|
6
7
|
readonly from: "adopted";
|
|
7
8
|
readonly load: typeof loadSnapshot;
|
|
@@ -10,6 +11,26 @@ declare const upgrades: readonly [{
|
|
|
10
11
|
readonly from: "decided";
|
|
11
12
|
readonly load: typeof loadDecided;
|
|
12
13
|
readonly apply: typeof upgradeEffects;
|
|
14
|
+
}, {
|
|
15
|
+
readonly from: "effected";
|
|
16
|
+
readonly load: typeof loadEffected;
|
|
17
|
+
readonly apply: typeof upgradeCommandWaits;
|
|
18
|
+
}, {
|
|
19
|
+
readonly from: "waiting";
|
|
20
|
+
readonly load: typeof loadWaiting;
|
|
21
|
+
readonly apply: typeof upgradeCommandWaitChecks;
|
|
22
|
+
}, {
|
|
23
|
+
readonly from: "checked";
|
|
24
|
+
readonly load: typeof loadCurrent;
|
|
25
|
+
readonly apply: typeof upgradeSpendingIndexes;
|
|
26
|
+
}, {
|
|
27
|
+
readonly from: "indexed";
|
|
28
|
+
readonly load: typeof loadCurrent;
|
|
29
|
+
readonly apply: typeof upgradeEventIndexes;
|
|
30
|
+
}, {
|
|
31
|
+
readonly from: "event-indexed";
|
|
32
|
+
readonly load: typeof loadCurrent;
|
|
33
|
+
readonly apply: typeof upgradeRunIndexes;
|
|
13
34
|
}];
|
|
14
35
|
export type UpgradeStep = (typeof upgrades)[number];
|
|
15
36
|
export declare function upgradeSteps(kind: string): readonly UpgradeStep[];
|
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { upgradeCommandWaits, upgradeCommandWaitChecks, } from "../command-wait-restore.js";
|
|
2
|
+
import { loadDecided, loadEffected, loadWaiting, loadCurrent, } from "../../storage/decision-snapshots.js";
|
|
2
3
|
import { loadSnapshot } from "../../storage/domain-rows.js";
|
|
3
4
|
import { upgradeDecisions } from "../decision-upgrade.js";
|
|
4
|
-
import { upgradeEffects } from "../effect-upgrade.js";
|
|
5
|
+
import { upgradeEffects, upgradeEventIndexes, upgradeRunIndexes, upgradeSpendingIndexes, } from "../effect-upgrade.js";
|
|
5
6
|
const upgrades = [
|
|
6
7
|
{ from: "adopted", load: loadSnapshot, apply: upgradeDecisions },
|
|
7
8
|
{ from: "decided", load: loadDecided, apply: upgradeEffects },
|
|
9
|
+
{ from: "effected", load: loadEffected, apply: upgradeCommandWaits },
|
|
10
|
+
{ from: "waiting", load: loadWaiting, apply: upgradeCommandWaitChecks },
|
|
11
|
+
{ from: "checked", load: loadCurrent, apply: upgradeSpendingIndexes },
|
|
12
|
+
{ from: "indexed", load: loadCurrent, apply: upgradeEventIndexes },
|
|
13
|
+
{ from: "event-indexed", load: loadCurrent, apply: upgradeRunIndexes },
|
|
8
14
|
];
|
|
9
15
|
export function upgradeSteps(kind) {
|
|
10
16
|
const first = upgrades.findIndex((step) => step.from === kind);
|
|
@@ -3,10 +3,14 @@ export interface WatchedEvent {
|
|
|
3
3
|
readonly messageId: string | null;
|
|
4
4
|
readonly attributes: Readonly<Record<string, unknown>>;
|
|
5
5
|
}
|
|
6
|
+
export interface WatchReport {
|
|
7
|
+
readonly kind: "stranded" | "dead-lettered";
|
|
8
|
+
readonly messageId: string;
|
|
9
|
+
}
|
|
10
|
+
export type MessageRuns = (messageIds: readonly string[]) => Promise<ReadonlyMap<string, string>>;
|
|
6
11
|
export interface StrandingWatchdog {
|
|
7
12
|
readonly observe: (event: WatchedEvent) => void;
|
|
8
|
-
readonly
|
|
9
|
-
readonly deadLettered: () => string | undefined;
|
|
13
|
+
readonly report: (runs: MessageRuns) => Promise<WatchReport | undefined>;
|
|
10
14
|
}
|
|
11
15
|
export declare function strandingWatchdog(bound: {
|
|
12
16
|
readonly boundMilliseconds: number;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { terminal } from "../../authority/transitions.js";
|
|
1
2
|
const callbacks = ["deliveryCompleted", "deliveryFailed"];
|
|
2
3
|
const finished = [
|
|
3
4
|
"solid_objects.message.completed",
|
|
@@ -7,33 +8,54 @@ const finished = [
|
|
|
7
8
|
export function strandingWatchdog(bound) {
|
|
8
9
|
const clock = bound.clock ?? monotonic;
|
|
9
10
|
const lost = new Map();
|
|
10
|
-
const dead =
|
|
11
|
-
let reported;
|
|
11
|
+
const dead = new Set();
|
|
12
12
|
return {
|
|
13
13
|
observe: (event) => {
|
|
14
14
|
const { messageId } = event;
|
|
15
15
|
if (messageId === null)
|
|
16
16
|
return;
|
|
17
17
|
if (deadCallback(event))
|
|
18
|
-
dead.
|
|
18
|
+
dead.add(messageId);
|
|
19
19
|
if (event.name === "solid_objects.activation.lost" &&
|
|
20
20
|
!lost.has(messageId))
|
|
21
21
|
lost.set(messageId, clock());
|
|
22
22
|
if (finished.includes(event.name))
|
|
23
23
|
lost.delete(messageId);
|
|
24
24
|
},
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
report: async (runs) => {
|
|
26
|
+
const overdue = overdueMessages(lost, clock() - bound.boundMilliseconds);
|
|
27
|
+
const suspects = [...dead, ...overdue];
|
|
28
|
+
if (suspects.length === 0)
|
|
29
|
+
return undefined;
|
|
30
|
+
const statuses = await runs(suspects);
|
|
31
|
+
const released = suspects.filter((messageId) => settled(statuses.get(messageId)));
|
|
32
|
+
for (const messageId of released) {
|
|
33
|
+
lost.delete(messageId);
|
|
34
|
+
dead.delete(messageId);
|
|
35
|
+
}
|
|
36
|
+
return firstReport({ dead: [...dead], stranded: overdue, lost });
|
|
28
37
|
},
|
|
29
|
-
deadLettered: () => dead[0],
|
|
30
38
|
};
|
|
31
39
|
}
|
|
32
40
|
function monotonic() {
|
|
33
41
|
return performance.now();
|
|
34
42
|
}
|
|
35
|
-
function
|
|
36
|
-
return [...lost]
|
|
43
|
+
function overdueMessages(lost, limit) {
|
|
44
|
+
return [...lost]
|
|
45
|
+
.filter(([, at]) => at < limit)
|
|
46
|
+
.map(([messageId]) => messageId);
|
|
47
|
+
}
|
|
48
|
+
function settled(status) {
|
|
49
|
+
return terminal.some((candidate) => candidate === status);
|
|
50
|
+
}
|
|
51
|
+
function firstReport(found) {
|
|
52
|
+
const deadLetter = found.dead[0];
|
|
53
|
+
if (deadLetter !== undefined)
|
|
54
|
+
return { kind: "dead-lettered", messageId: deadLetter };
|
|
55
|
+
const stranded = found.stranded.find((messageId) => found.lost.has(messageId));
|
|
56
|
+
return stranded === undefined
|
|
57
|
+
? undefined
|
|
58
|
+
: { kind: "stranded", messageId: stranded };
|
|
37
59
|
}
|
|
38
60
|
function deadCallback(event) {
|
|
39
61
|
return (event.name === "solid_objects.dead_letter.created" &&
|
|
@@ -76,6 +76,7 @@ async function begun(opening) {
|
|
|
76
76
|
reason: "unresolved-delivery",
|
|
77
77
|
detail: condition,
|
|
78
78
|
};
|
|
79
|
+
await parts.memory.load(owned.database);
|
|
79
80
|
return integer(opened, "epoch");
|
|
80
81
|
}
|
|
81
82
|
async function start(opening) {
|
|
@@ -99,6 +100,7 @@ async function start(opening) {
|
|
|
99
100
|
authority: authoritySession({
|
|
100
101
|
database,
|
|
101
102
|
reader: parts.reader,
|
|
103
|
+
memory: parts.memory,
|
|
102
104
|
execute: (request) => authority.execute(json(request)),
|
|
103
105
|
run: (signal) => parts.runtime.run(signal),
|
|
104
106
|
stop: parts.stop,
|
|
@@ -106,8 +108,8 @@ async function start(opening) {
|
|
|
106
108
|
deliveryConfigured: options.delivery !== undefined,
|
|
107
109
|
epoch,
|
|
108
110
|
...parts.limits,
|
|
109
|
-
unhealthy: parts.unhealthy,
|
|
110
111
|
condition: parts.condition,
|
|
112
|
+
logger: parts.logger,
|
|
111
113
|
watchMilliseconds: parts.watchMilliseconds,
|
|
112
114
|
subscribe: (listener) => parts.subscribe(actorId, listener),
|
|
113
115
|
}),
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { commandWaitDeadline } from "../command-wait-restore.js";
|
|
1
2
|
import { createHash } from "node:crypto";
|
|
2
3
|
import { delivers, isSettled } from "../../authority/gates.js";
|
|
3
4
|
import { eligibleIntents, } from "../../authority/reducer.js";
|
|
@@ -26,6 +27,7 @@ export function protectedIntent(state, attempt) {
|
|
|
26
27
|
.filter((lease) => lease.resourceKey === operation.leaseKey)
|
|
27
28
|
.map((lease) => ({
|
|
28
29
|
...intent,
|
|
30
|
+
...commandWaitDeadline(state.commandWaits ?? {}, operation.operationId),
|
|
29
31
|
workflow,
|
|
30
32
|
purpose,
|
|
31
33
|
inputDigest: operation.inputDigest,
|
|
@@ -16,4 +16,4 @@ export interface Attempt {
|
|
|
16
16
|
readonly effectId: string;
|
|
17
17
|
}
|
|
18
18
|
export declare function deliverEffect(parts: EffectDelivery, attempt: Attempt): Promise<JsonObject>;
|
|
19
|
-
export declare function protectedArguments(value: JsonObject): EffectArguments
|
|
19
|
+
export declare function protectedArguments(value: JsonObject): EffectArguments & Pick<ProtectedIntent, "commandDeadline">;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { dispatchCommandWait, readCommandWaitDeadline, } from "../command-wait-restore.js";
|
|
1
2
|
import { dispatchDecision, } from "../../authority/dispatch-decision.js";
|
|
2
3
|
import { integer, optionalInteger, optionalText, text, } from "../../storage/domain-rows.js";
|
|
3
4
|
import { budgetRow } from "../../storage/effect-rows.js";
|
|
@@ -16,11 +17,16 @@ const absent = {
|
|
|
16
17
|
budget: undefined,
|
|
17
18
|
};
|
|
18
19
|
async function dispatchRead(connection, attempt) {
|
|
19
|
-
const row = await connection.get("SELECT d.outcome, d.input_digest, a.lease_generation, o.released_sequence, r.status, r.workflow, p.status AS operation_status, p.capability, p.units, l.operation_id AS lease_owner, l.generation, l.expires_at, l.state AS lease_state, b.run_id, b.effect_limit, b.spent, b.capabilities, b.exhausted_sequence FROM deliveries d JOIN outbox o ON o.operation_id = d.operation_id JOIN runs r ON r.run_id = o.run_id JOIN dispatch_attempts a ON a.effect_id = d.effect_id JOIN operations p ON p.operation_id = d.operation_id JOIN leases l ON l.resource_key = p.lease_key JOIN run_budgets b ON b.run_id = o.run_id WHERE d.effect_id = ? AND d.operation_id = ?", [attempt.effectId, attempt.intent.operationId]);
|
|
20
|
+
const row = await connection.get("SELECT d.outcome, d.input_digest, a.lease_generation, o.released_sequence, r.status, r.workflow, p.status AS operation_status, p.capability, p.units, p.method, p.target, p.payload, l.operation_id AS lease_owner, l.generation, l.expires_at, l.state AS lease_state, b.run_id, b.effect_limit, b.spent, b.capabilities, b.exhausted_sequence FROM deliveries d JOIN outbox o ON o.operation_id = d.operation_id JOIN runs r ON r.run_id = o.run_id JOIN dispatch_attempts a ON a.effect_id = d.effect_id JOIN operations p ON p.operation_id = d.operation_id JOIN leases l ON l.resource_key = p.lease_key JOIN run_budgets b ON b.run_id = o.run_id WHERE d.effect_id = ? AND d.operation_id = ?", [attempt.effectId, attempt.intent.operationId]);
|
|
20
21
|
if (row === undefined)
|
|
21
22
|
return absent;
|
|
22
23
|
const workflow = text(row, "workflow");
|
|
23
24
|
return {
|
|
25
|
+
...(await dispatchCommandWait(connection, {
|
|
26
|
+
runId: attempt.intent.runId,
|
|
27
|
+
workflow,
|
|
28
|
+
operationId: attempt.intent.operationId,
|
|
29
|
+
})),
|
|
24
30
|
attempt: {
|
|
25
31
|
outcome: optionalText(row, "outcome"),
|
|
26
32
|
inputDigest: text(row, "input_digest"),
|
|
@@ -37,6 +43,9 @@ async function dispatchRead(connection, attempt) {
|
|
|
37
43
|
status: text(row, "operation_status"),
|
|
38
44
|
capability: text(row, "capability"),
|
|
39
45
|
units: integer(row, "units"),
|
|
46
|
+
method: text(row, "method"),
|
|
47
|
+
target: text(row, "target"),
|
|
48
|
+
payload: text(row, "payload"),
|
|
40
49
|
},
|
|
41
50
|
budget: storedBudget(budgetRow(row)),
|
|
42
51
|
lease: {
|
|
@@ -52,7 +61,8 @@ async function called(parts, call) {
|
|
|
52
61
|
const adapterCall = parts.delivery[name]?.bind(parts.delivery);
|
|
53
62
|
if (adapterCall === undefined)
|
|
54
63
|
return { kind: "unknown", reason: "stop-not-supported" };
|
|
55
|
-
|
|
64
|
+
const deadline = await parts.reader.connection((connection) => readCommandWaitDeadline(connection, intent));
|
|
65
|
+
return settlement(await parts.calls.call(intent.operationId, (signal) => adapterCall({ ...intent, ...deadline }, signal)), intent.capability === "command"
|
|
56
66
|
? commandLimits.resultBytes
|
|
57
67
|
: parts.effects.resultBytes);
|
|
58
68
|
}
|
|
@@ -126,5 +136,8 @@ export function protectedArguments(value) {
|
|
|
126
136
|
method: text(value, "method"),
|
|
127
137
|
target: text(value, "target"),
|
|
128
138
|
payload: text(value, "payload"),
|
|
139
|
+
...(typeof value["commandDeadline"] === "string"
|
|
140
|
+
? { commandDeadline: value["commandDeadline"] }
|
|
141
|
+
: {}),
|
|
129
142
|
};
|
|
130
143
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { operationPhase } from "../../operation-identity.js";
|
|
2
|
+
import { endedCommandWaitCheck } from "../../authority/command-waits.js";
|
|
1
3
|
import { isInstant } from "../../authority/instants.js";
|
|
2
4
|
import { promotions } from "../../authority/leases.js";
|
|
3
5
|
import { execute } from "../../authority/reducer.js";
|
|
@@ -45,7 +47,9 @@ function closure(state, operation) {
|
|
|
45
47
|
return ["run-ended"];
|
|
46
48
|
const exhausted = (state.effects.budgets[operation.runId]?.exhaustedSequence ?? null) !==
|
|
47
49
|
null;
|
|
48
|
-
return exhausted
|
|
50
|
+
return exhausted && operationPhase(operation.operationId) !== "command-wait"
|
|
51
|
+
? ["budget-exhausted"]
|
|
52
|
+
: [];
|
|
49
53
|
}
|
|
50
54
|
function unblocked(state, followUp) {
|
|
51
55
|
const steps = [];
|
|
@@ -95,6 +99,9 @@ const outcomes = {
|
|
|
95
99
|
}),
|
|
96
100
|
completed: (attempt) => stated({
|
|
97
101
|
outcome: "completed",
|
|
102
|
+
...(attempt.worker === "command"
|
|
103
|
+
? { commandOutput: attempt.result }
|
|
104
|
+
: {}),
|
|
98
105
|
result: attempt.result === null ? null : documentDigest(attempt.result),
|
|
99
106
|
reason: attempt.reason,
|
|
100
107
|
...identified(attempt),
|
|
@@ -155,7 +162,9 @@ function acceptedNow(reconciling) {
|
|
|
155
162
|
export function reconciliations(state, reconciling) {
|
|
156
163
|
const accepted = acceptedNow(reconciling);
|
|
157
164
|
const rejected = rejectedReports(reconciling.results);
|
|
158
|
-
const due = (operation) => state.runs[operation.runId]?.status !== "cancelled" &&
|
|
165
|
+
const due = (operation) => state.runs[operation.runId]?.status !== "cancelled" &&
|
|
166
|
+
!endedCommandWaitCheck(state.commandWaits ?? {}, operation.operationId) &&
|
|
167
|
+
live(operation);
|
|
159
168
|
const live = (operation) => (operation.status === "recovering" &&
|
|
160
169
|
!accepted.has(operation.operationId)) ||
|
|
161
170
|
(operation.status === "blocked" && rejected.has(operation.operationId));
|
|
@@ -8,6 +8,10 @@ export interface OperationView extends OperationRow {
|
|
|
8
8
|
}
|
|
9
9
|
export type StoredDisposition = Omit<Evidence, "sequence">;
|
|
10
10
|
export interface EffectQueries {
|
|
11
|
+
readonly workerTurns: (window: {
|
|
12
|
+
readonly after: string;
|
|
13
|
+
readonly through: string;
|
|
14
|
+
}) => Promise<readonly OperationView[]>;
|
|
11
15
|
readonly operation: (operationId: string) => Promise<OperationView | undefined>;
|
|
12
16
|
readonly operations: (runId: string) => Promise<readonly OperationView[]>;
|
|
13
17
|
readonly evidence: (runId: string) => Promise<readonly number[]>;
|
|
@@ -34,7 +34,9 @@ const viewColumns = operationColumns
|
|
|
34
34
|
.map((name) => `o.${name}`)
|
|
35
35
|
.join(", ");
|
|
36
36
|
const waitCause = "CASE WHEN o.status != 'waiting' THEN NULL WHEN r.status != 'running' THEN 'run-not-running' WHEN EXISTS (SELECT 1 FROM leases h WHERE h.resource_key = o.lease_key AND h.state != 'released') THEN 'resource' ELSE 'ready' END";
|
|
37
|
-
const
|
|
37
|
+
const viewSelection = `SELECT ${viewColumns}, l.generation AS lease_generation, ${waitCause} AS wait_cause`;
|
|
38
|
+
const viewJoins = "JOIN runs r ON r.run_id = o.run_id LEFT JOIN leases l ON l.resource_key = o.lease_key AND l.operation_id = o.operation_id AND l.state != 'released'";
|
|
39
|
+
const viewed = `${viewSelection} FROM operations o ${viewJoins}`;
|
|
38
40
|
function operationView(row) {
|
|
39
41
|
return {
|
|
40
42
|
...operationRow(row),
|
|
@@ -52,6 +54,11 @@ async function operations(connection, runId) {
|
|
|
52
54
|
const rows = await connection.all(`${viewed} WHERE o.run_id = ? ORDER BY o.requested_sequence`, [runId]);
|
|
53
55
|
return rows.map(operationView);
|
|
54
56
|
}
|
|
57
|
+
async function workerTurns(connection, window) {
|
|
58
|
+
const settled = await connection.all(`${viewSelection} FROM events e CROSS JOIN operations o ${viewJoins} WHERE o.settled_sequence = e.sequence AND o.capability = 'claude' AND julianday(e.recorded_at) > julianday(?) AND julianday(e.recorded_at) <= julianday(?)`, [window.after, window.through]);
|
|
59
|
+
const open = await connection.all(`${viewSelection} FROM operations o INDEXED BY operations_worker_open ${viewJoins} WHERE o.capability = 'claude' AND o.settled_sequence IS NULL AND o.status NOT IN ('refused', 'completed', 'failed', 'stopped', 'cancelled')`);
|
|
60
|
+
return [...settled, ...open].map(operationView);
|
|
61
|
+
}
|
|
55
62
|
async function evidence(connection, runId) {
|
|
56
63
|
const rows = await connection.all("SELECT e.sequence FROM effect_evidence e JOIN events v ON v.sequence = e.sequence WHERE e.run_id = ? AND (e.disposition IN ('rejected', 'denied', 'refused') OR (v.type = 'operation.reconciled' AND json_extract(v.payload, '$.outcome') = 'unknown')) ORDER BY e.sequence", [runId]);
|
|
57
64
|
return rows.map((row) => integer(row, "sequence"));
|
|
@@ -74,6 +81,7 @@ async function budget(connection, runId) {
|
|
|
74
81
|
}
|
|
75
82
|
export function effectQueries(read, settings) {
|
|
76
83
|
return {
|
|
84
|
+
workerTurns: (window) => read((connection) => workerTurns(connection, window)),
|
|
77
85
|
stops: (runId) => read((connection) => stops(connection, runId)),
|
|
78
86
|
closure: (runId) => read((connection) => storedClosure(connection, { runId, stopLimit: settings.stopLimit })),
|
|
79
87
|
settledAt: (runId) => read((connection) => settledAt(connection, runId)),
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { readCommandWaitDeadline } from "../command-wait-restore.js";
|
|
1
2
|
import { detailColumns, detailRow } from "../../storage/decision-rows.js";
|
|
2
3
|
import { integer, runRow, text, } from "../../storage/domain-rows.js";
|
|
3
4
|
import { storedRun } from "../authority-restore.js";
|
|
@@ -57,6 +58,7 @@ export async function pendingEffect(connection, attempt) {
|
|
|
57
58
|
return {
|
|
58
59
|
...intent,
|
|
59
60
|
purpose,
|
|
61
|
+
...(await readCommandWaitDeadline(connection, intent)),
|
|
60
62
|
inputDigest: text(row, "input_digest"),
|
|
61
63
|
leaseGeneration: integer(row, "generation"),
|
|
62
64
|
capability: text(row, "capability"),
|