wicked-crew 0.7.8 → 0.7.10

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 +423 -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
@@ -0,0 +1,423 @@
1
+ /**
2
+ * THE STEERING-AUTHOR LANDING (crew#388) — the post-approval write that closes TH-12.
3
+ *
4
+ * ## The defect
5
+ *
6
+ * The `steering-author` workflow's doctrine says "approved rules land via the rules CRUD with
7
+ * `provenance.source: "chat"` — the run itself writes nothing", and the propose phase tells the
8
+ * worker "do not write them yourself". Correct on both counts — evaluator≠creator — but NO
9
+ * component performed the write: the generic `POST /runs/:id/gate` only confirmed the gate, core
10
+ * has no steering-author hook, and the studio's `onRunResolved` only reloads rules. Every
11
+ * chat-authored rule ever approved was silently lost, orphaned as prose in the run's transcript
12
+ * (campaign 2026-09-01, scenario C5, run f3db4335).
13
+ *
14
+ * ## The design
15
+ *
16
+ * The landing is CREW-side, on APPROVE of the propose gate — the run keeps writing nothing to the
17
+ * store. The proposal is read machine-readably first: the propose phase now ALSO writes the
18
+ * proposed-rules JSON to a declared per-run artifact (`<steering inbox>/proposed-rules.json`,
19
+ * inside the run's own `extraWriteRoots`) — an ARTIFACT of the proposal, not a store write, so
20
+ * evaluator≠creator holds. Parsing the propose unit's stored transcript is the FALLBACK (runs
21
+ * launched before this fix, or a worker that ignored the file contract), and the cached gate
22
+ * prompt is the last resort (the transcript is written only on approval, so a store hiccup there
23
+ * still has the prompt core composed FROM that output).
24
+ *
25
+ * Invariants:
26
+ * - AUDITABLE — every landed rule records `governance.rule.upserted` with the chat provenance
27
+ * and the run id, exactly as the doctrine documents; a landing that could not happen records
28
+ * `governance.steering.landing_failed` with the reason.
29
+ * - IDEMPOTENT — a durable marker (`landed.json` beside the proposal) is written after a full
30
+ * landing; a replayed approve (daemon restart mid-request, double-driven gate) finds it and
31
+ * re-lands nothing. The rule write itself is an UPSERT keyed by rule id, so even a lost
32
+ * marker degrades to a same-content overwrite, never a duplicate rule.
33
+ * - FAIL-LOUD — when no source yields a parseable proposal the approve still succeeds for the
34
+ * RUN (the gate decision is the operator's and already happened), but the response and the
35
+ * audit trail carry an explicit `landing.outcome: "failed"` with the reason. A silent no-op
36
+ * is the bug this module exists to end.
37
+ * - AMEND-APPROVE — an approve carrying an amend note lands the proposal UNCHANGED: the amend
38
+ * steers the RUN (core injects it into the run's continuation), not the rule text. An
39
+ * operator who wants different rules rejects and re-authors; editing rule text inside a gate
40
+ * note would land words nobody reviewed as JSON nobody saw.
41
+ */
42
+ import { promises as fsp } from 'node:fs';
43
+ import { join } from 'node:path';
44
+ import { resolveRunWorkflow } from '../qe/acceptance.js';
45
+ import { coreUnitId } from './evidence.js';
46
+ import { STEERING_PROPOSAL_FILENAME, STEERING_TYPES, steeringInboxDir } from './governance-steering.js';
47
+ export { STEERING_PROPOSAL_FILENAME } from './governance-steering.js';
48
+ /** The workflow whose propose gate this landing serves. */
49
+ export const STEERING_AUTHOR_WORKFLOW = 'steering-author';
50
+ /** Durable idempotency marker written beside the proposal after a full landing. */
51
+ export const STEERING_LANDED_MARKER_FILENAME = 'landed.json';
52
+ /** Where the propose phase is told to write its machine-readable proposal. */
53
+ export function steeringProposalPath(runId) {
54
+ return join(steeringInboxDir(runId), STEERING_PROPOSAL_FILENAME);
55
+ }
56
+ /** Where a completed landing records what it landed (replay dedupe). */
57
+ export function steeringLandedMarkerPath(runId) {
58
+ return join(steeringInboxDir(runId), STEERING_LANDED_MARKER_FILENAME);
59
+ }
60
+ /**
61
+ * The steering fields a rule write may carry (the merged model's additions) — mirrored by
62
+ * `POST /governance/rules`, which refuses them on a pre-steering engine because the engine
63
+ * would silently DROP them and persist a rule that enforces differently than written. The
64
+ * landing applies the same guard: authored-then-downgraded is a loud landing failure, never
65
+ * a quiet field amputation.
66
+ */
67
+ export const STEERING_RULE_FIELDS = [
68
+ 'steering_type',
69
+ 'applies_to',
70
+ 'excludes',
71
+ 'weight',
72
+ 'effect',
73
+ 'trigger',
74
+ 'obligations',
75
+ 'criteria',
76
+ ];
77
+ /** True when this run IS a steering-author run (by workflow id, or — for runs whose stored
78
+ * `workflow_id` is core's `wf-<uuid>` instance id — by exact phase sequence). Defensive on a
79
+ * view without a `workflow_id` (partial-stub adapters in tests; a free-text run has no def):
80
+ * "not steering-author" is the honest answer there, and the legacy gate path must not 500. */
81
+ export function isSteeringAuthorRun(run, workflows) {
82
+ if (typeof run.session.workflow_id !== 'string')
83
+ return false;
84
+ return resolveRunWorkflow(run, workflows)?.id === STEERING_AUTHOR_WORKFLOW;
85
+ }
86
+ /**
87
+ * Recover the default steering type from the author route's own problem-statement preamble
88
+ * (`Author steering rules for the '<type>' steering type …`) so a proposed rule that omitted
89
+ * `steering_type` still lands on the sub-page the operator authored it for. `undefined` when
90
+ * the problem does not carry the preamble (a hand-launched run) — the engine's serde default
91
+ * (`architecture`) then applies, same as any other write.
92
+ */
93
+ export function steeringTypeFromProblem(problem) {
94
+ const m = /^Author steering rules for the '([a-z-]+)' steering type/.exec(problem);
95
+ const type = m?.[1];
96
+ return type !== undefined && STEERING_TYPES.has(type) ? type : undefined;
97
+ }
98
+ function isRawRule(v) {
99
+ return (typeof v === 'object' &&
100
+ v !== null &&
101
+ !Array.isArray(v) &&
102
+ typeof v['id'] === 'string' &&
103
+ v['id'].trim().length > 0 &&
104
+ typeof v['statement'] === 'string' &&
105
+ v['statement'].trim().length > 0);
106
+ }
107
+ /** Accept a bare array or a `{ rules: [...] }` wrapper; every entry must look like a rule. */
108
+ function rulesFromJson(parsed) {
109
+ const arr = Array.isArray(parsed)
110
+ ? parsed
111
+ : typeof parsed === 'object' && parsed !== null && Array.isArray(parsed['rules'])
112
+ ? parsed['rules']
113
+ : null;
114
+ if (arr === null || arr.length === 0)
115
+ return null;
116
+ return arr.every(isRawRule) ? arr : null;
117
+ }
118
+ /**
119
+ * Extract the proposed rules from free text — the whole text as JSON first (the deliverable
120
+ * file's shape), then each fenced code block, then every balanced top-level `[...]` in the
121
+ * text (the transcript / gate-prompt shape, where the JSON array is embedded in prose).
122
+ * `null` when nothing parses to a non-empty array of `{id, statement}` objects.
123
+ */
124
+ export function extractProposedRules(text) {
125
+ const trimmed = text.trim();
126
+ if (trimmed.length === 0)
127
+ return null;
128
+ // 1. The whole text is the JSON (the deliverable-file contract).
129
+ try {
130
+ const whole = rulesFromJson(JSON.parse(trimmed));
131
+ if (whole !== null)
132
+ return whole;
133
+ }
134
+ catch {
135
+ /* fall through to embedded extraction */
136
+ }
137
+ // 2. Fenced code blocks — workers habitually wrap JSON in ```json fences.
138
+ for (const m of trimmed.matchAll(/```(?:json)?\s*\n([\s\S]*?)```/g)) {
139
+ const block = m[1];
140
+ if (block === undefined)
141
+ continue;
142
+ try {
143
+ const rules = rulesFromJson(JSON.parse(block.trim()));
144
+ if (rules !== null)
145
+ return rules;
146
+ }
147
+ catch {
148
+ /* try the next block */
149
+ }
150
+ }
151
+ // 3. Balanced top-level arrays embedded in prose. String-aware bracket walk, so a `]` inside
152
+ // a statement never closes the array early.
153
+ for (let i = trimmed.indexOf('['); i !== -1; i = trimmed.indexOf('[', i + 1)) {
154
+ let depth = 0;
155
+ let inString = false;
156
+ let escaped = false;
157
+ for (let j = i; j < trimmed.length; j++) {
158
+ const ch = trimmed[j];
159
+ if (escaped) {
160
+ escaped = false;
161
+ continue;
162
+ }
163
+ if (inString) {
164
+ if (ch === '\\')
165
+ escaped = true;
166
+ else if (ch === '"')
167
+ inString = false;
168
+ continue;
169
+ }
170
+ if (ch === '"')
171
+ inString = true;
172
+ else if (ch === '[')
173
+ depth++;
174
+ else if (ch === ']') {
175
+ depth--;
176
+ if (depth === 0) {
177
+ try {
178
+ const rules = rulesFromJson(JSON.parse(trimmed.slice(i, j + 1)));
179
+ if (rules !== null)
180
+ return rules;
181
+ }
182
+ catch {
183
+ /* not JSON — keep scanning from the next '[' */
184
+ }
185
+ break;
186
+ }
187
+ }
188
+ }
189
+ }
190
+ return null;
191
+ }
192
+ /**
193
+ * Stamp the chat provenance and the recovered default steering type onto one proposed rule.
194
+ * `source: "chat"` is FORCED, not defaulted — the landing is the doctrine's one write path for
195
+ * chat-authored rules, and a worker that wrote some other source into its proposal must not be
196
+ * able to disguise where the rule came from. Everything else passes through untouched: the
197
+ * ENGINE's upsert path is the one spelling of what a valid rule is.
198
+ */
199
+ export function normalizeProposedRule(raw, defaultType, coercions) {
200
+ const prior = typeof raw['provenance'] === 'object' && raw['provenance'] !== null && !Array.isArray(raw['provenance'])
201
+ ? raw['provenance']
202
+ : {};
203
+ const sourceKinds = Array.isArray(prior['source_kinds']) ? prior['source_kinds'] : [];
204
+ const out = {
205
+ ...raw,
206
+ provenance: { ...prior, source: 'chat', source_kinds: sourceKinds },
207
+ };
208
+ const declaredType = raw['steering_type'];
209
+ if ((typeof declaredType !== 'string' || !STEERING_TYPES.has(declaredType)) &&
210
+ defaultType !== undefined) {
211
+ out['steering_type'] = defaultType;
212
+ }
213
+ // ── Shape coercion (live re-verify finding, run 3234c023): a REAL worker authors plausible
214
+ // shapes the engine schema refuses — `targets` as a string array (the engine's Targets is a
215
+ // {language, layer, framework} facet object), `trigger` as prose (a struct engine-side), and
216
+ // `criteria` as a list (a string engine-side). The old passthrough failed the WHOLE landing
217
+ // with the engine's parse error; the doctrine's loudness belongs on the parts that are wrong,
218
+ // not on the rule. Each coercion is recorded (the landing audits them) so nothing is silent.
219
+ const note = (msg) => {
220
+ coercions?.push(`${String(out['id'] ?? '?')}: ${msg}`);
221
+ };
222
+ const targets = out['targets'];
223
+ if (targets !== undefined && (typeof targets !== 'object' || targets === null || Array.isArray(targets))) {
224
+ // A facet OBJECT passes through untouched; anything else cannot mean what the engine means
225
+ // by targets — the glob scoping the worker usually intends already lives in applies_to.
226
+ // Coerced to the EMPTY facet object (not deleted): the published ConformanceRule shape has
227
+ // targets required, and readers like GET /governance/rules touch rule.targets.* directly.
228
+ out['targets'] = {};
229
+ note('replaced non-facet targets with {} (the engine Targets is a {language,layer,framework} object)');
230
+ }
231
+ const trigger = out['trigger'];
232
+ if (trigger !== undefined && (typeof trigger !== 'object' || trigger === null || Array.isArray(trigger))) {
233
+ delete out['trigger'];
234
+ note('dropped prose trigger (the engine Trigger is a structured condition object)');
235
+ }
236
+ const criteria = out['criteria'];
237
+ if (Array.isArray(criteria)) {
238
+ out['criteria'] = criteria.filter((c) => typeof c === 'string').join('\n');
239
+ note('joined criteria list into the single string the engine stores');
240
+ }
241
+ else if (criteria !== undefined && typeof criteria !== 'string') {
242
+ delete out['criteria'];
243
+ note('dropped non-string criteria');
244
+ }
245
+ const confidence = out['confidence'];
246
+ if (typeof confidence === 'number' && Number.isFinite(confidence)) {
247
+ if (confidence < 0 || confidence > 1) {
248
+ out['confidence'] = Math.min(1, Math.max(0, confidence));
249
+ note('clamped confidence into [0,1]');
250
+ }
251
+ }
252
+ else {
253
+ // REQUIRED engine-side (f32, no serde default) — a proposal without one must still land.
254
+ out['confidence'] = 0.8;
255
+ note(confidence === undefined ? 'defaulted missing confidence to 0.8' : 'replaced non-numeric confidence with 0.8');
256
+ }
257
+ return out;
258
+ }
259
+ /** Read a file, mapping ONLY a missing file to null — any other error (EACCES, EIO) throws. */
260
+ async function readIfExists(path) {
261
+ try {
262
+ return await fsp.readFile(path, 'utf8');
263
+ }
264
+ catch (err) {
265
+ if (err.code === 'ENOENT')
266
+ return null;
267
+ throw err;
268
+ }
269
+ }
270
+ /**
271
+ * Perform the landing for an APPROVED steering-author propose gate. Called AFTER
272
+ * `confirmGate` resolved — the gate decision is already durable; this function's only job is
273
+ * the write the doctrine promised. Never throws: every failure is folded into a loud
274
+ * `outcome: "failed"` result (and the audit trail), because a landing error must not turn an
275
+ * already-successful gate approval into an HTTP 500.
276
+ *
277
+ * `gatePrompt` is the cached gate prompt captured BEFORE the confirm (terminal events prune
278
+ * the cache) — the last-resort proposal source.
279
+ */
280
+ export async function landSteeringProposal(deps, run, gatePrompt) {
281
+ const runId = run.session.id;
282
+ const { adapter, audit, actor } = deps;
283
+ const failed = (error, landedIds = [], source) => {
284
+ audit.record('governance.steering.landing_failed', actor, {
285
+ runId,
286
+ detail: { error, ...(landedIds.length > 0 ? { landedRuleIds: landedIds } : {}) },
287
+ });
288
+ return {
289
+ outcome: 'failed',
290
+ ruleIds: landedIds,
291
+ ...(source !== undefined ? { source } : {}),
292
+ error,
293
+ };
294
+ };
295
+ // ── Idempotency: a replayed approve re-lands nothing ─────────────────────────
296
+ let markerText = null;
297
+ try {
298
+ markerText = await readIfExists(steeringLandedMarkerPath(runId));
299
+ }
300
+ catch {
301
+ /* an unreadable marker (not just missing) is treated as absent — the upsert is
302
+ idempotent by rule id, so the worst case is a same-content overwrite */
303
+ }
304
+ if (markerText !== null) {
305
+ try {
306
+ const marker = JSON.parse(markerText);
307
+ if (Array.isArray(marker.ruleIds)) {
308
+ return {
309
+ outcome: 'landed',
310
+ ruleIds: marker.ruleIds,
311
+ source: marker.source,
312
+ alreadyLanded: true,
313
+ };
314
+ }
315
+ }
316
+ catch {
317
+ /* a corrupt marker is treated as absent — the upsert is idempotent anyway */
318
+ }
319
+ }
320
+ // ── Read the proposal: deliverable file → stored transcript → cached gate prompt ──
321
+ let rawRules = null;
322
+ let source;
323
+ let fileText = null;
324
+ try {
325
+ fileText = await readIfExists(steeringProposalPath(runId));
326
+ }
327
+ catch (err) {
328
+ // A present-but-unreadable deliverable (EACCES, EIO) must NOT silently fall back to the
329
+ // transcript — that would mask an operational failure. Fail the landing loudly instead.
330
+ return failed(`the run's proposal deliverable exists but could not be read: ${err instanceof Error ? err.message : String(err)}`);
331
+ }
332
+ if (fileText !== null) {
333
+ rawRules = extractProposedRules(fileText);
334
+ if (rawRules !== null)
335
+ source = 'deliverable';
336
+ }
337
+ if (rawRules === null) {
338
+ // The transcript is stored on approval (deny-dominates writes no output for a rejected
339
+ // unit), so post-confirm it is readable. Find the propose unit by its phase-suffixed id.
340
+ const proposeUnit = run.units.find((u) => u.id === `${runId}:propose` || u.id.endsWith(':propose'));
341
+ if (proposeUnit !== undefined) {
342
+ try {
343
+ const transcript = await adapter.workOutput(coreUnitId(runId, proposeUnit));
344
+ if (transcript !== null) {
345
+ rawRules = extractProposedRules(transcript);
346
+ if (rawRules !== null)
347
+ source = 'transcript';
348
+ }
349
+ }
350
+ catch {
351
+ /* an unreadable transcript falls through to the gate prompt */
352
+ }
353
+ }
354
+ }
355
+ if (rawRules === null && gatePrompt !== undefined) {
356
+ rawRules = extractProposedRules(gatePrompt);
357
+ if (rawRules !== null)
358
+ source = 'gate-prompt';
359
+ }
360
+ if (rawRules === null || source === undefined) {
361
+ return failed(`the approved steering proposal could not be parsed from the run record: no ` +
362
+ `${STEERING_PROPOSAL_FILENAME} in the run's steering inbox, and no JSON array of ` +
363
+ `{id, statement} rule objects in the propose unit's stored transcript or gate prompt. ` +
364
+ `The gate approval stands, but NO rules were landed — re-author via ` +
365
+ `POST /governance/steering/author, or land the transcript's rules by hand through ` +
366
+ `POST /governance/rules.`);
367
+ }
368
+ const defaultType = steeringTypeFromProblem(run.session.problem);
369
+ const coercions = [];
370
+ const rules = rawRules.map((r) => normalizeProposedRule(r, defaultType, coercions));
371
+ // ── The same pre-steering-engine guard as POST /governance/rules ─────────────
372
+ if (!adapter.steeringSupported()) {
373
+ const carrying = rules.filter((r) => STEERING_RULE_FIELDS.some((f) => r[f] !== undefined));
374
+ if (carrying.length > 0) {
375
+ return failed(`the installed engine predates the steering model and would silently drop the steering ` +
376
+ `fields on ${carrying.length} proposed rule(s) — landing refused so the rules are not ` +
377
+ `persisted enforcing differently than authored. Upgrade wicked-core-ts (>= 0.7.5) and ` +
378
+ `re-author.`);
379
+ }
380
+ }
381
+ // ── Land, auditing each write exactly as the doctrine documents ──────────────
382
+ const landedIds = [];
383
+ const failures = [];
384
+ for (const rule of rules) {
385
+ try {
386
+ await adapter.upsertConformanceRule(rule);
387
+ landedIds.push(rule.id);
388
+ audit.record('governance.rule.upserted', actor, {
389
+ runId,
390
+ detail: {
391
+ id: rule.id,
392
+ source: 'chat',
393
+ via: STEERING_AUTHOR_WORKFLOW,
394
+ // Shape coercions this landing applied to THIS rule (see normalizeProposedRule) —
395
+ // audited so a worker-authored field the engine could not store is never silently
396
+ // reshaped. Coercion notes are prefixed with the rule id they belong to.
397
+ ...(() => {
398
+ const own = coercions.filter((c) => c.startsWith(`${rule.id}:`));
399
+ return own.length > 0 ? { coerced: own } : {};
400
+ })(),
401
+ },
402
+ });
403
+ }
404
+ catch (err) {
405
+ failures.push(`${rule.id}: ${err instanceof Error ? err.message : String(err)}`);
406
+ }
407
+ }
408
+ if (failures.length > 0) {
409
+ return failed(`landing was partial: ${landedIds.length} of ${rules.length} proposed rule(s) landed; ` +
410
+ `the store refused ${failures.join('; ')}`, landedIds, source);
411
+ }
412
+ // ── Durable marker (best-effort — the upsert is idempotent even without it) ──
413
+ try {
414
+ await fsp.mkdir(steeringInboxDir(runId), { recursive: true });
415
+ const marker = { ruleIds: landedIds, source, at: new Date().toISOString() };
416
+ await fsp.writeFile(steeringLandedMarkerPath(runId), JSON.stringify(marker, null, 2), 'utf8');
417
+ }
418
+ catch {
419
+ /* a missing marker degrades to a re-upsert of identical content, never a duplicate */
420
+ }
421
+ return { outcome: 'landed', ruleIds: landedIds, source };
422
+ }
423
+ //# sourceMappingURL=steering-landing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"steering-landing.js","sourceRoot":"","sources":["../../src/api/steering-landing.ts"],"names":[],"mappings":"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"}
@@ -115,14 +115,17 @@ export declare const TestingReconSchema: z.ZodObject<{
115
115
  problem: z.ZodString;
116
116
  projectId: z.ZodOptional<z.ZodString>;
117
117
  repoRefs: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
118
+ ungated: z.ZodOptional<z.ZodBoolean>;
118
119
  }, "strict", z.ZodTypeAny, {
119
120
  problem: string;
120
121
  projectId?: string | undefined;
121
122
  repoRefs?: string[] | undefined;
123
+ ungated?: boolean | undefined;
122
124
  }, {
123
125
  problem: string;
124
126
  projectId?: string | undefined;
125
127
  repoRefs?: string[] | undefined;
128
+ ungated?: boolean | undefined;
126
129
  }>;
