dorfl 0.1.1 → 0.2.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/dist/advance-ci-template.d.ts +3 -3
- package/dist/advance-ci-template.js +1 -1
- package/dist/advance-ci-template.js.map +1 -1
- package/dist/advance-classify.d.ts +5 -5
- package/dist/advance-classify.d.ts.map +1 -1
- package/dist/advance-classify.js +4 -4
- package/dist/advance-drivers.d.ts +8 -8
- package/dist/advance-drivers.d.ts.map +1 -1
- package/dist/advance-drivers.js +20 -8
- package/dist/advance-drivers.js.map +1 -1
- package/dist/advance-isolated.d.ts +3 -3
- package/dist/advance-isolated.d.ts.map +1 -1
- package/dist/advance-isolated.js +1 -1
- package/dist/advance-lifecycle-template.d.ts +2 -2
- package/dist/advance-lifecycle-template.d.ts.map +1 -1
- package/dist/advance-lifecycle-template.js +85 -13
- package/dist/advance-lifecycle-template.js.map +1 -1
- package/dist/advance-loop-driver.d.ts +3 -3
- package/dist/advance-loop-driver.d.ts.map +1 -1
- package/dist/advance-loop-driver.js +1 -1
- package/dist/advance-treeless-publish.d.ts +24 -1
- package/dist/advance-treeless-publish.d.ts.map +1 -1
- package/dist/advance-treeless-publish.js +41 -0
- package/dist/advance-treeless-publish.js.map +1 -1
- package/dist/advance.d.ts +69 -17
- package/dist/advance.d.ts.map +1 -1
- package/dist/advance.js +409 -102
- package/dist/advance.js.map +1 -1
- package/dist/advancing-lock.d.ts +31 -3
- package/dist/advancing-lock.d.ts.map +1 -1
- package/dist/advancing-lock.js +55 -5
- package/dist/advancing-lock.js.map +1 -1
- package/dist/agent-launch.d.ts +12 -0
- package/dist/agent-launch.d.ts.map +1 -1
- package/dist/agent-launch.js +22 -12
- package/dist/agent-launch.js.map +1 -1
- package/dist/agent-stop.d.ts +40 -2
- package/dist/agent-stop.d.ts.map +1 -1
- package/dist/agent-stop.js +30 -2
- package/dist/agent-stop.js.map +1 -1
- package/dist/apply-decide.d.ts +19 -5
- package/dist/apply-decide.d.ts.map +1 -1
- package/dist/apply-decide.js +38 -9
- package/dist/apply-decide.js.map +1 -1
- package/dist/apply-merge-action.d.ts +20 -8
- package/dist/apply-merge-action.d.ts.map +1 -1
- package/dist/apply-merge-action.js +44 -9
- package/dist/apply-merge-action.js.map +1 -1
- package/dist/apply-persist.d.ts +62 -31
- package/dist/apply-persist.d.ts.map +1 -1
- package/dist/apply-persist.js +173 -44
- package/dist/apply-persist.js.map +1 -1
- package/dist/apply-stuck-action.d.ts +151 -0
- package/dist/apply-stuck-action.d.ts.map +1 -0
- package/dist/apply-stuck-action.js +125 -0
- package/dist/apply-stuck-action.js.map +1 -0
- package/dist/brand.d.ts +12 -1
- package/dist/brand.d.ts.map +1 -1
- package/dist/brand.js +2 -1
- package/dist/brand.js.map +1 -1
- package/dist/buildable-body.d.ts +14 -14
- package/dist/buildable-body.js +9 -9
- package/dist/claim-cas.d.ts +3 -3
- package/dist/claim-cas.js +1 -1
- package/dist/claim-cas.js.map +1 -1
- package/dist/cli-spinner.d.ts +1 -1
- package/dist/cli-spinner.js +1 -1
- package/dist/cli.d.ts +10 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +385 -128
- package/dist/cli.js.map +1 -1
- package/dist/close-job-template.d.ts +3 -3
- package/dist/close-job-template.js +9 -9
- package/dist/close-job.d.ts +8 -8
- package/dist/close-job.js +25 -25
- package/dist/close-job.js.map +1 -1
- package/dist/complete.d.ts +9 -6
- package/dist/complete.d.ts.map +1 -1
- package/dist/complete.js +99 -45
- package/dist/complete.js.map +1 -1
- package/dist/concurrency.d.ts +1 -1
- package/dist/concurrency.js +1 -1
- package/dist/config.d.ts +86 -40
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +61 -9
- package/dist/config.js.map +1 -1
- package/dist/continue-branch.d.ts +1 -1
- package/dist/continue-branch.d.ts.map +1 -1
- package/dist/continue-branch.js +23 -1
- package/dist/continue-branch.js.map +1 -1
- package/dist/cwd-section.js +1 -1
- package/dist/cwd-section.js.map +1 -1
- package/dist/decision-engine.d.ts +39 -11
- package/dist/decision-engine.d.ts.map +1 -1
- package/dist/decision-engine.js +10 -6
- package/dist/decision-engine.js.map +1 -1
- package/dist/do-autopick.d.ts +6 -6
- package/dist/do-autopick.d.ts.map +1 -1
- package/dist/do-autopick.js +16 -6
- package/dist/do-autopick.js.map +1 -1
- package/dist/do-config.d.ts +4 -4
- package/dist/do-config.js +3 -3
- package/dist/do-config.js.map +1 -1
- package/dist/do-remote-auto.d.ts +2 -2
- package/dist/do-remote-auto.js +1 -1
- package/dist/do.d.ts +74 -81
- package/dist/do.d.ts.map +1 -1
- package/dist/do.js +439 -50
- package/dist/do.js.map +1 -1
- package/dist/drop-source.d.ts +2 -2
- package/dist/env-config.d.ts.map +1 -1
- package/dist/env-config.js +19 -11
- package/dist/env-config.js.map +1 -1
- package/dist/failure-cause.d.ts +3 -2
- package/dist/failure-cause.d.ts.map +1 -1
- package/dist/failure-cause.js +28 -1
- package/dist/failure-cause.js.map +1 -1
- package/dist/format.d.ts +6 -6
- package/dist/format.d.ts.map +1 -1
- package/dist/format.js +13 -30
- package/dist/format.js.map +1 -1
- package/dist/frontmatter.d.ts +28 -15
- package/dist/frontmatter.d.ts.map +1 -1
- package/dist/frontmatter.js +38 -24
- package/dist/frontmatter.js.map +1 -1
- package/dist/gc.d.ts +65 -6
- package/dist/gc.d.ts.map +1 -1
- package/dist/gc.js +126 -9
- package/dist/gc.js.map +1 -1
- package/dist/github.d.ts +14 -0
- package/dist/github.d.ts.map +1 -1
- package/dist/github.js +73 -0
- package/dist/github.js.map +1 -1
- package/dist/harness.d.ts +25 -0
- package/dist/harness.d.ts.map +1 -1
- package/dist/harness.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/install-ci-branch-protection.d.ts +133 -39
- package/dist/install-ci-branch-protection.d.ts.map +1 -1
- package/dist/install-ci-branch-protection.js +191 -49
- package/dist/install-ci-branch-protection.js.map +1 -1
- package/dist/install-ci-capabilities/advance-lifecycle.d.ts +1 -1
- package/dist/install-ci-capabilities/advance-lifecycle.js +1 -1
- package/dist/install-ci-capabilities/close-job.d.ts +1 -1
- package/dist/install-ci-capabilities/close-job.js +1 -1
- package/dist/install-ci-capabilities/example-noop.d.ts +1 -1
- package/dist/install-ci-capabilities/example-noop.js +1 -1
- package/dist/install-ci-capabilities/intake.d.ts +2 -2
- package/dist/install-ci-capabilities/intake.js +2 -2
- package/dist/install-ci-capabilities/verify.d.ts +1 -1
- package/dist/install-ci-capabilities/verify.js +1 -1
- package/dist/install-ci-core.d.ts +24 -4
- package/dist/install-ci-core.d.ts.map +1 -1
- package/dist/install-ci-core.js +12 -5
- package/dist/install-ci-core.js.map +1 -1
- package/dist/install-ci-github.d.ts +33 -1
- package/dist/install-ci-github.d.ts.map +1 -1
- package/dist/install-ci-github.js +74 -1
- package/dist/install-ci-github.js.map +1 -1
- package/dist/install-ci.d.ts +1 -1
- package/dist/install-ci.js +4 -4
- package/dist/install-ci.js.map +1 -1
- package/dist/install-skills.d.ts +123 -0
- package/dist/install-skills.d.ts.map +1 -0
- package/dist/install-skills.js +100 -0
- package/dist/install-skills.js.map +1 -0
- package/dist/intake-event.d.ts +6 -6
- package/dist/intake-event.js +6 -6
- package/dist/intake-marker.d.ts +3 -3
- package/dist/intake-marker.d.ts.map +1 -1
- package/dist/intake-triage.d.ts +1 -1
- package/dist/intake-triage.js +2 -2
- package/dist/intake-trigger-template.d.ts +8 -8
- package/dist/intake-trigger-template.d.ts.map +1 -1
- package/dist/intake-trigger-template.js +17 -17
- package/dist/intake-trigger-template.js.map +1 -1
- package/dist/intake.d.ts +65 -52
- package/dist/intake.d.ts.map +1 -1
- package/dist/intake.js +92 -76
- package/dist/intake.js.map +1 -1
- package/dist/integration-core.d.ts +27 -24
- package/dist/integration-core.d.ts.map +1 -1
- package/dist/integration-core.js +191 -77
- package/dist/integration-core.js.map +1 -1
- package/dist/integrator.d.ts +1 -1
- package/dist/integrator.d.ts.map +1 -1
- package/dist/integrator.js +19 -3
- package/dist/integrator.js.map +1 -1
- package/dist/isolation.d.ts +4 -4
- package/dist/isolation.d.ts.map +1 -1
- package/dist/isolation.js +9 -0
- package/dist/isolation.js.map +1 -1
- package/dist/issue-provider.d.ts +4 -4
- package/dist/issue-provider.js +1 -1
- package/dist/item-lock.d.ts +216 -149
- package/dist/item-lock.d.ts.map +1 -1
- package/dist/item-lock.js +345 -270
- package/dist/item-lock.js.map +1 -1
- package/dist/item-path.d.ts +2 -2
- package/dist/item-path.js +2 -2
- package/dist/ledger-lint.d.ts +9 -9
- package/dist/ledger-lint.js +9 -9
- package/dist/ledger-read.d.ts +57 -57
- package/dist/ledger-read.d.ts.map +1 -1
- package/dist/ledger-read.js +24 -24
- package/dist/ledger-read.js.map +1 -1
- package/dist/ledger-write.d.ts +33 -28
- package/dist/ledger-write.d.ts.map +1 -1
- package/dist/ledger-write.js +100 -122
- package/dist/ledger-write.js.map +1 -1
- package/dist/lifecycle-gather.d.ts +18 -1
- package/dist/lifecycle-gather.d.ts.map +1 -1
- package/dist/lifecycle-gather.js +23 -17
- package/dist/lifecycle-gather.js.map +1 -1
- package/dist/lifecycle-pools.d.ts +44 -7
- package/dist/lifecycle-pools.d.ts.map +1 -1
- package/dist/lifecycle-pools.js +27 -7
- package/dist/lifecycle-pools.js.map +1 -1
- package/dist/merge-question-surfacer.d.ts +18 -4
- package/dist/merge-question-surfacer.d.ts.map +1 -1
- package/dist/merge-question-surfacer.js +20 -5
- package/dist/merge-question-surfacer.js.map +1 -1
- package/dist/migrate-stuck-locks.d.ts +129 -0
- package/dist/migrate-stuck-locks.d.ts.map +1 -0
- package/dist/migrate-stuck-locks.js +355 -0
- package/dist/migrate-stuck-locks.js.map +1 -0
- package/dist/mint-adr.js +4 -4
- package/dist/mirror-pool-scan.d.ts +2 -2
- package/dist/mirror-pool-scan.js +3 -3
- package/dist/mirror-pool-scan.js.map +1 -1
- package/dist/needs-attention.d.ts +304 -27
- package/dist/needs-attention.d.ts.map +1 -1
- package/dist/needs-attention.js +542 -67
- package/dist/needs-attention.js.map +1 -1
- package/dist/orphan-sidecar.d.ts +10 -6
- package/dist/orphan-sidecar.d.ts.map +1 -1
- package/dist/orphan-sidecar.js +35 -2
- package/dist/orphan-sidecar.js.map +1 -1
- package/dist/pi-harness.d.ts +16 -0
- package/dist/pi-harness.d.ts.map +1 -1
- package/dist/pi-harness.js +82 -2
- package/dist/pi-harness.js.map +1 -1
- package/dist/placement.d.ts +8 -8
- package/dist/placement.js +3 -3
- package/dist/prd-to-spec.d.ts.map +1 -1
- package/dist/prd-to-spec.js +9 -5
- package/dist/prd-to-spec.js.map +1 -1
- package/dist/prompt.d.ts +16 -19
- package/dist/prompt.d.ts.map +1 -1
- package/dist/prompt.js +17 -19
- package/dist/prompt.js.map +1 -1
- package/dist/protocol/CLAIM-PROTOCOL.md +17 -10
- package/dist/protocol/REVIEW-PROTOCOL.md +4 -1
- package/dist/protocol/SURFACE-PROTOCOL.md +16 -2
- package/dist/protocol/TASKING-PROTOCOL.md +3 -1
- package/dist/protocol/WORK-CONTRACT.md +22 -18
- package/dist/protocol/task-template.md +1 -1
- package/dist/readiness.d.ts +1 -1
- package/dist/reap-branches.d.ts +12 -9
- package/dist/reap-branches.d.ts.map +1 -1
- package/dist/reap-branches.js +25 -7
- package/dist/reap-branches.js.map +1 -1
- package/dist/recover-isolated.d.ts +12 -0
- package/dist/recover-isolated.d.ts.map +1 -1
- package/dist/recover-isolated.js +6 -1
- package/dist/recover-isolated.js.map +1 -1
- package/dist/repo-config.d.ts +23 -2
- package/dist/repo-config.d.ts.map +1 -1
- package/dist/repo-config.js +64 -18
- package/dist/repo-config.js.map +1 -1
- package/dist/repo-mirror.d.ts.map +1 -1
- package/dist/repo-mirror.js +18 -2
- package/dist/repo-mirror.js.map +1 -1
- package/dist/review-gate.d.ts +3 -3
- package/dist/review-gate.d.ts.map +1 -1
- package/dist/review-gate.js +11 -10
- package/dist/review-gate.js.map +1 -1
- package/dist/review-verdict.d.ts +2 -2
- package/dist/review-verdict.d.ts.map +1 -1
- package/dist/review-verdict.js +2 -2
- package/dist/review-verdict.js.map +1 -1
- package/dist/run.d.ts +2 -2
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +58 -23
- package/dist/run.js.map +1 -1
- package/dist/scan.d.ts +26 -17
- package/dist/scan.d.ts.map +1 -1
- package/dist/scan.js +29 -15
- package/dist/scan.js.map +1 -1
- package/dist/select-order.d.ts +1 -1
- package/dist/select-priority.d.ts +14 -14
- package/dist/select-priority.d.ts.map +1 -1
- package/dist/select-priority.js +5 -5
- package/dist/select-priority.js.map +1 -1
- package/dist/sidecar-apply.js +1 -1
- package/dist/sidecar-apply.js.map +1 -1
- package/dist/sidecar.d.ts +47 -12
- package/dist/sidecar.d.ts.map +1 -1
- package/dist/sidecar.js +84 -4
- package/dist/sidecar.js.map +1 -1
- package/dist/skills/answer-questions/SKILL.md +89 -0
- package/dist/skills/capture-signal/SKILL.md +52 -0
- package/dist/skills/convert-from-prd-to-spec/SKILL.md +90 -0
- package/dist/skills/drive-tasks/SKILL.md +218 -0
- package/dist/skills/from-idea/SKILL.md +83 -0
- package/dist/skills/merge-prs/SKILL.md +70 -0
- package/dist/skills/orchestrate/SKILL.md +101 -0
- package/dist/skills/promote/SKILL.md +35 -0
- package/dist/skills/review/SKILL.md +16 -0
- package/dist/skills/setup/SKILL.md +258 -0
- package/dist/skills/setup/protocol/ADR-FORMAT.md +47 -0
- package/dist/skills/setup/protocol/CLAIM-PROTOCOL.md +224 -0
- package/dist/skills/setup/protocol/REVIEW-PROTOCOL.md +122 -0
- package/dist/skills/setup/protocol/SURFACE-PROTOCOL.md +135 -0
- package/dist/skills/setup/protocol/TASKING-PROTOCOL.md +124 -0
- package/dist/skills/setup/protocol/WORK-CONTRACT.md +280 -0
- package/dist/skills/setup/protocol/spec-template.md +71 -0
- package/dist/skills/setup/protocol/task-template.md +65 -0
- package/dist/skills/surface-questions/SKILL.md +16 -0
- package/dist/skills/to-spec/SKILL.md +34 -0
- package/dist/skills/to-task/SKILL.md +19 -0
- package/dist/skills/triage-observations/SKILL.md +78 -0
- package/dist/skills/work/SKILL.md +51 -0
- package/dist/slug-namespace.d.ts +6 -6
- package/dist/slug-namespace.js +8 -8
- package/dist/slug-namespace.js.map +1 -1
- package/dist/spec-complete.d.ts.map +1 -1
- package/dist/spec-complete.js +4 -5
- package/dist/spec-complete.js.map +1 -1
- package/dist/start.d.ts +1 -1
- package/dist/start.d.ts.map +1 -1
- package/dist/start.js +54 -60
- package/dist/start.js.map +1 -1
- package/dist/status.d.ts +3 -3
- package/dist/status.js +4 -4
- package/dist/status.js.map +1 -1
- package/dist/surface-gate.d.ts +2 -2
- package/dist/surface-gate.d.ts.map +1 -1
- package/dist/surface-gate.js +10 -3
- package/dist/surface-gate.js.map +1 -1
- package/dist/surface-persist.d.ts +2 -2
- package/dist/surface-persist.d.ts.map +1 -1
- package/dist/surface-persist.js +1 -1
- package/dist/surface-persist.js.map +1 -1
- package/dist/tasker-review-loop.d.ts +11 -10
- package/dist/tasker-review-loop.d.ts.map +1 -1
- package/dist/tasker-review-loop.js +8 -8
- package/dist/tasker-review-loop.js.map +1 -1
- package/dist/tasking-eligibility.d.ts +21 -21
- package/dist/tasking-eligibility.d.ts.map +1 -1
- package/dist/tasking-eligibility.js +10 -10
- package/dist/tasking-lock.d.ts +10 -10
- package/dist/tasking-lock.d.ts.map +1 -1
- package/dist/tasking-lock.js +69 -49
- package/dist/tasking-lock.js.map +1 -1
- package/dist/tasking.d.ts +73 -39
- package/dist/tasking.d.ts.map +1 -1
- package/dist/tasking.js +309 -95
- package/dist/tasking.js.map +1 -1
- package/dist/triage-gate.d.ts +1 -1
- package/dist/triage-persist.d.ts +15 -11
- package/dist/triage-persist.d.ts.map +1 -1
- package/dist/triage-persist.js +48 -18
- package/dist/triage-persist.js.map +1 -1
- package/dist/vendor/incur/agents.d.ts +58 -0
- package/dist/vendor/incur/agents.d.ts.map +1 -0
- package/dist/vendor/incur/agents.js +343 -0
- package/dist/vendor/incur/agents.js.map +1 -0
- package/dist/verify-workflow-template.d.ts +1 -1
- package/dist/verify-workflow-template.js +3 -3
- package/dist/watch-session.d.ts +11 -3
- package/dist/watch-session.d.ts.map +1 -1
- package/dist/watch-session.js +94 -7
- package/dist/watch-session.js.map +1 -1
- package/dist/work-layout.d.ts +15 -9
- package/dist/work-layout.d.ts.map +1 -1
- package/dist/work-layout.js +14 -9
- package/dist/work-layout.js.map +1 -1
- package/dist/workspace.d.ts +2 -2
- package/package.json +2 -2
- package/src/advance-ci-template.ts +4 -4
- package/src/advance-classify.ts +5 -5
- package/src/advance-drivers.ts +26 -13
- package/src/advance-isolated.ts +3 -3
- package/src/advance-lifecycle-template.ts +98 -13
- package/src/advance-loop-driver.ts +3 -3
- package/src/advance-treeless-publish.ts +46 -1
- package/src/advance.ts +495 -115
- package/src/advancing-lock.ts +102 -7
- package/src/agent-launch.ts +37 -12
- package/src/agent-stop.ts +60 -2
- package/src/apply-decide.ts +38 -9
- package/src/apply-merge-action.ts +49 -11
- package/src/apply-persist.ts +236 -62
- package/src/apply-stuck-action.ts +260 -0
- package/src/brand.ts +14 -2
- package/src/buildable-body.ts +14 -14
- package/src/claim-cas.ts +4 -4
- package/src/cli-spinner.ts +1 -1
- package/src/cli.ts +472 -141
- package/src/close-job-template.ts +9 -9
- package/src/close-job.ts +26 -26
- package/src/complete.ts +121 -63
- package/src/concurrency.ts +1 -1
- package/src/config.ts +143 -49
- package/src/continue-branch.ts +23 -1
- package/src/cwd-section.ts +1 -1
- package/src/decision-engine.ts +57 -19
- package/src/do-autopick.ts +21 -10
- package/src/do-config.ts +7 -7
- package/src/do-remote-auto.ts +2 -2
- package/src/do.ts +558 -85
- package/src/drop-source.ts +2 -2
- package/src/env-config.ts +19 -11
- package/src/failure-cause.ts +30 -1
- package/src/format.ts +13 -33
- package/src/frontmatter.ts +55 -35
- package/src/gc.ts +172 -9
- package/src/github.ts +78 -0
- package/src/harness.ts +25 -0
- package/src/index.ts +10 -0
- package/src/install-ci-branch-protection.ts +283 -58
- package/src/install-ci-capabilities/advance-lifecycle.ts +1 -1
- package/src/install-ci-capabilities/close-job.ts +1 -1
- package/src/install-ci-capabilities/example-noop.ts +1 -1
- package/src/install-ci-capabilities/intake.ts +2 -2
- package/src/install-ci-capabilities/verify.ts +1 -1
- package/src/install-ci-core.ts +34 -7
- package/src/install-ci-github.ts +87 -1
- package/src/install-ci.ts +4 -4
- package/src/install-skills.ts +166 -0
- package/src/intake-event.ts +6 -6
- package/src/intake-marker.ts +3 -3
- package/src/intake-triage.ts +2 -2
- package/src/intake-trigger-template.ts +18 -18
- package/src/intake.ts +138 -103
- package/src/integration-core.ts +234 -100
- package/src/integrator.ts +22 -9
- package/src/isolation.ts +13 -4
- package/src/issue-provider.ts +4 -4
- package/src/item-lock.ts +505 -361
- package/src/item-path.ts +2 -2
- package/src/ledger-lint.ts +9 -9
- package/src/ledger-read.ts +81 -81
- package/src/ledger-write.ts +137 -152
- package/src/lifecycle-gather.ts +45 -22
- package/src/lifecycle-pools.ts +71 -13
- package/src/merge-question-surfacer.ts +32 -8
- package/src/migrate-stuck-locks.ts +451 -0
- package/src/mint-adr.ts +4 -4
- package/src/mirror-pool-scan.ts +5 -5
- package/src/needs-attention.ts +877 -104
- package/src/orphan-sidecar.ts +49 -8
- package/src/pi-harness.ts +82 -2
- package/src/placement.ts +8 -8
- package/src/prd-to-spec.ts +13 -5
- package/src/prompt.ts +20 -25
- package/src/readiness.ts +1 -1
- package/src/reap-branches.ts +38 -14
- package/src/recover-isolated.ts +18 -1
- package/src/repo-config.ts +66 -17
- package/src/repo-mirror.ts +23 -1
- package/src/review-gate.ts +12 -11
- package/src/review-verdict.ts +3 -3
- package/src/run.ts +69 -23
- package/src/scan.ts +36 -22
- package/src/select-order.ts +1 -1
- package/src/select-priority.ts +15 -15
- package/src/sidecar-apply.ts +1 -1
- package/src/sidecar.ts +141 -14
- package/src/slug-namespace.ts +10 -10
- package/src/spec-complete.ts +4 -5
- package/src/start.ts +57 -63
- package/src/status.ts +7 -7
- package/src/surface-gate.ts +12 -5
- package/src/surface-persist.ts +3 -3
- package/src/tasker-review-loop.ts +18 -17
- package/src/tasking-eligibility.ts +21 -21
- package/src/tasking-lock.ts +75 -60
- package/src/tasking.ts +381 -135
- package/src/triage-gate.ts +1 -1
- package/src/triage-persist.ts +71 -27
- package/src/vendor/incur/LICENSE +21 -0
- package/src/vendor/incur/README.md +19 -0
- package/src/vendor/incur/agents.ts +392 -0
- package/src/verify-workflow-template.ts +3 -3
- package/src/watch-session.ts +102 -7
- package/src/work-layout.ts +14 -9
- package/src/workspace.ts +2 -2
package/src/apply-persist.ts
CHANGED
|
@@ -1,23 +1,27 @@
|
|
|
1
|
-
import {existsSync, readFileSync} from 'node:fs';
|
|
2
|
-
import {join} from 'node:path';
|
|
1
|
+
import {existsSync, mkdirSync, readFileSync, writeFileSync} from 'node:fs';
|
|
2
|
+
import {dirname, join} from 'node:path';
|
|
3
3
|
import {run, type RunResult} from './git.js';
|
|
4
|
+
import {setFrontmatterMarker} from './frontmatter.js';
|
|
4
5
|
import {applyAtomic, type ApplyAtomicResult} from './sidecar-apply.js';
|
|
5
6
|
import {
|
|
6
7
|
allAnswered,
|
|
7
8
|
appendQuestions,
|
|
8
9
|
parseSidecar,
|
|
10
|
+
resolveSidecarIdentity,
|
|
9
11
|
sidecarPathFor,
|
|
10
12
|
type NewQuestion,
|
|
11
13
|
type SidecarEntry,
|
|
12
14
|
type SidecarModel,
|
|
15
|
+
type SidecarType,
|
|
13
16
|
} from './sidecar.js';
|
|
14
17
|
import {
|
|
15
18
|
APPLY_LIFECYCLE_FOLDERS,
|
|
16
19
|
resolveItemPathByIdentity,
|
|
17
20
|
} from './item-path.js';
|
|
21
|
+
import {workItemRel} from './work-layout.js';
|
|
18
22
|
|
|
19
23
|
/**
|
|
20
|
-
* The engine-owned APPLY PERSIST (
|
|
24
|
+
* The engine-owned APPLY PERSIST (spec `advance-loop`, task `advance-rung-apply`;
|
|
21
25
|
* AGENTIC apply, task `agentic-apply-retire-disposition-vocabulary`) — the half of
|
|
22
26
|
* the APPLY rung the ENGINE owns. On `classify=apply` (ALL sidecar entries
|
|
23
27
|
* answered), it applies the HUMAN's answers to the item ATOMICALLY (item body +
|
|
@@ -27,10 +31,15 @@ import {
|
|
|
27
31
|
* - **append / re-pause** — when the apply has NEW questions to ask: append
|
|
28
32
|
* `qN+1…`, stay `needsAnswers:true`, re-pause (the "all answered?" flips back
|
|
29
33
|
* to false); OR
|
|
30
|
-
* - **
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
+
* - **dispose** — when the caller decided the SOURCE should be DISPOSED
|
|
35
|
+
* (`dispose` set): REGIME-POLYMORPHIC on the source's type (task
|
|
36
|
+
* `apply-disposition-delete-to-dispose-regime-polymorphic`, spec
|
|
37
|
+
* `surface-stuck-as-questions-and-retire-stuck-lock-state` decision #5):
|
|
38
|
+
* an OBSERVATION is `git rm`-ed with its sidecar in one revertible commit
|
|
39
|
+
* (reason in the message, git history = archive); a TASK is `git mv`-ed to
|
|
40
|
+
* `tasks/cancelled/` (RETAINED, `reason:` written into the moved body); a
|
|
41
|
+
* SPEC is `git mv`-ed to `specs/dropped/` (RETAINED). A task can NEVER be
|
|
42
|
+
* hard-deleted from here — dispose is the only path off the board; OR
|
|
34
43
|
* - **resolve fully** (the default) — clear `needsAnswers` + DELETE the sidecar
|
|
35
44
|
* in the SAME atomic commit (the invariant `needsAnswers:false ⟺ no active
|
|
36
45
|
* sidecar`); the item advances toward build by its normal lifecycle.
|
|
@@ -41,19 +50,19 @@ import {
|
|
|
41
50
|
* no `keep`/`triaged:keep` resting state. A sidecar entry is BINARY (no-answer |
|
|
42
51
|
* answered); what to DO with a fully-answered OBSERVATION is decided by the
|
|
43
52
|
* AGENTIC apply decision in the advance tick (`advance.ts` `applyRung` over the
|
|
44
|
-
* shared `decide` engine), which then routes here (re-pause /
|
|
53
|
+
* shared `decide` engine), which then routes here (re-pause / dispose / via
|
|
45
54
|
* `promoteObservation` for a mint). A signal is still-open, acted-on, or deleted
|
|
46
55
|
* — there is no \"retain as resolved\" state.
|
|
47
56
|
*
|
|
48
|
-
* The work-item (task/
|
|
49
|
-
* the `
|
|
50
|
-
* task/
|
|
57
|
+
* The work-item (task/spec) terminal MOVES (`tasks/cancelled`, `specs/dropped`) and
|
|
58
|
+
* the stuck (lock `state: stuck`) LIFECYCLE state are a SEPARATE lifecycle concern (a
|
|
59
|
+
* task/spec is dropped by its own lifecycle, not by a question answer) — they are
|
|
51
60
|
* NOT routed from here any more (they were the removed disposition vocabulary).
|
|
52
61
|
*
|
|
53
62
|
* It is the SIBLING of {@link import('./surface-persist.js').persistSurfacedQuestions}:
|
|
54
63
|
* that is the SURFACE rung's one-commit primitive (append-or-create + set
|
|
55
64
|
* `needsAnswers`); this is the APPLY rung's (apply answers + resolve / re-pause /
|
|
56
|
-
*
|
|
65
|
+
* dispose). Kept file-orthogonal so the rung bodies land in different tasks.
|
|
57
66
|
*
|
|
58
67
|
* **NEVER invents an answer (US #4).** The apply rung applies ONLY what the human
|
|
59
68
|
* authored — the recorded `answer:` text. It does NOT fill, guess, or author an
|
|
@@ -87,13 +96,13 @@ const APPLIED_HEADING = '## Applied answers';
|
|
|
87
96
|
* resolved (no leftover "these are still open" prose above `## Applied answers`).
|
|
88
97
|
*
|
|
89
98
|
* The strip is STRUCTURAL (marker-pair based), NOT a heading-text regex — the
|
|
90
|
-
*
|
|
99
|
+
* spec's D1 decision: a `## Open questions` heading match would be fragile to
|
|
91
100
|
* author wording (`## Open questions (clear needsAnswers when resolved)` vs.
|
|
92
101
|
* `## Open questions`). Items authored WITHOUT the markers are left untouched
|
|
93
102
|
* (backward compat — no marker ⇒ nothing to strip ⇒ identical bytes).
|
|
94
103
|
*
|
|
95
104
|
* The sibling task `templates-mark-transient-open-questions-block` introduces
|
|
96
|
-
* the markers in the
|
|
105
|
+
* the markers in the spec/task templates; this task exports the constants so
|
|
97
106
|
* the two tasks agree on the literal byte sequence.
|
|
98
107
|
*/
|
|
99
108
|
export const OPEN_QUESTIONS_MARKER_OPEN = '<!-- open-questions -->';
|
|
@@ -102,7 +111,7 @@ export const OPEN_QUESTIONS_MARKER_CLOSE = '<!-- /open-questions -->';
|
|
|
102
111
|
export interface ApplyAnsweredQuestionsOptions {
|
|
103
112
|
/** Working clone/worktree the apply commits in. */
|
|
104
113
|
cwd: string;
|
|
105
|
-
/** The namespaced item identity (`task:foo` / `
|
|
114
|
+
/** The namespaced item identity (`task:foo` / `spec:bar` / `observation:baz`). */
|
|
106
115
|
item: string;
|
|
107
116
|
/**
|
|
108
117
|
* The item file path RELATIVE to `cwd` (e.g. `work/backlog/foo.md`). The
|
|
@@ -116,19 +125,30 @@ export interface ApplyAnsweredQuestionsOptions {
|
|
|
116
125
|
* a caller-supplied batch). When non-empty, the apply APPENDS them (`qN+1…`,
|
|
117
126
|
* never mutating an answered entry) and RE-PAUSES (`needsAnswers:true` stays) —
|
|
118
127
|
* the "all answered?" flips back to false. Empty/omitted ⇒ resolve the item (or
|
|
119
|
-
*
|
|
128
|
+
* dispose it, when `dispose` is set).
|
|
120
129
|
*/
|
|
121
130
|
appendQuestions?: NewQuestion[];
|
|
122
131
|
/**
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
* the
|
|
132
|
+
* DISPOSE the SOURCE (the agentic `dispose` verdict, or a direct disposal):
|
|
133
|
+
* REGIME-POLYMORPHIC on the source's type (task
|
|
134
|
+
* `apply-disposition-delete-to-dispose-regime-polymorphic`, spec
|
|
135
|
+
* `surface-stuck-as-questions-and-retire-stuck-lock-state` decision #5):
|
|
136
|
+
* - OBSERVATION → `git rm` the source + its answered sidecar in a STANDALONE
|
|
137
|
+
* revertible commit, the `reason` recorded in the commit message (git
|
|
138
|
+
* history is the archive; notes leave by deletion, decision 12);
|
|
139
|
+
* - TASK → `git mv` the source to the task regime's won't-proceed terminal
|
|
140
|
+
* `tasks/cancelled/` (RETAINED, `reason:` written into the moved body's
|
|
141
|
+
* frontmatter); the sidecar is `git rm`-ed in the same commit;
|
|
142
|
+
* - SPEC → `git mv` the source to `specs/dropped/` (RETAINED); sidecar
|
|
143
|
+
* `git rm`-ed in the same commit.
|
|
144
|
+
* A TASK can NEVER be hard-deleted through this option — dispose is the only
|
|
145
|
+
* path off the board, true by construction (there is no `delete: true` escape
|
|
146
|
+
* hatch here). Fires DIRECT (no preview/confirm — decision 12). Mutually
|
|
147
|
+
* exclusive with `appendQuestions` (re-pause and dispose cannot both happen on
|
|
148
|
+
* one apply); when both are given the re-pause wins (you cannot dispose a
|
|
149
|
+
* source you are still asking about).
|
|
130
150
|
*/
|
|
131
|
-
|
|
151
|
+
dispose?: {reason: string};
|
|
132
152
|
/** Advisory committer id for the commit subject. Defaults to git user.name. */
|
|
133
153
|
by?: string;
|
|
134
154
|
/** Environment for child git processes. */
|
|
@@ -144,14 +164,26 @@ export type ApplyTerminal =
|
|
|
144
164
|
/** New questions appended; stayed needsAnswers:true and re-paused. */
|
|
145
165
|
| 'repaused'
|
|
146
166
|
/**
|
|
147
|
-
* The SOURCE was
|
|
148
|
-
* a direct
|
|
149
|
-
* STANDALONE revertible commit, the reason
|
|
150
|
-
* history = archive).
|
|
151
|
-
* resting marker. This is the apply rung applying the human's
|
|
152
|
-
* (human-authored, not a unilateral agent destruction of a
|
|
167
|
+
* The SOURCE (an OBSERVATION) was disposed BY DELETION (the agentic `dispose`
|
|
168
|
+
* verdict on an observation, or a direct disposal): the source (+ its answered
|
|
169
|
+
* sidecar) were `git rm`-ed in a STANDALONE revertible commit, the reason in
|
|
170
|
+
* the commit message (git history = archive). Notes leave by being GONE —
|
|
171
|
+
* there is no resting marker. This is the apply rung applying the human's
|
|
172
|
+
* RATIFIED answer (human-authored, not a unilateral agent destruction of a
|
|
173
|
+
* live signal). Preserved verbatim as `'deleted'` for observation disposals;
|
|
174
|
+
* see {@link ApplyTerminal | 'disposed'} for the task/spec branches.
|
|
153
175
|
*/
|
|
154
176
|
| 'deleted'
|
|
177
|
+
/**
|
|
178
|
+
* The SOURCE (a TASK or SPEC) was DISPOSED to its regime's won't-proceed
|
|
179
|
+
* terminal (task `apply-disposition-delete-to-dispose-regime-polymorphic`,
|
|
180
|
+
* spec `surface-stuck-as-questions-and-retire-stuck-lock-state` decision #5):
|
|
181
|
+
* a task `git mv`-ed to `tasks/cancelled/`, a spec `git mv`-ed to
|
|
182
|
+
* `specs/dropped/`. The file is RETAINED (git history + terminal folder is
|
|
183
|
+
* the archive), with the human's `reason:` written into the moved body's
|
|
184
|
+
* frontmatter and the answered sidecar `git rm`-ed in the same commit.
|
|
185
|
+
*/
|
|
186
|
+
| 'disposed'
|
|
155
187
|
/**
|
|
156
188
|
* The item file was GONE by the time apply tried to write (a concurrent
|
|
157
189
|
* promote/terminal-move/delete between capture and write). Apply exited
|
|
@@ -274,7 +306,7 @@ function withAppliedAnswers(body: string, entries: SidecarEntry[]): string {
|
|
|
274
306
|
|
|
275
307
|
/**
|
|
276
308
|
* Strip ALL marker-fenced open-questions blocks from an item body — the FULL
|
|
277
|
-
* RESOLUTION reconcile step (
|
|
309
|
+
* RESOLUTION reconcile step (spec `apply-reconciles-stale-open-questions`,
|
|
278
310
|
* decisions D1 / D3). Removes each `<!-- open-questions -->` … `<!--
|
|
279
311
|
* /open-questions -->` pair (markers included) plus the blank lines that
|
|
280
312
|
* flanked it, so the answers in `## Applied answers` no longer sit beneath a
|
|
@@ -324,9 +356,12 @@ function stripOpenQuestionsBlocks(body: string): string {
|
|
|
324
356
|
*
|
|
325
357
|
* 1. **append / re-pause** — `appendQuestions` is non-empty: append `qN+1…`,
|
|
326
358
|
* keep `needsAnswers:true`, re-pause (one commit, body + sidecar).
|
|
327
|
-
* 2. **
|
|
328
|
-
*
|
|
329
|
-
*
|
|
359
|
+
* 2. **dispose** — `dispose` is set (the `dispose` verdict): REGIME-POLYMORPHIC
|
|
360
|
+
* on the source's type — an OBSERVATION is `git rm`-ed with its sidecar in
|
|
361
|
+
* a standalone revertible commit (reason in the message); a TASK is `git
|
|
362
|
+
* mv`-ed to `tasks/cancelled/` (`reason:` written into the moved body,
|
|
363
|
+
* sidecar `git rm`-ed in the same commit); a SPEC is `git mv`-ed to
|
|
364
|
+
* `specs/dropped/` (same shape as the task branch).
|
|
330
365
|
* 3. **resolve fully** (the default) — clear `needsAnswers` + delete the sidecar
|
|
331
366
|
* in ONE commit; the item advances toward build by its normal lifecycle.
|
|
332
367
|
*/
|
|
@@ -342,11 +377,11 @@ export function applyAnsweredQuestions(
|
|
|
342
377
|
|
|
343
378
|
const {model, path: sidecarPath} = readSidecar(cwd, item);
|
|
344
379
|
|
|
345
|
-
// FOLDER-AGNOSTIC at WRITE-TIME (F3a,
|
|
380
|
+
// FOLDER-AGNOSTIC at WRITE-TIME (F3a, spec
|
|
346
381
|
// `staging-surface-and-apply-promote-safety`): re-resolve the item's CURRENT
|
|
347
382
|
// path by IDENTITY, mirroring the sidecar's already-folder-agnostic
|
|
348
383
|
// resolution. The captured `itemPath` is ADVISORY — a concurrent `promote`
|
|
349
|
-
// (`tasks/backlog → tasks/ready`, `
|
|
384
|
+
// (`tasks/backlog → tasks/ready`, `specs/proposed → specs/ready`) may have
|
|
350
385
|
// moved the item between capture and now, and we MUST write the post-move
|
|
351
386
|
// path, never the stale one. If the item has vanished entirely, exit CLEAN
|
|
352
387
|
// (no commit, no ghost file) — the matching benign skip the surface/triage
|
|
@@ -383,7 +418,7 @@ export function applyAnsweredQuestions(
|
|
|
383
418
|
|
|
384
419
|
// (1) APPEND / RE-PAUSE: the apply has new questions. Append them (`qN+1…`,
|
|
385
420
|
// never mutating an answered entry), stay needsAnswers:true, re-pause. Re-pause
|
|
386
|
-
// WINS over a
|
|
421
|
+
// WINS over a dispose — you cannot dispose a source you are still asking
|
|
387
422
|
// about.
|
|
388
423
|
const followups = options.appendQuestions ?? [];
|
|
389
424
|
if (followups.length > 0) {
|
|
@@ -409,17 +444,39 @@ export function applyAnsweredQuestions(
|
|
|
409
444
|
};
|
|
410
445
|
}
|
|
411
446
|
|
|
412
|
-
// (2)
|
|
413
|
-
//
|
|
414
|
-
//
|
|
415
|
-
//
|
|
416
|
-
// the
|
|
417
|
-
|
|
418
|
-
|
|
447
|
+
// (2) DISPOSE: the caller decided the source should be DISPOSED (the `dispose`
|
|
448
|
+
// verdict). REGIME-POLYMORPHIC on the source type (task
|
|
449
|
+
// `apply-disposition-delete-to-dispose-regime-polymorphic`, spec
|
|
450
|
+
// `surface-stuck-as-questions-and-retire-stuck-lock-state` decision #5):
|
|
451
|
+
// - observation → `git rm` the note + sidecar in one revertible commit
|
|
452
|
+
// (reason in the message; notes leave by deletion, decision 12);
|
|
453
|
+
// - task → `git mv` to `tasks/cancelled/` (RETAINED; `reason:` written into
|
|
454
|
+
// the moved body; sidecar `git rm`-ed in the same commit);
|
|
455
|
+
// - spec → `git mv` to `specs/dropped/` (RETAINED, same shape).
|
|
456
|
+
// DIRECT — no preview/confirm (decision 12); the human's answer is the source
|
|
457
|
+
// of truth. A TASK is never `git rm`-ed here (true by construction: the
|
|
458
|
+
// task-branch calls `git mv`, no branch of this dispatcher hard-deletes a
|
|
459
|
+
// task).
|
|
460
|
+
if (options.dispose !== undefined) {
|
|
461
|
+
const {type} = resolveSidecarIdentity(item);
|
|
462
|
+
if (type === 'observation') {
|
|
463
|
+
return disposeObservationByDeletion({
|
|
464
|
+
cwd,
|
|
465
|
+
item,
|
|
466
|
+
itemPath,
|
|
467
|
+
reason: options.dispose.reason,
|
|
468
|
+
sidecarPath,
|
|
469
|
+
by,
|
|
470
|
+
env,
|
|
471
|
+
note,
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
return disposeToTerminal({
|
|
419
475
|
cwd,
|
|
420
476
|
item,
|
|
421
477
|
itemPath,
|
|
422
|
-
|
|
478
|
+
type,
|
|
479
|
+
reason: options.dispose.reason,
|
|
423
480
|
sidecarPath,
|
|
424
481
|
by,
|
|
425
482
|
env,
|
|
@@ -455,11 +512,11 @@ export function applyAnsweredQuestions(
|
|
|
455
512
|
};
|
|
456
513
|
}
|
|
457
514
|
|
|
458
|
-
interface
|
|
515
|
+
interface DisposeInput {
|
|
459
516
|
cwd: string;
|
|
460
517
|
item: string;
|
|
461
518
|
itemPath: string;
|
|
462
|
-
/** The human's
|
|
519
|
+
/** The human's dispose reason (their answer text), recorded in the commit message. */
|
|
463
520
|
reason: string;
|
|
464
521
|
sidecarPath: string;
|
|
465
522
|
by: string;
|
|
@@ -468,25 +525,27 @@ interface DischargeInput {
|
|
|
468
525
|
}
|
|
469
526
|
|
|
470
527
|
/**
|
|
471
|
-
*
|
|
472
|
-
*
|
|
473
|
-
*
|
|
474
|
-
*
|
|
475
|
-
*
|
|
476
|
-
* `
|
|
528
|
+
* DISPOSE an OBSERVATION by DELETION (task
|
|
529
|
+
* `apply-disposition-delete-to-dispose-regime-polymorphic`; US #5/#11): `git rm`
|
|
530
|
+
* the observation-note AND its answered sidecar in ONE STANDALONE commit, the
|
|
531
|
+
* human's dispose reason recorded in the commit MESSAGE (git history = archive).
|
|
532
|
+
* There is no spawned artifact for a dispose-by-deletion, so the deletion is a
|
|
533
|
+
* standalone commit (a `mint`, by contrast, rides the new artifact's create
|
|
534
|
+
* commit through `promoteObservation`).
|
|
477
535
|
*
|
|
478
|
-
* A
|
|
479
|
-
*
|
|
480
|
-
*
|
|
481
|
-
*
|
|
482
|
-
*
|
|
536
|
+
* A disposed observation leaves by being GONE — notes have no terminal folder
|
|
537
|
+
* (decision 12: "notes leave by deletion"), unlike a task/spec which is `git
|
|
538
|
+
* mv`-ed to its regime's terminal by {@link disposeToTerminal}. This is the
|
|
539
|
+
* apply rung applying the human's RATIFIED answer (the deletion is
|
|
540
|
+
* human-authored), and it is git-recoverable (a single revertible commit) — a
|
|
541
|
+
* wrong inference is never catastrophic.
|
|
483
542
|
*/
|
|
484
|
-
function
|
|
485
|
-
input:
|
|
543
|
+
function disposeObservationByDeletion(
|
|
544
|
+
input: DisposeInput,
|
|
486
545
|
): ApplyAnsweredQuestionsResult {
|
|
487
546
|
const {cwd, item, itemPath, reason, sidecarPath, by, env, note} = input;
|
|
488
547
|
// `git rm` the source. The sidecar may not exist in every path; rm it too when
|
|
489
|
-
// present, so the
|
|
548
|
+
// present, so the dispose leaves no answered-sidecar residue. Both ride ONE
|
|
490
549
|
// commit.
|
|
491
550
|
const rmPaths = [itemPath];
|
|
492
551
|
if (existsSync(join(cwd, sidecarPath))) {
|
|
@@ -496,7 +555,7 @@ function dischargeByDeletion(
|
|
|
496
555
|
const reasonLine = reason.trim() === '' ? '(no reason given)' : reason.trim();
|
|
497
556
|
const subject = `advance: ${item} → deleted (by ${by})`;
|
|
498
557
|
const messageBody =
|
|
499
|
-
`
|
|
558
|
+
`Disposed by deletion (the human's ratified answer authors it; ` +
|
|
500
559
|
`git history is the archive).\n\nreason: ${reasonLine}`;
|
|
501
560
|
gitHard(['commit', '--quiet', '-m', subject, '-m', messageBody], cwd, env);
|
|
502
561
|
const commit = gitHard(['rev-parse', 'HEAD'], cwd, env).stdout.trim();
|
|
@@ -513,6 +572,121 @@ function dischargeByDeletion(
|
|
|
513
572
|
};
|
|
514
573
|
}
|
|
515
574
|
|
|
575
|
+
/**
|
|
576
|
+
* The per-regime WON'T-PROCEED TERMINAL folder key {@link disposeToTerminal}
|
|
577
|
+
* moves a task/spec into. The folder WORDS are deliberately different
|
|
578
|
+
* (`cancelled` for tasks, `dropped` for specs) so a task and spec sharing a slug
|
|
579
|
+
* cannot collide on one terminal path — the two regimes have namespaced
|
|
580
|
+
* terminals by design (spec `surface-stuck-as-questions-and-retire-stuck-lock-
|
|
581
|
+
* state`, and see `work-layout.ts`). Do NOT rename the folders here; the token
|
|
582
|
+
* that changed is the verdict outcome (`dispose`), NOT the folder words.
|
|
583
|
+
*/
|
|
584
|
+
const DISPOSE_TERMINAL_FOLDER = {
|
|
585
|
+
task: 'cancelled',
|
|
586
|
+
spec: 'specs-dropped',
|
|
587
|
+
} as const;
|
|
588
|
+
|
|
589
|
+
interface DisposeToTerminalInput extends DisposeInput {
|
|
590
|
+
type: Exclude<SidecarType, 'observation'>;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* DISPOSE a TASK or SPEC to its regime's won't-proceed TERMINAL folder (task
|
|
595
|
+
* `apply-disposition-delete-to-dispose-regime-polymorphic`, spec
|
|
596
|
+
* `surface-stuck-as-questions-and-retire-stuck-lock-state` decision #5): `git
|
|
597
|
+
* mv` the item to `tasks/cancelled/` (task) or `specs/dropped/` (spec), with the
|
|
598
|
+
* human's dispose reason written into the moved body's `reason:` frontmatter
|
|
599
|
+
* (durable, in-file archive of WHY the item won't proceed — symmetric across
|
|
600
|
+
* both regimes; the source of the moved item is the human's ratified answer),
|
|
601
|
+
* then `git rm` the answered sidecar, all in ONE commit.
|
|
602
|
+
*
|
|
603
|
+
* ## Decisions (recorded here per task etiquette)
|
|
604
|
+
*
|
|
605
|
+
* - **`reason:` frontmatter, symmetric across task AND spec.** The acceptance
|
|
606
|
+
* criteria explicitly require the reason for the task branch; the spec
|
|
607
|
+
* branch is only required to `git mv` to `specs/dropped/`. We nonetheless
|
|
608
|
+
* write the same `reason:` marker onto a disposed SPEC too, because (a) the
|
|
609
|
+
* two regimes are the same shape ("disposed to terminal"), so asymmetric
|
|
610
|
+
* behaviour would be a surprise; (b) the spec regime's dropped/ folder had
|
|
611
|
+
* no in-file WHY at all before, so any adjacent surface (an operator
|
|
612
|
+
* inspecting `specs/dropped/`) would otherwise have to grep the commit
|
|
613
|
+
* history for the reason. Setting it uses the same {@link
|
|
614
|
+
* setFrontmatterMarker} the surface rung already uses for `needsAnswers`.
|
|
615
|
+
* The commit message still carries the reason too (belt + braces — the
|
|
616
|
+
* frontmatter is the durable in-file record, the commit is the audit
|
|
617
|
+
* history). If a reviewer disagrees they can flip the spec branch back to a
|
|
618
|
+
* bare `git mv` in one line — the task branch is the load-bearing acceptance.
|
|
619
|
+
*
|
|
620
|
+
* - **The sidecar is `git rm`-ed in the same commit as the mv.** A disposed
|
|
621
|
+
* item is no longer in the question-loop (the answer settled it), so the
|
|
622
|
+
* sidecar has no reason to survive at the terminal folder. Same commit
|
|
623
|
+
* preserves the sidecar's `needsAnswers ⇔ active sidecar` invariant.
|
|
624
|
+
*
|
|
625
|
+
* A TASK is NEVER `git rm`-ed on this branch (that is the invariant this
|
|
626
|
+
* function exists to enforce): the disposal is a `git mv` to `tasks/cancelled/`,
|
|
627
|
+
* a folder-move that git can revert with a single `git revert`.
|
|
628
|
+
*/
|
|
629
|
+
function disposeToTerminal(
|
|
630
|
+
input: DisposeToTerminalInput,
|
|
631
|
+
): ApplyAnsweredQuestionsResult {
|
|
632
|
+
const {cwd, item, itemPath, type, reason, sidecarPath, by, env, note} = input;
|
|
633
|
+
const {slug} = resolveSidecarIdentity(item);
|
|
634
|
+
const folderKey = DISPOSE_TERMINAL_FOLDER[type];
|
|
635
|
+
const terminalPath = workItemRel(folderKey, `${slug}.md`);
|
|
636
|
+
|
|
637
|
+
// (a) Rewrite the item body with the `reason:` frontmatter marker BEFORE the
|
|
638
|
+
// mv so the marker rides the same commit as the terminal move. `git mv` reads
|
|
639
|
+
// the working-tree file, so a pre-mv rewrite is picked up by the subsequent
|
|
640
|
+
// stage of the moved path.
|
|
641
|
+
const reasonLine = reason.trim() === '' ? '(no reason given)' : reason.trim();
|
|
642
|
+
const itemAbs = join(cwd, itemPath);
|
|
643
|
+
const rewritten = setFrontmatterMarker(
|
|
644
|
+
readFileSync(itemAbs, 'utf8'),
|
|
645
|
+
'reason',
|
|
646
|
+
reasonLine,
|
|
647
|
+
);
|
|
648
|
+
writeFileSync(itemAbs, rewritten);
|
|
649
|
+
|
|
650
|
+
// (b) Ensure the terminal folder exists (git mv fatals on a missing parent).
|
|
651
|
+
mkdirSync(dirname(join(cwd, terminalPath)), {recursive: true});
|
|
652
|
+
|
|
653
|
+
// (c) `git mv` the source to its regime terminal.
|
|
654
|
+
gitHard(['mv', '--', itemPath, terminalPath], cwd, env);
|
|
655
|
+
|
|
656
|
+
// (d) `git rm` the answered sidecar (the loop is settled) in the same commit.
|
|
657
|
+
const rmPaths: string[] = [];
|
|
658
|
+
if (existsSync(join(cwd, sidecarPath))) {
|
|
659
|
+
rmPaths.push(sidecarPath);
|
|
660
|
+
}
|
|
661
|
+
if (rmPaths.length > 0) {
|
|
662
|
+
gitHard(['rm', '--quiet', '--', ...rmPaths], cwd, env);
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
// (e) Stage the rewritten (now-moved) body so its `reason:` marker rides the
|
|
666
|
+
// same commit as the mv.
|
|
667
|
+
gitHard(['add', '--', terminalPath], cwd, env);
|
|
668
|
+
|
|
669
|
+
const subject = `advance: ${item} → disposed (by ${by})`;
|
|
670
|
+
const messageBody =
|
|
671
|
+
`Disposed to regime terminal '${folderKey}' (the human's ratified answer ` +
|
|
672
|
+
`authors it; git history + terminal folder are the archive).\n\n` +
|
|
673
|
+
`reason: ${reasonLine}`;
|
|
674
|
+
gitHard(['commit', '--quiet', '-m', subject, '-m', messageBody], cwd, env);
|
|
675
|
+
const commit = gitHard(['rev-parse', 'HEAD'], cwd, env).stdout.trim();
|
|
676
|
+
const message =
|
|
677
|
+
`applied ${item} → disposed (source git mv-ed to '${terminalPath}', ` +
|
|
678
|
+
`reason: written into the moved body's frontmatter, sidecar deleted in the ` +
|
|
679
|
+
`same commit).`;
|
|
680
|
+
note(message);
|
|
681
|
+
return {
|
|
682
|
+
outcome: 'disposed',
|
|
683
|
+
commit,
|
|
684
|
+
sidecarPath,
|
|
685
|
+
itemPath: terminalPath,
|
|
686
|
+
message,
|
|
687
|
+
};
|
|
688
|
+
}
|
|
689
|
+
|
|
516
690
|
// Re-export the heading constant the tests assert against, so the byte-level
|
|
517
691
|
// marker stays in one place.
|
|
518
692
|
export {APPLIED_HEADING};
|