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/ledger-write.ts
CHANGED
|
@@ -9,6 +9,7 @@ import type {IntegrationMode} from './config.js';
|
|
|
9
9
|
import {
|
|
10
10
|
routeToNeedsAttention,
|
|
11
11
|
returnToBacklog,
|
|
12
|
+
surfaceStuckToNeedsAttention,
|
|
12
13
|
type RouteToNeedsAttentionOptions,
|
|
13
14
|
type RouteToNeedsAttentionResult,
|
|
14
15
|
type ReturnToBacklogOptions,
|
|
@@ -17,11 +18,7 @@ import {
|
|
|
17
18
|
type SurfaceToNeedsAttentionResult,
|
|
18
19
|
type BranchPushOutcome,
|
|
19
20
|
} from './needs-attention.js';
|
|
20
|
-
import {
|
|
21
|
-
markStuckItemLock,
|
|
22
|
-
resumeItemLock,
|
|
23
|
-
type TransitionOutcome,
|
|
24
|
-
} from './item-lock.js';
|
|
21
|
+
import type {NewQuestion} from './sidecar.js';
|
|
25
22
|
|
|
26
23
|
/**
|
|
27
24
|
* The **write half** of the ledger-transition seam (ADR
|
|
@@ -89,9 +86,9 @@ export type LedgerTransitionKind =
|
|
|
89
86
|
| 'tasking'
|
|
90
87
|
| 'advancing'
|
|
91
88
|
/**
|
|
92
|
-
* The **promote** transition (
|
|
89
|
+
* The **promote** transition (spec `staging-pool-position-gate-and-trust-model`,
|
|
93
90
|
* task `pre-backlog-staging-folder-and-promote-step-a`): move a STAGED task
|
|
94
|
-
* `work/
|
|
91
|
+
* `work/tasks/backlog/<slug>.md → work/tasks/ready/<slug>.md` to enter the
|
|
95
92
|
* agent-eligible pool. A durable `main` move, the same category as `requeue`
|
|
96
93
|
* (tree-less CAS via {@link applyTransition}). RUNNER/human-owned — no
|
|
97
94
|
* agent-facing path performs it (governing ADR
|
|
@@ -158,14 +155,15 @@ export interface ApplyCompleteTransitionInput {
|
|
|
158
155
|
export type ApplyCompleteTransitionResult = IntegrateResult;
|
|
159
156
|
|
|
160
157
|
/**
|
|
161
|
-
* A *prepared* NEEDS-ATTENTION transition the caller asks the seam to apply:
|
|
162
|
-
* stuck claimed item
|
|
163
|
-
*
|
|
164
|
-
* any surfaced questions, and an OPTIONAL arbiter to also push the branch
|
|
165
|
-
* NOT *where* the
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
* mirrors {@link RouteToNeedsAttentionOptions} so the
|
|
158
|
+
* A *prepared* NEEDS-ATTENTION transition the caller asks the seam to apply:
|
|
159
|
+
* mark a stuck claimed item on its per-item lock with the reason. Like the
|
|
160
|
+
* other inputs it is storage-agnostic — it names the slug, the reason prose,
|
|
161
|
+
* any surfaced questions, and an OPTIONAL arbiter to also push the work branch
|
|
162
|
+
* to, NOT *where* the surface commits/publishes (the sole strategy decides
|
|
163
|
+
* that: post lock-cutover, a lock amend to `state: stuck` with the reason on
|
|
164
|
+
* the lock entry — no `work/needs-attention/` folder write — plus the optional
|
|
165
|
+
* branch push). This mirrors {@link RouteToNeedsAttentionOptions} so the
|
|
166
|
+
* mechanism stays unchanged.
|
|
169
167
|
*/
|
|
170
168
|
export type ApplyNeedsAttentionTransitionInput = RouteToNeedsAttentionOptions;
|
|
171
169
|
|
|
@@ -174,16 +172,17 @@ export type ApplyNeedsAttentionTransitionInput = RouteToNeedsAttentionOptions;
|
|
|
174
172
|
* move result the folder-native mechanism produces. The RECOVERABLE branch push
|
|
175
173
|
* outcome rides on `branchPush` (the caller reads it rather than assuming
|
|
176
174
|
* "pushed" off the local move). The OBSERVABLE half is now the per-item lock
|
|
177
|
-
* `state: stuck` amend (
|
|
175
|
+
* `state: stuck` amend (spec `ledger-status-per-item-lock-refs`); there is no
|
|
178
176
|
* separate on-`main` surface outcome to report.
|
|
179
177
|
*/
|
|
180
178
|
export type ApplyNeedsAttentionTransitionResult = RouteToNeedsAttentionResult;
|
|
181
179
|
|
|
182
180
|
/**
|
|
183
181
|
* A *prepared* RETURN-TO-BACKLOG transition: re-queue a STUCK item so it can be
|
|
184
|
-
* re-claimed — recovered
|
|
185
|
-
*
|
|
186
|
-
*
|
|
182
|
+
* re-claimed — recovered via its per-item lock on the arbiter (post lock-cutover
|
|
183
|
+
* the body never moved into a status folder; it rests in `backlog/`, so requeue
|
|
184
|
+
* releases/clears the lock rather than moving a `.md`). Covers both a resolved
|
|
185
|
+
* stuck hold and a claim that never surfaced.
|
|
187
186
|
* Storage-agnostic, mirroring {@link ReturnToBacklogOptions}.
|
|
188
187
|
*/
|
|
189
188
|
export type ApplyReturnToBacklogTransitionInput = ReturnToBacklogOptions;
|
|
@@ -198,11 +197,12 @@ export type ApplyReturnToBacklogTransitionResult =
|
|
|
198
197
|
|
|
199
198
|
/**
|
|
200
199
|
* A *prepared* TREE-LESS NEEDS-ATTENTION (surface) transition: surface a stuck
|
|
201
|
-
* AFTER-COMMIT, LEDGER-ONLY item (
|
|
202
|
-
*
|
|
200
|
+
* AFTER-COMMIT, LEDGER-ONLY item (post lock-cutover — mark its per-item lock
|
|
201
|
+
* `state: stuck` with the reason, no `in-progress/ → needs-attention/` folder
|
|
202
|
+
* move) WITHOUT a checkout — the SURFACE-direction sibling of the
|
|
203
203
|
* tree-less requeue, sharing its exact mechanism. The work is ALREADY committed
|
|
204
204
|
* on the kept `work/<slug>` branch (intact on the arbiter, recoverable), so the
|
|
205
|
-
* surface is purely the
|
|
205
|
+
* surface is purely the lock amend + reason — no `pushBranch`, no
|
|
206
206
|
* worktree. Storage-agnostic, mirroring {@link SurfaceToNeedsAttentionOptions}.
|
|
207
207
|
* NOT for the wip-save / gate-failed / agent-failed surfaces (which may carry
|
|
208
208
|
* uncommitted work — those keep {@link applyNeedsAttentionTransition}, the
|
|
@@ -322,21 +322,22 @@ export interface LedgerWriteStrategy {
|
|
|
322
322
|
input: ApplyCompleteTransitionInput,
|
|
323
323
|
): Promise<ApplyCompleteTransitionResult>;
|
|
324
324
|
/**
|
|
325
|
-
* Apply a NEEDS-ATTENTION transition:
|
|
326
|
-
*
|
|
327
|
-
* strategy delegates to the
|
|
328
|
-
* strategy could surface the stuck item elsewhere
|
|
329
|
-
* `
|
|
325
|
+
* Apply a NEEDS-ATTENTION transition: mark a stuck claimed item on its
|
|
326
|
+
* per-item lock with its reason (post lock-cutover — no folder write). The
|
|
327
|
+
* sole strategy delegates to the underlying mechanism unchanged; a future
|
|
328
|
+
* strategy could surface the stuck item elsewhere without
|
|
329
|
+
* `complete.ts`/`run.ts` changing.
|
|
330
330
|
*/
|
|
331
331
|
applyNeedsAttentionTransition(
|
|
332
332
|
input: ApplyNeedsAttentionTransitionInput,
|
|
333
333
|
): Promise<ApplyNeedsAttentionTransitionResult>;
|
|
334
334
|
/**
|
|
335
335
|
* Apply a TREE-LESS NEEDS-ATTENTION (surface) transition: surface a stuck
|
|
336
|
-
* AFTER-COMMIT, LEDGER-ONLY item (
|
|
336
|
+
* AFTER-COMMIT, LEDGER-ONLY item (post lock-cutover — mark its per-item lock
|
|
337
|
+
* `state: stuck`, no `in-progress/ → needs-attention/` folder move) WITHOUT a
|
|
337
338
|
* checkout, reusing the SAME tree-less mechanism `requeue` uses for the reverse
|
|
338
|
-
* direction. The sole strategy delegates to the tree-less surface (
|
|
339
|
-
*
|
|
339
|
+
* direction. The sole strategy delegates to the tree-less surface (a pure lock
|
|
340
|
+
* amend CAS-published to the arbiter's lock ref). NOT
|
|
340
341
|
* for the uncommitted-wip surfaces, which keep {@link
|
|
341
342
|
* applyNeedsAttentionTransition} (the cwd-bound path that can commit wip first).
|
|
342
343
|
*/
|
|
@@ -344,10 +345,11 @@ export interface LedgerWriteStrategy {
|
|
|
344
345
|
input: ApplyTreelessNeedsAttentionTransitionInput,
|
|
345
346
|
): ApplyTreelessNeedsAttentionTransitionResult;
|
|
346
347
|
/**
|
|
347
|
-
* Apply a RETURN-TO-BACKLOG transition: re-queue a STUCK item (
|
|
348
|
-
*
|
|
348
|
+
* Apply a RETURN-TO-BACKLOG transition: re-queue a STUCK item (recovered via
|
|
349
|
+
* its per-item lock on the arbiter — post lock-cutover the body rests in
|
|
350
|
+
* `backlog/`, not a status folder) for
|
|
349
351
|
* re-claiming, routed through the SAME seam. Like `claim`, it is TREE-LESS —
|
|
350
|
-
* the
|
|
352
|
+
* the amend is a compare-and-swap push to the arbiter ref (it never writes the
|
|
351
353
|
* cwd tree).
|
|
352
354
|
*/
|
|
353
355
|
applyReturnToBacklogTransition(
|
|
@@ -630,12 +632,12 @@ export const currentLedgerWrite: LedgerWriteStrategy = {
|
|
|
630
632
|
* bounce its `work/prd-<slug>`, a temp-branch caller pushes NOTHING.)
|
|
631
633
|
*
|
|
632
634
|
* Both halves are ONE operation done in ONE place: it delegates to {@link
|
|
633
|
-
* routeToNeedsAttention}, which
|
|
634
|
-
*
|
|
635
|
-
*
|
|
636
|
-
*
|
|
637
|
-
*
|
|
638
|
-
*
|
|
635
|
+
* routeToNeedsAttention}, which saves the aborted work as a **wip** commit
|
|
636
|
+
* on the work branch (post lock-cutover no `work/needs-attention/` folder
|
|
637
|
+
* write ever fires here) and — when an `arbiter` is given — pushes the work
|
|
638
|
+
* branch (best-effort, branch-parameterised, emptiness-guarded; SURFACE-
|
|
639
|
+
* ONLY when `pushBranch: false`). The OBSERVABLE lock amend rides on
|
|
640
|
+
* {@link bounceToStuckLock} directly below. The seam does NOT strip the arbiter: the same
|
|
639
641
|
* arbiter both publishes the surface (here) AND drives the helper's branch push,
|
|
640
642
|
* so "record stuck" and "save the work" can never drift apart. The human-vs-
|
|
641
643
|
* autonomous gate rides on whether an `arbiter` is given at all (human
|
|
@@ -657,9 +659,10 @@ export const currentLedgerWrite: LedgerWriteStrategy = {
|
|
|
657
659
|
// outage-retried), so the partial work travels cross-machine and a `requeue`
|
|
658
660
|
// continues from the tip. The work-branch push is NOT a `main` write.
|
|
659
661
|
const saved = await routeToNeedsAttention(input);
|
|
660
|
-
const
|
|
662
|
+
const surfaced = await bounceThroughSurface({
|
|
661
663
|
cwd: input.cwd,
|
|
662
664
|
slug: input.slug,
|
|
665
|
+
item: `task:${input.slug}`,
|
|
663
666
|
reason: input.reason,
|
|
664
667
|
questions: input.questions,
|
|
665
668
|
arbiter: input.arbiter,
|
|
@@ -667,11 +670,12 @@ export const currentLedgerWrite: LedgerWriteStrategy = {
|
|
|
667
670
|
note: input.note,
|
|
668
671
|
});
|
|
669
672
|
return {
|
|
670
|
-
// `moved` reflects the OBSERVABLE half (the
|
|
671
|
-
|
|
672
|
-
|
|
673
|
+
// `moved` reflects the OBSERVABLE half (the surface record): the sidecar +
|
|
674
|
+
// `needsAnswers:true` on `<arbiter>/main` (or the human-local no-op).
|
|
675
|
+
moved: surfaced.moved,
|
|
676
|
+
reasonNotMoved: surfaced.reasonNotMoved,
|
|
673
677
|
// The branch push outcome is the honest RECOVERABLE report (`do`/`run` read
|
|
674
|
-
// it).
|
|
678
|
+
// it).
|
|
675
679
|
branchPush: saved.branchPush,
|
|
676
680
|
pushError: saved.pushError,
|
|
677
681
|
};
|
|
@@ -680,7 +684,7 @@ export const currentLedgerWrite: LedgerWriteStrategy = {
|
|
|
680
684
|
/**
|
|
681
685
|
* The return-to-backlog transition under the SAME strategy: re-queue the
|
|
682
686
|
* stuck item by delegating to {@link returnToBacklog}, which moves the slug's
|
|
683
|
-
* current `work/<needs-attention|in-progress>/<slug>.md → work/
|
|
687
|
+
* current `work/<needs-attention|in-progress>/<slug>.md → work/tasks/ready/<slug>.md`
|
|
684
688
|
* TREE-LESSLY — it
|
|
685
689
|
* builds the move off `<arbiter>/main` with plumbing and CAS-publishes it back
|
|
686
690
|
* THROUGH this same write seam (`applyTransition`, the very push+lease+verify
|
|
@@ -693,165 +697,146 @@ export const currentLedgerWrite: LedgerWriteStrategy = {
|
|
|
693
697
|
},
|
|
694
698
|
|
|
695
699
|
/**
|
|
696
|
-
* The tree-less surface transition under the SAME strategy: surface the
|
|
697
|
-
* AFTER-COMMIT, LEDGER-ONLY item by delegating to the tree-less
|
|
698
|
-
*
|
|
699
|
-
*
|
|
700
|
-
*
|
|
701
|
-
*
|
|
702
|
-
* staging/committing in the cwd working tree. The reverse of
|
|
700
|
+
* The tree-less surface transition under the SAME strategy: surface the
|
|
701
|
+
* stuck AFTER-COMMIT, LEDGER-ONLY item by delegating to the tree-less
|
|
702
|
+
* surface — post lock-cutover a pure LOCK AMEND (`state: stuck` with the
|
|
703
|
+
* reason on the lock entry), CAS-published to the arbiter's lock ref via
|
|
704
|
+
* the same push+lease+verify seam `claim`/`requeue` use, never staging or
|
|
705
|
+
* committing in the cwd working tree. The reverse of
|
|
703
706
|
* {@link applyReturnToBacklogTransition}, the same one mechanism.
|
|
704
707
|
*/
|
|
705
708
|
async applyTreelessNeedsAttentionTransition(
|
|
706
709
|
input: ApplyTreelessNeedsAttentionTransitionInput,
|
|
707
710
|
): ApplyTreelessNeedsAttentionTransitionResult {
|
|
708
|
-
//
|
|
709
|
-
// `
|
|
710
|
-
//
|
|
711
|
-
//
|
|
712
|
-
//
|
|
713
|
-
//
|
|
714
|
-
//
|
|
715
|
-
// already
|
|
716
|
-
const
|
|
711
|
+
// PR-2b surface cutover (spec
|
|
712
|
+
// `surface-stuck-as-questions-and-retire-stuck-lock-state`, decision #1): the
|
|
713
|
+
// after-commit / ledger-only surface (continue-push-failure / continue-rebase-
|
|
714
|
+
// conflict) surfaces the item on `<arbiter>/main` (a `stuck`-kind sidecar +
|
|
715
|
+
// `needsAnswers:true` on the item body in ONE commit) THEN releases the per-
|
|
716
|
+
// item lock. Surface-FIRST, release-SECOND, with `main`-authoritative crash
|
|
717
|
+
// recovery inherited from {@link runTreelessLedgerMove}. The recoverable work
|
|
718
|
+
// is already committed on the kept `work/<slug>` branch (intact on the arbiter).
|
|
719
|
+
const surfaced = await bounceThroughSurface({
|
|
717
720
|
cwd: input.cwd,
|
|
718
721
|
slug: input.slug,
|
|
722
|
+
item: `task:${input.slug}`,
|
|
719
723
|
reason: input.reason,
|
|
720
724
|
questions: input.questions,
|
|
721
725
|
arbiter: input.arbiter,
|
|
722
726
|
env: input.env,
|
|
723
727
|
note: input.note,
|
|
724
728
|
});
|
|
725
|
-
return {moved:
|
|
729
|
+
return {moved: surfaced.moved, reasonNotMoved: surfaced.reasonNotMoved};
|
|
726
730
|
},
|
|
727
731
|
|
|
728
732
|
/**
|
|
729
733
|
* The resolve-needs-attention transition under the SAME strategy — satisfying
|
|
730
|
-
* the INTENT "clear the stuck surface + restore
|
|
731
|
-
* the resume lock amend (
|
|
732
|
-
* in-progress
|
|
733
|
-
*
|
|
734
|
-
* there (the item is
|
|
735
|
-
* never-`--force` publish.
|
|
736
|
-
* strategy; the seam's contract is only the intent "clear the surface."
|
|
734
|
+
* the INTENT "clear the stuck surface + restore active." It delegates to
|
|
735
|
+
* the resume lock amend (post lock-cutover — `stuck → active` on the per-item
|
|
736
|
+
* lock, no reverse `needs-attention/ → in-progress/` folder move) and, when an
|
|
737
|
+
* `arbiter` is given, CAS-publishes that lock amend to the arbiter's lock ref —
|
|
738
|
+
* CLEARING the stuck surface there (the item is active again). Same
|
|
739
|
+
* all-or-nothing, never-`--force` publish. The lock-ref amend is a detail of
|
|
740
|
+
* THIS strategy; the seam's contract is only the intent "clear the surface."
|
|
737
741
|
*/
|
|
738
742
|
async applyResolveNeedsAttentionTransition(
|
|
739
|
-
|
|
743
|
+
_input: ApplyResolveNeedsAttentionTransitionInput,
|
|
740
744
|
): Promise<ApplyResolveNeedsAttentionTransitionResult> {
|
|
741
|
-
//
|
|
742
|
-
// `
|
|
743
|
-
//
|
|
744
|
-
//
|
|
745
|
-
//
|
|
746
|
-
//
|
|
747
|
-
//
|
|
748
|
-
|
|
749
|
-
return {moved: true};
|
|
750
|
-
}
|
|
751
|
-
const r = await resumeItemLock({
|
|
752
|
-
item: `task:${input.slug}`,
|
|
753
|
-
cwd: input.cwd,
|
|
754
|
-
arbiter: input.arbiter,
|
|
755
|
-
env: input.env,
|
|
756
|
-
});
|
|
757
|
-
if (r.outcome === 'transitioned') {
|
|
758
|
-
return {moved: true};
|
|
759
|
-
}
|
|
760
|
-
// `wrong-state` (already active — not actually stuck) is tolerated as a no-op
|
|
761
|
-
// success: the item is already in-flight, the caller onboards onto it anyway.
|
|
762
|
-
if (r.outcome === 'wrong-state') {
|
|
763
|
-
return {moved: true};
|
|
764
|
-
}
|
|
765
|
-
return {
|
|
766
|
-
moved: false,
|
|
767
|
-
reasonNotMoved: `could not resume '${input.slug}' (${r.outcome}: ${r.message}).`,
|
|
768
|
-
};
|
|
745
|
+
// Post-`retire-stuck-lock-state`: the `stuck` lock state is retired, so
|
|
746
|
+
// there is no `stuck → active` lock amend to perform. A parked item is
|
|
747
|
+
// now a `needsAnswers:true` pool item on `main` with a sidecar, drained
|
|
748
|
+
// by the apply rung (answer the sidecar), not by a resolve verb. The seam
|
|
749
|
+
// is kept for source compatibility of its remaining legacy callers
|
|
750
|
+
// (start.ts's legacy `needs-attention/` folder branch), where it is a
|
|
751
|
+
// recorded no-op success.
|
|
752
|
+
return {moved: true};
|
|
769
753
|
},
|
|
770
754
|
};
|
|
771
755
|
|
|
772
756
|
/**
|
|
773
|
-
* The SOLE stuck-state RECORD
|
|
774
|
-
* `
|
|
775
|
-
*
|
|
776
|
-
* `
|
|
777
|
-
*
|
|
778
|
-
*
|
|
779
|
-
*
|
|
780
|
-
*
|
|
781
|
-
* bounce
|
|
782
|
-
*
|
|
783
|
-
* The bounce holds the TASK's `implement` lock that `claim` acquired (task
|
|
784
|
-
* `claim-acquires-unified-lock-no-body-move`), so the normal stuck path is a plain
|
|
785
|
-
* `active → stuck` amend (`transitioned`). The OUTCOME MAPPING onto `{moved}`:
|
|
786
|
-
* - `transitioned` — the lock is now stuck (the stuck state is recorded) ⇒
|
|
787
|
-
* `moved: true`.
|
|
788
|
-
* - `wrong-state` — the lock is ALREADY `stuck` (an idempotent re-surface of a
|
|
789
|
-
* still-stuck item) ⇒ `moved: true` (the stuck record stands).
|
|
790
|
-
* - `not-held` — there is NO held lock to amend (an item that predates the
|
|
791
|
-
* lock, or a flow where claim did not acquire) ⇒ `moved: false` honestly: with
|
|
792
|
-
* the folder retired there is no other substrate to record the stuck state on,
|
|
793
|
-
* so the caller reports the bounce did NOT land (retry/resolve) rather than
|
|
794
|
-
* fake a success.
|
|
795
|
-
* - `lost`/`error` — a concurrent CAS race / environment fault ⇒ `moved: false`.
|
|
796
|
-
* - no arbiter — a human local-only `complete` (no arbiter handle): the lock
|
|
797
|
-
* ref lives on the arbiter, so there is no lock to amend; treat as a recorded
|
|
798
|
-
* no-op (`moved: true`) — a human is right there (the same human-vs-autonomous
|
|
799
|
-
* posture the old local-only folder move took). NOTE this records nothing
|
|
800
|
-
* durable, by design: the human is in the loop.
|
|
757
|
+
* The SOLE stuck-state RECORD (PR-2b, spec
|
|
758
|
+
* `surface-stuck-as-questions-and-retire-stuck-lock-state`, user stories 1/3/8,
|
|
759
|
+
* decisions #1/#4): surface the bounced item as a `stuck`-kind sidecar +
|
|
760
|
+
* `needsAnswers:true` on the item body in ONE commit on `<arbiter>/main`, THEN
|
|
761
|
+
* release the per-item lock. Surface-FIRST, release-SECOND — the ordering is
|
|
762
|
+
* load-bearing so a crash between them is recoverable from `main` (the classifier
|
|
763
|
+
* fold in `item-lock.ts` re-derives `cleared-stale` from the main-side truth
|
|
764
|
+
* PR-2a landed). This REPLACES the retired `active → stuck` lock amend: no
|
|
765
|
+
* bounce leaves a `stuck` lock; a bounced item rests as a plain `needsAnswers:true`
|
|
766
|
+
* pool item (`eligible:false` by construction).
|
|
801
767
|
*
|
|
802
|
-
*
|
|
803
|
-
*
|
|
768
|
+
* The OUTCOME MAPPING onto `{moved}`:
|
|
769
|
+
* - `surfaced` — the sidecar + `needsAnswers:true` commit landed on
|
|
770
|
+
* `<arbiter>/main` and the lock was released ⇒ `moved: true`.
|
|
771
|
+
* - `bodyAbsent` — the D1 probe found no body for the item on `main` (a
|
|
772
|
+
* bounce for an item whose body never landed — e.g. a claim that lost/raced).
|
|
773
|
+
* The surface is a CLEAN NO-OP; the lock is STILL released so the bounce is
|
|
774
|
+
* never a dead-end held lock ⇒ `moved: true` (nothing to record, nothing left
|
|
775
|
+
* stuck).
|
|
776
|
+
* - `!surfaced` — the surface commit did NOT land (contention exhausted,
|
|
777
|
+
* item missing on main by explicit path, environment fault) ⇒ `moved: false`
|
|
778
|
+
* with `reasonNotMoved` so the caller reports the honest not-landed state.
|
|
779
|
+
* - no arbiter — a human local-only `complete` (no arbiter handle): the
|
|
780
|
+
* surface primitive requires an arbiter, so this is a recorded no-op (`moved:
|
|
781
|
+
* true`) — a human is right there (the same human-vs-autonomous posture the
|
|
782
|
+
* retired lock amend took). NOTE this records nothing durable, by design.
|
|
804
783
|
*/
|
|
805
|
-
async function
|
|
784
|
+
async function bounceThroughSurface(params: {
|
|
806
785
|
cwd: string;
|
|
807
786
|
slug: string;
|
|
787
|
+
item: string;
|
|
808
788
|
reason: string;
|
|
809
789
|
questions?: string[];
|
|
810
790
|
arbiter?: string;
|
|
811
791
|
env?: NodeJS.ProcessEnv;
|
|
812
792
|
note?: (message: string) => void;
|
|
813
793
|
}): Promise<{moved: boolean; reasonNotMoved?: string}> {
|
|
814
|
-
const {cwd, slug, reason, questions, arbiter, env} = params;
|
|
794
|
+
const {cwd, slug, item, reason, questions, arbiter, env} = params;
|
|
815
795
|
const note = params.note ?? (() => {});
|
|
816
796
|
if (!arbiter) {
|
|
817
|
-
// No arbiter handle ⇒ no
|
|
818
|
-
// the human is right there, so this is a recorded no-op (parity
|
|
819
|
-
// local-only
|
|
797
|
+
// No arbiter handle ⇒ no `<arbiter>/main` to surface on. A human local-only
|
|
798
|
+
// `complete`: the human is right there, so this is a recorded no-op (parity
|
|
799
|
+
// with the retired local-only lock amend that wrote nothing cross-machine).
|
|
820
800
|
note(
|
|
821
|
-
`'${slug}' bounced locally (no arbiter) — the stuck reason is not
|
|
822
|
-
'on
|
|
801
|
+
`'${slug}' bounced locally (no arbiter) — the stuck reason is not surfaced ` +
|
|
802
|
+
'on <arbiter>/main (a human is right here).',
|
|
823
803
|
);
|
|
824
804
|
return {moved: true};
|
|
825
805
|
}
|
|
806
|
+
const asNewQuestions: NewQuestion[] | undefined = questions?.map((q) => ({
|
|
807
|
+
question: q,
|
|
808
|
+
kind: 'stuck' as const,
|
|
809
|
+
}));
|
|
826
810
|
try {
|
|
827
|
-
const r = await
|
|
828
|
-
item: `task:${slug}`,
|
|
829
|
-
reason,
|
|
830
|
-
questions,
|
|
811
|
+
const r = await surfaceStuckToNeedsAttention({
|
|
831
812
|
cwd,
|
|
813
|
+
slug,
|
|
814
|
+
item,
|
|
815
|
+
reason,
|
|
816
|
+
questions: asNewQuestions,
|
|
832
817
|
arbiter,
|
|
833
818
|
env,
|
|
819
|
+
note,
|
|
834
820
|
});
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
821
|
+
if (r.surfaced) {
|
|
822
|
+
note(`Surfaced '${item}' on ${arbiter}/main (stuck): ${reason}`);
|
|
823
|
+
return {moved: true};
|
|
824
|
+
}
|
|
825
|
+
if (r.bodyAbsent) {
|
|
826
|
+
note(
|
|
827
|
+
`'${item}' has no body on ${arbiter}/main — surface skipped as a clean ` +
|
|
828
|
+
'no-op; the lock was still released to avoid a dead-end held lock.',
|
|
829
|
+
);
|
|
842
830
|
return {moved: true};
|
|
843
831
|
}
|
|
844
832
|
const reasonNotMoved =
|
|
845
|
-
r.
|
|
846
|
-
|
|
847
|
-
'the stuck state — the item is not lock-held).'
|
|
848
|
-
: `could not mark the per-item lock for '${slug}' stuck (${r.outcome}: ` +
|
|
849
|
-
`${r.message}).`;
|
|
833
|
+
r.reasonNotSurfaced ??
|
|
834
|
+
`could not surface '${item}' on ${arbiter}/main (unknown reason).`;
|
|
850
835
|
note(reasonNotMoved);
|
|
851
836
|
return {moved: false, reasonNotMoved};
|
|
852
837
|
} catch (err) {
|
|
853
838
|
const reasonNotMoved =
|
|
854
|
-
`could not
|
|
839
|
+
`could not surface '${item}' on ${arbiter}/main ` +
|
|
855
840
|
`(${err instanceof Error ? err.message : String(err)}).`;
|
|
856
841
|
note(reasonNotMoved);
|
|
857
842
|
return {moved: false, reasonNotMoved};
|
package/src/lifecycle-gather.ts
CHANGED
|
@@ -65,8 +65,8 @@ function readSidecarInPlace(
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
/**
|
|
68
|
-
* Collect every `needsAnswers:true` task (from `work/backlog`) +
|
|
69
|
-
* `work/
|
|
68
|
+
* Collect every `needsAnswers:true` task (from `work/backlog`) + spec (from
|
|
69
|
+
* `work/specs`) for the in-place repo, through the read seam (the SAME readers the
|
|
70
70
|
* build-pool scan uses). These are the SURFACE/APPLY candidates this task draws
|
|
71
71
|
* into the selection (today they are build/task-INELIGIBLE, so nothing else
|
|
72
72
|
* surfaces them).
|
|
@@ -89,25 +89,25 @@ function blockedItemsInPlace(
|
|
|
89
89
|
out.push({namespace: 'spec', slug: spec.slug});
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
|
-
// TASKED resting prds (`
|
|
93
|
-
// `surfaceStaging`), because a
|
|
94
|
-
// while resting in `
|
|
95
|
-
// it was TASKED"). This is NOT a staging widening: a tasked
|
|
92
|
+
// TASKED resting prds (`specs/tasked/`) — enumerated UNCONDITIONALLY (NOT behind
|
|
93
|
+
// `surfaceStaging`), because a spec may legitimately carry `needsAnswers:true`
|
|
94
|
+
// while resting in `specs/tasked/` (WORK-CONTRACT "A SPEC that has drifted AFTER
|
|
95
|
+
// it was TASKED"). This is NOT a staging widening: a tasked spec is a durable
|
|
96
96
|
// resting state, like the pool, so it is enumerated like the pool. Routing
|
|
97
97
|
// still respects the gates in `buildLifecyclePools` (an ANSWERED sidecar -> the
|
|
98
98
|
// always-on APPLY pool so the human's answer is never STRANDED; a NO-sidecar
|
|
99
|
-
// tasked
|
|
100
|
-
// tasked
|
|
99
|
+
// tasked spec -> SURFACE, still gated by `surfaceBlockers`). Without this, a
|
|
100
|
+
// tasked spec's answered sidecar is enumerated by no pool and apply never runs
|
|
101
101
|
// on it (observation `tasked-prd-needsanswers-sidecar-stranded-no-apply-pool`).
|
|
102
102
|
for (const spec of read.resolveLocalSpecTasked({repoPath})) {
|
|
103
103
|
if (spec.needsAnswers === true) {
|
|
104
104
|
out.push({namespace: 'spec', slug: spec.slug});
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
|
-
// SURFACE-on-STAGING widening (
|
|
107
|
+
// SURFACE-on-STAGING widening (spec
|
|
108
108
|
// `staging-surface-and-apply-promote-safety` F2): when `surfaceStaging` is
|
|
109
109
|
// ON, the candidate set ADDITIONALLY enumerates `needsAnswers` items resting
|
|
110
|
-
// in STAGING (`tasks/backlog/` + `
|
|
110
|
+
// in STAGING (`tasks/backlog/` + `specs/proposed/`), so a tasked item
|
|
111
111
|
// surfaces its questions BEFORE the human promotes it. BUILD/claim still
|
|
112
112
|
// reads POOL-only (`scoreItems` over `state.ready`); only the surface polarity
|
|
113
113
|
// widens here.
|
|
@@ -136,9 +136,27 @@ export function gatherLifecycleInPlace(input: {
|
|
|
136
136
|
repoPath: string;
|
|
137
137
|
read?: LedgerReadStrategy;
|
|
138
138
|
gates?: LifecyclePoolGates;
|
|
139
|
+
/**
|
|
140
|
+
* The HELD TASK slugs to SUBTRACT from the triage/surface/apply candidate
|
|
141
|
+
* inputs before {@link buildLifecyclePools} routes them (task
|
|
142
|
+
* `in-place-scan-subtracts-held-locked-slugs-from-propose-matrix`).
|
|
143
|
+
*
|
|
144
|
+
* Symmetric to the pool-side subtraction `scoreItems` already runs on
|
|
145
|
+
* `state.ready`: without it, a `needsAnswers` TASK whose per-item lock is
|
|
146
|
+
* currently held (state `active`/`stuck`) still slips into the surface / apply
|
|
147
|
+
* pool, so `scan --json` enumerates a matrix leg for it that then always loses
|
|
148
|
+
* the claim CAS (`claim-cas.ts:127-132`) — reddening the propose tick every
|
|
149
|
+
* cadence for as long as the item is held. Narrowly TASK-scoped (this is what
|
|
150
|
+
* {@link heldTaskSlugs} returns): an observation triage entry / a spec surface
|
|
151
|
+
* entry is NOT filtered here, because the lock ref prefix `task-<slug>` only
|
|
152
|
+
* gates the task namespace. Defaults empty (byte-identical to pre-fix
|
|
153
|
+
* behaviour) so callers who cannot resolve a lock read still work.
|
|
154
|
+
*/
|
|
155
|
+
heldSlugs?: Set<string>;
|
|
139
156
|
}): SelectedLifecyclePools {
|
|
140
157
|
const read = input.read ?? ledgerRead;
|
|
141
158
|
const repoPath = input.repoPath;
|
|
159
|
+
const heldSlugs = input.heldSlugs ?? new Set<string>();
|
|
142
160
|
|
|
143
161
|
const rawObservations = read.resolveLocalState({repoPath}).observations;
|
|
144
162
|
const observations: ObservationCandidate[] = rawObservations.map((obs) => ({
|
|
@@ -151,12 +169,17 @@ export function gatherLifecycleInPlace(input: {
|
|
|
151
169
|
read,
|
|
152
170
|
repoPath,
|
|
153
171
|
surfaceStaging,
|
|
154
|
-
)
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
172
|
+
)
|
|
173
|
+
// Held-slug subtraction (task-scoped): a `needsAnswers` TASK whose per-item
|
|
174
|
+
// lock is currently held is EXCLUDED from surface/apply enumeration. Spec /
|
|
175
|
+
// observation entries are untouched — the lock ref set here is task-only.
|
|
176
|
+
.filter((item) => !(item.namespace === 'task' && heldSlugs.has(item.slug)))
|
|
177
|
+
.map((item) => ({
|
|
178
|
+
repoPath,
|
|
179
|
+
namespace: item.namespace,
|
|
180
|
+
slug: item.slug,
|
|
181
|
+
sidecar: readSidecarInPlace(repoPath, item.namespace, item.slug),
|
|
182
|
+
}));
|
|
160
183
|
|
|
161
184
|
return buildLifecyclePools({
|
|
162
185
|
repoPath,
|
|
@@ -195,7 +218,7 @@ async function readSidecarMirror(
|
|
|
195
218
|
* Gather + build the lifecycle pools for a MIRROR-SIDE bare hub mirror (async).
|
|
196
219
|
* Reads the SAME logical inputs as {@link gatherLifecycleInPlace} \u2014 observations +
|
|
197
220
|
* the `needsAnswers` pool from the mirror's committed `main` (via
|
|
198
|
-
* `resolveMirrorState`), the
|
|
221
|
+
* `resolveMirrorState`), the spec pool via `resolveMirrorSpecPool`, and each item's
|
|
199
222
|
* sidecar via `git show` \u2014 then hands them to the SAME shared
|
|
200
223
|
* {@link buildLifecyclePools}, so the in-place + mirror enumerations AGREE.
|
|
201
224
|
*/
|
|
@@ -232,9 +255,9 @@ export async function gatherLifecycleMirror(input: {
|
|
|
232
255
|
blocked.push({namespace: 'spec', slug: spec.slug});
|
|
233
256
|
}
|
|
234
257
|
}
|
|
235
|
-
// TASKED resting prds (`<ref>:work/
|
|
236
|
-
// the mirror-side counterpart of the in-place tasked-
|
|
237
|
-
// (so a `needsAnswers` tasked
|
|
258
|
+
// TASKED resting prds (`<ref>:work/specs/tasked/`) — enumerated UNCONDITIONALLY,
|
|
259
|
+
// the mirror-side counterpart of the in-place tasked-spec enumeration above
|
|
260
|
+
// (so a `needsAnswers` tasked spec's answered sidecar is never stranded on the
|
|
238
261
|
// mirror/CI advance path either). Routing still respects the gates.
|
|
239
262
|
const specTasked = await read.resolveMirrorSpecTasked({mirrorPath, ref, env});
|
|
240
263
|
for (const spec of specTasked) {
|
|
@@ -242,10 +265,10 @@ export async function gatherLifecycleMirror(input: {
|
|
|
242
265
|
blocked.push({namespace: 'spec', slug: spec.slug});
|
|
243
266
|
}
|
|
244
267
|
}
|
|
245
|
-
// SURFACE-on-STAGING widening (
|
|
268
|
+
// SURFACE-on-STAGING widening (spec
|
|
246
269
|
// `staging-surface-and-apply-promote-safety` F2): mirror-side counterpart of
|
|
247
270
|
// the in-place widening above — enumerate `needsAnswers` items in
|
|
248
|
-
// STAGING (`tasks/backlog/` + `
|
|
271
|
+
// STAGING (`tasks/backlog/` + `specs/proposed/`) from the bare mirror's
|
|
249
272
|
// committed `<ref>` tree, so the in-place + mirror surfaces AGREE. The
|
|
250
273
|
// staging reads are skipped entirely when the gate is OFF (no extra git
|
|
251
274
|
// ls-tree work in the legacy mode).
|