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
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The `install-ci` CLOSE-JOB capability (
|
|
2
|
+
* The `install-ci` CLOSE-JOB capability (spec `runner-in-ci`, task
|
|
3
3
|
* `install-ci-close-job-workflow`; capability E: close issues when their work
|
|
4
4
|
* lands). This module GENERATES the one fixed workflow file for the close-job and
|
|
5
5
|
* STRUCTURALLY VALIDATES it, mirroring the snapshot-assertion style of
|
|
6
6
|
* `advance-lifecycle-template.ts` / `advance-ci-template.ts` (the package depends on
|
|
7
7
|
* NO YAML lib, so the checks are presence/shape assertions over the raw text).
|
|
8
8
|
*
|
|
9
|
-
* The discipline (from the
|
|
9
|
+
* The discipline (from the spec capability-E row + the Out-of-Scope fence):
|
|
10
10
|
*
|
|
11
11
|
* - TRIGGER: a MERGE to `main`. There is no native "PR merged" event, so the
|
|
12
12
|
* workflow uses `push: {branches: [main]}` (NOT `pull_request: closed`): it
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* cannot close. (See the `## Decisions` block in the task.)
|
|
17
17
|
* - The job INVOKES the close machinery via `dorfl close-merged-issues`,
|
|
18
18
|
* which CONSUMES the UNCHANGED engine pieces: the resolution
|
|
19
|
-
* (`resolveClosingIssue`), the "
|
|
19
|
+
* (`resolveClosingIssue`), the "spec complete?" query (`prd-complete-query`,
|
|
20
20
|
* done), and `IssueProvider.closeIssue`. CI owns ONLY the job + trigger; it
|
|
21
21
|
* re-implements NONE of those (the Out-of-Scope fence).
|
|
22
22
|
* - CI runs IN-PLACE (the CI container IS the isolation): no
|
|
@@ -54,7 +54,7 @@ export const CLOSE_JOB_WORKFLOW_PATH = 'workflows/close-job.yml';
|
|
|
54
54
|
*/
|
|
55
55
|
export function generateCloseJobWorkflow(_config: ResolvedCIConfig): string {
|
|
56
56
|
return `\
|
|
57
|
-
# dorfl — the ISSUE CLOSE-JOB in CI (capability E,
|
|
57
|
+
# dorfl — the ISSUE CLOSE-JOB in CI (capability E, spec runner-in-ci).
|
|
58
58
|
# EMITTED by \`dorfl install-ci\`; the human commits it. DO NOT hand-edit a
|
|
59
59
|
# copy — re-run install-ci to upgrade the shell.
|
|
60
60
|
#
|
|
@@ -69,9 +69,9 @@ export function generateCloseJobWorkflow(_config: ResolvedCIConfig): string {
|
|
|
69
69
|
# the landed work closes and closes them. CI owns ONLY this job + the trigger; the
|
|
70
70
|
# command CONSUMES the engine's UNCHANGED pieces and re-implements none of them:
|
|
71
71
|
# * the RESOLUTION (resolveClosingIssue): a lone task closes its own \`issue:\`;
|
|
72
|
-
# a fanned task reaches the number via \`task.
|
|
73
|
-
# * the "
|
|
74
|
-
# ONLY when ALL its \`
|
|
72
|
+
# a fanned task reaches the number via \`task.spec: → spec issue:\`.
|
|
73
|
+
# * the "spec complete?" QUERY (prd-complete-query, done): a spec's issue closes
|
|
74
|
+
# ONLY when ALL its \`spec:<slug>\` tasks are in work/done/.
|
|
75
75
|
# * the CLOSE (IssueProvider.closeIssue): the atomic comment+close seam — NO
|
|
76
76
|
# direct \`gh\` in the engine core; any comment rides this close, never the PR
|
|
77
77
|
# comment seam.
|
|
@@ -110,14 +110,14 @@ jobs:
|
|
|
110
110
|
close-merged-issues:
|
|
111
111
|
runs-on: ubuntu-latest
|
|
112
112
|
steps:
|
|
113
|
-
- uses: actions/checkout@
|
|
113
|
+
- uses: actions/checkout@v5
|
|
114
114
|
with:
|
|
115
115
|
fetch-depth: 0
|
|
116
116
|
- uses: ./.github/actions/dorfl-setup
|
|
117
117
|
- name: close issues whose work has landed on main
|
|
118
118
|
# In-place in this checkout (no --isolated/--remote): the CI container IS
|
|
119
119
|
# the isolation. Resolves the closing issue(s) from the work/ tree, runs
|
|
120
|
-
# the "
|
|
120
|
+
# the "spec complete?" query for the spec case, and closes via the provider
|
|
121
121
|
# seam — all UNCHANGED engine pieces, consumed not re-built.
|
|
122
122
|
env:
|
|
123
123
|
GH_TOKEN: \${{ secrets.GITHUB_TOKEN }}
|
package/src/close-job.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The CI CLOSE-JOB driver (
|
|
2
|
+
* The CI CLOSE-JOB driver (spec `runner-in-ci`, capability E; task
|
|
3
3
|
* `install-ci-close-job-workflow`). When work lands on `main`, this resolves which
|
|
4
4
|
* source issue(s) the landed work closes and closes them — but it OWNS none of the
|
|
5
5
|
* machinery it relies on. It is the thin JOB that WIRES three UNCHANGED engine
|
|
6
6
|
* pieces together (the Out-of-Scope fence: do NOT re-build them):
|
|
7
7
|
*
|
|
8
8
|
* - the RESOLUTION — {@link resolveClosingIssue} (`frontmatter.ts`): an artifact
|
|
9
|
-
* uses `issue:` XOR `
|
|
10
|
-
* fanned task reaches the number via `task.
|
|
11
|
-
* issue:`, and `
|
|
9
|
+
* uses `issue:` XOR `spec:`; a lone task closes its own `issue:` directly, a
|
|
10
|
+
* fanned task reaches the number via `task.spec: → work/specs/<spec>.md spec
|
|
11
|
+
* issue:`, and `spec:` WINS on a (hand-edited) conflict;
|
|
12
12
|
* - the QUERY — {@link isSpecComplete} (`spec-complete.ts`, task
|
|
13
13
|
* `prd-complete-query`, done): a spec is COMPLETE iff ≥1 `spec:<slug>` task AND
|
|
14
14
|
* all such tasks are in `work/done/`;
|
|
@@ -19,12 +19,12 @@
|
|
|
19
19
|
*
|
|
20
20
|
* The closure conditions, per artifact kind:
|
|
21
21
|
*
|
|
22
|
-
* - a **lone task** (`issue:`, no `
|
|
22
|
+
* - a **lone task** (`issue:`, no `spec:`) that resides in `work/done/` — its PR
|
|
23
23
|
* merged, so its own issue closes (reason `completed`);
|
|
24
|
-
* - a **
|
|
24
|
+
* - a **spec** (`issue:`) — closes ONLY when {@link isSpecComplete} says ALL its
|
|
25
25
|
* `spec:<slug>` tasks are in `work/done/` (reason `completed`).
|
|
26
26
|
*
|
|
27
|
-
* A
|
|
27
|
+
* A spec whose query is NOT yet complete is left OPEN (the final fanned task's
|
|
28
28
|
* merge tick closes it). A lone task still outside `work/done/` is skipped. The
|
|
29
29
|
* close DEGRADES (never throws) on a missing/unauthenticated provider, exactly
|
|
30
30
|
* like intake's bounce close — the run reports the real cause and stays exit-0.
|
|
@@ -62,7 +62,7 @@ const SPEC_LIFECYCLE_FOLDERS = SPEC_FOLDERS;
|
|
|
62
62
|
/** Why the close-job acted (or did not act) on a candidate issue. */
|
|
63
63
|
export type CloseDecision =
|
|
64
64
|
| 'closed' // the issue was closed via the provider seam
|
|
65
|
-
| 'not-complete' // a
|
|
65
|
+
| 'not-complete' // a spec whose query says it is not yet complete → left open
|
|
66
66
|
| 'not-landed' // a lone task not yet in work/done/ → left open
|
|
67
67
|
| 'close-failed'; // closure condition held but the provider close degraded
|
|
68
68
|
|
|
@@ -111,9 +111,9 @@ function listMarkdown(repoPath: string, folder: WorkFolderKey): string[] {
|
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
/**
|
|
114
|
-
* Read a
|
|
115
|
-
* `undefined` when no
|
|
116
|
-
* issue, or a typo'd `
|
|
114
|
+
* Read a spec's `issue:` number by slug, scanning the spec folders. Returns
|
|
115
|
+
* `undefined` when no spec with that slug carries an `issue:` (a spec with no source
|
|
116
|
+
* issue, or a typo'd `spec:` hop — degrades to "no issue to close", never crashes).
|
|
117
117
|
*/
|
|
118
118
|
function specIssueNumber(
|
|
119
119
|
repoPath: string,
|
|
@@ -137,14 +137,14 @@ function specIssueNumber(
|
|
|
137
137
|
* Resolve the DEDUPLICATED set of closure candidates from the `work/` tree, each
|
|
138
138
|
* via the UNCHANGED {@link resolveClosingIssue}:
|
|
139
139
|
*
|
|
140
|
-
* - every
|
|
141
|
-
*
|
|
142
|
-
* - every LONE task (`issue:` and NO `
|
|
140
|
+
* - every spec carrying `issue:` (in `work/specs/ready/` or `work/specs/tasked/`) is a
|
|
141
|
+
* spec-kind candidate keyed on its own `spec:` query;
|
|
142
|
+
* - every LONE task (`issue:` and NO `spec:`) is an `issue`-kind candidate.
|
|
143
143
|
*
|
|
144
|
-
* A fanned task carries `
|
|
145
|
-
* through its
|
|
146
|
-
* the
|
|
147
|
-
* tasks point at it.
|
|
144
|
+
* A fanned task carries `spec:` (NOT its own `issue:`), so it reaches the number
|
|
145
|
+
* through its spec's candidate, never as its own — the issue number lives ONLY on
|
|
146
|
+
* the spec. Deduplicated by issue number: a spec enumerated once even though many
|
|
147
|
+
* tasks point at it. Spec candidates are listed before lone-task candidates, each
|
|
148
148
|
* group slug-sorted, for a deterministic log.
|
|
149
149
|
*/
|
|
150
150
|
function resolveCandidates(repoPath: string): {
|
|
@@ -165,9 +165,9 @@ function resolveCandidates(repoPath: string): {
|
|
|
165
165
|
);
|
|
166
166
|
const slug = fm.slug ?? basename(file, '.md');
|
|
167
167
|
const closing = resolveClosingIssue(fm);
|
|
168
|
-
// A
|
|
169
|
-
// hand-edit conflict `
|
|
170
|
-
// `issue:`-bearing
|
|
168
|
+
// A spec's own closing link is its `issue:` (a spec has no `spec:`); on the
|
|
169
|
+
// hand-edit conflict `spec:` wins via resolveClosingIssue, so only a true
|
|
170
|
+
// `issue:`-bearing spec becomes a candidate here.
|
|
171
171
|
if (closing?.via === 'issue' && !seen.has(closing.issue)) {
|
|
172
172
|
seen.add(closing.issue);
|
|
173
173
|
specCandidates.push({issueNumber: closing.issue, via: 'spec', slug});
|
|
@@ -175,7 +175,7 @@ function resolveCandidates(repoPath: string): {
|
|
|
175
175
|
}
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
-
// Lone-task candidates: a task with `issue:` and NO `
|
|
178
|
+
// Lone-task candidates: a task with `issue:` and NO `spec:` closes its OWN
|
|
179
179
|
// issue directly when it lands in work/done/.
|
|
180
180
|
for (const folder of TASK_FOLDERS) {
|
|
181
181
|
for (const file of listMarkdown(repoPath, folder)) {
|
|
@@ -184,9 +184,9 @@ function resolveCandidates(repoPath: string): {
|
|
|
184
184
|
);
|
|
185
185
|
const slug = fm.slug ?? basename(file, '.md');
|
|
186
186
|
const closing = resolveClosingIssue(fm);
|
|
187
|
-
// `resolveClosingIssue` returns `via: 'issue'` ONLY when there is no `
|
|
188
|
-
// (
|
|
189
|
-
// its issue through the
|
|
187
|
+
// `resolveClosingIssue` returns `via: 'issue'` ONLY when there is no `spec:`
|
|
188
|
+
// (spec wins on conflict), so a fanned task never lands here — it reaches
|
|
189
|
+
// its issue through the spec candidate above.
|
|
190
190
|
if (closing?.via === 'issue' && !seen.has(closing.issue)) {
|
|
191
191
|
seen.add(closing.issue);
|
|
192
192
|
taskCandidates.push({issueNumber: closing.issue, via: 'issue', slug});
|
|
@@ -222,7 +222,7 @@ function closeComment(via: 'issue' | 'spec', slug: string): string {
|
|
|
222
222
|
|
|
223
223
|
/**
|
|
224
224
|
* Run the close-job over a repo's `work/` tree: resolve the closure candidates,
|
|
225
|
-
* apply the per-kind closure condition (a landed lone task; a
|
|
225
|
+
* apply the per-kind closure condition (a landed lone task; a spec whose
|
|
226
226
|
* {@link isSpecComplete} query holds), and close the qualifying issues through the
|
|
227
227
|
* {@link IssueProvider.closeIssue} seam (reason `completed`, an informational
|
|
228
228
|
* comment riding the SAME atomic close). REUSES the unchanged resolution + query +
|
package/src/complete.ts
CHANGED
|
@@ -13,6 +13,8 @@ import {
|
|
|
13
13
|
import {ledgerWrite} from './ledger-write.js';
|
|
14
14
|
import {releaseItemLock} from './item-lock.js';
|
|
15
15
|
import {workBranchRef, parseWorkBranchRef} from './slug-namespace.js';
|
|
16
|
+
import {isProvablyMergedForReap} from './gc.js';
|
|
17
|
+
import type {SidecarType} from './sidecar.js';
|
|
16
18
|
import type {ReviewProvider} from './integrator.js';
|
|
17
19
|
import type {IntegrationMode} from './config.js';
|
|
18
20
|
import {runAsync, localMainAheadCount, type RunResult} from './git.js';
|
|
@@ -160,7 +162,7 @@ export interface CompleteOptions {
|
|
|
160
162
|
*/
|
|
161
163
|
freshWorktreeGate?: boolean;
|
|
162
164
|
/**
|
|
163
|
-
* **The cross-job merge-serialiser CAS-retry cap** (config `mergeRetries`,
|
|
165
|
+
* **The cross-job merge-serialiser CAS-retry cap** (config `mergeRetries`, spec
|
|
164
166
|
* `land-time-reverify-and-parallel-merge-ceiling` Story 5 / Applied Answer q1
|
|
165
167
|
* (a)). Threaded verbatim into {@link performIntegration} as `mergeRetries` so
|
|
166
168
|
* the resolved per-repo value controls how many re-rebase-and-retry attempts
|
|
@@ -172,7 +174,7 @@ export interface CompleteOptions {
|
|
|
172
174
|
/** Skip the acceptance gate (human-only escape hatch; never used unattended). */
|
|
173
175
|
skipVerify?: boolean;
|
|
174
176
|
/**
|
|
175
|
-
* **`--allow-backlog`** (
|
|
177
|
+
* **`--allow-backlog`** (spec
|
|
176
178
|
* `do-allow-backlog-drive-staged-tasks-without-promotion`): TREAT a
|
|
177
179
|
* `tasks/backlog/`-resident body (staging) as a VALID build source, so a
|
|
178
180
|
* staged task driven in place done-moves `tasks/backlog/ → tasks/done/`
|
|
@@ -185,7 +187,7 @@ export interface CompleteOptions {
|
|
|
185
187
|
*/
|
|
186
188
|
allowBacklog?: boolean;
|
|
187
189
|
/**
|
|
188
|
-
* **Gate 2 — the PR/code review gate** (GATES
|
|
190
|
+
* **Gate 2 — the PR/code review gate** (GATES spec `work/specs/tasked/review.md`). When
|
|
189
191
|
* `true`, after the green `verify` and BEFORE the done-move, run the `review`
|
|
190
192
|
* SKILL as a FRESH-CONTEXT agent (its own harness launch) and route its verdict:
|
|
191
193
|
* `approve` → proceed to done-move/commit/integrate; `block` → route to
|
|
@@ -315,9 +317,12 @@ export interface CompleteResult {
|
|
|
315
317
|
outcome: CompleteOutcome;
|
|
316
318
|
/**
|
|
317
319
|
* True iff a FAILURE outcome (gate-failed / rebase-conflict) was routed to
|
|
318
|
-
*
|
|
319
|
-
*
|
|
320
|
-
*
|
|
320
|
+
* the shared needs-attention mechanism (ADR §12) — post lock-cutover, the
|
|
321
|
+
* per-item lock is amended to `state: stuck` with the reason recorded on the
|
|
322
|
+
* lock entry (there is no `work/needs-attention/` folder write anymore),
|
|
323
|
+
* rather than the item being left dangling. Undefined/false on the success,
|
|
324
|
+
* `--skip-verify`, refused, and usage-error paths (none of which mark the
|
|
325
|
+
* item stuck).
|
|
321
326
|
*/
|
|
322
327
|
routedToNeedsAttention?: boolean;
|
|
323
328
|
/** The work branch that was completed, when one was resolved. */
|
|
@@ -417,7 +422,7 @@ export async function performComplete(
|
|
|
417
422
|
return await runComplete(options, note);
|
|
418
423
|
} catch (err) {
|
|
419
424
|
// AUTONOMOUS-STRAND SURFACE (task
|
|
420
|
-
// `autonomous-integration-refusal-surfaces-not-strands-in-progress`,
|
|
425
|
+
// `autonomous-integration-refusal-surfaces-not-strands-in-progress`, spec
|
|
421
426
|
// `ledger-integrity` story 7). On the AUTONOMOUS path (`surfaceArbiter` set
|
|
422
427
|
// — the human-vs-autonomous gate the core's other failures use), a SOURCE-
|
|
423
428
|
// STRAND `CompleteRefusal` (the slug-is-stuck `nothing to complete`) and the
|
|
@@ -489,13 +494,11 @@ function strandRefusalSlug(err: unknown): string | undefined {
|
|
|
489
494
|
}
|
|
490
495
|
|
|
491
496
|
/**
|
|
492
|
-
* Surface an autonomous-path strand refusal
|
|
493
|
-
*
|
|
494
|
-
*
|
|
495
|
-
*
|
|
496
|
-
*
|
|
497
|
-
* build the one-file `work/<src>/<slug>.md → work/needs-attention/<slug>.md`
|
|
498
|
-
* move on a scratch index, and CAS-publish it. It NEVER touches the caller's
|
|
497
|
+
* Surface an autonomous-path strand refusal via the TREE-LESS seam ({@link
|
|
498
|
+
* ledgerWrite.applyTreelessNeedsAttentionTransition}). Post lock-cutover the
|
|
499
|
+
* seam is a pure LOCK AMEND — the item's per-item lock is moved to
|
|
500
|
+
* `state: stuck` with the reason on the lock entry; no folder move, no
|
|
501
|
+
* `work/needs-attention/` write. It NEVER touches the caller's
|
|
499
502
|
* working tree / HEAD / index — important here because the refusal was raised
|
|
500
503
|
* precisely because the working tree does NOT hold an `.md` to `git mv`. It is
|
|
501
504
|
* idempotent (a re-surface of an already-surfaced slug is a no-op) and reports
|
|
@@ -523,11 +526,13 @@ async function surfaceAutonomousStrand(params: {
|
|
|
523
526
|
});
|
|
524
527
|
if (surfaced.moved) {
|
|
525
528
|
const message =
|
|
526
|
-
`'${slug}' refused (${reason}); surfaced
|
|
527
|
-
|
|
529
|
+
`'${slug}' refused (${reason}); surfaced on ${arbiter}/main as a stuck ` +
|
|
530
|
+
'question (needsAnswers) so the next autonomous tick does NOT re-claim it.';
|
|
528
531
|
note(message);
|
|
532
|
+
// PR-2b D3: a clean surface is GREEN (exitCode 0). The autonomous strand
|
|
533
|
+
// surface is one of the cleanly-surfaced bounce sites this policy applies to.
|
|
529
534
|
return {
|
|
530
|
-
exitCode:
|
|
535
|
+
exitCode: 0,
|
|
531
536
|
outcome: 'strand-surfaced',
|
|
532
537
|
routedToNeedsAttention: true,
|
|
533
538
|
message,
|
|
@@ -633,7 +638,7 @@ async function runComplete(
|
|
|
633
638
|
);
|
|
634
639
|
}
|
|
635
640
|
// The branch HEAD is on when it IS a work branch for this slug (so an explicit
|
|
636
|
-
// `
|
|
641
|
+
// `spec:`-style recovery still completes the branch it is standing on); else
|
|
637
642
|
// synthesise the task branch.
|
|
638
643
|
const branch =
|
|
639
644
|
headParsed && headParsed.slug === slug
|
|
@@ -668,15 +673,17 @@ async function runComplete(
|
|
|
668
673
|
// removes it from THERE, so the move can never disagree with what the arbiter
|
|
669
674
|
// holds even when the local tree diverges (ledger-integrity defect 1). The
|
|
670
675
|
// `source` we pass is the arbiter-content fallback for the degenerate "arbiter
|
|
671
|
-
// holds nothing" case, not the authority. `in-progress/`
|
|
672
|
-
//
|
|
673
|
-
//
|
|
676
|
+
// holds nothing" case, not the authority. The legacy `in-progress/` FOLDER PROBE
|
|
677
|
+
// is GONE (task `finish-in-progress-folder-cutover-remove-legacy-recovery-readers`):
|
|
678
|
+
// the per-item-lock cutover moved claim OFF writing `work/in-progress/` (the body
|
|
679
|
+
// rests in `tasks/backlog/`, liveness is the held lock), so nothing writes that
|
|
680
|
+
// folder anymore and the `existsSync(inProgress)` arm could not fire. Liveness is
|
|
681
|
+
// the lock, not the folder.
|
|
674
682
|
const backlog = workItemPath(cwd, 'tasks-ready', slug);
|
|
675
683
|
const staged = workItemPath(cwd, 'tasks-backlog', slug);
|
|
676
|
-
const inProgress = workItemPath(cwd, 'in-progress', slug);
|
|
677
684
|
const done = workItemPath(cwd, 'done', slug);
|
|
678
685
|
const onBacklog = existsSync(backlog);
|
|
679
|
-
// `--allow-backlog` drive (
|
|
686
|
+
// `--allow-backlog` drive (spec
|
|
680
687
|
// `do-allow-backlog-drive-staged-tasks-without-promotion`): a staged task driven
|
|
681
688
|
// in place RESTS in `tasks/backlog/` (claim never moved it). Detect it as a build
|
|
682
689
|
// source so the done-move goes `tasks/backlog/ → tasks/done/` DIRECTLY (the
|
|
@@ -686,7 +693,6 @@ async function runComplete(
|
|
|
686
693
|
// strand `complete` must REFUSE (the honest "not finished, not done" position),
|
|
687
694
|
// NOT silently integrate — only the deliberate drive promotes from staging.
|
|
688
695
|
const onPreBacklog = options.allowBacklog === true && existsSync(staged);
|
|
689
|
-
const onInProgress = existsSync(inProgress);
|
|
690
696
|
// SELF-RENAMING FOLDER task backstop: the binary-known `work/done/<slug>.md`,
|
|
691
697
|
// OR — when none of the binary-known ledger folders hold the record — the slug
|
|
692
698
|
// at a RENAMED done-position the migration agent placed it in (e.g.
|
|
@@ -695,13 +701,10 @@ async function runComplete(
|
|
|
695
701
|
// resolution is byte-for-byte unchanged.
|
|
696
702
|
const onDone =
|
|
697
703
|
existsSync(done) ||
|
|
698
|
-
(!onBacklog &&
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
// STRANDED-DONE AUTO-RECOVER (prd `ledger-integrity` story 6, the autonomous
|
|
703
|
-
// half of `finish-already-committed-branch`). When neither in-progress/ nor
|
|
704
|
-
// needs-attention/ holds the slug on the BRANCH tree BUT done/ does, the work
|
|
704
|
+
(!onBacklog && !onPreBacklog && recordAtRenamedDonePosition(cwd, slug));
|
|
705
|
+
// STRANDED-DONE AUTO-RECOVER (spec `ledger-integrity` story 6, the autonomous
|
|
706
|
+
// half of `finish-already-committed-branch`). When the pool/staging does NOT
|
|
707
|
+
// hold the slug on the BRANCH tree BUT done/ does, the work
|
|
705
708
|
// branch was already built + done-moved + committed by a prior run that never
|
|
706
709
|
// landed on the arbiter (a terminal push failed, or the PR never merged). The
|
|
707
710
|
// autonomous `do`/`advance`/plain-`complete` path used to refuse this with
|
|
@@ -713,8 +716,7 @@ async function runComplete(
|
|
|
713
716
|
// `<arbiter>/main` returns `already-integrated` (clean no-op, NEVER a
|
|
714
717
|
// re-push/double-integrate). Mutually exclusive with the build-path source +
|
|
715
718
|
// `recovering` flags — the core ignores them when `committedRecovery` is set.
|
|
716
|
-
const folderShapeStranded =
|
|
717
|
-
!onBacklog && !onPreBacklog && !onInProgress && onDone;
|
|
719
|
+
const folderShapeStranded = !onBacklog && !onPreBacklog && onDone;
|
|
718
720
|
// DIRTY-CONTINUE GATE (task `recover-autodetect-gated-on-nothing-to-commit`).
|
|
719
721
|
// The folder-shape stranded-done auto-detect is necessary but NOT sufficient on
|
|
720
722
|
// a CONTINUE: a requeued task whose prior attempt already done-moved the slug
|
|
@@ -749,24 +751,19 @@ async function runComplete(
|
|
|
749
751
|
// "nothing to complete" CompleteRefusal). We default `source` to `'tasks-ready'`
|
|
750
752
|
// so `sourcePath` resolves to the canonical pool path the refusal message
|
|
751
753
|
// names; the refusal fires because that file does not exist on disk.
|
|
752
|
-
const source: 'tasks-ready' | 'tasks-backlog' | '
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
: onPreBacklog
|
|
760
|
-
? 'tasks-backlog'
|
|
761
|
-
: 'tasks-ready';
|
|
754
|
+
const source: 'tasks-ready' | 'tasks-backlog' | 'done' = dirtyContinue
|
|
755
|
+
? 'done'
|
|
756
|
+
: onBacklog
|
|
757
|
+
? 'tasks-ready'
|
|
758
|
+
: onPreBacklog
|
|
759
|
+
? 'tasks-backlog'
|
|
760
|
+
: 'tasks-ready';
|
|
762
761
|
const sourcePath =
|
|
763
762
|
source === 'tasks-ready'
|
|
764
763
|
? backlog
|
|
765
764
|
: source === 'tasks-backlog'
|
|
766
765
|
? staged
|
|
767
|
-
:
|
|
768
|
-
? inProgress
|
|
769
|
-
: done;
|
|
766
|
+
: done;
|
|
770
767
|
if (dirtyContinue) {
|
|
771
768
|
// Announce LOUDLY (parallel to the `committedRecovery` recovery note above):
|
|
772
769
|
// the autonomous integrate path took the CONTINUE-BUILD branch, not the
|
|
@@ -892,7 +889,7 @@ async function runComplete(
|
|
|
892
889
|
freshWorktreeGate: options.freshWorktreeGate,
|
|
893
890
|
// The cross-job merge-serialiser CAS-retry cap (config `mergeRetries`) — the
|
|
894
891
|
// git-alone FLOOR of the cross-job land-queue, resolved through the gate-family
|
|
895
|
-
// precedence chain (
|
|
892
|
+
// precedence chain (spec `land-time-reverify-and-parallel-merge-ceiling` Story
|
|
896
893
|
// 5). Threaded so a wide-matrix CI's raised cap actually reaches the merge loop.
|
|
897
894
|
mergeRetries: options.mergeRetries,
|
|
898
895
|
skipVerify: options.skipVerify,
|
|
@@ -924,9 +921,19 @@ async function runComplete(
|
|
|
924
921
|
|
|
925
922
|
// The FAILURE outcomes map 1:1 onto `complete`'s — the core already note()'d
|
|
926
923
|
// the reason and did any routing; the tail never runs for them.
|
|
924
|
+
// PR-2b exit-code policy (spec
|
|
925
|
+
// `surface-stuck-as-questions-and-retire-stuck-lock-state`, decision #4 / D3):
|
|
926
|
+
// a cleanly-surfaced bounce is GREEN (`exitCode: 0`) iff its surface transition
|
|
927
|
+
// SUCCEEDED (`routedToNeedsAttention: true`); a FAILED surface stays non-zero
|
|
928
|
+
// (retry/resolve). Applies to `prepare-failed`/`gate-failed`/`review-blocked`/
|
|
929
|
+
// `review-unparseable`/`rebase-conflict`. The empty-diff backstop is owned by
|
|
930
|
+
// task `empty-diff-bounce-surfaces-dispose-defaulted-question` and is NOT
|
|
931
|
+
// reached here.
|
|
932
|
+
const surfaceExit = (routed: boolean | undefined): 0 | 1 =>
|
|
933
|
+
routed === true ? 0 : 1;
|
|
927
934
|
if (core.outcome === 'prepare-failed') {
|
|
928
935
|
return {
|
|
929
|
-
exitCode:
|
|
936
|
+
exitCode: surfaceExit(core.routedToNeedsAttention),
|
|
930
937
|
outcome: 'prepare-failed',
|
|
931
938
|
routedToNeedsAttention: core.routedToNeedsAttention,
|
|
932
939
|
branch: core.branch,
|
|
@@ -935,7 +942,7 @@ async function runComplete(
|
|
|
935
942
|
}
|
|
936
943
|
if (core.outcome === 'gate-failed') {
|
|
937
944
|
return {
|
|
938
|
-
exitCode:
|
|
945
|
+
exitCode: surfaceExit(core.routedToNeedsAttention),
|
|
939
946
|
outcome: 'gate-failed',
|
|
940
947
|
routedToNeedsAttention: core.routedToNeedsAttention,
|
|
941
948
|
branch: core.branch,
|
|
@@ -944,7 +951,7 @@ async function runComplete(
|
|
|
944
951
|
}
|
|
945
952
|
if (core.outcome === 'review-blocked') {
|
|
946
953
|
return {
|
|
947
|
-
exitCode:
|
|
954
|
+
exitCode: surfaceExit(core.routedToNeedsAttention),
|
|
948
955
|
outcome: 'review-blocked',
|
|
949
956
|
routedToNeedsAttention: core.routedToNeedsAttention,
|
|
950
957
|
branch: core.branch,
|
|
@@ -958,7 +965,7 @@ async function runComplete(
|
|
|
958
965
|
// `do`/`run` tail re-labels its cause `transient-infra` (NOT a reviewer block) off
|
|
959
966
|
// the parse-failure phrase in `core.reason`.
|
|
960
967
|
return {
|
|
961
|
-
exitCode:
|
|
968
|
+
exitCode: surfaceExit(core.routedToNeedsAttention),
|
|
962
969
|
outcome: 'review-unparseable',
|
|
963
970
|
routedToNeedsAttention: core.routedToNeedsAttention,
|
|
964
971
|
branch: core.branch,
|
|
@@ -967,7 +974,7 @@ async function runComplete(
|
|
|
967
974
|
}
|
|
968
975
|
if (core.outcome === 'rebase-conflict') {
|
|
969
976
|
return {
|
|
970
|
-
exitCode:
|
|
977
|
+
exitCode: surfaceExit(core.routedToNeedsAttention),
|
|
971
978
|
outcome: 'rebase-conflict',
|
|
972
979
|
routedToNeedsAttention: core.routedToNeedsAttention,
|
|
973
980
|
branch: core.branch,
|
|
@@ -983,7 +990,7 @@ async function runComplete(
|
|
|
983
990
|
// because the work is already integrated and the branch may or may not
|
|
984
991
|
// still exist locally.
|
|
985
992
|
//
|
|
986
|
-
// CROSS-SUBSTRATE RELEASE (
|
|
993
|
+
// CROSS-SUBSTRATE RELEASE (spec `ledger-status-per-item-lock-refs` US #9/#10;
|
|
987
994
|
// task `complete-lock-then-durable-main-move-crash-safe`): the durable
|
|
988
995
|
// `main` record is already terminal (the kept tip is provably on
|
|
989
996
|
// `<arbiter>/main`), so the per-item lock claim took is now stale: release it
|
|
@@ -1021,7 +1028,7 @@ async function runComplete(
|
|
|
1021
1028
|
const commitMessage = core.commitMessage;
|
|
1022
1029
|
const mode = result.mode;
|
|
1023
1030
|
|
|
1024
|
-
// CROSS-SUBSTRATE RELEASE, gated on the work being DURABLY ON `main` (
|
|
1031
|
+
// CROSS-SUBSTRATE RELEASE, gated on the work being DURABLY ON `main` (spec
|
|
1025
1032
|
// `ledger-status-per-item-lock-refs` US #9/#10; ADR
|
|
1026
1033
|
// `ledger-status-on-per-item-lock-refs`; the trail's Amendment 6; task
|
|
1027
1034
|
// `complete-lock-then-durable-main-move-crash-safe`). ORDER MATTERS: the
|
|
@@ -1120,6 +1127,43 @@ async function runComplete(
|
|
|
1120
1127
|
// ONE thing the human must act on, so it is emitted as a visually-distinct
|
|
1121
1128
|
// block (blank lines + heading + TTY-aware color) ON TOP of the plain summary
|
|
1122
1129
|
// note below — cosmetic only; the structured result is unchanged.
|
|
1130
|
+
//
|
|
1131
|
+
// BENIGN ALREADY-LANDED RACE TAIL (task `propose-push-survives-stale-lease-
|
|
1132
|
+
// on-reaped-work-ref`, follow-up
|
|
1133
|
+
// `complete-propose-honour-already-landed-and-rename-continue-branch-module`):
|
|
1134
|
+
// when the integrator's propose push observed a REAPED `work/<slug>` ref AND
|
|
1135
|
+
// the work was provably on `<arbiter>/main`, it returns `alreadyLanded: true`
|
|
1136
|
+
// with a custom `instruction`. In that case NOTHING was pushed and there is
|
|
1137
|
+
// NO ref for a PR to point at, so emitting the generic
|
|
1138
|
+
// `formatProposeNextStep` push+PR block ("Pushed ... Open a PR/MR ...") would
|
|
1139
|
+
// misreport a clean no-op as unfinished work. Surface the integrator's
|
|
1140
|
+
// `instruction` VERBATIM instead — it is already the correct clean-no-op
|
|
1141
|
+
// prose (the CI-dominant recovery path via `performIntegration` already does
|
|
1142
|
+
// the same; this is the sibling `complete.ts` caller's honest report). The
|
|
1143
|
+
// tail (switch-to-main / delete-local-branch / `--no-switch`) is UNCHANGED
|
|
1144
|
+
// — only the emitted next-step + summary text differ.
|
|
1145
|
+
if (result.alreadyLanded === true) {
|
|
1146
|
+
const instruction =
|
|
1147
|
+
result.instruction ??
|
|
1148
|
+
`${branch}: already on ${arbiter}/main (clean no-op).`;
|
|
1149
|
+
const tail = options.noSwitch
|
|
1150
|
+
? `; left on ${branch} (--no-switch).`
|
|
1151
|
+
: deletedLocalBranch
|
|
1152
|
+
? `; switched to main and deleted ${branch}.`
|
|
1153
|
+
: '; switched to main.';
|
|
1154
|
+
const message = `Completed '${slug}': ${instruction}${tail}`;
|
|
1155
|
+
note(message);
|
|
1156
|
+
return {
|
|
1157
|
+
exitCode: 0,
|
|
1158
|
+
outcome: 'completed',
|
|
1159
|
+
branch,
|
|
1160
|
+
commitMessage,
|
|
1161
|
+
mergedToMain: false,
|
|
1162
|
+
switchedTo,
|
|
1163
|
+
deletedLocalBranch,
|
|
1164
|
+
message,
|
|
1165
|
+
};
|
|
1166
|
+
}
|
|
1123
1167
|
const color = options.color ?? shouldUseColor(process.stdout);
|
|
1124
1168
|
const noteBlock = options.noteBlock ?? note;
|
|
1125
1169
|
noteBlock(
|
|
@@ -1158,7 +1202,7 @@ async function runComplete(
|
|
|
1158
1202
|
/**
|
|
1159
1203
|
* Release the per-item lock `claim` ALSO acquired (`action: implement`, keyed
|
|
1160
1204
|
* `task:<slug>`) AFTER the durable `main` move has landed — the SECOND, lock-
|
|
1161
|
-
* release half of complete's cross-substrate ordering (
|
|
1205
|
+
* release half of complete's cross-substrate ordering (spec
|
|
1162
1206
|
* `ledger-status-per-item-lock-refs` US #9/#10; task
|
|
1163
1207
|
* `complete-lock-then-durable-main-move-crash-safe`).
|
|
1164
1208
|
*
|
|
@@ -1316,15 +1360,29 @@ export async function isLocalBranchProvablyOnArbiter(
|
|
|
1316
1360
|
// Refresh remote-tracking refs against the live arbiter (best-effort).
|
|
1317
1361
|
await gitSoft(['fetch', '--quiet', arbiter], cwd, env);
|
|
1318
1362
|
|
|
1319
|
-
// Merged: tip is
|
|
1363
|
+
// Merged: the tip is provably on <arbiter>/main — fast-path ancestor OR
|
|
1364
|
+
// squash-aware fallback (durable done/dropped record on main + branch
|
|
1365
|
+
// carries nothing main lacks). The SAME predicate `gc.ts`'s worktree reaper
|
|
1366
|
+
// and `reap-branches.ts`'s remote sweep use — do not fork it.
|
|
1367
|
+
const parsed = parseWorkBranchRef(branch);
|
|
1368
|
+
const arbiterMainRef = `${arbiter}/main`;
|
|
1320
1369
|
const merged =
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1370
|
+
parsed === undefined
|
|
1371
|
+
? (
|
|
1372
|
+
await gitSoft(
|
|
1373
|
+
['merge-base', '--is-ancestor', localTip, arbiterMainRef],
|
|
1374
|
+
cwd,
|
|
1375
|
+
env,
|
|
1376
|
+
)
|
|
1377
|
+
).status === 0
|
|
1378
|
+
: isProvablyMergedForReap({
|
|
1379
|
+
cwd,
|
|
1380
|
+
tip: localTip,
|
|
1381
|
+
arbiterMain: arbiterMainRef,
|
|
1382
|
+
namespace: parsed.namespace as SidecarType,
|
|
1383
|
+
slug: parsed.slug,
|
|
1384
|
+
env,
|
|
1385
|
+
});
|
|
1328
1386
|
if (merged) {
|
|
1329
1387
|
return true;
|
|
1330
1388
|
}
|
package/src/concurrency.ts
CHANGED
|
@@ -49,7 +49,7 @@ export interface RunConcurrentOptions<I, T> {
|
|
|
49
49
|
/**
|
|
50
50
|
* A per-key async serialiser: `withKeyedLock(key, fn)` runs `fn` to completion
|
|
51
51
|
* before the next caller for the SAME key starts; different keys never block each
|
|
52
|
-
* other. Used to serialise the
|
|
52
|
+
* other. Used to serialise the spec, shared-working-tree CLAIM step PER REPO
|
|
53
53
|
* inside the otherwise-concurrent tick.
|
|
54
54
|
*
|
|
55
55
|
* Two concurrent claims in ONE repo would prepare their claim micro-commit in the
|