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/integration-core.ts
CHANGED
|
@@ -57,8 +57,8 @@ import {isAncestor} from './gc.js';
|
|
|
57
57
|
* integrates), so verify-then-review holds on the merged tree, never split across
|
|
58
58
|
* two trees. Any failure routes to needs-attention.
|
|
59
59
|
*
|
|
60
|
-
* It is the CORE in the head / core / tail decomposition (
|
|
61
|
-
* `work/
|
|
60
|
+
* It is the CORE in the head / core / tail decomposition (spec
|
|
61
|
+
* `work/specs/tasked/run-do-integrate-convergence.md`): the caller-specific HEAD
|
|
62
62
|
* (repo/arbiter/branch checks, source resolution, the `recovering` flag) and TAIL
|
|
63
63
|
* (switch-to-main / `syncLocalMain` / delete-local-branch / `--no-switch` / the
|
|
64
64
|
* propose next-step block, or — for `run` — the job-record + worktree reap) stay
|
|
@@ -98,7 +98,7 @@ export type IntegrationCoreOutcome =
|
|
|
98
98
|
/**
|
|
99
99
|
* The CORE's input — everything the band needs, nothing caller-shaped. Every
|
|
100
100
|
* divergence between the human `complete` path and the autonomous `do`/`run` path
|
|
101
|
-
* maps to a FIELD VALUE here, not an `if (caller === …)` branch (
|
|
101
|
+
* maps to a FIELD VALUE here, not an `if (caller === …)` branch (spec: "zero
|
|
102
102
|
* caller-identity leakage"). In-place vs worktree = `cwd`; arbiter name =
|
|
103
103
|
* `arbiter`; human vs autonomous surfacing = `surfaceArbiter`; do's recovery =
|
|
104
104
|
* `source` + `recovering`; per-repo/lang gate = `verify`.
|
|
@@ -108,9 +108,9 @@ export type IntegrationCoreOutcome =
|
|
|
108
108
|
* task-shaped done-move + title source. The shared band
|
|
109
109
|
* (verify→review→commit→rebase→integrate→propose-PR-with-title/body) is
|
|
110
110
|
* IDENTICAL; only the "which item move + which file to read the title from" step
|
|
111
|
-
* is caller-supplied. This is the seam the `do
|
|
112
|
-
* rides (task `slice-output-through-integration`): its "item move" is the
|
|
113
|
-
* LIFECYCLE move (`work/
|
|
111
|
+
* is caller-supplied. This is the seam the `do spec:<slug>` TASKING transition
|
|
112
|
+
* rides (task `slice-output-through-integration`): its "item move" is the spec
|
|
113
|
+
* LIFECYCLE move (`work/specs/ready/<slug>.md → work/specs/tasked/<slug>.md`, residence =
|
|
114
114
|
* tasked-ness) plus its EMITTED backlog files — NOT a task done-move. Supplying it
|
|
115
115
|
* makes every integrate-time arg (`--propose`/`--merge`, provider, title/body)
|
|
116
116
|
* apply to tasking BY CONSTRUCTION, because they resolve ONCE here.
|
|
@@ -127,7 +127,7 @@ export interface IntegrationLifecycle {
|
|
|
127
127
|
/**
|
|
128
128
|
* Absolute path to the item file whose `title:` frontmatter seeds the default
|
|
129
129
|
* commit summary AND the synthesised propose-mode PR title. For the tasking
|
|
130
|
-
* transition this is the held
|
|
130
|
+
* transition this is the held spec (`work/specs/ready/<slug>.md`) — read BEFORE
|
|
131
131
|
* {@link stage} moves it. IGNORED when {@link title} is supplied (the explicit
|
|
132
132
|
* title wins — no file read).
|
|
133
133
|
*/
|
|
@@ -137,16 +137,16 @@ export interface IntegrationLifecycle {
|
|
|
137
137
|
* uses THIS as the title source for the default commit summary AND the synthesised
|
|
138
138
|
* propose-mode PR title, INSTEAD of reading {@link titlePath}. This is the seam for
|
|
139
139
|
* a lifecycle whose output file does NOT yet exist at title-read time — the intake
|
|
140
|
-
* lone-task /
|
|
140
|
+
* lone-task / spec path WRITES `work/backlog/<slug>.md` / `work/specs/ready/<slug>.md` in
|
|
141
141
|
* {@link stage}, which runs AFTER the title read, so a `titlePath` read would race
|
|
142
|
-
* the write and fall back to a generic subject. The `do
|
|
143
|
-
* leaves this unset (its `titlePath` is an already-existing held
|
|
142
|
+
* the write and fall back to a generic subject. The `do spec:` tasking transition
|
|
143
|
+
* leaves this unset (its `titlePath` is an already-existing held spec, read fine).
|
|
144
144
|
*/
|
|
145
145
|
title?: string;
|
|
146
146
|
/**
|
|
147
147
|
* STAGE the lifecycle move + emitted files into the index on the current work
|
|
148
148
|
* branch (runner-owned git; the agent never does git). For the tasking
|
|
149
|
-
* transition: `git mv work/
|
|
149
|
+
* transition: `git mv work/specs/ready/<slug>.md → work/specs/tasked/<slug>.md`
|
|
150
150
|
* (residence = tasked-ness; no marker), and write+`git add` the produced
|
|
151
151
|
* `work/backlog/*.md` files. The band's subsequent `git add -A` + atomic commit
|
|
152
152
|
* folds this staging
|
|
@@ -165,8 +165,8 @@ export interface IntegrationLifecycle {
|
|
|
165
165
|
|
|
166
166
|
/**
|
|
167
167
|
* The default LIVENESS CEILING for the merge-mode `${branch}:main` push (the
|
|
168
|
-
* durable promotions `tasks/ready → tasks/done` and, via `lifecycle`, `
|
|
169
|
-
* →
|
|
168
|
+
* durable promotions `tasks/ready → tasks/done` and, via `lifecycle`, `specs/ready
|
|
169
|
+
* → specs/tasked`). Task `c2-rebase-until-real-on-durable-main-promotions` turned
|
|
170
170
|
* the previous SMALL FIXED CAP (was 5, the `run-fleet-claim-integrate-and-sibling-
|
|
171
171
|
* rebase-concurrency-safe` Race-1 budget) into rebase-until-real-conflict: a CLEAN
|
|
172
172
|
* re-rebase no longer counts against a tiny give-up budget — only a GENUINE
|
|
@@ -271,7 +271,7 @@ export interface IntegrationCoreInput {
|
|
|
271
271
|
* `work/<type>-<slug>` identity. When omitted, the core derives it from the
|
|
272
272
|
* branch HEAD is on (the robust default — the type is encoded IN the name). A
|
|
273
273
|
* caller that knows the type explicitly may pass it (e.g. the tasking path
|
|
274
|
-
* passes its `work/
|
|
274
|
+
* passes its `work/specs/ready-<slug>`).
|
|
275
275
|
*/
|
|
276
276
|
branch?: string;
|
|
277
277
|
/**
|
|
@@ -279,7 +279,7 @@ export interface IntegrationCoreInput {
|
|
|
279
279
|
* freshly-built path — since claim no longer moves the body, a freshly-built
|
|
280
280
|
* task RESTS in the pool on `main`, task
|
|
281
281
|
* `cutover-claim-body-stays-and-complete-sources-from-backlog`),
|
|
282
|
-
* `tasks-backlog` (the `--allow-backlog` staged-drive path,
|
|
282
|
+
* `tasks-backlog` (the `--allow-backlog` staged-drive path, spec
|
|
283
283
|
* `do-allow-backlog-drive-staged-tasks-without-promotion`: a human drove a
|
|
284
284
|
* STAGED task in place, so the done-move goes `tasks/backlog/ → tasks/done/`
|
|
285
285
|
* DIRECTLY — the explicit drive IS the promotion, never bouncing through the
|
|
@@ -313,8 +313,8 @@ export interface IntegrationCoreInput {
|
|
|
313
313
|
// like a normal build.
|
|
314
314
|
source: 'tasks-ready' | 'tasks-backlog' | 'in-progress' | 'done';
|
|
315
315
|
/**
|
|
316
|
-
* Vestigial: was `true` when completing FROM `
|
|
317
|
-
* recovery finish under the legacy folder model). The per-item-lock cutover
|
|
316
|
+
* Vestigial: was `true` when completing FROM the retired `needs-attention/`
|
|
317
|
+
* folder (a recovery finish under the legacy folder model). The per-item-lock cutover
|
|
318
318
|
* (`cutover-needs-attention-becomes-lock-stuck-recovery-surface`) retired
|
|
319
319
|
* that folder — a stuck item is now the lock `state: stuck` and the body
|
|
320
320
|
* stays in `tasks/ready/`, so a recovery `complete` is structurally a normal
|
|
@@ -325,7 +325,7 @@ export interface IntegrationCoreInput {
|
|
|
325
325
|
*/
|
|
326
326
|
recovering: boolean;
|
|
327
327
|
/**
|
|
328
|
-
* **RECOVER an already-committed, already-done-moved STRANDED branch** (
|
|
328
|
+
* **RECOVER an already-committed, already-done-moved STRANDED branch** (spec
|
|
329
329
|
* `ledger-integrity` story 6, the `finish-already-committed-branch` task). When
|
|
330
330
|
* `true`, the work is ALREADY committed on the work branch with the task already
|
|
331
331
|
* `git mv`'d into `work/done/` (a terminal push failed AFTER steps 2–3, leaving
|
|
@@ -564,7 +564,7 @@ export interface IntegrationCoreInput {
|
|
|
564
564
|
* `slice-output-through-integration`). When set, the band reads the title from
|
|
565
565
|
* its {@link IntegrationLifecycle.titlePath}, calls its
|
|
566
566
|
* {@link IntegrationLifecycle.stage} INSTEAD of the task `git mv → work/done/`,
|
|
567
|
-
* and uses the plain rebase ({@link recovering} is irrelevant). The `do
|
|
567
|
+
* and uses the plain rebase ({@link recovering} is irrelevant). The `do spec:`
|
|
568
568
|
* TASKING transition supplies it; `do`/`complete`/`run` leave it unset (the
|
|
569
569
|
* task done-move is unchanged).
|
|
570
570
|
*/
|
|
@@ -579,9 +579,11 @@ export interface IntegrationCoreResult {
|
|
|
579
579
|
/** What the core resolved (the tail maps this 1:1 onto its own outcome). */
|
|
580
580
|
outcome: IntegrationCoreOutcome;
|
|
581
581
|
/**
|
|
582
|
-
* True iff a FAILURE outcome was routed
|
|
583
|
-
*
|
|
584
|
-
*
|
|
582
|
+
* True iff a FAILURE outcome was routed through the shared needs-attention
|
|
583
|
+
* mechanism — post lock-cutover, the per-item lock was amended to
|
|
584
|
+
* `state: stuck` with the reason on the lock entry (no folder move). False
|
|
585
|
+
* on the success path and when a failure was NOT surfaced (e.g. a red
|
|
586
|
+
* re-gate that stays put in recovery).
|
|
585
587
|
*/
|
|
586
588
|
routedToNeedsAttention: boolean;
|
|
587
589
|
/** The work branch that was processed (`work/<slug>`). */
|
|
@@ -606,8 +608,8 @@ export interface IntegrationCoreResult {
|
|
|
606
608
|
* needs-attention routing can record the findings as the item-body prose. The
|
|
607
609
|
* tasking path (task `slice-acceptance-gate`) reads this: the core's build
|
|
608
610
|
* `applyNeedsAttentionTransition` is keyed on a TASK lock, so the tasking path
|
|
609
|
-
* routes the
|
|
610
|
-
* `
|
|
611
|
+
* routes the spec itself via the lock release's needs-attention redirect (amend the
|
|
612
|
+
* `spec:<slug>` unified lock `active -> stuck`, no folder move), using THIS
|
|
611
613
|
* findings text as the body. Absent on every non-`review-blocked` outcome. (The
|
|
612
614
|
* build path ignores it — its routing already records the findings in-body.)
|
|
613
615
|
*/
|
|
@@ -667,7 +669,7 @@ export async function performIntegration(
|
|
|
667
669
|
// in the `run` caller, not here.
|
|
668
670
|
const freshWorktreeGate = input.freshWorktreeGate === true;
|
|
669
671
|
|
|
670
|
-
// RECOVER an already-committed, already-done-moved STRANDED branch (
|
|
672
|
+
// RECOVER an already-committed, already-done-moved STRANDED branch (spec
|
|
671
673
|
// `ledger-integrity` story 6). The work + the done-move are ALREADY committed on
|
|
672
674
|
// the work branch (a terminal push failed AFTER steps 2–3); SKIP steps 0–3
|
|
673
675
|
// (prepare / gate / review / done-move / commit) and run ONLY the
|
|
@@ -687,8 +689,21 @@ export async function performIntegration(
|
|
|
687
689
|
recoveryRebaseJitterMs: input.recoveryRebaseJitterMs,
|
|
688
690
|
recoveryRebaseSleep: input.recoveryRebaseSleep,
|
|
689
691
|
recoveryRebaseRandom: input.recoveryRebaseRandom,
|
|
692
|
+
// GATE-2 REVIEW on the recovery path (task
|
|
693
|
+
// `committed-recovery-always-reviews`): a stranded already-complete
|
|
694
|
+
// branch is NOT "already reviewed" — its earlier attempt's PR never
|
|
695
|
+
// merged and Gate 2 may never have run on it. So when `review` is on we
|
|
696
|
+
// MUST run Gate 2 on the rebased tip here too (the SAME reasoning that
|
|
697
|
+
// forces the re-verify: `<arbiter>/main` moved, the merged tree is new).
|
|
698
|
+
// Pass the whole `input` so the recovery tail can call `runGate2Review`
|
|
699
|
+
// with the identical gate/model/watch/round wiring the build path uses.
|
|
700
|
+
input,
|
|
701
|
+
// PR BODY on the recovery path: the recovery has NO fresh agent output
|
|
702
|
+
// (no rebuild), so carry whatever `body` the caller supplied so the PR
|
|
703
|
+
// gets a description instead of degrading to a blank `gh --fill`.
|
|
704
|
+
body: input.body,
|
|
690
705
|
// Answered-merge land (task `committed-recovery-honours-fresh-worktree-gate`,
|
|
691
|
-
//
|
|
706
|
+
// spec `land-time-reverify-and-parallel-merge-ceiling`): the apply-rung
|
|
692
707
|
// dispatches an answered `merge` through this committed-recovery tail (the
|
|
693
708
|
// branch already carries its done-move commit, so the build path's
|
|
694
709
|
// `git mv`+`add -A`+commit would raise `IntegrationNothingStaged`). UNLIKE
|
|
@@ -713,7 +728,7 @@ export async function performIntegration(
|
|
|
713
728
|
}
|
|
714
729
|
|
|
715
730
|
// The file whose `title:` seeds the commit summary + PR title. For a TASKING
|
|
716
|
-
// transition (a non-task `lifecycle`) this is the held
|
|
731
|
+
// transition (a non-task `lifecycle`) this is the held spec it supplies; for a
|
|
717
732
|
// build it is the task in its source folder. Read BEFORE any move.
|
|
718
733
|
const lifecycle = input.lifecycle;
|
|
719
734
|
// CONTINUE-BUILD (`source: 'done'`, task
|
|
@@ -740,7 +755,7 @@ export async function performIntegration(
|
|
|
740
755
|
// passes no flag, so there an untrusted-origin task RELIABLY forces propose.
|
|
741
756
|
//
|
|
742
757
|
// SCOPE: the task BUILD transition ONLY. It NEVER fires for a `lifecycle`
|
|
743
|
-
// transition (tasking / intake-emit — a
|
|
758
|
+
// transition (tasking / intake-emit — a spec/task FILE landing on main is inert;
|
|
744
759
|
// intake's OWN per-emit resolver already decided that mode), and the source file
|
|
745
760
|
// here is the task being built. A `trusted`/unset task ⇒ untouched (zero
|
|
746
761
|
// behaviour change for the normal human path).
|
|
@@ -793,10 +808,11 @@ export async function performIntegration(
|
|
|
793
808
|
}
|
|
794
809
|
if (!prep.passed) {
|
|
795
810
|
const reason = `prepare (env-prep) failed (exit ${prep.exitCode})`;
|
|
796
|
-
//
|
|
797
|
-
//
|
|
798
|
-
//
|
|
799
|
-
//
|
|
811
|
+
// Mark the item stuck on its per-item lock (the SAME seam a red gate uses)
|
|
812
|
+
// — recording the prepare-failed reason on the lock entry + saving the
|
|
813
|
+
// agent's uncommitted work as a wip commit (post lock-cutover: a lock amend,
|
|
814
|
+
// no `in-progress/ → needs-attention/` folder move). We NEVER run `verify`
|
|
815
|
+
// on an env that could not be made ready.
|
|
800
816
|
const routed = await ledgerWrite.applyNeedsAttentionTransition({
|
|
801
817
|
cwd,
|
|
802
818
|
slug,
|
|
@@ -810,10 +826,10 @@ export async function performIntegration(
|
|
|
810
826
|
routedToNeedsAttention: routed.moved,
|
|
811
827
|
branch,
|
|
812
828
|
reason: routed.moved
|
|
813
|
-
? `Env-prep (prepare) failed (exit ${prep.exitCode});
|
|
814
|
-
'
|
|
829
|
+
? `Env-prep (prepare) failed (exit ${prep.exitCode}); marked '${slug}' ` +
|
|
830
|
+
'stuck on its per-item lock (the environment could not be made ready, ' +
|
|
815
831
|
'so the acceptance gate was NOT run). Fix the prepare command, then ' +
|
|
816
|
-
'
|
|
832
|
+
'`requeue` to release the stuck lock.'
|
|
817
833
|
: `Env-prep (prepare) failed (exit ${prep.exitCode}); not completing ` +
|
|
818
834
|
`'${slug}' (the environment could not be made ready, so the ` +
|
|
819
835
|
'acceptance gate was NOT run). Fix the prepare command, then retry.',
|
|
@@ -832,12 +848,12 @@ export async function performIntegration(
|
|
|
832
848
|
note('Running the acceptance gate (verify)…');
|
|
833
849
|
const gate = await runVerify({cwd, verify: input.verify, env});
|
|
834
850
|
if (!gate.passed) {
|
|
835
|
-
// Don't leave the item dangling
|
|
836
|
-
//
|
|
837
|
-
//
|
|
838
|
-
//
|
|
839
|
-
//
|
|
840
|
-
//
|
|
851
|
+
// Don't leave the item dangling: mark it stuck on its per-item lock with
|
|
852
|
+
// the reason (ADR §12) THROUGH the ledger write seam's needs-attention
|
|
853
|
+
// transition. Post lock-cutover this is a lock amend (`state: stuck` + the
|
|
854
|
+
// reason on the lock entry, no `in-progress/ → needs-attention/` folder
|
|
855
|
+
// move) plus saving the agent's uncommitted work as a wip commit. No
|
|
856
|
+
// partial state.
|
|
841
857
|
const reason = `acceptance gate failed (exit ${gate.exitCode})`;
|
|
842
858
|
const routed = await ledgerWrite.applyNeedsAttentionTransition({
|
|
843
859
|
cwd,
|
|
@@ -860,16 +876,16 @@ export async function performIntegration(
|
|
|
860
876
|
routedToNeedsAttention: routed.moved,
|
|
861
877
|
branch,
|
|
862
878
|
reason: routed.moved
|
|
863
|
-
? `Acceptance gate failed (exit ${gate.exitCode});
|
|
864
|
-
'
|
|
865
|
-
'
|
|
879
|
+
? `Acceptance gate failed (exit ${gate.exitCode}); marked '${slug}' ` +
|
|
880
|
+
'stuck on its per-item lock (surfaced by status; `requeue` once ' +
|
|
881
|
+
'resolved). Fix the work, or use --skip-verify to override.'
|
|
866
882
|
: `Acceptance gate failed (exit ${gate.exitCode}); not completing ` +
|
|
867
883
|
`'${slug}'. Fix the work, or use --skip-verify to override.`,
|
|
868
884
|
};
|
|
869
885
|
}
|
|
870
886
|
}
|
|
871
887
|
|
|
872
|
-
// 1b. Gate 2 — the PR/code REVIEW gate (GATES
|
|
888
|
+
// 1b. Gate 2 — the PR/code REVIEW gate (GATES spec `work/specs/tasked/review.md`). It is a
|
|
873
889
|
// JUDGEMENT gate layered ON TOP of the deterministic `verify` floor (ADR §8)
|
|
874
890
|
// — NEVER a replacement, and ALWAYS verify-THEN-review on the SAME tree.
|
|
875
891
|
//
|
|
@@ -924,10 +940,10 @@ export async function performIntegration(
|
|
|
924
940
|
// never be the multi-line commit-subject run-on `--fill` would derive.
|
|
925
941
|
//
|
|
926
942
|
// When the lifecycle supplies an EXPLICIT `title`, use it DIRECTLY (no file read):
|
|
927
|
-
// the intake lone-task /
|
|
943
|
+
// the intake lone-task / spec path writes its output file in `stage()`, which runs
|
|
928
944
|
// AFTER this point, so a `titlePath` read would race the write and degrade the
|
|
929
|
-
// subject/PR title to the generic fallback. The `do
|
|
930
|
-
// `title` unset and keeps reading its already-existing held
|
|
945
|
+
// subject/PR title to the generic fallback. The `do spec:` tasking path leaves
|
|
946
|
+
// `title` unset and keeps reading its already-existing held spec (unchanged).
|
|
931
947
|
const explicitTitle = lifecycle?.title;
|
|
932
948
|
const taskTitle =
|
|
933
949
|
explicitTitle !== undefined ? explicitTitle : readTaskTitle(sourcePath);
|
|
@@ -943,7 +959,7 @@ export async function performIntegration(
|
|
|
943
959
|
|
|
944
960
|
// 2. STAGE the item move into the index. For a build that is the task done-move
|
|
945
961
|
// (`work/<source>/<slug>.md → work/done/<slug>.md`); for a TASKING
|
|
946
|
-
// transition (a non-task `lifecycle`) it is the caller-supplied
|
|
962
|
+
// transition (a non-task `lifecycle`) it is the caller-supplied spec
|
|
947
963
|
// lifecycle move + emitted backlog files (the runner stages them, the agent
|
|
948
964
|
// never does git). Either way the subsequent `git add -A` folds the agent's
|
|
949
965
|
// uncommitted work + this staging into ONE atomic commit.
|
|
@@ -1001,7 +1017,7 @@ export async function performIntegration(
|
|
|
1001
1017
|
// they are TRACKED, not dropped/untracked. Rule B is extended HERE: the runner REPORTS
|
|
1002
1018
|
// exactly which note files landed (honest reporting — what actually reached the commit,
|
|
1003
1019
|
// read from the staged set, not assumed). This is the ONE shared place — BOTH the build
|
|
1004
|
-
// path (`do <task>`/`run`/`complete`) and the tasking path (`do
|
|
1020
|
+
// path (`do <task>`/`run`/`complete`) and the tasking path (`do spec:`, via the
|
|
1005
1021
|
// `lifecycle` seam) route through it, so the channel is NOT forked. Zero notes ⇒ no
|
|
1006
1022
|
// report (the no-note case is byte-for-byte unchanged).
|
|
1007
1023
|
await reportScoopedNotes(cwd, env, note);
|
|
@@ -1038,16 +1054,14 @@ export async function performIntegration(
|
|
|
1038
1054
|
// 4. Rebase-before-integrate (ADR §10): rebase the work branch onto the
|
|
1039
1055
|
// latest <arbiter>/main. Clean → continue. Conflict → abort + stop.
|
|
1040
1056
|
//
|
|
1041
|
-
// RECOVERY reconciliation:
|
|
1042
|
-
//
|
|
1043
|
-
//
|
|
1044
|
-
//
|
|
1045
|
-
//
|
|
1046
|
-
//
|
|
1047
|
-
//
|
|
1048
|
-
//
|
|
1049
|
-
// needs-attention/). The done-move thus SUPERSEDES the surfaced state — no
|
|
1050
|
-
// leftover/conflicting on-`main` surface for the human to resolve.
|
|
1057
|
+
// RECOVERY reconciliation: post the per-item-lock cut-over, a stuck item's
|
|
1058
|
+
// body never moved into a `needs-attention/` folder (stuck is the lock
|
|
1059
|
+
// `state: stuck`; the body rests in `backlog/`), so a recovery `complete`'s
|
|
1060
|
+
// kept branch carries NO historical `in-progress → needs-attention`
|
|
1061
|
+
// move-only commit to drop and `<arbiter>/main` holds no surface move to
|
|
1062
|
+
// conflict with. The old recovery drop (`rebaseDroppingNeedsAttentionSurface`,
|
|
1063
|
+
// drop-bookkeeping-rebase) is deleted; recovery is now the SAME plain replay
|
|
1064
|
+
// onto `<arbiter>/main` as any other build (see the plain-rebase note below).
|
|
1051
1065
|
// Fetch the arbiter's `main` into the `<arbiter>/main` remote-tracking ref
|
|
1052
1066
|
// EXPLICITLY. A `run` JOB WORKTREE is cut from a bare hub mirror whose remote
|
|
1053
1067
|
// has no fetch refspec (so `<arbiter>/main` would not otherwise resolve / would
|
|
@@ -1099,7 +1113,7 @@ export async function performIntegration(
|
|
|
1099
1113
|
};
|
|
1100
1114
|
}
|
|
1101
1115
|
}
|
|
1102
|
-
// PLAIN rebase. After the per-item-lock cut-over (
|
|
1116
|
+
// PLAIN rebase. After the per-item-lock cut-over (spec
|
|
1103
1117
|
// `ledger-status-per-item-lock-refs`, tasks 9a–9d) no transient status
|
|
1104
1118
|
// lands on a work branch: needs-attention is the lock `state: stuck` (not a
|
|
1105
1119
|
// `git mv` to `needs-attention/`), the body rests in `backlog/` while
|
|
@@ -1209,12 +1223,12 @@ export async function performIntegration(
|
|
|
1209
1223
|
// recovery above can fall through to integrate while a genuine code conflict
|
|
1210
1224
|
// still routes here.
|
|
1211
1225
|
async function rebaseConflictRoute(): Promise<IntegrationCoreResult> {
|
|
1212
|
-
// Then
|
|
1213
|
-
// §12) THROUGH the ledger write seam's needs-attention transition,
|
|
1214
|
-
// than leaving it dangling
|
|
1215
|
-
//
|
|
1216
|
-
//
|
|
1217
|
-
//
|
|
1226
|
+
// Then mark the item stuck on its per-item lock with the conflict reason
|
|
1227
|
+
// (ADR §12) THROUGH the ledger write seam's needs-attention transition,
|
|
1228
|
+
// rather than leaving it dangling. Post lock-cutover this is a lock amend
|
|
1229
|
+
// (`state: stuck` + the reason on the lock entry, no `done/ →
|
|
1230
|
+
// needs-attention/` folder move); the done-move already committed above
|
|
1231
|
+
// stands. No partial state.
|
|
1218
1232
|
const reason = `rebase onto ${arbiter}/main conflicted (aborted, never auto-resolved)`;
|
|
1219
1233
|
const routed = await ledgerWrite.applyNeedsAttentionTransition({
|
|
1220
1234
|
cwd,
|
|
@@ -1236,9 +1250,9 @@ export async function performIntegration(
|
|
|
1236
1250
|
commitMessage,
|
|
1237
1251
|
reason: routed.moved
|
|
1238
1252
|
? `Rebasing ${branch} onto ${arbiter}/main conflicted; the rebase was ` +
|
|
1239
|
-
`aborted (never auto-resolved) and '${slug}' was
|
|
1240
|
-
'
|
|
1241
|
-
'
|
|
1253
|
+
`aborted (never auto-resolved) and '${slug}' was marked stuck on ` +
|
|
1254
|
+
'its per-item lock (surfaced by status). Resolve against the latest ' +
|
|
1255
|
+
'main, then `requeue` to release the stuck lock and re-run.'
|
|
1242
1256
|
: `Rebasing ${branch} onto ${arbiter}/main conflicted; the rebase was ` +
|
|
1243
1257
|
'aborted (never auto-resolved). Resolve against the latest main, ' +
|
|
1244
1258
|
'then re-run complete.',
|
|
@@ -1318,9 +1332,9 @@ export async function performIntegration(
|
|
|
1318
1332
|
branch,
|
|
1319
1333
|
commitMessage,
|
|
1320
1334
|
reason: routed.moved
|
|
1321
|
-
? `${what} on the rebased tip;
|
|
1322
|
-
'
|
|
1323
|
-
'
|
|
1335
|
+
? `${what} on the rebased tip; marked '${slug}' stuck on its ` +
|
|
1336
|
+
'per-item lock (surfaced by status; `requeue` once resolved). ' +
|
|
1337
|
+
'Fix the work, or use --skip-verify to override.'
|
|
1324
1338
|
: `${what} on the rebased tip; not completing '${slug}'. Fix the ` +
|
|
1325
1339
|
'work, or use --skip-verify to override.',
|
|
1326
1340
|
};
|
|
@@ -1335,7 +1349,8 @@ export async function performIntegration(
|
|
|
1335
1349
|
if (gated.review) {
|
|
1336
1350
|
if (gated.review.kind === 'blocked') {
|
|
1337
1351
|
// The done-move was already committed (steps 2–3), so the slug sits in
|
|
1338
|
-
// work/done/; the routing
|
|
1352
|
+
// work/done/; the routing marked it stuck on its per-item lock (post
|
|
1353
|
+
// lock-cutover — a lock amend, no folder move).
|
|
1339
1354
|
return gated.review.result;
|
|
1340
1355
|
}
|
|
1341
1356
|
approvedVerdict = gated.review.verdict;
|
|
@@ -1503,9 +1518,10 @@ export async function performIntegration(
|
|
|
1503
1518
|
commitMessage,
|
|
1504
1519
|
reason: routed.moved
|
|
1505
1520
|
? `Integrating ${branch} onto ${arbiter}/main kept hitting a ` +
|
|
1506
|
-
`non-fast-forward push (a sibling advanced main); '${slug}' was
|
|
1507
|
-
`
|
|
1508
|
-
`latest main, then
|
|
1521
|
+
`non-fast-forward push (a sibling advanced main); '${slug}' was ` +
|
|
1522
|
+
`marked stuck on its per-item lock (surfaced by status). Resolve ` +
|
|
1523
|
+
`against the latest main, then \`requeue\` to release the stuck ` +
|
|
1524
|
+
`lock and re-run.`
|
|
1509
1525
|
: `Integrating ${branch} onto ${arbiter}/main kept hitting a ` +
|
|
1510
1526
|
`non-fast-forward push (a sibling advanced main). Resolve against the ` +
|
|
1511
1527
|
`latest main, then re-run complete.`,
|
|
@@ -1580,7 +1596,7 @@ export async function performIntegration(
|
|
|
1580
1596
|
}
|
|
1581
1597
|
|
|
1582
1598
|
/**
|
|
1583
|
-
* RECOVER an already-committed, already-done-moved STRANDED branch (
|
|
1599
|
+
* RECOVER an already-committed, already-done-moved STRANDED branch (spec
|
|
1584
1600
|
* `ledger-integrity` story 6, the `finish-already-committed-branch` task). The
|
|
1585
1601
|
* green work AND the `git mv → work/done/` are ALREADY committed on the work
|
|
1586
1602
|
* branch (a terminal push failed AFTER `performIntegration`'s steps 2–3), and the
|
|
@@ -1590,7 +1606,7 @@ export async function performIntegration(
|
|
|
1590
1606
|
* primitive the build path uses.
|
|
1591
1607
|
*
|
|
1592
1608
|
* RE-GATE on the REBASED TIP (task `committed-recovery-honours-fresh-worktree-
|
|
1593
|
-
* gate`,
|
|
1609
|
+
* gate`, spec `land-time-reverify-and-parallel-merge-ceiling`): when the caller
|
|
1594
1610
|
* sets `freshWorktreeGate` (and not `skipVerify`), the EXISTING
|
|
1595
1611
|
* `runFreshWorktreeGate` runs on the rebased tip AFTER the rebase loop and
|
|
1596
1612
|
* BEFORE `applyCompleteTransition`, mirroring the build path's
|
|
@@ -1635,7 +1651,7 @@ async function recoverAlreadyCommitted(params: {
|
|
|
1635
1651
|
/**
|
|
1636
1652
|
* Run the EXISTING `runFreshWorktreeGate` (`prepare` then `verify`) on the
|
|
1637
1653
|
* rebased tip AFTER the rebase loop and BEFORE `applyCompleteTransition`
|
|
1638
|
-
* (task `committed-recovery-honours-fresh-worktree-gate`,
|
|
1654
|
+
* (task `committed-recovery-honours-fresh-worktree-gate`, spec
|
|
1639
1655
|
* `land-time-reverify-and-parallel-merge-ceiling`). The original stranded-
|
|
1640
1656
|
* recovery caller (`complete --integration`'s already-built strand) leaves
|
|
1641
1657
|
* this UNSET ⇒ no gate, no extra fetch — byte-identical to before. The
|
|
@@ -1653,6 +1669,23 @@ async function recoverAlreadyCommitted(params: {
|
|
|
1653
1669
|
prepare?: VerifyConfig;
|
|
1654
1670
|
/** Acceptance gate config for the fresh gate (mirrors the build path). */
|
|
1655
1671
|
verify?: VerifyConfig;
|
|
1672
|
+
/**
|
|
1673
|
+
* The full integration input, threaded so the recovery tail can run Gate 2
|
|
1674
|
+
* (`runGate2Review`) with the identical gate/model/watch/round wiring the
|
|
1675
|
+
* build path uses (task `committed-recovery-always-reviews`). Gate 2 runs on
|
|
1676
|
+
* the rebased tip when `input.review` is on and the fresh gate ran green — a
|
|
1677
|
+
* stranded already-complete branch is NOT trusted as already-reviewed (its
|
|
1678
|
+
* earlier attempt never merged). Optional so the pre-existing non-review
|
|
1679
|
+
* callers (and tests) that do not thread it stay byte-identical.
|
|
1680
|
+
*/
|
|
1681
|
+
input?: IntegrationCoreInput;
|
|
1682
|
+
/**
|
|
1683
|
+
* The propose-mode PR BODY (task `committed-recovery-always-reviews`): the
|
|
1684
|
+
* recovery has NO fresh agent output (no rebuild), so the caller passes
|
|
1685
|
+
* whatever advisory body it has so the PR carries a description instead of a
|
|
1686
|
+
* blank `gh --fill`. Undefined ⇒ today's `--fill` fallback.
|
|
1687
|
+
*/
|
|
1688
|
+
body?: string;
|
|
1656
1689
|
/**
|
|
1657
1690
|
* Autonomous needs-attention surface (mirrors the build path): when set, a
|
|
1658
1691
|
* red rebased-tip gate cherry-picks the bounce onto `main` + pushes the
|
|
@@ -1704,6 +1737,14 @@ async function recoverAlreadyCommitted(params: {
|
|
|
1704
1737
|
// (`isAncestor` is the SAME reachability predicate `gc.ts` uses; do not fork it.)
|
|
1705
1738
|
// KEPT before the retry loop: a no-op MUST short-circuit before we burn any
|
|
1706
1739
|
// re-fetch/re-rebase budget.
|
|
1740
|
+
//
|
|
1741
|
+
// DELIBERATELY the RAW ancestry predicate, NOT `isProvablyMergedForReap`
|
|
1742
|
+
// (task `reap-squash-merged-remote-work-branches`, ratified): this is an
|
|
1743
|
+
// integration-IDEMPOTENCY check, not reap-safety. A squash-landed LOOKALIKE
|
|
1744
|
+
// whose tip is NOT genuinely reachable would falsely read "already
|
|
1745
|
+
// integrated" here and skip a needed rebase/re-push. The squash-aware helper
|
|
1746
|
+
// is scoped to reap-safety ONLY; see gc.ts `isProvablyMergedForReap` and
|
|
1747
|
+
// work/notes/observations/reap-squash-helper-scope-2026-07-10.md.
|
|
1707
1748
|
if (isAncestor(cwd, tip, `refs/remotes/${arbiter}/main`, env)) {
|
|
1708
1749
|
const message =
|
|
1709
1750
|
`Nothing to recover for '${slug}': its work branch tip is already on ` +
|
|
@@ -1801,7 +1842,7 @@ async function recoverAlreadyCommitted(params: {
|
|
|
1801
1842
|
}
|
|
1802
1843
|
|
|
1803
1844
|
// FRESH-WORKTREE GATE on the REBASED TIP (task `committed-recovery-honours-
|
|
1804
|
-
// fresh-worktree-gate`,
|
|
1845
|
+
// fresh-worktree-gate`, spec `land-time-reverify-and-parallel-merge-ceiling`):
|
|
1805
1846
|
// when `freshWorktreeGate` is set (the answered-merge land caller) and not
|
|
1806
1847
|
// `--skip-verify`, re-run the acceptance gate on the rebased tip BEFORE we
|
|
1807
1848
|
// integrate, mirroring the build path's `freshWorktreeGate && !skipVerify &&
|
|
@@ -1812,13 +1853,23 @@ async function recoverAlreadyCommitted(params: {
|
|
|
1812
1853
|
// clean-rebase-but-broken merge. With `freshWorktreeGate` UNSET (the original
|
|
1813
1854
|
// stranded-recovery caller, whose pre-strand build already gated) this whole
|
|
1814
1855
|
// block is skipped and behaviour is byte-identical to before.
|
|
1856
|
+
// Carry an approved Gate-2 verdict (when review ran) so its authored `review`
|
|
1857
|
+
// prose is posted as a PR comment AFTER the integrate below — the SAME audit
|
|
1858
|
+
// trail the build path keeps (task `committed-recovery-always-reviews`).
|
|
1859
|
+
let approvedVerdict: ReviewVerdict | undefined;
|
|
1815
1860
|
if (params.freshWorktreeGate && !params.skipVerify) {
|
|
1816
1861
|
const tip = (
|
|
1817
1862
|
await gitSoft(['rev-parse', '--verify', '--quiet', 'HEAD'], cwd, env)
|
|
1818
1863
|
).stdout.trim();
|
|
1819
|
-
//
|
|
1820
|
-
//
|
|
1821
|
-
//
|
|
1864
|
+
// GATE-2 REVIEW callback (task `committed-recovery-always-reviews`): when
|
|
1865
|
+
// `input.review` is on, run Gate 2 on the rebased tip AFTER the green verify
|
|
1866
|
+
// — EXACTLY the build path's fresh-gate `review:` callback. A stranded
|
|
1867
|
+
// already-complete branch is NOT trusted as already-reviewed (its earlier
|
|
1868
|
+
// attempt's PR never merged, and Gate 2 may never have run on it); the same
|
|
1869
|
+
// reasoning that forces the re-verify here (`<arbiter>/main` moved, so the
|
|
1870
|
+
// merged tree is new) forces the re-review. The needs-attention ROUTING
|
|
1871
|
+
// targets `cwd` (the work branch + ledger), identical to the build path.
|
|
1872
|
+
const reviewInput = params.input;
|
|
1822
1873
|
const gated = await runFreshWorktreeGate({
|
|
1823
1874
|
cwd,
|
|
1824
1875
|
commit: tip,
|
|
@@ -1826,6 +1877,19 @@ async function recoverAlreadyCommitted(params: {
|
|
|
1826
1877
|
verify: params.verify,
|
|
1827
1878
|
env,
|
|
1828
1879
|
note,
|
|
1880
|
+
review:
|
|
1881
|
+
reviewInput?.review === true
|
|
1882
|
+
? (reviewCwd) =>
|
|
1883
|
+
runGate2Review({
|
|
1884
|
+
reviewCwd,
|
|
1885
|
+
input: reviewInput,
|
|
1886
|
+
slug,
|
|
1887
|
+
branch,
|
|
1888
|
+
cwd,
|
|
1889
|
+
env,
|
|
1890
|
+
note,
|
|
1891
|
+
})
|
|
1892
|
+
: undefined,
|
|
1829
1893
|
});
|
|
1830
1894
|
if (!gated.passed) {
|
|
1831
1895
|
const outcome: IntegrationCoreOutcome =
|
|
@@ -1851,15 +1915,43 @@ async function recoverAlreadyCommitted(params: {
|
|
|
1851
1915
|
routedToNeedsAttention: routed.moved,
|
|
1852
1916
|
branch,
|
|
1853
1917
|
reason: routed.moved
|
|
1854
|
-
? `${what} on the rebased tip during committed-recovery;
|
|
1855
|
-
`'${slug}'
|
|
1856
|
-
'
|
|
1918
|
+
? `${what} on the rebased tip during committed-recovery; marked ` +
|
|
1919
|
+
`'${slug}' stuck on its per-item lock (surfaced by status; ` +
|
|
1920
|
+
'`requeue` once resolved). Fix the work, or use --skip-verify ' +
|
|
1857
1921
|
'to override.'
|
|
1858
1922
|
: `${what} on the rebased tip during committed-recovery; not ` +
|
|
1859
1923
|
`completing '${slug}'. Fix the work, or use --skip-verify to ` +
|
|
1860
1924
|
'override.',
|
|
1861
1925
|
};
|
|
1862
1926
|
}
|
|
1927
|
+
// GATE-2 REVIEW outcome on the rebased tip: a BLOCK routes to needs-attention
|
|
1928
|
+
// exactly as the build path (only the reviewed tree moved, not the routing).
|
|
1929
|
+
// On APPROVE: carry the verdict for the post-integrate PR comment and write
|
|
1930
|
+
// the per-run non-blocking-nits observation. UNLIKE the build path this branch
|
|
1931
|
+
// integrates the ALREADY-committed kept tip (no upcoming done-move/commit to
|
|
1932
|
+
// sweep the nits file into), so we FOLD the observation into the kept commit
|
|
1933
|
+
// via `commit --amend` — mirroring the build path's fresh-gate amend so the
|
|
1934
|
+
// nits still land in the SAME commit that integrates (no separate commit).
|
|
1935
|
+
if (gated.review) {
|
|
1936
|
+
if (gated.review.kind === 'blocked') {
|
|
1937
|
+
return gated.review.result;
|
|
1938
|
+
}
|
|
1939
|
+
approvedVerdict = gated.review.verdict;
|
|
1940
|
+
const nitsBefore = await stagedCaptureNotes(cwd, env);
|
|
1941
|
+
writeReviewNitsObservation({
|
|
1942
|
+
cwd,
|
|
1943
|
+
slug,
|
|
1944
|
+
findings: gated.review.verdict?.findings ?? [],
|
|
1945
|
+
note,
|
|
1946
|
+
});
|
|
1947
|
+
await gitHard(['add', '-A'], cwd, env);
|
|
1948
|
+
if (!(await nothingStaged(cwd, env))) {
|
|
1949
|
+
const nitsAfter = await stagedCaptureNotes(cwd, env);
|
|
1950
|
+
if (nitsAfter.length > nitsBefore.length) {
|
|
1951
|
+
await gitHard(['commit', '-q', '--amend', '--no-edit'], cwd, env);
|
|
1952
|
+
}
|
|
1953
|
+
}
|
|
1954
|
+
}
|
|
1863
1955
|
}
|
|
1864
1956
|
|
|
1865
1957
|
// Integrate the rebased kept commit through the SAME complete-transition
|
|
@@ -1872,12 +1964,27 @@ async function recoverAlreadyCommitted(params: {
|
|
|
1872
1964
|
(params.openPr
|
|
1873
1965
|
? bridgeProvider(params.openPr)
|
|
1874
1966
|
: selectProvider({arbiterUrl: await arbiterUrl(cwd, arbiter, env)}));
|
|
1967
|
+
// PR TITLE + BODY on the recovery path (task `committed-recovery-always-
|
|
1968
|
+
// reviews`): the stranded branch already holds the task in `work/done/`, so
|
|
1969
|
+
// synthesise the SAME single-line `<type>(<slug>): <title>` PR title the build
|
|
1970
|
+
// path does (from the done-resident task file, never agent text) and scaffold
|
|
1971
|
+
// the task-pointer body around the caller-supplied advisory `body`. Undefined
|
|
1972
|
+
// body ⇒ `composeProposeBody` returns undefined ⇒ the provider degrades to
|
|
1973
|
+
// `gh --fill` (no regression); a supplied body gives the PR a real description
|
|
1974
|
+
// instead of the blank one the recovery path used to open.
|
|
1975
|
+
const prTitle = synthesiseProposeTitle({
|
|
1976
|
+
type: (params.input?.type ?? DEFAULT_TYPE).trim() || DEFAULT_TYPE,
|
|
1977
|
+
slug,
|
|
1978
|
+
title: readTaskTitle(workItemPath(cwd, 'done', slug)),
|
|
1979
|
+
});
|
|
1875
1980
|
const integration = await ledgerWrite.applyCompleteTransition({
|
|
1876
1981
|
arbiter,
|
|
1877
1982
|
branch,
|
|
1878
1983
|
mode,
|
|
1879
1984
|
provider,
|
|
1880
1985
|
noPR: params.noPR,
|
|
1986
|
+
title: prTitle,
|
|
1987
|
+
body: composeProposeBody({slug, body: params.body}),
|
|
1881
1988
|
deleteMergedHead: true,
|
|
1882
1989
|
cwd,
|
|
1883
1990
|
env,
|
|
@@ -1889,6 +1996,32 @@ async function recoverAlreadyCommitted(params: {
|
|
|
1889
1996
|
`(absorbed a moving ${arbiter}/main across ${attempt} re-fetch+re-` +
|
|
1890
1997
|
`rebase attempt${attempt === 1 ? '' : 's'}).`,
|
|
1891
1998
|
);
|
|
1999
|
+
// Post the Gate-2 review as a PR comment (task `committed-recovery-always-
|
|
2000
|
+
// reviews`): the SAME post-integrate audit trail the build path keeps — the
|
|
2001
|
+
// approved verdict's authored `review` prose, on the opened PR. Advisory only
|
|
2002
|
+
// (a block never reaches here — it returned above); the same URL/branch
|
|
2003
|
+
// precedence the build path uses (parsed url wins; else a branch-resolved
|
|
2004
|
+
// fallback when a PR opened but its url was unparseable). `postPRComment*`
|
|
2005
|
+
// never throws. A clean no-op in merge mode / push-only propose (no PR).
|
|
2006
|
+
if (approvedVerdict?.review !== undefined) {
|
|
2007
|
+
if (integration.url !== undefined) {
|
|
2008
|
+
const posted = provider.postPRComment({
|
|
2009
|
+
cwd,
|
|
2010
|
+
url: integration.url,
|
|
2011
|
+
body: approvedVerdict.review,
|
|
2012
|
+
env,
|
|
2013
|
+
});
|
|
2014
|
+
note(posted.instruction);
|
|
2015
|
+
} else if (integration.requestOpened) {
|
|
2016
|
+
const posted = provider.postPRCommentOnBranch({
|
|
2017
|
+
cwd,
|
|
2018
|
+
branch,
|
|
2019
|
+
body: approvedVerdict.review,
|
|
2020
|
+
env,
|
|
2021
|
+
});
|
|
2022
|
+
note(posted.instruction);
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
1892
2025
|
return {
|
|
1893
2026
|
outcome: 'completed',
|
|
1894
2027
|
routedToNeedsAttention: false,
|
|
@@ -1931,8 +2064,9 @@ function resolveWorkBranch(
|
|
|
1931
2064
|
*
|
|
1932
2065
|
* Carries the {@link slug} so the autonomous-strand surface in `complete.ts`
|
|
1933
2066
|
* (which catches this error in `performComplete`'s outer try/catch, OUTSIDE the
|
|
1934
|
-
* `runComplete` slug scope) can
|
|
1935
|
-
*
|
|
2067
|
+
* `runComplete` slug scope) can mark the item stuck on its per-item lock (post
|
|
2068
|
+
* lock-cutover — the tree-less lock amend, no `in-progress/ → needs-attention/`
|
|
2069
|
+
* folder move) without re-deriving the slug from the error message.
|
|
1936
2070
|
*/
|
|
1937
2071
|
export class IntegrationNothingStaged extends Error {
|
|
1938
2072
|
constructor(
|
|
@@ -2113,8 +2247,8 @@ export function composeProposeBody(input: {
|
|
|
2113
2247
|
* On a review APPROVE that carries ≥1 NON-BLOCKING finding, write ONE per-run
|
|
2114
2248
|
* observation `work/notes/observations/review-nits-<slug>-<YYYY-MM-DD>.md` capturing all
|
|
2115
2249
|
* of this run's non-blocking nits, so they get a durable, contract-native home
|
|
2116
|
-
* instead of evaporating (the block path already
|
|
2117
|
-
*
|
|
2250
|
+
* instead of evaporating (the block path already records BLOCKING findings as the
|
|
2251
|
+
* stuck reason on the item's per-item lock; the approve path dropped non-blocking ones — see
|
|
2118
2252
|
* `work/findings/review-nonblocking-findings-disposition.md`).
|
|
2119
2253
|
*
|
|
2120
2254
|
* The RUNNER writes it (the review agent stays write-free). It is a PLAIN
|
|
@@ -2322,7 +2456,7 @@ async function stagedCaptureNotes(
|
|
|
2322
2456
|
* The DURABLE `work/` status folders a slug's ledger file can resting-live in (the
|
|
2323
2457
|
* one-slug-one-folder set the invariant is asserted over). After the capstone
|
|
2324
2458
|
* cut-over (task `cutover-retire-slicing-advancing-markers-and-trim-folder-sets`,
|
|
2325
|
-
*
|
|
2459
|
+
* spec `ledger-status-per-item-lock-refs`) the ONLY `work/` moves on `main` are the
|
|
2326
2460
|
* durable resting transitions, so the source a build completes FROM is `backlog/`
|
|
2327
2461
|
* (claim no longer moves the body, task
|
|
2328
2462
|
* `cutover-claim-body-stays-and-complete-sources-from-backlog`) and the canonical
|
|
@@ -2337,7 +2471,7 @@ async function stagedCaptureNotes(
|
|
|
2337
2471
|
* The folders {@link readArbiterLedgerPlacement} scans for a slug's source on the
|
|
2338
2472
|
* arbiter: the durable `LEDGER_STATUS_FOLDERS` (`tasks-ready`/`done`/`cancelled`)
|
|
2339
2473
|
* PLUS `tasks-backlog` (staging). Staging is included ONLY for the arbiter-side
|
|
2340
|
-
* source RESOLUTION of a `--allow-backlog` done-move (
|
|
2474
|
+
* source RESOLUTION of a `--allow-backlog` done-move (spec
|
|
2341
2475
|
* `do-allow-backlog-drive-staged-tasks-without-promotion`) and the one-slug-one-
|
|
2342
2476
|
* folder guard over the malformed "same slug in `tasks/ready/` AND `tasks/backlog/`"
|
|
2343
2477
|
* state; it is DELIBERATELY NOT added to the shared `LEDGER_STATUS_FOLDERS` (which
|
|
@@ -2384,12 +2518,12 @@ interface ArbiterLedgerPlacement {
|
|
|
2384
2518
|
* destination is unambiguous), mirroring the manual `279b542` cleanup.
|
|
2385
2519
|
*
|
|
2386
2520
|
* It scans {@link ARBITER_PLACEMENT_FOLDERS} — the durable `LEDGER_STATUS_FOLDERS`
|
|
2387
|
-
* PLUS `tasks-backlog`, so a `--allow-backlog` staged drive (
|
|
2521
|
+
* PLUS `tasks-backlog`, so a `--allow-backlog` staged drive (spec
|
|
2388
2522
|
* `do-allow-backlog-drive-staged-tasks-without-promotion`) whose done-move sources
|
|
2389
2523
|
* from `tasks/backlog/` is DISCOVERED here too (the arbiter is the authority for
|
|
2390
2524
|
* the actual source folder; the local `source` is the fallback). Including staging
|
|
2391
2525
|
* also makes the one-slug-one-folder guard cover the malformed "same slug in both
|
|
2392
|
-
* `tasks/ready/` and `tasks/backlog/`" state (the
|
|
2526
|
+
* `tasks/ready/` and `tasks/backlog/`" state (the spec's decision 5): it FAILS LOUD
|
|
2393
2527
|
* rather than the resolver silently arbitrating a collision the contract forbids.
|
|
2394
2528
|
*/
|
|
2395
2529
|
function readArbiterLedgerPlacement(
|
|
@@ -2841,8 +2975,8 @@ async function runGate2Review(params: {
|
|
|
2841
2975
|
});
|
|
2842
2976
|
const message = routed.moved
|
|
2843
2977
|
? `PR/code review (Gate 2) produced an UNPARSEABLE verdict for '${slug}'; ` +
|
|
2844
|
-
'
|
|
2845
|
-
'transient-infra — re-run). NOT integrated.'
|
|
2978
|
+
'marked it stuck on its per-item lock (work branch pushed + lock ' +
|
|
2979
|
+
'surfaced; transient-infra — re-run). NOT integrated.'
|
|
2846
2980
|
: `PR/code review (Gate 2) produced an UNPARSEABLE verdict for '${slug}'; ` +
|
|
2847
2981
|
'NOT integrating.';
|
|
2848
2982
|
note(message);
|
|
@@ -2888,9 +3022,9 @@ async function runGate2Review(params: {
|
|
|
2888
3022
|
note,
|
|
2889
3023
|
});
|
|
2890
3024
|
const message = routed.moved
|
|
2891
|
-
? `PR/code review (Gate 2) blocked '${slug}';
|
|
2892
|
-
'
|
|
2893
|
-
'recorded
|
|
3025
|
+
? `PR/code review (Gate 2) blocked '${slug}'; marked it stuck on its ` +
|
|
3026
|
+
'per-item lock (surfaced by status; the blocking findings are ' +
|
|
3027
|
+
'recorded on the lock entry). NOT integrated.'
|
|
2894
3028
|
: `PR/code review (Gate 2) blocked '${slug}'; NOT integrating.`;
|
|
2895
3029
|
note(message);
|
|
2896
3030
|
return {
|