127
130
  export interface TestingRoutesDeps {
128
131
  audit: AuditLog;
@@ -1 +1 @@
1
- {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../src/api/testing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAGL,KAAK,WAAW,EACjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,KAAK,EAAwC,MAAM,kBAAkB,CAAC;AACpF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAM3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AA+CvE,eAAO,MAAM,wBAAwB;;;;;;;;;EAK1B,CAAC;AAEZ,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKxB,CAAC;AAMZ,eAAO,MAAM,kBAAkB;;;;;;;;;;;;EASpB,CAAC;AAEZ,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,QAAQ,CAAC;IAChB,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,GAAG;QAAE,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE,KAAK,KAAK,CAAC;IAC5D,kGAAkG;IAClG,MAAM,EAAE,MAAM,OAAO,EAAE,CAAC;IACxB;+FAC2F;IAC3F,QAAQ,CAAC,EAAE;QAAE,GAAG,EAAE,UAAU,GAAG,IAAI,CAAC;QAAC,KAAK,EAAE,eAAe,CAAA;KAAE,CAAC;CAC/D;AAED,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,eAAe,EACpB,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,iBAAiB,GACtB,IAAI,CAqNN"}
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../src/api/testing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAGL,KAAK,WAAW,EACjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,KAAK,EAAwC,MAAM,kBAAkB,CAAC;AACpF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAO3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AA+CvE,eAAO,MAAM,wBAAwB;;;;;;;;;EAK1B,CAAC;AAEZ,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKxB,CAAC;AAQZ,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;EAUpB,CAAC;AAEZ,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,QAAQ,CAAC;IAChB,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,GAAG;QAAE,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE,KAAK,KAAK,CAAC;IAC5D,kGAAkG;IAClG,MAAM,EAAE,MAAM,OAAO,EAAE,CAAC;IACxB;+FAC2F;IAC3F,QAAQ,CAAC,EAAE;QAAE,GAAG,EAAE,UAAU,GAAG,IAAI,CAAC;QAAC,KAAK,EAAE,eAAe,CAAA;KAAE,CAAC;CAC/D;AAED,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,eAAe,EACpB,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,iBAAiB,GACtB,IAAI,CAuVN"}