wicked-crew 0.7.8 → 0.7.9

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 (119) hide show
  1. package/dist/api/audit.d.ts +9 -1
  2. package/dist/api/audit.d.ts.map +1 -1
  3. package/dist/api/audit.js +11 -3
  4. package/dist/api/audit.js.map +1 -1
  5. package/dist/api/delivery-index.d.ts +94 -7
  6. package/dist/api/delivery-index.d.ts.map +1 -1
  7. package/dist/api/delivery-index.js +182 -4
  8. package/dist/api/delivery-index.js.map +1 -1
  9. package/dist/api/elicitation-cache.d.ts +10 -0
  10. package/dist/api/elicitation-cache.d.ts.map +1 -1
  11. package/dist/api/elicitation-cache.js +18 -0
  12. package/dist/api/elicitation-cache.js.map +1 -1
  13. package/dist/api/governance-steering.d.ts +8 -0
  14. package/dist/api/governance-steering.d.ts.map +1 -1
  15. package/dist/api/governance-steering.js +36 -12
  16. package/dist/api/governance-steering.js.map +1 -1
  17. package/dist/api/post-hoc-deliver.d.ts +38 -0
  18. package/dist/api/post-hoc-deliver.d.ts.map +1 -0
  19. package/dist/api/post-hoc-deliver.js +57 -0
  20. package/dist/api/post-hoc-deliver.js.map +1 -0
  21. package/dist/api/routes.d.ts +34 -7
  22. package/dist/api/routes.d.ts.map +1 -1
  23. package/dist/api/routes.js +314 -35
  24. package/dist/api/routes.js.map +1 -1
  25. package/dist/api/seat-signin.d.ts +18 -2
  26. package/dist/api/seat-signin.d.ts.map +1 -1
  27. package/dist/api/seat-signin.js +21 -2
  28. package/dist/api/seat-signin.js.map +1 -1
  29. package/dist/api/server.d.ts +22 -7
  30. package/dist/api/server.d.ts.map +1 -1
  31. package/dist/api/server.js +131 -22
  32. package/dist/api/server.js.map +1 -1
  33. package/dist/api/stall-watchdog.d.ts +46 -21
  34. package/dist/api/stall-watchdog.d.ts.map +1 -1
  35. package/dist/api/stall-watchdog.js +193 -19
  36. package/dist/api/stall-watchdog.js.map +1 -1
  37. package/dist/api/steering-landing.d.ts +130 -0
  38. package/dist/api/steering-landing.d.ts.map +1 -0
  39. package/dist/api/steering-landing.js +367 -0
  40. package/dist/api/steering-landing.js.map +1 -0
  41. package/dist/api/testing.d.ts +3 -0
  42. package/dist/api/testing.d.ts.map +1 -1
  43. package/dist/api/testing.js +146 -18
  44. package/dist/api/testing.js.map +1 -1
  45. package/dist/api/unit-output.d.ts.map +1 -1
  46. package/dist/api/unit-output.js +7 -1
  47. package/dist/api/unit-output.js.map +1 -1
  48. package/dist/campaigns/plan.d.ts +46 -0
  49. package/dist/campaigns/plan.d.ts.map +1 -1
  50. package/dist/campaigns/plan.js +80 -0
  51. package/dist/campaigns/plan.js.map +1 -1
  52. package/dist/campaigns/routes.d.ts +2 -2
  53. package/dist/campaigns/worktrees.d.ts +39 -0
  54. package/dist/campaigns/worktrees.d.ts.map +1 -0
  55. package/dist/campaigns/worktrees.js +95 -0
  56. package/dist/campaigns/worktrees.js.map +1 -0
  57. package/dist/cli/index.js +46 -13
  58. package/dist/cli/index.js.map +1 -1
  59. package/dist/core/adapter.d.ts +65 -13
  60. package/dist/core/adapter.d.ts.map +1 -1
  61. package/dist/core/adapter.js +148 -31
  62. package/dist/core/adapter.js.map +1 -1
  63. package/dist/core/bridge-reaper.d.ts +54 -9
  64. package/dist/core/bridge-reaper.d.ts.map +1 -1
  65. package/dist/core/bridge-reaper.js +116 -11
  66. package/dist/core/bridge-reaper.js.map +1 -1
  67. package/dist/core/types.d.ts +25 -12
  68. package/dist/core/types.d.ts.map +1 -1
  69. package/dist/core/types.js +14 -0
  70. package/dist/core/types.js.map +1 -1
  71. package/dist/interactive/chat-events.d.ts.map +1 -1
  72. package/dist/interactive/chat-events.js +5 -2
  73. package/dist/interactive/chat-events.js.map +1 -1
  74. package/dist/interactive/demo-events.d.ts.map +1 -1
  75. package/dist/interactive/demo-events.js +5 -2
  76. package/dist/interactive/demo-events.js.map +1 -1
  77. package/dist/interactive/doc-delete-routes.d.ts +69 -0
  78. package/dist/interactive/doc-delete-routes.d.ts.map +1 -0
  79. package/dist/interactive/doc-delete-routes.js +240 -0
  80. package/dist/interactive/doc-delete-routes.js.map +1 -0
  81. package/dist/interactive/doc-ledger-sweep.d.ts +53 -0
  82. package/dist/interactive/doc-ledger-sweep.d.ts.map +1 -0
  83. package/dist/interactive/doc-ledger-sweep.js +45 -0
  84. package/dist/interactive/doc-ledger-sweep.js.map +1 -0
  85. package/dist/interactive/draft-events.d.ts.map +1 -1
  86. package/dist/interactive/draft-events.js +5 -2
  87. package/dist/interactive/draft-events.js.map +1 -1
  88. package/dist/interactive/edit-events.d.ts.map +1 -1
  89. package/dist/interactive/edit-events.js +5 -2
  90. package/dist/interactive/edit-events.js.map +1 -1
  91. package/dist/interactive/ledger.d.ts +20 -0
  92. package/dist/interactive/ledger.d.ts.map +1 -1
  93. package/dist/interactive/ledger.js +32 -0
  94. package/dist/interactive/ledger.js.map +1 -1
  95. package/dist/interactive/ws-relay.d.ts +10 -0
  96. package/dist/interactive/ws-relay.d.ts.map +1 -1
  97. package/dist/interactive/ws-relay.js +16 -0
  98. package/dist/interactive/ws-relay.js.map +1 -1
  99. package/dist/projects/graph-paths.d.ts +7 -22
  100. package/dist/projects/graph-paths.d.ts.map +1 -1
  101. package/dist/projects/graph-paths.js +10 -37
  102. package/dist/projects/graph-paths.js.map +1 -1
  103. package/dist/projects/settings.d.ts +32 -2
  104. package/dist/projects/settings.d.ts.map +1 -1
  105. package/dist/projects/settings.js +48 -6
  106. package/dist/projects/settings.js.map +1 -1
  107. package/dist/projects/state-home.d.ts +42 -0
  108. package/dist/projects/state-home.d.ts.map +1 -0
  109. package/dist/projects/state-home.js +55 -0
  110. package/dist/projects/state-home.js.map +1 -0
  111. package/dist/qe/acceptance.d.ts +9 -0
  112. package/dist/qe/acceptance.d.ts.map +1 -1
  113. package/dist/qe/acceptance.js +21 -1
  114. package/dist/qe/acceptance.js.map +1 -1
  115. package/dist/studio/assets/{index-BdQQv2hz.js → index-gtE6scX0.js} +98 -98
  116. package/dist/studio/index.html +1 -1
  117. package/dist/studio/testid-inventory.json +70 -4
  118. package/endpoint-manifest.json +28 -2
  119. package/package.json +4 -4
