@tacuchi/agent-workflow-cli 25.7.0 → 25.9.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/CHANGELOG.md +110 -0
- package/README.md +5 -1
- package/dist/adapters/git-cli.js +311 -24
- package/dist/adapters/git-cli.js.map +1 -1
- package/dist/adapters/node-file-system.js +48 -0
- package/dist/adapters/node-file-system.js.map +1 -1
- package/dist/application/amend-service.js +51 -14
- package/dist/application/amend-service.js.map +1 -1
- package/dist/application/branch-resolver.js +6 -3
- package/dist/application/branch-resolver.js.map +1 -1
- package/dist/application/capability/design-handler.js +124 -43
- package/dist/application/capability/design-handler.js.map +1 -1
- package/dist/application/capability/dispatcher.js +4 -1
- package/dist/application/capability/dispatcher.js.map +1 -1
- package/dist/application/capability/durable-effect.js +3 -0
- package/dist/application/capability/durable-effect.js.map +1 -1
- package/dist/application/capability/readiness.js +26 -10
- package/dist/application/capability/readiness.js.map +1 -1
- package/dist/application/capability/wrapper.js +10 -3
- package/dist/application/capability/wrapper.js.map +1 -1
- package/dist/application/check-branch-service.js +158 -19
- package/dist/application/check-branch-service.js.map +1 -1
- package/dist/application/checkpoint/markdown.js +2 -2
- package/dist/application/checkpoint/markdown.js.map +1 -1
- package/dist/application/checkpoint/state-reader.js +12 -0
- package/dist/application/checkpoint/state-reader.js.map +1 -1
- package/dist/application/checkpoint-service.js +12 -4
- package/dist/application/checkpoint-service.js.map +1 -1
- package/dist/application/checkpoint-write-service.js +91 -17
- package/dist/application/checkpoint-write-service.js.map +1 -1
- package/dist/application/claims-ledger.js +137 -11
- package/dist/application/claims-ledger.js.map +1 -1
- package/dist/application/claims-recovery.js +85 -44
- package/dist/application/claims-recovery.js.map +1 -1
- package/dist/application/database-tool-catalog.js +33 -0
- package/dist/application/database-tool-catalog.js.map +1 -1
- package/dist/application/design/consumer-document.js +2 -2
- package/dist/application/design/consumer-document.js.map +1 -1
- package/dist/application/design/design-content-gate-service.js +20 -2
- package/dist/application/design/design-content-gate-service.js.map +1 -1
- package/dist/application/design/design-gate-service.js +2 -0
- package/dist/application/design/design-gate-service.js.map +1 -1
- package/dist/application/design/design-index-service.js +4 -0
- package/dist/application/design/design-index-service.js.map +1 -1
- package/dist/application/design/design-publish-service.js +1 -4
- package/dist/application/design/design-publish-service.js.map +1 -1
- package/dist/application/design/design-record-service.js +13 -7
- package/dist/application/design/design-record-service.js.map +1 -1
- package/dist/application/design/design-resolver-service.js +22 -3
- package/dist/application/design/design-resolver-service.js.map +1 -1
- package/dist/application/design/design-simple-service.js +24 -5
- package/dist/application/design/design-simple-service.js.map +1 -1
- package/dist/application/design/digest.js +41 -0
- package/dist/application/design/digest.js.map +1 -0
- package/dist/application/dev-only-services.js +171 -27
- package/dist/application/dev-only-services.js.map +1 -1
- package/dist/application/doc-branch-ledger.js +145 -0
- package/dist/application/doc-branch-ledger.js.map +1 -0
- package/dist/application/docs-canon-service.js +1 -1
- package/dist/application/docs-canon-service.js.map +1 -1
- package/dist/application/doctor/dist-integrity.js +113 -0
- package/dist/application/doctor/dist-integrity.js.map +1 -0
- package/dist/application/doctor/hosts.js +5 -2
- package/dist/application/doctor/hosts.js.map +1 -1
- package/dist/application/doctor/prepare.js +4 -1
- package/dist/application/doctor/prepare.js.map +1 -1
- package/dist/application/doctor/provider-installation.js +39 -19
- package/dist/application/doctor/provider-installation.js.map +1 -1
- package/dist/application/doctor/provider-mcps.js +10 -2
- package/dist/application/doctor/provider-mcps.js.map +1 -1
- package/dist/application/doctor/provider-skills.js +25 -0
- package/dist/application/doctor/provider-skills.js.map +1 -1
- package/dist/application/doctor/provider-visibility.js +76 -3
- package/dist/application/doctor/provider-visibility.js.map +1 -1
- package/dist/application/doctor/provider-workspace-block.js +156 -0
- package/dist/application/doctor/provider-workspace-block.js.map +1 -0
- package/dist/application/doctor/repair-runner.js +47 -3
- package/dist/application/doctor/repair-runner.js.map +1 -1
- package/dist/application/doctor/report.js +24 -4
- package/dist/application/doctor/report.js.map +1 -1
- package/dist/application/doctor/skills-toml-migrate.js +76 -0
- package/dist/application/doctor/skills-toml-migrate.js.map +1 -0
- package/dist/application/export-catalog-check.js +200 -0
- package/dist/application/export-catalog-check.js.map +1 -0
- package/dist/application/export-service.js +716 -79
- package/dist/application/export-service.js.map +1 -1
- package/dist/application/fix-git-service.js +285 -64
- package/dist/application/fix-git-service.js.map +1 -1
- package/dist/application/flow/advance.js +241 -30
- package/dist/application/flow/advance.js.map +1 -1
- package/dist/application/flow/annul-service.js +3 -1
- package/dist/application/flow/annul-service.js.map +1 -1
- package/dist/application/flow/batch-commit.js +189 -0
- package/dist/application/flow/batch-commit.js.map +1 -0
- package/dist/application/flow/checkout-observation.js +110 -8
- package/dist/application/flow/checkout-observation.js.map +1 -1
- package/dist/application/flow/close-artifacts.js +105 -0
- package/dist/application/flow/close-artifacts.js.map +1 -0
- package/dist/application/flow/close-at-boundary.js +155 -0
- package/dist/application/flow/close-at-boundary.js.map +1 -0
- package/dist/application/flow/close-document-guidance.js +70 -0
- package/dist/application/flow/close-document-guidance.js.map +1 -0
- package/dist/application/flow/flow-service.js +49 -5
- package/dist/application/flow/flow-service.js.map +1 -1
- package/dist/application/flow/internal-actions.js +361 -80
- package/dist/application/flow/internal-actions.js.map +1 -1
- package/dist/application/flow/internal-drive.js +47 -19
- package/dist/application/flow/internal-drive.js.map +1 -1
- package/dist/application/flow/plan-entry.js +82 -0
- package/dist/application/flow/plan-entry.js.map +1 -0
- package/dist/application/flow/prove.js +32 -1
- package/dist/application/flow/prove.js.map +1 -1
- package/dist/application/flow/quick-checkouts.js +48 -0
- package/dist/application/flow/quick-checkouts.js.map +1 -0
- package/dist/application/flow/reinfer-batch.js +177 -0
- package/dist/application/flow/reinfer-batch.js.map +1 -0
- package/dist/application/flow/reopen-run.js +159 -0
- package/dist/application/flow/reopen-run.js.map +1 -0
- package/dist/application/flow/run-journey.js +11 -8
- package/dist/application/flow/run-journey.js.map +1 -1
- package/dist/application/flow/run-projection.js +16 -5
- package/dist/application/flow/run-projection.js.map +1 -1
- package/dist/application/flow/run-state-service.js +3 -1
- package/dist/application/flow/run-state-service.js.map +1 -1
- package/dist/application/flow/submit.js +731 -154
- package/dist/application/flow/submit.js.map +1 -1
- package/dist/application/generate-launch-service.js +16 -6
- package/dist/application/generate-launch-service.js.map +1 -1
- package/dist/application/git-flow-service.js +34 -3
- package/dist/application/git-flow-service.js.map +1 -1
- package/dist/application/history-publications.js +24 -0
- package/dist/application/history-publications.js.map +1 -1
- package/dist/application/history-reconcile-service.js +45 -0
- package/dist/application/history-reconcile-service.js.map +1 -0
- package/dist/application/history-table.js +61 -12
- package/dist/application/history-table.js.map +1 -1
- package/dist/application/history-update-service.js +25 -4
- package/dist/application/history-update-service.js.map +1 -1
- package/dist/application/hook-branch-check.js +25 -3
- package/dist/application/hook-branch-check.js.map +1 -1
- package/dist/application/hook-git-commit-advisor.js +3 -4
- package/dist/application/hook-git-commit-advisor.js.map +1 -1
- package/dist/application/hook-sql-mutation-guard.js +147 -12
- package/dist/application/hook-sql-mutation-guard.js.map +1 -1
- package/dist/application/hook-turn-start.js +51 -0
- package/dist/application/hook-turn-start.js.map +1 -0
- package/dist/application/host-memory/codex.js +1 -1
- package/dist/application/host-memory/codex.js.map +1 -1
- package/dist/application/hub-registry.js +135 -0
- package/dist/application/hub-registry.js.map +1 -0
- package/dist/application/local-proposal.js +72 -19
- package/dist/application/local-proposal.js.map +1 -1
- package/dist/application/mcp-host-reader.js +1 -1
- package/dist/application/mcp-host-reader.js.map +1 -1
- package/dist/application/mcp-host-writer.js +16 -10
- package/dist/application/mcp-host-writer.js.map +1 -1
- package/dist/application/merge-state-service.js +150 -34
- package/dist/application/merge-state-service.js.map +1 -1
- package/dist/application/multiroot/claude.js +17 -10
- package/dist/application/multiroot/claude.js.map +1 -1
- package/dist/application/multiroot/codex.js +17 -11
- package/dist/application/multiroot/codex.js.map +1 -1
- package/dist/application/multiroot-service.js +52 -28
- package/dist/application/multiroot-service.js.map +1 -1
- package/dist/application/parsers/execution-batches.js +64 -0
- package/dist/application/parsers/execution-batches.js.map +1 -0
- package/dist/application/parsers/phases.js +23 -2
- package/dist/application/parsers/phases.js.map +1 -1
- package/dist/application/parsers/project-block.js +146 -17
- package/dist/application/parsers/project-block.js.map +1 -1
- package/dist/application/parsers/tasks.js +16 -2
- package/dist/application/parsers/tasks.js.map +1 -1
- package/dist/application/parsers/toml.js +19 -0
- package/dist/application/parsers/toml.js.map +1 -0
- package/dist/application/paths-service.js +13 -16
- package/dist/application/paths-service.js.map +1 -1
- package/dist/application/persist-service.js +118 -5
- package/dist/application/persist-service.js.map +1 -1
- package/dist/application/plan-exec-batch-service.js +162 -22
- package/dist/application/plan-exec-batch-service.js.map +1 -1
- package/dist/application/plan-exec-decision-service.js +61 -12
- package/dist/application/plan-exec-decision-service.js.map +1 -1
- package/dist/application/plan-exec-plan-diff.js +105 -0
- package/dist/application/plan-exec-plan-diff.js.map +1 -0
- package/dist/application/plan-lint-service.js +2 -0
- package/dist/application/plan-lint-service.js.map +1 -1
- package/dist/application/plan-passes.js +41 -0
- package/dist/application/plan-passes.js.map +1 -0
- package/dist/application/preparation-receipts.js +58 -0
- package/dist/application/preparation-receipts.js.map +1 -0
- package/dist/application/project-md-upsert-service.js +191 -52
- package/dist/application/project-md-upsert-service.js.map +1 -1
- package/dist/application/project-tab-data.js +40 -10
- package/dist/application/project-tab-data.js.map +1 -1
- package/dist/application/release-data/artifacts.js +15 -7
- package/dist/application/release-data/artifacts.js.map +1 -1
- package/dist/application/release-data/bundles.js +52 -6
- package/dist/application/release-data/bundles.js.map +1 -1
- package/dist/application/release-data/common.js +2 -2
- package/dist/application/release-data/common.js.map +1 -1
- package/dist/application/release-data/rollback.js +7 -0
- package/dist/application/release-data/rollback.js.map +1 -0
- package/dist/application/release-data/sessions.js +2 -2
- package/dist/application/release-data/sessions.js.map +1 -1
- package/dist/application/release-pass-ledger.js +1 -1
- package/dist/application/render/history-row.js +2 -0
- package/dist/application/render/history-row.js.map +1 -1
- package/dist/application/render/project-block.js +28 -11
- package/dist/application/render/project-block.js.map +1 -1
- package/dist/application/reseal-service.js +1 -0
- package/dist/application/reseal-service.js.map +1 -1
- package/dist/application/resume-service.js +55 -8
- package/dist/application/resume-service.js.map +1 -1
- package/dist/application/retirement/apply.js +25 -7
- package/dist/application/retirement/apply.js.map +1 -1
- package/dist/application/retirement/attribution.js +121 -48
- package/dist/application/retirement/attribution.js.map +1 -1
- package/dist/application/retirement/prepare.js +17 -11
- package/dist/application/retirement/prepare.js.map +1 -1
- package/dist/application/retirement/preview.js +2 -1
- package/dist/application/retirement/preview.js.map +1 -1
- package/dist/application/self/codex-plugin.js +1 -1
- package/dist/application/self/codex-plugin.js.map +1 -1
- package/dist/application/self/host-states.js +3 -3
- package/dist/application/self/host-states.js.map +1 -1
- package/dist/application/self/install-hooks.js +1 -1
- package/dist/application/self/install-hooks.js.map +1 -1
- package/dist/application/self/install-skill.js +35 -11
- package/dist/application/self/install-skill.js.map +1 -1
- package/dist/application/self/install-targets.js +73 -2
- package/dist/application/self/install-targets.js.map +1 -1
- package/dist/application/self/mcp-config.js +19 -11
- package/dist/application/self/mcp-config.js.map +1 -1
- package/dist/application/self/opencode-plugin.js +1 -0
- package/dist/application/self/opencode-plugin.js.map +1 -1
- package/dist/application/self/uninstall.js +22 -8
- package/dist/application/self/uninstall.js.map +1 -1
- package/dist/application/semantic-operation/protocol.js +66 -5
- package/dist/application/semantic-operation/protocol.js.map +1 -1
- package/dist/application/session-archive-service.js +113 -0
- package/dist/application/session-archive-service.js.map +1 -0
- package/dist/application/session-binding-service.js +35 -0
- package/dist/application/session-binding-service.js.map +1 -1
- package/dist/application/session-close-service.js +390 -54
- package/dist/application/session-close-service.js.map +1 -1
- package/dist/application/session-create-service.js +97 -5
- package/dist/application/session-create-service.js.map +1 -1
- package/dist/application/session-custody-recorder.js +15 -12
- package/dist/application/session-custody-recorder.js.map +1 -1
- package/dist/application/session-custody-service.js +1 -0
- package/dist/application/session-custody-service.js.map +1 -1
- package/dist/application/session-narrative.js +51 -12
- package/dist/application/session-narrative.js.map +1 -1
- package/dist/application/session-pause-service.js +46 -0
- package/dist/application/session-pause-service.js.map +1 -0
- package/dist/application/session-resolver.js +36 -11
- package/dist/application/session-resolver.js.map +1 -1
- package/dist/application/session-resume-service.js +190 -20
- package/dist/application/session-resume-service.js.map +1 -1
- package/dist/application/sessions-service.js +4 -0
- package/dist/application/sessions-service.js.map +1 -1
- package/dist/application/sessions-sweep-service.js +77 -0
- package/dist/application/sessions-sweep-service.js.map +1 -0
- package/dist/application/settle-service.js +3 -1
- package/dist/application/settle-service.js.map +1 -1
- package/dist/application/skills-resolver-service.js +1 -1
- package/dist/application/skills-resolver-service.js.map +1 -1
- package/dist/application/source-add-service.js +37 -0
- package/dist/application/source-add-service.js.map +1 -0
- package/dist/application/source-boundary-policy.js +97 -8
- package/dist/application/source-boundary-policy.js.map +1 -1
- package/dist/application/source-pipeline.js +68 -0
- package/dist/application/source-pipeline.js.map +1 -0
- package/dist/application/source-remove-service.js +15 -3
- package/dist/application/source-remove-service.js.map +1 -1
- package/dist/application/sources-service.js +71 -16
- package/dist/application/sources-service.js.map +1 -1
- package/dist/application/status-service.js +55 -5
- package/dist/application/status-service.js.map +1 -1
- package/dist/application/unit-dependencies.js +100 -0
- package/dist/application/unit-dependencies.js.map +1 -0
- package/dist/application/unit-membership.js +37 -0
- package/dist/application/unit-membership.js.map +1 -0
- package/dist/application/unit-residue.js +72 -0
- package/dist/application/unit-residue.js.map +1 -0
- package/dist/application/visibility-doctor-service.js +66 -4
- package/dist/application/visibility-doctor-service.js.map +1 -1
- package/dist/application/working-branch-service.js +6 -0
- package/dist/application/working-branch-service.js.map +1 -1
- package/dist/application/workline-graph.js +1 -1
- package/dist/application/workline-graph.js.map +1 -1
- package/dist/application/workline-index-service.js +118 -17
- package/dist/application/workline-index-service.js.map +1 -1
- package/dist/application/workspace-commit-service.js +218 -0
- package/dist/application/workspace-commit-service.js.map +1 -0
- package/dist/application/workspace-init-service.js +64 -34
- package/dist/application/workspace-init-service.js.map +1 -1
- package/dist/application/workspace-local-config.js +90 -0
- package/dist/application/workspace-local-config.js.map +1 -0
- package/dist/application/workspace-materialization-service.js +52 -3
- package/dist/application/workspace-materialization-service.js.map +1 -1
- package/dist/application/workspace-migrate/apply.js +525 -4
- package/dist/application/workspace-migrate/apply.js.map +1 -1
- package/dist/application/workspace-migrate/markers.js +9 -6
- package/dist/application/workspace-migrate/markers.js.map +1 -1
- package/dist/application/workspace-migrate/plan.js +97 -5
- package/dist/application/workspace-migrate/plan.js.map +1 -1
- package/dist/application/workspace-move-service.js +270 -0
- package/dist/application/workspace-move-service.js.map +1 -0
- package/dist/application/workspace-untrack-service.js +28 -0
- package/dist/application/workspace-untrack-service.js.map +1 -0
- package/dist/application/worktree-service.js +654 -105
- package/dist/application/worktree-service.js.map +1 -1
- package/dist/cli/ascii.js +86 -0
- package/dist/cli/ascii.js.map +1 -0
- package/dist/cli/commands/add-source.js +38 -0
- package/dist/cli/commands/add-source.js.map +1 -0
- package/dist/cli/commands/amend.js +14 -2
- package/dist/cli/commands/amend.js.map +1 -1
- package/dist/cli/commands/capability.js +26 -0
- package/dist/cli/commands/capability.js.map +1 -1
- package/dist/cli/commands/check-branch.js +1 -0
- package/dist/cli/commands/check-branch.js.map +1 -1
- package/dist/cli/commands/checkpoint-read.js +1 -0
- package/dist/cli/commands/checkpoint-read.js.map +1 -1
- package/dist/cli/commands/checkpoint-write.js +4 -1
- package/dist/cli/commands/checkpoint-write.js.map +1 -1
- package/dist/cli/commands/claims.js +1 -0
- package/dist/cli/commands/claims.js.map +1 -1
- package/dist/cli/commands/code-scan.js +1 -0
- package/dist/cli/commands/code-scan.js.map +1 -1
- package/dist/cli/commands/context-budget.js +1 -0
- package/dist/cli/commands/context-budget.js.map +1 -1
- package/dist/cli/commands/context-plan.js +1 -0
- package/dist/cli/commands/context-plan.js.map +1 -1
- package/dist/cli/commands/cut-intent.js +1 -0
- package/dist/cli/commands/cut-intent.js.map +1 -1
- package/dist/cli/commands/designs.js +15 -5
- package/dist/cli/commands/designs.js.map +1 -1
- package/dist/cli/commands/dev-only.js +22 -5
- package/dist/cli/commands/dev-only.js.map +1 -1
- package/dist/cli/commands/doc-branch.js +184 -0
- package/dist/cli/commands/doc-branch.js.map +1 -0
- package/dist/cli/commands/doctor.js +9 -0
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/export.js +89 -16
- package/dist/cli/commands/export.js.map +1 -1
- package/dist/cli/commands/fix-git.js +89 -13
- package/dist/cli/commands/fix-git.js.map +1 -1
- package/dist/cli/commands/flow.js +129 -13
- package/dist/cli/commands/flow.js.map +1 -1
- package/dist/cli/commands/generate-launch.js +15 -2
- package/dist/cli/commands/generate-launch.js.map +1 -1
- package/dist/cli/commands/git-flow.js +1 -0
- package/dist/cli/commands/git-flow.js.map +1 -1
- package/dist/cli/commands/history-update.js +7 -9
- package/dist/cli/commands/history-update.js.map +1 -1
- package/dist/cli/commands/history.js +14 -0
- package/dist/cli/commands/history.js.map +1 -0
- package/dist/cli/commands/hook.js +26 -5
- package/dist/cli/commands/hook.js.map +1 -1
- package/dist/cli/commands/host-doctor.js +1 -0
- package/dist/cli/commands/host-doctor.js.map +1 -1
- package/dist/cli/commands/host-memory.js +2 -9
- package/dist/cli/commands/host-memory.js.map +1 -1
- package/dist/cli/commands/index.js +18 -1
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/mcp.js +30 -4
- package/dist/cli/commands/mcp.js.map +1 -1
- package/dist/cli/commands/merge-state.js +3 -2
- package/dist/cli/commands/merge-state.js.map +1 -1
- package/dist/cli/commands/multiroot.js +16 -0
- package/dist/cli/commands/multiroot.js.map +1 -1
- package/dist/cli/commands/persist.js +7 -5
- package/dist/cli/commands/persist.js.map +1 -1
- package/dist/cli/commands/plan.js +1 -0
- package/dist/cli/commands/plan.js.map +1 -1
- package/dist/cli/commands/plugin-cache.js +4 -0
- package/dist/cli/commands/plugin-cache.js.map +1 -1
- package/dist/cli/commands/plugin-doctor.js +3 -0
- package/dist/cli/commands/plugin-doctor.js.map +1 -1
- package/dist/cli/commands/project-md-upsert.js +8 -3
- package/dist/cli/commands/project-md-upsert.js.map +1 -1
- package/dist/cli/commands/release-data.js +12 -0
- package/dist/cli/commands/release-data.js.map +1 -1
- package/dist/cli/commands/release-pass.js +13 -3
- package/dist/cli/commands/release-pass.js.map +1 -1
- package/dist/cli/commands/remove-source.js +1 -0
- package/dist/cli/commands/remove-source.js.map +1 -1
- package/dist/cli/commands/reseal.js +1 -0
- package/dist/cli/commands/reseal.js.map +1 -1
- package/dist/cli/commands/resume-summary.js +5 -0
- package/dist/cli/commands/resume-summary.js.map +1 -1
- package/dist/cli/commands/resume.js +13 -3
- package/dist/cli/commands/resume.js.map +1 -1
- package/dist/cli/commands/retirement.js +1 -0
- package/dist/cli/commands/retirement.js.map +1 -1
- package/dist/cli/commands/self.js +39 -1
- package/dist/cli/commands/self.js.map +1 -1
- package/dist/cli/commands/session-artifacts.js +1 -0
- package/dist/cli/commands/session-artifacts.js.map +1 -1
- package/dist/cli/commands/session-close.js +185 -31
- package/dist/cli/commands/session-close.js.map +1 -1
- package/dist/cli/commands/session-create.js +4 -1
- package/dist/cli/commands/session-create.js.map +1 -1
- package/dist/cli/commands/session-pause.js +14 -0
- package/dist/cli/commands/session-pause.js.map +1 -0
- package/dist/cli/commands/session-resume.js +1 -0
- package/dist/cli/commands/session-resume.js.map +1 -1
- package/dist/cli/commands/sessions.js +16 -2
- package/dist/cli/commands/sessions.js.map +1 -1
- package/dist/cli/commands/set-branch.js +29 -4
- package/dist/cli/commands/set-branch.js.map +1 -1
- package/dist/cli/commands/set-edit-mode.js +20 -0
- package/dist/cli/commands/set-edit-mode.js.map +1 -0
- package/dist/cli/commands/set-pipeline.js +35 -0
- package/dist/cli/commands/set-pipeline.js.map +1 -0
- package/dist/cli/commands/settle.js +1 -0
- package/dist/cli/commands/settle.js.map +1 -1
- package/dist/cli/commands/skill-index.js +1 -0
- package/dist/cli/commands/skill-index.js.map +1 -1
- package/dist/cli/commands/skills.js +1 -0
- package/dist/cli/commands/skills.js.map +1 -1
- package/dist/cli/commands/sources.js +5 -0
- package/dist/cli/commands/sources.js.map +1 -1
- package/dist/cli/commands/stack.js +1 -0
- package/dist/cli/commands/stack.js.map +1 -1
- package/dist/cli/commands/status.js +36 -2
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/tool.js +5 -21
- package/dist/cli/commands/tool.js.map +1 -1
- package/dist/cli/commands/unknown-flags.js +68 -16
- package/dist/cli/commands/unknown-flags.js.map +1 -1
- package/dist/cli/commands/visibility.js +2 -0
- package/dist/cli/commands/visibility.js.map +1 -1
- package/dist/cli/commands/workspace-commit.js +62 -0
- package/dist/cli/commands/workspace-commit.js.map +1 -0
- package/dist/cli/commands/workspace-init.js +51 -2
- package/dist/cli/commands/workspace-init.js.map +1 -1
- package/dist/cli/commands/workspace-migrate.js +31 -14
- package/dist/cli/commands/workspace-migrate.js.map +1 -1
- package/dist/cli/commands/workspace-move.js +42 -0
- package/dist/cli/commands/workspace-move.js.map +1 -0
- package/dist/cli/commands/worktree.js +5 -4
- package/dist/cli/commands/worktree.js.map +1 -1
- package/dist/cli/context-id.js +6 -0
- package/dist/cli/context-id.js.map +1 -1
- package/dist/cli/full-cli.js +555 -0
- package/dist/cli/full-cli.js.map +1 -0
- package/dist/cli/help-groups.js +108 -14
- package/dist/cli/help-groups.js.map +1 -1
- package/dist/cli/hook-stdin-cache.js +12 -0
- package/dist/cli/hook-stdin-cache.js.map +1 -0
- package/dist/cli/main.js +47 -471
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/output-mode.js +11 -2
- package/dist/cli/output-mode.js.map +1 -1
- package/dist/cli/parser.js +18 -5
- package/dist/cli/parser.js.map +1 -1
- package/dist/cli/registry.js.map +1 -1
- package/dist/cli/render.js +30 -1
- package/dist/cli/render.js.map +1 -1
- package/dist/cli/tui/app.js +1 -1
- package/dist/cli/tui/app.js.map +1 -1
- package/dist/cli/tui/components/workspace-init-form.js +4 -1
- package/dist/cli/tui/components/workspace-init-form.js.map +1 -1
- package/dist/cli/tui/data/recommended-skills.js +2 -2
- package/dist/cli/tui/data/recommended-skills.js.map +1 -1
- package/dist/cli/tui/data/workflow-content.js +6 -1
- package/dist/cli/tui/data/workflow-content.js.map +1 -1
- package/dist/cli/tui/tabs/mcp-tab.js +4 -3
- package/dist/cli/tui/tabs/mcp-tab.js.map +1 -1
- package/dist/cli/tui/tabs/project-tab.js +7 -2
- package/dist/cli/tui/tabs/project-tab.js.map +1 -1
- package/dist/dist-manifest.json +4117 -0
- package/dist/domain/capability/protocol.js.map +1 -1
- package/dist/domain/decision-note.js +13 -0
- package/dist/domain/decision-note.js.map +1 -1
- package/dist/domain/design/artifact.js +22 -3
- package/dist/domain/design/artifact.js.map +1 -1
- package/dist/domain/design/capability.js +1 -0
- package/dist/domain/design/capability.js.map +1 -1
- package/dist/domain/design/expansion.js +1 -1
- package/dist/domain/design/expansion.js.map +1 -1
- package/dist/domain/design/maturity.js +16 -0
- package/dist/domain/design/maturity.js.map +1 -1
- package/dist/domain/design/reference.js +5 -0
- package/dist/domain/design/reference.js.map +1 -1
- package/dist/domain/doctor/operations.js +28 -2
- package/dist/domain/doctor/operations.js.map +1 -1
- package/dist/domain/effective-contract.js +3 -1
- package/dist/domain/effective-contract.js.map +1 -1
- package/dist/domain/elicitation.js +1 -1
- package/dist/domain/flow/answer.js +273 -130
- package/dist/domain/flow/answer.js.map +1 -1
- package/dist/domain/flow/authority.js +330 -44
- package/dist/domain/flow/authority.js.map +1 -1
- package/dist/domain/flow/batch-review.js +65 -0
- package/dist/domain/flow/batch-review.js.map +1 -0
- package/dist/domain/flow/decision-schema.js +47 -0
- package/dist/domain/flow/decision-schema.js.map +1 -0
- package/dist/domain/flow/directive.js +16 -0
- package/dist/domain/flow/directive.js.map +1 -1
- package/dist/domain/flow/execution-result.js +169 -9
- package/dist/domain/flow/execution-result.js.map +1 -1
- package/dist/domain/flow/route.js.map +1 -1
- package/dist/domain/flow/rules.js +5 -6
- package/dist/domain/flow/rules.js.map +1 -1
- package/dist/domain/flow/run-state.js +531 -47
- package/dist/domain/flow/run-state.js.map +1 -1
- package/dist/domain/flow/test-run-evidence.js +285 -0
- package/dist/domain/flow/test-run-evidence.js.map +1 -0
- package/dist/domain/flow/unchanged-phase.js +15 -0
- package/dist/domain/flow/unchanged-phase.js.map +1 -0
- package/dist/domain/harnesses.js +22 -6
- package/dist/domain/harnesses.js.map +1 -1
- package/dist/domain/isolation-unit.js +2 -2
- package/dist/domain/isolation-unit.js.map +1 -1
- package/dist/domain/lineage.js +7 -2
- package/dist/domain/lineage.js.map +1 -1
- package/dist/domain/obligation-correspondence.js +4 -2
- package/dist/domain/obligation-correspondence.js.map +1 -1
- package/dist/domain/plan-handoff.js +5 -0
- package/dist/domain/plan-handoff.js.map +1 -0
- package/dist/domain/proposal.js +18 -7
- package/dist/domain/proposal.js.map +1 -1
- package/dist/domain/reservation.js +5 -3
- package/dist/domain/reservation.js.map +1 -1
- package/dist/domain/retirement/proposal.js +1 -0
- package/dist/domain/retirement/proposal.js.map +1 -1
- package/dist/domain/session/custody.js +10 -6
- package/dist/domain/session/custody.js.map +1 -1
- package/dist/domain/session/narrative.js +4 -1
- package/dist/domain/session/narrative.js.map +1 -1
- package/dist/domain/skills.js +2 -0
- package/dist/domain/skills.js.map +1 -1
- package/dist/domain/sql-lexer.js +15 -2
- package/dist/domain/sql-lexer.js.map +1 -1
- package/dist/runtime/namespace-resolver.js +4 -0
- package/dist/runtime/namespace-resolver.js.map +1 -1
- package/dist/runtime/workline-marker.js +35 -8
- package/dist/runtime/workline-marker.js.map +1 -1
- package/dist/runtime/workspace-resolution.js +123 -0
- package/dist/runtime/workspace-resolution.js.map +1 -0
- package/package.json +5 -4
- package/skills/w/SKILL.md +3 -1
- package/skills/w/artifacts/artifacts-core/CHECKPOINT.md +1 -1
- package/skills/w/artifacts/artifacts-core/SCRIPTS.rollback.sql +8 -0
- package/skills/w/artifacts/artifacts-core/SCRIPTS.sql +4 -8
- package/skills/w/commands/export-diagrams.md +3 -3
- package/skills/w/commands/export-manuals.md +6 -6
- package/skills/w/commands/export-reports.md +3 -3
- package/skills/w/commands/export-scripts.md +5 -5
- package/skills/w/commands/fix-git.md +12 -13
- package/skills/w/commands/persist.md +2 -2
- package/skills/w/commands/plan-exec.md +4 -2
- package/skills/w/commands/spec-new.md +1 -1
- package/skills/w/commands/workspace-init.md +2 -0
- package/skills/w/context/MANIFEST.json +1 -1
- package/skills/w/exports/export-diagrams/EXPORT.md +3 -3
- package/skills/w/exports/export-manuals/EXPORT.md +14 -16
- package/skills/w/exports/export-reports/EXPORT.md +3 -3
- package/skills/w/exports/export-scripts/EXPORT.md +45 -21
- package/skills/w/harness/HARNESS.md +5 -3
- package/skills/w/hooks/hooks.template.json +6 -4
- package/skills/w/loops/CHASSIS.md +12 -6
- package/skills/w/loops/CODE-POLICIES.md +7 -4
- package/skills/w/loops/plan-exec-loop/LOOP.md +23 -22
- package/skills/w/loops/plan-new-loop/LOOP.md +23 -31
- package/skills/w/loops/plan-refine-loop/LOOP.md +8 -2
- package/skills/w/loops/quick-loop/LOOP.md +6 -5
- package/skills/w/modules/DESIGN-REFERENCES.md +9 -11
- package/skills/w/modules/PLAN-EXECUTION-BATCHES.md +4 -4
- package/skills/w/modules/SESSION-NUMBERING.md +2 -0
- package/skills/w/roles/design/CONTRACT.md +16 -7
- package/skills/w/roles/design/ROLE.md +4 -2
- package/skills/w/roles/git/ROLE.md +16 -9
- package/skills/w/roles/research/ROLE.md +1 -1
- package/skills/w/roles/sql/ROLE.md +16 -14
- package/skills/w/schemas/design/ui-screen.v1.schema.json +9 -0
|
@@ -26,7 +26,8 @@ import { canonicalJson, semanticDigest } from "../../application/semantic-operat
|
|
|
26
26
|
import { isEffectClass, touchesTheWorld } from "../capability/effects.js";
|
|
27
27
|
import { AttemptLedger } from "../capability/protocol.js";
|
|
28
28
|
import { normalizeObligations, validateDecisionNote } from "../decision-note.js";
|
|
29
|
-
import { journeyOfFlow } from "./authority.js";
|
|
29
|
+
import { expandJourney, journeyOfFlow, } from "./authority.js";
|
|
30
|
+
import { isBatchReview } from "./batch-review.js";
|
|
30
31
|
import { V11_JOURNEY_BASE } from "./journey-baseline.js";
|
|
31
32
|
import { assuranceForRoute, isAssuranceStatus, isRouteDisposition, } from "./route.js";
|
|
32
33
|
/**
|
|
@@ -40,7 +41,7 @@ import { assuranceForRoute, isAssuranceStatus, isRouteDisposition, } from "./rou
|
|
|
40
41
|
* turning the cap off in silence while somebody alternates CLI versions over one
|
|
41
42
|
* run. Failing with a cause is the requirement; failing silently is the defect.
|
|
42
43
|
*/
|
|
43
|
-
export const FLOW_RUN_STATE_VERSION =
|
|
44
|
+
export const FLOW_RUN_STATE_VERSION = 15;
|
|
44
45
|
/**
|
|
45
46
|
* The versions this CLI CONTINUES without adoption, newest first.
|
|
46
47
|
*
|
|
@@ -50,8 +51,23 @@ export const FLOW_RUN_STATE_VERSION = 12;
|
|
|
50
51
|
* cursor, the answers or the attempts. Every later version joins this set with its own
|
|
51
52
|
* upgrade step, which is what keeps "v11 or later survives an update" true
|
|
52
53
|
* without an exception per release.
|
|
54
|
+
*
|
|
55
|
+
* v13 added `reentries` and the `reentry_iteration` of attempts, observations and
|
|
56
|
+
* events. All three are absent on a run that never re-entered, which is every
|
|
57
|
+
* v12 run, so its upgrade step only re-stamps the version.
|
|
58
|
+
* It also added each batch's `base` and `credit`, a reseated run's `inherited_bases`
|
|
59
|
+
* and the `route-refused` trace kind. A v12 run has none of them either, and a
|
|
60
|
+
* batch without `base` is read as the one that was in flight when the CLI updated.
|
|
53
61
|
*/
|
|
54
|
-
|
|
62
|
+
// v14 adds batch reviews, signal retractions and QUICK checkout observations.
|
|
63
|
+
// Older observations and events remain unchanged.
|
|
64
|
+
export const FLOW_RUN_STATE_CONTINUABLE = [
|
|
65
|
+
FLOW_RUN_STATE_VERSION,
|
|
66
|
+
14,
|
|
67
|
+
13,
|
|
68
|
+
12,
|
|
69
|
+
11,
|
|
70
|
+
];
|
|
55
71
|
/**
|
|
56
72
|
* The versions this CLI READS, newest first.
|
|
57
73
|
*
|
|
@@ -75,6 +91,14 @@ export const FLOW_RUN_STATE_READABLE = [
|
|
|
75
91
|
*/
|
|
76
92
|
const CONTINUABLE_UPGRADES = {
|
|
77
93
|
11: (state) => ({ ...state, version: 12, journey_base: [...V11_JOURNEY_BASE[state.flow]] }),
|
|
94
|
+
12: (state) => ({ ...state, version: 13 }),
|
|
95
|
+
// Historical reviews are never fabricated. A still-open batch must supply one.
|
|
96
|
+
13: (state) => ({ ...state, version: 14 }),
|
|
97
|
+
14: (state) => ({
|
|
98
|
+
...state,
|
|
99
|
+
version: 15,
|
|
100
|
+
...(state.scope ? { scope: { isolation: "unit", ...state.scope } } : {}),
|
|
101
|
+
}),
|
|
78
102
|
};
|
|
79
103
|
/** The CLI-owned run state inside the session folder. Machine-local, dotted. */
|
|
80
104
|
export const FLOW_RUN_STATE_FILE = ".flow-run.json";
|
|
@@ -111,12 +135,47 @@ export function attemptsAt(state, transition) {
|
|
|
111
135
|
}
|
|
112
136
|
/** The monotone-counter key for one boundary, scoped when that boundary repeats in a batch. */
|
|
113
137
|
export function attemptCounterKey(state, transition) {
|
|
114
|
-
|
|
115
|
-
return attemptCounterKeyForIteration(transition, iteration ?? undefined);
|
|
138
|
+
return attemptCounterKeyForIteration(transition, iterationOf(state, transition));
|
|
116
139
|
}
|
|
117
|
-
/** Stable counter key for a historical attempt whose
|
|
140
|
+
/** Stable counter key for a historical attempt whose iteration is recorded on the row. */
|
|
118
141
|
export function attemptCounterKeyForIteration(transition, iteration) {
|
|
119
|
-
|
|
142
|
+
const batch = iteration.batch_iteration === undefined ? "" : `@batch-${iteration.batch_iteration}`;
|
|
143
|
+
const reentry = iteration.reentry_iteration === undefined ? "" : `@reentry-${iteration.reentry_iteration}`;
|
|
144
|
+
return `${transition}${batch}${reentry}`;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* The iteration of `transition` where the run stands: its batch copy and its
|
|
148
|
+
* reentry copy. Spread it into any record keyed per boundary.
|
|
149
|
+
*/
|
|
150
|
+
export function iterationOf(state, transition) {
|
|
151
|
+
const batch = currentBatchIteration(state, transition);
|
|
152
|
+
const reentry = currentReentryIteration(state, transition);
|
|
153
|
+
return {
|
|
154
|
+
...(batch === null ? {} : { batch_iteration: batch }),
|
|
155
|
+
...(reentry === null ? {} : { reentry_iteration: reentry }),
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
/** Whether a persisted record belongs to this iteration of its boundary. */
|
|
159
|
+
export function sameIteration(record, iteration) {
|
|
160
|
+
return (record.batch_iteration === iteration.batch_iteration &&
|
|
161
|
+
record.reentry_iteration === iteration.reentry_iteration);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Which reentry inserted the row of `transition` the cursor is on, or `null` on
|
|
165
|
+
* the row's own place. Read at the cursor and backwards from it, so it answers
|
|
166
|
+
* the same before the row is applied and right after.
|
|
167
|
+
*/
|
|
168
|
+
export function currentReentryIteration(state, transition) {
|
|
169
|
+
if ((state.reentries ?? []).length === 0)
|
|
170
|
+
return null;
|
|
171
|
+
const { rows, copies } = expandJourney(state);
|
|
172
|
+
for (let index = Math.min(state.applied.length, rows.length - 1); index >= 0; index -= 1) {
|
|
173
|
+
if (rows[index]?.id !== transition)
|
|
174
|
+
continue;
|
|
175
|
+
const copy = copies[index] ?? 0;
|
|
176
|
+
return copy === 0 ? null : copy;
|
|
177
|
+
}
|
|
178
|
+
return null;
|
|
120
179
|
}
|
|
121
180
|
/**
|
|
122
181
|
* The three numbers and the difference between them, computed once.
|
|
@@ -127,15 +186,28 @@ export function attemptCounterKeyForIteration(transition, iteration) {
|
|
|
127
186
|
* directive and the recovery guard would end up disagreeing about the same run.
|
|
128
187
|
*/
|
|
129
188
|
function spendAt(state, transition) {
|
|
130
|
-
const iteration =
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
189
|
+
const iteration = iterationOf(state, transition);
|
|
190
|
+
const recorded = state.attempts.filter((attempt) => attempt.transition === transition && sameIteration(attempt, iteration));
|
|
191
|
+
const seen = new Set();
|
|
192
|
+
const rows = recorded.filter((attempt) => {
|
|
193
|
+
const key = `${attempt.invocation_id}:${attempt.attempt}:${attempt.request_digest}`;
|
|
194
|
+
if (seen.has(key))
|
|
195
|
+
return false;
|
|
196
|
+
seen.add(key);
|
|
197
|
+
return true;
|
|
198
|
+
});
|
|
135
199
|
const key = attemptCounterKey(state, transition);
|
|
136
|
-
|
|
200
|
+
// Old runs may hold a twin row and a counter raised over that twin. Removing
|
|
201
|
+
// both copies of the same resend from the reading preserves the anti-rollback
|
|
202
|
+
// excess, which is the portion the monotone floor still has to protect.
|
|
203
|
+
const floor = Math.max(0, (state.attempt_floor?.[key] ?? 0) - (recorded.length - rows.length));
|
|
137
204
|
const granted = state.attempt_grants?.[key] ?? 0;
|
|
138
|
-
return {
|
|
205
|
+
return {
|
|
206
|
+
rows,
|
|
207
|
+
floor,
|
|
208
|
+
granted,
|
|
209
|
+
spent: Math.max(0, Math.max(rows.filter((row) => row.approval !== true).length, floor) - granted),
|
|
210
|
+
};
|
|
139
211
|
}
|
|
140
212
|
/**
|
|
141
213
|
* The whole accounting of one transition, conflicts named and answerability read.
|
|
@@ -150,23 +222,24 @@ export function attemptAccountingAt(state, transition) {
|
|
|
150
222
|
// — and a projection that disagrees with the state it describes is the very
|
|
151
223
|
// thing this reading exists to stop. It cannot mask a real divergence: a
|
|
152
224
|
// counter that runs AHEAD of the rows stays ahead of this maximum.
|
|
153
|
-
const
|
|
225
|
+
const paid = rows.filter((row) => row.approval !== true).length;
|
|
226
|
+
const floor = Math.max(read, paid);
|
|
154
227
|
const ordinals = rows.map((attempt) => attempt.attempt);
|
|
155
228
|
const conflicts = [];
|
|
156
|
-
if (floor >
|
|
229
|
+
if (floor > paid) {
|
|
157
230
|
conflicts.push({
|
|
158
231
|
between: [
|
|
159
232
|
{ name: "attempt_floor", value: floor },
|
|
160
|
-
{ name: "attempts", value:
|
|
233
|
+
{ name: "attempts", value: paid },
|
|
161
234
|
],
|
|
162
235
|
cause: "el contador monótono declara más intentos que las filas persistidas: o se restauró una copia anterior del ledger, o una escritura murió entre el contador y el estado",
|
|
163
236
|
});
|
|
164
237
|
}
|
|
165
|
-
if (granted > Math.max(
|
|
238
|
+
if (granted > Math.max(paid, floor)) {
|
|
166
239
|
conflicts.push({
|
|
167
240
|
between: [
|
|
168
241
|
{ name: "attempt_grants", value: granted },
|
|
169
|
-
{ name: "attempts", value: Math.max(
|
|
242
|
+
{ name: "attempts", value: Math.max(paid, floor) },
|
|
170
243
|
],
|
|
171
244
|
cause: "se perdonan más intentos de los que esta transición llegó a registrar",
|
|
172
245
|
});
|
|
@@ -228,7 +301,8 @@ export function reconcileAttemptsAt(state, transition) {
|
|
|
228
301
|
};
|
|
229
302
|
}
|
|
230
303
|
const { rows, floor: read, granted, spent } = spendAt(state, transition);
|
|
231
|
-
const
|
|
304
|
+
const paid = rows.filter((row) => row.approval !== true).length;
|
|
305
|
+
const floor = Math.max(read, paid);
|
|
232
306
|
const accounting = attemptAccountingAt(state, transition);
|
|
233
307
|
const repairs = [];
|
|
234
308
|
// What is repaired is the EFFECTIVE spend, not the raw difference between the
|
|
@@ -237,7 +311,7 @@ export function reconcileAttemptsAt(state, transition) {
|
|
|
237
311
|
// against that difference would forgive it again on every single advance and
|
|
238
312
|
// quietly remove the cap. Written against the spend, the second reading finds
|
|
239
313
|
// `spent === rows` and has nothing to do.
|
|
240
|
-
const unforgiven = spent -
|
|
314
|
+
const unforgiven = spent - paid;
|
|
241
315
|
if (unforgiven > 0) {
|
|
242
316
|
repairs.push({
|
|
243
317
|
rule: "forgive-counter-excess",
|
|
@@ -247,7 +321,7 @@ export function reconcileAttemptsAt(state, transition) {
|
|
|
247
321
|
after: granted + unforgiven,
|
|
248
322
|
});
|
|
249
323
|
}
|
|
250
|
-
const recorded = Math.max(
|
|
324
|
+
const recorded = Math.max(paid, floor);
|
|
251
325
|
if (granted > recorded) {
|
|
252
326
|
repairs.push({
|
|
253
327
|
rule: "clamp-grants",
|
|
@@ -287,10 +361,11 @@ function conflictCause(accounting, field) {
|
|
|
287
361
|
function repeatedOrdinal(state) {
|
|
288
362
|
const seen = new Map();
|
|
289
363
|
for (const row of state.attempts) {
|
|
290
|
-
const ordinals = seen.get(row.invocation_id) ?? new
|
|
291
|
-
|
|
364
|
+
const ordinals = seen.get(row.invocation_id) ?? new Map();
|
|
365
|
+
const previous = ordinals.get(row.attempt);
|
|
366
|
+
if (previous !== undefined && previous !== row.request_digest)
|
|
292
367
|
return row.attempt;
|
|
293
|
-
ordinals.
|
|
368
|
+
ordinals.set(row.attempt, row.request_digest);
|
|
294
369
|
seen.set(row.invocation_id, ordinals);
|
|
295
370
|
}
|
|
296
371
|
return null;
|
|
@@ -316,11 +391,10 @@ export function applyAttemptReconciliation(state, reconciliation) {
|
|
|
316
391
|
grants[key] = repair.after;
|
|
317
392
|
next = sealRunState({ ...withoutSeal(next), attempt_grants: grants });
|
|
318
393
|
}
|
|
319
|
-
const iteration = currentBatchIteration(next, reconciliation.transition);
|
|
320
394
|
return withEvent(next, {
|
|
321
395
|
kind: "reconciled",
|
|
322
396
|
transition: reconciliation.transition,
|
|
323
|
-
...(
|
|
397
|
+
...iterationOf(next, reconciliation.transition),
|
|
324
398
|
operation: "flow.attempt-reconciliation",
|
|
325
399
|
repairs: reconciliation.repairs,
|
|
326
400
|
});
|
|
@@ -349,12 +423,8 @@ function unanswerableAt(state) {
|
|
|
349
423
|
}
|
|
350
424
|
return null;
|
|
351
425
|
}
|
|
352
|
-
export function recoveryBlockedAt(state, transition) {
|
|
353
|
-
const
|
|
354
|
-
const trace = state.events.filter((event) => event.transition === transition &&
|
|
355
|
-
(iteration === null
|
|
356
|
-
? event.batch_iteration === undefined
|
|
357
|
-
: event.batch_iteration === iteration));
|
|
426
|
+
export function recoveryBlockedAt(state, transition, iteration = iterationOf(state, transition)) {
|
|
427
|
+
const trace = state.events.filter((event) => event.transition === transition && sameIteration(event, iteration));
|
|
358
428
|
const material = [...trace].reverse().find(declaresMaterialEffect);
|
|
359
429
|
if (material !== undefined)
|
|
360
430
|
return { reason: "materialized", event: material };
|
|
@@ -377,7 +447,9 @@ function declaresMaterialEffect(event) {
|
|
|
377
447
|
// more block a recovery than reading the file could.
|
|
378
448
|
if (event.kind === "reconciled" ||
|
|
379
449
|
event.kind === "aligned" ||
|
|
450
|
+
event.kind === "route-refused" ||
|
|
380
451
|
event.kind === "restarted" ||
|
|
452
|
+
event.kind === "retracted" ||
|
|
381
453
|
event.kind === "annulled") {
|
|
382
454
|
return false;
|
|
383
455
|
}
|
|
@@ -417,6 +489,7 @@ export const PLAN_EXEC_BATCH_STAGES = [
|
|
|
417
489
|
"deviation",
|
|
418
490
|
"validating",
|
|
419
491
|
"reviewing",
|
|
492
|
+
"batch-committing",
|
|
420
493
|
"closed",
|
|
421
494
|
"committing",
|
|
422
495
|
"integrating",
|
|
@@ -634,6 +707,101 @@ export function upgradeContinuable(state) {
|
|
|
634
707
|
}
|
|
635
708
|
return sealRunState(withoutSeal(current));
|
|
636
709
|
}
|
|
710
|
+
/** Record a reentry of the journey, after every one already recorded. */
|
|
711
|
+
export function withReentry(state, reentry) {
|
|
712
|
+
return sealRunState({
|
|
713
|
+
...withoutSeal(state),
|
|
714
|
+
reentries: [...(state.reentries ?? []), reentry],
|
|
715
|
+
});
|
|
716
|
+
}
|
|
717
|
+
/**
|
|
718
|
+
* Take back the last reentry, for the close that recorded its intention and then
|
|
719
|
+
* could not happen. The field goes back to absent when it empties, so the run
|
|
720
|
+
* serializes the bytes it had before the intention.
|
|
721
|
+
*/
|
|
722
|
+
export function withoutLastReentry(state) {
|
|
723
|
+
const { reentries: _all, ...rest } = withoutSeal(state);
|
|
724
|
+
const kept = (state.reentries ?? []).slice(0, -1);
|
|
725
|
+
return sealRunState(kept.length === 0 ? rest : { ...rest, reentries: kept });
|
|
726
|
+
}
|
|
727
|
+
/** Seal the base of one batch; a batch that already has one keeps it. */
|
|
728
|
+
export function withPlanExecBatchBase(state, batchId, base) {
|
|
729
|
+
const batches = state.batches ?? [];
|
|
730
|
+
const target = batches.find((batch) => batch.id === batchId);
|
|
731
|
+
// A re-run of the acquisition on the same batch must not move its base: the
|
|
732
|
+
// batch would then be compared against its own half-done work.
|
|
733
|
+
if (target === undefined || target.base !== undefined)
|
|
734
|
+
return state;
|
|
735
|
+
return sealRunState({
|
|
736
|
+
...withoutSeal(state),
|
|
737
|
+
batches: batches.map((batch) => (batch.id === batchId ? { ...batch, base } : batch)),
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
/** Record the proofs that credited one batch. */
|
|
741
|
+
export function withPlanExecBatchCredit(state, batchId, credit) {
|
|
742
|
+
const batches = state.batches ?? [];
|
|
743
|
+
if (!batches.some((batch) => batch.id === batchId))
|
|
744
|
+
return state;
|
|
745
|
+
return sealRunState({
|
|
746
|
+
...withoutSeal(state),
|
|
747
|
+
batches: batches.map((batch) => batch.id === batchId ? { ...batch, credit, credit_phases: [...batch.phases] } : batch),
|
|
748
|
+
});
|
|
749
|
+
}
|
|
750
|
+
export function withPlanExecBatchUpdate(state, id, update) {
|
|
751
|
+
return sealRunState({
|
|
752
|
+
...withoutSeal(state),
|
|
753
|
+
batches: (state.batches ?? []).map((batch) => (batch.id === id ? update(batch) : batch)),
|
|
754
|
+
});
|
|
755
|
+
}
|
|
756
|
+
/** Re-seal the SAME unpublished batch; old validation/review cannot credit a new base. */
|
|
757
|
+
export function withReinferredPlanExecBatch(state, batchId, planDigest, anchor) {
|
|
758
|
+
const replaced = withPlanExecBatchUpdate(state, batchId, (batch) => {
|
|
759
|
+
const { credit: _credit, credit_phases: _phases, review: _review, commit_proposal: _proposal, ...rest } = batch;
|
|
760
|
+
return { ...rest, plan_digest: planDigest, stage: "inferred" };
|
|
761
|
+
});
|
|
762
|
+
const traced = withPlanExecBatchStage(replaced, batchId, "inferred", "plan-exec.batch-inference", "entered");
|
|
763
|
+
if (anchor === null)
|
|
764
|
+
return traced;
|
|
765
|
+
const reentered = withReentry(traced, {
|
|
766
|
+
kind: "reinfer",
|
|
767
|
+
transition: anchor,
|
|
768
|
+
occurrence: state.applied.filter((id) => id === anchor).length + 1,
|
|
769
|
+
from: "plan-exec.validation-execution",
|
|
770
|
+
});
|
|
771
|
+
return withPendingAction(withBoundary(reentered, "plan-exec.validation-execution"), null);
|
|
772
|
+
}
|
|
773
|
+
/** Old runs that closed even one batch without a commit result stay on the old tail. */
|
|
774
|
+
export function legacyPlanExecCommits(state) {
|
|
775
|
+
if (state.skipped.includes("plan-exec.batch-commit-proposal"))
|
|
776
|
+
return true;
|
|
777
|
+
const acquired = state.applied.filter((transition) => transition === "plan-exec.unit-acquisition").length;
|
|
778
|
+
return (state.batches ?? []).some((batch) => (batch.published_plan_digest !== undefined && batch.commit_result === undefined) ||
|
|
779
|
+
(batch.iteration === state.batch_loop?.iteration &&
|
|
780
|
+
batch.snapshot === undefined &&
|
|
781
|
+
acquired >= batch.iteration));
|
|
782
|
+
}
|
|
783
|
+
/** Record only the current iteration's review, never borrowing one from a prior batch. */
|
|
784
|
+
export function withPlanExecBatchReview(state, review) {
|
|
785
|
+
return sealRunState({
|
|
786
|
+
...withoutSeal(state),
|
|
787
|
+
batches: (state.batches ?? []).map((batch) => batch.iteration === state.batch_loop?.iteration ? { ...batch, review } : batch),
|
|
788
|
+
});
|
|
789
|
+
}
|
|
790
|
+
/** A legacy close may have passed the old untyped review. Insert a fresh, answerable copy. */
|
|
791
|
+
export function withPendingBatchReview(state) {
|
|
792
|
+
const review = "plan-exec.review-findings";
|
|
793
|
+
if (state.flow !== "plan-exec" || state.boundary !== "plan-exec.batch-close")
|
|
794
|
+
return state;
|
|
795
|
+
const batch = (state.batches ?? []).find((entry) => entry.published_plan_digest === undefined);
|
|
796
|
+
if (batch === undefined || batch.review !== undefined)
|
|
797
|
+
return state;
|
|
798
|
+
return withBoundary(withReentry(state, {
|
|
799
|
+
kind: "review",
|
|
800
|
+
transition: "plan-exec.batch-close",
|
|
801
|
+
from: review,
|
|
802
|
+
occurrence: state.applied.filter((id) => id === "plan-exec.batch-close").length + 1,
|
|
803
|
+
}), review);
|
|
804
|
+
}
|
|
637
805
|
/** Record one inferred or declared batch, refusing duplicate ids at the caller's boundary. */
|
|
638
806
|
export function withPlanExecBatch(state, batch) {
|
|
639
807
|
const batches = state.batches ?? [];
|
|
@@ -697,6 +865,7 @@ const PLAN_EXEC_BATCH_STAGE_BY_TRANSITION = {
|
|
|
697
865
|
"plan-exec.deviation-recognition": "deviation",
|
|
698
866
|
"plan-exec.validation-execution": "validating",
|
|
699
867
|
"plan-exec.review-findings": "reviewing",
|
|
868
|
+
"plan-exec.batch-commit": "batch-committing",
|
|
700
869
|
// These only occur after the final batch publication. They therefore extend
|
|
701
870
|
// the last closed batch's trace instead of fabricating a new one for Git/done.
|
|
702
871
|
"plan-exec.final-validation": "validating",
|
|
@@ -772,6 +941,9 @@ export const PLAN_EXEC_BATCH_LOOP_TRANSITIONS = new Set([
|
|
|
772
941
|
"plan-exec.validation-execution",
|
|
773
942
|
"plan-exec.deferred-check",
|
|
774
943
|
"plan-exec.review-findings",
|
|
944
|
+
"plan-exec.batch-commit-proposal",
|
|
945
|
+
"plan-exec.batch-commit-authorization",
|
|
946
|
+
"plan-exec.batch-commit",
|
|
775
947
|
"plan-exec.batch-close",
|
|
776
948
|
]);
|
|
777
949
|
/** Seal the plan bytes the batch publication actually produced. */
|
|
@@ -817,6 +989,33 @@ export function withPlanExecBatchPublicationPrepared(state, batchId, publication
|
|
|
817
989
|
export function withHandoff(state, handoff) {
|
|
818
990
|
return sealRunState({ ...withoutSeal(state), handoff });
|
|
819
991
|
}
|
|
992
|
+
export function withPlanExecEntry(state, entry) {
|
|
993
|
+
return sealRunState({ ...withoutSeal(state), plan_exec_entry: entry });
|
|
994
|
+
}
|
|
995
|
+
export function withDecisionDate(state, date) {
|
|
996
|
+
return state.decision_date === date
|
|
997
|
+
? state
|
|
998
|
+
: sealRunState({ ...withoutSeal(state), decision_date: date });
|
|
999
|
+
}
|
|
1000
|
+
/** Both the human exit and the structural rule deliver the same recoverable destination. */
|
|
1001
|
+
export function planRefineHandoff(state, decisions, selection) {
|
|
1002
|
+
const plan = state.scope?.plan ?? state.plan_exec_entry?.plan ?? null;
|
|
1003
|
+
const packageBody = {
|
|
1004
|
+
plan,
|
|
1005
|
+
observations: state.observations.filter((observation) => observation.transition.startsWith("plan-exec.entry-") ||
|
|
1006
|
+
observation.transition.startsWith("plan-exec.deviation-")),
|
|
1007
|
+
decisions: plan === null
|
|
1008
|
+
? { ...decisions, recovery: "nombrá el plan que debe refinar /w:plan-refine <plan>" }
|
|
1009
|
+
: decisions,
|
|
1010
|
+
selection,
|
|
1011
|
+
};
|
|
1012
|
+
return {
|
|
1013
|
+
destination: "plan-refine",
|
|
1014
|
+
command: plan === null ? "/w:plan-refine <plan>" : `/w:plan-refine ${plan}`,
|
|
1015
|
+
package: packageBody,
|
|
1016
|
+
package_digest: semanticDigest(packageBody),
|
|
1017
|
+
};
|
|
1018
|
+
}
|
|
820
1019
|
/** Persist the gate's executable consequence before the run leaves that boundary. */
|
|
821
1020
|
export function withSelectedChoice(state, selected) {
|
|
822
1021
|
return sealRunState({ ...withoutSeal(state), selected_choice: selected });
|
|
@@ -837,6 +1036,72 @@ export function withDecisionPreparation(state, preparation) {
|
|
|
837
1036
|
export function withFixPreview(state, preview) {
|
|
838
1037
|
return sealRunState({ ...withoutSeal(state), fix_preview: preview });
|
|
839
1038
|
}
|
|
1039
|
+
export function withQuickCheckouts(state, checkouts) {
|
|
1040
|
+
if (checkouts === null && state.quick_checkouts === undefined)
|
|
1041
|
+
return state;
|
|
1042
|
+
return state.flow === "quick"
|
|
1043
|
+
? sealRunState({ ...withoutSeal(state), quick_checkouts: checkouts })
|
|
1044
|
+
: state;
|
|
1045
|
+
}
|
|
1046
|
+
/** Remove a mistaken signal only before any of its consumers has used it. */
|
|
1047
|
+
export function retractSignal(state, journey, signal) {
|
|
1048
|
+
const producers = journey.filter((row) => row.signals?.includes(signal)).map((row) => row.id);
|
|
1049
|
+
const consumers = journey.filter((row) => {
|
|
1050
|
+
const rule = row.condition?.threshold;
|
|
1051
|
+
return (rule !== undefined &&
|
|
1052
|
+
producers.includes(rule.observed) &&
|
|
1053
|
+
(rule.of === undefined || rule.of.includes(signal)));
|
|
1054
|
+
});
|
|
1055
|
+
if (producers.length === 0 || consumers.length === 0) {
|
|
1056
|
+
return {
|
|
1057
|
+
ok: false,
|
|
1058
|
+
failure: {
|
|
1059
|
+
code: "FLOW_RETRACT_SIGNAL_UNKNOWN",
|
|
1060
|
+
message: `la señal '${signal}' no tiene un consumidor retirable en este recorrido`,
|
|
1061
|
+
action: "usá una señal declarada por el recorrido y consumida por una condición pendiente",
|
|
1062
|
+
},
|
|
1063
|
+
};
|
|
1064
|
+
}
|
|
1065
|
+
const removed = state.observations.filter((item) => item.signals.includes(signal) && sameIteration(item, iterationOf(state, item.transition)));
|
|
1066
|
+
if (removed.length === 0)
|
|
1067
|
+
return { ok: true, state };
|
|
1068
|
+
const consumed = consumers.find((row) => removed.some((observation) => signalWasConsumed(state, row, observation)));
|
|
1069
|
+
if (consumed !== undefined) {
|
|
1070
|
+
return {
|
|
1071
|
+
ok: false,
|
|
1072
|
+
failure: {
|
|
1073
|
+
code: "FLOW_RETRACT_ALREADY_CONSUMED",
|
|
1074
|
+
message: `'${consumed.id}' ya aplicó o dejó una ejecución sin resolver; no se retira '${signal}'`,
|
|
1075
|
+
action: "conservá la señal: retirar no revierte decisiones ni efectos ya ejercidos",
|
|
1076
|
+
},
|
|
1077
|
+
};
|
|
1078
|
+
}
|
|
1079
|
+
const updated = sealRunState({
|
|
1080
|
+
...withoutSeal(state),
|
|
1081
|
+
observations: state.observations.map((item) => removed.includes(item)
|
|
1082
|
+
? { ...item, signals: item.signals.filter((value) => value !== signal) }
|
|
1083
|
+
: item),
|
|
1084
|
+
});
|
|
1085
|
+
return {
|
|
1086
|
+
ok: true,
|
|
1087
|
+
state: withEvent(updated, {
|
|
1088
|
+
kind: "retracted",
|
|
1089
|
+
transition: state.boundary ?? producers[0] ?? "",
|
|
1090
|
+
...iterationOf(state, state.boundary ?? producers[0] ?? ""),
|
|
1091
|
+
operation: "flow.retract",
|
|
1092
|
+
signal,
|
|
1093
|
+
observations: removed,
|
|
1094
|
+
}),
|
|
1095
|
+
};
|
|
1096
|
+
}
|
|
1097
|
+
function signalWasConsumed(state, consumer, observation) {
|
|
1098
|
+
if (consumer.condition?.threshold.observed !== observation.transition)
|
|
1099
|
+
return false;
|
|
1100
|
+
// Only a consumer after THIS producer occurrence can have consumed its signal.
|
|
1101
|
+
const producer = state.applied.lastIndexOf(observation.transition);
|
|
1102
|
+
const consumed = state.applied.slice(producer + 1).includes(consumer.id);
|
|
1103
|
+
return consumed || recoveryBlockedAt(state, consumer.id, observation) !== null;
|
|
1104
|
+
}
|
|
840
1105
|
/**
|
|
841
1106
|
* Record what the closure owes — written once, when the batch loop ends.
|
|
842
1107
|
*
|
|
@@ -954,7 +1219,7 @@ export function restatesLastEvent(state, event) {
|
|
|
954
1219
|
if (last === undefined || last.kind !== "failed" || event.kind !== "failed")
|
|
955
1220
|
return false;
|
|
956
1221
|
return (last.transition === event.transition &&
|
|
957
|
-
last
|
|
1222
|
+
sameIteration(last, event) &&
|
|
958
1223
|
last.code === event.code &&
|
|
959
1224
|
last.message === event.message);
|
|
960
1225
|
}
|
|
@@ -975,7 +1240,7 @@ export function restatesLastEvent(state, event) {
|
|
|
975
1240
|
*/
|
|
976
1241
|
export function withObservation(state, observation) {
|
|
977
1242
|
const repeated = state.observations.some((past) => past.transition === observation.transition &&
|
|
978
|
-
past
|
|
1243
|
+
sameIteration(past, observation) &&
|
|
979
1244
|
sameSignals(past.signals, observation.signals));
|
|
980
1245
|
if (repeated)
|
|
981
1246
|
return state;
|
|
@@ -1310,6 +1575,9 @@ function checkRecordShape(parsed, invalid) {
|
|
|
1310
1575
|
if (version >= 12 && !isStringArray(parsed.journey_base)) {
|
|
1311
1576
|
return invalid("no dice contra qué recorrido se escribió su cursor");
|
|
1312
1577
|
}
|
|
1578
|
+
if (!isReentryArray(parsed.reentries)) {
|
|
1579
|
+
return invalid("declara una reentrada sin tipo, frontera, ocurrencia u origen");
|
|
1580
|
+
}
|
|
1313
1581
|
if (parsed.exhausted_reruns !== undefined && !isStringArray(parsed.exhausted_reruns)) {
|
|
1314
1582
|
return invalid("declara vueltas de fronteras agotadas que no son transiciones");
|
|
1315
1583
|
}
|
|
@@ -1350,8 +1618,91 @@ function checkCommonRecordShape(parsed, invalid) {
|
|
|
1350
1618
|
if (!isCounterMap(parsed.attempt_floor) || !isCounterMap(parsed.attempt_grants)) {
|
|
1351
1619
|
return invalid("trae una contabilidad de intentos que no es un contador por transición");
|
|
1352
1620
|
}
|
|
1621
|
+
if (!isInheritedBaseArray(parsed.inherited_bases)) {
|
|
1622
|
+
return invalid("hereda una base de batch sin sus fases o sin sus fuentes");
|
|
1623
|
+
}
|
|
1624
|
+
if (!isPlanExecEntry(parsed.plan_exec_entry)) {
|
|
1625
|
+
return invalid("declara una entrada de plan-exec sin plan o con fases inválidas");
|
|
1626
|
+
}
|
|
1627
|
+
if (parsed.decision_date !== undefined &&
|
|
1628
|
+
(typeof parsed.decision_date !== "string" || !/^\d{4}-\d{2}-\d{2}$/.test(parsed.decision_date))) {
|
|
1629
|
+
return invalid("declara una fecha de decisión inválida");
|
|
1630
|
+
}
|
|
1353
1631
|
return null;
|
|
1354
1632
|
}
|
|
1633
|
+
function isPlanExecEntry(value) {
|
|
1634
|
+
if (value === undefined)
|
|
1635
|
+
return true;
|
|
1636
|
+
if (!isRecord(value) || !(value.plan === null || isNonEmptyString(value.plan)))
|
|
1637
|
+
return false;
|
|
1638
|
+
if (value.sources !== undefined &&
|
|
1639
|
+
(value.plan === null || !Array.isArray(value.sources) || !value.sources.every(isNonEmptyString)))
|
|
1640
|
+
return false;
|
|
1641
|
+
if (value.grammar_failure !== undefined &&
|
|
1642
|
+
(!isRecord(value.grammar_failure) ||
|
|
1643
|
+
!isNonEmptyString(value.grammar_failure.code) ||
|
|
1644
|
+
!isNonEmptyString(value.grammar_failure.message) ||
|
|
1645
|
+
!isNonEmptyString(value.grammar_failure.action)))
|
|
1646
|
+
return false;
|
|
1647
|
+
const phases = value.phases_without_open_tasks;
|
|
1648
|
+
const approval = value.approved_without_changes;
|
|
1649
|
+
if (approval !== undefined &&
|
|
1650
|
+
(value.plan === null ||
|
|
1651
|
+
!Array.isArray(phases) ||
|
|
1652
|
+
!Array.isArray(approval) ||
|
|
1653
|
+
approval.length === 0 ||
|
|
1654
|
+
new Set(approval).size !== approval.length ||
|
|
1655
|
+
!approval.every((phase) => phases.includes(phase))))
|
|
1656
|
+
return false;
|
|
1657
|
+
return (phases === null ||
|
|
1658
|
+
(Array.isArray(phases) &&
|
|
1659
|
+
phases.every((phase) => Number.isInteger(phase) && phase > 0) &&
|
|
1660
|
+
new Set(phases).size === phases.length));
|
|
1661
|
+
}
|
|
1662
|
+
function isInheritedBaseArray(value) {
|
|
1663
|
+
if (value === undefined)
|
|
1664
|
+
return true;
|
|
1665
|
+
return (Array.isArray(value) &&
|
|
1666
|
+
value.every((entry) => isRecord(entry) &&
|
|
1667
|
+
Array.isArray(entry.phases) &&
|
|
1668
|
+
entry.phases.length > 0 &&
|
|
1669
|
+
entry.phases.every((phase) => Number.isInteger(phase) && phase > 0) &&
|
|
1670
|
+
isSourceMap(entry.base, true) &&
|
|
1671
|
+
entry.base !== undefined));
|
|
1672
|
+
}
|
|
1673
|
+
/**
|
|
1674
|
+
* The bases a reseated run inherits from the archived registry, read tolerantly:
|
|
1675
|
+
* the archive may be the very state that could not be continued, so anything
|
|
1676
|
+
* that is not a well-formed batch base is left behind rather than trusted.
|
|
1677
|
+
*/
|
|
1678
|
+
export function inheritedBasesFrom(archived) {
|
|
1679
|
+
if (archived === null)
|
|
1680
|
+
return [];
|
|
1681
|
+
let parsed;
|
|
1682
|
+
try {
|
|
1683
|
+
parsed = JSON.parse(archived);
|
|
1684
|
+
}
|
|
1685
|
+
catch {
|
|
1686
|
+
return [];
|
|
1687
|
+
}
|
|
1688
|
+
if (!isRecord(parsed) || !Array.isArray(parsed.batches))
|
|
1689
|
+
return [];
|
|
1690
|
+
const inherited = parsed.batches.flatMap((batch) => {
|
|
1691
|
+
if (!isRecord(batch) || batch.base === undefined)
|
|
1692
|
+
return [];
|
|
1693
|
+
const candidate = { phases: batch.phases, base: batch.base };
|
|
1694
|
+
return isInheritedBaseArray([candidate]) ? [candidate] : [];
|
|
1695
|
+
});
|
|
1696
|
+
const earlier = isInheritedBaseArray(parsed.inherited_bases)
|
|
1697
|
+
? (parsed.inherited_bases ?? [])
|
|
1698
|
+
: [];
|
|
1699
|
+
return [...earlier, ...inherited];
|
|
1700
|
+
}
|
|
1701
|
+
export function withInheritedBases(state, inherited) {
|
|
1702
|
+
if (inherited.length === 0)
|
|
1703
|
+
return state;
|
|
1704
|
+
return sealRunState({ ...withoutSeal(state), inherited_bases: [...inherited] });
|
|
1705
|
+
}
|
|
1355
1706
|
/** Fields added by v10 that have no truthful default on a persisted run. */
|
|
1356
1707
|
function checkV10RecordShape(parsed, invalid) {
|
|
1357
1708
|
if (!isPlanExecBatchArray(parsed.batches)) {
|
|
@@ -1372,7 +1723,7 @@ function checkV10RecordShape(parsed, invalid) {
|
|
|
1372
1723
|
if (!isDecisionPreparation(parsed.decision_preparation)) {
|
|
1373
1724
|
return invalid("declara una vista de decisión sin nota, preview o linaje sellados");
|
|
1374
1725
|
}
|
|
1375
|
-
if (!isFixPreview(parsed.fix_preview)) {
|
|
1726
|
+
if (!isFixPreview(parsed.fix_preview) || !isQuickCheckouts(parsed.quick_checkouts)) {
|
|
1376
1727
|
return invalid("declara un preview de arreglo sin archivos, intención o forma del diff");
|
|
1377
1728
|
}
|
|
1378
1729
|
if (!isSettlement(parsed.settlement)) {
|
|
@@ -1440,7 +1791,7 @@ function isRouteProposal(value) {
|
|
|
1440
1791
|
!isRouteDisposition(control.recommendation) ||
|
|
1441
1792
|
!isRecord(control.alternatives) ||
|
|
1442
1793
|
!isNonEmptyString(control.alternatives.apply) ||
|
|
1443
|
-
!isNonEmptyString(control.alternatives.omit) ||
|
|
1794
|
+
(control.alternatives.omit !== undefined && !isNonEmptyString(control.alternatives.omit)) ||
|
|
1444
1795
|
!isNonEmptyString(control.alternatives.substitute) ||
|
|
1445
1796
|
!isNonEmptyString(control.consequence) ||
|
|
1446
1797
|
!isNonEmptyString(control.risk) ||
|
|
@@ -1509,6 +1860,17 @@ function isScope(value) {
|
|
|
1509
1860
|
return false;
|
|
1510
1861
|
if (!isStringArray(value.sources) || value.sources.length === 0)
|
|
1511
1862
|
return false;
|
|
1863
|
+
if (value.isolation !== undefined && value.isolation !== "unit" && value.isolation !== "in-place")
|
|
1864
|
+
return false;
|
|
1865
|
+
if (value.final_validation !== undefined &&
|
|
1866
|
+
(!Array.isArray(value.final_validation) ||
|
|
1867
|
+
!value.final_validation.every((entry) => isRecord(entry) &&
|
|
1868
|
+
typeof entry.alias === "string" &&
|
|
1869
|
+
[entry.build, entry.test].every((item) => isRecord(item) &&
|
|
1870
|
+
(item.command === null || typeof item.command === "string") &&
|
|
1871
|
+
(item.origin === null || item.origin === "plan" || item.origin === "source") &&
|
|
1872
|
+
(item.action === undefined || typeof item.action === "string")))))
|
|
1873
|
+
return false;
|
|
1512
1874
|
return value.sources.every((alias) => alias.trim().length > 0);
|
|
1513
1875
|
}
|
|
1514
1876
|
function isPlanExecBatchArray(value) {
|
|
@@ -1531,7 +1893,11 @@ function isPlanExecBatchArray(value) {
|
|
|
1531
1893
|
entry.phases.length === 0 ||
|
|
1532
1894
|
!entry.phases.every((phase) => typeof phase === "number" && Number.isInteger(phase) && phase > 0) ||
|
|
1533
1895
|
!isStringArray(entry.tasks) ||
|
|
1534
|
-
entry.
|
|
1896
|
+
(entry.validation_only !== undefined && typeof entry.validation_only !== "boolean") ||
|
|
1897
|
+
(entry.validation_only === true && entry.tasks.length !== 0) ||
|
|
1898
|
+
(entry.validation_only === false && entry.kind === "validation-only") ||
|
|
1899
|
+
(entry.kind === "validation-only" ? entry.tasks.length !== 0 : entry.tasks.length === 0) ||
|
|
1900
|
+
(entry.kind !== undefined && entry.kind !== "validation-only") ||
|
|
1535
1901
|
new Set(entry.tasks).size !== entry.tasks.length ||
|
|
1536
1902
|
typeof entry.plan_digest !== "string" ||
|
|
1537
1903
|
entry.plan_digest.length === 0 ||
|
|
@@ -1542,7 +1908,16 @@ function isPlanExecBatchArray(value) {
|
|
|
1542
1908
|
(entry.publication !== undefined &&
|
|
1543
1909
|
entry.publication.status === "applied" &&
|
|
1544
1910
|
entry.published_plan_digest !== entry.publication.after_plan_digest) ||
|
|
1545
|
-
!PLAN_EXEC_BATCH_STAGES.includes(entry.stage)
|
|
1911
|
+
!PLAN_EXEC_BATCH_STAGES.includes(entry.stage) ||
|
|
1912
|
+
!isSourceMap(entry.base, true) ||
|
|
1913
|
+
!isSourceMap(entry.credit, false) ||
|
|
1914
|
+
!isBatchPartition(entry.partition, entry.phases, entry.mode) ||
|
|
1915
|
+
!isBatchSnapshot(entry.snapshot) ||
|
|
1916
|
+
!isBatchCommitProposal(entry.commit_proposal) ||
|
|
1917
|
+
!isBatchCommitResult(entry.commit_result) ||
|
|
1918
|
+
(entry.credit_phases !== undefined &&
|
|
1919
|
+
(entry.credit === undefined || !samePhaseRange(entry.credit_phases, entry.phases))) ||
|
|
1920
|
+
(entry.review !== undefined && !isBatchReview(entry.review))) {
|
|
1546
1921
|
return false;
|
|
1547
1922
|
}
|
|
1548
1923
|
ids.add(entry.id);
|
|
@@ -1550,6 +1925,75 @@ function isPlanExecBatchArray(value) {
|
|
|
1550
1925
|
return true;
|
|
1551
1926
|
});
|
|
1552
1927
|
}
|
|
1928
|
+
function isBatchSnapshot(value) {
|
|
1929
|
+
if (value === undefined)
|
|
1930
|
+
return true;
|
|
1931
|
+
return (isRecord(value) &&
|
|
1932
|
+
Object.values(value).every((entry) => isRecord(entry) &&
|
|
1933
|
+
isNonEmptyString(entry.head) &&
|
|
1934
|
+
isNonEmptyString(entry.branch) &&
|
|
1935
|
+
Array.isArray(entry.dirty) &&
|
|
1936
|
+
entry.dirty.every((path) => isRecord(path) && isNonEmptyString(path.path) && isNonEmptyString(path.digest))));
|
|
1937
|
+
}
|
|
1938
|
+
function isBatchCommitProposal(value) {
|
|
1939
|
+
if (value === undefined)
|
|
1940
|
+
return true;
|
|
1941
|
+
return (isRecord(value) &&
|
|
1942
|
+
isNonEmptyString(value.digest) &&
|
|
1943
|
+
(value.approved_digest === undefined || isNonEmptyString(value.approved_digest)) &&
|
|
1944
|
+
Array.isArray(value.sources) &&
|
|
1945
|
+
value.sources.every((item) => isRecord(item) &&
|
|
1946
|
+
isNonEmptyString(item.alias) &&
|
|
1947
|
+
isNonEmptyString(item.message) &&
|
|
1948
|
+
isStringArray(item.paths) &&
|
|
1949
|
+
(item.foreign_paths === undefined || isStringArray(item.foreign_paths)) &&
|
|
1950
|
+
item.paths.length > 0 &&
|
|
1951
|
+
Array.isArray(item.dirty) &&
|
|
1952
|
+
item.dirty.length === item.paths.length &&
|
|
1953
|
+
item.dirty.every((path) => isRecord(path) && isNonEmptyString(path.path) && isNonEmptyString(path.digest))));
|
|
1954
|
+
}
|
|
1955
|
+
function isBatchCommitResult(value) {
|
|
1956
|
+
if (value === undefined)
|
|
1957
|
+
return true;
|
|
1958
|
+
return (isRecord(value) &&
|
|
1959
|
+
Object.values(value).every((receipt) => isRecord(receipt) &&
|
|
1960
|
+
isNonEmptyString(receipt.after) &&
|
|
1961
|
+
(receipt.before === null || isNonEmptyString(receipt.before)) &&
|
|
1962
|
+
(receipt.branch === null || isNonEmptyString(receipt.branch)) &&
|
|
1963
|
+
isStringArray(receipt.parents)));
|
|
1964
|
+
}
|
|
1965
|
+
function samePhaseRange(value, phases) {
|
|
1966
|
+
return (Array.isArray(value) &&
|
|
1967
|
+
value.length === phases.length &&
|
|
1968
|
+
value.every((phase, index) => phase === phases[index]));
|
|
1969
|
+
}
|
|
1970
|
+
function isBatchPartition(value, phases, mode) {
|
|
1971
|
+
if (value === undefined)
|
|
1972
|
+
return true;
|
|
1973
|
+
if (!isRecord(value) ||
|
|
1974
|
+
!isNonEmptyString(value.reason) ||
|
|
1975
|
+
!isRecord(value.effective) ||
|
|
1976
|
+
value.effective.mode !== mode ||
|
|
1977
|
+
!samePhaseRange(value.effective.phases, phases))
|
|
1978
|
+
return false;
|
|
1979
|
+
return (value.declared === null ||
|
|
1980
|
+
(Array.isArray(value.declared) &&
|
|
1981
|
+
value.declared.length > 0 &&
|
|
1982
|
+
value.declared.every((row) => isRecord(row) &&
|
|
1983
|
+
isNonEmptyString(row.id) &&
|
|
1984
|
+
(row.mode === "continuous" || row.mode === "isolated") &&
|
|
1985
|
+
Array.isArray(row.phases) &&
|
|
1986
|
+
row.phases.length > 0 &&
|
|
1987
|
+
row.phases.every((phase) => Number.isSafeInteger(phase) && phase > 0))));
|
|
1988
|
+
}
|
|
1989
|
+
/** Absent, or a non-empty alias → digest map; `nullable` admits an unobserved source. */
|
|
1990
|
+
function isSourceMap(value, nullable) {
|
|
1991
|
+
if (value === undefined)
|
|
1992
|
+
return true;
|
|
1993
|
+
if (!isRecord(value) || Object.keys(value).length === 0)
|
|
1994
|
+
return false;
|
|
1995
|
+
return Object.values(value).every((digest) => (nullable && digest === null) || (typeof digest === "string" && digest.length > 0));
|
|
1996
|
+
}
|
|
1553
1997
|
function isPlanExecBatchPublication(value) {
|
|
1554
1998
|
if (value === undefined)
|
|
1555
1999
|
return true;
|
|
@@ -1587,6 +2031,7 @@ function isPlanExecBatchTraceArray(value, batches) {
|
|
|
1587
2031
|
typeof entry.iteration === "number" &&
|
|
1588
2032
|
Number.isInteger(entry.iteration) &&
|
|
1589
2033
|
typeof entry.transition === "string" &&
|
|
2034
|
+
(entry.approval === undefined || entry.approval === true) &&
|
|
1590
2035
|
entry.transition.length > 0 &&
|
|
1591
2036
|
PLAN_EXEC_BATCH_STAGES.includes(entry.stage) &&
|
|
1592
2037
|
(entry.kind === "entered" || entry.kind === "completed" || entry.kind === "blocked"));
|
|
@@ -1744,7 +2189,13 @@ function isFixPreview(value) {
|
|
|
1744
2189
|
return (typeof value.intent === "string" &&
|
|
1745
2190
|
value.intent.trim().length > 0 &&
|
|
1746
2191
|
typeof value.diff === "string" &&
|
|
1747
|
-
value.diff.trim().length > 0
|
|
2192
|
+
value.diff.trim().length > 0 &&
|
|
2193
|
+
isQuickCheckouts(value.checkouts));
|
|
2194
|
+
}
|
|
2195
|
+
function isQuickCheckouts(value) {
|
|
2196
|
+
return (value === null ||
|
|
2197
|
+
value === undefined ||
|
|
2198
|
+
(isRecord(value) && Object.values(value).every(nonEmpty)));
|
|
1748
2199
|
}
|
|
1749
2200
|
function isDecisionPreview(value, baseline) {
|
|
1750
2201
|
if (!isRecord(value) ||
|
|
@@ -1862,10 +2313,8 @@ function isEvent(entry) {
|
|
|
1862
2313
|
return false;
|
|
1863
2314
|
if (typeof entry.transition !== "string" || typeof entry.operation !== "string")
|
|
1864
2315
|
return false;
|
|
1865
|
-
if (entry
|
|
1866
|
-
(!Number.isInteger(entry.batch_iteration) || entry.batch_iteration < 1)) {
|
|
2316
|
+
if (!isIterationRecord(entry))
|
|
1867
2317
|
return false;
|
|
1868
|
-
}
|
|
1869
2318
|
return EVENT_BODIES.get(entry.kind)?.(entry) === true;
|
|
1870
2319
|
}
|
|
1871
2320
|
const nonEmpty = (value) => typeof value === "string" && value.trim().length > 0;
|
|
@@ -1880,6 +2329,9 @@ const EVENT_BODIES = new Map(Object.entries({
|
|
|
1880
2329
|
isEffectClassArray(entry.effects) &&
|
|
1881
2330
|
isStringArray(entry.evidence),
|
|
1882
2331
|
reconciled: (entry) => isRepairArray(entry.repairs),
|
|
2332
|
+
retracted: (entry) => nonEmpty(entry.signal) &&
|
|
2333
|
+
isObservationArray(entry.observations) &&
|
|
2334
|
+
entry.observations.length > 0,
|
|
1883
2335
|
restarted: (entry) => nonEmpty(entry.archive) && nonEmpty(entry.cause),
|
|
1884
2336
|
annulled: (entry) => isStringArray(entry.batches) &&
|
|
1885
2337
|
entry.batches.length > 0 &&
|
|
@@ -1888,6 +2340,7 @@ const EVENT_BODIES = new Map(Object.entries({
|
|
|
1888
2340
|
isStringArray(entry.tasks) &&
|
|
1889
2341
|
nonEmpty(entry.digest),
|
|
1890
2342
|
aligned: (entry) => Number.isInteger(entry.position) && entry.position >= 0 && nonEmpty(entry.reason),
|
|
2343
|
+
"route-refused": (entry) => isRouteDisposition(entry.disposition) && nonEmpty(entry.reason),
|
|
1891
2344
|
failed: (entry) => typeof entry.code === "string" &&
|
|
1892
2345
|
typeof entry.message === "string" &&
|
|
1893
2346
|
typeof entry.recovery === "string" &&
|
|
@@ -1913,8 +2366,40 @@ function isObservationArray(value) {
|
|
|
1913
2366
|
return value.every((entry) => isRecord(entry) &&
|
|
1914
2367
|
typeof entry.transition === "string" &&
|
|
1915
2368
|
isStringArray(entry.signals) &&
|
|
1916
|
-
(entry
|
|
1917
|
-
|
|
2369
|
+
isIterationRecord(entry));
|
|
2370
|
+
}
|
|
2371
|
+
const REENTRY_KINDS = ["refine", "close", "reopen", "review", "reinfer"];
|
|
2372
|
+
/** Absent, or reentries each with its kind, its boundary, its occurrence and its origin. */
|
|
2373
|
+
function isReentryArray(value) {
|
|
2374
|
+
if (value === undefined)
|
|
2375
|
+
return true;
|
|
2376
|
+
if (!Array.isArray(value))
|
|
2377
|
+
return false;
|
|
2378
|
+
return value.every((entry) => isRecord(entry) &&
|
|
2379
|
+
REENTRY_KINDS.includes(entry.kind) &&
|
|
2380
|
+
(entry.kind !== "review" ||
|
|
2381
|
+
(entry.transition === "plan-exec.batch-close" &&
|
|
2382
|
+
entry.from === "plan-exec.review-findings")) &&
|
|
2383
|
+
(entry.kind !== "reinfer" ||
|
|
2384
|
+
(entry.from === "plan-exec.validation-execution" &&
|
|
2385
|
+
[
|
|
2386
|
+
"plan-exec.deferred-check",
|
|
2387
|
+
"plan-exec.review-findings",
|
|
2388
|
+
"plan-exec.batch-commit-proposal",
|
|
2389
|
+
"plan-exec.batch-close",
|
|
2390
|
+
].includes(entry.transition))) &&
|
|
2391
|
+
nonEmpty(entry.transition) &&
|
|
2392
|
+
Number.isInteger(entry.occurrence) &&
|
|
2393
|
+
entry.occurrence >= 1 &&
|
|
2394
|
+
// A redraft names where it re-enters; the other kinds repeat from their row.
|
|
2395
|
+
(entry.kind === "refine"
|
|
2396
|
+
? nonEmpty(entry.from)
|
|
2397
|
+
: entry.from === null || nonEmpty(entry.from)));
|
|
2398
|
+
}
|
|
2399
|
+
/** Both iteration fields, each absent or a positive integer. */
|
|
2400
|
+
function isIterationRecord(entry) {
|
|
2401
|
+
const ordinal = (value) => value === undefined || (Number.isInteger(value) && value >= 1);
|
|
2402
|
+
return ordinal(entry.batch_iteration) && ordinal(entry.reentry_iteration);
|
|
1918
2403
|
}
|
|
1919
2404
|
/**
|
|
1920
2405
|
* The two optional fields are checked as ABSENT-or-well-formed, never defaulted.
|
|
@@ -1950,8 +2435,7 @@ function isAttemptArray(value) {
|
|
|
1950
2435
|
Number.isInteger(entry.attempt) &&
|
|
1951
2436
|
typeof entry.request_digest === "string" &&
|
|
1952
2437
|
typeof entry.transition === "string" &&
|
|
1953
|
-
(entry
|
|
1954
|
-
(Number.isInteger(entry.batch_iteration) && entry.batch_iteration >= 1)) &&
|
|
2438
|
+
isIterationRecord(entry) &&
|
|
1955
2439
|
(entry.parent_request_digest === null || typeof entry.parent_request_digest === "string"));
|
|
1956
2440
|
}
|
|
1957
2441
|
//# sourceMappingURL=run-state.js.map
|