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/repo-config.ts
CHANGED
|
@@ -2,6 +2,7 @@ import {readFileSync, existsSync} from 'node:fs';
|
|
|
2
2
|
import {join} from 'node:path';
|
|
3
3
|
import {
|
|
4
4
|
mergeConfig,
|
|
5
|
+
validateDeadlineConfig,
|
|
5
6
|
warnDeprecatedConfigKeys,
|
|
6
7
|
type Config,
|
|
7
8
|
type PartialConfig,
|
|
@@ -61,23 +62,23 @@ export const REPO_CONFIG_FILENAME = brand.repoConfigFilename;
|
|
|
61
62
|
*/
|
|
62
63
|
export const REPO_ALLOWED_KEYS = [
|
|
63
64
|
'integration',
|
|
64
|
-
// `taskingIntegration` (the per-TRANSITION override for the
|
|
65
|
+
// `taskingIntegration` (the per-TRANSITION override for the spec→tasks TASKING
|
|
65
66
|
// transition ONLY) is a genuine repo property exactly like `integration`: whether
|
|
66
|
-
// THIS repo tasks a
|
|
67
|
+
// THIS repo tasks a spec straight onto `main` (task FILES land, no PR) while it
|
|
67
68
|
// still BUILDS each task as a reviewable PR is agreed by all collaborators +
|
|
68
69
|
// travels with the repo. Resolved per-repo through the SAME chain as
|
|
69
70
|
// `integration`, then falls back to `integration` when unset. DISTINCT from
|
|
70
|
-
// intake's per-EMITTED-TYPE `{task,
|
|
71
|
+
// intake's per-EMITTED-TYPE `{task, spec}` resolver (front door, author-trust):
|
|
71
72
|
// this is a per-lifecycle-transition knob, inside the boundary, config-resolved.
|
|
72
73
|
'taskingIntegration',
|
|
73
|
-
// `tasksLandIn` (the per-repo TASK-PLACEMENT default — staging vs pool,
|
|
74
|
+
// `tasksLandIn` (the per-repo TASK-PLACEMENT default — staging vs pool, spec
|
|
74
75
|
// `staging-pool-position-gate-and-trust-model` US #5) is a genuine repo property
|
|
75
76
|
// exactly like `taskingIntegration`/`integration`: whether THIS repo's tasker
|
|
76
|
-
// output lands STAGED (`
|
|
77
|
+
// output lands STAGED (`tasks/backlog/`, review-without-PR human-promote path) or
|
|
77
78
|
// straight in the agent-eligible POOL (`ready/`, trusted fast-path) is agreed
|
|
78
79
|
// by all collaborators + travels with the repo. Resolved per-repo through the
|
|
79
80
|
// SAME chain as `taskingIntegration` (flag > env > per-repo > global > built-in
|
|
80
|
-
// `
|
|
81
|
+
// `backlog`). DISTINCT from intake's per-emitted-type stamps (front door):
|
|
81
82
|
// this is a per-lifecycle PLACEMENT knob, inside the trust boundary,
|
|
82
83
|
// config-resolved. Fed into the shared placement resolver as the
|
|
83
84
|
// configured-default rung (`src/placement.ts`).
|
|
@@ -91,7 +92,7 @@ export const REPO_ALLOWED_KEYS = [
|
|
|
91
92
|
// through the SAME chain as `tasksLandIn` (flag `--specs-land-in` > env
|
|
92
93
|
// `DORFL_SPECS_LAND_IN` > per-repo > global > built-in). Fed into the shared
|
|
93
94
|
// placement resolver as the configured-default rung for the spec lifecycle
|
|
94
|
-
// (`src/placement.ts`). The sole spec-placement key after the prd → spec HARD
|
|
95
|
+
// (`src/placement.ts`). The sole spec-placement key after the ''prd'' → `spec` HARD
|
|
95
96
|
// CUTOVER (the legacy `prdsLandIn` key is GONE — clean break, no accepted alias).
|
|
96
97
|
'specsLandIn',
|
|
97
98
|
// `noPR` (the PR-INTENT axis — push the branch but deliberately skip the PR) is
|
|
@@ -116,7 +117,7 @@ export const REPO_ALLOWED_KEYS = [
|
|
|
116
117
|
'autoBuild',
|
|
117
118
|
// `autoTask` (may an agent auto-task undeclared prds in this repo?) is a
|
|
118
119
|
// genuine repo property — the tasking-autonomy mirror of `autoBuild`
|
|
119
|
-
// (`work/
|
|
120
|
+
// (`work/specs/auto-task.md`), resolved per-repo through the same chain.
|
|
120
121
|
'autoTask',
|
|
121
122
|
// `observationTriage` (the 3-state `off|ask|auto` gate over the observation
|
|
122
123
|
// INBOX) is a genuine repo property — the observation-side question-surfacing
|
|
@@ -125,7 +126,7 @@ export const REPO_ALLOWED_KEYS = [
|
|
|
125
126
|
// boolean (no alias; no external users owed a migration window, 2026-06-12).
|
|
126
127
|
'observationTriage',
|
|
127
128
|
// `mergeQuestions` (the 3-state `off|ask|auto` gate over the MERGE-QUESTION
|
|
128
|
-
// SURFACER —
|
|
129
|
+
// SURFACER — spec `land-time-reverify-and-parallel-merge-ceiling` Story 17 /
|
|
129
130
|
// task `merge-questions-gate-axis`) is a genuine repo property exactly like
|
|
130
131
|
// `observationTriage`: whether THIS repo's unmerged `work/*` branches surface
|
|
131
132
|
// as merge-questions (and whether they auto-land) is agreed by all
|
|
@@ -136,13 +137,13 @@ export const REPO_ALLOWED_KEYS = [
|
|
|
136
137
|
// (flag > env > per-repo > global > default `ask`).
|
|
137
138
|
'mergeQuestions',
|
|
138
139
|
// `surfaceBlockers` (the BOOLEAN gate over DECLARED blocked work — whether a
|
|
139
|
-
// task/
|
|
140
|
+
// task/spec carrying `needsAnswers:true` is rendered into a question sidecar) is a
|
|
140
141
|
// genuine repo property — the blocked-work side of the question-surfacing gate
|
|
141
142
|
// family (ADR `ci-config-policy-and-gate-family`), the orthogonal peer of
|
|
142
143
|
// `observationTriage`, resolved per-repo through the same chain as `autoBuild`.
|
|
143
144
|
'surfaceBlockers',
|
|
144
145
|
// `surfaceStaging` (the BOOLEAN gate-family member that widens SURFACE into
|
|
145
|
-
// STAGING —
|
|
146
|
+
// STAGING — spec `staging-surface-and-apply-promote-safety` F2) is a genuine
|
|
146
147
|
// repo property exactly like its siblings (`surfaceBlockers`/`autoBuild`):
|
|
147
148
|
// whether THIS repo inspects staging for questions is agreed by all
|
|
148
149
|
// collaborators + travels with the repo. Default `true`; resolved per-repo
|
|
@@ -161,8 +162,8 @@ export const REPO_ALLOWED_KEYS = [
|
|
|
161
162
|
// (machine paths/commands), so they are rejected below.
|
|
162
163
|
'model',
|
|
163
164
|
'harness',
|
|
164
|
-
// Gate 2 (PR/code review) policy is a genuine repo property (GATES
|
|
165
|
-
// `work/
|
|
165
|
+
// Gate 2 (PR/code review) policy is a genuine repo property (GATES spec
|
|
166
|
+
// `work/specs/tasked/review.md`), resolved per-repo like `integration`/`autoBuild`:
|
|
166
167
|
// whether this repo runs Gate 2 (`review`), which model the review agent runs
|
|
167
168
|
// on (`reviewModel`), and the revise↔review loop bound (`reviewMaxRounds`).
|
|
168
169
|
// `reviewModel` is routing intent (not auth), so — like `model` — it is
|
|
@@ -185,7 +186,7 @@ export const REPO_ALLOWED_KEYS = [
|
|
|
185
186
|
// artifact (and pays the per-gate install cost) is agreed by all collaborators
|
|
186
187
|
// + travels with the repo. Resolved per-repo through the SAME chain.
|
|
187
188
|
'freshWorktreeGate',
|
|
188
|
-
// `mergeRetries` (the cross-job merge serialiser's CAS-retry cap —
|
|
189
|
+
// `mergeRetries` (the cross-job merge serialiser's CAS-retry cap — spec
|
|
189
190
|
// `land-time-reverify-and-parallel-merge-ceiling` Story 5 / Applied Answer q1 (a))
|
|
190
191
|
// is a genuine repo property exactly like `freshWorktreeGate`: "how many
|
|
191
192
|
// re-rebase-and-retry attempts before a contender bounces to needs-attention"
|
|
@@ -195,7 +196,7 @@ export const REPO_ALLOWED_KEYS = [
|
|
|
195
196
|
// CAS still costs only a re-rebase + re-gate retry, never a `--force`.
|
|
196
197
|
'mergeRetries',
|
|
197
198
|
// `strictMergeApproval` (the OPT-IN strictness layered on the OQ6
|
|
198
|
-
// stale-approval default —
|
|
199
|
+
// stale-approval default — spec `land-time-reverify-and-parallel-merge-ceiling`
|
|
199
200
|
// sidecar OQ6 / task `strict-merge-approval-gate`) is a genuine repo property
|
|
200
201
|
// exactly like `mergeQuestions`/`mergeRetries`: whether THIS repo re-surfaces
|
|
201
202
|
// the merge-question on a merge-base change (the host-agnostic analogue of
|
|
@@ -207,6 +208,16 @@ export const REPO_ALLOWED_KEYS = [
|
|
|
207
208
|
// default or shape. The re-surface vs. land branch is
|
|
208
209
|
// `apply-rung-merge-disposition`'s consumer, never here.
|
|
209
210
|
'strictMergeApproval',
|
|
211
|
+
// `agentDeadlineMinutes` / `checkpointHeadroomMinutes` / `maxAutoCheckpoints`
|
|
212
|
+
// (spec `graceful-pre-timeout-wip-checkpoint`) are genuine repo properties:
|
|
213
|
+
// how long an agent session runs before checkpointing, and how much head-room
|
|
214
|
+
// the GitHub backstop leaves above it, are agreed by all collaborators + travel
|
|
215
|
+
// with the repo. The dynamic GitHub `timeout-minutes` cap is rendered by the
|
|
216
|
+
// `enumerate` job at run time FROM this committed config, so an edit reflects
|
|
217
|
+
// EVERYWHERE (internal deadline AND GitHub cap) with no install-ci re-run.
|
|
218
|
+
'agentDeadlineMinutes',
|
|
219
|
+
'checkpointHeadroomMinutes',
|
|
220
|
+
'maxAutoCheckpoints',
|
|
210
221
|
// `promptGuidance` (the NUDGE namespace — prompt-text knobs that strengthen
|
|
211
222
|
// the worker's in-band wrapper line, e.g. `testFirst`) is a genuine repo
|
|
212
223
|
// property: "is this repo nudged toward test-first?" travels with the repo
|
|
@@ -257,9 +268,42 @@ export type RepoRejectedKey = (typeof REPO_REJECTED_KEYS)[number];
|
|
|
257
268
|
|
|
258
269
|
const ALLOWED_SET = new Set<string>(REPO_ALLOWED_KEYS);
|
|
259
270
|
|
|
260
|
-
/**
|
|
271
|
+
/**
|
|
272
|
+
* The LEGACY per-repo config filename (`.dorfl.json`, the original dotfile form)
|
|
273
|
+
* still honoured on READ for backward compatibility. Reads prefer
|
|
274
|
+
* {@link REPO_CONFIG_FILENAME} (`dorfl.json`) and fall back to this; writes /
|
|
275
|
+
* `setup` use the preferred name. Derived from the single brand identity so a
|
|
276
|
+
* rename flips it in lockstep (see `brand.ts`).
|
|
277
|
+
*/
|
|
278
|
+
export const REPO_CONFIG_FILENAME_LEGACY = brand.repoConfigFilenameLegacy;
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Resolve which per-repo config file a repo USES: the PREFERRED
|
|
282
|
+
* `dorfl.json` if present, else the LEGACY `.dorfl.json` if present, else the
|
|
283
|
+
* preferred path (the location a missing file WOULD live / be created at). So a
|
|
284
|
+
* repo that already committed the legacy dotfile keeps working, while a fresh
|
|
285
|
+
* repo (and every write) uses the plain name. If BOTH exist, the preferred
|
|
286
|
+
* `dorfl.json` wins (a deliberate, documented precedence, not a merge).
|
|
287
|
+
*/
|
|
288
|
+
export function resolveRepoConfigPath(repoPath: string): string {
|
|
289
|
+
const preferred = join(repoPath, REPO_CONFIG_FILENAME);
|
|
290
|
+
if (existsSync(preferred)) {
|
|
291
|
+
return preferred;
|
|
292
|
+
}
|
|
293
|
+
const legacy = join(repoPath, REPO_CONFIG_FILENAME_LEGACY);
|
|
294
|
+
if (existsSync(legacy)) {
|
|
295
|
+
return legacy;
|
|
296
|
+
}
|
|
297
|
+
return preferred;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* The path to a repo's config file. Prefers the plain `dorfl.json`, falls back
|
|
302
|
+
* to the legacy `.dorfl.json` when only that exists (see
|
|
303
|
+
* {@link resolveRepoConfigPath}).
|
|
304
|
+
*/
|
|
261
305
|
export function repoConfigPath(repoPath: string): string {
|
|
262
|
-
return
|
|
306
|
+
return resolveRepoConfigPath(repoPath);
|
|
263
307
|
}
|
|
264
308
|
|
|
265
309
|
/** The result of reading (and filtering) a repo's `.dorfl.json`. */
|
|
@@ -542,6 +586,11 @@ export function resolveRepoConfigFromLoaded(
|
|
|
542
586
|
...envOverrides(env),
|
|
543
587
|
...(flags ?? {}),
|
|
544
588
|
});
|
|
589
|
+
// Fail-loud range validation for the deadline / backstop / ceiling triple
|
|
590
|
+
// (spec `graceful-pre-timeout-wip-checkpoint`): a bad value from ANY layer
|
|
591
|
+
// (flag / env / per-repo / global) throws with a clear message naming the
|
|
592
|
+
// field + range — NEVER silently clamped.
|
|
593
|
+
validateDeadlineConfig(config);
|
|
545
594
|
return {
|
|
546
595
|
config,
|
|
547
596
|
rejected: repo.rejected,
|
package/src/repo-mirror.ts
CHANGED
|
@@ -5,6 +5,7 @@ import type {Config, PartialConfig} from './config.js';
|
|
|
5
5
|
import type {ConfigOverrideMap} from './config-override.js';
|
|
6
6
|
import {
|
|
7
7
|
REPO_CONFIG_FILENAME,
|
|
8
|
+
REPO_CONFIG_FILENAME_LEGACY,
|
|
8
9
|
loadRepoConfigFromContent,
|
|
9
10
|
resolveRepoConfigFromLoaded,
|
|
10
11
|
type LoadedRepoConfig,
|
|
@@ -247,7 +248,28 @@ export function readRepoConfigFromMirrorMain(
|
|
|
247
248
|
mirrorDir: string,
|
|
248
249
|
env?: NodeJS.ProcessEnv,
|
|
249
250
|
): string | undefined {
|
|
250
|
-
|
|
251
|
+
// Prefer the plain `dorfl.json`; fall back to the legacy `.dorfl.json` when the
|
|
252
|
+
// preferred name is absent on `main` (a repo that committed the dotfile before
|
|
253
|
+
// dual-support). A genuine read fault on the FIRST attempt propagates; a
|
|
254
|
+
// path-missing on the first falls through to the legacy attempt.
|
|
255
|
+
const preferred = showConfigOnMain(mirrorDir, REPO_CONFIG_FILENAME, env);
|
|
256
|
+
if (preferred !== undefined) {
|
|
257
|
+
return preferred;
|
|
258
|
+
}
|
|
259
|
+
return showConfigOnMain(mirrorDir, REPO_CONFIG_FILENAME_LEGACY, env);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* `git show main:<filename>` in a mirror, returning the bytes, or `undefined`
|
|
264
|
+
* when the PATH is absent on `main` (the expected config-less / wrong-name case).
|
|
265
|
+
* A genuine fault (unresolvable `main` / bad object) throws.
|
|
266
|
+
*/
|
|
267
|
+
function showConfigOnMain(
|
|
268
|
+
mirrorDir: string,
|
|
269
|
+
filename: string,
|
|
270
|
+
env?: NodeJS.ProcessEnv,
|
|
271
|
+
): string | undefined {
|
|
272
|
+
const spec = `main:${filename}`;
|
|
251
273
|
const res = run('git', ['show', spec], mirrorDir, {env});
|
|
252
274
|
if (res.status === 0) {
|
|
253
275
|
return res.stdout;
|
package/src/review-gate.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {NullHarness, substituteModel, type Harness} from './harness.js';
|
|
2
2
|
import {launchWithOptionalWatch} from './agent-launch.js';
|
|
3
3
|
import {boundaryLine} from './watch-session.js';
|
|
4
|
+
import {workItemRel} from './work-layout.js';
|
|
4
5
|
import {
|
|
5
6
|
parseReviewVerdict,
|
|
6
7
|
ReviewParseError,
|
|
@@ -18,7 +19,7 @@ export {
|
|
|
18
19
|
} from './review-verdict.js';
|
|
19
20
|
|
|
20
21
|
/**
|
|
21
|
-
* **Gate 2 — the PR/code review gate** (GATES
|
|
22
|
+
* **Gate 2 — the PR/code review gate** (GATES spec `work/specs/tasked/review.md`), the
|
|
22
23
|
* JUDGEMENT layer that rides ON TOP of the deterministic `verify` floor (ADR §8).
|
|
23
24
|
*
|
|
24
25
|
* After the green `verify` and BEFORE the done-move, `complete`/`do` invoke the
|
|
@@ -110,7 +111,7 @@ export function buildReviewPrompt(slug: string): string {
|
|
|
110
111
|
return [
|
|
111
112
|
`You are a FRESH-CONTEXT reviewer (Gate 2 — PR/code review). Review the`,
|
|
112
113
|
`code changes on this work branch AGAINST the task that specified them`,
|
|
113
|
-
`(work/in-progress/${slug}.md or work/done/${slug}.md) and its source
|
|
114
|
+
`(work/in-progress/${slug}.md or work/done/${slug}.md) and its source spec.`,
|
|
114
115
|
``,
|
|
115
116
|
reviewDisciplinePrompt(),
|
|
116
117
|
``,
|
|
@@ -150,7 +151,7 @@ export function buildReviewPrompt(slug: string): string {
|
|
|
150
151
|
`comment on the PR — write it FOR a human landing there, NOT as scratch`,
|
|
151
152
|
`thinking. LEAD with the verdict ("Approved" or "Blocked") and then give the`,
|
|
152
153
|
`lenses' reasoning and the destination check ("merged as written, do we reach`,
|
|
153
|
-
`the task/
|
|
154
|
+
`the task/spec goal?"). Write it deliberately; do NOT narrate your process`,
|
|
154
155
|
`("Let me check…"). Keep it TIGHT: aim for a few short sentences and DO NOT`,
|
|
155
156
|
`exceed ~1500 characters — a long, multi-paragraph field is exactly what`,
|
|
156
157
|
`corrupts the JSON on large diffs; say less, not more. It is plain text inside`,
|
|
@@ -247,10 +248,10 @@ export function harnessReviewGate(
|
|
|
247
248
|
* Render the TASK-SET acceptance-gate PROMPT — the task-path mirror of
|
|
248
249
|
* {@link buildReviewPrompt} (task `slice-acceptance-gate`). Instead of
|
|
249
250
|
* reviewing a code diff against ONE task, this instructs a FRESH-CONTEXT
|
|
250
|
-
* agent to review the WHOLE candidate SET of tasks produced for
|
|
251
|
+
* agent to review the WHOLE candidate SET of tasks produced for spec `slug`,
|
|
251
252
|
* using the **review discipline**'s SET-OF-TASKS lens (coherence / dependency
|
|
252
253
|
* graph / gaps + overlap / "if every task is built exactly as written, do we
|
|
253
|
-
* reach the system the
|
|
254
|
+
* reach the system the spec describes, and is each task
|
|
254
255
|
* correct-if-implemented?"). It emits the SAME unified `ReviewVerdict` shape
|
|
255
256
|
* so {@link parseReviewVerdict} reads it identically.
|
|
256
257
|
*
|
|
@@ -265,24 +266,24 @@ export function harnessReviewGate(
|
|
|
265
266
|
export function buildTaskAcceptancePrompt(slug: string): string {
|
|
266
267
|
return [
|
|
267
268
|
`You are a FRESH-CONTEXT reviewer (the task-SET ACCEPTANCE GATE). Review`,
|
|
268
|
-
`the candidate tasks this tasking run produced for the
|
|
269
|
+
`the candidate tasks this tasking run produced for the spec "${slug}" — the`,
|
|
269
270
|
`new/changed candidate task files on this work branch — AGAINST their source`,
|
|
270
|
-
`
|
|
271
|
+
`spec (${workItemRel('specs-ready', `${slug}.md`)} — the held spec stays in specs/ready/ while it is being`,
|
|
271
272
|
`tasked).`,
|
|
272
273
|
``,
|
|
273
274
|
reviewDisciplinePrompt(),
|
|
274
275
|
``,
|
|
275
276
|
`Review the WHOLE SET as a SET, not each task in isolation. The set-level`,
|
|
276
277
|
`framings the review discipline names:`,
|
|
277
|
-
` - COHERENCE — do the tasks speak the
|
|
278
|
-
` consistently; no task re-means or forks a concept another task/the
|
|
278
|
+
` - COHERENCE — do the tasks speak the spec's (and the system's) language`,
|
|
279
|
+
` consistently; no task re-means or forks a concept another task/the spec`,
|
|
279
280
|
` already owns?`,
|
|
280
281
|
` - DEPENDENCY GRAPH — is the \`blockedBy\`/ordering graph sound (acyclic, the`,
|
|
281
282
|
` keystone first, each task's stated blockers really land its premise)?`,
|
|
282
|
-
` - GAPS + OVERLAP — does the set COVER the
|
|
283
|
+
` - GAPS + OVERLAP — does the set COVER the spec with no missing piece, and`,
|
|
283
284
|
` without two tasks doing the same work or fighting over the same seam?`,
|
|
284
285
|
` - CORRECT-IF-IMPLEMENTED — if EVERY task is built EXACTLY as written, do we`,
|
|
285
|
-
` reach the system the
|
|
286
|
+
` reach the system the spec describes, and is each task individually`,
|
|
286
287
|
` correct-if-implemented (no task that compiles but builds the wrong thing)?`,
|
|
287
288
|
``,
|
|
288
289
|
`This is a TERMINAL one-shot accept/reject gate: do NOT edit any task, do NOT`,
|
package/src/review-verdict.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* (`work/protocol/REVIEW-PROTOCOL.md`, source-of-truth
|
|
5
5
|
* `skills/setup/protocol/REVIEW-PROTOCOL.md`).
|
|
6
6
|
*
|
|
7
|
-
* This is the keystone of the `runner-invoked-disciplines-into-protocol`
|
|
7
|
+
* This is the keystone of the `runner-invoked-disciplines-into-protocol` spec
|
|
8
8
|
* (task 1, D4): every runner-invoked review prompt builder
|
|
9
9
|
* ({@link buildReviewPrompt}, {@link buildTaskAcceptancePrompt} in
|
|
10
10
|
* `review-gate.ts`; {@link buildLoneTaskReviewPrompt} in `intake.ts`;
|
|
@@ -84,7 +84,7 @@ export interface ReviewVerdict {
|
|
|
84
84
|
questions?: string[];
|
|
85
85
|
/** For the tasker improver loop: specific tasks to emit `needsAnswers: true`. */
|
|
86
86
|
uncertainTasks?: UncertainTask[];
|
|
87
|
-
/** For the tasker improver loop: route the WHOLE
|
|
87
|
+
/** For the tasker improver loop: route the WHOLE spec to needs-attention. */
|
|
88
88
|
decompositionUnclear?: {questions: string[]};
|
|
89
89
|
}
|
|
90
90
|
|
|
@@ -397,7 +397,7 @@ export function reviewDisciplinePrompt(): string {
|
|
|
397
397
|
'(the in-band, protocol-native review protocol every set-up repo carries;',
|
|
398
398
|
'the human-facing pointer is `skills/review/SKILL.md`). Apply its lenses',
|
|
399
399
|
'IN ORDER, ENDING in the destination check ("if this is built/merged',
|
|
400
|
-
'exactly as written, do we end up with the system the
|
|
400
|
+
'exactly as written, do we end up with the system the spec/task',
|
|
401
401
|
'goal describes?"). Be ADVERSARIAL; verify against what ACTUALLY LANDED',
|
|
402
402
|
'(the bytes on disk), not intent. Weight findings by REAL impact \u2014 the',
|
|
403
403
|
'lenses find candidates, impact decides severity (a technically-true nit',
|
package/src/run.ts
CHANGED
|
@@ -31,7 +31,11 @@ import {
|
|
|
31
31
|
parseStopSentinel,
|
|
32
32
|
isWorkBranchDiffEmpty,
|
|
33
33
|
emptyDiffStopReason,
|
|
34
|
+
emptyDiffDisposeEnvelope,
|
|
35
|
+
type AgentStopKind,
|
|
34
36
|
} from './agent-stop.js';
|
|
37
|
+
import {surfaceStuckToNeedsAttention} from './needs-attention.js';
|
|
38
|
+
import {resolveItemPathByIdentity} from './item-path.js';
|
|
35
39
|
import {
|
|
36
40
|
classifyFailureCause,
|
|
37
41
|
failureCauseLabel,
|
|
@@ -190,6 +194,7 @@ export type ItemStatus =
|
|
|
190
194
|
| 'surface-unmoved' // the tree-less surface to needs-attention did NOT land on the arbiter (lost the CAS race / no arbiter) — the item is STILL in-progress on the arbiter; retry/resolve
|
|
191
195
|
| 'agent-failed' // the agent ran but produced bad/empty output (the conservative generic), OR the cause is unknown
|
|
192
196
|
| 'transient-infra' // a harness-surfaced model/connection outage (post-retry) or a git/provider outage — RETRY the same work (FAILURE-CAUSE axis)
|
|
197
|
+
| 'needs-reauth' // a credential expired / was revoked (OAuth refresh) — retry cannot help; a human must RE-AUTH (FAILURE-CAUSE axis)
|
|
193
198
|
| 'config-error' // a thrown CORE wiring/config error (e.g. review on, no reviewGate) — fix the WIRING, not the task (FAILURE-CAUSE axis)
|
|
194
199
|
| 'agent-stopped'; // the agent DELIBERATELY stopped (task drifted) OR produced no change — gate + Gate-2 skipped
|
|
195
200
|
|
|
@@ -457,6 +462,7 @@ export async function runOnce(options: RunOnceOptions): Promise<RunOnceResult> {
|
|
|
457
462
|
// are the same agent/run-failure routed to needs-attention, just labelled
|
|
458
463
|
// by cause).
|
|
459
464
|
i.status === 'transient-infra' ||
|
|
465
|
+
i.status === 'needs-reauth' ||
|
|
460
466
|
i.status === 'config-error' ||
|
|
461
467
|
// The surface to needs-attention did NOT land (lost the CAS race); the item
|
|
462
468
|
// is still in-progress on the arbiter — a genuine FAILURE (not a clean
|
|
@@ -709,16 +715,19 @@ async function runOneItem(
|
|
|
709
715
|
// `work/<slug>` tip == the arbiter tip (the kept branch, unchanged,
|
|
710
716
|
// after-commit). The DURABLE artifact is that branch on the arbiter + the
|
|
711
717
|
// main surface (ADR §14: the job worktree is a disposable cache; recovery
|
|
712
|
-
// flows through the branch +
|
|
713
|
-
// worktree). So the surface is purely the
|
|
714
|
-
//
|
|
715
|
-
//
|
|
718
|
+
// flows through the branch + lock surfaces, NOT by editing the
|
|
719
|
+
// worktree). So the surface is purely the lock amend to `state: stuck` +
|
|
720
|
+
// reason (post lock-cutover — no `in-progress/ → needs-attention/` folder
|
|
721
|
+
// move, no branch push, no worktree
|
|
722
|
+
// mutation). Because the branch is provably on the arbiter, the §4 reap
|
|
716
723
|
// predicate still HOLDS and this worktree is reaped — more §14-aligned.
|
|
717
724
|
if (tree.continueRebaseConflict) {
|
|
718
725
|
const reason =
|
|
719
726
|
`continuing the kept ${tree.branch}: rebase onto the latest main ` +
|
|
720
|
-
'conflicted (aborted, never auto-resolved) —
|
|
721
|
-
'
|
|
727
|
+
'conflicted (aborted, never auto-resolved) — run `requeue --reconcile` ' +
|
|
728
|
+
'to non-destructively re-sync the mirror and retry the rebase (keeps ' +
|
|
729
|
+
'the work). Last resort: `requeue --reset` DESTRUCTIVELY discards the ' +
|
|
730
|
+
'branch and starts fresh.';
|
|
722
731
|
updateJobRecord(tree.dir, {state: 'needs-attention', reason});
|
|
723
732
|
const surfaced = await ledgerWrite.applyTreelessNeedsAttentionTransition({
|
|
724
733
|
cwd: tree.dir,
|
|
@@ -747,9 +756,10 @@ async function runOneItem(
|
|
|
747
756
|
const reason =
|
|
748
757
|
`continuing the kept ${tree.branch}: publishing the rebased work branch ` +
|
|
749
758
|
`to the arbiter failed terminally (${tree.continuePushFailure}) — the ` +
|
|
750
|
-
'kept branch is left intact on the arbiter (recoverable);
|
|
751
|
-
'
|
|
752
|
-
'
|
|
759
|
+
'kept branch is left intact on the arbiter (recoverable); ' +
|
|
760
|
+
'`requeue --reconcile` to non-destructively re-sync the mirror and ' +
|
|
761
|
+
'retry once the churn settles (keeps the work). Last resort: ' +
|
|
762
|
+
'`requeue --reset` DESTRUCTIVELY discards the branch and starts fresh.';
|
|
753
763
|
updateJobRecord(tree.dir, {state: 'needs-attention', reason});
|
|
754
764
|
const surfaced = await ledgerWrite.applyTreelessNeedsAttentionTransition({
|
|
755
765
|
cwd: tree.dir,
|
|
@@ -765,7 +775,7 @@ async function runOneItem(
|
|
|
765
775
|
}
|
|
766
776
|
|
|
767
777
|
// 3. Build the prompt — the SAME dual-use assembly `dorfl prompt`
|
|
768
|
-
// emits: the canonical wrapper (+ source
|
|
778
|
+
// emits: the canonical wrapper (+ source spec) + the task's ## Prompt.
|
|
769
779
|
let prompt: string;
|
|
770
780
|
try {
|
|
771
781
|
// CONTINUE-aware resolution: only on a continue (the job continued a kept
|
|
@@ -801,7 +811,7 @@ async function runOneItem(
|
|
|
801
811
|
})
|
|
802
812
|
: undefined;
|
|
803
813
|
// Thread the resolved per-repo nudge through the per-item override layer
|
|
804
|
-
// (a task or
|
|
814
|
+
// (a task or spec may pin `promptGuidance.testFirst` in its frontmatter,
|
|
805
815
|
// superseding the repo policy for THIS item) before the wrapper is built.
|
|
806
816
|
const itemGuidance = resolvePromptGuidanceForItem({
|
|
807
817
|
cwd: tree.dir,
|
|
@@ -862,24 +872,31 @@ async function runOneItem(
|
|
|
862
872
|
// the arbiter) and SKIPS the gate + Gate-2 (the whole `performIntegration`
|
|
863
873
|
// band) — a clean STOP is NOT "a build that changed nothing".
|
|
864
874
|
const sentinel = parseStopSentinel(agent.output);
|
|
865
|
-
const stopReason =
|
|
875
|
+
const stopReason: {kind: AgentStopKind; reason: string} | undefined =
|
|
866
876
|
sentinel !== undefined
|
|
867
|
-
? sentinel.reason
|
|
877
|
+
? {kind: 'sentinel', reason: sentinel.reason}
|
|
868
878
|
: (await isWorkBranchDiffEmpty({
|
|
869
879
|
cwd: tree.dir,
|
|
870
880
|
arbiter: tree.arbiterRemote,
|
|
871
881
|
env: gitEnv,
|
|
872
882
|
}))
|
|
873
|
-
? emptyDiffStopReason(slug)
|
|
883
|
+
? {kind: 'empty-diff', reason: emptyDiffStopReason(slug)}
|
|
874
884
|
: undefined;
|
|
875
885
|
if (stopReason !== undefined) {
|
|
876
|
-
return await saveAgentStop(
|
|
886
|
+
return await saveAgentStop(
|
|
887
|
+
base,
|
|
888
|
+
tree,
|
|
889
|
+
slug,
|
|
890
|
+
stopReason.reason,
|
|
891
|
+
stopReason.kind,
|
|
892
|
+
ctx,
|
|
893
|
+
);
|
|
877
894
|
}
|
|
878
895
|
|
|
879
896
|
// 5–7 (CONVERGED). The whole gate → review → done-move → commit → rebase →
|
|
880
897
|
// integrate band — plus the needs-attention routing on any failure — now runs
|
|
881
898
|
// through the SHARED `performIntegration` core (`integration-core.ts`, the
|
|
882
|
-
// run/do convergence
|
|
899
|
+
// run/do convergence spec). `run` no longer forks its own gate / done-move /
|
|
883
900
|
// completion commit / `Integrator`+`integrateWithRebase`: that closed all
|
|
884
901
|
// three drift instances at once (the fleet now gets the review gate, the PR
|
|
885
902
|
// title/body, AND the per-repo language-agnostic `verify` gate instead of the
|
|
@@ -954,7 +971,7 @@ async function runOneItem(
|
|
|
954
971
|
// (`do`/`--isolated`/`--remote`/`complete`) already pass it unconditionally.
|
|
955
972
|
freshWorktreeGate: config.freshWorktreeGate,
|
|
956
973
|
// The cross-job merge-serialiser CAS-retry cap (config `mergeRetries`) —
|
|
957
|
-
// the git-alone FLOOR of the cross-job land queue (
|
|
974
|
+
// the git-alone FLOOR of the cross-job land queue (spec `land-time-reverify-
|
|
958
975
|
// and-parallel-merge-ceiling` Story 5 / Applied Answer q1 (a)). Threaded
|
|
959
976
|
// from the per-repo resolved config so a wide-matrix CI's raised cap actually
|
|
960
977
|
// reaches the merge loop — across separate `run` fleet jobs the CAS loop IS
|
|
@@ -1138,9 +1155,10 @@ function runAgent(
|
|
|
1138
1155
|
* This mirrors `do.ts`'s `saveAgentFailure`: route the failure through the SAME
|
|
1139
1156
|
* ledger write seam's needs-attention transition the gate-fail / integrate-
|
|
1140
1157
|
* conflict bounces use — which (with the arbiter) saves the agent's work as a wip
|
|
1141
|
-
* commit,
|
|
1142
|
-
*
|
|
1143
|
-
* (OBSERVABLE
|
|
1158
|
+
* commit, then — post lock-cutover — amends the item's per-item lock to
|
|
1159
|
+
* `state: stuck` with the failure detail as the reason on the lock entry
|
|
1160
|
+
* (OBSERVABLE; the `needs-attention/` folder move is retired), AND pushes the
|
|
1161
|
+
* `work/<slug>` branch (RECOVERABLE — the durable
|
|
1144
1162
|
* artifact a requeue-continue lands the next agent on; continue-detection reads
|
|
1145
1163
|
* <arbiter>/work/<slug> ahead of main). The push is best-effort — an unreachable
|
|
1146
1164
|
* arbiter leaves the retained worktree + the local commits standing (the genuinely
|
|
@@ -1194,8 +1212,9 @@ function failureCauseToItemStatus(cause: FailureCause): ItemStatus {
|
|
|
1194
1212
|
|
|
1195
1213
|
/**
|
|
1196
1214
|
* Build the HONEST {@link ItemResult} for a CONTINUE-site surface that did NOT
|
|
1197
|
-
* land on the arbiter (`{moved: false}`). The tree-less
|
|
1198
|
-
*
|
|
1215
|
+
* land on the arbiter (`{moved: false}`). The tree-less stuck-lock amend (post
|
|
1216
|
+
* lock-cutover — `state: stuck` + reason, in place of the retired `in-progress/ →
|
|
1217
|
+
* needs-attention/` move) lost the CAS race against a busy arbiter (its
|
|
1199
1218
|
* contention-retry cap exhausted) or had no arbiter to publish to, so the item is
|
|
1200
1219
|
* STILL in-progress on the arbiter — reporting a clean `needs-attention` would
|
|
1201
1220
|
* mislead (it claims the surface landed, when it did not). The DISTINCT
|
|
@@ -1236,9 +1255,36 @@ async function saveAgentStop(
|
|
|
1236
1255
|
tree: IsolatedTree,
|
|
1237
1256
|
slug: string,
|
|
1238
1257
|
reason: string,
|
|
1258
|
+
kind: AgentStopKind,
|
|
1239
1259
|
ctx: OneItemContext,
|
|
1240
1260
|
): Promise<ItemResult> {
|
|
1241
1261
|
updateJobRecord(tree.dir, {state: 'needs-attention', reason});
|
|
1262
|
+
// EMPTY-DIFF branch (spec resolved decision #2, task
|
|
1263
|
+
// `empty-diff-bounce-surfaces-dispose-defaulted-question`): surface a sidecar
|
|
1264
|
+
// carrying an engine-authored DISPOSE-DEFAULTED envelope question on
|
|
1265
|
+
// `<arbiter>/main` (via the PR-1 tree-less surface primitive) and release the
|
|
1266
|
+
// lock — NOT the general lock-stuck bounce path. "Nothing to do" is a
|
|
1267
|
+
// non-deterministic LLM judgement, so a blind requeue would infinite-loop;
|
|
1268
|
+
// the surfaced sidecar + `needsAnswers:true` on `main` parks the item as a
|
|
1269
|
+
// human-visible question a `dispose` answer settles to `tasks/cancelled/`.
|
|
1270
|
+
if (kind === 'empty-diff') {
|
|
1271
|
+
const item = `task:${slug}`;
|
|
1272
|
+
const itemPath = resolveItemPathByIdentity(tree.dir, item);
|
|
1273
|
+
if (itemPath !== undefined) {
|
|
1274
|
+
await surfaceStuckToNeedsAttention({
|
|
1275
|
+
cwd: tree.dir,
|
|
1276
|
+
slug,
|
|
1277
|
+
item,
|
|
1278
|
+
itemPath,
|
|
1279
|
+
reason,
|
|
1280
|
+
envelope: emptyDiffDisposeEnvelope({item, reason}),
|
|
1281
|
+
arbiter: tree.arbiterRemote,
|
|
1282
|
+
env: ctx.gitEnv ?? ctx.env,
|
|
1283
|
+
});
|
|
1284
|
+
return {...base, status: 'agent-stopped', detail: reason};
|
|
1285
|
+
}
|
|
1286
|
+
// Fallthrough (body missing) — fall through to the lock-stuck bounce below.
|
|
1287
|
+
}
|
|
1242
1288
|
await ledgerWrite.applyNeedsAttentionTransition({
|
|
1243
1289
|
cwd: tree.dir,
|
|
1244
1290
|
slug,
|
|
@@ -1262,7 +1308,7 @@ export function defaultRunWorkspace(): string {
|
|
|
1262
1308
|
* One supervised TICK over the registry, as a swappable unit. Today the tick IS
|
|
1263
1309
|
* `runOnce` (claim+build+integrate a concurrent batch of eligible TASKS). The
|
|
1264
1310
|
* loop ({@link runLoop}) is deliberately written against this signature — NOT
|
|
1265
|
-
* against `runOnce` directly — so the advance-loop
|
|
1311
|
+
* against `runOnce` directly — so the advance-loop spec can later swap the tick
|
|
1266
1312
|
* (build / task / triage / surface / apply) WITHOUT re-architecting the loop
|
|
1267
1313
|
* (the forward-pointer: the loop owns concurrency/scheduling, the tick owns one
|
|
1268
1314
|
* item's work). The loop never reaches inside a tick.
|