wicked-crew 0.7.11 → 0.7.12

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.
Files changed (44) hide show
  1. package/dist/api/delivery-index.d.ts +21 -0
  2. package/dist/api/delivery-index.d.ts.map +1 -1
  3. package/dist/api/delivery-index.js +35 -0
  4. package/dist/api/delivery-index.js.map +1 -1
  5. package/dist/api/post-hoc-deliver.d.ts +27 -0
  6. package/dist/api/post-hoc-deliver.d.ts.map +1 -1
  7. package/dist/api/post-hoc-deliver.js +54 -0
  8. package/dist/api/post-hoc-deliver.js.map +1 -1
  9. package/dist/api/routes.d.ts +5 -1
  10. package/dist/api/routes.d.ts.map +1 -1
  11. package/dist/api/routes.js +124 -12
  12. package/dist/api/routes.js.map +1 -1
  13. package/dist/api/seat-health.d.ts +11 -0
  14. package/dist/api/seat-health.d.ts.map +1 -1
  15. package/dist/api/seat-health.js +23 -0
  16. package/dist/api/seat-health.js.map +1 -1
  17. package/dist/api/server.d.ts.map +1 -1
  18. package/dist/api/server.js +5 -1
  19. package/dist/api/server.js.map +1 -1
  20. package/dist/api/testing.d.ts.map +1 -1
  21. package/dist/api/testing.js +11 -27
  22. package/dist/api/testing.js.map +1 -1
  23. package/dist/campaigns/rollup.d.ts.map +1 -1
  24. package/dist/campaigns/rollup.js +17 -3
  25. package/dist/campaigns/rollup.js.map +1 -1
  26. package/dist/cli/index.js +13 -2
  27. package/dist/cli/index.js.map +1 -1
  28. package/dist/core/adapter.d.ts +0 -12
  29. package/dist/core/adapter.d.ts.map +1 -1
  30. package/dist/core/adapter.js +0 -14
  31. package/dist/core/adapter.js.map +1 -1
  32. package/dist/core/daemon-signal-log.d.ts +44 -0
  33. package/dist/core/daemon-signal-log.d.ts.map +1 -0
  34. package/dist/core/daemon-signal-log.js +57 -0
  35. package/dist/core/daemon-signal-log.js.map +1 -0
  36. package/dist/core/deliver.d.ts +20 -3
  37. package/dist/core/deliver.d.ts.map +1 -1
  38. package/dist/core/deliver.js +82 -9
  39. package/dist/core/deliver.js.map +1 -1
  40. package/package.json +2 -2
  41. package/dist/campaigns/worktrees.d.ts +0 -39
  42. package/dist/campaigns/worktrees.d.ts.map +0 -1
  43. package/dist/campaigns/worktrees.js +0 -95
  44. package/dist/campaigns/worktrees.js.map +0 -1