@@ -13,7 +13,15 @@
13
13
  * promise chain so concurrent handlers never interleave partial lines.
14
14
  */
15
15
  import type { Actor, AuditEntry } from '../core/types.js';
16
- /** Where the audit trail lives unless overridden. */
16
+ /**
17
+ * Where the audit trail lives unless overridden: the explicit `WICKED_CREW_AUDIT_LOG` env
18
+ * override, then the daemon's state home — the `--db` parent when the bootstrap configured one,
19
+ * the historical `~/.wicked-crew` default otherwise (crew#353's principle, same seam as the
20
+ * project graphs and the project settings store). A `--db`-isolated daemon must neither APPEND
21
+ * its trail to the operator's real `~/.wicked-crew/audit.log` (every `run.launched` /
22
+ * `settings.updated` / `project.created` did exactly that) nor HYDRATE its retry/guidance/
23
+ * delivery indexes from the operator's real trail at boot.
24
+ */
17
25
  export declare function defaultAuditPath(env?: NodeJS.ProcessEnv): string;
18
26
  export interface AuditReadFilter {
19
27
  runId?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/api/audit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE1D,qDAAqD;AACrD,wBAAgB,gBAAgB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAE7E;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,mFAAmF;AACnF,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;AAE7D,qBAAa,QAAQ;IAMjB,QAAQ,CAAC,IAAI,EAAE,MAAM;IACrB,OAAO,CAAC,QAAQ,CAAC,IAAI;IANvB,OAAO,CAAC,KAAK,CAAoC;IACjD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAS;gBAGd,IAAI,GAAE,MAA2B,EACzB,IAAI,GAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAA6B;IAGvE;;;;;;OAMG;IACH,MAAM,CAAC,IAAI,IAAI,QAAQ;IAMvB;;;;OAIG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,IAAI;IAyBzG,wCAAwC;IACxC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB;;;;OAIG;IACG,IAAI,CAAC,MAAM,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAM3D;;;;;;;OAOG;IACH,OAAO,CAAC,MAAM,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAIxD,gFAAgF;YAClE,IAAI;CA0BnB"}
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/api/audit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE1D;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAE7E;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,mFAAmF;AACnF,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;AAE7D,qBAAa,QAAQ;IAMjB,QAAQ,CAAC,IAAI,EAAE,MAAM;IACrB,OAAO,CAAC,QAAQ,CAAC,IAAI;IANvB,OAAO,CAAC,KAAK,CAAoC;IACjD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAS;gBAGd,IAAI,GAAE,MAA2B,EACzB,IAAI,GAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAA6B;IAGvE;;;;;;OAMG;IACH,MAAM,CAAC,IAAI,IAAI,QAAQ;IAMvB;;;;OAIG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,IAAI;IAyBzG,wCAAwC;IACxC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB;;;;OAIG;IACG,IAAI,CAAC,MAAM,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAM3D;;;;;;;OAOG;IACH,OAAO,CAAC,MAAM,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAIxD,gFAAgF;YAClE,IAAI;CA0BnB"}
package/dist/api/audit.js CHANGED
@@ -13,11 +13,19 @@
13
13
  * promise chain so concurrent handlers never interleave partial lines.
14
14
  */
15
15
  import { appendFile, mkdir, readFile } from 'node:fs/promises';
16
- import { homedir } from 'node:os';
17
16
  import { dirname, join } from 'node:path';
18
- /** Where the audit trail lives unless overridden. */
17
+ import { crewStateHome } from '../projects/state-home.js';
18
+ /**
19
+ * Where the audit trail lives unless overridden: the explicit `WICKED_CREW_AUDIT_LOG` env
20
+ * override, then the daemon's state home — the `--db` parent when the bootstrap configured one,
21
+ * the historical `~/.wicked-crew` default otherwise (crew#353's principle, same seam as the
22
+ * project graphs and the project settings store). A `--db`-isolated daemon must neither APPEND
23
+ * its trail to the operator's real `~/.wicked-crew/audit.log` (every `run.launched` /
24
+ * `settings.updated` / `project.created` did exactly that) nor HYDRATE its retry/guidance/
25
+ * delivery indexes from the operator's real trail at boot.
26
+ */
19
27
  export function defaultAuditPath(env = process.env) {
20
- return env['WICKED_CREW_AUDIT_LOG'] ?? join(homedir(), '.wicked-crew', 'audit.log');
28
+ return env['WICKED_CREW_AUDIT_LOG'] ?? join(crewStateHome(), 'audit.log');
21
29
  }
22
30
  export class AuditLog {
23
31
  path;
@@ -1 +1 @@
1
- {"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/api/audit.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/api/audit.ts"],"names":[],"mappings":"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"}
@@ -21,12 +21,95 @@
21
21
  * the per-run output endpoint.
22
22
  */
23
23
  import type { AuditLog } from './audit.js';
24
- import type { SessionView, WorkUnit } from '../core/types.js';
25
- /** The wire shape `AgentSession.delivery` carries (api-types 0.11.0). */
26
- export interface SessionDelivery {
27
- kind: 'pull_request';
28
- url: string;
24
+ import type { AgentSession, SessionView, WorkUnit } from '../core/types.js';
25
+ /** What `AgentSession.delivery` + `deliverUrl` spell on the wire (api-types 0.18.0, crew#393). */
26
+ export interface DeliveryState {
27
+ delivery: 'delivered' | 'stranded' | 'vacuous' | 'none';
28
+ /** Present exactly when `delivery === 'delivered'`. */
29
+ deliverUrl?: string;
29
30
  }
31
+ /**
32
+ * The tri-state delivery derivation (crew#393) — HONEST by construction, computed at DTO
33
+ * assembly from three facts and nothing else:
34
+ *
35
+ * 1. a recorded PR URL (the `run.delivered` trail via {@link DeliveryIndex}) ⇒ `'delivered'`;
36
+ * 2. otherwise a COMPLETED repo-scoped run whose worktree still exists on disk ⇒ `'stranded'`
37
+ * — reviewable work nobody lifted into a PR. This is a derivation over the run record's
38
+ * existing fields (`status`, `repo_ref`, `workdir`) plus one stat, so runs recorded BEFORE
39
+ * this field existed (the run 83052f0b class) read `'stranded'` exactly like new ones;
40
+ * 3. everything else ⇒ `'none'`: repo-less runs, non-terminal runs, failed/cancelled runs
41
+ * (their unit rejection already spells the failure), and completed runs whose worktree
42
+ * was cleaned up (nothing left to lift).
43
+ *
44
+ * `worktreeExists` is injected (a `fs.existsSync` in production) so route tests can pin the
45
+ * derivation without staging real directories.
46
+ */
47
+ export declare function deliveryStateOf(session: Pick<AgentSession, 'status' | 'repo_ref' | 'workdir'>, url: string | undefined, worktreeExists: (path: string) => boolean): DeliveryState;
48
+ /** The probes behind the `'vacuous'` derivation (crew#311) — injected so route tests can pin the
49
+ * derivation without staging real repos; production wires the memoized git probes below. */
50
+ export interface VacuityProbes {
51
+ /** One stat — the `'stranded'` gate (crew#393; `fs.existsSync` in production). */
52
+ worktreeExists: (path: string) => boolean;
53
+ /** True ⇔ the worktree POSITIVELY carries no contribution (both git instruments empty). */
54
+ worktreeIsClean: (path: string) => Promise<boolean>;
55
+ /** True ⇔ the run's `wicked/<runId>` branch in the repo `repoRef` names POSITIVELY carries no
56
+ * commits of its own (or no longer exists) — the reaped-worktree half of vacuity. */
57
+ runBranchIsEmpty: (repoRef: string, runId: string) => Promise<boolean>;
58
+ }
59
+ /**
60
+ * The delivery derivation WITH the vacuity split (crew#311) — the async refinement over
61
+ * {@link deliveryStateOf} the run DTOs actually use.
62
+ *
63
+ * The crew#311 class — units all reach `done` while producing NOTHING (three governed builds
64
+ * folded "done" on 280–509 bytes of read-narration over a worktree clean at main's HEAD) — used
65
+ * to be indistinguishable on the wire from real outcomes, in BOTH of its shapes:
66
+ *
67
+ * - worktree still on disk and clean ⇒ it read `'stranded'`, pointing the operator at a
68
+ * post-hoc deliver that must refuse (there is nothing to lift);
69
+ * - worktree already REAPED ⇒ it read `'none'`, silently green. This is the shape a vacuous
70
+ * completion normally lands in: the engine's terminal reap (FINDING-003,
71
+ * `reap_worktree_if_clean`) removes exactly the clean trees, and never touches the
72
+ * `wicked/<runId>` branch — so "reaped tree + empty run branch" is PROOF the run left no
73
+ * work anywhere, while "reaped tree + commits on the branch" is landed work and stays
74
+ * `'none'` (nothing left in a worktree to lift).
75
+ *
76
+ * Both shapes now read `'vacuous'`, and only on POSITIVE reads: every probe fails toward the
77
+ * pre-existing label (`'stranded'` / `'none'`), so a non-git directory, a missing repo record,
78
+ * a deleted repo, or a git failure reads exactly as it did before this existed. (One honest
79
+ * edge: an operator who hand-deleted a completed run's branch has made its work unreachable —
80
+ * it reads vacuous, which is what the run now amounts to.)
81
+ */
82
+ export declare function deliveryStateWithVacuity(session: Pick<AgentSession, 'id' | 'status' | 'repo_ref' | 'workdir'>, url: string | undefined, probes: VacuityProbes): Promise<DeliveryState>;
83
+ /** How long a per-worktree cleanliness read is trusted before the next request re-probes. A
84
+ * terminal run's worktree only changes under operator hands, and `GET /runs` is polled — an
85
+ * unmemoized probe would be two git subprocesses per stranded run per poll. */
86
+ export declare const WORKTREE_CLEAN_TTL_MS = 30000;
87
+ /**
88
+ * The production `worktreeIsClean` probe: the SAME two read-only instruments as the engine's
89
+ * `worktree_is_clean` — uncommitted paths (`git status --porcelain`, untracked included) and
90
+ * run-branch-only commits (`git log --oneline HEAD --not --exclude=wicked/* --branches`) —
91
+ * memoized per worktree path for {@link WORKTREE_CLEAN_TTL_MS}.
92
+ *
93
+ * Fails toward NOT-clean (see {@link deliveryStateWithVacuity} — a failure must keep the
94
+ * pre-existing 'stranded' label, never invent 'vacuous'), and failures obey the TTL too, so a
95
+ * transient git error doesn't pin a run's label until restart.
96
+ */
97
+ export declare function gitWorktreeIsClean(ttlMs?: number, now?: () => number): (path: string) => Promise<boolean>;
98
+ /**
99
+ * The production `runBranchIsEmpty` probe — the reaped-worktree half of vacuity (crew#311).
100
+ *
101
+ * TRUE only on positive proof that the run left nothing on its branch: either
102
+ * `refs/heads/wicked/<runId>` no longer exists in the run's repo, or it exists and
103
+ * `git log <branch> --not --exclude=wicked/* --branches` is empty (the branch carries no commit
104
+ * of its own — the exact second instrument of the engine's `worktree_is_clean`, aimed at the
105
+ * branch instead of a checkout). An unresolvable repo, a git failure, or any commit on the
106
+ * branch reads FALSE — the label falls back to `'none'`, never inventing vacuity.
107
+ *
108
+ * `resolveRepoRoot` is injected (routes wire it to the adapter's repo registry) and its answer
109
+ * rides the same TTL memo as the verdict, so a `GET /runs` poll costs at most one registry read
110
+ * + one git pair per run per window.
111
+ */
112
+ export declare function gitRunBranchIsEmpty(resolveRepoRoot: (repoRef: string) => Promise<string | undefined>, ttlMs?: number, now?: () => number): (repoRef: string, runId: string) => Promise<boolean>;
30
113
  /**
31
114
  * The PR URL in a deliver transcript — crew's own extraction, mirrored
32
115
  * (`core/deliver.ts`: `grep -Eo 'https://[^[:space:]]+/pull/[0-9]+' | tail -1`). Requiring
@@ -55,7 +138,11 @@ export declare class DeliveryIndex {
55
138
  hydrate(audit: AuditLog, log?: (msg: string) => void): Promise<void>;
56
139
  /** Record the run's delivered PR URL (idempotent — the newest write wins). */
57
140
  set(runId: string, url: string): void;
58
- /** The delivery for this run, or `undefined` (the DTO spells that as an ABSENT field). */
59
- deliveryFor(runId: string): SessionDelivery | undefined;
141
+ /**
142
+ * The recorded PR URL for this run, or `undefined` — the fact {@link deliveryStateOf} turns
143
+ * into the wire's `delivery: 'delivered'` + `deliverUrl` (api-types 0.18.0; the 0.11.0 object
144
+ * spelling `{ kind: 'pull_request', url }` is gone from the wire, crew#393).
145
+ */
146
+ urlFor(runId: string): string | undefined;
60
147
  }
61
148
  //# sourceMappingURL=delivery-index.d.ts.map
@@ -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,WAAW,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE9D,yEAAyE;AACzE,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;CACb;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,0FAA0F;IAC1F,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;CAIxD"}
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"}
@@ -20,6 +20,181 @@
20
20
  * hydrate — that is an unbounded boot cost. Historical runs still resolve their URL through
21
21
  * the per-run output endpoint.
22
22
  */
23
+ import { execCapped } from '../core/exec.js';
24
+ /**
25
+ * The tri-state delivery derivation (crew#393) — HONEST by construction, computed at DTO
26
+ * assembly from three facts and nothing else:
27
+ *
28
+ * 1. a recorded PR URL (the `run.delivered` trail via {@link DeliveryIndex}) ⇒ `'delivered'`;
29
+ * 2. otherwise a COMPLETED repo-scoped run whose worktree still exists on disk ⇒ `'stranded'`
30
+ * — reviewable work nobody lifted into a PR. This is a derivation over the run record's
31
+ * existing fields (`status`, `repo_ref`, `workdir`) plus one stat, so runs recorded BEFORE
32
+ * this field existed (the run 83052f0b class) read `'stranded'` exactly like new ones;
33
+ * 3. everything else ⇒ `'none'`: repo-less runs, non-terminal runs, failed/cancelled runs
34
+ * (their unit rejection already spells the failure), and completed runs whose worktree
35
+ * was cleaned up (nothing left to lift).
36
+ *
37
+ * `worktreeExists` is injected (a `fs.existsSync` in production) so route tests can pin the
38
+ * derivation without staging real directories.
39
+ */
40
+ export function deliveryStateOf(session, url, worktreeExists) {
41
+ if (url !== undefined)
42
+ return { delivery: 'delivered', deliverUrl: url };
43
+ if (session.status === 'completed' &&
44
+ session.repo_ref != null &&
45
+ typeof session.workdir === 'string' &&
46
+ session.workdir !== '' &&
47
+ worktreeExists(session.workdir)) {
48
+ return { delivery: 'stranded' };
49
+ }
50
+ return { delivery: 'none' };
51
+ }
52
+ /**
53
+ * The delivery derivation WITH the vacuity split (crew#311) — the async refinement over
54
+ * {@link deliveryStateOf} the run DTOs actually use.
55
+ *
56
+ * The crew#311 class — units all reach `done` while producing NOTHING (three governed builds
57
+ * folded "done" on 280–509 bytes of read-narration over a worktree clean at main's HEAD) — used
58
+ * to be indistinguishable on the wire from real outcomes, in BOTH of its shapes:
59
+ *
60
+ * - worktree still on disk and clean ⇒ it read `'stranded'`, pointing the operator at a
61
+ * post-hoc deliver that must refuse (there is nothing to lift);
62
+ * - worktree already REAPED ⇒ it read `'none'`, silently green. This is the shape a vacuous
63
+ * completion normally lands in: the engine's terminal reap (FINDING-003,
64
+ * `reap_worktree_if_clean`) removes exactly the clean trees, and never touches the
65
+ * `wicked/<runId>` branch — so "reaped tree + empty run branch" is PROOF the run left no
66
+ * work anywhere, while "reaped tree + commits on the branch" is landed work and stays
67
+ * `'none'` (nothing left in a worktree to lift).
68
+ *
69
+ * Both shapes now read `'vacuous'`, and only on POSITIVE reads: every probe fails toward the
70
+ * pre-existing label (`'stranded'` / `'none'`), so a non-git directory, a missing repo record,
71
+ * a deleted repo, or a git failure reads exactly as it did before this existed. (One honest
72
+ * edge: an operator who hand-deleted a completed run's branch has made its work unreachable —
73
+ * it reads vacuous, which is what the run now amounts to.)
74
+ */
75
+ export async function deliveryStateWithVacuity(session, url, probes) {
76
+ const state = deliveryStateOf(session, url, probes.worktreeExists);
77
+ if (state.delivery === 'stranded') {
78
+ // `deliveryStateOf` only answers 'stranded' after proving workdir is a non-empty string.
79
+ return (await probes.worktreeIsClean(session.workdir))
80
+ ? { delivery: 'vacuous' }
81
+ : state;
82
+ }
83
+ if (state.delivery === 'none' &&
84
+ session.status === 'completed' &&
85
+ session.repo_ref != null &&
86
+ (await probes.runBranchIsEmpty(session.repo_ref, session.id))) {
87
+ return { delivery: 'vacuous' };
88
+ }
89
+ return state;
90
+ }
91
+ /** How long a per-worktree cleanliness read is trusted before the next request re-probes. A
92
+ * terminal run's worktree only changes under operator hands, and `GET /runs` is polled — an
93
+ * unmemoized probe would be two git subprocesses per stranded run per poll. */
94
+ export const WORKTREE_CLEAN_TTL_MS = 30_000;
95
+ /**
96
+ * The production `worktreeIsClean` probe: the SAME two read-only instruments as the engine's
97
+ * `worktree_is_clean` — uncommitted paths (`git status --porcelain`, untracked included) and
98
+ * run-branch-only commits (`git log --oneline HEAD --not --exclude=wicked/* --branches`) —
99
+ * memoized per worktree path for {@link WORKTREE_CLEAN_TTL_MS}.
100
+ *
101
+ * Fails toward NOT-clean (see {@link deliveryStateWithVacuity} — a failure must keep the
102
+ * pre-existing 'stranded' label, never invent 'vacuous'), and failures obey the TTL too, so a
103
+ * transient git error doesn't pin a run's label until restart.
104
+ */
105
+ export function gitWorktreeIsClean(ttlMs = WORKTREE_CLEAN_TTL_MS, now = Date.now) {
106
+ const memo = new Map();
107
+ const probe = async (path) => {
108
+ const gitEmpty = async (args) => {
109
+ // Read-only git plumbing over the run's own worktree; argv array, never a shell string.
110
+ const { stdout } = await execCapped('git', args, {
111
+ cwd: path,
112
+ timeout: 10_000,
113
+ windowsHide: true,
114
+ });
115
+ return stdout.trim() === '';
116
+ };
117
+ try {
118
+ return ((await gitEmpty(['status', '--porcelain'])) &&
119
+ (await gitEmpty(['log', '--oneline', 'HEAD', '--not', '--exclude=wicked/*', '--branches'])));
120
+ }
121
+ catch {
122
+ return false;
123
+ }
124
+ };
125
+ return async (path) => {
126
+ const hit = memo.get(path);
127
+ if (hit !== undefined && now() - hit.at < ttlMs)
128
+ return hit.clean;
129
+ const clean = await probe(path);
130
+ memo.set(path, { at: now(), clean });
131
+ return clean;
132
+ };
133
+ }
134
+ /**
135
+ * The production `runBranchIsEmpty` probe — the reaped-worktree half of vacuity (crew#311).
136
+ *
137
+ * TRUE only on positive proof that the run left nothing on its branch: either
138
+ * `refs/heads/wicked/<runId>` no longer exists in the run's repo, or it exists and
139
+ * `git log <branch> --not --exclude=wicked/* --branches` is empty (the branch carries no commit
140
+ * of its own — the exact second instrument of the engine's `worktree_is_clean`, aimed at the
141
+ * branch instead of a checkout). An unresolvable repo, a git failure, or any commit on the
142
+ * branch reads FALSE — the label falls back to `'none'`, never inventing vacuity.
143
+ *
144
+ * `resolveRepoRoot` is injected (routes wire it to the adapter's repo registry) and its answer
145
+ * rides the same TTL memo as the verdict, so a `GET /runs` poll costs at most one registry read
146
+ * + one git pair per run per window.
147
+ */
148
+ export function gitRunBranchIsEmpty(resolveRepoRoot, ttlMs = WORKTREE_CLEAN_TTL_MS, now = Date.now) {
149
+ const memo = new Map();
150
+ const probe = async (repoRef, runId) => {
151
+ let root;
152
+ try {
153
+ root = await resolveRepoRoot(repoRef);
154
+ }
155
+ catch {
156
+ root = undefined; // registry read failed — fall toward 'none', never invent vacuity
157
+ }
158
+ if (root === undefined)
159
+ return false;
160
+ const branch = `refs/heads/wicked/${runId}`;
161
+ const gitOut = (args) =>
162
+ // Read-only git plumbing over the registered repo root; argv array, never a shell string.
163
+ execCapped('git', args, { cwd: root, timeout: 10_000, windowsHide: true });
164
+ try {
165
+ await gitOut(['rev-parse', '--verify', '--quiet', branch]);
166
+ }
167
+ catch (err) {
168
+ // `--verify --quiet` on a missing ref is a CLEAN exit 1 — the one verifiable "branch
169
+ // gone". Anything else (git unspawnable, deleted root ⇒ ENOENT, a 128 "not a git
170
+ // repository", a timeout kill) is an infra failure and must never invent vacuity.
171
+ return err.code === 1;
172
+ }
173
+ try {
174
+ const { stdout } = await gitOut([
175
+ 'log',
176
+ '--oneline',
177
+ branch,
178
+ '--not',
179
+ '--exclude=wicked/*',
180
+ '--branches',
181
+ ]);
182
+ return stdout.trim() === '';
183
+ }
184
+ catch {
185
+ return false;
186
+ }
187
+ };
188
+ return async (repoRef, runId) => {
189
+ const key = `${repoRef}\0${runId}`;
190
+ const hit = memo.get(key);
191
+ if (hit !== undefined && now() - hit.at < ttlMs)
192
+ return hit.empty;
193
+ const empty = await probe(repoRef, runId);
194
+ memo.set(key, { at: now(), empty });
195
+ return empty;
196
+ };
197
+ }
23
198
  /**
24
199
  * The PR URL in a deliver transcript — crew's own extraction, mirrored
25
200
  * (`core/deliver.ts`: `grep -Eo 'https://[^[:space:]]+/pull/[0-9]+' | tail -1`). Requiring
@@ -78,10 +253,13 @@ export class DeliveryIndex {
78
253
  set(runId, url) {
79
254
  this.runToUrl.set(runId, url);
80
255
  }
81
- /** The delivery for this run, or `undefined` (the DTO spells that as an ABSENT field). */
82
- deliveryFor(runId) {
83
- const url = this.runToUrl.get(runId);
84
- return url === undefined ? undefined : { kind: 'pull_request', url };
256
+ /**
257
+ * The recorded PR URL for this run, or `undefined` — the fact {@link deliveryStateOf} turns
258
+ * into the wire's `delivery: 'delivered'` + `deliverUrl` (api-types 0.18.0; the 0.11.0 object
259
+ * spelling `{ kind: 'pull_request', url }` is gone from the wire, crew#393).
260
+ */
261
+ urlFor(runId) {
262
+ return this.runToUrl.get(runId);
85
263
  }
86
264
  }
87
265
  //# sourceMappingURL=delivery-index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"delivery-index.js","sourceRoot":"","sources":["../../src/api/delivery-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAWH;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;IACxD,OAAO,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC;AACzE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,IAAiB;IAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;IAC/D,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACpC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,IAAI,IAAI,CAAC;AAC/F,CAAC;AAED,MAAM,OAAO,aAAa;IACP,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;IAEtD;;;;;;;;OAQG;IACH,KAAK,CAAC,OAAO,CAAC,KAAe,EAAE,GAA2B;QACxD,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;YAC/B,KAAK,MAAM,KAAK,IAAI,MAAM,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC,EAAE,CAAC;gBACrE,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ;oBAAE,SAAS;gBAC9C,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC;oBAAE,SAAS;gBACpC,kFAAkF;gBAClF,qFAAqF;gBACrF,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBACtB,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC;gBAClC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,EAAE;oBAAE,SAAS;gBACpD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YACtC,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,EAAE,CACH,wFACE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CACjD,EAAE,CACH,CAAC;QACJ,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,GAAG,CAAC,KAAa,EAAE,GAAW;QAC5B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAChC,CAAC;IAED,0FAA0F;IAC1F,WAAW,CAAC,KAAa;QACvB,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACrC,OAAO,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,CAAC;IACvE,CAAC;CACF"}
1
+ {"version":3,"file":"delivery-index.js","sourceRoot":"","sources":["../../src/api/delivery-index.ts"],"names":[],"mappings":"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"}
@@ -72,6 +72,16 @@ export declare class ElicitationCache {
72
72
  * Fold one live CoreEvent into the cache.
73
73
  *
74
74
  * `elicitationCreated` → store the new prompt (replaces any prior one).
75
+ * `elicitationResolved` → the engine says that elicitation is DEAD (answered, declined,
76
+ * timed out, torn down, superseded by the next session prompt — the `reason` field), so
77
+ * drop the entry and bump the generation. Without this, an engine-side timeout/teardown
78
+ * left the prompt advertised on GET forever and a late POST forwarded into a guaranteed
79
+ * "no matching elicitation" 500 whose error-path restore re-advertised the dead prompt —
80
+ * the silent-wedge shape crew#357/#358 forbid. Guarded by id: a resolved frame for an
81
+ * elicitation OTHER than the cached one (a late frame racing a newer prompt) must not
82
+ * delete the newer prompt. When no entry is present the generation still bumps — the F8
83
+ * posture: a POST may have `take`n the entry just before this frame arrived, and its
84
+ * error-path `restoreIfUnchanged` must then be a no-op.
75
85
  * Terminal events → delete the entry and bump the generation.
76
86
  * All other events → no-op.
77
87
  */
@@ -1 +1 @@
1
- {"version":3,"file":"elicitation-cache.d.ts","sourceRoot":"","sources":["../../src/api/elicitation-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/D;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACzB,2DAA2D;IAC3D,UAAU,EAAE,MAAM,CAAC;CACpB;AAQD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuC;IAC/D,mFAAmF;IACnF,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA6B;IAElD,OAAO,CAAC,OAAO;IAIf;;;;OAIG;IACH,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,gBAAgB,EAAE,YAAY,CAAC,GAAG,IAAI;IAWzD,0EAA0E;IAC1E,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS;IAIhD;;;;;;;;;OASG;IACH,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,gBAAgB,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS;IAQzE;;;;;;;;;;OAUG;IACH,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO;IAQhF;;;;;;OAMG;IACH,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAiB9B;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,IAAI;CAQtC"}
1
+ {"version":3,"file":"elicitation-cache.d.ts","sourceRoot":"","sources":["../../src/api/elicitation-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/D;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACzB,2DAA2D;IAC3D,UAAU,EAAE,MAAM,CAAC;CACpB;AAQD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuC;IAC/D,mFAAmF;IACnF,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA6B;IAElD,OAAO,CAAC,OAAO;IAIf;;;;OAIG;IACH,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,gBAAgB,EAAE,YAAY,CAAC,GAAG,IAAI;IAWzD,0EAA0E;IAC1E,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS;IAIhD;;;;;;;;;OASG;IACH,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,gBAAgB,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS;IAQzE;;;;;;;;;;OAUG;IACH,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO;IAQhF;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAwB9B;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,IAAI;CAQtC"}
@@ -84,6 +84,16 @@ export class ElicitationCache {
84
84
  * Fold one live CoreEvent into the cache.
85
85
  *
86
86
  * `elicitationCreated` → store the new prompt (replaces any prior one).
87
+ * `elicitationResolved` → the engine says that elicitation is DEAD (answered, declined,
88
+ * timed out, torn down, superseded by the next session prompt — the `reason` field), so
89
+ * drop the entry and bump the generation. Without this, an engine-side timeout/teardown
90
+ * left the prompt advertised on GET forever and a late POST forwarded into a guaranteed
91
+ * "no matching elicitation" 500 whose error-path restore re-advertised the dead prompt —
92
+ * the silent-wedge shape crew#357/#358 forbid. Guarded by id: a resolved frame for an
93
+ * elicitation OTHER than the cached one (a late frame racing a newer prompt) must not
94
+ * delete the newer prompt. When no entry is present the generation still bumps — the F8
95
+ * posture: a POST may have `take`n the entry just before this frame arrived, and its
96
+ * error-path `restoreIfUnchanged` must then be a no-op.
87
97
  * Terminal events → delete the entry and bump the generation.
88
98
  * All other events → no-op.
89
99
  */
@@ -99,6 +109,14 @@ export class ElicitationCache {
99
109
  options: Array.isArray(event.options) ? event.options : null,
100
110
  });
101
111
  }
112
+ else if (event.type === 'elicitationResolved') {
113
+ const entry = this.entries.get(runId);
114
+ if (entry !== undefined && entry.elicitationId !== String(event.elicitationId ?? '')) {
115
+ return; // stale frame about an already-replaced elicitation — keep the newer prompt
116
+ }
117
+ this.entries.delete(runId);
118
+ this.bumpGen(runId);
119
+ }
102
120
  else if (TERMINAL_EVENTS.has(event.type)) {
103
121
  this.entries.delete(runId);
104
122
  this.bumpGen(runId);
@@ -1 +1 @@
1
- {"version":3,"file":"elicitation-cache.js","sourceRoot":"","sources":["../../src/api/elicitation-cache.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"elicitation-cache.js","sourceRoot":"","sources":["../../src/api/elicitation-cache.ts"],"names":[],"mappings":"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"}
@@ -127,6 +127,14 @@ export declare const SteeringAuthorSchema: z.ZodObject<{
127
127
  * ride the problem statement, never the prompt-fattening content itself).
128
128
  */
129
129
  export declare function steeringInboxDir(runId: string): string;
130
+ /**
131
+ * The propose phase's machine-readable artifact (crew#388): the file — inside
132
+ * {@link steeringInboxDir} — the workflow tells the worker to write the proposed-rules JSON
133
+ * array to, and the FIRST place the post-approval landing (`api/steering-landing.ts`) reads.
134
+ * One spelling, exported: the author route composes it into the problem statement, the landing
135
+ * derives the same path from the run id.
136
+ */
137
+ export declare const STEERING_PROPOSAL_FILENAME = "proposed-rules.json";
130
138
  export interface SteeringRoutesDeps {
131
139
  audit: AuditLog;
132
140
  actorOf: (req: FastifyRequest & {
@@ -1 +1 @@
1
- {"version":3,"file":"governance-steering.d.ts","sourceRoot":"","sources":["../../src/api/governance-steering.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAA4B,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAChF,OAAO,KAAK,EAAE,KAAK,EAA6C,MAAM,kBAAkB,CAAC;AACzF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAK3C;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,0GAQvB,CAAC;AAEX,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,MAAM,CAAiC,CAAC;AAEjF,0FAA0F;AAC1F,eAAO,MAAM,qBAAqB,iBAAiB,CAAC;AAEpD,mGAAmG;AACnG,eAAO,MAAM,wBAAwB,QAAa,CAAC;AACnD,gFAAgF;AAChF,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAC/C,4FAA4F;AAC5F,eAAO,MAAM,+BAA+B,QAAY,CAAC;AA0CzD,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAQtB,CAAC;AAEZ,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAYtB,CAAC;AAEZ;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQtD;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,QAAQ,CAAC;IAChB,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,GAAG;QAAE,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE,KAAK,KAAK,CAAC;IAC5D,yEAAyE;IACzE,MAAM,EAAE,MAAM,OAAO,EAAE,CAAC;CACzB;AAED,wBAAgB,gCAAgC,CAC9C,GAAG,EAAE,eAAe,EACpB,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,kBAAkB,GACvB,IAAI,CAkMN"}
1
+ {"version":3,"file":"governance-steering.d.ts","sourceRoot":"","sources":["../../src/api/governance-steering.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAA4B,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAChF,OAAO,KAAK,EAAE,KAAK,EAA6C,MAAM,kBAAkB,CAAC;AACzF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAK3C;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,0GAQvB,CAAC;AAEX,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,MAAM,CAAiC,CAAC;AAEjF,0FAA0F;AAC1F,eAAO,MAAM,qBAAqB,iBAAiB,CAAC;AAEpD,mGAAmG;AACnG,eAAO,MAAM,wBAAwB,QAAa,CAAC;AACnD,gFAAgF;AAChF,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAC/C,4FAA4F;AAC5F,eAAO,MAAM,+BAA+B,QAAY,CAAC;AA0CzD,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAQtB,CAAC;AAEZ,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAYtB,CAAC;AAEZ;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQtD;AAED;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,wBAAwB,CAAC;AAEhE,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,QAAQ,CAAC;IAChB,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,GAAG;QAAE,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE,KAAK,KAAK,CAAC;IAC5D,yEAAyE;IACzE,MAAM,EAAE,MAAM,OAAO,EAAE,CAAC;CACzB;AAED,wBAAgB,gCAAgC,CAC9C,GAAG,EAAE,eAAe,EACpB,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,kBAAkB,GACvB,IAAI,CAkNN"}
@@ -116,6 +116,14 @@ export function steeringInboxDir(runId) {
116
116
  const home = process.env.HOME ?? process.env.USERPROFILE ?? '/tmp';
117
117
  return join(home, '.wicked', 'steering-inbox', runId);
118
118
  }
119
+ /**
120
+ * The propose phase's machine-readable artifact (crew#388): the file — inside
121
+ * {@link steeringInboxDir} — the workflow tells the worker to write the proposed-rules JSON
122
+ * array to, and the FIRST place the post-approval landing (`api/steering-landing.ts`) reads.
123
+ * One spelling, exported: the author route composes it into the problem statement, the landing
124
+ * derives the same path from the run id.
125
+ */
126
+ export const STEERING_PROPOSAL_FILENAME = 'proposed-rules.json';
119
127
  export function registerGovernanceSteeringRoutes(app, adapter, deps) {
120
128
  const { audit, actorOf } = deps;
121
129
  // ── Batch import (the Steering page's Import action) ─────────────────────────
@@ -180,7 +188,9 @@ export function registerGovernanceSteeringRoutes(app, adapter, deps) {
180
188
  // propose phase: TH-12 propose-as-gate), inline documents land in the per-run steering inbox
181
189
  // (the run reads the daemon host's filesystem — the existing run file mechanism), and the
182
190
  // operator answers the proposal through the standard POST /runs/:id/gate. Approved rules land
183
- // via POST /governance/rules with `provenance.source: "chat"` — the run itself writes nothing.
191
+ // CREW-SIDE on that approve — the gate handler performs the store write with
192
+ // `provenance.source: "chat"` (see `api/steering-landing.ts`, crew#388); the run itself
193
+ // writes nothing to any store, only its proposal artifact in the inbox.
184
194
  //
185
195
  // Gated on the steering engine too, on purpose: the run only PROPOSES, but proposing rules
186
196
  // whose steering fields the CRUD would then refuse (501) is a trap, not a feature.
@@ -245,23 +255,31 @@ export function registerGovernanceSteeringRoutes(app, adapter, deps) {
245
255
  }
246
256
  }
247
257
  const runId = b.sessionId ?? randomUUID();
258
+ // The inbox exists for EVERY authoring run (not only ones with inline documents): it is
259
+ // also where the propose phase writes its machine-readable proposal (crew#388 — the file
260
+ // the post-approval landing reads), and it rides the launch as the run's extra write root.
261
+ const dir = steeringInboxDir(runId);
262
+ await fsp.mkdir(dir, { recursive: true });
248
263
  // Inline documents → per-run inbox files; only their PATHS ride the problem statement
249
264
  // (content in the prompt would fatten it past what prompt transports tolerate).
250
265
  const docPaths = [];
251
- if (b.documents !== undefined && b.documents.length > 0) {
252
- const dir = steeringInboxDir(runId);
253
- await fsp.mkdir(dir, { recursive: true });
254
- for (const [i, doc] of b.documents.entries()) {
255
- // basename + charset scrub: the caller's `name` is display text, never a path. The
256
- // index prefix keeps scrubbed names collision-free and the filename non-empty.
257
- const safe = `${i}-${basename(doc.name).replace(/[^a-zA-Z0-9._-]/g, '_')}`;
258
- const target = join(dir, safe);
259
- await fsp.writeFile(target, doc.content, 'utf8');
260
- docPaths.push(target);
261
- }
266
+ for (const [i, doc] of (b.documents ?? []).entries()) {
267
+ // basename + charset scrub: the caller's `name` is display text, never a path. The
268
+ // index prefix keeps scrubbed names collision-free and the filename non-empty.
269
+ const safe = `${i}-${basename(doc.name).replace(/[^a-zA-Z0-9._-]/g, '_')}`;
270
+ const target = join(dir, safe);
271
+ await fsp.writeFile(target, doc.content, 'utf8');
272
+ docPaths.push(target);
262
273
  }
263
274
  const type = b.type ?? DEFAULT_STEERING_TYPE;
264
275
  const sources = [...(b.paths ?? []), ...docPaths];
276
+ // The per-run proposal artifact (crew#388): the propose phase writes the proposed-rules
277
+ // JSON here (its instructions name "the absolute proposal file path in the problem
278
+ // statement"), and the gate handler's landing reads THIS file first — machine-readable by
279
+ // design, with transcript parsing only as the fallback. The path is per-run and inside
280
+ // the inbox the launch declares as an extra write root, so the write is governed and the
281
+ // run still writes NOTHING to any store (evaluator≠creator).
282
+ const proposalPath = join(dir, STEERING_PROPOSAL_FILENAME);
265
283
  const problem = [
266
284
  `Author steering rules for the '${type}' steering type (use it as the default steering_type for every proposed rule without a better fit).`,
267
285
  '',
@@ -270,6 +288,8 @@ export function registerGovernanceSteeringRoutes(app, adapter, deps) {
270
288
  ...(sources.length > 0
271
289
  ? ['', 'Analyze these files/directories on this machine:', ...sources.map((s) => `- ${s}`)]
272
290
  : []),
291
+ '',
292
+ `Proposal file (for the propose phase): write the proposed rules JSON array to exactly this absolute path: ${proposalPath}`,
273
293
  ].join('\n');
274
294
  try {
275
295
  await adapter.launchRun({
@@ -277,6 +297,10 @@ export function registerGovernanceSteeringRoutes(app, adapter, deps) {
277
297
  sessionId: runId,
278
298
  clisJson: JSON.stringify(deps.roster()),
279
299
  workflow: 'steering-author',
300
+ // The proposal artifact lands in the per-run inbox, which sits OUTSIDE any unit
301
+ // sandbox/worktree — without this declaration the engine's boundary denies the one
302
+ // file the landing is designed to read (the crew#263 shape).
303
+ extraWriteRoots: [dir],
280
304
  ...(b.repoRef !== undefined ? { repoRef: b.repoRef } : {}),
281
305
  });
282
306
  // The same trail entry POST /runs writes — this IS a run launch, findable by the same