@tacuchi/agent-workflow-cli 25.8.0 → 26.0.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 +106 -0
- package/README.md +6 -3
- package/dist/adapters/git-cli.js +225 -17
- 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 +218 -43
- package/dist/application/capability/design-handler.js.map +1 -1
- package/dist/application/capability/dispatcher.js +182 -19
- 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 +8 -54
- package/dist/application/capability/readiness.js.map +1 -1
- package/dist/application/capability/resolution.js +124 -192
- package/dist/application/capability/resolution.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 +166 -20
- 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 +3 -3
- 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 +9 -1
- package/dist/application/doctor/provider-mcps.js.map +1 -1
- package/dist/application/doctor/provider-skills.js +29 -115
- 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 +36 -39
- 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/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 +202 -25
- 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 +63 -10
- 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 +25 -14
- package/dist/application/flow/close-at-boundary.js.map +1 -1
- 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 +46 -3
- package/dist/application/flow/flow-service.js.map +1 -1
- package/dist/application/flow/internal-actions.js +300 -82
- package/dist/application/flow/internal-actions.js.map +1 -1
- package/dist/application/flow/internal-drive.js +24 -1
- 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 +12 -5
- package/dist/application/flow/reopen-run.js.map +1 -1
- package/dist/application/flow/run-state-service.js +2 -0
- package/dist/application/flow/run-state-service.js.map +1 -1
- package/dist/application/flow/submit.js +584 -117
- 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-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 +33 -5
- 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 +122 -50
- 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/clean-legacy.js +1 -2
- package/dist/application/self/clean-legacy.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 +5 -49
- package/dist/application/self/install-skill.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/skill-files.js +29 -0
- package/dist/application/self/skill-files.js.map +1 -0
- package/dist/application/self/uninstall.js +1 -1
- 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 +42 -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 +134 -13
- 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 +6 -92
- 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 +105 -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 +2 -0
- package/dist/cli/ascii.js.map +1 -1
- 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 -3
- package/dist/cli/commands/amend.js.map +1 -1
- package/dist/cli/commands/capability.js +23 -4
- package/dist/cli/commands/capability.js.map +1 -1
- package/dist/cli/commands/designs.js +14 -5
- package/dist/cli/commands/designs.js.map +1 -1
- package/dist/cli/commands/dev-only.js +19 -6
- 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 +5 -1
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/export.js +78 -18
- package/dist/cli/commands/export.js.map +1 -1
- package/dist/cli/commands/fix-git.js +89 -14
- package/dist/cli/commands/fix-git.js.map +1 -1
- package/dist/cli/commands/flow.js +120 -15
- package/dist/cli/commands/flow.js.map +1 -1
- package/dist/cli/commands/generate-launch.js +14 -2
- package/dist/cli/commands/generate-launch.js.map +1 -1
- package/dist/cli/commands/history-update.js +1 -1
- 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 +15 -2
- package/dist/cli/commands/hook.js.map +1 -1
- package/dist/cli/commands/index.js +18 -5
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/merge-state.js +2 -2
- package/dist/cli/commands/merge-state.js.map +1 -1
- package/dist/cli/commands/persist.js +6 -5
- package/dist/cli/commands/persist.js.map +1 -1
- package/dist/cli/commands/project-md-upsert.js +5 -3
- package/dist/cli/commands/project-md-upsert.js.map +1 -1
- package/dist/cli/commands/release-pass.js +3 -3
- package/dist/cli/commands/release-pass.js.map +1 -1
- package/dist/cli/commands/resume.js +12 -3
- package/dist/cli/commands/resume.js.map +1 -1
- package/dist/cli/commands/self.js +8 -24
- package/dist/cli/commands/self.js.map +1 -1
- package/dist/cli/commands/session-close.js +64 -9
- package/dist/cli/commands/session-close.js.map +1 -1
- package/dist/cli/commands/session-create.js +4 -2
- 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/sessions.js +16 -3
- package/dist/cli/commands/sessions.js.map +1 -1
- package/dist/cli/commands/set-branch.js +28 -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/skills.js +4 -11
- package/dist/cli/commands/skills.js.map +1 -1
- package/dist/cli/commands/sources.js +4 -0
- package/dist/cli/commands/sources.js.map +1 -1
- package/dist/cli/commands/status.js +35 -2
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/unknown-flags.js +1 -0
- package/dist/cli/commands/unknown-flags.js.map +1 -1
- package/dist/cli/commands/visibility.js +1 -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 +39 -2
- package/dist/cli/commands/workspace-init.js.map +1 -1
- package/dist/cli/commands/workspace-migrate.js +31 -3
- 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 +4 -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 +76 -19
- 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 -453
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/parser.js +4 -0
- package/dist/cli/parser.js.map +1 -1
- package/dist/cli/tui/app.js +3 -4
- package/dist/cli/tui/app.js.map +1 -1
- package/dist/cli/tui/components/host-admin-section.js +2 -13
- package/dist/cli/tui/components/host-admin-section.js.map +1 -1
- package/dist/cli/tui/components/tabs-config.js +1 -2
- package/dist/cli/tui/components/tabs-config.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/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/cli/tui/tui-prefs.js +2 -0
- package/dist/cli/tui/tui-prefs.js.map +1 -1
- package/dist/dist-manifest.json +3973 -0
- package/dist/domain/capability/protocol.js +3 -1
- 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 +20 -12
- 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 +265 -130
- package/dist/domain/flow/answer.js.map +1 -1
- package/dist/domain/flow/authority.js +194 -37
- 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 +91 -2
- package/dist/domain/flow/execution-result.js.map +1 -1
- package/dist/domain/flow/run-state.js +352 -24
- 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 +14 -5
- 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 +4 -6
- package/dist/domain/skills.js.map +1 -1
- package/dist/domain/sql-lexer.js +1 -1
- 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 +6 -5
- package/skills/w/SKILL.md +12 -17
- 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/README.md +4 -4
- package/skills/w/exports/export-diagrams/EXPORT.md +4 -4
- 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 +46 -22
- package/skills/w/harness/HARNESS.md +4 -7
- package/skills/w/hooks/hooks.template.json +6 -4
- package/skills/w/loops/CHASSIS.md +12 -6
- package/skills/w/loops/CODE-POLICIES.md +8 -5
- package/skills/w/loops/README.md +2 -2
- 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 +7 -6
- package/skills/w/loops/spec-refine-loop/LOOP.md +1 -1
- 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/README.md +11 -47
- package/skills/w/roles/design/CONTRACT.md +6 -4
- package/skills/w/roles/design/ROLE.md +7 -3
- package/skills/w/roles/diagrams/ROLE.md +1 -1
- package/skills/w/roles/git/ROLE.md +17 -10
- package/skills/w/roles/research/ROLE.md +2 -2
- package/skills/w/roles/sql/ROLE.md +17 -15
- package/skills/w/schemas/design/ui-screen.v1.schema.json +9 -0
- package/dist/application/capability/descriptor-loader.js +0 -109
- package/dist/application/capability/descriptor-loader.js.map +0 -1
- package/dist/application/capability/installed-inventory.js +0 -168
- package/dist/application/capability/installed-inventory.js.map +0 -1
- package/dist/application/self/install-plugin-skills-git.js +0 -226
- package/dist/application/self/install-plugin-skills-git.js.map +0 -1
- package/dist/application/self/install-plugin-skills.js +0 -203
- package/dist/application/self/install-plugin-skills.js.map +0 -1
- package/dist/application/self/plugin-cache-clear.js +0 -133
- package/dist/application/self/plugin-cache-clear.js.map +0 -1
- package/dist/application/self/plugin-cache-reload.js +0 -141
- package/dist/application/self/plugin-cache-reload.js.map +0 -1
- package/dist/application/self/skills-apply.js +0 -623
- package/dist/application/self/skills-apply.js.map +0 -1
- package/dist/application/self/skills-catalog.js +0 -35
- package/dist/application/self/skills-catalog.js.map +0 -1
- package/dist/application/self/skills-change.js +0 -479
- package/dist/application/self/skills-change.js.map +0 -1
- package/dist/application/self/skills-discovery.js +0 -275
- package/dist/application/self/skills-discovery.js.map +0 -1
- package/dist/application/self/skills-manager.js +0 -253
- package/dist/application/self/skills-manager.js.map +0 -1
- package/dist/application/self/skills-payload.js +0 -566
- package/dist/application/self/skills-payload.js.map +0 -1
- package/dist/application/self/skills-registry.js +0 -107
- package/dist/application/self/skills-registry.js.map +0 -1
- package/dist/application/skill-index-service.js +0 -78
- package/dist/application/skill-index-service.js.map +0 -1
- package/dist/cli/commands/plugin-cache.js +0 -25
- package/dist/cli/commands/plugin-cache.js.map +0 -1
- package/dist/cli/commands/skill-index.js +0 -19
- package/dist/cli/commands/skill-index.js.map +0 -1
- package/dist/cli/tui/data/recommended-skills.js +0 -482
- package/dist/cli/tui/data/recommended-skills.js.map +0 -1
- package/dist/cli/tui/tabs/skills-tab.js +0 -664
- package/dist/cli/tui/tabs/skills-tab.js.map +0 -1
|
@@ -25,35 +25,42 @@
|
|
|
25
25
|
*/
|
|
26
26
|
import { join } from "node:path";
|
|
27
27
|
import { dispositionOf } from "../../domain/flow/route.js";
|
|
28
|
-
import { withPlanExecBatch, withPlanExecBatchBase, withPlanExecBatchLoop, withSettlement, } from "../../domain/flow/run-state.js";
|
|
29
|
-
import {
|
|
28
|
+
import { legacyPlanExecCommits, withPlanExecBatch, withPlanExecBatchBase, withPlanExecBatchLoop, withPlanExecBatchUpdate, withSettlement, } from "../../domain/flow/run-state.js";
|
|
29
|
+
import { approvedValidationOnly } from "../../domain/flow/unchanged-phase.js";
|
|
30
|
+
import { canonicalEol, sealProposal } from "../../domain/proposal.js";
|
|
30
31
|
import { obligationExit } from "../../domain/reconciliation.js";
|
|
31
32
|
import { runArtifactsCommand } from "../artifacts-service.js";
|
|
32
|
-
import { appendClaimEvent, claimKey, claimShapedAmong, completedClaimsIn, ledgerPath,
|
|
33
|
+
import { appendClaimEvent, claimKey, claimShapedAmong, completedClaimsIn, ledgerPath, readClaimEvents, revokedAmong, } from "../claims-ledger.js";
|
|
33
34
|
import { applyLocalProposal } from "../local-proposal.js";
|
|
34
35
|
import { parseMdSectionBilingual } from "../markdown.js";
|
|
35
36
|
import { parsePhases } from "../parsers/phases.js";
|
|
36
|
-
import { parseTasks } from "../parsers/tasks.js";
|
|
37
37
|
import { resolveWorkspaceRoot } from "../paths-service.js";
|
|
38
|
-
import {
|
|
38
|
+
import { inferNextPlanExecBatch, preparePlanExecDoneSeal, publishPlanExecBatch, } from "../plan-exec-batch-service.js";
|
|
39
39
|
import { settlePlanExecObligations } from "../plan-exec-decision-service.js";
|
|
40
|
+
import { sealedPlanPath } from "../plan-exec-plan-diff.js";
|
|
40
41
|
import { readSessionArtifacts } from "../release-data/artifacts.js";
|
|
41
42
|
import { canonicalJson } from "../semantic-operation/protocol.js";
|
|
43
|
+
import { canonicalArtifactPath } from "../session-artifacts.js";
|
|
42
44
|
import { runSessionClose } from "../session-close-service.js";
|
|
43
45
|
import { recordPublication } from "../session-custody-recorder.js";
|
|
46
|
+
import { readCustody } from "../session-custody-service.js";
|
|
44
47
|
import { runStatusCommand } from "../status-service.js";
|
|
45
48
|
import { buildWorklineIndex } from "../workline-index-service.js";
|
|
46
|
-
import {
|
|
47
|
-
import {
|
|
49
|
+
import { runWorkspaceCommit } from "../workspace-commit-service.js";
|
|
50
|
+
import { classifyListedUnits, runWorktree } from "../worktree-service.js";
|
|
51
|
+
import { commitBatch, verifyBatchGitState } from "./batch-commit.js";
|
|
52
|
+
import { observeScopedFingerprints, resolveCheckoutCandidates } from "./checkout-observation.js";
|
|
53
|
+
import { preserveBoundaryClose } from "./close-artifacts.js";
|
|
54
|
+
import { closeDocumentGuidance } from "./close-document-guidance.js";
|
|
48
55
|
import { projectRun } from "./run-projection.js";
|
|
49
56
|
import { applyUnderLock, locateRun, readRun } from "./run-state-service.js";
|
|
50
57
|
export function internalActionExecutor(deps) {
|
|
51
58
|
return async (plan, run) => {
|
|
52
59
|
switch (plan.operation) {
|
|
53
60
|
case "workspace.board":
|
|
54
|
-
return board(deps);
|
|
61
|
+
return board(deps, run);
|
|
55
62
|
case "session.artifacts":
|
|
56
|
-
return artifacts(deps, run, plan.dump ?? null);
|
|
63
|
+
return artifacts(deps, run, plan.dump ?? null, run.session.endsWith("-plan-refine"));
|
|
57
64
|
case "session.close":
|
|
58
65
|
return close(deps, run);
|
|
59
66
|
case "worktree.ensure":
|
|
@@ -64,6 +71,8 @@ export function internalActionExecutor(deps) {
|
|
|
64
71
|
return inferBatch(deps, run);
|
|
65
72
|
case "plan-exec.batch-close":
|
|
66
73
|
return closeBatch(deps, run);
|
|
74
|
+
case "plan-exec.batch-commit":
|
|
75
|
+
return commitBatch(deps, run);
|
|
67
76
|
case "plan-exec.plan-done":
|
|
68
77
|
return sealPlanDone(deps, run);
|
|
69
78
|
case "plan-exec.settlement-publish":
|
|
@@ -91,7 +100,7 @@ async function ensureUnits(deps, run) {
|
|
|
91
100
|
return refusal("worktree.ensure", "la corrida no fijó qué fuentes edita: no hay unidad que adquirir", canonicalJson({ scope: null }));
|
|
92
101
|
}
|
|
93
102
|
const acquired = [];
|
|
94
|
-
for (const alias of scope.sources) {
|
|
103
|
+
for (const alias of scope.isolation === "in-place" ? [] : scope.sources) {
|
|
95
104
|
// `workspace` is the documentary/control checkout itself. It is a valid
|
|
96
105
|
// source-bounded proof surface, but never a source repository that needs a
|
|
97
106
|
// per-session Git worktree.
|
|
@@ -115,12 +124,14 @@ async function ensureUnits(deps, run) {
|
|
|
115
124
|
}
|
|
116
125
|
return {
|
|
117
126
|
ok: true,
|
|
118
|
-
summary:
|
|
127
|
+
summary: scope.isolation === "in-place"
|
|
128
|
+
? "in-place: sin unidad"
|
|
129
|
+
: `unidades de ${run.session}: ${acquired.map((unit) => `${unit.alias} → ${unit.branch}`).join(", ")}`,
|
|
119
130
|
output: canonicalJson({ plan: scope.plan, units: acquired }),
|
|
120
131
|
// The tree IS there, however it got there — the same reading `proposal.publish`
|
|
121
132
|
// makes of a re-entry that finds the bytes already written. Crediting nothing
|
|
122
133
|
// when `created` is false would refuse the resumption this row is idempotent for.
|
|
123
|
-
effects: ["local_additive"],
|
|
134
|
+
effects: ["local_additive", "mutate_overwrite"],
|
|
124
135
|
...(based.state === null ? {} : { state: based.state }),
|
|
125
136
|
};
|
|
126
137
|
}
|
|
@@ -148,6 +159,55 @@ async function recordBatchBase(deps, run, sources) {
|
|
|
148
159
|
const observed = await observeScopedFingerprints(deps.fs, deps.git, deps.paths, run.session, sources);
|
|
149
160
|
if (!observed.ok)
|
|
150
161
|
return observed;
|
|
162
|
+
const legacy = live.ok && legacyPlanExecCommits(live.state);
|
|
163
|
+
const candidates = legacy
|
|
164
|
+
? []
|
|
165
|
+
: await resolveCheckoutCandidates(deps.fs, deps.paths, run.session);
|
|
166
|
+
const snapshot = {};
|
|
167
|
+
for (const alias of legacy ? [] : sources) {
|
|
168
|
+
if (alias === "workspace")
|
|
169
|
+
continue;
|
|
170
|
+
const root = candidates.find((candidate) => candidate.source === alias)?.root;
|
|
171
|
+
if (root === undefined)
|
|
172
|
+
return {
|
|
173
|
+
ok: false,
|
|
174
|
+
failure: {
|
|
175
|
+
code: "PLAN_EXEC_BATCH_UNIT_MISSING",
|
|
176
|
+
message: `falta la unidad de ${alias}`,
|
|
177
|
+
action: "adquirí la unidad antes de iniciar el lote",
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
try {
|
|
181
|
+
const [head, branch, dirty] = await Promise.all([
|
|
182
|
+
deps.git.head(root),
|
|
183
|
+
deps.git.currentBranch(root),
|
|
184
|
+
deps.git.dirtyPaths(root),
|
|
185
|
+
]);
|
|
186
|
+
if (head === null ||
|
|
187
|
+
branch === undefined ||
|
|
188
|
+
(run.scope?.isolation !== "in-place" && dirty.length > 0)) {
|
|
189
|
+
return {
|
|
190
|
+
ok: false,
|
|
191
|
+
failure: {
|
|
192
|
+
code: "PLAN_EXEC_BATCH_UNIT_DIRTY",
|
|
193
|
+
message: `${alias}: no puede iniciar el lote con HEAD/rama ausente o rutas sucias: ${dirty.map((entry) => entry.path).join(", ")}`,
|
|
194
|
+
action: "cerrá los cambios del lote anterior antes de iniciar éste",
|
|
195
|
+
},
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
snapshot[alias] = { head, branch, dirty };
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
return {
|
|
202
|
+
ok: false,
|
|
203
|
+
failure: {
|
|
204
|
+
code: "PLAN_EXEC_BATCH_GIT_UNOBSERVABLE",
|
|
205
|
+
message: `${alias}: ${String(error)}`,
|
|
206
|
+
action: "restaurá la lectura de git y reintentá la adquisición",
|
|
207
|
+
},
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
}
|
|
151
211
|
const recorded = await applyUnderLock(deps.fs, locateRun(deps.paths, run.session), (current) => {
|
|
152
212
|
if (current === null) {
|
|
153
213
|
return {
|
|
@@ -168,7 +228,9 @@ async function recordBatchBase(deps, run, sources) {
|
|
|
168
228
|
// base is the one the archived run sealed before that work, not today's tree.
|
|
169
229
|
const inherited = current.inherited_bases?.find((entry) => entry.phases.length === batch.phases.length &&
|
|
170
230
|
entry.phases.every((phase, index) => phase === batch.phases[index]));
|
|
171
|
-
|
|
231
|
+
let next = withPlanExecBatchBase(current, batch.id, inherited?.base ?? observed.base);
|
|
232
|
+
if (batch.snapshot === undefined && !legacyPlanExecCommits(current))
|
|
233
|
+
next = withPlanExecBatchUpdate(next, batch.id, (item) => ({ ...item, snapshot }));
|
|
172
234
|
return { ok: true, state: next, value: null, persist: next !== current };
|
|
173
235
|
}, run.state_digest === undefined ? {} : { expectDigest: run.state_digest });
|
|
174
236
|
if (!recorded.ok)
|
|
@@ -215,7 +277,7 @@ async function publish(deps, run) {
|
|
|
215
277
|
ok: true,
|
|
216
278
|
summary: result.already_applied
|
|
217
279
|
? `la propuesta ya estaba aplicada: ${destinations.join(", ")} sin cambios`
|
|
218
|
-
: `publicado: ${result.written.join(", ")}`,
|
|
280
|
+
: `publicado: ${result.written.join(", ")}${result.notice === undefined ? "" : `; aviso: ${result.notice}`}`,
|
|
219
281
|
output: canonicalJson({ ...result, digest: proposal.digest, destinations, claims }),
|
|
220
282
|
// Only what really landed. A re-entry that found the bytes already there
|
|
221
283
|
// credits the same classes — the effect IS applied — and the summary is what
|
|
@@ -233,8 +295,8 @@ async function publish(deps, run) {
|
|
|
233
295
|
* never held up by a ledger it does not depend on — an unreadable ledger must not
|
|
234
296
|
* stop every loop in the system from saving.
|
|
235
297
|
*/
|
|
236
|
-
async function revokedFence(deps, owner, destinations) {
|
|
237
|
-
const read = await readClaimEvents(deps.fs, deps.paths);
|
|
298
|
+
export async function revokedFence(deps, owner, destinations) {
|
|
299
|
+
const read = await readClaimEvents(deps.fs, deps.paths, { lockHeld: true });
|
|
238
300
|
const blocked = revokedAmong(read.events, owner, destinations);
|
|
239
301
|
if (blocked.length > 0) {
|
|
240
302
|
return {
|
|
@@ -244,13 +306,10 @@ async function revokedFence(deps, owner, destinations) {
|
|
|
244
306
|
};
|
|
245
307
|
}
|
|
246
308
|
if (read.unreadable > 0) {
|
|
247
|
-
//
|
|
248
|
-
//
|
|
249
|
-
//
|
|
250
|
-
|
|
251
|
-
// workspace-wide outage rather than the narrow fail-closed this needs to be.
|
|
252
|
-
const mine = new Set(openClaimsOf(read.events, owner).map((claim) => claimKey(claim)));
|
|
253
|
-
const atRisk = claimShapedAmong(owner, destinations).filter((claim) => mine.has(claimKey(claim)));
|
|
309
|
+
// An illegible revoked row may have removed the very open claim a narrowed
|
|
310
|
+
// check would rely on. Every numbered destination is at risk; loose files
|
|
311
|
+
// outside the claim namespace remain unaffected.
|
|
312
|
+
const atRisk = claimShapedAmong(owner, destinations);
|
|
254
313
|
if (atRisk.length > 0) {
|
|
255
314
|
return {
|
|
256
315
|
code: "CLAIM_LEDGER_UNREADABLE",
|
|
@@ -286,6 +345,8 @@ async function recordCompletedClaims(deps, owner, result, destinations) {
|
|
|
286
345
|
const recorded = [];
|
|
287
346
|
try {
|
|
288
347
|
const read = await readClaimEvents(deps.fs, deps.paths);
|
|
348
|
+
if (read.unreadable > 0)
|
|
349
|
+
return { recorded, ledger_unreadable: read.unreadable };
|
|
289
350
|
const completed = completedClaimsIn(read.events, owner, {
|
|
290
351
|
written: result.written,
|
|
291
352
|
already_applied: result.already_applied,
|
|
@@ -312,13 +373,23 @@ async function recordCompletedClaims(deps, owner, result, destinations) {
|
|
|
312
373
|
};
|
|
313
374
|
}
|
|
314
375
|
}
|
|
315
|
-
async function board(deps) {
|
|
376
|
+
async function board(deps, run) {
|
|
316
377
|
const data = await runStatusCommand(deps.fs, deps.env, deps.paths, { git: deps.git });
|
|
317
378
|
const counts = data.counts;
|
|
379
|
+
const custody = run.session.endsWith("-plan-new")
|
|
380
|
+
? await readCustody(deps.fs, locateRun(deps.paths, run.session).dir)
|
|
381
|
+
: null;
|
|
382
|
+
const superseded = custody?.status === "present"
|
|
383
|
+
? data.specs.find((spec) => spec.status === "superseded" &&
|
|
384
|
+
custody.custody.artifacts.some((artifact) => artifact.role === "input" && artifact.path === spec.file))
|
|
385
|
+
: undefined;
|
|
386
|
+
const warning = superseded === undefined
|
|
387
|
+
? null
|
|
388
|
+
: `la spec ${superseded.number} fue reemplazada${superseded.superseded_by ? ` por ${superseded.superseded_by}` : ""}: plan-new debe usar el reemplazo`;
|
|
318
389
|
return {
|
|
319
390
|
ok: true,
|
|
320
|
-
summary: `tablero: ${counts.specs} specs, ${counts.plans} planes, ${counts.sessions_active} sesiones activas, ${counts.pending} pendientes`,
|
|
321
|
-
output: canonicalJson(data),
|
|
391
|
+
summary: `tablero: ${counts.specs} specs, ${counts.plans} planes, ${counts.sessions_active} sesiones activas, ${counts.pending} pendientes${warning ? `; aviso: ${warning}` : ""}`,
|
|
392
|
+
output: canonicalJson(warning ? { ...data, spec_readiness_warning: warning } : data),
|
|
322
393
|
effects: ["read_only"],
|
|
323
394
|
};
|
|
324
395
|
}
|
|
@@ -332,10 +403,13 @@ async function board(deps) {
|
|
|
332
403
|
* says the specific artifacts have content. A dump alone would pass a session
|
|
333
404
|
* whose criteria were never seeded.
|
|
334
405
|
*/
|
|
335
|
-
async function artifacts(deps, run, dump) {
|
|
406
|
+
async function artifacts(deps, run, dump, planRefine = false) {
|
|
336
407
|
// The presence report, without the narrative: this operation checks that the
|
|
337
408
|
// artifacts are THERE, and projecting the session's whole reading to answer
|
|
338
409
|
// that would be work nobody asked for on every advance.
|
|
410
|
+
if (dump?.includes("objetivo") && dump.includes("checkpoint")) {
|
|
411
|
+
await seedMissingCheckpoint(deps, run);
|
|
412
|
+
}
|
|
339
413
|
const report = await runArtifactsCommand(deps.fs, deps.env, deps.paths, {
|
|
340
414
|
code: run.code,
|
|
341
415
|
noNarrative: true,
|
|
@@ -346,22 +420,27 @@ async function artifacts(deps, run, dump) {
|
|
|
346
420
|
if (report.artifacts.session === null) {
|
|
347
421
|
return refusal("session.artifacts", `la sesión '${report.session}' no tiene su SESSION.md`, canonicalJson(report));
|
|
348
422
|
}
|
|
423
|
+
const destination = planRefine ? await refineDestination(deps, run, canonicalJson(report)) : "";
|
|
424
|
+
if (typeof destination !== "string")
|
|
425
|
+
return destination;
|
|
426
|
+
const legacyWarning = destination;
|
|
349
427
|
if (dump === null) {
|
|
350
428
|
return {
|
|
351
429
|
ok: true,
|
|
352
|
-
summary: `sesión ${report.session}: SESSION.md presente, ${report.artifacts.session.criterios_count} criterios, ${report.artifacts.decisiones_count} decisiones`,
|
|
430
|
+
summary: `sesión ${report.session}: SESSION.md presente, ${report.artifacts.session.criterios_count} criterios, ${report.artifacts.decisiones_count} decisiones${legacyWarning}`,
|
|
353
431
|
output: canonicalJson(report),
|
|
354
432
|
effects: SEEDED_EFFECTS,
|
|
355
433
|
};
|
|
356
434
|
}
|
|
357
435
|
const dumped = await readSessionArtifacts(deps.fs, deps.paths, run.code, [...dump], deps.runtime);
|
|
358
|
-
const
|
|
436
|
+
const script = dump.includes("scripts") ? await rootScript(deps, run) : null;
|
|
437
|
+
const output = canonicalJson({ report, dump: dumped, root_script: script });
|
|
359
438
|
if (dumped.error !== undefined) {
|
|
360
439
|
return refusal("session.artifacts", String(dumped.hint ?? dumped.error), output);
|
|
361
440
|
}
|
|
362
|
-
const empty = dump.filter((kind) => !hasContent(dumped[kind]));
|
|
441
|
+
const empty = dump.filter((kind) => !hasContent(dumped[kind]) && !(kind === "scripts" && hasContent(script)));
|
|
363
442
|
if (empty.length > 0) {
|
|
364
|
-
return refusal("session.artifacts", `sin contenido: ${empty.join(", ")}`, output);
|
|
443
|
+
return refusal("session.artifacts", `sin contenido: ${empty.join(", ")}${empty.includes("scripts") ? " (SCRIPTS.sql o scripts/*.sql)" : ""}`, output);
|
|
365
444
|
}
|
|
366
445
|
// `objetivo` is the artifact that carries the success criteria, so demanding it
|
|
367
446
|
// is demanding them: a SESSION.md with a criteria heading and nothing under it
|
|
@@ -373,11 +452,46 @@ async function artifacts(deps, run, dump) {
|
|
|
373
452
|
}
|
|
374
453
|
return {
|
|
375
454
|
ok: true,
|
|
376
|
-
summary: `sesión ${report.session}: ${dump.join(", ")} con contenido, ${report.artifacts.session.criterios_count} criterios`,
|
|
455
|
+
summary: `sesión ${report.session}: ${dump.join(", ")} con contenido, ${report.artifacts.session.criterios_count} criterios${legacyWarning}`,
|
|
377
456
|
output,
|
|
378
457
|
effects: SEEDED_EFFECTS,
|
|
379
458
|
};
|
|
380
459
|
}
|
|
460
|
+
async function seedMissingCheckpoint(deps, run) {
|
|
461
|
+
const folder = join(deps.paths.cwdSessionsDir(), run.session);
|
|
462
|
+
const checkpoint = canonicalArtifactPath(folder, "checkpoint");
|
|
463
|
+
if (await deps.fs.exists(checkpoint))
|
|
464
|
+
return;
|
|
465
|
+
const session = canonicalArtifactPath(folder, "session");
|
|
466
|
+
if (!(await deps.fs.exists(session)))
|
|
467
|
+
return;
|
|
468
|
+
const objective = parseMdSectionBilingual(await deps.fs.readText(session), "Objective")?.trim();
|
|
469
|
+
if (!objective || objective.includes("_[AI:"))
|
|
470
|
+
return;
|
|
471
|
+
await deps.fs.publishTextExclusive(checkpoint, `# CHECKPOINT\n\n## Completed\n\n## Pending / Next\n\n${objective}\n`);
|
|
472
|
+
}
|
|
473
|
+
/** Only this evidence reader accepts the root script; exports keep their dump. */
|
|
474
|
+
async function rootScript(deps, run) {
|
|
475
|
+
const path = canonicalArtifactPath(join(deps.paths.cwdSessionsDir(), run.session), "scripts_sql");
|
|
476
|
+
return (await deps.fs.exists(path)) ? { path, content: await deps.fs.readText(path) } : null;
|
|
477
|
+
}
|
|
478
|
+
/** A new refine must be bound to an existing plan; only pre-custody sessions degrade. */
|
|
479
|
+
async function refineDestination(deps, run, report) {
|
|
480
|
+
const custody = await readCustody(deps.fs, locateRun(deps.paths, run.session).dir);
|
|
481
|
+
if (custody.status === "unreadable") {
|
|
482
|
+
return refusal("session.artifacts", `custodia ilegible: ${custody.reason}`, report);
|
|
483
|
+
}
|
|
484
|
+
if (custody.status === "absent") {
|
|
485
|
+
return "; sesión legada sin custodia: no se puede verificar su plan destino";
|
|
486
|
+
}
|
|
487
|
+
for (const artifact of custody.custody.artifacts) {
|
|
488
|
+
if (artifact.role !== "input" || !/^docs\/plans\/\d{3,}-plan-[^/]+\.md$/.test(artifact.path))
|
|
489
|
+
continue;
|
|
490
|
+
if (await deps.fs.exists(join(deps.paths.workspaceDir(), artifact.path)))
|
|
491
|
+
return "";
|
|
492
|
+
}
|
|
493
|
+
return refusal("session.artifacts", "plan-refine exige un plan destino existente: creá la sesión con --input docs/plans/PPP-plan-<slug>.md o el descriptor <slug>-plan-refine, del que session-create deriva el plan", canonicalJson({ report, custody: custody.custody.artifacts.map((artifact) => artifact.path) }));
|
|
494
|
+
}
|
|
381
495
|
/**
|
|
382
496
|
* What a satisfied artifact reading really attests.
|
|
383
497
|
*
|
|
@@ -456,6 +570,16 @@ async function inferBatch(deps, run) {
|
|
|
456
570
|
}
|
|
457
571
|
const active = (current.batches ?? []).find((batch) => batch.published_plan_digest === undefined);
|
|
458
572
|
if (active !== undefined) {
|
|
573
|
+
if (active.commit_result !== undefined && Object.keys(active.commit_result).length > 0) {
|
|
574
|
+
return {
|
|
575
|
+
ok: false,
|
|
576
|
+
failure: {
|
|
577
|
+
code: "PLAN_EXEC_BATCH_REINFER_COMMITTED",
|
|
578
|
+
message: `${active.id} ya tiene recibos de commit y no puede re-inferirse`,
|
|
579
|
+
action: `revisá los recibos; para reabrir su trabajo usá aw flow annul --session ${run.session} --from ${active.id}`,
|
|
580
|
+
},
|
|
581
|
+
};
|
|
582
|
+
}
|
|
459
583
|
return {
|
|
460
584
|
ok: true,
|
|
461
585
|
state: current,
|
|
@@ -477,7 +601,7 @@ async function inferBatch(deps, run) {
|
|
|
477
601
|
},
|
|
478
602
|
};
|
|
479
603
|
}
|
|
480
|
-
const next =
|
|
604
|
+
const next = inferNextPlanExecBatch(text, current);
|
|
481
605
|
if (!next.ok) {
|
|
482
606
|
if (next.failure.code !== "PLAN_EXEC_BATCH_NONE_OPEN") {
|
|
483
607
|
return { ok: false, failure: next.failure };
|
|
@@ -494,6 +618,27 @@ async function inferBatch(deps, run) {
|
|
|
494
618
|
value: { batch: null, created: false, no_work: true },
|
|
495
619
|
};
|
|
496
620
|
}
|
|
621
|
+
// Store the exact plan text BEFORE publishing the inferred state. A retry
|
|
622
|
+
// either sees the same addressed copy or refuses rather than losing its base.
|
|
623
|
+
try {
|
|
624
|
+
const snapshot = sealedPlanPath(location.dir, next.batch.plan_digest);
|
|
625
|
+
await deps.fs.mkdirp(join(location.dir, ".plan-seals"));
|
|
626
|
+
const saved = await deps.fs.publishTextExclusive(snapshot, text);
|
|
627
|
+
if (!saved.created &&
|
|
628
|
+
canonicalEol(await deps.fs.readText(snapshot)) !== canonicalEol(text)) {
|
|
629
|
+
throw new Error("la copia direccionada no coincide con el plan inferido");
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
catch (error) {
|
|
633
|
+
return {
|
|
634
|
+
ok: false,
|
|
635
|
+
failure: {
|
|
636
|
+
code: "PLAN_EXEC_BATCH_SNAPSHOT_UNAVAILABLE",
|
|
637
|
+
message: `no se pudo guardar la copia sellada: ${String(error)}`,
|
|
638
|
+
action: "revisá el almacenamiento de la sesión y reintentá la inferencia",
|
|
639
|
+
},
|
|
640
|
+
};
|
|
641
|
+
}
|
|
497
642
|
return {
|
|
498
643
|
ok: true,
|
|
499
644
|
state: withPlanExecBatch(current, next.batch),
|
|
@@ -508,7 +653,7 @@ async function inferBatch(deps, run) {
|
|
|
508
653
|
summary: inferred.value.no_work
|
|
509
654
|
? "el plan ya no tiene tareas abiertas: se omite el batch vacío y se expone la validación final"
|
|
510
655
|
: inferred.value.created
|
|
511
|
-
? `batch ${inferred.value.batch?.id ?? "nuevo"} inferido y sellado antes de implementar`
|
|
656
|
+
? `batch ${inferred.value.batch?.id ?? "nuevo"} inferido y sellado antes de implementar; partición ${canonicalJson(inferred.value.batch?.partition ?? null)}`
|
|
512
657
|
: `batch ${inferred.value.batch?.id ?? "actual"} ya estaba inferido; se conserva su snapshot sellado`,
|
|
513
658
|
output: canonicalJson({ batch: inferred.value.batch, created: inferred.value.created }),
|
|
514
659
|
effects: [],
|
|
@@ -643,12 +788,26 @@ async function closeBatch(deps, run) {
|
|
|
643
788
|
return refusal("plan-exec.batch-close", "no hay un batch inferido para cerrar: la corrida no puede acreditar tareas que no selló antes de implementarlas", canonicalJson({ code: "PLAN_EXEC_BATCH_NOT_INFERRED", plan: run.scope.plan }));
|
|
644
789
|
}
|
|
645
790
|
// A batch born with a base was meant to be credited at its phase validation.
|
|
791
|
+
if (validationOnlyCloseMissing(live.state, batch)) {
|
|
792
|
+
return refusal("plan-exec.batch-close", "el lote de sólo validación carece de aprobación o de evidencia acreditada", canonicalJson({ code: "PLAN_VALIDATION_ONLY_NOT_APPROVED", batch: batch.id }));
|
|
793
|
+
}
|
|
646
794
|
// Reaching the close without that credit — an exhausted validation degraded
|
|
647
795
|
// past, a route that skipped it — would publish its tasks as done on no proof.
|
|
648
796
|
if (batch.base !== undefined && batch.credit === undefined) {
|
|
649
797
|
return refusal("plan-exec.batch-close", `el batch ${batch.id} no tiene acreditación: su validación de fase nunca aceptó una prueba propia del checkout de sus fuentes`, canonicalJson({ code: "PLAN_EXEC_BATCH_UNCREDITED", batch: batch.id, plan: run.scope.plan }));
|
|
650
798
|
}
|
|
651
799
|
const phaseUpdates = phaseUpdatesForClosedBatch(text, batch);
|
|
800
|
+
if (batch.review === undefined && batch.published_plan_digest === undefined) {
|
|
801
|
+
return refusal("plan-exec.batch-close", `el batch ${batch.id} no tiene revisión registrada; completá review-findings con un revisor distinto y las correcciones revisadas`, canonicalJson({ code: "PLAN_EXEC_BATCH_REVIEW_MISSING", batch: batch.id }));
|
|
802
|
+
}
|
|
803
|
+
if (!legacyPlanExecCommits(live.state) && batch.commit_result === undefined) {
|
|
804
|
+
return refusal("plan-exec.batch-close", `el batch ${batch.id} no tiene resultado de commits verificado`, canonicalJson({ code: "PLAN_EXEC_BATCH_COMMIT_MISSING", batch: batch.id }));
|
|
805
|
+
}
|
|
806
|
+
if (!legacyPlanExecCommits(live.state)) {
|
|
807
|
+
const gitFailure = await verifyBatchGitState(deps, run, batch, run.scope?.isolation === "in-place");
|
|
808
|
+
if (gitFailure !== null)
|
|
809
|
+
return refusal("plan-exec.batch-close", gitFailure.message, canonicalJson(gitFailure));
|
|
810
|
+
}
|
|
652
811
|
if (!phaseUpdates.ok) {
|
|
653
812
|
return refusal("plan-exec.batch-close", `${phaseUpdates.failure.message} — ${phaseUpdates.failure.action}`, canonicalJson({ failure: phaseUpdates.failure }));
|
|
654
813
|
}
|
|
@@ -676,11 +835,12 @@ async function closeBatch(deps, run) {
|
|
|
676
835
|
ok: true,
|
|
677
836
|
summary: published.already_applied
|
|
678
837
|
? `batch ${published.batch.id} ya estaba publicado en ${run.scope.plan}`
|
|
679
|
-
: `batch ${published.batch.id} publicado: ${published.written.join(", ")}`,
|
|
838
|
+
: `batch ${published.batch.id} publicado: ${published.written.join(", ")}${published.notice === undefined ? "" : `; aviso: ${published.notice}`}`,
|
|
680
839
|
output: canonicalJson({
|
|
681
840
|
batch: published.batch,
|
|
682
841
|
written: published.written,
|
|
683
842
|
already_applied: published.already_applied,
|
|
843
|
+
...(published.notice === undefined ? {} : { notice: published.notice }),
|
|
684
844
|
}),
|
|
685
845
|
effects: ["mutate_overwrite"],
|
|
686
846
|
state,
|
|
@@ -697,6 +857,10 @@ async function closeBatch(deps, run) {
|
|
|
697
857
|
* already names the NEXT batch — or nothing, when it was the last one. The
|
|
698
858
|
* publisher then confirms it through its own already-applied path.
|
|
699
859
|
*/
|
|
860
|
+
function validationOnlyCloseMissing(state, batch) {
|
|
861
|
+
return (batch.kind === "validation-only" &&
|
|
862
|
+
(!approvedValidationOnly(state, batch) || batch.credit === undefined));
|
|
863
|
+
}
|
|
700
864
|
function batchToClose(state) {
|
|
701
865
|
const batches = state.batches ?? [];
|
|
702
866
|
const open = batches.find((batch) => batch.published_plan_digest === undefined);
|
|
@@ -756,11 +920,21 @@ async function sealPlanDone(deps, run) {
|
|
|
756
920
|
return refusal("plan-exec.plan-done", "la corrida cambió mientras se preparaba el sello final", canonicalJson({ expected: run.state_digest, actual: live.state.digest }));
|
|
757
921
|
}
|
|
758
922
|
const missing = PLAN_DONE_REQUIRED_TRANSITIONS.filter((transition) => {
|
|
923
|
+
if (transition === "plan-exec.final-validation") {
|
|
924
|
+
return (!live.state.applied.includes(transition) ||
|
|
925
|
+
live.state.skipped.includes(transition) ||
|
|
926
|
+
(live.state.degraded ?? []).some((item) => item.transition === transition) ||
|
|
927
|
+
dispositionOf(live.state.route_decisions, transition)?.disposition === "substitute");
|
|
928
|
+
}
|
|
759
929
|
if (live.state.applied.includes(transition))
|
|
760
930
|
return false;
|
|
761
931
|
const disposition = dispositionOf(live.state.route_decisions, transition)?.disposition;
|
|
762
932
|
return disposition !== "omit" && disposition !== "substitute";
|
|
763
933
|
});
|
|
934
|
+
if (!legacyPlanExecCommits(live.state) &&
|
|
935
|
+
(live.state.batches ?? []).some((batch) => batch.commit_result === undefined)) {
|
|
936
|
+
return refusal("plan-exec.plan-done", "hay lotes sin recibo o resultado de commit", canonicalJson({ code: "PLAN_EXEC_DONE_BATCH_COMMIT_MISSING" }));
|
|
937
|
+
}
|
|
764
938
|
if (missing.length > 0) {
|
|
765
939
|
return refusal("plan-exec.plan-done", `todavía falta evidencia de ${missing.join(", ")}`, canonicalJson({ code: "PLAN_EXEC_DONE_PREREQUISITE", missing }));
|
|
766
940
|
}
|
|
@@ -828,6 +1002,12 @@ async function sealPlanDone(deps, run) {
|
|
|
828
1002
|
}
|
|
829
1003
|
/** The plan seal says exactly which evidence was absent or substituted. */
|
|
830
1004
|
function planDoneClosure(state, session) {
|
|
1005
|
+
const destination = state.scope?.isolation === "in-place"
|
|
1006
|
+
? `commits en el checkout (${(state.batches ?? [])
|
|
1007
|
+
.flatMap((batch) => Object.values(batch.commit_result ?? {}).map((receipt) => receipt.branch))
|
|
1008
|
+
.filter((branch) => branch !== null)
|
|
1009
|
+
.join(", ")}); sin integración`
|
|
1010
|
+
: "commits e integración";
|
|
831
1011
|
const decisions = state.route_decisions ?? [];
|
|
832
1012
|
const controls = new Map((state.route_proposal?.controls ?? []).map((control) => [control.transition, control]));
|
|
833
1013
|
const omitted = decisions
|
|
@@ -841,15 +1021,15 @@ function planDoneClosure(state, session) {
|
|
|
841
1021
|
.map((decision) => decision.substitution)
|
|
842
1022
|
.filter((substitution) => substitution !== null);
|
|
843
1023
|
if (state.assurance === "unverified_accepted") {
|
|
844
|
-
return `evidencia omitida en la propuesta aceptada (${omitted.join("; ") || "sin detalle"});
|
|
1024
|
+
return `evidencia omitida en la propuesta aceptada (${omitted.join("; ") || "sin detalle"}); ${destination} acreditados por la corrida ${session}; no se afirma que la validación pasó`;
|
|
845
1025
|
}
|
|
846
1026
|
if (state.assurance === "partially_verified") {
|
|
847
|
-
return `validación sustituta pendiente (${substitutions.map((substitution) => substitution.validation).join(", ") || "sin detalle"}); riesgo aceptado: ${substitutions.map((substitution) => substitution.risk).join(", ") || "assurance parcial"};
|
|
1027
|
+
return `validación sustituta pendiente (${substitutions.map((substitution) => substitution.validation).join(", ") || "sin detalle"}); riesgo aceptado: ${substitutions.map((substitution) => substitution.risk).join(", ") || "assurance parcial"}; ${destination} acreditados por la corrida ${session}`;
|
|
848
1028
|
}
|
|
849
1029
|
if (substitutions.length > 0) {
|
|
850
|
-
return `validación sustituta ejecutada (${substitutions.map((substitution) => substitution.validation).join(", ")});
|
|
1030
|
+
return `validación sustituta ejecutada (${substitutions.map((substitution) => substitution.validation).join(", ")}); ${destination} acreditados por la corrida ${session}`;
|
|
851
1031
|
}
|
|
852
|
-
return `validación final,
|
|
1032
|
+
return `validación final, ${destination} acreditados por la corrida ${session}`;
|
|
853
1033
|
}
|
|
854
1034
|
/** The documentary checks that must pass in the same critical section as done. */
|
|
855
1035
|
export async function planDonePrecondition(deps, path, session) {
|
|
@@ -958,40 +1138,6 @@ function phaseUpdatesForClosedBatch(text, batch) {
|
|
|
958
1138
|
updates: batch.phases.map((phase) => ({ phase, state: "validada" })),
|
|
959
1139
|
};
|
|
960
1140
|
}
|
|
961
|
-
function inferNextBatch(text, state) {
|
|
962
|
-
// `inferPlanExecBatch` itself validates that the phase has real, uniquely
|
|
963
|
-
// labelled Tn.m tasks. We only choose the first still-open phase from the
|
|
964
|
-
// document, which is a deterministic batch boundary rather than a claimed one.
|
|
965
|
-
const openPhase = parseTasks(text).items.find((task) => task.status === "open" && task.phase !== undefined)?.phase;
|
|
966
|
-
if (openPhase === undefined) {
|
|
967
|
-
const unresolved = parsePhases(text).items.find((phase) => phase.state !== "validada");
|
|
968
|
-
if (unresolved !== undefined) {
|
|
969
|
-
return {
|
|
970
|
-
ok: false,
|
|
971
|
-
failure: {
|
|
972
|
-
code: "PLAN_EXEC_BATCH_PHASE_UNRESOLVED",
|
|
973
|
-
message: `F${unresolved.n} sigue '${unresolved.state}' pero no tiene tareas abiertas acreditables`,
|
|
974
|
-
action: "normalizá la fase con plan-refine; no se salta a la validación final sobre una fase no validada",
|
|
975
|
-
},
|
|
976
|
-
};
|
|
977
|
-
}
|
|
978
|
-
return {
|
|
979
|
-
ok: false,
|
|
980
|
-
failure: {
|
|
981
|
-
code: "PLAN_EXEC_BATCH_NONE_OPEN",
|
|
982
|
-
message: "el plan no tiene una fase con tareas abiertas que este batch pueda acreditar",
|
|
983
|
-
action: "el batch ya está cerrado: reanudá la corrida para que exponga la validación final",
|
|
984
|
-
},
|
|
985
|
-
};
|
|
986
|
-
}
|
|
987
|
-
const iteration = Math.max(0, ...(state.batches ?? []).map((batch) => batch.iteration)) + 1;
|
|
988
|
-
return inferPlanExecBatch(text, {
|
|
989
|
-
id: `batch-${iteration}`,
|
|
990
|
-
iteration,
|
|
991
|
-
mode: "continuous",
|
|
992
|
-
phases: [openPhase],
|
|
993
|
-
});
|
|
994
|
-
}
|
|
995
1141
|
/**
|
|
996
1142
|
* Close the run's session — and refuse to, while it still holds a unit.
|
|
997
1143
|
*
|
|
@@ -1003,14 +1149,74 @@ function inferNextBatch(text, state) {
|
|
|
1003
1149
|
* notice behind a `.closed` marker that also makes the remedy stop resolving.
|
|
1004
1150
|
*/
|
|
1005
1151
|
async function close(deps, run) {
|
|
1006
|
-
const
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1152
|
+
const read = await readRun(deps.fs, locateRun(deps.paths, run.session));
|
|
1153
|
+
if (!read.ok && read.failure.code !== "FLOW_RUN_ABSENT") {
|
|
1154
|
+
return refusal("session.close", read.failure.message, canonicalJson(read.failure));
|
|
1155
|
+
}
|
|
1156
|
+
const boundaryClose = read.ok && read.state.reentries?.at(-1)?.kind === "close";
|
|
1157
|
+
const listed = await runWorktree({ fs: deps.fs, env: deps.env, git: deps.git, paths: deps.paths }, { action: "list" });
|
|
1158
|
+
if (!("units" in listed)) {
|
|
1159
|
+
return refusal("session.close", "no se pudieron leer las unidades; revisá 'aw worktree list' y reintentá con 'aw flow advance'", canonicalJson(listed));
|
|
1160
|
+
}
|
|
1161
|
+
const classified = await classifyListedUnits(deps, listed.units);
|
|
1162
|
+
const pending = boundaryClose
|
|
1163
|
+
? await preserveBoundaryClose(deps.fs, deps.paths, deps.git, read.state, classified, listed.unreadable ?? [])
|
|
1164
|
+
: [];
|
|
1165
|
+
const documents = read.ok ? await closeDocumentGuidance(deps.fs, deps.paths, read.state) : [];
|
|
1166
|
+
const result = await runSessionClose(deps.fs, deps.paths, {
|
|
1167
|
+
code: run.code,
|
|
1168
|
+
withEvidence: read.ok &&
|
|
1169
|
+
read.state.events.some((event) => event.kind === "executed" && event.operation === "workspace.evidence-approved"),
|
|
1170
|
+
// `Cerrar` and a consented QUICK escalation are explicit human exits:
|
|
1171
|
+
// incomplete criteria travel in BACKLOG, not as an invented completion.
|
|
1172
|
+
force: boundaryClose ||
|
|
1173
|
+
(read.ok &&
|
|
1174
|
+
read.state.flow === "quick" &&
|
|
1175
|
+
read.state.applied.includes("quick.escalation-destination") &&
|
|
1176
|
+
!read.state.skipped.includes("quick.escalation-destination")),
|
|
1177
|
+
requireIntegrated: !boundaryClose,
|
|
1178
|
+
final: !boundaryClose,
|
|
1179
|
+
preserveReservations: boundaryClose
|
|
1180
|
+
? (read.state.proposal?.artifacts.filter((a) => a.reserved).map((a) => a.path) ?? [])
|
|
1181
|
+
: [],
|
|
1182
|
+
}, async () => ({ units: classified, unreadable: listed.unreadable ?? [] }), deps.git, undefined, (alias, folder) => releaseClassifiedUnit(deps, alias, folder));
|
|
1183
|
+
if ("sessionClose" in result) {
|
|
1184
|
+
const approval = read.ok
|
|
1185
|
+
? [...read.state.events]
|
|
1186
|
+
.reverse()
|
|
1187
|
+
.find((event) => event.kind === "executed" && event.operation === "workspace.commit-approved")
|
|
1188
|
+
: undefined;
|
|
1189
|
+
if (approval?.kind === "executed") {
|
|
1190
|
+
if (result.sessionClose.archive_error !== undefined ||
|
|
1191
|
+
result.sessionClose.history_error !== undefined) {
|
|
1192
|
+
result.sessionClose.commit_error = `no se ejecutó el commit: ${result.sessionClose.archive_error ?? result.sessionClose.history_error}`;
|
|
1193
|
+
}
|
|
1194
|
+
else {
|
|
1195
|
+
try {
|
|
1196
|
+
const accepted = JSON.parse(approval.summary);
|
|
1197
|
+
if (typeof accepted === "object" &&
|
|
1198
|
+
accepted !== null &&
|
|
1199
|
+
"approval" in accepted &&
|
|
1200
|
+
typeof accepted.approval === "string") {
|
|
1201
|
+
const commit = await runWorkspaceCommit(deps.fs, deps.git, undefined, deps.paths, {
|
|
1202
|
+
code: run.session,
|
|
1203
|
+
approval: accepted.approval,
|
|
1204
|
+
withEvidence: read.ok &&
|
|
1205
|
+
read.state.events.some((event) => event.kind === "executed" && event.operation === "workspace.evidence-approved"),
|
|
1206
|
+
});
|
|
1207
|
+
if ("committed" in commit && commit.committed)
|
|
1208
|
+
result.sessionClose.commit_receipt = commit.committed;
|
|
1209
|
+
else
|
|
1210
|
+
result.sessionClose.commit_error =
|
|
1211
|
+
"error" in commit ? commit.error : "el commit aprobado no se produjo";
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
catch (error) {
|
|
1215
|
+
result.sessionClose.commit_error = error instanceof Error ? error.message : String(error);
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1014
1220
|
if ("sessionHeld" in result) {
|
|
1015
1221
|
const held = result.sessionHeld;
|
|
1016
1222
|
return refusal("session.close", `${held.reason} — integralas con '${held.integrate}'`, canonicalJson(result));
|
|
@@ -1020,15 +1226,27 @@ async function close(deps, run) {
|
|
|
1020
1226
|
return refusal("session.close", `la sesión no cerró: ${why}`, canonicalJson(result));
|
|
1021
1227
|
}
|
|
1022
1228
|
const closed = result.sessionClose;
|
|
1229
|
+
if (documents.length > 0)
|
|
1230
|
+
closed.outdated_documents = documents;
|
|
1231
|
+
if (boundaryClose) {
|
|
1232
|
+
closed.pending_work = pending;
|
|
1233
|
+
closed.reopen = `aw session-resume --code ${run.session} --reopen`;
|
|
1234
|
+
}
|
|
1023
1235
|
return {
|
|
1024
1236
|
ok: closed.closed,
|
|
1025
|
-
summary: `sesión ${closed.folder} cerrada${closed.history === undefined ? " (sin fila de HISTORY)" : ` · HISTORY ${closed.history.action}`}`,
|
|
1237
|
+
summary: `sesión ${closed.folder} cerrada${closed.history === undefined ? " (sin fila de HISTORY)" : ` · HISTORY ${closed.history.action}`}${closed.sql_pending_export === undefined ? "" : ` · sql_pending_export: ${closed.sql_pending_export.files.join(", ")} → ${closed.sql_pending_export.command}`}${pending.length === 0 ? "" : ` · ${pending.join(" ")} · ${closed.reopen}`}${documents.length === 0 ? "" : ` · ${documents.join(" · ")}`}${!boundaryClose && closed.unverifiable_sources?.length ? ` · no verificable: ${closed.unverifiable_sources.map((item) => `${item.alias}: ${item.reason}`).join("; ")}` : ""}${closed.empty_units?.length ? ` · vacías conservadas: ${closed.empty_units.map((item) => item.alias).join(", ")}` : ""}${closed.preserved_units?.length ? ` · preservadas conservadas: ${closed.preserved_units.map((item) => item.alias).join(", ")}` : ""}${closed.released_empty?.length ? ` · vacías liberadas: ${closed.released_empty.map((item) => item.alias).join(", ")}` : ""}${closed.released_preserved?.length ? ` · preservadas liberadas: ${closed.released_preserved.map((item) => item.alias).join(", ")}` : ""}${closed.released_integrated?.length ? ` · integradas liberadas: ${closed.released_integrated.map((item) => item.alias).join(", ")}` : ""}${closed.commit_receipt ? ` · commit ${closed.commit_receipt.after}` : closed.commit_error ? ` · commit pendiente: ${closed.commit_error}` : ""}`,
|
|
1026
1238
|
output: canonicalJson(result),
|
|
1027
1239
|
// Closing ensures the CHECKPOINT exists and rewrites the session's marker plus
|
|
1028
1240
|
// its HISTORY row: additive and overwriting, both real.
|
|
1029
1241
|
effects: closed.closed ? ["local_additive", "mutate_overwrite"] : [],
|
|
1030
1242
|
};
|
|
1031
1243
|
}
|
|
1244
|
+
async function releaseClassifiedUnit(deps, alias, folder) {
|
|
1245
|
+
const result = await runWorktree({ fs: deps.fs, env: deps.env, git: deps.git, paths: deps.paths }, { action: "release", alias, sessionCode: folder });
|
|
1246
|
+
if ("error" in result || "released" in result)
|
|
1247
|
+
return result;
|
|
1248
|
+
return { error: "unit_unresolved", message: `no se pudo liberar ${alias} de ${folder}` };
|
|
1249
|
+
}
|
|
1032
1250
|
function refusal(operation, message, output) {
|
|
1033
1251
|
return { ok: false, summary: `${operation}: ${message}`, output, effects: [] };
|
|
1034
1252
|
}
|