@@ -124,6 +124,27 @@ export declare function prUrlFrom(text: string): string | null;
124
124
  * overlay-carried deliver phases (crew#321).
125
125
  */
126
126
  export declare function deliverUnitOf(view: SessionView): WorkUnit | null;
127
+ /**
128
+ * Is this a `failed` run whose ONLY failure was the deliver phase's LIFT collision (crew#418)?
129
+ *
130
+ * The deliver phase is the LAST phase, so a rejected deliver unit whose `denial_reason` carries
131
+ * the deliver script's {@link DELIVER_LIFT_CONFLICT_MARKER} — with EVERY non-deliver unit still
132
+ * `done` — means the run's WORK is complete and committed on its `wicked/<id>` branch: only the
133
+ * lift into origin collided (a rebase conflict the changelog union merge could not clear, or a
134
+ * non-fast-forward push). The engine reports the run `failed` because a Tool phase exited
135
+ * non-zero; crew reinterprets THIS shape on the wire as `completed` + `delivery: 'stranded'`
136
+ * (recoverable via `POST /runs/:id/deliver`) — the same wire-derivation posture as `delivery`
137
+ * itself, leaving the engine's durable `failed` record untouched. The deliver unit stays
138
+ * `rejected` with its marker-bearing `denial_reason`, so WHY it stranded is still on the wire.
139
+ *
140
+ * FALSE — the run stays `failed` — for every genuine failure, because each misses a condition:
141
+ * - a rejected NON-deliver unit (a build/test/work phase failed) — `some(rejected)` guard;
142
+ * - a deliver rejection WITHOUT the marker: a spawn/infra fault (the crew#400 posture), a
143
+ * `gh` failure, nothing-to-deliver, or a wrong-worktree-branch refusal — the marker is the
144
+ * deliver script's own authority on WHY it refused, so crew never guesses from git's output;
145
+ * - a repo-less run (nothing to strand), or any non-`failed` status.
146
+ */
147
+ export declare function isDeliverConflictStranded(view: SessionView): boolean;
127
148
  export declare class DeliveryIndex {
128
149
  private readonly runToUrl;
129
150
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"delivery-index.d.ts","sourceRoot":"","sources":["../../src/api/delivery-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAG5E,kGAAkG;AAClG,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,WAAW,GAAG,UAAU,GAAG,SAAS,GAAG,MAAM,CAAC;IACxD,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC,EAC9D,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GACxC,aAAa,CAYf;AAED;6FAC6F;AAC7F,MAAM,WAAW,aAAa;IAC5B,kFAAkF;IAClF,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAC1C,2FAA2F;IAC3F,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACpD;0FACsF;IACtF,gBAAgB,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACxE;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC,EACrE,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,aAAa,CAAC,CAiBxB;AAED;;gFAEgF;AAChF,eAAO,MAAM,qBAAqB,QAAS,CAAC;AAE5C;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,GAAE,MAA8B,EACrC,GAAG,GAAE,MAAM,MAAiB,GAC3B,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CA4BpC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CACjC,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,EACjE,KAAK,GAAE,MAA8B,EACrC,GAAG,GAAE,MAAM,MAAiB,GAC3B,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CA4CtD;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGrD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,WAAW,GAAG,QAAQ,GAAG,IAAI,CAIhE;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA6B;IAEtD;;;;;;;;OAQG;IACG,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAsB1E,8EAA8E;IAC9E,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAIrC;;;;OAIG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;CAG1C"}
1
+ {"version":3,"file":"delivery-index.d.ts","sourceRoot":"","sources":["../../src/api/delivery-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAI5E,kGAAkG;AAClG,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,WAAW,GAAG,UAAU,GAAG,SAAS,GAAG,MAAM,CAAC;IACxD,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC,EAC9D,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GACxC,aAAa,CAYf;AAED;6FAC6F;AAC7F,MAAM,WAAW,aAAa;IAC5B,kFAAkF;IAClF,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAC1C,2FAA2F;IAC3F,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACpD;0FACsF;IACtF,gBAAgB,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACxE;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC,EACrE,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,aAAa,CAAC,CAiBxB;AAED;;gFAEgF;AAChF,eAAO,MAAM,qBAAqB,QAAS,CAAC;AAE5C;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,GAAE,MAA8B,EACrC,GAAG,GAAE,MAAM,MAAiB,GAC3B,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CA4BpC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CACjC,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,EACjE,KAAK,GAAE,MAA8B,EACrC,GAAG,GAAE,MAAM,MAAiB,GAC3B,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CA4CtD;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGrD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,WAAW,GAAG,QAAQ,GAAG,IAAI,CAIhE;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CASpE;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA6B;IAEtD;;;;;;;;OAQG;IACG,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAsB1E,8EAA8E;IAC9E,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAIrC;;;;OAIG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;CAG1C"}
@@ -21,6 +21,7 @@
21
21
  * the per-run output endpoint.
22
22
  */
23
23
  import { execCapped } from '../core/exec.js';
24
+ import { DELIVER_LIFT_CONFLICT_MARKER } from '../core/deliver.js';
24
25
  /**
25
26
  * The tri-state delivery derivation (crew#393) — HONEST by construction, computed at DTO
26
27
  * assembly from three facts and nothing else:
@@ -217,6 +218,40 @@ export function deliverUnitOf(view) {
217
218
  return byId;
218
219
  return view.units.find((u) => (u.tool_cmd ?? []).join(' ').includes('gh pr create')) ?? null;
219
220
  }
221
+ /**
222
+ * Is this a `failed` run whose ONLY failure was the deliver phase's LIFT collision (crew#418)?
223
+ *
224
+ * The deliver phase is the LAST phase, so a rejected deliver unit whose `denial_reason` carries
225
+ * the deliver script's {@link DELIVER_LIFT_CONFLICT_MARKER} — with EVERY non-deliver unit still
226
+ * `done` — means the run's WORK is complete and committed on its `wicked/<id>` branch: only the
227
+ * lift into origin collided (a rebase conflict the changelog union merge could not clear, or a
228
+ * non-fast-forward push). The engine reports the run `failed` because a Tool phase exited
229
+ * non-zero; crew reinterprets THIS shape on the wire as `completed` + `delivery: 'stranded'`
230
+ * (recoverable via `POST /runs/:id/deliver`) — the same wire-derivation posture as `delivery`
231
+ * itself, leaving the engine's durable `failed` record untouched. The deliver unit stays
232
+ * `rejected` with its marker-bearing `denial_reason`, so WHY it stranded is still on the wire.
233
+ *
234
+ * FALSE — the run stays `failed` — for every genuine failure, because each misses a condition:
235
+ * - a rejected NON-deliver unit (a build/test/work phase failed) — `some(rejected)` guard;
236
+ * - a deliver rejection WITHOUT the marker: a spawn/infra fault (the crew#400 posture), a
237
+ * `gh` failure, nothing-to-deliver, or a wrong-worktree-branch refusal — the marker is the
238
+ * deliver script's own authority on WHY it refused, so crew never guesses from git's output;
239
+ * - a repo-less run (nothing to strand), or any non-`failed` status.
240
+ */
241
+ export function isDeliverConflictStranded(view) {
242
+ if (view.session.status !== 'failed')
243
+ return false;
244
+ if (view.session.repo_ref == null)
245
+ return false;
246
+ const deliver = deliverUnitOf(view);
247
+ if (deliver === null || deliver.status !== 'rejected')
248
+ return false;
249
+ // A rejected unit that is NOT the deliver phase = a genuine work/build/test failure, not a
250
+ // clean run whose only casualty was the lift.
251
+ if (view.units.some((u) => u.id !== deliver.id && u.status === 'rejected'))
252
+ return false;
253
+ return (deliver.denial_reason ?? '').includes(DELIVER_LIFT_CONFLICT_MARKER);
254
+ }
220
255
  export class DeliveryIndex {
221
256
  runToUrl = new Map();
222
257
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"delivery-index.js","sourceRoot":"","sources":["../../src/api/delivery-index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"delivery-index.js","sourceRoot":"","sources":["../../src/api/delivery-index.ts"],"names":[],"mappings":"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"}
@@ -28,6 +28,33 @@ export interface DeliverScriptResult {
28
28
  /** The exec seam the deliver route runs the script through — injectable so route tests can
29
29
  * point HOME/PATH at a fixture (a stub `gh`, a temp home) without touching the daemon env. */
30
30
  export type DeliverExec = (workdir: string, intent?: string) => Promise<DeliverScriptResult>;
31
+ /** A worktree stood back up from a run's `wicked/<id>` branch, plus its teardown (crew#418). */
32
+ export interface ReprovisionedWorktree {
33
+ /** The path to deliver in — a throwaway checkout of `wicked/<runId>`. */
34
+ workdir: string;
35
+ /** Remove the throwaway worktree; the `wicked/<runId>` branch (the record) survives. */
36
+ cleanup: () => Promise<void>;
37
+ }
38
+ /** The reprovision seam (crew#418) — injectable so route tests never shell out to git. Resolves
39
+ * to a throwaway worktree checked out on the run's branch, or `null` when the branch is gone. */
40
+ export type WorktreeReprovisioner = (repoRoot: string, runId: string) => Promise<ReprovisionedWorktree | null>;
41
+ /**
42
+ * Stand a run's committed work back up from its `wicked/<runId>` branch (crew#418).
43
+ *
44
+ * The engine REAPS a failed-deliver run's worktree once the deliver phase has committed the work
45
+ * (a clean tree; `git worktree remove` succeeds even with the branch ahead) — the work then lives
46
+ * ONLY on the `wicked/<runId>` branch, which the reap never deletes ("the checkout is scaffolding,
47
+ * the branch is the record"). A post-hoc lift therefore has no worktree to run in; this checks the
48
+ * branch out at a THROWAWAY path so the hardened deliver script can commit-nothing / rebase / push
49
+ * it. The path's basename is deliberately NOT the run id, so the script's branch derivation falls
50
+ * back to `git branch --show-current` — which the checkout puts on `wicked/<runId>` — instead of
51
+ * `wicked/<basename>`. Never touches the engine's recorded worktree path, so it cannot race the
52
+ * engine's own worktree bookkeeping.
53
+ *
54
+ * Resolves `null` when the branch does not exist (nothing to reprovision) — the caller then
55
+ * answers the same "nothing to deliver" refusal as a truly empty run.
56
+ */
57
+ export declare const gitReprovisionWorktree: WorktreeReprovisioner;
31
58
  /**
32
59
  * The production {@link DeliverExec}: `bash -lc <script>` in the run's worktree — the exact
33
60
  * invocation core's `run_tool_cmd` uses for the deliver phase (login shell, so the operator's
@@ -1 +1 @@
1
- {"version":3,"file":"post-hoc-deliver.d.ts","sourceRoot":"","sources":["../../src/api/post-hoc-deliver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,wFAAwF;AACxF,MAAM,WAAW,mBAAmB;IAClC,6FAA6F;IAC7F,MAAM,EAAE,MAAM,CAAC;IACf,gGAAgG;IAChG,MAAM,EAAE,MAAM,CAAC;IACf;+FAC2F;IAC3F,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;+FAC+F;AAC/F,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAQ7F;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,MAAM,EACf,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC3B,OAAO,CAAC,mBAAmB,CAAC,CA+B9B"}
1
+ {"version":3,"file":"post-hoc-deliver.d.ts","sourceRoot":"","sources":["../../src/api/post-hoc-deliver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AASH,wFAAwF;AACxF,MAAM,WAAW,mBAAmB;IAClC,6FAA6F;IAC7F,MAAM,EAAE,MAAM,CAAC;IACf,gGAAgG;IAChG,MAAM,EAAE,MAAM,CAAC;IACf;+FAC2F;IAC3F,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;+FAC+F;AAC/F,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAE7F,gGAAgG;AAChG,MAAM,WAAW,qBAAqB;IACpC,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAC;IAChB,wFAAwF;IACxF,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED;kGACkG;AAClG,MAAM,MAAM,qBAAqB,GAAG,CAClC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,KACV,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAAC;AAE3C;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,sBAAsB,EAAE,qBAmCpC,CAAC;AAQF;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,MAAM,EACf,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC3B,OAAO,CAAC,mBAAmB,CAAC,CA+B9B"}
@@ -16,7 +16,61 @@
16
16
  * crew-side via `prUrlFrom`, the same grep the script itself ends with).
17
17
  */
18
18
  import { execFile } from 'node:child_process';
19
+ import { mkdtemp, rm } from 'node:fs/promises';
20
+ import { tmpdir } from 'node:os';
21
+ import { join } from 'node:path';
19
22
  import { deliverPrScript } from '../core/deliver.js';
23
+ /**
24
+ * Stand a run's committed work back up from its `wicked/<runId>` branch (crew#418).
25
+ *
26
+ * The engine REAPS a failed-deliver run's worktree once the deliver phase has committed the work
27
+ * (a clean tree; `git worktree remove` succeeds even with the branch ahead) — the work then lives
28
+ * ONLY on the `wicked/<runId>` branch, which the reap never deletes ("the checkout is scaffolding,
29
+ * the branch is the record"). A post-hoc lift therefore has no worktree to run in; this checks the
30
+ * branch out at a THROWAWAY path so the hardened deliver script can commit-nothing / rebase / push
31
+ * it. The path's basename is deliberately NOT the run id, so the script's branch derivation falls
32
+ * back to `git branch --show-current` — which the checkout puts on `wicked/<runId>` — instead of
33
+ * `wicked/<basename>`. Never touches the engine's recorded worktree path, so it cannot race the
34
+ * engine's own worktree bookkeeping.
35
+ *
36
+ * Resolves `null` when the branch does not exist (nothing to reprovision) — the caller then
37
+ * answers the same "nothing to deliver" refusal as a truly empty run.
38
+ */
39
+ export const gitReprovisionWorktree = async (repoRoot, runId) => {
40
+ const branch = `wicked/${runId}`;
41
+ const run = (args) => new Promise((resolve, reject) => {
42
+ execFile('git', ['-C', repoRoot, ...args], { windowsHide: true }, (err) => err === null ? resolve() : reject(err));
43
+ });
44
+ const dir = await mkdtemp(join(tmpdir(), `wicked-deliver-${runId.replace(/[^\w.-]/g, '_')}-`));
45
+ // Is the run's branch even there? Absent ⇒ the work is genuinely GONE → null (the route answers
46
+ // 409 "nothing to deliver"). This is the ONLY reason to report null: an OPERATIONAL git failure
47
+ // below (permissions, corruption, a busy repo) must surface as an error, not be misreported as
48
+ // "gone" — so it is left to throw and the route answers 500.
49
+ try {
50
+ await run(['rev-parse', '--verify', '--quiet', `refs/heads/${branch}`]);
51
+ }
52
+ catch {
53
+ await rm(dir, { recursive: true, force: true }).catch(() => undefined);
54
+ return null;
55
+ }
56
+ try {
57
+ // Drop any dangling admin entry the reap left, THEN check the branch out at the empty temp dir
58
+ // (`git worktree add` accepts an existing empty directory).
59
+ await run(['worktree', 'prune']);
60
+ await run(['worktree', 'add', dir, branch]);
61
+ }
62
+ catch (err) {
63
+ await rm(dir, { recursive: true, force: true }).catch(() => undefined);
64
+ throw err; // operational failure standing the worktree up — NOT "gone"
65
+ }
66
+ return {
67
+ workdir: dir,
68
+ cleanup: async () => {
69
+ await run(['worktree', 'remove', '--force', dir]).catch(() => undefined);
70
+ await rm(dir, { recursive: true, force: true }).catch(() => undefined);
71
+ },
72
+ };
73
+ };
20
74
  /** Everything the script prints stays bounded — 8 MiB is far past any real transcript. */
21
75
  const OUTPUT_CAP_BYTES = 8 * 1024 * 1024;
22
76
  /** A post-hoc lift talks to a real remote; 5 minutes is generous, hanging forever is not. */
@@ -1 +1 @@
1
- {"version":3,"file":"post-hoc-deliver.js","sourceRoot":"","sources":["../../src/api/post-hoc-deliver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAiBrD,0FAA0F;AAC1F,MAAM,gBAAgB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAEzC,6FAA6F;AAC7F,MAAM,iBAAiB,GAAG,CAAC,GAAG,MAAM,CAAC;AAErC;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAC9B,OAAe,EACf,MAAe,EACf,GAA4B;IAE5B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,QAAQ,CACN,MAAM,EACN,CAAC,KAAK,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC,EAChC;YACE,GAAG,EAAE,OAAO;YACZ,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,EAAE;YAC/B,SAAS,EAAE,gBAAgB;YAC3B,OAAO,EAAE,iBAAiB;SAC3B,EACD,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YACtB,uFAAuF;YACvF,oFAAoF;YACpF,MAAM,MAAM,GAAG,GAAG,MAAM,IAAI,EAAE,GAAG,MAAM,IAAI,EAAE,EAAE,CAAC;YAChD,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;gBACjB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;gBAC/B,OAAO;YACT,CAAC;YACD,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,GAA2C,CAAC;YACrE,qFAAqF;YACrF,kFAAkF;YAClF,gFAAgF;YAChF,OAAO,CAAC;gBACN,MAAM,EAAE,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAC3C,MAAM,EAAE,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAE,GAAa,CAAC,OAAO;gBACvD,YAAY,EAAE,OAAO,IAAI,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI;aAC1D,CAAC,CAAC;QACL,CAAC,CACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"post-hoc-deliver.js","sourceRoot":"","sources":["../../src/api/post-hoc-deliver.ts"],"names":[],"mappings":"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"}
@@ -14,7 +14,7 @@ import { RetryIndex } from './retry-index.js';
14
14
  import { GroupIndex } from './group-index.js';
15
15
  import { GuidanceIndex } from './guidance-index.js';
16
16
  import { DeliveryIndex } from './delivery-index.js';
17
- import { type DeliverExec } from './post-hoc-deliver.js';
17
+ import { type DeliverExec, type WorktreeReprovisioner } from './post-hoc-deliver.js';
18
18
  import { type AuthMode } from './auth.js';
19
19
  export { API_PREFIX } from './api-prefix.js';
20
20
  /**
@@ -235,6 +235,10 @@ export interface RuntimeDeps {
235
235
  * deliver script in a run's worktree. Injectable so route tests aim the spawn's HOME/PATH at
236
236
  * a fixture (stub `gh`, local bare origin); defaults to the real `bash -lc` spawn. */
237
237
  deliverExec?: DeliverExec;
238
+ /** Stand a lift-conflict-stranded run's worktree back up from its `wicked/<id>` branch when the
239
+ * engine has reaped it (crew#418) — the post-hoc deliver path uses it before the exec above.
240
+ * Injectable so route tests never shell out to git; defaults to {@link gitReprovisionWorktree}. */
241
+ reprovisionWorktree?: WorktreeReprovisioner;
238
242
  openWithOs?: (target: string) => Promise<void>;
239
243
  /** Seat sign-in presence probe (seat sign-in) — injectable so route tests never read the
240
244
  * developer's real dotfiles. Defaults to the file/env heuristic in seat-signin.ts. */
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/api/routes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/api/routes.ts"],"names":[],"mappings":"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"}
@@ -34,8 +34,8 @@ import { AcpFoldCache, EngineVersionCache, eventsDirOf, installedPackageVersion,
34
34
  import { RetryIndex } from './retry-index.js';
35
35
  import { GroupIndex } from './group-index.js';
36
36
  import { GuidanceIndex } from './guidance-index.js';
37
- import { DeliveryIndex, deliveryStateWithVacuity, gitRunBranchIsEmpty, gitWorktreeIsClean, prUrlFrom, } from './delivery-index.js';
38
- import { runDeliverScript } from './post-hoc-deliver.js';
37
+ import { DeliveryIndex, deliveryStateWithVacuity, gitRunBranchIsEmpty, gitWorktreeIsClean, isDeliverConflictStranded, prUrlFrom, } from './delivery-index.js';
38
+ import { gitReprovisionWorktree, runDeliverScript, } from './post-hoc-deliver.js';
39
39
  import { LOCAL_ACTOR } from './auth.js';
40
40
  // Re-exported so existing `import { API_PREFIX } from './routes.js'` callers keep working; the
41
41
  // value lives in the leaf module api-prefix.ts to keep unit-output.ts out of this file's cycle.
@@ -263,6 +263,9 @@ runtime = {}) {
263
263
  }),
264
264
  };
265
265
  const deliverExec = runtime.deliverExec ?? runDeliverScript;
266
+ const reprovisionWorktree = runtime.reprovisionWorktree ?? gitReprovisionWorktree;
267
+ /** Repo root for a repo ref, from the registry — shared by the reprovision path below. */
268
+ const repoRootOf = async (repoRef) => (await adapter.listRepos()).find((r) => r.id === repoRef)?.root_path;
266
269
  // The run-DTO joins (DES-UX-001 §8.2/§8.3, DES-UX-002 §7.2): `project_id` from the membership
267
270
  // record — `null` = genuinely unfiled, so the field is ALWAYS present on served runs —
268
271
  // `retry_of` from the lineage index and `guidance` from the guidance index, each set only
@@ -275,7 +278,42 @@ runtime = {}) {
275
278
  // "done" with nothing produced must be LOUD on the wire, never silently green.
276
279
  // Applied at DTO assembly on exactly the two endpoints that serve the run DTO
277
280
  // (GET /runs + GET /runs/:id); the internal sessionsDetail() consumers are untouched.
281
+ // crew#418 A: a `failed` run whose ONLY failure was the deliver phase's LIFT collision (a
282
+ // rebase conflict the changelog union merge could not clear, or a non-fast-forward push) is
283
+ // reinterpreted on the wire as `completed` + `delivery: 'stranded'` — recoverable, not a hard
284
+ // failure. The engine's durable record stays `failed` (audit trail); this is a wire derivation,
285
+ // exactly like `delivery` itself, applied at the SAME three terminal-status decision points so
286
+ // the run reads consistently across GET /runs(/:id), resume, and POST /runs/:id/deliver. The
287
+ // deliver unit stays `rejected` with its marker-bearing `denial_reason`, so WHY it stranded is
288
+ // still on the wire.
289
+ //
290
+ // Returns whether this run IS such a strand — the caller uses it for a BRANCH-based `'stranded'`
291
+ // read: the engine reaps a failed-deliver run's worktree once the deliver phase has committed
292
+ // the work (a clean tree), so the work lives on the `wicked/<id>` branch, not the worktree — the
293
+ // worktree-stat derivation would read `'none'` (and flicker as the async reap lands). The
294
+ // lift-conflict marker is proof the branch carries the work (the deliver script verified it was
295
+ // ahead of the default branch before it ever attempted the rebase), so the read is a STABLE
296
+ // `'stranded'` regardless of whether the worktree survived. Idempotent: a second call sees the
297
+ // already-flipped `completed` and returns false, so the flip never re-fires.
298
+ const normalizeStranded = (view) => {
299
+ const conflictStrand = isDeliverConflictStranded(view); // true only while status === 'failed'
300
+ if (conflictStrand)
301
+ view.session.status = 'completed';
302
+ return conflictStrand;
303
+ };
304
+ /** The run's delivery state, honest by construction (crew#393/#311/#418): a recorded PR wins
305
+ * (`'delivered'`); else a lift-conflict strand reads `'stranded'` from the branch; else the
306
+ * worktree-stat derivation (stranded / vacuous / none). */
307
+ const resolveDelivery = async (view, conflictStrand) => {
308
+ const url = deliveryIndex.urlFor(view.session.id);
309
+ if (url !== undefined)
310
+ return { delivery: 'delivered', deliverUrl: url };
311
+ if (conflictStrand)
312
+ return { delivery: 'stranded' };
313
+ return deliveryStateWithVacuity(view.session, undefined, vacuityProbes);
314
+ };
278
315
  const decorateRun = async (view) => {
316
+ const conflictStrand = normalizeStranded(view);
279
317
  view.session.project_id = projects.index.projectOf(view.session.id) ?? null;
280
318
  const retryOf = retryIndex.retryOfFor(view.session.id);
281
319
  if (retryOf !== undefined)
@@ -292,7 +330,7 @@ runtime = {}) {
292
330
  const guidance = guidanceIndex.guidanceFor(view.session.id);
293
331
  if (guidance !== undefined)
294
332
  view.session.guidance = guidance;
295
- const state = await deliveryStateWithVacuity(view.session, deliveryIndex.urlFor(view.session.id), vacuityProbes);
333
+ const state = await resolveDelivery(view, conflictStrand);
296
334
  view.session.delivery = state.delivery;
297
335
  if (state.deliverUrl !== undefined)
298
336
  view.session.deliverUrl = state.deliverUrl;
@@ -906,6 +944,30 @@ runtime = {}) {
906
944
  // existing worktree. Idempotent: a delivered run answers its recorded URL, never a second PR.
907
945
  // Failure is a loud 4xx/5xx carrying the script's own words — never a silent 200.
908
946
  const deliverInFlight = new Set();
947
+ // Per-REPO serialization for the worktree-admin-sensitive region (reprovision → deliver →
948
+ // cleanup). deliverInFlight is per-RUN and stops the same run double-delivering, but two
949
+ // DIFFERENT stranded runs in the same repo would both run `git worktree prune/add/remove`
950
+ // against one `.git/worktrees` admin state and race. Chaining a promise per repo ref serializes
951
+ // them; different repos still run in parallel. The tail entry is pruned so the map cannot grow.
952
+ const repoDeliverChain = new Map();
953
+ const withRepoDeliverLock = async (repoRef, fn) => {
954
+ const prior = repoDeliverChain.get(repoRef) ?? Promise.resolve();
955
+ let release;
956
+ const mine = new Promise((r) => {
957
+ release = r;
958
+ });
959
+ repoDeliverChain.set(repoRef, mine); // WE are now the tail
960
+ await prior.catch(() => undefined); // wait our turn; a prior failure never blocks ours
961
+ try {
962
+ return await fn();
963
+ }
964
+ finally {
965
+ release(); // unblock whoever chained after us
966
+ // If nothing chained after us, drop the entry so idle repos leave no trace.
967
+ if (repoDeliverChain.get(repoRef) === mine)
968
+ repoDeliverChain.delete(repoRef);
969
+ }
970
+ };
909
971
  /** The last words of a failed deliver script — enough to name the refusal, bounded so a full
910
972
  * git transcript never becomes an error body. */
911
973
  const deliverErrorTail = (output) => {
@@ -934,6 +996,10 @@ runtime = {}) {
934
996
  const run = views.find((v) => v.session.id === id);
935
997
  if (!run)
936
998
  return reply.code(404).send({ error: 'Run not found' });
999
+ // crew#418 A: a run stranded by a deliver-phase lift collision reads `failed` from the
1000
+ // engine but IS liftable post-hoc — normalize its status to `completed` so this route
1001
+ // accepts it, exactly as the run wire and the resume route see it.
1002
+ const conflictStrand = normalizeStranded(run);
937
1003
  const s = run.session;
938
1004
  if (s.status !== 'completed') {
939
1005
  return reply.code(409).send({
@@ -945,22 +1011,55 @@ runtime = {}) {
945
1011
  error: `run ${id} is not repo-scoped — there is no worktree to lift into a PR`,
946
1012
  });
947
1013
  }
948
- if (!worktreeExists(s.workdir)) {
949
- return reply.code(409).send({
950
- error: `run ${id}'s worktree is gone (${s.workdir}) — nothing left to deliver`,
951
- });
952
- }
1014
+ // Capture the ref + workdir while the null-check narrowing is fresh — an intervening await
1015
+ // below invalidates property narrowing, so re-reading `s.repo_ref`/`s.workdir` later widens
1016
+ // back to `| null`.
1017
+ const repoRef = s.repo_ref;
1018
+ const initialWorkdir = s.workdir;
953
1019
  // One delivery per run at a time: the script pushes and opens a PR, so two concurrent
954
- // spawns could race gh into two PRs — the exact double-open idempotency forbids.
1020
+ // spawns could race gh into two PRs — the exact double-open idempotency forbids. The guard
1021
+ // wraps the reprovision too, so a reaped run's `wicked/<id>` branch is only ever checked out
1022
+ // by one throwaway worktree at a time.
955
1023
  if (deliverInFlight.has(id)) {
956
1024
  return reply.code(409).send({
957
1025
  error: `a delivery for run ${id} is already in progress — wait for it to finish`,
958
1026
  });
959
1027
  }
960
1028
  deliverInFlight.add(id);
1029
+ // The worktree the script runs in. Usually the run's own; but the engine REAPS a
1030
+ // failed-deliver run's worktree once its work is committed (crew#418) — the work then lives
1031
+ // on the `wicked/<id>` branch. For such a strand, stand a throwaway worktree back up from
1032
+ // that branch and lift THAT; the branch (the record) is untouched. `cleanupWorktree` tears
1033
+ // the throwaway down after the lift.
961
1034
  let result;
1035
+ let worktreeGone = false;
962
1036
  try {
963
- result = await deliverExec(s.workdir, s.problem);
1037
+ // The worktree admin (reprovision), the deliver spawn, AND the throwaway teardown all run
1038
+ // under the per-repo lock, so a second stranded run in this repo cannot touch
1039
+ // `.git/worktrees` until this one has stood its worktree up, lifted, and torn it back
1040
+ // down. `cw` is a LOCAL torn down in the lock body's own finally — nothing captured-mutated
1041
+ // crosses the closure boundary.
1042
+ await withRepoDeliverLock(repoRef, async () => {
1043
+ let workdir = initialWorkdir;
1044
+ let cw = null;
1045
+ try {
1046
+ if (!worktreeExists(workdir)) {
1047
+ const root = conflictStrand ? await repoRootOf(repoRef) : undefined;
1048
+ const reprov = root !== undefined ? await reprovisionWorktree(root, id) : null;
1049
+ if (reprov === null) {
1050
+ worktreeGone = true;
1051
+ return;
1052
+ }
1053
+ workdir = reprov.workdir;
1054
+ cw = reprov.cleanup;
1055
+ }
1056
+ result = await deliverExec(workdir, s.problem ?? undefined);
1057
+ }
1058
+ finally {
1059
+ if (cw !== null)
1060
+ await cw(); // tear the throwaway down whether the lift succeeded or threw
1061
+ }
1062
+ });
964
1063
  }
965
1064
  catch (err) {
966
1065
  return reply.code(500).send({ error: `deliver script could not run: ${message(err)}` });
@@ -968,6 +1067,15 @@ runtime = {}) {
968
1067
  finally {
969
1068
  deliverInFlight.delete(id);
970
1069
  }
1070
+ if (worktreeGone) {
1071
+ return reply.code(409).send({
1072
+ error: `run ${id}'s worktree is gone (${s.workdir}) — nothing left to deliver`,
1073
+ });
1074
+ }
1075
+ if (result === undefined) {
1076
+ // Unreachable: the lock body assigns `result` on every path that is not `worktreeGone`.
1077
+ return reply.code(500).send({ error: `deliver for run ${id} produced no result` });
1078
+ }
971
1079
  if (result.spawnFailure === true) {
972
1080
  // The script never reached its own verdict (spawn failure, timeout kill) — an infra
973
1081
  // fault, not a refusal: 500 so the caller knows a retry is reasonable.
@@ -1342,6 +1450,10 @@ runtime = {}) {
1342
1450
  const run = views.find((v) => v.session.id === id);
1343
1451
  if (!run)
1344
1452
  return reply.code(404).send({ error: 'Run not found' });
1453
+ // crew#418 A: a run stranded by a deliver-phase lift collision reads `failed` from the engine
1454
+ // but its work is complete and liftable — normalize to `completed` so the terminal branch
1455
+ // below refuses resume with the DELIVER recovery (POST /runs/:id/deliver), not a re-entry.
1456
+ const conflictStrand = normalizeStranded(run);
1345
1457
  // A TERMINAL run is refused LOUDLY, with the actual recovery named (crew#311 defect 2).
1346
1458
  // The engine's `resume_run` no-ops on completed/cancelled and answers the status token, so
1347
1459
  // this route used to reply 200 {"status":"cancelled"} — on the exact runs an operator was
@@ -1351,14 +1463,14 @@ runtime = {}) {
1351
1463
  // The 409 body carries the machine-readable pointer (`ResumeRefusal` in api-types).
1352
1464
  const terminal = run.session.status;
1353
1465
  if (terminal === 'completed' || terminal === 'cancelled') {
1354
- const state = await deliveryStateWithVacuity(run.session, deliveryIndex.urlFor(id), vacuityProbes);
1466
+ const state = await resolveDelivery(run, conflictStrand);
1355
1467
  const recovery = terminal === 'completed' && state.delivery === 'stranded'
1356
1468
  ? 'deliver'
1357
1469
  : 'retry';
1358
1470
  const why = terminal === 'cancelled'
1359
1471
  ? `run ${id} is cancelled — a terminal run cannot be resumed; relaunch the work as a new run with POST /runs {"retryOf":"${id}"}`
1360
1472
  : state.delivery === 'stranded'
1361
- ? `run ${id} is already completed — nothing to resume; its unlifted work is in the worktree: deliver it with POST /runs/${id}/deliver`
1473
+ ? `run ${id} is already completed — nothing to resume; its unlifted work is on the wicked/${id} branch: deliver it with POST /runs/${id}/deliver`
1362
1474
  : state.delivery === 'vacuous'
1363
1475
  ? `run ${id} is already completed, but VACUOUSLY — its units produced no work to resume or deliver; relaunch with POST /runs {"retryOf":"${id}"}`
1364
1476
  : `run ${id} is already completed — nothing to resume; relaunch the work as a new run with POST /runs {"retryOf":"${id}"}`;