dorfl 0.1.2 → 0.2.1
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-drivers.d.ts +1 -1
- package/dist/advance-drivers.d.ts.map +1 -1
- package/dist/advance-drivers.js +15 -3
- package/dist/advance-drivers.js.map +1 -1
- package/dist/advance-lifecycle-template.d.ts.map +1 -1
- package/dist/advance-lifecycle-template.js +76 -4
- package/dist/advance-lifecycle-template.js.map +1 -1
- package/dist/advance-treeless-publish.d.ts +23 -0
- 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 +59 -7
- package/dist/advance.d.ts.map +1 -1
- package/dist/advance.js +389 -82
- package/dist/advance.js.map +1 -1
- package/dist/advancing-lock.d.ts +30 -2
- package/dist/advancing-lock.d.ts.map +1 -1
- package/dist/advancing-lock.js +50 -0
- 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 +17 -3
- package/dist/apply-decide.d.ts.map +1 -1
- package/dist/apply-decide.js +36 -7
- package/dist/apply-decide.js.map +1 -1
- package/dist/apply-merge-action.d.ts +17 -5
- package/dist/apply-merge-action.d.ts.map +1 -1
- package/dist/apply-merge-action.js +43 -8
- package/dist/apply-merge-action.js.map +1 -1
- package/dist/apply-persist.d.ts +57 -26
- package/dist/apply-persist.d.ts.map +1 -1
- package/dist/apply-persist.js +166 -37
- 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/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 +320 -63
- package/dist/cli.js.map +1 -1
- package/dist/close-job-template.js +1 -1
- package/dist/complete.d.ts +6 -3
- package/dist/complete.d.ts.map +1 -1
- package/dist/complete.js +91 -37
- package/dist/complete.js.map +1 -1
- package/dist/config.d.ts +55 -9
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +56 -4
- package/dist/config.js.map +1 -1
- package/dist/continue-branch.d.ts.map +1 -1
- package/dist/continue-branch.js +22 -0
- package/dist/continue-branch.js.map +1 -1
- package/dist/decision-engine.d.ts +38 -10
- 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.map +1 -1
- package/dist/do-autopick.js +11 -1
- package/dist/do-autopick.js.map +1 -1
- package/dist/do-config.d.ts +1 -1
- package/dist/do.d.ts +49 -56
- package/dist/do.d.ts.map +1 -1
- package/dist/do.js +419 -30
- package/dist/do.js.map +1 -1
- package/dist/env-config.d.ts.map +1 -1
- package/dist/env-config.js +12 -4
- 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 +10 -27
- package/dist/format.js.map +1 -1
- package/dist/frontmatter.d.ts +16 -4
- package/dist/frontmatter.d.ts.map +1 -1
- package/dist/frontmatter.js +27 -1
- 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 +132 -38
- package/dist/install-ci-branch-protection.d.ts.map +1 -1
- package/dist/install-ci-branch-protection.js +190 -48
- package/dist/install-ci-branch-protection.js.map +1 -1
- package/dist/install-ci-core.d.ts +21 -1
- package/dist/install-ci-core.d.ts.map +1 -1
- package/dist/install-ci-core.js +10 -3
- package/dist/install-ci-core.js.map +1 -1
- package/dist/install-ci-github.d.ts +32 -0
- package/dist/install-ci-github.d.ts.map +1 -1
- package/dist/install-ci-github.js +73 -0
- package/dist/install-ci-github.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-trigger-template.js +1 -1
- package/dist/intake.d.ts +17 -4
- package/dist/intake.d.ts.map +1 -1
- package/dist/intake.js +23 -7
- package/dist/intake.js.map +1 -1
- package/dist/integration-core.d.ts +10 -7
- package/dist/integration-core.d.ts.map +1 -1
- package/dist/integration-core.js +174 -60
- 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 +2 -2
- package/dist/isolation.d.ts.map +1 -1
- package/dist/isolation.js +9 -0
- package/dist/isolation.js.map +1 -1
- package/dist/item-lock.d.ts +196 -129
- package/dist/item-lock.d.ts.map +1 -1
- package/dist/item-lock.js +329 -254
- package/dist/item-lock.js.map +1 -1
- package/dist/ledger-write.d.ts +31 -26
- 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 +17 -0
- package/dist/lifecycle-gather.d.ts.map +1 -1
- package/dist/lifecycle-gather.js +7 -1
- package/dist/lifecycle-gather.js.map +1 -1
- package/dist/lifecycle-pools.d.ts +40 -3
- package/dist/lifecycle-pools.d.ts.map +1 -1
- package/dist/lifecycle-pools.js +26 -6
- package/dist/lifecycle-pools.js.map +1 -1
- package/dist/merge-question-surfacer.d.ts +15 -1
- package/dist/merge-question-surfacer.d.ts.map +1 -1
- package/dist/merge-question-surfacer.js +18 -3
- 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/needs-attention.d.ts +293 -16
- package/dist/needs-attention.d.ts.map +1 -1
- package/dist/needs-attention.js +532 -57
- package/dist/needs-attention.js.map +1 -1
- package/dist/orphan-sidecar.d.ts +8 -4
- 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 +3 -3
- package/dist/placement.js +1 -1
- 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/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/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 +5 -0
- 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 +53 -7
- 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-verdict.js +1 -1
- package/dist/review-verdict.js.map +1 -1
- package/dist/run.d.ts +1 -1
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +54 -19
- package/dist/run.js.map +1 -1
- package/dist/scan.d.ts +17 -8
- package/dist/scan.d.ts.map +1 -1
- package/dist/scan.js +22 -8
- package/dist/scan.js.map +1 -1
- package/dist/select-priority.d.ts +2 -2
- package/dist/select-priority.js +1 -1
- 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 +45 -10
- package/dist/sidecar.d.ts.map +1 -1
- package/dist/sidecar.js +82 -2
- 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 +5 -5
- package/dist/slug-namespace.js +5 -5
- package/dist/slug-namespace.js.map +1 -1
- package/dist/spec-complete.d.ts.map +1 -1
- package/dist/spec-complete.js +2 -3
- package/dist/spec-complete.js.map +1 -1
- package/dist/start.d.ts.map +1 -1
- package/dist/start.js +51 -57
- package/dist/start.js.map +1 -1
- 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.js +1 -1
- package/dist/surface-persist.js.map +1 -1
- package/dist/tasker-review-loop.d.ts +4 -3
- package/dist/tasker-review-loop.d.ts.map +1 -1
- package/dist/tasker-review-loop.js.map +1 -1
- package/dist/tasking-lock.d.ts +2 -2
- package/dist/tasking-lock.d.ts.map +1 -1
- package/dist/tasking-lock.js +53 -32
- package/dist/tasking-lock.js.map +1 -1
- package/dist/tasking.d.ts +40 -6
- package/dist/tasking.d.ts.map +1 -1
- package/dist/tasking.js +224 -12
- package/dist/tasking.js.map +1 -1
- package/dist/triage-persist.d.ts +10 -6
- package/dist/triage-persist.d.ts.map +1 -1
- package/dist/triage-persist.js +34 -4
- 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.js +1 -1
- 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 +7 -3
- package/dist/work-layout.d.ts.map +1 -1
- package/dist/work-layout.js +6 -3
- package/dist/work-layout.js.map +1 -1
- package/dist/workspace.d.ts +1 -1
- package/package.json +2 -2
- package/src/advance-drivers.ts +16 -3
- package/src/advance-lifecycle-template.ts +89 -4
- package/src/advance-treeless-publish.ts +45 -0
- package/src/advance.ts +467 -87
- package/src/advancing-lock.ts +96 -1
- package/src/agent-launch.ts +37 -12
- package/src/agent-stop.ts +60 -2
- package/src/apply-decide.ts +36 -7
- package/src/apply-merge-action.ts +45 -7
- package/src/apply-persist.ts +228 -54
- package/src/apply-stuck-action.ts +260 -0
- package/src/brand.ts +14 -2
- package/src/cli-spinner.ts +1 -1
- package/src/cli.ts +401 -70
- package/src/close-job-template.ts +1 -1
- package/src/complete.ts +110 -52
- package/src/config.ts +107 -13
- package/src/continue-branch.ts +22 -0
- package/src/decision-engine.ts +55 -17
- package/src/do-autopick.ts +12 -1
- package/src/do-config.ts +1 -1
- package/src/do.ts +511 -38
- package/src/env-config.ts +12 -4
- package/src/failure-cause.ts +30 -1
- package/src/format.ts +10 -30
- package/src/frontmatter.ts +35 -5
- 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 +282 -57
- package/src/install-ci-core.ts +30 -3
- package/src/install-ci-github.ts +86 -0
- package/src/install-skills.ts +166 -0
- package/src/intake-trigger-template.ts +1 -1
- package/src/intake.ts +46 -11
- package/src/integration-core.ts +199 -65
- package/src/integrator.ts +22 -9
- package/src/isolation.ts +11 -2
- package/src/item-lock.ts +485 -341
- package/src/ledger-write.ts +135 -150
- package/src/lifecycle-gather.ts +29 -6
- package/src/lifecycle-pools.ts +67 -9
- package/src/merge-question-surfacer.ts +28 -4
- package/src/migrate-stuck-locks.ts +451 -0
- package/src/needs-attention.ts +857 -84
- package/src/orphan-sidecar.ts +47 -6
- package/src/pi-harness.ts +82 -2
- package/src/placement.ts +3 -3
- package/src/prd-to-spec.ts +13 -5
- package/src/reap-branches.ts +38 -14
- package/src/recover-isolated.ts +17 -0
- package/src/repo-config.ts +55 -6
- package/src/repo-mirror.ts +23 -1
- package/src/review-verdict.ts +1 -1
- package/src/run.ts +64 -18
- package/src/scan.ts +22 -8
- package/src/select-priority.ts +3 -3
- package/src/sidecar-apply.ts +1 -1
- package/src/sidecar.ts +138 -11
- package/src/slug-namespace.ts +7 -7
- package/src/spec-complete.ts +2 -3
- package/src/start.ts +53 -59
- package/src/surface-gate.ts +10 -3
- package/src/surface-persist.ts +1 -1
- package/src/tasker-review-loop.ts +4 -3
- package/src/tasking-lock.ts +52 -36
- package/src/tasking.ts +261 -17
- package/src/triage-persist.ts +56 -12
- 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 +1 -1
- package/src/watch-session.ts +102 -7
- package/src/work-layout.ts +6 -3
- package/src/workspace.ts +1 -1
package/dist/integration-core.js
CHANGED
|
@@ -171,6 +171,19 @@ export async function performIntegration(input) {
|
|
|
171
171
|
recoveryRebaseJitterMs: input.recoveryRebaseJitterMs,
|
|
172
172
|
recoveryRebaseSleep: input.recoveryRebaseSleep,
|
|
173
173
|
recoveryRebaseRandom: input.recoveryRebaseRandom,
|
|
174
|
+
// GATE-2 REVIEW on the recovery path (task
|
|
175
|
+
// `committed-recovery-always-reviews`): a stranded already-complete
|
|
176
|
+
// branch is NOT "already reviewed" — its earlier attempt's PR never
|
|
177
|
+
// merged and Gate 2 may never have run on it. So when `review` is on we
|
|
178
|
+
// MUST run Gate 2 on the rebased tip here too (the SAME reasoning that
|
|
179
|
+
// forces the re-verify: `<arbiter>/main` moved, the merged tree is new).
|
|
180
|
+
// Pass the whole `input` so the recovery tail can call `runGate2Review`
|
|
181
|
+
// with the identical gate/model/watch/round wiring the build path uses.
|
|
182
|
+
input,
|
|
183
|
+
// PR BODY on the recovery path: the recovery has NO fresh agent output
|
|
184
|
+
// (no rebuild), so carry whatever `body` the caller supplied so the PR
|
|
185
|
+
// gets a description instead of degrading to a blank `gh --fill`.
|
|
186
|
+
body: input.body,
|
|
174
187
|
// Answered-merge land (task `committed-recovery-honours-fresh-worktree-gate`,
|
|
175
188
|
// spec `land-time-reverify-and-parallel-merge-ceiling`): the apply-rung
|
|
176
189
|
// dispatches an answered `merge` through this committed-recovery tail (the
|
|
@@ -222,7 +235,7 @@ export async function performIntegration(input) {
|
|
|
222
235
|
// passes no flag, so there an untrusted-origin task RELIABLY forces propose.
|
|
223
236
|
//
|
|
224
237
|
// SCOPE: the task BUILD transition ONLY. It NEVER fires for a `lifecycle`
|
|
225
|
-
// transition (tasking / intake-emit — a
|
|
238
|
+
// transition (tasking / intake-emit — a spec/task FILE landing on main is inert;
|
|
226
239
|
// intake's OWN per-emit resolver already decided that mode), and the source file
|
|
227
240
|
// here is the task being built. A `trusted`/unset task ⇒ untouched (zero
|
|
228
241
|
// behaviour change for the normal human path).
|
|
@@ -270,10 +283,11 @@ export async function performIntegration(input) {
|
|
|
270
283
|
}
|
|
271
284
|
if (!prep.passed) {
|
|
272
285
|
const reason = `prepare (env-prep) failed (exit ${prep.exitCode})`;
|
|
273
|
-
//
|
|
274
|
-
//
|
|
275
|
-
//
|
|
276
|
-
//
|
|
286
|
+
// Mark the item stuck on its per-item lock (the SAME seam a red gate uses)
|
|
287
|
+
// — recording the prepare-failed reason on the lock entry + saving the
|
|
288
|
+
// agent's uncommitted work as a wip commit (post lock-cutover: a lock amend,
|
|
289
|
+
// no `in-progress/ → needs-attention/` folder move). We NEVER run `verify`
|
|
290
|
+
// on an env that could not be made ready.
|
|
277
291
|
const routed = await ledgerWrite.applyNeedsAttentionTransition({
|
|
278
292
|
cwd,
|
|
279
293
|
slug,
|
|
@@ -287,10 +301,10 @@ export async function performIntegration(input) {
|
|
|
287
301
|
routedToNeedsAttention: routed.moved,
|
|
288
302
|
branch,
|
|
289
303
|
reason: routed.moved
|
|
290
|
-
? `Env-prep (prepare) failed (exit ${prep.exitCode});
|
|
291
|
-
'
|
|
304
|
+
? `Env-prep (prepare) failed (exit ${prep.exitCode}); marked '${slug}' ` +
|
|
305
|
+
'stuck on its per-item lock (the environment could not be made ready, ' +
|
|
292
306
|
'so the acceptance gate was NOT run). Fix the prepare command, then ' +
|
|
293
|
-
'
|
|
307
|
+
'`requeue` to release the stuck lock.'
|
|
294
308
|
: `Env-prep (prepare) failed (exit ${prep.exitCode}); not completing ` +
|
|
295
309
|
`'${slug}' (the environment could not be made ready, so the ` +
|
|
296
310
|
'acceptance gate was NOT run). Fix the prepare command, then retry.',
|
|
@@ -309,12 +323,12 @@ export async function performIntegration(input) {
|
|
|
309
323
|
note('Running the acceptance gate (verify)…');
|
|
310
324
|
const gate = await runVerify({ cwd, verify: input.verify, env });
|
|
311
325
|
if (!gate.passed) {
|
|
312
|
-
// Don't leave the item dangling
|
|
313
|
-
//
|
|
314
|
-
//
|
|
315
|
-
//
|
|
316
|
-
//
|
|
317
|
-
//
|
|
326
|
+
// Don't leave the item dangling: mark it stuck on its per-item lock with
|
|
327
|
+
// the reason (ADR §12) THROUGH the ledger write seam's needs-attention
|
|
328
|
+
// transition. Post lock-cutover this is a lock amend (`state: stuck` + the
|
|
329
|
+
// reason on the lock entry, no `in-progress/ → needs-attention/` folder
|
|
330
|
+
// move) plus saving the agent's uncommitted work as a wip commit. No
|
|
331
|
+
// partial state.
|
|
318
332
|
const reason = `acceptance gate failed (exit ${gate.exitCode})`;
|
|
319
333
|
const routed = await ledgerWrite.applyNeedsAttentionTransition({
|
|
320
334
|
cwd,
|
|
@@ -337,9 +351,9 @@ export async function performIntegration(input) {
|
|
|
337
351
|
routedToNeedsAttention: routed.moved,
|
|
338
352
|
branch,
|
|
339
353
|
reason: routed.moved
|
|
340
|
-
? `Acceptance gate failed (exit ${gate.exitCode});
|
|
341
|
-
'
|
|
342
|
-
'
|
|
354
|
+
? `Acceptance gate failed (exit ${gate.exitCode}); marked '${slug}' ` +
|
|
355
|
+
'stuck on its per-item lock (surfaced by status; `requeue` once ' +
|
|
356
|
+
'resolved). Fix the work, or use --skip-verify to override.'
|
|
343
357
|
: `Acceptance gate failed (exit ${gate.exitCode}); not completing ` +
|
|
344
358
|
`'${slug}'. Fix the work, or use --skip-verify to override.`,
|
|
345
359
|
};
|
|
@@ -501,16 +515,14 @@ export async function performIntegration(input) {
|
|
|
501
515
|
// 4. Rebase-before-integrate (ADR §10): rebase the work branch onto the
|
|
502
516
|
// latest <arbiter>/main. Clean → continue. Conflict → abort + stop.
|
|
503
517
|
//
|
|
504
|
-
// RECOVERY reconciliation:
|
|
505
|
-
//
|
|
506
|
-
//
|
|
507
|
-
//
|
|
508
|
-
//
|
|
509
|
-
//
|
|
510
|
-
//
|
|
511
|
-
//
|
|
512
|
-
// needs-attention/). The done-move thus SUPERSEDES the surfaced state — no
|
|
513
|
-
// leftover/conflicting on-`main` surface for the human to resolve.
|
|
518
|
+
// RECOVERY reconciliation: post the per-item-lock cut-over, a stuck item's
|
|
519
|
+
// body never moved into a `needs-attention/` folder (stuck is the lock
|
|
520
|
+
// `state: stuck`; the body rests in `backlog/`), so a recovery `complete`'s
|
|
521
|
+
// kept branch carries NO historical `in-progress → needs-attention`
|
|
522
|
+
// move-only commit to drop and `<arbiter>/main` holds no surface move to
|
|
523
|
+
// conflict with. The old recovery drop (`rebaseDroppingNeedsAttentionSurface`,
|
|
524
|
+
// drop-bookkeeping-rebase) is deleted; recovery is now the SAME plain replay
|
|
525
|
+
// onto `<arbiter>/main` as any other build (see the plain-rebase note below).
|
|
514
526
|
// Fetch the arbiter's `main` into the `<arbiter>/main` remote-tracking ref
|
|
515
527
|
// EXPLICITLY. A `run` JOB WORKTREE is cut from a bare hub mirror whose remote
|
|
516
528
|
// has no fetch refspec (so `<arbiter>/main` would not otherwise resolve / would
|
|
@@ -656,12 +668,12 @@ export async function performIntegration(input) {
|
|
|
656
668
|
// recovery above can fall through to integrate while a genuine code conflict
|
|
657
669
|
// still routes here.
|
|
658
670
|
async function rebaseConflictRoute() {
|
|
659
|
-
// Then
|
|
660
|
-
// §12) THROUGH the ledger write seam's needs-attention transition,
|
|
661
|
-
// than leaving it dangling
|
|
662
|
-
//
|
|
663
|
-
//
|
|
664
|
-
//
|
|
671
|
+
// Then mark the item stuck on its per-item lock with the conflict reason
|
|
672
|
+
// (ADR §12) THROUGH the ledger write seam's needs-attention transition,
|
|
673
|
+
// rather than leaving it dangling. Post lock-cutover this is a lock amend
|
|
674
|
+
// (`state: stuck` + the reason on the lock entry, no `done/ →
|
|
675
|
+
// needs-attention/` folder move); the done-move already committed above
|
|
676
|
+
// stands. No partial state.
|
|
665
677
|
const reason = `rebase onto ${arbiter}/main conflicted (aborted, never auto-resolved)`;
|
|
666
678
|
const routed = await ledgerWrite.applyNeedsAttentionTransition({
|
|
667
679
|
cwd,
|
|
@@ -683,9 +695,9 @@ export async function performIntegration(input) {
|
|
|
683
695
|
commitMessage,
|
|
684
696
|
reason: routed.moved
|
|
685
697
|
? `Rebasing ${branch} onto ${arbiter}/main conflicted; the rebase was ` +
|
|
686
|
-
`aborted (never auto-resolved) and '${slug}' was
|
|
687
|
-
'
|
|
688
|
-
'
|
|
698
|
+
`aborted (never auto-resolved) and '${slug}' was marked stuck on ` +
|
|
699
|
+
'its per-item lock (surfaced by status). Resolve against the latest ' +
|
|
700
|
+
'main, then `requeue` to release the stuck lock and re-run.'
|
|
689
701
|
: `Rebasing ${branch} onto ${arbiter}/main conflicted; the rebase was ` +
|
|
690
702
|
'aborted (never auto-resolved). Resolve against the latest main, ' +
|
|
691
703
|
'then re-run complete.',
|
|
@@ -758,9 +770,9 @@ export async function performIntegration(input) {
|
|
|
758
770
|
branch,
|
|
759
771
|
commitMessage,
|
|
760
772
|
reason: routed.moved
|
|
761
|
-
? `${what} on the rebased tip;
|
|
762
|
-
'
|
|
763
|
-
'
|
|
773
|
+
? `${what} on the rebased tip; marked '${slug}' stuck on its ` +
|
|
774
|
+
'per-item lock (surfaced by status; `requeue` once resolved). ' +
|
|
775
|
+
'Fix the work, or use --skip-verify to override.'
|
|
764
776
|
: `${what} on the rebased tip; not completing '${slug}'. Fix the ` +
|
|
765
777
|
'work, or use --skip-verify to override.',
|
|
766
778
|
};
|
|
@@ -775,7 +787,8 @@ export async function performIntegration(input) {
|
|
|
775
787
|
if (gated.review) {
|
|
776
788
|
if (gated.review.kind === 'blocked') {
|
|
777
789
|
// The done-move was already committed (steps 2–3), so the slug sits in
|
|
778
|
-
// work/done/; the routing
|
|
790
|
+
// work/done/; the routing marked it stuck on its per-item lock (post
|
|
791
|
+
// lock-cutover — a lock amend, no folder move).
|
|
779
792
|
return gated.review.result;
|
|
780
793
|
}
|
|
781
794
|
approvedVerdict = gated.review.verdict;
|
|
@@ -936,9 +949,10 @@ export async function performIntegration(input) {
|
|
|
936
949
|
commitMessage,
|
|
937
950
|
reason: routed.moved
|
|
938
951
|
? `Integrating ${branch} onto ${arbiter}/main kept hitting a ` +
|
|
939
|
-
`non-fast-forward push (a sibling advanced main); '${slug}' was
|
|
940
|
-
`
|
|
941
|
-
`latest main, then
|
|
952
|
+
`non-fast-forward push (a sibling advanced main); '${slug}' was ` +
|
|
953
|
+
`marked stuck on its per-item lock (surfaced by status). Resolve ` +
|
|
954
|
+
`against the latest main, then \`requeue\` to release the stuck ` +
|
|
955
|
+
`lock and re-run.`
|
|
942
956
|
: `Integrating ${branch} onto ${arbiter}/main kept hitting a ` +
|
|
943
957
|
`non-fast-forward push (a sibling advanced main). Resolve against the ` +
|
|
944
958
|
`latest main, then re-run complete.`,
|
|
@@ -1017,7 +1031,7 @@ export async function performIntegration(input) {
|
|
|
1017
1031
|
* primitive the build path uses.
|
|
1018
1032
|
*
|
|
1019
1033
|
* RE-GATE on the REBASED TIP (task `committed-recovery-honours-fresh-worktree-
|
|
1020
|
-
* gate`,
|
|
1034
|
+
* gate`, spec `land-time-reverify-and-parallel-merge-ceiling`): when the caller
|
|
1021
1035
|
* sets `freshWorktreeGate` (and not `skipVerify`), the EXISTING
|
|
1022
1036
|
* `runFreshWorktreeGate` runs on the rebased tip AFTER the rebase loop and
|
|
1023
1037
|
* BEFORE `applyCompleteTransition`, mirroring the build path's
|
|
@@ -1071,6 +1085,14 @@ async function recoverAlreadyCommitted(params) {
|
|
|
1071
1085
|
// (`isAncestor` is the SAME reachability predicate `gc.ts` uses; do not fork it.)
|
|
1072
1086
|
// KEPT before the retry loop: a no-op MUST short-circuit before we burn any
|
|
1073
1087
|
// re-fetch/re-rebase budget.
|
|
1088
|
+
//
|
|
1089
|
+
// DELIBERATELY the RAW ancestry predicate, NOT `isProvablyMergedForReap`
|
|
1090
|
+
// (task `reap-squash-merged-remote-work-branches`, ratified): this is an
|
|
1091
|
+
// integration-IDEMPOTENCY check, not reap-safety. A squash-landed LOOKALIKE
|
|
1092
|
+
// whose tip is NOT genuinely reachable would falsely read "already
|
|
1093
|
+
// integrated" here and skip a needed rebase/re-push. The squash-aware helper
|
|
1094
|
+
// is scoped to reap-safety ONLY; see gc.ts `isProvablyMergedForReap` and
|
|
1095
|
+
// work/notes/observations/reap-squash-helper-scope-2026-07-10.md.
|
|
1074
1096
|
if (isAncestor(cwd, tip, `refs/remotes/${arbiter}/main`, env)) {
|
|
1075
1097
|
const message = `Nothing to recover for '${slug}': its work branch tip is already on ` +
|
|
1076
1098
|
`${arbiter}/main (already integrated). No re-push, no double-integrate.`;
|
|
@@ -1162,7 +1184,7 @@ async function recoverAlreadyCommitted(params) {
|
|
|
1162
1184
|
attempt++;
|
|
1163
1185
|
}
|
|
1164
1186
|
// FRESH-WORKTREE GATE on the REBASED TIP (task `committed-recovery-honours-
|
|
1165
|
-
// fresh-worktree-gate`,
|
|
1187
|
+
// fresh-worktree-gate`, spec `land-time-reverify-and-parallel-merge-ceiling`):
|
|
1166
1188
|
// when `freshWorktreeGate` is set (the answered-merge land caller) and not
|
|
1167
1189
|
// `--skip-verify`, re-run the acceptance gate on the rebased tip BEFORE we
|
|
1168
1190
|
// integrate, mirroring the build path's `freshWorktreeGate && !skipVerify &&
|
|
@@ -1173,11 +1195,21 @@ async function recoverAlreadyCommitted(params) {
|
|
|
1173
1195
|
// clean-rebase-but-broken merge. With `freshWorktreeGate` UNSET (the original
|
|
1174
1196
|
// stranded-recovery caller, whose pre-strand build already gated) this whole
|
|
1175
1197
|
// block is skipped and behaviour is byte-identical to before.
|
|
1198
|
+
// Carry an approved Gate-2 verdict (when review ran) so its authored `review`
|
|
1199
|
+
// prose is posted as a PR comment AFTER the integrate below — the SAME audit
|
|
1200
|
+
// trail the build path keeps (task `committed-recovery-always-reviews`).
|
|
1201
|
+
let approvedVerdict;
|
|
1176
1202
|
if (params.freshWorktreeGate && !params.skipVerify) {
|
|
1177
1203
|
const tip = (await gitSoft(['rev-parse', '--verify', '--quiet', 'HEAD'], cwd, env)).stdout.trim();
|
|
1178
|
-
//
|
|
1179
|
-
//
|
|
1180
|
-
//
|
|
1204
|
+
// GATE-2 REVIEW callback (task `committed-recovery-always-reviews`): when
|
|
1205
|
+
// `input.review` is on, run Gate 2 on the rebased tip AFTER the green verify
|
|
1206
|
+
// — EXACTLY the build path's fresh-gate `review:` callback. A stranded
|
|
1207
|
+
// already-complete branch is NOT trusted as already-reviewed (its earlier
|
|
1208
|
+
// attempt's PR never merged, and Gate 2 may never have run on it); the same
|
|
1209
|
+
// reasoning that forces the re-verify here (`<arbiter>/main` moved, so the
|
|
1210
|
+
// merged tree is new) forces the re-review. The needs-attention ROUTING
|
|
1211
|
+
// targets `cwd` (the work branch + ledger), identical to the build path.
|
|
1212
|
+
const reviewInput = params.input;
|
|
1181
1213
|
const gated = await runFreshWorktreeGate({
|
|
1182
1214
|
cwd,
|
|
1183
1215
|
commit: tip,
|
|
@@ -1185,6 +1217,17 @@ async function recoverAlreadyCommitted(params) {
|
|
|
1185
1217
|
verify: params.verify,
|
|
1186
1218
|
env,
|
|
1187
1219
|
note,
|
|
1220
|
+
review: reviewInput?.review === true
|
|
1221
|
+
? (reviewCwd) => runGate2Review({
|
|
1222
|
+
reviewCwd,
|
|
1223
|
+
input: reviewInput,
|
|
1224
|
+
slug,
|
|
1225
|
+
branch,
|
|
1226
|
+
cwd,
|
|
1227
|
+
env,
|
|
1228
|
+
note,
|
|
1229
|
+
})
|
|
1230
|
+
: undefined,
|
|
1188
1231
|
});
|
|
1189
1232
|
if (!gated.passed) {
|
|
1190
1233
|
const outcome = gated.kind === 'prepare' ? 'prepare-failed' : 'gate-failed';
|
|
@@ -1207,15 +1250,43 @@ async function recoverAlreadyCommitted(params) {
|
|
|
1207
1250
|
routedToNeedsAttention: routed.moved,
|
|
1208
1251
|
branch,
|
|
1209
1252
|
reason: routed.moved
|
|
1210
|
-
? `${what} on the rebased tip during committed-recovery;
|
|
1211
|
-
`'${slug}'
|
|
1212
|
-
'
|
|
1253
|
+
? `${what} on the rebased tip during committed-recovery; marked ` +
|
|
1254
|
+
`'${slug}' stuck on its per-item lock (surfaced by status; ` +
|
|
1255
|
+
'`requeue` once resolved). Fix the work, or use --skip-verify ' +
|
|
1213
1256
|
'to override.'
|
|
1214
1257
|
: `${what} on the rebased tip during committed-recovery; not ` +
|
|
1215
1258
|
`completing '${slug}'. Fix the work, or use --skip-verify to ` +
|
|
1216
1259
|
'override.',
|
|
1217
1260
|
};
|
|
1218
1261
|
}
|
|
1262
|
+
// GATE-2 REVIEW outcome on the rebased tip: a BLOCK routes to needs-attention
|
|
1263
|
+
// exactly as the build path (only the reviewed tree moved, not the routing).
|
|
1264
|
+
// On APPROVE: carry the verdict for the post-integrate PR comment and write
|
|
1265
|
+
// the per-run non-blocking-nits observation. UNLIKE the build path this branch
|
|
1266
|
+
// integrates the ALREADY-committed kept tip (no upcoming done-move/commit to
|
|
1267
|
+
// sweep the nits file into), so we FOLD the observation into the kept commit
|
|
1268
|
+
// via `commit --amend` — mirroring the build path's fresh-gate amend so the
|
|
1269
|
+
// nits still land in the SAME commit that integrates (no separate commit).
|
|
1270
|
+
if (gated.review) {
|
|
1271
|
+
if (gated.review.kind === 'blocked') {
|
|
1272
|
+
return gated.review.result;
|
|
1273
|
+
}
|
|
1274
|
+
approvedVerdict = gated.review.verdict;
|
|
1275
|
+
const nitsBefore = await stagedCaptureNotes(cwd, env);
|
|
1276
|
+
writeReviewNitsObservation({
|
|
1277
|
+
cwd,
|
|
1278
|
+
slug,
|
|
1279
|
+
findings: gated.review.verdict?.findings ?? [],
|
|
1280
|
+
note,
|
|
1281
|
+
});
|
|
1282
|
+
await gitHard(['add', '-A'], cwd, env);
|
|
1283
|
+
if (!(await nothingStaged(cwd, env))) {
|
|
1284
|
+
const nitsAfter = await stagedCaptureNotes(cwd, env);
|
|
1285
|
+
if (nitsAfter.length > nitsBefore.length) {
|
|
1286
|
+
await gitHard(['commit', '-q', '--amend', '--no-edit'], cwd, env);
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1219
1290
|
}
|
|
1220
1291
|
// Integrate the rebased kept commit through the SAME complete-transition
|
|
1221
1292
|
// primitive the build path uses (no duplication of the integrate mechanism; the
|
|
@@ -1226,12 +1297,27 @@ async function recoverAlreadyCommitted(params) {
|
|
|
1226
1297
|
(params.openPr
|
|
1227
1298
|
? bridgeProvider(params.openPr)
|
|
1228
1299
|
: selectProvider({ arbiterUrl: await arbiterUrl(cwd, arbiter, env) }));
|
|
1300
|
+
// PR TITLE + BODY on the recovery path (task `committed-recovery-always-
|
|
1301
|
+
// reviews`): the stranded branch already holds the task in `work/done/`, so
|
|
1302
|
+
// synthesise the SAME single-line `<type>(<slug>): <title>` PR title the build
|
|
1303
|
+
// path does (from the done-resident task file, never agent text) and scaffold
|
|
1304
|
+
// the task-pointer body around the caller-supplied advisory `body`. Undefined
|
|
1305
|
+
// body ⇒ `composeProposeBody` returns undefined ⇒ the provider degrades to
|
|
1306
|
+
// `gh --fill` (no regression); a supplied body gives the PR a real description
|
|
1307
|
+
// instead of the blank one the recovery path used to open.
|
|
1308
|
+
const prTitle = synthesiseProposeTitle({
|
|
1309
|
+
type: (params.input?.type ?? DEFAULT_TYPE).trim() || DEFAULT_TYPE,
|
|
1310
|
+
slug,
|
|
1311
|
+
title: readTaskTitle(workItemPath(cwd, 'done', slug)),
|
|
1312
|
+
});
|
|
1229
1313
|
const integration = await ledgerWrite.applyCompleteTransition({
|
|
1230
1314
|
arbiter,
|
|
1231
1315
|
branch,
|
|
1232
1316
|
mode,
|
|
1233
1317
|
provider,
|
|
1234
1318
|
noPR: params.noPR,
|
|
1319
|
+
title: prTitle,
|
|
1320
|
+
body: composeProposeBody({ slug, body: params.body }),
|
|
1235
1321
|
deleteMergedHead: true,
|
|
1236
1322
|
cwd,
|
|
1237
1323
|
env,
|
|
@@ -1241,6 +1327,33 @@ async function recoverAlreadyCommitted(params) {
|
|
|
1241
1327
|
: `Recovered '${slug}': integrated the kept commit from ${branch} ` +
|
|
1242
1328
|
`(absorbed a moving ${arbiter}/main across ${attempt} re-fetch+re-` +
|
|
1243
1329
|
`rebase attempt${attempt === 1 ? '' : 's'}).`);
|
|
1330
|
+
// Post the Gate-2 review as a PR comment (task `committed-recovery-always-
|
|
1331
|
+
// reviews`): the SAME post-integrate audit trail the build path keeps — the
|
|
1332
|
+
// approved verdict's authored `review` prose, on the opened PR. Advisory only
|
|
1333
|
+
// (a block never reaches here — it returned above); the same URL/branch
|
|
1334
|
+
// precedence the build path uses (parsed url wins; else a branch-resolved
|
|
1335
|
+
// fallback when a PR opened but its url was unparseable). `postPRComment*`
|
|
1336
|
+
// never throws. A clean no-op in merge mode / push-only propose (no PR).
|
|
1337
|
+
if (approvedVerdict?.review !== undefined) {
|
|
1338
|
+
if (integration.url !== undefined) {
|
|
1339
|
+
const posted = provider.postPRComment({
|
|
1340
|
+
cwd,
|
|
1341
|
+
url: integration.url,
|
|
1342
|
+
body: approvedVerdict.review,
|
|
1343
|
+
env,
|
|
1344
|
+
});
|
|
1345
|
+
note(posted.instruction);
|
|
1346
|
+
}
|
|
1347
|
+
else if (integration.requestOpened) {
|
|
1348
|
+
const posted = provider.postPRCommentOnBranch({
|
|
1349
|
+
cwd,
|
|
1350
|
+
branch,
|
|
1351
|
+
body: approvedVerdict.review,
|
|
1352
|
+
env,
|
|
1353
|
+
});
|
|
1354
|
+
note(posted.instruction);
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1244
1357
|
return {
|
|
1245
1358
|
outcome: 'completed',
|
|
1246
1359
|
routedToNeedsAttention: false,
|
|
@@ -1278,8 +1391,9 @@ function resolveWorkBranch(cwd, slug, env) {
|
|
|
1278
1391
|
*
|
|
1279
1392
|
* Carries the {@link slug} so the autonomous-strand surface in `complete.ts`
|
|
1280
1393
|
* (which catches this error in `performComplete`'s outer try/catch, OUTSIDE the
|
|
1281
|
-
* `runComplete` slug scope) can
|
|
1282
|
-
*
|
|
1394
|
+
* `runComplete` slug scope) can mark the item stuck on its per-item lock (post
|
|
1395
|
+
* lock-cutover — the tree-less lock amend, no `in-progress/ → needs-attention/`
|
|
1396
|
+
* folder move) without re-deriving the slug from the error message.
|
|
1283
1397
|
*/
|
|
1284
1398
|
export class IntegrationNothingStaged extends Error {
|
|
1285
1399
|
slug;
|
|
@@ -1432,8 +1546,8 @@ export function composeProposeBody(input) {
|
|
|
1432
1546
|
* On a review APPROVE that carries ≥1 NON-BLOCKING finding, write ONE per-run
|
|
1433
1547
|
* observation `work/notes/observations/review-nits-<slug>-<YYYY-MM-DD>.md` capturing all
|
|
1434
1548
|
* of this run's non-blocking nits, so they get a durable, contract-native home
|
|
1435
|
-
* instead of evaporating (the block path already
|
|
1436
|
-
*
|
|
1549
|
+
* instead of evaporating (the block path already records BLOCKING findings as the
|
|
1550
|
+
* stuck reason on the item's per-item lock; the approve path dropped non-blocking ones — see
|
|
1437
1551
|
* `work/findings/review-nonblocking-findings-disposition.md`).
|
|
1438
1552
|
*
|
|
1439
1553
|
* The RUNNER writes it (the review agent stays write-free). It is a PLAIN
|
|
@@ -2018,8 +2132,8 @@ async function runGate2Review(params) {
|
|
|
2018
2132
|
});
|
|
2019
2133
|
const message = routed.moved
|
|
2020
2134
|
? `PR/code review (Gate 2) produced an UNPARSEABLE verdict for '${slug}'; ` +
|
|
2021
|
-
'
|
|
2022
|
-
'transient-infra — re-run). NOT integrated.'
|
|
2135
|
+
'marked it stuck on its per-item lock (work branch pushed + lock ' +
|
|
2136
|
+
'surfaced; transient-infra — re-run). NOT integrated.'
|
|
2023
2137
|
: `PR/code review (Gate 2) produced an UNPARSEABLE verdict for '${slug}'; ` +
|
|
2024
2138
|
'NOT integrating.';
|
|
2025
2139
|
note(message);
|
|
@@ -2064,9 +2178,9 @@ async function runGate2Review(params) {
|
|
|
2064
2178
|
note,
|
|
2065
2179
|
});
|
|
2066
2180
|
const message = routed.moved
|
|
2067
|
-
? `PR/code review (Gate 2) blocked '${slug}';
|
|
2068
|
-
'
|
|
2069
|
-
'recorded
|
|
2181
|
+
? `PR/code review (Gate 2) blocked '${slug}'; marked it stuck on its ` +
|
|
2182
|
+
'per-item lock (surfaced by status; the blocking findings are ' +
|
|
2183
|
+
'recorded on the lock entry). NOT integrated.'
|
|
2070
2184
|
: `PR/code review (Gate 2) blocked '${slug}'; NOT integrating.`;
|
|
2071
2185
|
note(message);
|
|
2072
2186
|
return {
|