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
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import {existsSync} from 'node:fs';
|
|
2
|
+
import {run} from './git.js';
|
|
3
|
+
import {evaluateDeletionSafety, RETAIN_REASON_TEXT} from './gc.js';
|
|
4
|
+
import {resolveHarness} from './harness.js';
|
|
5
|
+
// Import for the registration side-effect: ensures the `pi` adapter is in the
|
|
6
|
+
// harness registry so a pi job's liveness is answered by the pi adapter (the
|
|
7
|
+
// same reason `status.ts` imports it).
|
|
8
|
+
import './pi-harness.js';
|
|
9
|
+
import {jobWorktreePath, readJobRecord} from './workspace.js';
|
|
10
|
+
import {workBranchRef} from './slug-namespace.js';
|
|
11
|
+
import {refWrite} from './ref-write.js';
|
|
12
|
+
import type {BackoffOptions, Sleep} from './retry-backoff.js';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* **Save a CRASHED run's local-only work before its lock is released** (task
|
|
16
|
+
* `a-crashed-runs-local-work-is-saved-before-its-lock-is-released`).
|
|
17
|
+
*
|
|
18
|
+
* A `do --isolated` run that is killed mid-agent (a host restart, an OOM kill)
|
|
19
|
+
* leaves its per-item lock `active` and its job worktree RETAINED under
|
|
20
|
+
* `<workspacesDir>/work/<work-id>/`. The runner's own abort handler may already
|
|
21
|
+
* have made the usual wip commit there, but the process died before pushing it,
|
|
22
|
+
* so the work exists ONLY in that worktree. A plain `requeue` then released the
|
|
23
|
+
* lock without saving it, and the next claim (or `gc --force`) cut the worktree
|
|
24
|
+
* away: the work was lost.
|
|
25
|
+
*
|
|
26
|
+
* This is the SAVE step `requeue` runs before it releases a held lock. It
|
|
27
|
+
* locates the slug's retained job worktree by the SAME arbiter-URL + slug naming
|
|
28
|
+
* `do --isolated` created it with (`jobWorktreePath`, as `complete --isolated`
|
|
29
|
+
* locates it), and:
|
|
30
|
+
*
|
|
31
|
+
* - no retained worktree (or one that belongs to a same-slug SPEC run)
|
|
32
|
+
* ⇒ `no-worktree`: nothing to do, requeue behaves as before;
|
|
33
|
+
* - the run is still ALIVE per its harness (PID/session, never mtime, ADR §5)
|
|
34
|
+
* ⇒ `alive`: we never write into a live agent's tree;
|
|
35
|
+
* - the gc deletion-safety predicate already holds (clean tree AND tip on the
|
|
36
|
+
* arbiter) ⇒ `nothing-unsaved`: requeue behaves as before;
|
|
37
|
+
* - otherwise commit any uncommitted residue as the usual wip commit and push
|
|
38
|
+
* the work branch through `refWrite.saveWorkBranch` (the SAME save half
|
|
39
|
+
* `routeToNeedsAttention` and the deadline checkpoint use: plain push, never
|
|
40
|
+
* `--force`, bounded backoff), then RE-CHECK the predicate: holds ⇒ `saved`,
|
|
41
|
+
* else `not-saved` with why (the caller keeps the lock and the worktree).
|
|
42
|
+
*
|
|
43
|
+
* A worktree whose HEAD is not on its work branch (e.g. a run killed mid-rebase,
|
|
44
|
+
* detached HEAD) is `not-saved` WITHOUT touching it: committing onto a detached
|
|
45
|
+
* HEAD would strand the commit, so the human resolves it by hand.
|
|
46
|
+
*/
|
|
47
|
+
export type CrashedRunSaveOutcome =
|
|
48
|
+
| {kind: 'no-worktree'}
|
|
49
|
+
| {kind: 'alive'; dir: string; branch: string}
|
|
50
|
+
| {kind: 'nothing-unsaved'; dir: string; branch: string}
|
|
51
|
+
| {kind: 'saved'; dir: string; branch: string; committedResidue: boolean}
|
|
52
|
+
| {kind: 'not-saved'; dir: string; branch: string; detail: string};
|
|
53
|
+
|
|
54
|
+
export interface SaveCrashedRunWorkOptions {
|
|
55
|
+
/** The operator's checkout; its `arbiter` remote names the repo. */
|
|
56
|
+
cwd: string;
|
|
57
|
+
/** The arbiter remote NAME in {@link cwd}. */
|
|
58
|
+
arbiter: string;
|
|
59
|
+
/** The task slug (the branch is `work/task-<slug>`). */
|
|
60
|
+
slug: string;
|
|
61
|
+
/** The execution working area (config `workspacesDir`). */
|
|
62
|
+
workspacesDir: string;
|
|
63
|
+
env?: NodeJS.ProcessEnv;
|
|
64
|
+
note?: (message: string) => void;
|
|
65
|
+
/** Backoff bounds for the save push (tests pass a no-wait `sleep`). */
|
|
66
|
+
backoff?: BackoffOptions;
|
|
67
|
+
sleep?: Sleep;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** The arbiter remote name valid INSIDE a job worktree (cut from the bare hub mirror). */
|
|
71
|
+
const WORKTREE_ARBITER_REMOTE = 'origin';
|
|
72
|
+
|
|
73
|
+
export async function saveCrashedRunWork(
|
|
74
|
+
options: SaveCrashedRunWorkOptions,
|
|
75
|
+
): Promise<CrashedRunSaveOutcome> {
|
|
76
|
+
const note = options.note ?? (() => {});
|
|
77
|
+
const {cwd, arbiter, slug, workspacesDir, env} = options;
|
|
78
|
+
|
|
79
|
+
const url = run('git', ['remote', 'get-url', arbiter], cwd, {env});
|
|
80
|
+
if (url.status !== 0 || url.stdout.trim() === '') {
|
|
81
|
+
return {kind: 'no-worktree'};
|
|
82
|
+
}
|
|
83
|
+
const dir = jobWorktreePath(workspacesDir, url.stdout.trim(), slug);
|
|
84
|
+
if (!existsSync(dir)) {
|
|
85
|
+
return {kind: 'no-worktree'};
|
|
86
|
+
}
|
|
87
|
+
const branch = workBranchRef('task', slug);
|
|
88
|
+
const record = readJobRecord(dir);
|
|
89
|
+
if (record !== undefined && record.branch !== branch) {
|
|
90
|
+
// A same-slug SPEC (tasking) run shares the work-id; it is not this task's.
|
|
91
|
+
return {kind: 'no-worktree'};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (
|
|
95
|
+
record !== undefined &&
|
|
96
|
+
record.state === 'running' &&
|
|
97
|
+
resolveHarness(record.harness).isAlive(record.harness)
|
|
98
|
+
) {
|
|
99
|
+
note(
|
|
100
|
+
`'${slug}': its run in ${dir} is still ALIVE (per its harness), so ` +
|
|
101
|
+
'requeue does not touch its worktree.',
|
|
102
|
+
);
|
|
103
|
+
return {kind: 'alive', dir, branch};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const before = evaluateDeletionSafety({dir, branch, env});
|
|
107
|
+
if (before.safe) {
|
|
108
|
+
return {kind: 'nothing-unsaved', dir, branch};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const head = run('git', ['symbolic-ref', '-q', '--short', 'HEAD'], dir, {
|
|
112
|
+
env,
|
|
113
|
+
});
|
|
114
|
+
if (head.status !== 0 || head.stdout.trim() !== branch) {
|
|
115
|
+
return {
|
|
116
|
+
kind: 'not-saved',
|
|
117
|
+
dir,
|
|
118
|
+
branch,
|
|
119
|
+
detail:
|
|
120
|
+
`its worktree is not on ${branch} (HEAD: ` +
|
|
121
|
+
`${head.status === 0 ? head.stdout.trim() : 'detached, e.g. killed mid-rebase'}), ` +
|
|
122
|
+
'so it cannot be saved automatically',
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
note(
|
|
127
|
+
`'${slug}': its crashed run left unsaved work in ${dir} ` +
|
|
128
|
+
`(${RETAIN_REASON_TEXT[before.reason ?? 'unmerged-commits']}); saving it ` +
|
|
129
|
+
`to ${branch} on the arbiter before releasing the lock.`,
|
|
130
|
+
);
|
|
131
|
+
const saved = await refWrite.saveWorkBranch({
|
|
132
|
+
cwd: dir,
|
|
133
|
+
slug,
|
|
134
|
+
reason: `save a crashed run's local work before requeue`,
|
|
135
|
+
arbiter: WORKTREE_ARBITER_REMOTE,
|
|
136
|
+
branch,
|
|
137
|
+
env,
|
|
138
|
+
// The save half's own notes speak of a bounce; this is a requeue, so we
|
|
139
|
+
// report from the outcome instead.
|
|
140
|
+
note: () => {},
|
|
141
|
+
...(options.backoff !== undefined ? {backoff: options.backoff} : {}),
|
|
142
|
+
...(options.sleep !== undefined ? {sleep: options.sleep} : {}),
|
|
143
|
+
});
|
|
144
|
+
const committedResidue = saved.moveCommit !== undefined;
|
|
145
|
+
|
|
146
|
+
const after = evaluateDeletionSafety({dir, branch, env});
|
|
147
|
+
if (after.safe) {
|
|
148
|
+
note(
|
|
149
|
+
`Saved the crashed run's work: pushed ${branch}` +
|
|
150
|
+
(committedResidue
|
|
151
|
+
? ' (with a wip commit of its uncommitted files)'
|
|
152
|
+
: '') +
|
|
153
|
+
'.',
|
|
154
|
+
);
|
|
155
|
+
return {kind: 'saved', dir, branch, committedResidue};
|
|
156
|
+
}
|
|
157
|
+
const detail =
|
|
158
|
+
saved.branchPush === 'failed'
|
|
159
|
+
? `the push of ${branch} failed (${saved.pushError ?? 'unknown error'})`
|
|
160
|
+
: `it is still ${RETAIN_REASON_TEXT[after.reason ?? 'unmerged-commits']}`;
|
|
161
|
+
return {kind: 'not-saved', dir, branch, detail};
|
|
162
|
+
}
|
package/src/cwd-section.ts
CHANGED
|
@@ -6,6 +6,7 @@ import {listMirrors} from './registry.js';
|
|
|
6
6
|
import {encodeRepoKey, mirrorPath} from './repo-mirror.js';
|
|
7
7
|
import {
|
|
8
8
|
heldTaskSlugsStrict,
|
|
9
|
+
proposeKeptTaskSlugs,
|
|
9
10
|
heldSpecSlugsStrict,
|
|
10
11
|
listItemLockEntries,
|
|
11
12
|
classifyTerminalItemLocks,
|
|
@@ -421,12 +422,21 @@ export async function resolveCwdSection(
|
|
|
421
422
|
// with the arbiter-read held set SUBTRACTED so in-flight (lock-held) items are
|
|
422
423
|
// not reported eligible. Thread the per-machine override so the cwd section's
|
|
423
424
|
// eligibility matches what `do`/`advance` autopick will actually select.
|
|
425
|
+
// The held tasks whose lock a finished propose build keeps (the `propose-pr`
|
|
426
|
+
// marker): an answered `merge` on one of them is still enumerated, because
|
|
427
|
+
// its apply takes that lock over (task
|
|
428
|
+
// `wire-merge-questions-into-the-advance-tick`, decision 6). GRACEFUL: a read
|
|
429
|
+
// fault yields an empty set, so every held lock keeps excluding its item.
|
|
430
|
+
const proposeKeptSlugs = hasLockRemote
|
|
431
|
+
? await proposeKeptTaskSlugs(cwd, lockRemote, env)
|
|
432
|
+
: new Set<string>();
|
|
424
433
|
const localReport = scanRepoPaths(
|
|
425
434
|
[cwd],
|
|
426
435
|
config,
|
|
427
436
|
heldSlugs,
|
|
428
437
|
options.override,
|
|
429
438
|
heldSpecSlugs,
|
|
439
|
+
proposeKeptSlugs,
|
|
430
440
|
);
|
|
431
441
|
const repo = localReport.repos[0];
|
|
432
442
|
|
package/src/decision-engine.ts
CHANGED
|
@@ -138,6 +138,16 @@ export interface DecisionVerdict {
|
|
|
138
138
|
* append/re-pause loop).
|
|
139
139
|
*/
|
|
140
140
|
question?: string;
|
|
141
|
+
/**
|
|
142
|
+
* The follow-up questions as SEPARATE questions (`ask` outcome); when
|
|
143
|
+
* non-empty it takes precedence over {@link question}, and each becomes its
|
|
144
|
+
* own sidecar entry. The decision agent's contract emits the single
|
|
145
|
+
* `question` ({@link parseDecisionVerdict} does not read this field); the CI
|
|
146
|
+
* apply phase sets it when it replays a handed-over `ask`, so a handoff's
|
|
147
|
+
* questions are never joined into one (task
|
|
148
|
+
* `ci-surface-questions-keep-their-context-and-default`).
|
|
149
|
+
*/
|
|
150
|
+
questions?: string[];
|
|
141
151
|
}
|
|
142
152
|
|
|
143
153
|
/**
|
package/src/do-config.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
Config,
|
|
3
3
|
IntegrationMode,
|
|
4
|
-
MergeQuestions,
|
|
5
4
|
ObservationTriage,
|
|
6
5
|
PartialConfig,
|
|
7
6
|
} from './config.js';
|
|
@@ -79,7 +78,6 @@ export function doFlagOverrides(
|
|
|
79
78
|
SelectionOrderFlags &
|
|
80
79
|
ObservationTriageFlags &
|
|
81
80
|
SurfaceBlockersFlags &
|
|
82
|
-
MergeQuestionsFlags &
|
|
83
81
|
StrictMergeApprovalFlags &
|
|
84
82
|
NoPRFlags &
|
|
85
83
|
MergeRetriesFlags,
|
|
@@ -94,17 +92,10 @@ export function doFlagOverrides(
|
|
|
94
92
|
// boolean gate over DECLARED blocked work (the orthogonal peer of
|
|
95
93
|
// `--observation-triage`).
|
|
96
94
|
...surfaceBlockersFlagOverrides(flags),
|
|
97
|
-
// `--merge-questions <off|ask|auto>` rides the SAME flag-override chain
|
|
98
|
-
// (flag > env > per-repo > global > default `ask`): the 3-state gate over
|
|
99
|
-
// the merge-question SURFACER (spec `land-time-reverify-and-parallel-
|
|
100
|
-
// merge-ceiling` Story 17 / task `merge-questions-gate-axis`). SEPARATE
|
|
101
|
-
// axis from `--observation-triage` with a HIGHER default — NEVER rides
|
|
102
|
-
// `--observation-triage`.
|
|
103
|
-
...mergeQuestionsFlagOverrides(flags),
|
|
104
95
|
// `--strict-merge-approval`/`--no-strict-merge-approval` rides the SAME
|
|
105
96
|
// flag-override chain (flag > env > per-repo > global > default `false`):
|
|
106
97
|
// the OPT-IN strictness layered on the OQ6 stale-approval default. SEPARATE
|
|
107
|
-
// axis from
|
|
98
|
+
// axis from `mergeQuestions`: the re-surface vs. land branch is
|
|
108
99
|
// `apply-rung-merge-disposition`'s consumer; this only resolves the boolean.
|
|
109
100
|
...strictMergeApprovalFlagOverrides(flags),
|
|
110
101
|
// `--selection-order <order>` rides the SAME flag-override chain (flag > env >
|
|
@@ -450,51 +441,6 @@ export function mergeRetriesFlagOverrides(
|
|
|
450
441
|
return overrides;
|
|
451
442
|
}
|
|
452
443
|
|
|
453
|
-
/**
|
|
454
|
-
* The merge-questions CLI flag (`advance`): `--merge-questions <off|ask|auto>`,
|
|
455
|
-
* the 3-state gate over the MERGE-QUESTION SURFACER (spec
|
|
456
|
-
* `land-time-reverify-and-parallel-merge-ceiling` Story 17 / task
|
|
457
|
-
* `merge-questions-gate-axis`). MIRRORS `--observation-triage`'s SHAPE but is a
|
|
458
|
-
* SEPARATE axis with a HIGHER default (`ask`, never `off` — a dropped merge-
|
|
459
|
-
* question means pushed work never lands). Resolved through the SAME
|
|
460
|
-
* `flag > env > per-repo > global > default` chain as the other gate flags.
|
|
461
|
-
*/
|
|
462
|
-
export interface MergeQuestionsFlags {
|
|
463
|
-
/** `--merge-questions <off|ask|auto>` — the merge-question surfacer gate. */
|
|
464
|
-
mergeQuestions?: string;
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
/** The valid `--merge-questions` values (mirrors the env enum coercion). */
|
|
468
|
-
const MERGE_QUESTIONS_VALUES: readonly MergeQuestions[] = [
|
|
469
|
-
'off',
|
|
470
|
-
'ask',
|
|
471
|
-
'auto',
|
|
472
|
-
];
|
|
473
|
-
|
|
474
|
-
/**
|
|
475
|
-
* Map the `--merge-questions` flag into a {@link PartialConfig} override. Only a
|
|
476
|
-
* present flag contributes (absent ⇒ absent key). An INVALID value FAILS LOUDLY
|
|
477
|
-
* (the same loud-failure contract `--observation-triage` enforces) rather than
|
|
478
|
-
* silently falling through — a typo on a question-surfacing gate must never be
|
|
479
|
-
* quietly ignored.
|
|
480
|
-
*/
|
|
481
|
-
export function mergeQuestionsFlagOverrides(
|
|
482
|
-
flags: MergeQuestionsFlags,
|
|
483
|
-
): PartialConfig {
|
|
484
|
-
const overrides: PartialConfig = {};
|
|
485
|
-
if (flags.mergeQuestions !== undefined) {
|
|
486
|
-
const raw = flags.mergeQuestions;
|
|
487
|
-
if (!MERGE_QUESTIONS_VALUES.includes(raw as MergeQuestions)) {
|
|
488
|
-
throw new Error(
|
|
489
|
-
`Invalid value for --merge-questions: '${raw}'. ` +
|
|
490
|
-
`Expected one of: ${MERGE_QUESTIONS_VALUES.join(', ')}.`,
|
|
491
|
-
);
|
|
492
|
-
}
|
|
493
|
-
overrides.mergeQuestions = raw as MergeQuestions;
|
|
494
|
-
}
|
|
495
|
-
return overrides;
|
|
496
|
-
}
|
|
497
|
-
|
|
498
444
|
/**
|
|
499
445
|
* **The strict-merge-approval CLI flag** (`--strict-merge-approval` /
|
|
500
446
|
* `--no-strict-merge-approval`) — spec
|
|
@@ -504,8 +450,7 @@ export function mergeQuestionsFlagOverrides(
|
|
|
504
450
|
* change instead of auto-landing on a green re-verify (the host-agnostic
|
|
505
451
|
* analogue of GitHub's "dismiss stale approvals when the base changes"); OFF
|
|
506
452
|
* (default) honours the prior answer + lands when the rebased tip re-verifies
|
|
507
|
-
* GREEN. Offered
|
|
508
|
-
* the consumer). Resolved through the SAME `flag > env > per-repo > global >
|
|
453
|
+
* GREEN. Offered on `advance` (the apply rung is the consumer). Resolved through the SAME `flag > env > per-repo > global >
|
|
509
454
|
* default` chain as the other gate-family members. A negatable boolean
|
|
510
455
|
* (mirrors `--fresh-worktree-gate`).
|
|
511
456
|
*/
|