dorfl 0.14.2 → 0.15.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 +17 -16
- package/dist/advance-ci-template.d.ts.map +1 -1
- package/dist/advance-ci-template.js +42 -53
- package/dist/advance-ci-template.js.map +1 -1
- package/dist/advance-drivers.d.ts +8 -0
- package/dist/advance-drivers.d.ts.map +1 -1
- package/dist/advance-drivers.js +28 -4
- package/dist/advance-drivers.js.map +1 -1
- package/dist/advance-isolated.d.ts.map +1 -1
- package/dist/advance-isolated.js +3 -2
- package/dist/advance-isolated.js.map +1 -1
- package/dist/advance-lifecycle-template.d.ts +41 -40
- package/dist/advance-lifecycle-template.d.ts.map +1 -1
- package/dist/advance-lifecycle-template.js +309 -489
- package/dist/advance-lifecycle-template.js.map +1 -1
- package/dist/advance-loop-driver.d.ts.map +1 -1
- package/dist/advance-loop-driver.js +3 -2
- package/dist/advance-loop-driver.js.map +1 -1
- package/dist/advance-treeless-publish.d.ts +31 -0
- package/dist/advance-treeless-publish.d.ts.map +1 -1
- package/dist/advance-treeless-publish.js +40 -0
- package/dist/advance-treeless-publish.js.map +1 -1
- package/dist/advance.d.ts +63 -3
- package/dist/advance.d.ts.map +1 -1
- package/dist/advance.js +80 -12
- package/dist/advance.js.map +1 -1
- package/dist/advancing-lock.d.ts +9 -0
- package/dist/advancing-lock.d.ts.map +1 -1
- package/dist/advancing-lock.js +21 -1
- package/dist/advancing-lock.js.map +1 -1
- package/dist/agent-env.d.ts +61 -0
- package/dist/agent-env.d.ts.map +1 -0
- package/dist/agent-env.js +144 -0
- package/dist/agent-env.js.map +1 -0
- package/dist/agent-stop.d.ts +35 -0
- package/dist/agent-stop.d.ts.map +1 -1
- package/dist/agent-stop.js +62 -0
- package/dist/agent-stop.js.map +1 -1
- package/dist/apply-merge-action.d.ts +76 -34
- package/dist/apply-merge-action.d.ts.map +1 -1
- package/dist/apply-merge-action.js +339 -129
- package/dist/apply-merge-action.js.map +1 -1
- package/dist/apply-stuck-action.js +2 -2
- package/dist/apply-stuck-action.js.map +1 -1
- package/dist/ci-agent-result.d.ts +151 -0
- package/dist/ci-agent-result.d.ts.map +1 -0
- package/dist/ci-agent-result.js +314 -0
- package/dist/ci-agent-result.js.map +1 -0
- package/dist/ci-handoff-apply.d.ts +162 -0
- package/dist/ci-handoff-apply.d.ts.map +1 -0
- package/dist/ci-handoff-apply.js +497 -0
- package/dist/ci-handoff-apply.js.map +1 -0
- package/dist/ci-handoff-format.d.ts +369 -0
- package/dist/ci-handoff-format.d.ts.map +1 -0
- package/dist/ci-handoff-format.js +646 -0
- package/dist/ci-handoff-format.js.map +1 -0
- package/dist/ci-handoff-lfs.d.ts +146 -0
- package/dist/ci-handoff-lfs.d.ts.map +1 -0
- package/dist/ci-handoff-lfs.js +397 -0
- package/dist/ci-handoff-lfs.js.map +1 -0
- package/dist/ci-handoff.d.ts +99 -0
- package/dist/ci-handoff.d.ts.map +1 -0
- package/dist/ci-handoff.js +277 -0
- package/dist/ci-handoff.js.map +1 -0
- package/dist/ci-lock-outputs.d.ts +93 -0
- package/dist/ci-lock-outputs.d.ts.map +1 -0
- package/dist/ci-lock-outputs.js +223 -0
- package/dist/ci-lock-outputs.js.map +1 -0
- package/dist/ci-phase-build.d.ts +178 -0
- package/dist/ci-phase-build.d.ts.map +1 -0
- package/dist/ci-phase-build.js +989 -0
- package/dist/ci-phase-build.js.map +1 -0
- package/dist/ci-phase-driver.d.ts +247 -0
- package/dist/ci-phase-driver.d.ts.map +1 -0
- package/dist/ci-phase-driver.js +370 -0
- package/dist/ci-phase-driver.js.map +1 -0
- package/dist/ci-phase-intake.d.ts +172 -0
- package/dist/ci-phase-intake.d.ts.map +1 -0
- package/dist/ci-phase-intake.js +555 -0
- package/dist/ci-phase-intake.js.map +1 -0
- package/dist/ci-phase-tasking.d.ts +205 -0
- package/dist/ci-phase-tasking.d.ts.map +1 -0
- package/dist/ci-phase-tasking.js +906 -0
- package/dist/ci-phase-tasking.js.map +1 -0
- package/dist/ci-phase-treeless.d.ts +224 -0
- package/dist/ci-phase-treeless.d.ts.map +1 -0
- package/dist/ci-phase-treeless.js +1482 -0
- package/dist/ci-phase-treeless.js.map +1 -0
- package/dist/ci-read-token.d.ts +47 -0
- package/dist/ci-read-token.d.ts.map +1 -0
- package/dist/ci-read-token.js +80 -0
- package/dist/ci-read-token.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +447 -22
- package/dist/cli.js.map +1 -1
- package/dist/close-job-template.d.ts +10 -1
- package/dist/close-job-template.d.ts.map +1 -1
- package/dist/close-job-template.js +46 -14
- package/dist/close-job-template.js.map +1 -1
- package/dist/close-job.d.ts +20 -5
- package/dist/close-job.d.ts.map +1 -1
- package/dist/close-job.js +65 -12
- package/dist/close-job.js.map +1 -1
- package/dist/complete.d.ts.map +1 -1
- package/dist/complete.js +20 -1
- package/dist/complete.js.map +1 -1
- package/dist/config.d.ts +41 -44
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +2 -4
- package/dist/config.js.map +1 -1
- package/dist/continue-branch.d.ts +63 -15
- package/dist/continue-branch.d.ts.map +1 -1
- package/dist/continue-branch.js +75 -8
- package/dist/continue-branch.js.map +1 -1
- package/dist/crashed-run-save.d.ts +73 -0
- package/dist/crashed-run-save.d.ts.map +1 -0
- package/dist/crashed-run-save.js +86 -0
- package/dist/crashed-run-save.js.map +1 -0
- package/dist/cwd-section.d.ts.map +1 -1
- package/dist/cwd-section.js +10 -2
- package/dist/cwd-section.js.map +1 -1
- package/dist/decision-engine.d.ts +10 -0
- package/dist/decision-engine.d.ts.map +1 -1
- package/dist/decision-engine.js.map +1 -1
- package/dist/do-config.d.ts +2 -24
- package/dist/do-config.d.ts.map +1 -1
- package/dist/do-config.js +1 -33
- package/dist/do-config.js.map +1 -1
- package/dist/do.d.ts +149 -1
- package/dist/do.d.ts.map +1 -1
- package/dist/do.js +115 -25
- package/dist/do.js.map +1 -1
- package/dist/dorfl-item-template.d.ts +98 -0
- package/dist/dorfl-item-template.d.ts.map +1 -0
- package/dist/dorfl-item-template.js +504 -0
- package/dist/dorfl-item-template.js.map +1 -0
- package/dist/env-config.d.ts.map +1 -1
- package/dist/env-config.js +7 -5
- package/dist/env-config.js.map +1 -1
- package/dist/frontmatter.d.ts +52 -0
- package/dist/frontmatter.d.ts.map +1 -1
- package/dist/frontmatter.js +136 -2
- package/dist/frontmatter.js.map +1 -1
- package/dist/gc.d.ts +13 -0
- package/dist/gc.d.ts.map +1 -1
- package/dist/gc.js +16 -2
- package/dist/gc.js.map +1 -1
- package/dist/git.d.ts +18 -1
- package/dist/git.d.ts.map +1 -1
- package/dist/git.js +70 -5
- package/dist/git.js.map +1 -1
- package/dist/harness.d.ts +44 -5
- package/dist/harness.d.ts.map +1 -1
- package/dist/harness.js +24 -1
- package/dist/harness.js.map +1 -1
- package/dist/index.d.ts +11 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -3
- package/dist/index.js.map +1 -1
- package/dist/install-ci-action-pins.d.ts +123 -0
- package/dist/install-ci-action-pins.d.ts.map +1 -0
- package/dist/install-ci-action-pins.js +190 -0
- package/dist/install-ci-action-pins.js.map +1 -0
- package/dist/install-ci-actions-pr-creation.d.ts +70 -0
- package/dist/install-ci-actions-pr-creation.d.ts.map +1 -0
- package/dist/install-ci-actions-pr-creation.js +106 -0
- package/dist/install-ci-actions-pr-creation.js.map +1 -0
- package/dist/install-ci-capabilities/dorfl-item.d.ts +12 -0
- package/dist/install-ci-capabilities/dorfl-item.d.ts.map +1 -0
- package/dist/install-ci-capabilities/dorfl-item.js +26 -0
- package/dist/install-ci-capabilities/dorfl-item.js.map +1 -0
- package/dist/install-ci-core.d.ts +155 -37
- package/dist/install-ci-core.d.ts.map +1 -1
- package/dist/install-ci-core.js +304 -200
- package/dist/install-ci-core.js.map +1 -1
- package/dist/install-ci-github.d.ts +47 -2
- package/dist/install-ci-github.d.ts.map +1 -1
- package/dist/install-ci-github.js +113 -1
- package/dist/install-ci-github.js.map +1 -1
- package/dist/install-ci.d.ts +25 -6
- package/dist/install-ci.d.ts.map +1 -1
- package/dist/install-ci.js +72 -36
- package/dist/install-ci.js.map +1 -1
- package/dist/intake-marker.d.ts +6 -1
- package/dist/intake-marker.d.ts.map +1 -1
- package/dist/intake-marker.js.map +1 -1
- package/dist/intake-triage.d.ts.map +1 -1
- package/dist/intake-triage.js +6 -2
- package/dist/intake-triage.js.map +1 -1
- package/dist/intake-trigger-template.d.ts +31 -25
- package/dist/intake-trigger-template.d.ts.map +1 -1
- package/dist/intake-trigger-template.js +107 -292
- package/dist/intake-trigger-template.js.map +1 -1
- package/dist/intake.d.ts +186 -4
- package/dist/intake.d.ts.map +1 -1
- package/dist/intake.js +533 -416
- package/dist/intake.js.map +1 -1
- package/dist/integration-core.d.ts +154 -1
- package/dist/integration-core.d.ts.map +1 -1
- package/dist/integration-core.js +759 -486
- package/dist/integration-core.js.map +1 -1
- package/dist/integrator.d.ts +12 -0
- package/dist/integrator.d.ts.map +1 -1
- package/dist/integrator.js +21 -0
- package/dist/integrator.js.map +1 -1
- package/dist/isolation.d.ts +12 -2
- package/dist/isolation.d.ts.map +1 -1
- package/dist/isolation.js +19 -8
- package/dist/isolation.js.map +1 -1
- package/dist/item-lock.d.ts +93 -11
- package/dist/item-lock.d.ts.map +1 -1
- package/dist/item-lock.js +233 -65
- package/dist/item-lock.js.map +1 -1
- package/dist/land-question-residue.d.ts +58 -0
- package/dist/land-question-residue.d.ts.map +1 -0
- package/dist/land-question-residue.js +95 -0
- package/dist/land-question-residue.js.map +1 -0
- package/dist/lifecycle-gather.d.ts +16 -0
- package/dist/lifecycle-gather.d.ts.map +1 -1
- package/dist/lifecycle-gather.js +54 -6
- package/dist/lifecycle-gather.js.map +1 -1
- package/dist/merge-answer.d.ts +41 -0
- package/dist/merge-answer.d.ts.map +1 -0
- package/dist/merge-answer.js +60 -0
- package/dist/merge-answer.js.map +1 -0
- package/dist/merge-question-surfacer.d.ts +105 -30
- package/dist/merge-question-surfacer.d.ts.map +1 -1
- package/dist/merge-question-surfacer.js +202 -91
- package/dist/merge-question-surfacer.js.map +1 -1
- package/dist/merge-question-tick.d.ts +64 -0
- package/dist/merge-question-tick.d.ts.map +1 -0
- package/dist/merge-question-tick.js +96 -0
- package/dist/merge-question-tick.js.map +1 -0
- package/dist/mint-adr.d.ts.map +1 -1
- package/dist/mint-adr.js +20 -2
- package/dist/mint-adr.js.map +1 -1
- package/dist/needs-attention.d.ts +72 -2
- package/dist/needs-attention.d.ts.map +1 -1
- package/dist/needs-attention.js +275 -38
- package/dist/needs-attention.js.map +1 -1
- package/dist/phase-recorder.d.ts +168 -0
- package/dist/phase-recorder.d.ts.map +1 -0
- package/dist/phase-recorder.js +218 -0
- package/dist/phase-recorder.js.map +1 -0
- package/dist/phase.d.ts +94 -0
- package/dist/phase.d.ts.map +1 -0
- package/dist/phase.js +148 -0
- package/dist/phase.js.map +1 -0
- package/dist/pi-harness.d.ts.map +1 -1
- package/dist/pi-harness.js +19 -6
- package/dist/pi-harness.js.map +1 -1
- package/dist/prepare.d.ts.map +1 -1
- package/dist/prepare.js +4 -0
- package/dist/prepare.js.map +1 -1
- package/dist/prompt.d.ts +4 -0
- package/dist/prompt.d.ts.map +1 -1
- package/dist/prompt.js +48 -1
- package/dist/prompt.js.map +1 -1
- package/dist/protocol/CLAIM-PROTOCOL.md +3 -1
- package/dist/protocol/WORK-CONTRACT.md +1 -1
- package/dist/reap-branches.d.ts +48 -0
- package/dist/reap-branches.d.ts.map +1 -1
- package/dist/reap-branches.js +64 -0
- package/dist/reap-branches.js.map +1 -1
- package/dist/ref-write.d.ts +198 -0
- package/dist/ref-write.d.ts.map +1 -0
- package/dist/ref-write.js +79 -0
- package/dist/ref-write.js.map +1 -0
- package/dist/repo-config.js +8 -8
- package/dist/repo-config.js.map +1 -1
- package/dist/repo-mirror.d.ts +36 -0
- package/dist/repo-mirror.d.ts.map +1 -1
- package/dist/repo-mirror.js +91 -1
- package/dist/repo-mirror.js.map +1 -1
- package/dist/review-verdict.d.ts +1 -1
- package/dist/review-verdict.js +1 -1
- package/dist/run.d.ts +7 -1
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +28 -4
- package/dist/run.js.map +1 -1
- package/dist/scan.d.ts +19 -1
- package/dist/scan.d.ts.map +1 -1
- package/dist/scan.js +21 -8
- package/dist/scan.js.map +1 -1
- package/dist/sidecar.d.ts +14 -0
- package/dist/sidecar.d.ts.map +1 -1
- package/dist/sidecar.js +21 -0
- package/dist/sidecar.js.map +1 -1
- package/dist/single-job-warning.d.ts +63 -0
- package/dist/single-job-warning.d.ts.map +1 -0
- package/dist/single-job-warning.js +110 -0
- package/dist/single-job-warning.js.map +1 -0
- package/dist/skills/setup/protocol/CLAIM-PROTOCOL.md +3 -1
- package/dist/skills/setup/protocol/WORK-CONTRACT.md +1 -1
- package/dist/spec-complete.d.ts +13 -6
- package/dist/spec-complete.d.ts.map +1 -1
- package/dist/spec-complete.js +23 -11
- package/dist/spec-complete.js.map +1 -1
- package/dist/start.d.ts.map +1 -1
- package/dist/start.js +47 -14
- package/dist/start.js.map +1 -1
- package/dist/status.d.ts +12 -0
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +11 -3
- package/dist/status.js.map +1 -1
- package/dist/tasking.d.ts +246 -1
- package/dist/tasking.d.ts.map +1 -1
- package/dist/tasking.js +452 -358
- package/dist/tasking.js.map +1 -1
- package/dist/triage-persist.d.ts.map +1 -1
- package/dist/triage-persist.js +21 -2
- package/dist/triage-persist.js.map +1 -1
- package/dist/verify-workflow-template.d.ts.map +1 -1
- package/dist/verify-workflow-template.js +8 -4
- package/dist/verify-workflow-template.js.map +1 -1
- package/dist/verify.d.ts.map +1 -1
- package/dist/verify.js +4 -0
- package/dist/verify.js.map +1 -1
- package/dist/watch-session.d.ts +42 -13
- package/dist/watch-session.d.ts.map +1 -1
- package/dist/watch-session.js +52 -23
- package/dist/watch-session.js.map +1 -1
- package/dist/work-layout.d.ts +10 -4
- package/dist/work-layout.d.ts.map +1 -1
- package/dist/work-layout.js +11 -3
- package/dist/work-layout.js.map +1 -1
- package/dist/workspace.d.ts +65 -4
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js +159 -11
- package/dist/workspace.js.map +1 -1
- package/package.json +1 -1
- package/src/advance-ci-template.ts +80 -81
- package/src/advance-drivers.ts +45 -6
- package/src/advance-isolated.ts +3 -5
- package/src/advance-lifecycle-template.ts +375 -538
- package/src/advance-loop-driver.ts +3 -5
- package/src/advance-treeless-publish.ts +61 -0
- package/src/advance.ts +145 -15
- package/src/advancing-lock.ts +36 -1
- package/src/agent-env.ts +174 -0
- package/src/agent-stop.ts +81 -0
- package/src/apply-merge-action.ts +401 -154
- package/src/apply-stuck-action.ts +2 -2
- package/src/ci-agent-result.ts +421 -0
- package/src/ci-handoff-apply.ts +737 -0
- package/src/ci-handoff-format.ts +926 -0
- package/src/ci-handoff-lfs.ts +519 -0
- package/src/ci-handoff.ts +392 -0
- package/src/ci-lock-outputs.ts +273 -0
- package/src/ci-phase-build.ts +1328 -0
- package/src/ci-phase-driver.ts +548 -0
- package/src/ci-phase-intake.ts +861 -0
- package/src/ci-phase-tasking.ts +1255 -0
- package/src/ci-phase-treeless.ts +2028 -0
- package/src/ci-read-token.ts +90 -0
- package/src/cli.ts +591 -29
- package/src/close-job-template.ts +52 -15
- package/src/close-job.ts +77 -12
- package/src/complete.ts +19 -1
- package/src/config.ts +43 -48
- package/src/continue-branch.ts +121 -16
- package/src/crashed-run-save.ts +162 -0
- package/src/cwd-section.ts +10 -0
- package/src/decision-engine.ts +10 -0
- package/src/do-config.ts +2 -57
- package/src/do.ts +170 -28
- package/src/dorfl-item-template.ts +556 -0
- package/src/env-config.ts +7 -5
- package/src/frontmatter.ts +155 -2
- package/src/gc.ts +27 -2
- package/src/git.ts +83 -5
- package/src/harness.ts +58 -6
- package/src/index.ts +50 -1
- package/src/install-ci-action-pins.ts +209 -0
- package/src/install-ci-actions-pr-creation.ts +186 -0
- package/src/install-ci-capabilities/dorfl-item.ts +33 -0
- package/src/install-ci-core.ts +388 -233
- package/src/install-ci-github.ts +149 -1
- package/src/install-ci.ts +83 -37
- package/src/intake-marker.ts +6 -1
- package/src/intake-triage.ts +7 -3
- package/src/intake-trigger-template.ts +126 -327
- package/src/intake.ts +725 -544
- package/src/integration-core.ts +975 -523
- package/src/integrator.ts +28 -0
- package/src/isolation.ts +29 -10
- package/src/item-lock.ts +308 -92
- package/src/land-question-residue.ts +122 -0
- package/src/lifecycle-gather.ts +82 -10
- package/src/merge-answer.ts +82 -0
- package/src/merge-question-surfacer.ts +320 -112
- package/src/merge-question-tick.ts +182 -0
- package/src/mint-adr.ts +28 -2
- package/src/needs-attention.ts +350 -42
- package/src/phase-recorder.ts +350 -0
- package/src/phase.ts +177 -0
- package/src/pi-harness.ts +25 -5
- package/src/prepare.ts +4 -0
- package/src/prompt.ts +68 -1
- package/src/reap-branches.ts +107 -0
- package/src/ref-write.ts +324 -0
- package/src/repo-config.ts +8 -8
- package/src/repo-mirror.ts +107 -1
- package/src/review-verdict.ts +1 -1
- package/src/run.ts +47 -6
- package/src/scan.ts +37 -7
- package/src/sidecar.ts +36 -0
- package/src/single-job-warning.ts +135 -0
- package/src/spec-complete.ts +36 -14
- package/src/start.ts +55 -16
- package/src/status.ts +29 -3
- package/src/tasking.ts +593 -378
- package/src/triage-persist.ts +24 -2
- package/src/verify-workflow-template.ts +8 -4
- package/src/verify.ts +4 -0
- package/src/watch-session.ts +86 -28
- package/src/work-layout.ts +11 -3
- package/src/workspace.ts +210 -14
package/dist/item-lock.d.ts
CHANGED
|
@@ -106,7 +106,25 @@ export interface LockEntry {
|
|
|
106
106
|
state: LockState;
|
|
107
107
|
holder: string;
|
|
108
108
|
since: string;
|
|
109
|
+
/**
|
|
110
|
+
* Why a finished build still holds the lock, when it does (task
|
|
111
|
+
* `wire-merge-questions-into-the-advance-tick`, decision 4). Absent on every
|
|
112
|
+
* live hold. See {@link LockKeptFor}.
|
|
113
|
+
*/
|
|
114
|
+
keptFor?: LockKeptFor;
|
|
109
115
|
}
|
|
116
|
+
/**
|
|
117
|
+
* The PROPOSE-KEPT marker a lock entry may carry. `propose-pr`: a propose land
|
|
118
|
+
* pushed the work branch (and opened a PR where the host allows it) but the
|
|
119
|
+
* work is not on `main` yet, so the build's `implement` lock is KEPT HELD
|
|
120
|
+
* "until the PR merges" (task `propose-keep-lock-until-pr-merge`). No build is
|
|
121
|
+
* running under it. It is what lets the merge-question surfacer tell a finished
|
|
122
|
+
* propose build (ask) from a live build (skip), and what the answered-merge
|
|
123
|
+
* lock phase may take over (for the same item) instead of backing off. A lock
|
|
124
|
+
* WITHOUT the marker is a live build, including the rebuild of a bounced task's
|
|
125
|
+
* kept branch, whose tip can already carry the done-move.
|
|
126
|
+
*/
|
|
127
|
+
export type LockKeptFor = 'propose-pr';
|
|
110
128
|
/** Outcome of an acquire attempt. `acquired` = we hold it; `lost` = someone else
|
|
111
129
|
* does (a genuine same-item conflict). `error` = environment/usage. */
|
|
112
130
|
export type AcquireOutcome = 'acquired' | 'lost' | 'error';
|
|
@@ -126,12 +144,12 @@ export interface ReleaseResult {
|
|
|
126
144
|
message: string;
|
|
127
145
|
}
|
|
128
146
|
/**
|
|
129
|
-
* Outcome of an AMEND-style transition (resume-crash-orphan
|
|
147
|
+
* Outcome of an AMEND-style transition (resume-crash-orphan) — the
|
|
130
148
|
* lock-entry STATE MACHINE's interior moves. Post-CONTRACT step (task
|
|
131
149
|
* `retire-stuck-lock-state`) the `mark-stuck` transition + the `wrong-state`
|
|
132
150
|
* verdict are retired with the `stuck` state itself.
|
|
133
151
|
* - `transitioned` — we won the CAS; the entry is now at the target state
|
|
134
|
-
* (or removed, for
|
|
152
|
+
* (or removed, for the crash-orphan clear).
|
|
135
153
|
* - `not-held` — there is no entry to transition (the move's precondition
|
|
136
154
|
* is a held entry; absent ⇒ illegal here).
|
|
137
155
|
* - `lost` — the leased CAS was rejected because a CONCURRENT writer
|
|
@@ -146,7 +164,7 @@ export interface TransitionResult {
|
|
|
146
164
|
entry: string;
|
|
147
165
|
ref: string;
|
|
148
166
|
message: string;
|
|
149
|
-
/** The lock entry AFTER a successful `transitioned` (absent for
|
|
167
|
+
/** The lock entry AFTER a successful `transitioned` (absent for a removal). */
|
|
150
168
|
lock?: LockEntry;
|
|
151
169
|
}
|
|
152
170
|
/**
|
|
@@ -180,6 +198,13 @@ export interface AcquireOptions {
|
|
|
180
198
|
* contention.
|
|
181
199
|
*/
|
|
182
200
|
export declare function acquireItemLock(opts: AcquireOptions): Promise<AcquireResult>;
|
|
201
|
+
/**
|
|
202
|
+
* Lease every release of `item`'s lock on `expectedSha` until the returned
|
|
203
|
+
* function is called: a release then deletes the ref only while it still points
|
|
204
|
+
* at `expectedSha`, and otherwise reports an `error` and leaves it untouched (the
|
|
205
|
+
* lock was re-taken by another run).
|
|
206
|
+
*/
|
|
207
|
+
export declare function leaseLockReleases(item: string, expectedSha: string): () => void;
|
|
183
208
|
export interface ReleaseOptions {
|
|
184
209
|
/** The NAMESPACED item identity (same forms as {@link AcquireOptions.item}). */
|
|
185
210
|
item: string;
|
|
@@ -308,16 +333,53 @@ export interface ResumeOptions {
|
|
|
308
333
|
* sidecar (via the apply rung), not by "resuming" a lock.
|
|
309
334
|
*/
|
|
310
335
|
export declare function resumeItemLock(opts: ResumeOptions): Promise<TransitionResult>;
|
|
336
|
+
export interface MarkProposeKeptOptions {
|
|
337
|
+
/** The NAMESPACED item identity (same forms as {@link AcquireOptions.item}). */
|
|
338
|
+
item: string;
|
|
339
|
+
cwd: string;
|
|
340
|
+
arbiter?: string;
|
|
341
|
+
/**
|
|
342
|
+
* The lock sha the caller holds (the CI apply phase's `lockSha`). When set,
|
|
343
|
+
* the mark is refused (`lost`) unless the ref still points at it. Unset: the
|
|
344
|
+
* current sha is read and leased on (the laptop `complete`, which holds the
|
|
345
|
+
* lock it claimed).
|
|
346
|
+
*/
|
|
347
|
+
expectedSha?: string;
|
|
348
|
+
env?: NodeJS.ProcessEnv;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* STAMP the {@link LockKeptFor} `propose-pr` marker on a held lock (task
|
|
352
|
+
* `wire-merge-questions-into-the-advance-tick`, decision 4): a propose land
|
|
353
|
+
* that keeps the build's lock held "until the PR merges" calls this, so the lock
|
|
354
|
+
* says it is kept for a propose PR and no longer covers a live build. The entry
|
|
355
|
+
* keeps its `action`, `holder` and `since`; the ref is replaced by a leased CAS
|
|
356
|
+
* (never forced), so a concurrent change is `lost`. Idempotent: a lock that
|
|
357
|
+
* already carries the marker is `transitioned` without a write.
|
|
358
|
+
*/
|
|
359
|
+
export declare function markLockKeptForProposePr(opts: MarkProposeKeptOptions): Promise<TransitionResult>;
|
|
360
|
+
export interface TakeOverProposeKeptOptions {
|
|
361
|
+
/** The NAMESPACED item identity (same forms as {@link AcquireOptions.item}). */
|
|
362
|
+
item: string;
|
|
363
|
+
/** The action the taken-over lock is held for (the answered merge: `advance`). */
|
|
364
|
+
action: LockAction;
|
|
365
|
+
cwd: string;
|
|
366
|
+
arbiter?: string;
|
|
367
|
+
holder?: string;
|
|
368
|
+
env?: NodeJS.ProcessEnv;
|
|
369
|
+
}
|
|
311
370
|
/**
|
|
312
|
-
*
|
|
313
|
-
*
|
|
314
|
-
*
|
|
315
|
-
*
|
|
316
|
-
* `
|
|
317
|
-
*
|
|
318
|
-
*
|
|
371
|
+
* TAKE OVER a lock that a finished propose build of the SAME item keeps held
|
|
372
|
+
* (task `wire-merge-questions-into-the-advance-tick`, decisions 2 and 4): the
|
|
373
|
+
* answered-merge lock phase calls this when the create-only acquire found the
|
|
374
|
+
* item locked. It succeeds ONLY when the held entry carries the
|
|
375
|
+
* {@link LockKeptFor} `propose-pr` marker and was taken for `implement` (the
|
|
376
|
+
* propose build's own claim); the ref is then replaced, leased on the sha read,
|
|
377
|
+
* by a fresh `action` hold without the marker, so the rest of the run owns it
|
|
378
|
+
* exactly like a lock it created. Any other held lock (a live build, a tasking,
|
|
379
|
+
* another advance) is `lost`, as the plain acquire reports it. A lock released
|
|
380
|
+
* meanwhile falls back to the plain create-only acquire.
|
|
319
381
|
*/
|
|
320
|
-
export declare function
|
|
382
|
+
export declare function takeOverProposeKeptLock(opts: TakeOverProposeKeptOptions): Promise<AcquireResult>;
|
|
321
383
|
/**
|
|
322
384
|
* Read the current lock entry for an item from the arbiter (the `status`/`scan`
|
|
323
385
|
* read path): fetch the lock refs, read `lock.md` from the ref's tree. Returns
|
|
@@ -839,6 +901,26 @@ export declare function heldTaskSlugs(cwd: string, arbiter?: string, env?: NodeJ
|
|
|
839
901
|
* read-only surface keeps the graceful {@link heldTaskSlugs}.
|
|
840
902
|
*/
|
|
841
903
|
export declare function heldTaskSlugsStrict(cwd: string, arbiter?: string, env?: NodeJS.ProcessEnv): Promise<Set<string>>;
|
|
904
|
+
/**
|
|
905
|
+
* STRICT (fail-CLOSED) twin of {@link listItemLockEntries}: THROWS when the
|
|
906
|
+
* lock refs cannot be read (the same fetch {@link listItemLocks} does), so a
|
|
907
|
+
* caller that ACTS on the absence of a lock (the merge-question surfacer asks
|
|
908
|
+
* about a branch only when no live build holds its item) never mistakes an
|
|
909
|
+
* unreadable arbiter for "no locks". A held ref whose body does not parse is
|
|
910
|
+
* returned as a plain `implement` hold without the marker (a live build: the
|
|
911
|
+
* safe reading).
|
|
912
|
+
*/
|
|
913
|
+
export declare function listItemLockEntriesStrict(cwd: string, arbiter?: string, env?: NodeJS.ProcessEnv): Promise<LockEntry[]>;
|
|
914
|
+
/**
|
|
915
|
+
* The TASK slugs whose lock a finished propose build keeps held, i.e. whose
|
|
916
|
+
* entry carries the {@link LockKeptFor} `propose-pr` marker (task
|
|
917
|
+
* `wire-merge-questions-into-the-advance-tick`, decision 6). Selection uses it
|
|
918
|
+
* to let an answered `merge` through the held-slug subtraction; the
|
|
919
|
+
* merge-question surfacer to tell a finished propose build from a live one.
|
|
920
|
+
* GRACEFUL: a read fault yields an empty set, so a held lock keeps excluding
|
|
921
|
+
* its item (the safe direction).
|
|
922
|
+
*/
|
|
923
|
+
export declare function proposeKeptTaskSlugs(cwd: string, arbiter?: string, env?: NodeJS.ProcessEnv): Promise<Set<string>>;
|
|
842
924
|
/**
|
|
843
925
|
* List the SPEC slugs currently lock-held on the arbiter — the held-SPEC set the
|
|
844
926
|
* TASKABLE-spec pool readers SUBTRACT (fix
|
package/dist/item-lock.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"item-lock.d.ts","sourceRoot":"","sources":["../src/item-lock.ts"],"names":[],"mappings":"AACA,OAAO,EAAW,KAAK,SAAS,EAAC,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"item-lock.d.ts","sourceRoot":"","sources":["../src/item-lock.ts"],"names":[],"mappings":"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"}
|
package/dist/item-lock.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
2
|
import { runAsync } from './git.js';
|
|
3
|
+
import { refWrite } from './ref-write.js';
|
|
3
4
|
import { resolveSidecarIdentity, sidecarPathFor, } from './sidecar.js';
|
|
4
5
|
import { parseFrontmatter } from './frontmatter.js';
|
|
5
6
|
import { workItemRel } from './work-layout.js';
|
|
@@ -114,9 +115,12 @@ export function serialiseLockEntry(e) {
|
|
|
114
115
|
`state: ${e.state}`,
|
|
115
116
|
`holder: ${e.holder}`,
|
|
116
117
|
`since: ${e.since}`,
|
|
118
|
+
...(e.keptFor === undefined ? [] : [`keptFor: ${e.keptFor}`]),
|
|
117
119
|
'---',
|
|
118
120
|
'',
|
|
119
|
-
|
|
121
|
+
e.keptFor === undefined
|
|
122
|
+
? `Lock held for \`${e.entry}\` (${e.action}/${e.state}).`
|
|
123
|
+
: `Lock kept for \`${e.entry}\` (${e.action}/${e.state}, ${e.keptFor}): the build finished; its work is not on main yet.`,
|
|
120
124
|
'',
|
|
121
125
|
].join('\n');
|
|
122
126
|
}
|
|
@@ -184,7 +188,7 @@ export async function acquireItemLock(opts) {
|
|
|
184
188
|
since: new Date().toISOString(),
|
|
185
189
|
}, cwd, env);
|
|
186
190
|
// CREATE-ONLY push: --force-with-lease=<ref>: (empty) succeeds iff ref absent.
|
|
187
|
-
const push = await
|
|
191
|
+
const push = await refWrite.createLockRef({ arbiter, ref, commit, cwd, env });
|
|
188
192
|
if (push.status === 0) {
|
|
189
193
|
return { outcome: 'acquired', entry, ref, message: `locked ${entry}` };
|
|
190
194
|
}
|
|
@@ -232,6 +236,39 @@ export async function acquireItemLock(opts) {
|
|
|
232
236
|
};
|
|
233
237
|
}
|
|
234
238
|
}
|
|
239
|
+
/**
|
|
240
|
+
* Lock refs whose release is LEASED on a known sha: `<ref>` → the sha this
|
|
241
|
+
* process last observed for it (spec `ci-agent-job-without-write-token` §8, the
|
|
242
|
+
* lock-ownership rule; task `ci-split-build-path-non-integrate-intents`).
|
|
243
|
+
*
|
|
244
|
+
* The CI apply phase holds the lock the lock JOB took, and every CI run's lock
|
|
245
|
+
* `holder` is the same bot, so only the sha tells runs apart. Its releases are
|
|
246
|
+
* reached from deep inside the reused write halves (the surface, the
|
|
247
|
+
* return-to-backlog, the land's needs-attention routes), which do not carry the
|
|
248
|
+
* sha, so the apply phase registers it here for its whole run
|
|
249
|
+
* ({@link leaseLockReleases}) and {@link releaseLockEntry} refuses to delete a
|
|
250
|
+
* lock that no longer points at it. Process-global for the same reason the
|
|
251
|
+
* phase is (`phase.ts`): a phase run is a one-shot process. Empty outside the
|
|
252
|
+
* apply phase, where every release behaves exactly as before.
|
|
253
|
+
*/
|
|
254
|
+
const releaseLeases = new Map();
|
|
255
|
+
/**
|
|
256
|
+
* Lease every release of `item`'s lock on `expectedSha` until the returned
|
|
257
|
+
* function is called: a release then deletes the ref only while it still points
|
|
258
|
+
* at `expectedSha`, and otherwise reports an `error` and leaves it untouched (the
|
|
259
|
+
* lock was re-taken by another run).
|
|
260
|
+
*/
|
|
261
|
+
export function leaseLockReleases(item, expectedSha) {
|
|
262
|
+
const ref = itemLockRef(lockEntryFor(item));
|
|
263
|
+
const previous = releaseLeases.get(ref);
|
|
264
|
+
releaseLeases.set(ref, expectedSha);
|
|
265
|
+
return () => {
|
|
266
|
+
if (previous === undefined)
|
|
267
|
+
releaseLeases.delete(ref);
|
|
268
|
+
else
|
|
269
|
+
releaseLeases.set(ref, previous);
|
|
270
|
+
};
|
|
271
|
+
}
|
|
235
272
|
/**
|
|
236
273
|
* Release the per-item lock by DELETING the ref (`git push <arbiter>
|
|
237
274
|
* :refs/dorfl/lock/<entry>`). Deleting (not emptying) is what makes the
|
|
@@ -280,7 +317,23 @@ async function releaseLockEntry(entry, cwd, arbiter, env) {
|
|
|
280
317
|
// Delete the ref on the arbiter. Lease on the current value guards against a
|
|
281
318
|
// concurrent change between our fetch and the delete.
|
|
282
319
|
const cur = (await gitHard(['rev-parse', ref], cwd, env)).stdout.trim();
|
|
283
|
-
const
|
|
320
|
+
const lease = releaseLeases.get(ref);
|
|
321
|
+
if (lease !== undefined && lease !== cur) {
|
|
322
|
+
return {
|
|
323
|
+
outcome: 'error',
|
|
324
|
+
entry,
|
|
325
|
+
ref,
|
|
326
|
+
message: `not released: ${ref} now points at ${cur}, not the leased ` +
|
|
327
|
+
`${lease} (another run holds the lock now)`,
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
const del = await refWrite.deleteLockRef({
|
|
331
|
+
arbiter,
|
|
332
|
+
ref,
|
|
333
|
+
expectedSha: cur,
|
|
334
|
+
cwd,
|
|
335
|
+
env,
|
|
336
|
+
});
|
|
284
337
|
if (del.status === 0) {
|
|
285
338
|
// Drop our local copy of the ref too (best-effort).
|
|
286
339
|
await gitSoft(['update-ref', '-d', ref], cwd, env);
|
|
@@ -374,7 +427,7 @@ export async function releaseHeldItemLock(opts) {
|
|
|
374
427
|
/**
|
|
375
428
|
* Fetch the lock refs and return the held entry + its current ref sha, or
|
|
376
429
|
* `undefined` when the item is at REST (no ref). Shared read-before-CAS step for
|
|
377
|
-
* the amend-style transitions (
|
|
430
|
+
* the amend-style transitions (resume): they need BOTH
|
|
378
431
|
* the current entry (to check the state precondition + carry forward `action` /
|
|
379
432
|
* `holder` / `since`) and the current sha (to lease the CAS on it).
|
|
380
433
|
*/
|
|
@@ -402,40 +455,6 @@ async function fetchHeldEntry(entry, ref, cwd, arbiter, env) {
|
|
|
402
455
|
}
|
|
403
456
|
return { lock, sha };
|
|
404
457
|
}
|
|
405
|
-
/**
|
|
406
|
-
* AMEND the held entry in place via a leased CAS: build a NEW parentless commit
|
|
407
|
-
* carrying `next` and push it to the SAME ref with `--force-with-lease=<ref>:<sha>`
|
|
408
|
-
* (the sha we just read). The arbiter accepts ONLY if the ref is unchanged since
|
|
409
|
-
* our read — a concurrent writer who moved it makes our lease fail (`lost`). No
|
|
410
|
-
* retry loop: a rejection is a genuine same-item race the caller should lose.
|
|
411
|
-
*/
|
|
412
|
-
async function amendHeldEntry(next, ref, expectedSha, cwd, arbiter, env) {
|
|
413
|
-
const commit = await buildLockCommit(next, cwd, env);
|
|
414
|
-
const push = await gitSoft([
|
|
415
|
-
'push',
|
|
416
|
-
arbiter,
|
|
417
|
-
`${commit}:${ref}`,
|
|
418
|
-
`--force-with-lease=${ref}:${expectedSha}`,
|
|
419
|
-
], cwd, env);
|
|
420
|
-
if (push.status === 0) {
|
|
421
|
-
// Move our local copy to the new commit too (best-effort) so a subsequent
|
|
422
|
-
// read in the same clone sees the amended entry without a refetch.
|
|
423
|
-
await gitSoft(['update-ref', ref, commit], cwd, env);
|
|
424
|
-
return {
|
|
425
|
-
outcome: 'transitioned',
|
|
426
|
-
entry: next.entry,
|
|
427
|
-
ref,
|
|
428
|
-
message: `${next.entry} → ${next.action}/${next.state}`,
|
|
429
|
-
lock: next,
|
|
430
|
-
};
|
|
431
|
-
}
|
|
432
|
-
return {
|
|
433
|
-
outcome: 'lost',
|
|
434
|
-
entry: next.entry,
|
|
435
|
-
ref,
|
|
436
|
-
message: `'${next.entry}' lock changed concurrently (CAS lost). Back off.`,
|
|
437
|
-
};
|
|
438
|
-
}
|
|
439
458
|
/**
|
|
440
459
|
* The ONE leased-delete CLEAR path shared by every code path that removes a held
|
|
441
460
|
* lock ref by lease (the recovery {@link reconcileItemLockAgainstMain}, the
|
|
@@ -448,13 +467,13 @@ async function amendHeldEntry(next, ref, expectedSha, cwd, arbiter, env) {
|
|
|
448
467
|
* is no second clear mechanism.
|
|
449
468
|
*/
|
|
450
469
|
async function leasedDeleteLockRef(ref, expectedSha, cwd, arbiter, env) {
|
|
451
|
-
const del = await
|
|
452
|
-
'push',
|
|
470
|
+
const del = await refWrite.deleteLockRef({
|
|
453
471
|
arbiter,
|
|
454
|
-
'--delete',
|
|
455
472
|
ref,
|
|
456
|
-
|
|
457
|
-
|
|
473
|
+
expectedSha,
|
|
474
|
+
cwd,
|
|
475
|
+
env,
|
|
476
|
+
});
|
|
458
477
|
if (del.status !== 0) {
|
|
459
478
|
return 'lost';
|
|
460
479
|
}
|
|
@@ -573,18 +592,17 @@ export async function resumeItemLock(opts) {
|
|
|
573
592
|
}
|
|
574
593
|
}
|
|
575
594
|
/**
|
|
576
|
-
*
|
|
577
|
-
* the
|
|
578
|
-
*
|
|
579
|
-
*
|
|
580
|
-
*
|
|
581
|
-
*
|
|
582
|
-
*
|
|
595
|
+
* STAMP the {@link LockKeptFor} `propose-pr` marker on a held lock (task
|
|
596
|
+
* `wire-merge-questions-into-the-advance-tick`, decision 4): a propose land
|
|
597
|
+
* that keeps the build's lock held "until the PR merges" calls this, so the lock
|
|
598
|
+
* says it is kept for a propose PR and no longer covers a live build. The entry
|
|
599
|
+
* keeps its `action`, `holder` and `since`; the ref is replaced by a leased CAS
|
|
600
|
+
* (never forced), so a concurrent change is `lost`. Idempotent: a lock that
|
|
601
|
+
* already carries the marker is `transitioned` without a write.
|
|
583
602
|
*/
|
|
584
|
-
export async function
|
|
603
|
+
export async function markLockKeptForProposePr(opts) {
|
|
585
604
|
const arbiter = opts.arbiter ?? 'origin';
|
|
586
|
-
const env = opts
|
|
587
|
-
const cwd = opts.cwd;
|
|
605
|
+
const { cwd, env } = opts;
|
|
588
606
|
if (!opts.item) {
|
|
589
607
|
return { outcome: 'error', entry: '', ref: '', message: 'missing item' };
|
|
590
608
|
}
|
|
@@ -597,30 +615,135 @@ export async function requeueItemLock(opts) {
|
|
|
597
615
|
outcome: 'not-held',
|
|
598
616
|
entry,
|
|
599
617
|
ref,
|
|
600
|
-
message: `'${entry}' not locked`,
|
|
618
|
+
message: `'${entry}' not locked; nothing to mark`,
|
|
619
|
+
};
|
|
620
|
+
}
|
|
621
|
+
if (opts.expectedSha !== undefined && held.sha !== opts.expectedSha) {
|
|
622
|
+
return {
|
|
623
|
+
outcome: 'lost',
|
|
624
|
+
entry,
|
|
625
|
+
ref,
|
|
626
|
+
message: `'${entry}' now points at ${held.sha}, not ${opts.expectedSha}; not marked`,
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
if (held.lock.keptFor === 'propose-pr') {
|
|
630
|
+
return {
|
|
631
|
+
outcome: 'transitioned',
|
|
632
|
+
entry,
|
|
633
|
+
ref,
|
|
634
|
+
message: `'${entry}' is already kept for a propose PR`,
|
|
635
|
+
lock: held.lock,
|
|
601
636
|
};
|
|
602
637
|
}
|
|
603
|
-
const
|
|
604
|
-
|
|
638
|
+
const lock = { ...held.lock, keptFor: 'propose-pr' };
|
|
639
|
+
const commit = await buildLockCommit(lock, cwd, env);
|
|
640
|
+
const push = await refWrite.replaceLockRef({
|
|
605
641
|
arbiter,
|
|
606
|
-
'--delete',
|
|
607
642
|
ref,
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
643
|
+
commit,
|
|
644
|
+
expectedSha: held.sha,
|
|
645
|
+
cwd,
|
|
646
|
+
env,
|
|
647
|
+
});
|
|
648
|
+
if (push.status !== 0) {
|
|
612
649
|
return {
|
|
613
|
-
outcome: '
|
|
650
|
+
outcome: 'lost',
|
|
614
651
|
entry,
|
|
615
652
|
ref,
|
|
616
|
-
message: `
|
|
653
|
+
message: `marking '${entry}' kept for a propose PR was rejected: ${push.stderr.trim()}`,
|
|
617
654
|
};
|
|
618
655
|
}
|
|
619
656
|
return {
|
|
620
|
-
outcome: '
|
|
657
|
+
outcome: 'transitioned',
|
|
658
|
+
entry,
|
|
659
|
+
ref,
|
|
660
|
+
message: `marked '${entry}' kept for a propose PR`,
|
|
661
|
+
lock,
|
|
662
|
+
};
|
|
663
|
+
}
|
|
664
|
+
catch (err) {
|
|
665
|
+
return {
|
|
666
|
+
outcome: 'error',
|
|
667
|
+
entry,
|
|
668
|
+
ref,
|
|
669
|
+
message: err instanceof Error ? err.message : String(err),
|
|
670
|
+
};
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
/**
|
|
674
|
+
* TAKE OVER a lock that a finished propose build of the SAME item keeps held
|
|
675
|
+
* (task `wire-merge-questions-into-the-advance-tick`, decisions 2 and 4): the
|
|
676
|
+
* answered-merge lock phase calls this when the create-only acquire found the
|
|
677
|
+
* item locked. It succeeds ONLY when the held entry carries the
|
|
678
|
+
* {@link LockKeptFor} `propose-pr` marker and was taken for `implement` (the
|
|
679
|
+
* propose build's own claim); the ref is then replaced, leased on the sha read,
|
|
680
|
+
* by a fresh `action` hold without the marker, so the rest of the run owns it
|
|
681
|
+
* exactly like a lock it created. Any other held lock (a live build, a tasking,
|
|
682
|
+
* another advance) is `lost`, as the plain acquire reports it. A lock released
|
|
683
|
+
* meanwhile falls back to the plain create-only acquire.
|
|
684
|
+
*/
|
|
685
|
+
export async function takeOverProposeKeptLock(opts) {
|
|
686
|
+
const arbiter = opts.arbiter ?? 'origin';
|
|
687
|
+
const { cwd, env } = opts;
|
|
688
|
+
if (!opts.item) {
|
|
689
|
+
return { outcome: 'error', entry: '', ref: '', message: 'missing item' };
|
|
690
|
+
}
|
|
691
|
+
const entry = lockEntryFor(opts.item);
|
|
692
|
+
const ref = itemLockRef(entry);
|
|
693
|
+
try {
|
|
694
|
+
const held = await fetchHeldEntry(entry, ref, cwd, arbiter, env);
|
|
695
|
+
if (!held) {
|
|
696
|
+
return acquireItemLock({
|
|
697
|
+
item: opts.item,
|
|
698
|
+
action: opts.action,
|
|
699
|
+
cwd,
|
|
700
|
+
arbiter,
|
|
701
|
+
holder: opts.holder,
|
|
702
|
+
env,
|
|
703
|
+
});
|
|
704
|
+
}
|
|
705
|
+
if (held.lock.keptFor !== 'propose-pr' ||
|
|
706
|
+
held.lock.action !== 'implement' ||
|
|
707
|
+
held.lock.entry !== entry) {
|
|
708
|
+
return {
|
|
709
|
+
outcome: 'lost',
|
|
710
|
+
entry,
|
|
711
|
+
ref,
|
|
712
|
+
message: `'${entry}' is already locked (${held.lock.action}, not kept for a ` +
|
|
713
|
+
'propose PR): a live hold is never taken over. Back off.',
|
|
714
|
+
};
|
|
715
|
+
}
|
|
716
|
+
const holder = opts.holder ?? (await resolveHolder(cwd, env));
|
|
717
|
+
const commit = await buildLockCommit({
|
|
718
|
+
entry,
|
|
719
|
+
action: opts.action,
|
|
720
|
+
state: 'active',
|
|
721
|
+
holder,
|
|
722
|
+
since: new Date().toISOString(),
|
|
723
|
+
}, cwd, env);
|
|
724
|
+
const push = await refWrite.replaceLockRef({
|
|
725
|
+
arbiter,
|
|
726
|
+
ref,
|
|
727
|
+
commit,
|
|
728
|
+
expectedSha: held.sha,
|
|
729
|
+
cwd,
|
|
730
|
+
env,
|
|
731
|
+
});
|
|
732
|
+
if (push.status !== 0) {
|
|
733
|
+
return {
|
|
734
|
+
outcome: 'lost',
|
|
735
|
+
entry,
|
|
736
|
+
ref,
|
|
737
|
+
message: `taking over '${entry}' lost the race: ${push.stderr.trim()}`,
|
|
738
|
+
};
|
|
739
|
+
}
|
|
740
|
+
// Keep the local copy in step, as the create-only acquire's fetch would.
|
|
741
|
+
await gitSoft(['update-ref', ref, commit], cwd, env);
|
|
742
|
+
return {
|
|
743
|
+
outcome: 'acquired',
|
|
621
744
|
entry,
|
|
622
745
|
ref,
|
|
623
|
-
message: `'${entry}'
|
|
746
|
+
message: `took over '${entry}' from its finished propose build (kept for a propose PR)`,
|
|
624
747
|
};
|
|
625
748
|
}
|
|
626
749
|
catch (err) {
|
|
@@ -1756,6 +1879,47 @@ export async function heldTaskSlugsStrict(cwd, arbiter = 'origin', env) {
|
|
|
1756
1879
|
.filter((e) => e.startsWith(prefix))
|
|
1757
1880
|
.map((e) => e.slice(prefix.length)));
|
|
1758
1881
|
}
|
|
1882
|
+
/**
|
|
1883
|
+
* STRICT (fail-CLOSED) twin of {@link listItemLockEntries}: THROWS when the
|
|
1884
|
+
* lock refs cannot be read (the same fetch {@link listItemLocks} does), so a
|
|
1885
|
+
* caller that ACTS on the absence of a lock (the merge-question surfacer asks
|
|
1886
|
+
* about a branch only when no live build holds its item) never mistakes an
|
|
1887
|
+
* unreadable arbiter for "no locks". A held ref whose body does not parse is
|
|
1888
|
+
* returned as a plain `implement` hold without the marker (a live build: the
|
|
1889
|
+
* safe reading).
|
|
1890
|
+
*/
|
|
1891
|
+
export async function listItemLockEntriesStrict(cwd, arbiter = 'origin', env) {
|
|
1892
|
+
const names = await listItemLocks(cwd, arbiter, env);
|
|
1893
|
+
const entries = [];
|
|
1894
|
+
for (const entry of names) {
|
|
1895
|
+
const show = await gitSoft(['show', `${itemLockRef(entry)}:lock.md`], cwd, env);
|
|
1896
|
+
const lock = show.status === 0 ? parseLockEntry(show.stdout) : undefined;
|
|
1897
|
+
entries.push(lock ?? {
|
|
1898
|
+
entry,
|
|
1899
|
+
action: 'implement',
|
|
1900
|
+
state: 'active',
|
|
1901
|
+
holder: '',
|
|
1902
|
+
since: '',
|
|
1903
|
+
});
|
|
1904
|
+
}
|
|
1905
|
+
return entries;
|
|
1906
|
+
}
|
|
1907
|
+
/**
|
|
1908
|
+
* The TASK slugs whose lock a finished propose build keeps held, i.e. whose
|
|
1909
|
+
* entry carries the {@link LockKeptFor} `propose-pr` marker (task
|
|
1910
|
+
* `wire-merge-questions-into-the-advance-tick`, decision 6). Selection uses it
|
|
1911
|
+
* to let an answered `merge` through the held-slug subtraction; the
|
|
1912
|
+
* merge-question surfacer to tell a finished propose build from a live one.
|
|
1913
|
+
* GRACEFUL: a read fault yields an empty set, so a held lock keeps excluding
|
|
1914
|
+
* its item (the safe direction).
|
|
1915
|
+
*/
|
|
1916
|
+
export async function proposeKeptTaskSlugs(cwd, arbiter = 'origin', env) {
|
|
1917
|
+
const entries = await listItemLockEntries(cwd, arbiter, env);
|
|
1918
|
+
const prefix = 'task-';
|
|
1919
|
+
return new Set(entries
|
|
1920
|
+
.filter((e) => e.keptFor === 'propose-pr' && e.entry.startsWith(prefix))
|
|
1921
|
+
.map((e) => e.entry.slice(prefix.length)));
|
|
1922
|
+
}
|
|
1759
1923
|
/**
|
|
1760
1924
|
* List the SPEC slugs currently lock-held on the arbiter — the held-SPEC set the
|
|
1761
1925
|
* TASKABLE-spec pool readers SUBTRACT (fix
|
|
@@ -1827,6 +1991,10 @@ export function parseLockEntry(body) {
|
|
|
1827
1991
|
state: 'active',
|
|
1828
1992
|
holder: fields.holder ?? '',
|
|
1829
1993
|
since: fields.since ?? '',
|
|
1994
|
+
// Only the one known marker value is read; anything else is a live hold.
|
|
1995
|
+
...(fields.keptFor === 'propose-pr'
|
|
1996
|
+
? { keptFor: 'propose-pr' }
|
|
1997
|
+
: {}),
|
|
1830
1998
|
};
|
|
1831
1999
|
}
|
|
1832
2000
|
/**
|