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/dist/integration-core.js
CHANGED
|
@@ -14,8 +14,8 @@ import { workBranchRef } from './slug-namespace.js';
|
|
|
14
14
|
import { isAncestor } from './gc.js';
|
|
15
15
|
/**
|
|
16
16
|
* The default LIVENESS CEILING for the merge-mode `${branch}:main` push (the
|
|
17
|
-
* durable promotions `tasks/ready → tasks/done` and, via `lifecycle`, `
|
|
18
|
-
* →
|
|
17
|
+
* durable promotions `tasks/ready → tasks/done` and, via `lifecycle`, `specs/ready
|
|
18
|
+
* → specs/tasked`). Task `c2-rebase-until-real-on-durable-main-promotions` turned
|
|
19
19
|
* the previous SMALL FIXED CAP (was 5, the `run-fleet-claim-integrate-and-sibling-
|
|
20
20
|
* rebase-concurrency-safe` Race-1 budget) into rebase-until-real-conflict: a CLEAN
|
|
21
21
|
* re-rebase no longer counts against a tiny give-up budget — only a GENUINE
|
|
@@ -151,7 +151,7 @@ export async function performIntegration(input) {
|
|
|
151
151
|
// handed (caller-agnostic); the `run`-fleet `perRepoMax === 1` downgrade lives
|
|
152
152
|
// in the `run` caller, not here.
|
|
153
153
|
const freshWorktreeGate = input.freshWorktreeGate === true;
|
|
154
|
-
// RECOVER an already-committed, already-done-moved STRANDED branch (
|
|
154
|
+
// RECOVER an already-committed, already-done-moved STRANDED branch (spec
|
|
155
155
|
// `ledger-integrity` story 6). The work + the done-move are ALREADY committed on
|
|
156
156
|
// the work branch (a terminal push failed AFTER steps 2–3); SKIP steps 0–3
|
|
157
157
|
// (prepare / gate / review / done-move / commit) and run ONLY the
|
|
@@ -171,8 +171,21 @@ export async function performIntegration(input) {
|
|
|
171
171
|
recoveryRebaseJitterMs: input.recoveryRebaseJitterMs,
|
|
172
172
|
recoveryRebaseSleep: input.recoveryRebaseSleep,
|
|
173
173
|
recoveryRebaseRandom: input.recoveryRebaseRandom,
|
|
174
|
+
// GATE-2 REVIEW on the recovery path (task
|
|
175
|
+
// `committed-recovery-always-reviews`): a stranded already-complete
|
|
176
|
+
// branch is NOT "already reviewed" — its earlier attempt's PR never
|
|
177
|
+
// merged and Gate 2 may never have run on it. So when `review` is on we
|
|
178
|
+
// MUST run Gate 2 on the rebased tip here too (the SAME reasoning that
|
|
179
|
+
// forces the re-verify: `<arbiter>/main` moved, the merged tree is new).
|
|
180
|
+
// Pass the whole `input` so the recovery tail can call `runGate2Review`
|
|
181
|
+
// with the identical gate/model/watch/round wiring the build path uses.
|
|
182
|
+
input,
|
|
183
|
+
// PR BODY on the recovery path: the recovery has NO fresh agent output
|
|
184
|
+
// (no rebuild), so carry whatever `body` the caller supplied so the PR
|
|
185
|
+
// gets a description instead of degrading to a blank `gh --fill`.
|
|
186
|
+
body: input.body,
|
|
174
187
|
// Answered-merge land (task `committed-recovery-honours-fresh-worktree-gate`,
|
|
175
|
-
//
|
|
188
|
+
// spec `land-time-reverify-and-parallel-merge-ceiling`): the apply-rung
|
|
176
189
|
// dispatches an answered `merge` through this committed-recovery tail (the
|
|
177
190
|
// branch already carries its done-move commit, so the build path's
|
|
178
191
|
// `git mv`+`add -A`+commit would raise `IntegrationNothingStaged`). UNLIKE
|
|
@@ -196,7 +209,7 @@ export async function performIntegration(input) {
|
|
|
196
209
|
});
|
|
197
210
|
}
|
|
198
211
|
// The file whose `title:` seeds the commit summary + PR title. For a TASKING
|
|
199
|
-
// transition (a non-task `lifecycle`) this is the held
|
|
212
|
+
// transition (a non-task `lifecycle`) this is the held spec it supplies; for a
|
|
200
213
|
// build it is the task in its source folder. Read BEFORE any move.
|
|
201
214
|
const lifecycle = input.lifecycle;
|
|
202
215
|
// CONTINUE-BUILD (`source: 'done'`, task
|
|
@@ -222,7 +235,7 @@ export async function performIntegration(input) {
|
|
|
222
235
|
// passes no flag, so there an untrusted-origin task RELIABLY forces propose.
|
|
223
236
|
//
|
|
224
237
|
// SCOPE: the task BUILD transition ONLY. It NEVER fires for a `lifecycle`
|
|
225
|
-
// transition (tasking / intake-emit — a
|
|
238
|
+
// transition (tasking / intake-emit — a spec/task FILE landing on main is inert;
|
|
226
239
|
// intake's OWN per-emit resolver already decided that mode), and the source file
|
|
227
240
|
// here is the task being built. A `trusted`/unset task ⇒ untouched (zero
|
|
228
241
|
// behaviour change for the normal human path).
|
|
@@ -270,10 +283,11 @@ export async function performIntegration(input) {
|
|
|
270
283
|
}
|
|
271
284
|
if (!prep.passed) {
|
|
272
285
|
const reason = `prepare (env-prep) failed (exit ${prep.exitCode})`;
|
|
273
|
-
//
|
|
274
|
-
//
|
|
275
|
-
//
|
|
276
|
-
//
|
|
286
|
+
// Mark the item stuck on its per-item lock (the SAME seam a red gate uses)
|
|
287
|
+
// — recording the prepare-failed reason on the lock entry + saving the
|
|
288
|
+
// agent's uncommitted work as a wip commit (post lock-cutover: a lock amend,
|
|
289
|
+
// no `in-progress/ → needs-attention/` folder move). We NEVER run `verify`
|
|
290
|
+
// on an env that could not be made ready.
|
|
277
291
|
const routed = await ledgerWrite.applyNeedsAttentionTransition({
|
|
278
292
|
cwd,
|
|
279
293
|
slug,
|
|
@@ -287,10 +301,10 @@ export async function performIntegration(input) {
|
|
|
287
301
|
routedToNeedsAttention: routed.moved,
|
|
288
302
|
branch,
|
|
289
303
|
reason: routed.moved
|
|
290
|
-
? `Env-prep (prepare) failed (exit ${prep.exitCode});
|
|
291
|
-
'
|
|
304
|
+
? `Env-prep (prepare) failed (exit ${prep.exitCode}); marked '${slug}' ` +
|
|
305
|
+
'stuck on its per-item lock (the environment could not be made ready, ' +
|
|
292
306
|
'so the acceptance gate was NOT run). Fix the prepare command, then ' +
|
|
293
|
-
'
|
|
307
|
+
'`requeue` to release the stuck lock.'
|
|
294
308
|
: `Env-prep (prepare) failed (exit ${prep.exitCode}); not completing ` +
|
|
295
309
|
`'${slug}' (the environment could not be made ready, so the ` +
|
|
296
310
|
'acceptance gate was NOT run). Fix the prepare command, then retry.',
|
|
@@ -309,12 +323,12 @@ export async function performIntegration(input) {
|
|
|
309
323
|
note('Running the acceptance gate (verify)…');
|
|
310
324
|
const gate = await runVerify({ cwd, verify: input.verify, env });
|
|
311
325
|
if (!gate.passed) {
|
|
312
|
-
// Don't leave the item dangling
|
|
313
|
-
//
|
|
314
|
-
//
|
|
315
|
-
//
|
|
316
|
-
//
|
|
317
|
-
//
|
|
326
|
+
// Don't leave the item dangling: mark it stuck on its per-item lock with
|
|
327
|
+
// the reason (ADR §12) THROUGH the ledger write seam's needs-attention
|
|
328
|
+
// transition. Post lock-cutover this is a lock amend (`state: stuck` + the
|
|
329
|
+
// reason on the lock entry, no `in-progress/ → needs-attention/` folder
|
|
330
|
+
// move) plus saving the agent's uncommitted work as a wip commit. No
|
|
331
|
+
// partial state.
|
|
318
332
|
const reason = `acceptance gate failed (exit ${gate.exitCode})`;
|
|
319
333
|
const routed = await ledgerWrite.applyNeedsAttentionTransition({
|
|
320
334
|
cwd,
|
|
@@ -337,15 +351,15 @@ export async function performIntegration(input) {
|
|
|
337
351
|
routedToNeedsAttention: routed.moved,
|
|
338
352
|
branch,
|
|
339
353
|
reason: routed.moved
|
|
340
|
-
? `Acceptance gate failed (exit ${gate.exitCode});
|
|
341
|
-
'
|
|
342
|
-
'
|
|
354
|
+
? `Acceptance gate failed (exit ${gate.exitCode}); marked '${slug}' ` +
|
|
355
|
+
'stuck on its per-item lock (surfaced by status; `requeue` once ' +
|
|
356
|
+
'resolved). Fix the work, or use --skip-verify to override.'
|
|
343
357
|
: `Acceptance gate failed (exit ${gate.exitCode}); not completing ` +
|
|
344
358
|
`'${slug}'. Fix the work, or use --skip-verify to override.`,
|
|
345
359
|
};
|
|
346
360
|
}
|
|
347
361
|
}
|
|
348
|
-
// 1b. Gate 2 — the PR/code REVIEW gate (GATES
|
|
362
|
+
// 1b. Gate 2 — the PR/code REVIEW gate (GATES spec `work/specs/tasked/review.md`). It is a
|
|
349
363
|
// JUDGEMENT gate layered ON TOP of the deterministic `verify` floor (ADR §8)
|
|
350
364
|
// — NEVER a replacement, and ALWAYS verify-THEN-review on the SAME tree.
|
|
351
365
|
//
|
|
@@ -399,10 +413,10 @@ export async function performIntegration(input) {
|
|
|
399
413
|
// never be the multi-line commit-subject run-on `--fill` would derive.
|
|
400
414
|
//
|
|
401
415
|
// When the lifecycle supplies an EXPLICIT `title`, use it DIRECTLY (no file read):
|
|
402
|
-
// the intake lone-task /
|
|
416
|
+
// the intake lone-task / spec path writes its output file in `stage()`, which runs
|
|
403
417
|
// AFTER this point, so a `titlePath` read would race the write and degrade the
|
|
404
|
-
// subject/PR title to the generic fallback. The `do
|
|
405
|
-
// `title` unset and keeps reading its already-existing held
|
|
418
|
+
// subject/PR title to the generic fallback. The `do spec:` tasking path leaves
|
|
419
|
+
// `title` unset and keeps reading its already-existing held spec (unchanged).
|
|
406
420
|
const explicitTitle = lifecycle?.title;
|
|
407
421
|
const taskTitle = explicitTitle !== undefined ? explicitTitle : readTaskTitle(sourcePath);
|
|
408
422
|
const defaultMessage = explicitTitle !== undefined
|
|
@@ -415,7 +429,7 @@ export async function performIntegration(input) {
|
|
|
415
429
|
});
|
|
416
430
|
// 2. STAGE the item move into the index. For a build that is the task done-move
|
|
417
431
|
// (`work/<source>/<slug>.md → work/done/<slug>.md`); for a TASKING
|
|
418
|
-
// transition (a non-task `lifecycle`) it is the caller-supplied
|
|
432
|
+
// transition (a non-task `lifecycle`) it is the caller-supplied spec
|
|
419
433
|
// lifecycle move + emitted backlog files (the runner stages them, the agent
|
|
420
434
|
// never does git). Either way the subsequent `git add -A` folds the agent's
|
|
421
435
|
// uncommitted work + this staging into ONE atomic commit.
|
|
@@ -467,7 +481,7 @@ export async function performIntegration(input) {
|
|
|
467
481
|
// they are TRACKED, not dropped/untracked. Rule B is extended HERE: the runner REPORTS
|
|
468
482
|
// exactly which note files landed (honest reporting — what actually reached the commit,
|
|
469
483
|
// read from the staged set, not assumed). This is the ONE shared place — BOTH the build
|
|
470
|
-
// path (`do <task>`/`run`/`complete`) and the tasking path (`do
|
|
484
|
+
// path (`do <task>`/`run`/`complete`) and the tasking path (`do spec:`, via the
|
|
471
485
|
// `lifecycle` seam) route through it, so the channel is NOT forked. Zero notes ⇒ no
|
|
472
486
|
// report (the no-note case is byte-for-byte unchanged).
|
|
473
487
|
await reportScoopedNotes(cwd, env, note);
|
|
@@ -501,16 +515,14 @@ export async function performIntegration(input) {
|
|
|
501
515
|
// 4. Rebase-before-integrate (ADR §10): rebase the work branch onto the
|
|
502
516
|
// latest <arbiter>/main. Clean → continue. Conflict → abort + stop.
|
|
503
517
|
//
|
|
504
|
-
// RECOVERY reconciliation:
|
|
505
|
-
//
|
|
506
|
-
//
|
|
507
|
-
//
|
|
508
|
-
//
|
|
509
|
-
//
|
|
510
|
-
//
|
|
511
|
-
//
|
|
512
|
-
// needs-attention/). The done-move thus SUPERSEDES the surfaced state — no
|
|
513
|
-
// leftover/conflicting on-`main` surface for the human to resolve.
|
|
518
|
+
// RECOVERY reconciliation: post the per-item-lock cut-over, a stuck item's
|
|
519
|
+
// body never moved into a `needs-attention/` folder (stuck is the lock
|
|
520
|
+
// `state: stuck`; the body rests in `backlog/`), so a recovery `complete`'s
|
|
521
|
+
// kept branch carries NO historical `in-progress → needs-attention`
|
|
522
|
+
// move-only commit to drop and `<arbiter>/main` holds no surface move to
|
|
523
|
+
// conflict with. The old recovery drop (`rebaseDroppingNeedsAttentionSurface`,
|
|
524
|
+
// drop-bookkeeping-rebase) is deleted; recovery is now the SAME plain replay
|
|
525
|
+
// onto `<arbiter>/main` as any other build (see the plain-rebase note below).
|
|
514
526
|
// Fetch the arbiter's `main` into the `<arbiter>/main` remote-tracking ref
|
|
515
527
|
// EXPLICITLY. A `run` JOB WORKTREE is cut from a bare hub mirror whose remote
|
|
516
528
|
// has no fetch refspec (so `<arbiter>/main` would not otherwise resolve / would
|
|
@@ -553,7 +565,7 @@ export async function performIntegration(input) {
|
|
|
553
565
|
};
|
|
554
566
|
}
|
|
555
567
|
}
|
|
556
|
-
// PLAIN rebase. After the per-item-lock cut-over (
|
|
568
|
+
// PLAIN rebase. After the per-item-lock cut-over (spec
|
|
557
569
|
// `ledger-status-per-item-lock-refs`, tasks 9a–9d) no transient status
|
|
558
570
|
// lands on a work branch: needs-attention is the lock `state: stuck` (not a
|
|
559
571
|
// `git mv` to `needs-attention/`), the body rests in `backlog/` while
|
|
@@ -656,12 +668,12 @@ export async function performIntegration(input) {
|
|
|
656
668
|
// recovery above can fall through to integrate while a genuine code conflict
|
|
657
669
|
// still routes here.
|
|
658
670
|
async function rebaseConflictRoute() {
|
|
659
|
-
// Then
|
|
660
|
-
// §12) THROUGH the ledger write seam's needs-attention transition,
|
|
661
|
-
// than leaving it dangling
|
|
662
|
-
//
|
|
663
|
-
//
|
|
664
|
-
//
|
|
671
|
+
// Then mark the item stuck on its per-item lock with the conflict reason
|
|
672
|
+
// (ADR §12) THROUGH the ledger write seam's needs-attention transition,
|
|
673
|
+
// rather than leaving it dangling. Post lock-cutover this is a lock amend
|
|
674
|
+
// (`state: stuck` + the reason on the lock entry, no `done/ →
|
|
675
|
+
// needs-attention/` folder move); the done-move already committed above
|
|
676
|
+
// stands. No partial state.
|
|
665
677
|
const reason = `rebase onto ${arbiter}/main conflicted (aborted, never auto-resolved)`;
|
|
666
678
|
const routed = await ledgerWrite.applyNeedsAttentionTransition({
|
|
667
679
|
cwd,
|
|
@@ -683,9 +695,9 @@ export async function performIntegration(input) {
|
|
|
683
695
|
commitMessage,
|
|
684
696
|
reason: routed.moved
|
|
685
697
|
? `Rebasing ${branch} onto ${arbiter}/main conflicted; the rebase was ` +
|
|
686
|
-
`aborted (never auto-resolved) and '${slug}' was
|
|
687
|
-
'
|
|
688
|
-
'
|
|
698
|
+
`aborted (never auto-resolved) and '${slug}' was marked stuck on ` +
|
|
699
|
+
'its per-item lock (surfaced by status). Resolve against the latest ' +
|
|
700
|
+
'main, then `requeue` to release the stuck lock and re-run.'
|
|
689
701
|
: `Rebasing ${branch} onto ${arbiter}/main conflicted; the rebase was ` +
|
|
690
702
|
'aborted (never auto-resolved). Resolve against the latest main, ' +
|
|
691
703
|
'then re-run complete.',
|
|
@@ -758,9 +770,9 @@ export async function performIntegration(input) {
|
|
|
758
770
|
branch,
|
|
759
771
|
commitMessage,
|
|
760
772
|
reason: routed.moved
|
|
761
|
-
? `${what} on the rebased tip;
|
|
762
|
-
'
|
|
763
|
-
'
|
|
773
|
+
? `${what} on the rebased tip; marked '${slug}' stuck on its ` +
|
|
774
|
+
'per-item lock (surfaced by status; `requeue` once resolved). ' +
|
|
775
|
+
'Fix the work, or use --skip-verify to override.'
|
|
764
776
|
: `${what} on the rebased tip; not completing '${slug}'. Fix the ` +
|
|
765
777
|
'work, or use --skip-verify to override.',
|
|
766
778
|
};
|
|
@@ -775,7 +787,8 @@ export async function performIntegration(input) {
|
|
|
775
787
|
if (gated.review) {
|
|
776
788
|
if (gated.review.kind === 'blocked') {
|
|
777
789
|
// The done-move was already committed (steps 2–3), so the slug sits in
|
|
778
|
-
// work/done/; the routing
|
|
790
|
+
// work/done/; the routing marked it stuck on its per-item lock (post
|
|
791
|
+
// lock-cutover — a lock amend, no folder move).
|
|
779
792
|
return gated.review.result;
|
|
780
793
|
}
|
|
781
794
|
approvedVerdict = gated.review.verdict;
|
|
@@ -936,9 +949,10 @@ export async function performIntegration(input) {
|
|
|
936
949
|
commitMessage,
|
|
937
950
|
reason: routed.moved
|
|
938
951
|
? `Integrating ${branch} onto ${arbiter}/main kept hitting a ` +
|
|
939
|
-
`non-fast-forward push (a sibling advanced main); '${slug}' was
|
|
940
|
-
`
|
|
941
|
-
`latest main, then
|
|
952
|
+
`non-fast-forward push (a sibling advanced main); '${slug}' was ` +
|
|
953
|
+
`marked stuck on its per-item lock (surfaced by status). Resolve ` +
|
|
954
|
+
`against the latest main, then \`requeue\` to release the stuck ` +
|
|
955
|
+
`lock and re-run.`
|
|
942
956
|
: `Integrating ${branch} onto ${arbiter}/main kept hitting a ` +
|
|
943
957
|
`non-fast-forward push (a sibling advanced main). Resolve against the ` +
|
|
944
958
|
`latest main, then re-run complete.`,
|
|
@@ -1007,7 +1021,7 @@ export async function performIntegration(input) {
|
|
|
1007
1021
|
: await runRebaseToIntegrateTail();
|
|
1008
1022
|
}
|
|
1009
1023
|
/**
|
|
1010
|
-
* RECOVER an already-committed, already-done-moved STRANDED branch (
|
|
1024
|
+
* RECOVER an already-committed, already-done-moved STRANDED branch (spec
|
|
1011
1025
|
* `ledger-integrity` story 6, the `finish-already-committed-branch` task). The
|
|
1012
1026
|
* green work AND the `git mv → work/done/` are ALREADY committed on the work
|
|
1013
1027
|
* branch (a terminal push failed AFTER `performIntegration`'s steps 2–3), and the
|
|
@@ -1017,7 +1031,7 @@ export async function performIntegration(input) {
|
|
|
1017
1031
|
* primitive the build path uses.
|
|
1018
1032
|
*
|
|
1019
1033
|
* RE-GATE on the REBASED TIP (task `committed-recovery-honours-fresh-worktree-
|
|
1020
|
-
* gate`,
|
|
1034
|
+
* gate`, spec `land-time-reverify-and-parallel-merge-ceiling`): when the caller
|
|
1021
1035
|
* sets `freshWorktreeGate` (and not `skipVerify`), the EXISTING
|
|
1022
1036
|
* `runFreshWorktreeGate` runs on the rebased tip AFTER the rebase loop and
|
|
1023
1037
|
* BEFORE `applyCompleteTransition`, mirroring the build path's
|
|
@@ -1071,6 +1085,14 @@ async function recoverAlreadyCommitted(params) {
|
|
|
1071
1085
|
// (`isAncestor` is the SAME reachability predicate `gc.ts` uses; do not fork it.)
|
|
1072
1086
|
// KEPT before the retry loop: a no-op MUST short-circuit before we burn any
|
|
1073
1087
|
// re-fetch/re-rebase budget.
|
|
1088
|
+
//
|
|
1089
|
+
// DELIBERATELY the RAW ancestry predicate, NOT `isProvablyMergedForReap`
|
|
1090
|
+
// (task `reap-squash-merged-remote-work-branches`, ratified): this is an
|
|
1091
|
+
// integration-IDEMPOTENCY check, not reap-safety. A squash-landed LOOKALIKE
|
|
1092
|
+
// whose tip is NOT genuinely reachable would falsely read "already
|
|
1093
|
+
// integrated" here and skip a needed rebase/re-push. The squash-aware helper
|
|
1094
|
+
// is scoped to reap-safety ONLY; see gc.ts `isProvablyMergedForReap` and
|
|
1095
|
+
// work/notes/observations/reap-squash-helper-scope-2026-07-10.md.
|
|
1074
1096
|
if (isAncestor(cwd, tip, `refs/remotes/${arbiter}/main`, env)) {
|
|
1075
1097
|
const message = `Nothing to recover for '${slug}': its work branch tip is already on ` +
|
|
1076
1098
|
`${arbiter}/main (already integrated). No re-push, no double-integrate.`;
|
|
@@ -1162,7 +1184,7 @@ async function recoverAlreadyCommitted(params) {
|
|
|
1162
1184
|
attempt++;
|
|
1163
1185
|
}
|
|
1164
1186
|
// FRESH-WORKTREE GATE on the REBASED TIP (task `committed-recovery-honours-
|
|
1165
|
-
// fresh-worktree-gate`,
|
|
1187
|
+
// fresh-worktree-gate`, spec `land-time-reverify-and-parallel-merge-ceiling`):
|
|
1166
1188
|
// when `freshWorktreeGate` is set (the answered-merge land caller) and not
|
|
1167
1189
|
// `--skip-verify`, re-run the acceptance gate on the rebased tip BEFORE we
|
|
1168
1190
|
// integrate, mirroring the build path's `freshWorktreeGate && !skipVerify &&
|
|
@@ -1173,11 +1195,21 @@ async function recoverAlreadyCommitted(params) {
|
|
|
1173
1195
|
// clean-rebase-but-broken merge. With `freshWorktreeGate` UNSET (the original
|
|
1174
1196
|
// stranded-recovery caller, whose pre-strand build already gated) this whole
|
|
1175
1197
|
// block is skipped and behaviour is byte-identical to before.
|
|
1198
|
+
// Carry an approved Gate-2 verdict (when review ran) so its authored `review`
|
|
1199
|
+
// prose is posted as a PR comment AFTER the integrate below — the SAME audit
|
|
1200
|
+
// trail the build path keeps (task `committed-recovery-always-reviews`).
|
|
1201
|
+
let approvedVerdict;
|
|
1176
1202
|
if (params.freshWorktreeGate && !params.skipVerify) {
|
|
1177
1203
|
const tip = (await gitSoft(['rev-parse', '--verify', '--quiet', 'HEAD'], cwd, env)).stdout.trim();
|
|
1178
|
-
//
|
|
1179
|
-
//
|
|
1180
|
-
//
|
|
1204
|
+
// GATE-2 REVIEW callback (task `committed-recovery-always-reviews`): when
|
|
1205
|
+
// `input.review` is on, run Gate 2 on the rebased tip AFTER the green verify
|
|
1206
|
+
// — EXACTLY the build path's fresh-gate `review:` callback. A stranded
|
|
1207
|
+
// already-complete branch is NOT trusted as already-reviewed (its earlier
|
|
1208
|
+
// attempt's PR never merged, and Gate 2 may never have run on it); the same
|
|
1209
|
+
// reasoning that forces the re-verify here (`<arbiter>/main` moved, so the
|
|
1210
|
+
// merged tree is new) forces the re-review. The needs-attention ROUTING
|
|
1211
|
+
// targets `cwd` (the work branch + ledger), identical to the build path.
|
|
1212
|
+
const reviewInput = params.input;
|
|
1181
1213
|
const gated = await runFreshWorktreeGate({
|
|
1182
1214
|
cwd,
|
|
1183
1215
|
commit: tip,
|
|
@@ -1185,6 +1217,17 @@ async function recoverAlreadyCommitted(params) {
|
|
|
1185
1217
|
verify: params.verify,
|
|
1186
1218
|
env,
|
|
1187
1219
|
note,
|
|
1220
|
+
review: reviewInput?.review === true
|
|
1221
|
+
? (reviewCwd) => runGate2Review({
|
|
1222
|
+
reviewCwd,
|
|
1223
|
+
input: reviewInput,
|
|
1224
|
+
slug,
|
|
1225
|
+
branch,
|
|
1226
|
+
cwd,
|
|
1227
|
+
env,
|
|
1228
|
+
note,
|
|
1229
|
+
})
|
|
1230
|
+
: undefined,
|
|
1188
1231
|
});
|
|
1189
1232
|
if (!gated.passed) {
|
|
1190
1233
|
const outcome = gated.kind === 'prepare' ? 'prepare-failed' : 'gate-failed';
|
|
@@ -1207,15 +1250,43 @@ async function recoverAlreadyCommitted(params) {
|
|
|
1207
1250
|
routedToNeedsAttention: routed.moved,
|
|
1208
1251
|
branch,
|
|
1209
1252
|
reason: routed.moved
|
|
1210
|
-
? `${what} on the rebased tip during committed-recovery;
|
|
1211
|
-
`'${slug}'
|
|
1212
|
-
'
|
|
1253
|
+
? `${what} on the rebased tip during committed-recovery; marked ` +
|
|
1254
|
+
`'${slug}' stuck on its per-item lock (surfaced by status; ` +
|
|
1255
|
+
'`requeue` once resolved). Fix the work, or use --skip-verify ' +
|
|
1213
1256
|
'to override.'
|
|
1214
1257
|
: `${what} on the rebased tip during committed-recovery; not ` +
|
|
1215
1258
|
`completing '${slug}'. Fix the work, or use --skip-verify to ` +
|
|
1216
1259
|
'override.',
|
|
1217
1260
|
};
|
|
1218
1261
|
}
|
|
1262
|
+
// GATE-2 REVIEW outcome on the rebased tip: a BLOCK routes to needs-attention
|
|
1263
|
+
// exactly as the build path (only the reviewed tree moved, not the routing).
|
|
1264
|
+
// On APPROVE: carry the verdict for the post-integrate PR comment and write
|
|
1265
|
+
// the per-run non-blocking-nits observation. UNLIKE the build path this branch
|
|
1266
|
+
// integrates the ALREADY-committed kept tip (no upcoming done-move/commit to
|
|
1267
|
+
// sweep the nits file into), so we FOLD the observation into the kept commit
|
|
1268
|
+
// via `commit --amend` — mirroring the build path's fresh-gate amend so the
|
|
1269
|
+
// nits still land in the SAME commit that integrates (no separate commit).
|
|
1270
|
+
if (gated.review) {
|
|
1271
|
+
if (gated.review.kind === 'blocked') {
|
|
1272
|
+
return gated.review.result;
|
|
1273
|
+
}
|
|
1274
|
+
approvedVerdict = gated.review.verdict;
|
|
1275
|
+
const nitsBefore = await stagedCaptureNotes(cwd, env);
|
|
1276
|
+
writeReviewNitsObservation({
|
|
1277
|
+
cwd,
|
|
1278
|
+
slug,
|
|
1279
|
+
findings: gated.review.verdict?.findings ?? [],
|
|
1280
|
+
note,
|
|
1281
|
+
});
|
|
1282
|
+
await gitHard(['add', '-A'], cwd, env);
|
|
1283
|
+
if (!(await nothingStaged(cwd, env))) {
|
|
1284
|
+
const nitsAfter = await stagedCaptureNotes(cwd, env);
|
|
1285
|
+
if (nitsAfter.length > nitsBefore.length) {
|
|
1286
|
+
await gitHard(['commit', '-q', '--amend', '--no-edit'], cwd, env);
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1219
1290
|
}
|
|
1220
1291
|
// Integrate the rebased kept commit through the SAME complete-transition
|
|
1221
1292
|
// primitive the build path uses (no duplication of the integrate mechanism; the
|
|
@@ -1226,12 +1297,27 @@ async function recoverAlreadyCommitted(params) {
|
|
|
1226
1297
|
(params.openPr
|
|
1227
1298
|
? bridgeProvider(params.openPr)
|
|
1228
1299
|
: selectProvider({ arbiterUrl: await arbiterUrl(cwd, arbiter, env) }));
|
|
1300
|
+
// PR TITLE + BODY on the recovery path (task `committed-recovery-always-
|
|
1301
|
+
// reviews`): the stranded branch already holds the task in `work/done/`, so
|
|
1302
|
+
// synthesise the SAME single-line `<type>(<slug>): <title>` PR title the build
|
|
1303
|
+
// path does (from the done-resident task file, never agent text) and scaffold
|
|
1304
|
+
// the task-pointer body around the caller-supplied advisory `body`. Undefined
|
|
1305
|
+
// body ⇒ `composeProposeBody` returns undefined ⇒ the provider degrades to
|
|
1306
|
+
// `gh --fill` (no regression); a supplied body gives the PR a real description
|
|
1307
|
+
// instead of the blank one the recovery path used to open.
|
|
1308
|
+
const prTitle = synthesiseProposeTitle({
|
|
1309
|
+
type: (params.input?.type ?? DEFAULT_TYPE).trim() || DEFAULT_TYPE,
|
|
1310
|
+
slug,
|
|
1311
|
+
title: readTaskTitle(workItemPath(cwd, 'done', slug)),
|
|
1312
|
+
});
|
|
1229
1313
|
const integration = await ledgerWrite.applyCompleteTransition({
|
|
1230
1314
|
arbiter,
|
|
1231
1315
|
branch,
|
|
1232
1316
|
mode,
|
|
1233
1317
|
provider,
|
|
1234
1318
|
noPR: params.noPR,
|
|
1319
|
+
title: prTitle,
|
|
1320
|
+
body: composeProposeBody({ slug, body: params.body }),
|
|
1235
1321
|
deleteMergedHead: true,
|
|
1236
1322
|
cwd,
|
|
1237
1323
|
env,
|
|
@@ -1241,6 +1327,33 @@ async function recoverAlreadyCommitted(params) {
|
|
|
1241
1327
|
: `Recovered '${slug}': integrated the kept commit from ${branch} ` +
|
|
1242
1328
|
`(absorbed a moving ${arbiter}/main across ${attempt} re-fetch+re-` +
|
|
1243
1329
|
`rebase attempt${attempt === 1 ? '' : 's'}).`);
|
|
1330
|
+
// Post the Gate-2 review as a PR comment (task `committed-recovery-always-
|
|
1331
|
+
// reviews`): the SAME post-integrate audit trail the build path keeps — the
|
|
1332
|
+
// approved verdict's authored `review` prose, on the opened PR. Advisory only
|
|
1333
|
+
// (a block never reaches here — it returned above); the same URL/branch
|
|
1334
|
+
// precedence the build path uses (parsed url wins; else a branch-resolved
|
|
1335
|
+
// fallback when a PR opened but its url was unparseable). `postPRComment*`
|
|
1336
|
+
// never throws. A clean no-op in merge mode / push-only propose (no PR).
|
|
1337
|
+
if (approvedVerdict?.review !== undefined) {
|
|
1338
|
+
if (integration.url !== undefined) {
|
|
1339
|
+
const posted = provider.postPRComment({
|
|
1340
|
+
cwd,
|
|
1341
|
+
url: integration.url,
|
|
1342
|
+
body: approvedVerdict.review,
|
|
1343
|
+
env,
|
|
1344
|
+
});
|
|
1345
|
+
note(posted.instruction);
|
|
1346
|
+
}
|
|
1347
|
+
else if (integration.requestOpened) {
|
|
1348
|
+
const posted = provider.postPRCommentOnBranch({
|
|
1349
|
+
cwd,
|
|
1350
|
+
branch,
|
|
1351
|
+
body: approvedVerdict.review,
|
|
1352
|
+
env,
|
|
1353
|
+
});
|
|
1354
|
+
note(posted.instruction);
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1244
1357
|
return {
|
|
1245
1358
|
outcome: 'completed',
|
|
1246
1359
|
routedToNeedsAttention: false,
|
|
@@ -1278,8 +1391,9 @@ function resolveWorkBranch(cwd, slug, env) {
|
|
|
1278
1391
|
*
|
|
1279
1392
|
* Carries the {@link slug} so the autonomous-strand surface in `complete.ts`
|
|
1280
1393
|
* (which catches this error in `performComplete`'s outer try/catch, OUTSIDE the
|
|
1281
|
-
* `runComplete` slug scope) can
|
|
1282
|
-
*
|
|
1394
|
+
* `runComplete` slug scope) can mark the item stuck on its per-item lock (post
|
|
1395
|
+
* lock-cutover — the tree-less lock amend, no `in-progress/ → needs-attention/`
|
|
1396
|
+
* folder move) without re-deriving the slug from the error message.
|
|
1283
1397
|
*/
|
|
1284
1398
|
export class IntegrationNothingStaged extends Error {
|
|
1285
1399
|
slug;
|
|
@@ -1432,8 +1546,8 @@ export function composeProposeBody(input) {
|
|
|
1432
1546
|
* On a review APPROVE that carries ≥1 NON-BLOCKING finding, write ONE per-run
|
|
1433
1547
|
* observation `work/notes/observations/review-nits-<slug>-<YYYY-MM-DD>.md` capturing all
|
|
1434
1548
|
* of this run's non-blocking nits, so they get a durable, contract-native home
|
|
1435
|
-
* instead of evaporating (the block path already
|
|
1436
|
-
*
|
|
1549
|
+
* instead of evaporating (the block path already records BLOCKING findings as the
|
|
1550
|
+
* stuck reason on the item's per-item lock; the approve path dropped non-blocking ones — see
|
|
1437
1551
|
* `work/findings/review-nonblocking-findings-disposition.md`).
|
|
1438
1552
|
*
|
|
1439
1553
|
* The RUNNER writes it (the review agent stays write-free). It is a PLAIN
|
|
@@ -1605,7 +1719,7 @@ async function stagedCaptureNotes(cwd, env) {
|
|
|
1605
1719
|
* The DURABLE `work/` status folders a slug's ledger file can resting-live in (the
|
|
1606
1720
|
* one-slug-one-folder set the invariant is asserted over). After the capstone
|
|
1607
1721
|
* cut-over (task `cutover-retire-slicing-advancing-markers-and-trim-folder-sets`,
|
|
1608
|
-
*
|
|
1722
|
+
* spec `ledger-status-per-item-lock-refs`) the ONLY `work/` moves on `main` are the
|
|
1609
1723
|
* durable resting transitions, so the source a build completes FROM is `backlog/`
|
|
1610
1724
|
* (claim no longer moves the body, task
|
|
1611
1725
|
* `cutover-claim-body-stays-and-complete-sources-from-backlog`) and the canonical
|
|
@@ -1620,7 +1734,7 @@ async function stagedCaptureNotes(cwd, env) {
|
|
|
1620
1734
|
* The folders {@link readArbiterLedgerPlacement} scans for a slug's source on the
|
|
1621
1735
|
* arbiter: the durable `LEDGER_STATUS_FOLDERS` (`tasks-ready`/`done`/`cancelled`)
|
|
1622
1736
|
* PLUS `tasks-backlog` (staging). Staging is included ONLY for the arbiter-side
|
|
1623
|
-
* source RESOLUTION of a `--allow-backlog` done-move (
|
|
1737
|
+
* source RESOLUTION of a `--allow-backlog` done-move (spec
|
|
1624
1738
|
* `do-allow-backlog-drive-staged-tasks-without-promotion`) and the one-slug-one-
|
|
1625
1739
|
* folder guard over the malformed "same slug in `tasks/ready/` AND `tasks/backlog/`"
|
|
1626
1740
|
* state; it is DELIBERATELY NOT added to the shared `LEDGER_STATUS_FOLDERS` (which
|
|
@@ -1646,12 +1760,12 @@ const ARBITER_PLACEMENT_FOLDERS = [
|
|
|
1646
1760
|
* destination is unambiguous), mirroring the manual `279b542` cleanup.
|
|
1647
1761
|
*
|
|
1648
1762
|
* It scans {@link ARBITER_PLACEMENT_FOLDERS} — the durable `LEDGER_STATUS_FOLDERS`
|
|
1649
|
-
* PLUS `tasks-backlog`, so a `--allow-backlog` staged drive (
|
|
1763
|
+
* PLUS `tasks-backlog`, so a `--allow-backlog` staged drive (spec
|
|
1650
1764
|
* `do-allow-backlog-drive-staged-tasks-without-promotion`) whose done-move sources
|
|
1651
1765
|
* from `tasks/backlog/` is DISCOVERED here too (the arbiter is the authority for
|
|
1652
1766
|
* the actual source folder; the local `source` is the fallback). Including staging
|
|
1653
1767
|
* also makes the one-slug-one-folder guard cover the malformed "same slug in both
|
|
1654
|
-
* `tasks/ready/` and `tasks/backlog/`" state (the
|
|
1768
|
+
* `tasks/ready/` and `tasks/backlog/`" state (the spec's decision 5): it FAILS LOUD
|
|
1655
1769
|
* rather than the resolver silently arbitrating a collision the contract forbids.
|
|
1656
1770
|
*/
|
|
1657
1771
|
function readArbiterLedgerPlacement(cwd, arbiter, slug, env) {
|
|
@@ -2018,8 +2132,8 @@ async function runGate2Review(params) {
|
|
|
2018
2132
|
});
|
|
2019
2133
|
const message = routed.moved
|
|
2020
2134
|
? `PR/code review (Gate 2) produced an UNPARSEABLE verdict for '${slug}'; ` +
|
|
2021
|
-
'
|
|
2022
|
-
'transient-infra — re-run). NOT integrated.'
|
|
2135
|
+
'marked it stuck on its per-item lock (work branch pushed + lock ' +
|
|
2136
|
+
'surfaced; transient-infra — re-run). NOT integrated.'
|
|
2023
2137
|
: `PR/code review (Gate 2) produced an UNPARSEABLE verdict for '${slug}'; ` +
|
|
2024
2138
|
'NOT integrating.';
|
|
2025
2139
|
note(message);
|
|
@@ -2064,9 +2178,9 @@ async function runGate2Review(params) {
|
|
|
2064
2178
|
note,
|
|
2065
2179
|
});
|
|
2066
2180
|
const message = routed.moved
|
|
2067
|
-
? `PR/code review (Gate 2) blocked '${slug}';
|
|
2068
|
-
'
|
|
2069
|
-
'recorded
|
|
2181
|
+
? `PR/code review (Gate 2) blocked '${slug}'; marked it stuck on its ` +
|
|
2182
|
+
'per-item lock (surfaced by status; the blocking findings are ' +
|
|
2183
|
+
'recorded on the lock entry). NOT integrated.'
|
|
2070
2184
|
: `PR/code review (Gate 2) blocked '${slug}'; NOT integrating.`;
|
|
2071
2185
|
note(message);
|
|
2072
2186
|
return {
|