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/config.ts
CHANGED
|
@@ -17,12 +17,12 @@ import {
|
|
|
17
17
|
export type IntegrationMode = 'propose' | 'merge';
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
|
-
* **Per-repo TASK-PLACEMENT default** (
|
|
20
|
+
* **Per-repo TASK-PLACEMENT default** (spec
|
|
21
21
|
* `staging-pool-position-gate-and-trust-model`, task
|
|
22
22
|
* `runner-deterministic-slice-placement-policy-and-precedence`, governing ADR
|
|
23
23
|
* `placement-is-runner-deterministic-humanonly-is-agent-judgement`). Which
|
|
24
24
|
* folder the runner lands the tasker's emitted task files in BY DEFAULT —
|
|
25
|
-
* `'
|
|
25
|
+
* `'backlog'` (staging — durable + readable but NOT in the agent-eligible
|
|
26
26
|
* POOL; a runner/human promotion is needed to make an item claimable; the on-disk
|
|
27
27
|
* folder for this value is `work/tasks/backlog/`) or `'ready'` (the agent-eligible
|
|
28
28
|
* POOL — the trusted fast-path landing, on-disk `work/tasks/ready/`). The pool
|
|
@@ -30,32 +30,33 @@ export type IntegrationMode = 'propose' | 'merge';
|
|
|
30
30
|
* `rename-task-pool-folder-todo-to-ready`, a CLEAN BREAK matching the on-disk
|
|
31
31
|
* folder `tasks/ready/` and the spec-side `'ready'` pool spelling). The runner-deterministic
|
|
32
32
|
* placement RESOLVER (`src/placement.ts`) layers on top: `explicit operator flag
|
|
33
|
-
* > untrusted-origin ⇒
|
|
34
|
-
* (
|
|
33
|
+
* > untrusted-origin ⇒ backlog > tasksLandIn default > built-in
|
|
34
|
+
* (backlog)`. The staging value was renamed `'pre-backlog'` → `'backlog'`
|
|
35
|
+
* (matching the on-disk folder `tasks/backlog/`). An untrusted-origin tasker output is FORCED to staging even in
|
|
35
36
|
* a `'ready'` repo (the positional analogue of the existing
|
|
36
37
|
* `untrusted-origin-forces-build-propose` rule).
|
|
37
38
|
*/
|
|
38
|
-
export type TasksLandIn = '
|
|
39
|
+
export type TasksLandIn = 'backlog' | 'ready';
|
|
39
40
|
|
|
40
41
|
/**
|
|
41
|
-
* **Per-repo
|
|
42
|
+
* **Per-repo SPEC-PLACEMENT default** (spec
|
|
42
43
|
* `staging-pool-position-gate-and-trust-model`, task
|
|
43
44
|
* `pre-prd-staging-pool-split-and-untrusted-prd-placement`, governing ADR
|
|
44
45
|
* `placement-is-runner-deterministic-humanonly-is-agent-judgement`). Which
|
|
45
|
-
* folder the runner lands `intake`-authored
|
|
46
|
+
* folder the runner lands `intake`-authored spec files in BY DEFAULT —
|
|
46
47
|
* `'pre-proposed'` (staging — durable + readable but NOT in the auto-tasking
|
|
47
|
-
* POOL; a runner/human promotion is needed to make the
|
|
48
|
-
* on-disk folder for this value is `work/
|
|
48
|
+
* POOL; a runner/human promotion is needed to make the spec auto-taskable; the
|
|
49
|
+
* on-disk folder for this value is `work/specs/proposed/`) or `'ready'` (the
|
|
49
50
|
* auto-tasking POOL — the trusted fast-path landing, on-disk
|
|
50
|
-
* `work/
|
|
51
|
+
* `work/specs/ready/`). The same runner-deterministic placement RESOLVER
|
|
51
52
|
* (`src/placement.ts`) layers on top:
|
|
52
53
|
* `explicit operator flag > untrusted-origin ⇒ pre-proposed > specsLandIn
|
|
53
54
|
* default > built-in (pre-proposed)`. An untrusted-origin intake spec is FORCED
|
|
54
55
|
* to staging even in a `'ready'` repo (the positional analogue of the existing
|
|
55
|
-
* `untrusted-origin-forces-build-propose` rule). The
|
|
56
|
+
* `untrusted-origin-forces-build-propose` rule). The SPEC twin of
|
|
56
57
|
* {@link TasksLandIn}; the SAME shape, the SAME precedence chain. The value
|
|
57
|
-
* spellings mirror the live
|
|
58
|
-
* `
|
|
58
|
+
* spellings mirror the live spec folders (`specs/proposed/` staging,
|
|
59
|
+
* `specs/ready/` pool), exactly as {@link TasksLandIn} mirrors the task folders.
|
|
59
60
|
*/
|
|
60
61
|
export type SpecsLandIn = 'pre-proposed' | 'ready';
|
|
61
62
|
|
|
@@ -79,7 +80,7 @@ export type ObservationTriage = 'off' | 'ask' | 'auto';
|
|
|
79
80
|
|
|
80
81
|
/**
|
|
81
82
|
* **The `mergeQuestions` gate axis** — the 3-state member of the question-
|
|
82
|
-
* surfacing gate family that governs the MERGE-QUESTION surfacer (
|
|
83
|
+
* surfacing gate family that governs the MERGE-QUESTION surfacer (spec
|
|
83
84
|
* `land-time-reverify-and-parallel-merge-ceiling` Story 17 / task
|
|
84
85
|
* `merge-questions-gate-axis`). MIRRORS `observationTriage`'s shape
|
|
85
86
|
* (`off | ask | auto`) but is a SEPARATE axis — "should this built work merge?"
|
|
@@ -99,7 +100,7 @@ export type ObservationTriage = 'off' | 'ask' | 'auto';
|
|
|
99
100
|
* invoke the agentic decider — a merge-land is never an agent decision.
|
|
100
101
|
* Resolved through the SAME precedence chain as the other gates (flag > env >
|
|
101
102
|
* per-repo > global > default `ask`). The exact name + default + shape were
|
|
102
|
-
* answered in this task's Applied answers 2026-06-26 (q1/q2/q3) +
|
|
103
|
+
* answered in this task's Applied answers 2026-06-26 (q1/q2/q3) + SPEC sidecar
|
|
103
104
|
* Q3.
|
|
104
105
|
*/
|
|
105
106
|
export type MergeQuestions = 'off' | 'ask' | 'auto';
|
|
@@ -201,10 +202,10 @@ export interface Config {
|
|
|
201
202
|
/**
|
|
202
203
|
* Per-repo policy: may an agent auto-task *undeclared* (not `humanOnly`,
|
|
203
204
|
* no open questions) prds in this repo? `false` (default, strict, human-first)
|
|
204
|
-
* ⇒ a human must drive every
|
|
205
|
-
* any
|
|
205
|
+
* ⇒ a human must drive every spec's tasking; `true` ⇒ an agent may auto-task
|
|
206
|
+
* any spec that is not `humanOnly: true` and has no `needsAnswers`. Resolved like
|
|
206
207
|
* `autoBuild`: flag > `DORFL_AUTO_TASK` env > per-repo > global >
|
|
207
|
-
* default. The two-axis tasking gate (`work/
|
|
208
|
+
* default. The two-axis tasking gate (`work/specs/auto-task.md`), one level up
|
|
208
209
|
* from the build gate's `autoBuild`.
|
|
209
210
|
*/
|
|
210
211
|
autoTask: boolean;
|
|
@@ -227,7 +228,7 @@ export interface Config {
|
|
|
227
228
|
observationTriage: ObservationTriage;
|
|
228
229
|
/**
|
|
229
230
|
* Per-repo policy governing the MERGE-QUESTION SURFACER — the 3-state member
|
|
230
|
-
* of the question-surfacing gate family (
|
|
231
|
+
* of the question-surfacing gate family (spec
|
|
231
232
|
* `land-time-reverify-and-parallel-merge-ceiling` Story 17 / task
|
|
232
233
|
* `merge-questions-gate-axis`). MIRRORS `observationTriage`'s SHAPE
|
|
233
234
|
* (`off | ask | auto`) but is a SEPARATE axis with a DIFFERENT default —
|
|
@@ -251,7 +252,7 @@ export interface Config {
|
|
|
251
252
|
* Per-repo policy governing DECLARED blocked work — the BOOLEAN member of the
|
|
252
253
|
* question-surfacing gate family (its orthogonal PEER is `observationTriage`,
|
|
253
254
|
* which governs the raw observation INBOX; ADR `ci-config-policy-and-gate-family`
|
|
254
|
-
* §2). It gates whether a task/
|
|
255
|
+
* §2). It gates whether a task/spec carrying `needsAnswers: true` is rendered
|
|
255
256
|
* into an answerable question sidecar (`on`) or left silently blocked in the
|
|
256
257
|
* backlog (`off`). `false` (default, calm) ⇒ the `needsAnswers`-blocked pool is
|
|
257
258
|
* dropped from the auto-pick SELECTION, so a bare `advance` does NOT proactively
|
|
@@ -271,11 +272,11 @@ export interface Config {
|
|
|
271
272
|
/**
|
|
272
273
|
* Per-repo policy governing whether SURFACING (the question-minting polarity)
|
|
273
274
|
* inspects STAGING in addition to the agent pool — the BOOLEAN gate-family
|
|
274
|
-
* member added by
|
|
275
|
+
* member added by spec `staging-surface-and-apply-promote-safety` (F2). The
|
|
275
276
|
* BUILD polarity is UNCHANGED in either mode: staging items stay non-claimable,
|
|
276
277
|
* the trust model is untouched. `true` (default) ⇒ the SURFACE candidate set
|
|
277
|
-
* draws from STAGING (`tasks/backlog/`, `
|
|
278
|
-
* a `needsAnswers` task/
|
|
278
|
+
* draws from STAGING (`tasks/backlog/`, `specs/proposed/`) PLUS the pool, so
|
|
279
|
+
* a `needsAnswers` task/spec in staging surfaces its questions BEFORE a human
|
|
279
280
|
* promotes it (you promote an already-clarified item, not blind and then get
|
|
280
281
|
* asked after); `false` ⇒ the legacy POOL-ONLY behaviour (staging is not
|
|
281
282
|
* inspected for questions). Resolved like `surfaceBlockers`/`autoBuild`:
|
|
@@ -340,33 +341,33 @@ export interface Config {
|
|
|
340
341
|
/** Integration mode for completed items: `propose` (default) or `merge`. */
|
|
341
342
|
integration: IntegrationMode;
|
|
342
343
|
/**
|
|
343
|
-
* **Per-TRANSITION override for the
|
|
344
|
-
* set, the tasking transition (a `do
|
|
345
|
-
* the `work/
|
|
344
|
+
* **Per-TRANSITION override for the spec→tasks (TASKING) transition only.** When
|
|
345
|
+
* set, the tasking transition (a `do spec:<slug>` run: emit `work/tasks/backlog/*.md` +
|
|
346
|
+
* the `work/specs/ready/ → work/specs/tasked/` lifecycle move) integrates with THIS
|
|
346
347
|
* mode instead of the flat {@link integration}; the task-BUILD transition is
|
|
347
348
|
* unaffected (it always reads {@link integration}). UNSET (the default) ⇒ tasking
|
|
348
349
|
* falls back to {@link integration} — byte-for-byte today's behaviour for any repo
|
|
349
350
|
* that does not set it. The maintainer's target is `integration: 'propose'` +
|
|
350
|
-
* `taskingIntegration: 'merge'`: task a
|
|
351
|
+
* `taskingIntegration: 'merge'`: task a spec straight onto `main` (the task FILES
|
|
351
352
|
* land, no PR) but build each task as a reviewable PR. Resolved per-repo like
|
|
352
353
|
* {@link integration}: flag (`--merge`/`--propose`) > env
|
|
353
354
|
* (`DORFL_TASKING_INTEGRATION`) > per-repo > global > (fall back to)
|
|
354
355
|
* `integration` > default `propose`. DISTINCT from intake's per-EMITTED-TYPE
|
|
355
|
-
* `{task,
|
|
356
|
+
* `{task, spec}` resolver (front door, author-trust-resolved): this is a
|
|
356
357
|
* per-LIFECYCLE-TRANSITION knob, inside the trust boundary, operator/config-only.
|
|
357
358
|
*/
|
|
358
359
|
taskingIntegration?: IntegrationMode;
|
|
359
360
|
/**
|
|
360
|
-
* **Per-repo DEFAULT landing for the TASKER's emitted tasks** (
|
|
361
|
+
* **Per-repo DEFAULT landing for the TASKER's emitted tasks** (spec
|
|
361
362
|
* `staging-pool-position-gate-and-trust-model` US #5, task
|
|
362
363
|
* `runner-deterministic-slice-placement-policy-and-precedence`). Resolved
|
|
363
364
|
* per-repo EXACTLY like {@link taskingIntegration} (flag `--tasks-land-in`
|
|
364
365
|
* > env `DORFL_TASKS_LAND_IN` > per-repo > global > built-in
|
|
365
|
-
* `'
|
|
366
|
+
* `'backlog'`). The tasking path reads it and passes it as the
|
|
366
367
|
* CONFIGURED-DEFAULT rung into the shared placement resolver
|
|
367
368
|
* (`src/placement.ts`); the resolver overlays an EXPLICIT operator flag
|
|
368
369
|
* (top) and the UNTRUSTED-ORIGIN force (staging) on top, in that order. The
|
|
369
|
-
* tasker NEVER sets placement itself.
|
|
370
|
+
* tasker NEVER sets placement itself. Spec US #6 / the governing ADR: the
|
|
370
371
|
* runner OWNS placement from unforgeable inputs; the agent cannot
|
|
371
372
|
* influence it.
|
|
372
373
|
*/
|
|
@@ -385,7 +386,7 @@ export interface Config {
|
|
|
385
386
|
* influence it. KEY-LEVEL SYMMETRY with `tasksLandIn` — one resolver, two
|
|
386
387
|
* lifecycles, one precedence change touches ONE place.
|
|
387
388
|
*
|
|
388
|
-
* The sole spec-placement key after the prd → spec HARD CUTOVER (spec
|
|
389
|
+
* The sole spec-placement key after the ''prd'' → `spec` HARD CUTOVER (spec
|
|
389
390
|
* `prd-to-spec-vocabulary-cutover-and-migration-command`): the legacy
|
|
390
391
|
* `prdsLandIn` config key + `--prds-land-in` flag are GONE (clean break).
|
|
391
392
|
*/
|
|
@@ -483,7 +484,7 @@ export interface Config {
|
|
|
483
484
|
*/
|
|
484
485
|
verify?: VerifyConfig;
|
|
485
486
|
/**
|
|
486
|
-
* **Gate 2 — the PR/code review gate** (GATES
|
|
487
|
+
* **Gate 2 — the PR/code review gate** (GATES spec `work/specs/tasked/review.md`): run the
|
|
487
488
|
* `review` SKILL as a fresh-context judgement gate ON TOP of the deterministic
|
|
488
489
|
* `verify` floor, AFTER `verify` passes and BEFORE the done-move, on the
|
|
489
490
|
* `do`/`complete` path. Default **OFF** (it puts a model on the merge path —
|
|
@@ -508,8 +509,8 @@ export interface Config {
|
|
|
508
509
|
* re-rolled — re-reviewing an unchanged tip after a block would just be a
|
|
509
510
|
* stochastic dice re-roll that could launder a real reject into a pass). So a
|
|
510
511
|
* value > 1 makes a FALSE APPROVE harder to slip through (each extra round is a
|
|
511
|
-
* veto), it does NOT give blocked work a second chance. A non-approve forces
|
|
512
|
-
* `
|
|
512
|
+
* veto), it does NOT give blocked work a second chance. A non-approve forces the
|
|
513
|
+
* item stuck (the lock `state: stuck`; never silently merges or loops), per the maintainer
|
|
513
514
|
* decision. Default a small N (2): two independent approvals required. (A future
|
|
514
515
|
* builder-REVISE step that MUTATES the tree between rounds is the only thing that
|
|
515
516
|
* should make a block retryable, because it changes the artifact under review; it
|
|
@@ -519,7 +520,7 @@ export interface Config {
|
|
|
519
520
|
reviewMaxRounds: number;
|
|
520
521
|
/**
|
|
521
522
|
* **The tasker IMPROVER loop on/off toggle** (`--tasker-loop` /
|
|
522
|
-
* `--no-tasker-loop`). On the `do
|
|
523
|
+
* `--no-tasker-loop`). On the `do spec:<slug>` tasking path the improver loop is
|
|
523
524
|
* the task path's quality engine (auto-tasking has no `verify` floor), so it is
|
|
524
525
|
* ON by default; setting this false gates wiring the loop seam (the candidate
|
|
525
526
|
* tasks land as-is). Resolved per-repo like `integration`: flag
|
|
@@ -529,8 +530,8 @@ export interface Config {
|
|
|
529
530
|
taskerLoop: boolean;
|
|
530
531
|
/**
|
|
531
532
|
* **The tasker IMPROVER loop's convergence cap** (`slicer-review-edit-loop`,
|
|
532
|
-
* GATES
|
|
533
|
-
* A). On the `do
|
|
533
|
+
* GATES spec `work/specs/tasked/review.md` RESOLVED DESIGN — Shape 2 / insertion point
|
|
534
|
+
* A). On the `do spec:<slug>` tasking path, AFTER the agent produces candidate
|
|
534
535
|
* tasks the loop runs the `review` SKILL, APPLIES its edits, and re-reviews
|
|
535
536
|
* until a pass finds no NEW blocking issue (the natural terminator).
|
|
536
537
|
* `taskerLoopMax` is the HARD CAP on the in-context review passes (N) so the
|
|
@@ -583,7 +584,7 @@ export interface Config {
|
|
|
583
584
|
freshWorktreeGate: boolean;
|
|
584
585
|
/**
|
|
585
586
|
* **The cross-job merge serialiser's CAS-retry cap** — the git-alone FLOOR of the
|
|
586
|
-
* land-time cross-job queue (
|
|
587
|
+
* land-time cross-job queue (spec `land-time-reverify-and-parallel-merge-ceiling`,
|
|
587
588
|
* Story 5 + Applied Answer q1 (a)). The merge-mode `${branch}:main` push retries
|
|
588
589
|
* a non-fast-forward rejection by re-rebasing onto the moved `<arbiter>/main` and
|
|
589
590
|
* pushing again, up to this cap; only after exhaustion does a loser bounce to
|
|
@@ -605,7 +606,7 @@ export interface Config {
|
|
|
605
606
|
mergeRetries: number;
|
|
606
607
|
/**
|
|
607
608
|
* **Per-repo OPT-IN strictness layered on the OQ6 stale-approval default**
|
|
608
|
-
* (
|
|
609
|
+
* (spec `land-time-reverify-and-parallel-merge-ceiling`, sidecar OQ6 / task
|
|
609
610
|
* `strict-merge-approval-gate`). Controls how the apply rung treats a prior
|
|
610
611
|
* merge-answer when the merge-base CHANGED between the human's answer and
|
|
611
612
|
* the apply step. The default (`false`) honours the prior answer and lands
|
|
@@ -626,6 +627,40 @@ export interface Config {
|
|
|
626
627
|
* `observationTriage` default or shape — a SEPARATE, independent axis.
|
|
627
628
|
*/
|
|
628
629
|
strictMergeApproval: boolean;
|
|
630
|
+
/**
|
|
631
|
+
* **The dorfl-INTERNAL agent deadline** (minutes). The agent session self-stops
|
|
632
|
+
* at this budget; dorfl then SAVES the WIP (commit + push `work/<slug>`) and
|
|
633
|
+
* routes it per the progress+ceiling decision (auto-continue, or surface). This
|
|
634
|
+
* is the PRIMARY stop (see spec `graceful-pre-timeout-wip-checkpoint`); the
|
|
635
|
+
* GitHub `timeout-minutes` cap is a BACKSTOP set above it as
|
|
636
|
+
* `agentDeadlineMinutes + checkpointHeadroomMinutes`. Default 60; MAX 240 (4h).
|
|
637
|
+
* FAIL-LOUD: values outside `[1, 240]` throw at config load (never silently
|
|
638
|
+
* clamped). Resolved per-repo through the SAME chain as `integration` (flag >
|
|
639
|
+
* env `DORFL_AGENT_DEADLINE_MINUTES` > per-repo > global > default).
|
|
640
|
+
*/
|
|
641
|
+
agentDeadlineMinutes: number;
|
|
642
|
+
/**
|
|
643
|
+
* **The GitHub-backstop head-room above the internal deadline** (minutes). The
|
|
644
|
+
* enumerate job's dynamic `githubTimeout` output is
|
|
645
|
+
* `agentDeadlineMinutes + checkpointHeadroomMinutes`; the MIN 10 guarantees the
|
|
646
|
+
* GitHub cap is always at least 10 minutes above the internal deadline so the
|
|
647
|
+
* graceful save always has room to commit + push before the hard kill. Default
|
|
648
|
+
* 30; MIN 10; MAX 60 (1h). FAIL-LOUD: out-of-range throws at load. Resolved
|
|
649
|
+
* per-repo through the SAME chain as `agentDeadlineMinutes`.
|
|
650
|
+
*/
|
|
651
|
+
checkpointHeadroomMinutes: number;
|
|
652
|
+
/**
|
|
653
|
+
* **The auto-continue ceiling** for the deadline-checkpoint anti-loop guard
|
|
654
|
+
* (spec `graceful-pre-timeout-wip-checkpoint`). Counts CONSECUTIVE deadline
|
|
655
|
+
* auto-continues; on hitting this cap the next deadline checkpoint SURFACES a
|
|
656
|
+
* `needsAnswers:true` question ("this task has hit the deadline N times — it
|
|
657
|
+
* may be too big for one CI leg; split it or run it locally?") instead of
|
|
658
|
+
* auto-continuing. The counter naturally resets when the item completes (the
|
|
659
|
+
* work branch is discarded on integration). Default 5. Must be a positive
|
|
660
|
+
* integer (fail-loud). Resolved per-repo through the SAME chain as its
|
|
661
|
+
* siblings.
|
|
662
|
+
*/
|
|
663
|
+
maxAutoCheckpoints: number;
|
|
629
664
|
/**
|
|
630
665
|
* The optional runner **identity** (a bot): run the runner's git + provider
|
|
631
666
|
* operations as a configured entity via process-scoped env overrides, without
|
|
@@ -711,7 +746,7 @@ export const DEFAULT_CONFIG: Config = {
|
|
|
711
746
|
// auto-dispose the no-question cases). ADR `ci-config-policy-and-gate-family` §3.
|
|
712
747
|
observationTriage: 'off',
|
|
713
748
|
// The merge-question SURFACER defaults to `ask` — the conservative default
|
|
714
|
-
// (
|
|
749
|
+
// (spec `land-time-reverify-and-parallel-merge-ceiling` Applied answer q2 /
|
|
715
750
|
// task `merge-questions-gate-axis` Applied answer q2). NEVER `off` by default:
|
|
716
751
|
// a silently-dropped merge-question means finished, pushed work never lands —
|
|
717
752
|
// strictly more consequential than a dropped observation-promote prompt, so
|
|
@@ -728,9 +763,9 @@ export const DEFAULT_CONFIG: Config = {
|
|
|
728
763
|
// (a stuck build) is separate + always-on. ADR `ci-config-policy-and-gate-family` §3.
|
|
729
764
|
surfaceBlockers: false,
|
|
730
765
|
// SURFACING widens to STAGING by default (`true`) — a `needsAnswers` task in
|
|
731
|
-
// `tasks/backlog/` or a `needsAnswers`
|
|
766
|
+
// `tasks/backlog/` or a `needsAnswers` spec in `specs/proposed/` surfaces
|
|
732
767
|
// its questions BEFORE promotion, so a human promotes an already-clarified
|
|
733
|
-
// item.
|
|
768
|
+
// item. Spec `staging-surface-and-apply-promote-safety` (F2). BUILD/claim
|
|
734
769
|
// stays pool-only + trust-gated regardless: this widens ONLY the surface
|
|
735
770
|
// polarity, not the build polarity. Set `false` to restore the legacy
|
|
736
771
|
// pool-only surface behaviour.
|
|
@@ -741,7 +776,7 @@ export const DEFAULT_CONFIG: Config = {
|
|
|
741
776
|
// always first. Reproduces today's tasks-first two-pool default. Subsumes the
|
|
742
777
|
// removed `prdsFirst` boolean (`[task, build, ...]` reproduces `prdsFirst: true`).
|
|
743
778
|
selectionOrder: DEFAULT_SELECTION_ORDER,
|
|
744
|
-
maxParallel:
|
|
779
|
+
maxParallel: 2,
|
|
745
780
|
perRepoMax: 2,
|
|
746
781
|
defaultArbiter: 'origin',
|
|
747
782
|
workspacesDir: join(homedir(), brand.workdirName),
|
|
@@ -752,14 +787,14 @@ export const DEFAULT_CONFIG: Config = {
|
|
|
752
787
|
// branch but deliberately skip the PR (the explicit suppress-PR intent that
|
|
753
788
|
// re-homes the old `provider: none` use). NOT a provider choice.
|
|
754
789
|
noPR: false,
|
|
755
|
-
// The tasker's emitted tasks land STAGED (`
|
|
790
|
+
// The tasker's emitted tasks land STAGED (`tasks/backlog/`) by default — the
|
|
756
791
|
// conservative landing that preserves the tracer task's behaviour: an item is
|
|
757
792
|
// durable + readable but NOT in the agent-eligible pool until a human/runner
|
|
758
793
|
// promotes it. A repo opts into the trusted fast-path with `tasksLandIn:
|
|
759
794
|
// 'ready'` (or `--tasks-land-in ready` / `DORFL_TASKS_LAND_IN=ready`).
|
|
760
795
|
// The runner-deterministic resolver overlays explicit-flag + untrusted-origin
|
|
761
796
|
// force on top of this default (`src/placement.ts`).
|
|
762
|
-
tasksLandIn: '
|
|
797
|
+
tasksLandIn: 'backlog',
|
|
763
798
|
// `intake`-authored specs land STAGED (`pre-proposed/`) by default — the
|
|
764
799
|
// conservative landing that mirrors `tasksLandIn`'s built-in floor: a spec is
|
|
765
800
|
// durable + readable but NOT in the auto-tasking POOL until a human/runner
|
|
@@ -791,7 +826,7 @@ export const DEFAULT_CONFIG: Config = {
|
|
|
791
826
|
// (positive name, default-on).
|
|
792
827
|
freshWorktreeGate: true,
|
|
793
828
|
// The cross-job merge serialiser's CAS-retry cap — the git-alone FLOOR of the
|
|
794
|
-
// land-time cross-job queue (
|
|
829
|
+
// land-time cross-job queue (spec `land-time-reverify-and-parallel-merge-ceiling`,
|
|
795
830
|
// Story 5 + Applied Answer q1 (a)). Matches `integration-core.ts`'s built-in
|
|
796
831
|
// `DEFAULT_MERGE_RETRIES` fallback (1000 — the C2 large liveness ceiling, NOT a
|
|
797
832
|
// small Race-1 budget) so resolving it through this layer is byte-for-byte
|
|
@@ -800,14 +835,71 @@ export const DEFAULT_CONFIG: Config = {
|
|
|
800
835
|
mergeRetries: 1000,
|
|
801
836
|
// The strict-merge-approval gate defaults OFF (sidecar OQ6 / task
|
|
802
837
|
// `strict-merge-approval-gate`): the cheap "green re-verify is enough" path
|
|
803
|
-
// is the default; the OQ6
|
|
838
|
+
// is the default; the OQ6 SPEC answer pins this. A repo opts in to the
|
|
804
839
|
// host-agnostic "dismiss stale approvals on base change" discipline with
|
|
805
840
|
// `strictMergeApproval: true` (or `--strict-merge-approval` /
|
|
806
841
|
// `DORFL_STRICT_MERGE_APPROVAL=true`). The re-surface vs. land branch is
|
|
807
842
|
// `apply-rung-merge-disposition`'s consumer, NOT here.
|
|
808
843
|
strictMergeApproval: false,
|
|
844
|
+
// The dorfl-INTERNAL agent deadline defaults to 60 minutes (spec
|
|
845
|
+
// `graceful-pre-timeout-wip-checkpoint`). A legitimately-long task that runs
|
|
846
|
+
// past this checkpoints its WIP + auto-continues on the next tick (rather than
|
|
847
|
+
// losing everything to a 6h GitHub SIGKILL). MAX 240 (4h); fail-loud outside.
|
|
848
|
+
agentDeadlineMinutes: 60,
|
|
849
|
+
// The GitHub-backstop head-room above the internal deadline defaults to 30
|
|
850
|
+
// minutes: the enumerate job's dynamic `githubTimeout` output is
|
|
851
|
+
// deadline + headroom, so the default GitHub cap is 60 + 30 = 90 (1h30). MIN 10
|
|
852
|
+
// (guarantees the graceful save has room); MAX 60; fail-loud outside.
|
|
853
|
+
checkpointHeadroomMinutes: 30,
|
|
854
|
+
// The auto-continue ceiling defaults to 5 CONSECUTIVE deadline checkpoints;
|
|
855
|
+
// past that the next checkpoint SURFACES to a human (spec
|
|
856
|
+
// `graceful-pre-timeout-wip-checkpoint` anti-loop guard).
|
|
857
|
+
maxAutoCheckpoints: 5,
|
|
809
858
|
};
|
|
810
859
|
|
|
860
|
+
/**
|
|
861
|
+
* Fail-loud range validation for the deadline / backstop / ceiling triple
|
|
862
|
+
* (spec `graceful-pre-timeout-wip-checkpoint`). Called at the two resolution
|
|
863
|
+
* FINAL points (`loadConfig` for the global chain; `resolveRepoConfigFromLoaded`
|
|
864
|
+
* for the per-repo chain), so an out-of-range value from ANY layer (flag / env /
|
|
865
|
+
* per-repo / global) surfaces as a clean throw naming the field + the valid
|
|
866
|
+
* range. Never clamps — the task's decision is fail-loud, since a silently
|
|
867
|
+
* clamped 400-minute deadline would look correct in `dorfl config --json` and
|
|
868
|
+
* quietly break the invariant that GitHub cap > internal deadline.
|
|
869
|
+
*/
|
|
870
|
+
export function validateDeadlineConfig(config: Config): void {
|
|
871
|
+
const adm = config.agentDeadlineMinutes;
|
|
872
|
+
if (!Number.isInteger(adm) || adm < 1 || adm > 240) {
|
|
873
|
+
throw new Error(
|
|
874
|
+
`agentDeadlineMinutes must be a positive integer in [1, 240] ` +
|
|
875
|
+
`(got ${adm}). The dorfl-internal agent deadline caps a single ` +
|
|
876
|
+
`agent session; 240 minutes (4h) is the hard ceiling so the ` +
|
|
877
|
+
`GitHub backstop (deadline + headroom) still fits under GitHub's ` +
|
|
878
|
+
`6h job limit.`,
|
|
879
|
+
);
|
|
880
|
+
}
|
|
881
|
+
const chm = config.checkpointHeadroomMinutes;
|
|
882
|
+
if (!Number.isInteger(chm) || chm < 10 || chm > 60) {
|
|
883
|
+
throw new Error(
|
|
884
|
+
`checkpointHeadroomMinutes must be an integer in [10, 60] ` +
|
|
885
|
+
`(got ${chm}). This is the head-room the GitHub 'timeout-minutes' ` +
|
|
886
|
+
`backstop sits above the internal deadline (rendered dynamically ` +
|
|
887
|
+
`as agentDeadlineMinutes + checkpointHeadroomMinutes by the ` +
|
|
888
|
+
`advance-lifecycle 'enumerate' job); MIN 10 guarantees the ` +
|
|
889
|
+
`graceful save always has room to commit + push before the hard kill.`,
|
|
890
|
+
);
|
|
891
|
+
}
|
|
892
|
+
const cap = config.maxAutoCheckpoints;
|
|
893
|
+
if (!Number.isInteger(cap) || cap < 1) {
|
|
894
|
+
throw new Error(
|
|
895
|
+
`maxAutoCheckpoints must be a positive integer (got ${cap}). ` +
|
|
896
|
+
`It caps CONSECUTIVE deadline auto-continues; past this the ` +
|
|
897
|
+
`next checkpoint surfaces a needs-answers question to a human ` +
|
|
898
|
+
`(the anti-loop guard for the graceful pre-timeout checkpoint).`,
|
|
899
|
+
);
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
|
|
811
903
|
/** The conventional config location (`~/.config/dorfl/config.json`). */
|
|
812
904
|
export function defaultConfigPath(): string {
|
|
813
905
|
return join(homedir(), '.config', brand.configDirName, 'config.json');
|
|
@@ -879,5 +971,7 @@ export function loadConfig(path: string = defaultConfigPath()): Config {
|
|
|
879
971
|
);
|
|
880
972
|
}
|
|
881
973
|
}
|
|
882
|
-
|
|
974
|
+
const merged = mergeConfig(parsed);
|
|
975
|
+
validateDeadlineConfig(merged);
|
|
976
|
+
return merged;
|
|
883
977
|
}
|
package/src/continue-branch.ts
CHANGED
|
@@ -1,6 +1,28 @@
|
|
|
1
1
|
import {run, type RunResult} from './git.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
+
* BROADENED SCOPE NOTE (follow-up task
|
|
5
|
+
* `complete-propose-honour-already-landed-and-rename-continue-branch-module`):
|
|
6
|
+
* this module's name still reads as "continue-branch" (its ORIGINAL role: the
|
|
7
|
+
* continue-detection + rebase-onto-fresh-main helpers used by the onboarding
|
|
8
|
+
* paths, documented below), BUT it now ALSO hosts the shared
|
|
9
|
+
* **stale-lease work-branch push** helpers used by MULTIPLE callers:
|
|
10
|
+
*
|
|
11
|
+
* - {@link pushContinuedBranchWithStaleLeaseRetry} — the original
|
|
12
|
+
* continue/onboard caller (the mirror hub → arbiter reconcile push).
|
|
13
|
+
* - {@link pushProposeBranchWithStaleLeaseRetry} — the propose-mode
|
|
14
|
+
* integrator's push (task `propose-push-survives-stale-lease-on-reaped-work-
|
|
15
|
+
* ref`), which adds the BENIGN already-landed predicate (gone remote ref +
|
|
16
|
+
* work reachable from `<arbiter>/main`) on top of the shared `stale info`
|
|
17
|
+
* retry.
|
|
18
|
+
*
|
|
19
|
+
* A rename to something like `stale-lease-work-push.ts` was considered; the
|
|
20
|
+
* scope-note is preferred here because a rename would churn many imports
|
|
21
|
+
* across `src/` + `test/` for no behavioural gain, and the module already reads
|
|
22
|
+
* as a single conceptual bucket ("the work-branch push + continue-detection
|
|
23
|
+
* helpers"). Add new stale-lease work-ref push helpers here rather than
|
|
24
|
+
* spawning a sibling module.
|
|
25
|
+
*
|
|
4
26
|
* The **continue-detection** shared by BOTH onboarding paths (the keystone of
|
|
5
27
|
* the `requeue-continue-and-reset` task). `requeue` keeps the `work/<slug>`
|
|
6
28
|
* branch so the NEXT claim CONTINUES from its tip instead of force-cutting a
|
|
@@ -156,7 +178,7 @@ export interface ContinueRebaseResult {
|
|
|
156
178
|
* (ADR §10: rebase, NOT merge — linear history; the prior attempt's commits were
|
|
157
179
|
* based on an OLD main that moved while the item sat in backlog).
|
|
158
180
|
*
|
|
159
|
-
* This is a PLAIN rebase. After the per-item-lock cut-over (
|
|
181
|
+
* This is a PLAIN rebase. After the per-item-lock cut-over (spec
|
|
160
182
|
* `ledger-status-per-item-lock-refs`, tasks 9a–9d) NO transient status lands on
|
|
161
183
|
* a work branch: claim does not move the body (it rests in `backlog/`),
|
|
162
184
|
* needs-attention is the lock `state: stuck` (not a `git mv`), and the
|
package/src/cwd-section.ts
CHANGED
|
@@ -268,7 +268,7 @@ export async function resolveCwdSection(
|
|
|
268
268
|
const localReport = scanRepoPaths([cwd], config, heldSlugs, options.override);
|
|
269
269
|
const repo = localReport.repos[0];
|
|
270
270
|
|
|
271
|
-
// 3b. The PER-ITEM LOCK in-flight SURFACE for the cwd (
|
|
271
|
+
// 3b. The PER-ITEM LOCK in-flight SURFACE for the cwd (spec
|
|
272
272
|
// `ledger-status-per-item-lock-refs` US #8). The subtraction above removes a
|
|
273
273
|
// held slug from the eligible `items[]` pool; on its OWN that leaves a
|
|
274
274
|
// held/stuck cwd item in a BLIND SPOT — gone from every bucket with nothing
|
package/src/decision-engine.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {extractJsonObjectSpan} from './verdict-json.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* **The SHARED decision engine** (
|
|
4
|
+
* **The SHARED decision engine** (spec
|
|
5
5
|
* `agentic-question-resolution-retire-disposition-vocabulary` US #9, decision 3 +
|
|
6
6
|
* 13/14; task `decision-engine-shared-decide-seam`): the GENERALISED
|
|
7
7
|
* `decide(input, allowedOutcomes) → verdict` core every question-resolution
|
|
@@ -20,7 +20,7 @@ import {extractJsonObjectSpan} from './verdict-json.js';
|
|
|
20
20
|
* "the INPUT adapter differs per front door and is NOT forced to be shared").
|
|
21
21
|
* - **the ALLOWED-OUTCOME SET** ({@link decide}'s `allowedOutcomes`): each caller
|
|
22
22
|
* passes the SUBSET of {@link DecisionOutcome} it permits — advance-apply allows
|
|
23
|
-
* `{task |
|
|
23
|
+
* `{task | spec | adr | dispose | ask}`, intake keeps its own `{task | spec | ask |
|
|
24
24
|
* bounce}` (intake is NOT refactored onto this engine here — decision 13). The
|
|
25
25
|
* engine never hard-codes which outcomes a caller permits; it only VALIDATES the
|
|
26
26
|
* returned verdict against the set and rejects (loudly) one outside it
|
|
@@ -43,26 +43,47 @@ import {extractJsonObjectSpan} from './verdict-json.js';
|
|
|
43
43
|
* - **adr** — mint an adr from the input (NO caller wires this yet; the keystone's
|
|
44
44
|
* allowed set will, and `agentic-apply-mint-adr-route` adds the route — decision
|
|
45
45
|
* 14 keeps the engine agnostic so this is added without re-architecting).
|
|
46
|
-
* - **
|
|
47
|
-
*
|
|
46
|
+
* - **dispose** — DISPOSE the SOURCE the input is about, POLYMORPHIC on the
|
|
47
|
+
* source's regime (spec `surface-stuck-as-questions-and-retire-stuck-lock-state`
|
|
48
|
+
* resolved decision #5; task
|
|
49
|
+
* `apply-disposition-delete-to-dispose-regime-polymorphic`): an OBSERVATION is
|
|
50
|
+
* `git rm`-ed (notes leave by deletion, decision 12); a TASK is `git mv`-ed to
|
|
51
|
+
* its regime's won't-proceed terminal `tasks/cancelled/` (RETAINED — a task
|
|
52
|
+
* cannot be hard-deleted by the apply rung, only disposed to its terminal); a
|
|
53
|
+
* SPEC is `git mv`-ed to `specs/dropped/` (RETAINED). Making the token
|
|
54
|
+
* polymorphic (rather than adding a second `cancel` beside a literal `delete`)
|
|
55
|
+
* makes "a task cannot be deleted, only disposed to its terminal" true BY
|
|
56
|
+
* CONSTRUCTION.
|
|
57
|
+
* - **resolve** — the answer SETTLES the item with NO artifact to mint and the
|
|
58
|
+
* note RETAINED: route to the apply persist's resolve-fully path (harvest the
|
|
59
|
+
* answers into the body, clear `needsAnswers`, delete the sidecar) so the
|
|
60
|
+
* already-answered question stops re-surfacing. The SIBLING of `dispose` (both
|
|
61
|
+
* end the question-loop minting nothing), but `resolve` KEEPS the note whereas
|
|
62
|
+
* `dispose` drops-or-terminals it (task `apply-decide-resolve-verdict-mint-nothing`).
|
|
48
63
|
* - **ask** — ask the operator a follow-up (re-pause; the conversation
|
|
49
64
|
* accumulates — decision 5).
|
|
50
65
|
*
|
|
51
66
|
* No caller is forced to allow ALL of these: each passes its own SUBSET to
|
|
52
67
|
* {@link decide}. The engine is agnostic to which subset a caller permits.
|
|
53
68
|
*/
|
|
54
|
-
// MIGRATE step (
|
|
55
|
-
// parent-spec verdict outcome is `'spec'` (renamed from
|
|
69
|
+
// MIGRATE step (spec `prd-to-spec-vocabulary-cutover-and-migration-command`): the
|
|
70
|
+
// parent-spec verdict outcome is `'spec'` (renamed from ''prd''); the decider
|
|
56
71
|
// prompt emits it and the parser accepts it. This is a fresh per-call LLM verdict
|
|
57
|
-
// (nothing
|
|
58
|
-
export type DecisionOutcome =
|
|
72
|
+
// (nothing ''prd''-valued is persisted), so the rename needs no on-disk alias.
|
|
73
|
+
export type DecisionOutcome =
|
|
74
|
+
| 'task'
|
|
75
|
+
| 'spec'
|
|
76
|
+
| 'adr'
|
|
77
|
+
| 'dispose'
|
|
78
|
+
| 'resolve'
|
|
79
|
+
| 'ask';
|
|
59
80
|
|
|
60
81
|
/**
|
|
61
82
|
* The VERDICT the decider returns — the chosen {@link DecisionOutcome} plus the
|
|
62
83
|
* DRAFTED content for that outcome (the analogue of {@link IntakeVerdict}). Every
|
|
63
84
|
* content field is OPTIONAL on the shape: a given verdict only fills the channels
|
|
64
85
|
* its outcome consumes (a `task` fills the task channels, an `ask` fills
|
|
65
|
-
* `question`, a `
|
|
86
|
+
* `question`, a `dispose` may carry only a `reason`). The dispatching CALLER
|
|
66
87
|
* decides which channels it requires for each outcome it allows — the engine only
|
|
67
88
|
* guards the `outcome` discriminator against the allowed set, never the content
|
|
68
89
|
* (it stays outcome-agnostic).
|
|
@@ -93,11 +114,24 @@ export interface DecisionVerdict {
|
|
|
93
114
|
/** The drafted adr BODY (`adr` outcome) — the markdown AFTER the frontmatter. */
|
|
94
115
|
adrBody?: string;
|
|
95
116
|
/**
|
|
96
|
-
* The reason the source should be
|
|
97
|
-
*
|
|
98
|
-
*
|
|
117
|
+
* The reason the source should be DISPOSED (`dispose` outcome) — carried by
|
|
118
|
+
* the caller into the regime-polymorphic disposal: an OBSERVATION's reason
|
|
119
|
+
* rides the revertible git-rm commit message (decision 12: notes leave by
|
|
120
|
+
* deletion, git history = archive); a TASK/SPEC's reason is written into the
|
|
121
|
+
* moved item's `reason:` frontmatter so the durable body records why the
|
|
122
|
+
* item won't proceed (the file is RETAINED at the regime's terminal —
|
|
123
|
+
* `tasks/cancelled/` or `specs/dropped/`).
|
|
99
124
|
*/
|
|
100
|
-
|
|
125
|
+
disposeReason?: string;
|
|
126
|
+
/**
|
|
127
|
+
* Why the item is settled with NOTHING to mint (`resolve` outcome) — the
|
|
128
|
+
* SIBLING of {@link disposeReason}, but the note is RETAINED (the apply rung
|
|
129
|
+
* routes this to the resolve-fully path, which harvests the answers into the
|
|
130
|
+
* body rather than deleting the note). The reason is advisory context for the
|
|
131
|
+
* human/reviewer; the durable disposition record is the `## Applied answers`
|
|
132
|
+
* block the resolve-fully path writes.
|
|
133
|
+
*/
|
|
134
|
+
resolveReason?: string;
|
|
101
135
|
/**
|
|
102
136
|
* The drafted follow-up question(s) (`ask` outcome) — the caller appends them
|
|
103
137
|
* to the conversation and re-pauses (decision 5: reuse the existing
|
|
@@ -200,7 +234,7 @@ export async function decide<TInput>(
|
|
|
200
234
|
* object carrying an `"outcome"` field via the SHARED {@link extractJsonObjectSpan}
|
|
201
235
|
* (the same extractor every prompt→verdict→dispatch seam in this package uses —
|
|
202
236
|
* NOT a forked copy), `JSON.parse`s it, and validates the shape:
|
|
203
|
-
* `outcome ∈ {task,spec,adr,
|
|
237
|
+
* `outcome ∈ {task,spec,adr,dispose,resolve,ask}`.
|
|
204
238
|
*
|
|
205
239
|
* This validates the verdict is a WELL-FORMED member of the SUPERSET; the
|
|
206
240
|
* caller-specific allowed-outcome guard ({@link decide}) then rejects one outside
|
|
@@ -235,12 +269,13 @@ export function parseDecisionVerdict(output: string): DecisionVerdict {
|
|
|
235
269
|
outcome !== 'task' &&
|
|
236
270
|
outcome !== 'spec' &&
|
|
237
271
|
outcome !== 'adr' &&
|
|
238
|
-
outcome !== '
|
|
272
|
+
outcome !== 'dispose' &&
|
|
273
|
+
outcome !== 'resolve' &&
|
|
239
274
|
outcome !== 'ask'
|
|
240
275
|
) {
|
|
241
276
|
throw new Error(
|
|
242
|
-
`decision verdict 'outcome' was not one of task|spec|adr|
|
|
243
|
-
|
|
277
|
+
`decision verdict 'outcome' was not one of task|spec|adr|dispose|resolve|ask ` +
|
|
278
|
+
`(got ${JSON.stringify(outcome)}).`,
|
|
244
279
|
);
|
|
245
280
|
}
|
|
246
281
|
// Map the per-outcome fields onto the verdict shape, keeping ONLY the strings
|
|
@@ -264,8 +299,11 @@ export function parseDecisionVerdict(output: string): DecisionVerdict {
|
|
|
264
299
|
...(str(obj.adrSlug) !== undefined ? {adrSlug: str(obj.adrSlug)} : {}),
|
|
265
300
|
...(str(obj.adrTitle) !== undefined ? {adrTitle: str(obj.adrTitle)} : {}),
|
|
266
301
|
...(str(obj.adrBody) !== undefined ? {adrBody: str(obj.adrBody)} : {}),
|
|
267
|
-
...(str(obj.
|
|
268
|
-
? {
|
|
302
|
+
...(str(obj.disposeReason) !== undefined
|
|
303
|
+
? {disposeReason: str(obj.disposeReason)}
|
|
304
|
+
: {}),
|
|
305
|
+
...(str(obj.resolveReason) !== undefined
|
|
306
|
+
? {resolveReason: str(obj.resolveReason)}
|
|
269
307
|
: {}),
|
|
270
308
|
...(str(obj.question) !== undefined ? {question: str(obj.question)} : {}),
|
|
271
309
|
};
|