@miller-tech/uap 2.36.4 → 2.39.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/config/model-profiles/qwen38.json +3 -3
  2. package/config/model-registry.json +96 -6
  3. package/dist/.tsbuildinfo +1 -1
  4. package/dist/bin/cli.js +57 -0
  5. package/dist/bin/cli.js.map +1 -1
  6. package/dist/cli/deliver.d.ts +46 -0
  7. package/dist/cli/deliver.d.ts.map +1 -1
  8. package/dist/cli/deliver.js +155 -36
  9. package/dist/cli/deliver.js.map +1 -1
  10. package/dist/cli/models.d.ts +11 -1
  11. package/dist/cli/models.d.ts.map +1 -1
  12. package/dist/cli/models.js +164 -3
  13. package/dist/cli/models.js.map +1 -1
  14. package/dist/cli/workflow.d.ts +36 -0
  15. package/dist/cli/workflow.d.ts.map +1 -0
  16. package/dist/cli/workflow.js +246 -0
  17. package/dist/cli/workflow.js.map +1 -0
  18. package/dist/delivery/run-state.d.ts +1 -1
  19. package/dist/delivery/run-state.d.ts.map +1 -1
  20. package/dist/delivery/run-state.js +1 -1
  21. package/dist/delivery/run-state.js.map +1 -1
  22. package/dist/delivery/team-solve-deliver.d.ts +83 -0
  23. package/dist/delivery/team-solve-deliver.d.ts.map +1 -0
  24. package/dist/delivery/team-solve-deliver.js +191 -0
  25. package/dist/delivery/team-solve-deliver.js.map +1 -0
  26. package/dist/inference/model-files.d.ts +111 -0
  27. package/dist/inference/model-files.d.ts.map +1 -0
  28. package/dist/inference/model-files.js +172 -0
  29. package/dist/inference/model-files.js.map +1 -0
  30. package/dist/placement/registry.d.ts +650 -0
  31. package/dist/placement/registry.d.ts.map +1 -1
  32. package/dist/placement/registry.js +21 -0
  33. package/dist/placement/registry.js.map +1 -1
  34. package/dist/workflow/loader.d.ts +34 -0
  35. package/dist/workflow/loader.d.ts.map +1 -0
  36. package/dist/workflow/loader.js +232 -0
  37. package/dist/workflow/loader.js.map +1 -0
  38. package/dist/workflow/runner.d.ts +90 -0
  39. package/dist/workflow/runner.d.ts.map +1 -0
  40. package/dist/workflow/runner.js +416 -0
  41. package/dist/workflow/runner.js.map +1 -0
  42. package/dist/workflow/types.d.ts +400 -0
  43. package/dist/workflow/types.d.ts.map +1 -0
  44. package/dist/workflow/types.js +147 -0
  45. package/dist/workflow/types.js.map +1 -0
  46. package/docs/INDEX.md +1 -0
  47. package/docs/architecture/adr/0013-declarative-workflow-layer.md +99 -0
  48. package/docs/architecture/adr/0014-loop-steps-and-team-solve-deliver.md +142 -0
  49. package/docs/benchmarks/LCB_DROID_SMOKE.md +111 -0
  50. package/docs/guides/DELIVER.md +3 -1
  51. package/docs/guides/WORKFLOWS.md +179 -0
  52. package/docs/plans/model-performance-proof-options.md +39 -0
  53. package/docs/reference/CLI.md +33 -0
  54. package/docs/reference/CONFIGURATION.md +1 -0
  55. package/docs/reference/FEATURES.md +18 -0
  56. package/examples/auto-coordinator-example.js +127 -0
  57. package/examples/demo-order-solid.ts +19 -0
  58. package/examples/order-processing-strategy-pattern.ts +186 -0
  59. package/examples/order-processor-refactored.ts +473 -0
  60. package/examples/order-solid-refactor.ts +830 -0
  61. package/examples/refactored-order-processing.ts +106 -0
  62. package/examples/run-order-processing.ts +48 -0
  63. package/examples/solid-order-processing.ts +324 -0
  64. package/examples/strategy-pattern-example.ts +100 -0
  65. package/examples/workflows/team-solve/README.md +85 -0
  66. package/examples/workflows/team-solve/check-samples.sh +50 -0
  67. package/examples/workflows/team-solve/sample/task.md +22 -0
  68. package/examples/workflows/team-solve/sample/tests/1.in +2 -0
  69. package/examples/workflows/team-solve/sample/tests/1.out +1 -0
  70. package/examples/workflows/team-solve/sample/tests/2.in +2 -0
  71. package/examples/workflows/team-solve/sample/tests/2.out +1 -0
  72. package/examples/workflows/team-solve/sample/tests/3.in +2 -0
  73. package/examples/workflows/team-solve/sample/tests/3.out +1 -0
  74. package/examples/workflows/team-solve/sample/tests/4.in +2 -0
  75. package/examples/workflows/team-solve/sample/tests/4.out +1 -0
  76. package/examples/workflows/team-solve/sample/tests/5.in +1 -0
  77. package/examples/workflows/team-solve/sample/tests/5.out +1 -0
  78. package/examples/workflows/team-solve/steps/ideate-a.md +26 -0
  79. package/examples/workflows/team-solve/steps/ideate-b.md +28 -0
  80. package/examples/workflows/team-solve/steps/plan.md +20 -0
  81. package/examples/workflows/team-solve/steps/repair.md +25 -0
  82. package/examples/workflows/team-solve/steps/review.md +29 -0
  83. package/examples/workflows/team-solve/steps/solve.md +26 -0
  84. package/examples/workflows/team-solve/workflow.yaml +78 -0
  85. package/examples/workflows/team-solve-deliver/README.md +84 -0
  86. package/examples/workflows/team-solve-deliver/steps/ideate-a.md +25 -0
  87. package/examples/workflows/team-solve-deliver/steps/ideate-b.md +28 -0
  88. package/examples/workflows/team-solve-deliver/steps/plan.md +25 -0
  89. package/examples/workflows/team-solve-deliver/steps/repair.md +20 -0
  90. package/examples/workflows/team-solve-deliver/steps/review.md +31 -0
  91. package/examples/workflows/team-solve-deliver/steps/solve.md +28 -0
  92. package/examples/workflows/team-solve-deliver/steps/verify.md +9 -0
  93. package/examples/workflows/team-solve-deliver/workflow.yaml +74 -0
  94. package/package.json +2 -1
  95. package/src/policies/enforcers/__pycache__/_common.cpython-311.pyc +0 -0
  96. package/src/policies/enforcers/__pycache__/expert_review_required.cpython-311.pyc +0 -0
  97. package/src/policies/enforcers/__pycache__/quality_metrics_gate.cpython-311.pyc +0 -0
  98. package/templates/hooks/__pycache__/deliver_autoroute.cpython-311.pyc +0 -0
  99. package/tools/agents/scripts/__pycache__/toolcall_path_normalizer.cpython-311.pyc +0 -0
  100. package/tools/agents/scripts/anthropic_proxy.py +163 -18
@@ -0,0 +1,416 @@
1
+ /**
2
+ * Workflow runner — static steps onto the blackboard orchestrator.
3
+ *
4
+ * One runner, three step kinds, zero new graph semantics:
5
+ * agent → a FRESH single completion (role prompt + direct-dependency
6
+ * summaries + inlined run-dir files), reply written to the
7
+ * step's first `writes` entry. The Memdoor ledger discipline:
8
+ * steps talk through FILES, never through chat.
9
+ * command → shell in the run dir; exit 0 = success, unless `neverFails`
10
+ * (the `test` step pattern: capture, don't fail). The verdict
11
+ * step is just a command without the flag.
12
+ * gate → pause for `uap workflow approve`; unapproved = run BLOCKED
13
+ * (exit 2), resumable — a gate is an operator act, not a failure.
14
+ *
15
+ * Everything graph-shaped (dependency-triggered dispatch, skip cascade,
16
+ * bounded repair of a failed step, resume-at-the-boundary via initialDone /
17
+ * onProgress) is `orchestrate()` from task-orchestrator.ts, already
18
+ * validated by its own test suite. This module owns only the step seams.
19
+ */
20
+ import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'fs';
21
+ import { spawn } from 'child_process';
22
+ import { basename, dirname, join, normalize } from 'path';
23
+ import { orchestrate } from '../delivery/task-orchestrator.js';
24
+ import { WORKFLOW_EXIT, } from './types.js';
25
+ /** Summary prefix marking an unapproved gate — blocked, NOT failed. */
26
+ export const GATE_BLOCKED_PREFIX = 'GATE: awaiting approval';
27
+ /** Per-file inline cap for `reads:`. Elided with a marker, never a surprise. */
28
+ const READ_FILE_CAP_CHARS = 16_000;
29
+ /** Total budget for all inlined reads across one step (chars). */
30
+ const READ_TOTAL_CAP_CHARS = 48_000;
31
+ /** Default command kill timer (ms). */
32
+ const DEFAULT_COMMAND_TIMEOUT_MS = 120_000;
33
+ /** Gate approval poll interval (ms). */
34
+ const GATE_POLL_MS = 2_000;
35
+ const SPAWN_MAX_BUFFER = 8 * 1024 * 1024;
36
+ /** Names the runner owns inside the run directory. */
37
+ export const RUN_STATE_FILE = 'run-state.json';
38
+ export const GATES_DIR = '.gates';
39
+ export function runsDir(projectRoot) {
40
+ return join(projectRoot, '.uap', 'workflow-runs');
41
+ }
42
+ export function newRunId(workflow) {
43
+ const now = new Date();
44
+ const pad = (n) => String(n).padStart(2, '0');
45
+ return `${workflow}-${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
46
+ }
47
+ export function runStatePath(runDir) {
48
+ return join(runDir, RUN_STATE_FILE);
49
+ }
50
+ /** Read persisted state; null when absent (a fresh run). Fail-soft on corrupt. */
51
+ export function readRunState(runDir) {
52
+ const p = runStatePath(runDir);
53
+ if (!existsSync(p))
54
+ return null;
55
+ try {
56
+ return JSON.parse(readFileSync(p, 'utf8'));
57
+ }
58
+ catch {
59
+ return null;
60
+ }
61
+ }
62
+ export function writeRunState(runDir, state) {
63
+ mkdirSync(runDir, { recursive: true });
64
+ // Atomic (tmp + rename): an interrupt mid-write must never corrupt the
65
+ // resume state — stranding accepted work is exactly what resume exists to
66
+ // prevent. A `.tmp` remnant from a hard kill is inert and never read.
67
+ const finalPath = runStatePath(runDir);
68
+ const tmpPath = `${finalPath}.tmp`;
69
+ writeFileSync(tmpPath, JSON.stringify(state, null, 2) + '\n');
70
+ renameSync(tmpPath, finalPath);
71
+ }
72
+ /** Guard the runner's own files: a step writing run-state.json or .gates/
73
+ * would corrupt the machinery it runs under — including its own gate
74
+ * approval. Normalizes `./`-prefixed spellings so the guard compares what
75
+ * the filesystem will resolve, not what the author typed. */
76
+ export function assertNoReservedWrites(loaded) {
77
+ for (const s of loaded.def.steps) {
78
+ for (const p of s.writes ?? []) {
79
+ const norm = normalize(p);
80
+ if (norm === RUN_STATE_FILE ||
81
+ norm === GATES_DIR ||
82
+ norm.startsWith(`${GATES_DIR}/`)) {
83
+ throw new Error(`step "${s.id}" writes reserved path "${p}"`);
84
+ }
85
+ }
86
+ }
87
+ }
88
+ function inlineReads(runDir, step, log) {
89
+ if (!step.reads || step.reads.length === 0)
90
+ return '';
91
+ const sections = [];
92
+ let total = 0;
93
+ for (const p of step.reads) {
94
+ const abs = join(runDir, p);
95
+ if (!existsSync(abs)) {
96
+ // Fail-closed: the role prompt expects this file; a missing one means
97
+ // an upstream step lied about its writes (or the input was not copied).
98
+ throw new Error(`step "${step.id}" reads "${p}" but it does not exist in the run directory`);
99
+ }
100
+ const full = readFileSync(abs, 'utf8');
101
+ const capped = full.length > READ_FILE_CAP_CHARS
102
+ ? full.slice(0, READ_FILE_CAP_CHARS) + `\n…(elided ${full.length - READ_FILE_CAP_CHARS} chars)`
103
+ : full;
104
+ if (total + capped.length > READ_TOTAL_CAP_CHARS) {
105
+ log(` ⚠ ${step.id}: reads budget exhausted before "${p}" — file omitted from the prompt`);
106
+ break;
107
+ }
108
+ total += capped.length;
109
+ sections.push(`--- ${p} ---\n${capped}`);
110
+ }
111
+ if (sections.length === 0)
112
+ return '';
113
+ return `\n\nINPUT FILES (from the run directory — these are the ground truth):\n\n${sections.join('\n\n')}`;
114
+ }
115
+ /** Async command execution: a command step must never block the event loop —
116
+ * under parallel dispatch a synchronous spawn would freeze in-flight model
117
+ * completions and gate polls for the command's whole runtime. Exit code,
118
+ * start failure, and timeout are distinguished so the summary tells the
119
+ * truth about which of the three happened. Output is bounded at
120
+ * SPAWN_MAX_BUFFER (elided, never a crash). */
121
+ function spawnCommand(command, runDir, workflowDir, timeoutMs) {
122
+ return new Promise((resolve) => {
123
+ const child = spawn(command, {
124
+ shell: true,
125
+ cwd: runDir,
126
+ env: { ...process.env, UAP_WORKFLOW_DIR: workflowDir },
127
+ });
128
+ let output = '';
129
+ const append = (chunk) => {
130
+ if (output.length >= SPAWN_MAX_BUFFER)
131
+ return;
132
+ output += chunk.toString();
133
+ if (output.length > SPAWN_MAX_BUFFER) {
134
+ output = `${output.slice(0, SPAWN_MAX_BUFFER)}\n…(output elided at buffer bound)`;
135
+ }
136
+ };
137
+ child.stdout?.on('data', append);
138
+ child.stderr?.on('data', append);
139
+ let timedOut = false;
140
+ let settled = false;
141
+ const settle = (r) => {
142
+ if (settled)
143
+ return;
144
+ settled = true;
145
+ clearTimeout(timer);
146
+ resolve(r);
147
+ };
148
+ const timer = setTimeout(() => {
149
+ timedOut = true;
150
+ child.kill('SIGTERM');
151
+ // Escalate if the shell ignores TERM; the promise resolves on close.
152
+ setTimeout(() => child.kill('SIGKILL'), 5000).unref?.();
153
+ }, timeoutMs);
154
+ child.on('error', (err) => settle({ output, status: null, startError: err.message, timedOut: false }));
155
+ child.on('close', (code) => settle({ output, status: code, timedOut }));
156
+ });
157
+ }
158
+ /** Execute the workflow. The run directory is the ledger; state persists
159
+ * after every accepted step so an interrupt resumes at the step boundary. */
160
+ export async function runWorkflow(opts) {
161
+ const { loaded, runDir, mission } = opts;
162
+ assertNoReservedWrites(loaded);
163
+ // Preflight the seams BEFORE the run directory or state file exists — a
164
+ // rejected run must leave nothing behind (a fresh ledger dir with
165
+ // status 'running' would read as a live run in `status`). A missing loop
166
+ // provider or an agent seam must fail at start (exit-path clear), never
167
+ // mid-run after roles have been paid for. Pin preflight: the loader
168
+ // validated FILE pins at load; this catches CLI --model / --endpoint
169
+ // inputs too.
170
+ opts.resolveModel(undefined);
171
+ if (loaded.def.steps.some((s) => s.kind === 'loop') && !opts.runLoop) {
172
+ throw new Error('this workflow declares loop: steps but no convergence-loop provider was injected — ' +
173
+ 'loop steps run via a caller-owned seam (e.g. `uap deliver`); a standalone `uap workflow run` cannot execute them');
174
+ }
175
+ if (loaded.def.steps.some((s) => s.kind === 'agent') && !opts.completeStep && !opts.client) {
176
+ throw new Error('agent steps need a completion seam (client, or completeStep from the caller)');
177
+ }
178
+ mkdirSync(runDir, { recursive: true });
179
+ const log = opts.log ?? (() => undefined);
180
+ const byId = new Map(loaded.def.steps.map((s) => [s.id, s]));
181
+ // A fresh state, ALWAYS: done seeds come from opts.initialDone (the CLI's
182
+ // resume path) and never from whatever run-state.json happens to sit in
183
+ // the directory — a planted or stale state file must not be able to skip
184
+ // steps on a fresh run (a planted `verify` would exit 0 unverified).
185
+ const state = {
186
+ runId: basename(runDir),
187
+ workflow: loaded.def.name,
188
+ status: 'running',
189
+ startedAt: new Date().toISOString(),
190
+ updatedAt: new Date().toISOString(),
191
+ mission,
192
+ done: opts.initialDone ? [...opts.initialDone] : [],
193
+ failed: [],
194
+ };
195
+ state.updatedAt = new Date().toISOString();
196
+ writeRunState(runDir, state);
197
+ const tasks = loaded.def.steps.map((s) => {
198
+ const goal = s.kind === 'agent' || s.kind === 'loop'
199
+ ? (loaded.rolePrompts.get(s.id) ?? s.goal ?? '')
200
+ : s.kind === 'command'
201
+ ? `Run: ${s.command}`
202
+ : (s.approvalPrompt ?? `Approve step "${s.id}" to continue.`);
203
+ return {
204
+ id: s.id,
205
+ title: s.title ?? s.id,
206
+ goal,
207
+ deps: s.requires ?? [],
208
+ // Deliberately NO `files`: the assembler's "edit only these" line is
209
+ // deliver phrasing — a workflow step's role prompt already names the
210
+ // file it produces, and the reply lands in writes[0] verbatim.
211
+ criteria: s.criteria,
212
+ model: s.model,
213
+ };
214
+ });
215
+ // Seam preflights ran BEFORE the run dir existed (top of this function);
216
+ // nothing else gates the start.
217
+ const runTask = async (ctx, task) => {
218
+ const step = byId.get(task.id);
219
+ if (!step) {
220
+ return { taskId: task.id, success: false, summary: `unknown step "${task.id}"`, turns: 0 };
221
+ }
222
+ if (step.kind === 'agent') {
223
+ const prompt = ctx.prompt + inlineReads(runDir, step, log);
224
+ // completeStep (the caller's executor rails) takes precedence over the
225
+ // raw client — deliver's generator≠evaluator discipline rides through.
226
+ const content = opts.completeStep
227
+ ? await opts.completeStep(step, prompt)
228
+ : (await opts.client.complete(opts.resolveModel(step.model), prompt, {
229
+ temperature: opts.temperature ?? 0.7,
230
+ })).content;
231
+ // Fail-closed on the empty reply: writing an empty file and crediting
232
+ // the step would poison every dependent that reads it. (A truncated
233
+ // reply still lands — the client already re-requested once at 4x the
234
+ // budget; emptiness is the case that is unambiguously broken.)
235
+ if (!content || !content.trim()) {
236
+ return {
237
+ taskId: step.id,
238
+ success: false,
239
+ summary: 'model returned an empty reply — nothing written (retryable via step repair)',
240
+ turns: 1,
241
+ };
242
+ }
243
+ const target = step.writes?.[0];
244
+ if (target) {
245
+ mkdirSync(dirname(join(runDir, target)), { recursive: true });
246
+ writeFileSync(join(runDir, target), content);
247
+ }
248
+ const summary = target
249
+ ? `wrote ${target} (${content.length} chars)`
250
+ : content.slice(0, 200).replace(/\s+/g, ' ');
251
+ return { taskId: step.id, success: true, summary, turns: 1 };
252
+ }
253
+ if (step.kind === 'loop') {
254
+ // The convergence-loop seam: the engine assembles the instruction
255
+ // (role prompt + direct-dependency outputs + inlined reads) and hands
256
+ // it to the caller-owned loop. Gates are the loop's exit condition;
257
+ // the graph around it (repairs, skip cascade, resume) stays ours.
258
+ const prompt = ctx.prompt + inlineReads(runDir, step, log);
259
+ log(` ↻ loop ${step.id}${step.verifyOnly ? ' (verify-only)' : ''}`);
260
+ const r = await opts.runLoop({
261
+ stepId: step.id,
262
+ prompt,
263
+ ...(step.model ? { model: step.model } : {}),
264
+ ...(step.verifyOnly ? { verifyOnly: true } : {}),
265
+ ...(step.turns !== undefined ? { turns: step.turns } : {}),
266
+ });
267
+ return {
268
+ taskId: step.id,
269
+ success: r.success,
270
+ summary: r.summary.slice(0, 400),
271
+ turns: r.turns ?? 1,
272
+ };
273
+ }
274
+ if (step.kind === 'command') {
275
+ if (!step.command) {
276
+ // Loader already rejects this; fail-closed anyway — never spawn a lie.
277
+ return { taskId: step.id, success: false, summary: 'command step without command:', turns: 0 };
278
+ }
279
+ log(` $ ${step.command}`);
280
+ // Commands run with cwd = the run directory (the file ledger), but the
281
+ // workflow's own assets (harness scripts) stay in the workflow dir:
282
+ // $UAP_WORKFLOW_DIR is the explicit, injection-free seam between them.
283
+ const proc = await spawnCommand(step.command, runDir, loaded.dir, step.timeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS);
284
+ const target = step.writes?.[0] ?? `${step.id}.log`;
285
+ mkdirSync(dirname(join(runDir, target)), { recursive: true });
286
+ writeFileSync(join(runDir, target), proc.output);
287
+ if (proc.startError) {
288
+ return {
289
+ taskId: step.id,
290
+ success: step.neverFails === true,
291
+ summary: `command failed to start: ${proc.startError}`,
292
+ turns: 1,
293
+ };
294
+ }
295
+ if (proc.timedOut || proc.status === null) {
296
+ return {
297
+ taskId: step.id,
298
+ success: step.neverFails === true,
299
+ summary: `command timed out after ${step.timeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS}ms (output captured)`,
300
+ turns: 1,
301
+ };
302
+ }
303
+ return {
304
+ taskId: step.id,
305
+ success: step.neverFails === true || proc.status === 0,
306
+ summary: step.neverFails === true
307
+ ? `exit ${proc.status} (never-fails: captured to ${target})`
308
+ : `exit ${proc.status} (output in ${target})`,
309
+ turns: 1,
310
+ };
311
+ }
312
+ // gate: wait for the operator's approval file, bounded by waitMs.
313
+ const approvalFile = join(runDir, GATES_DIR, `${step.id}.approved`);
314
+ const deadline = Date.now() + (step.waitMs ?? 0);
315
+ while (!existsSync(approvalFile) && Date.now() < deadline) {
316
+ await new Promise((res) => setTimeout(res, GATE_POLL_MS));
317
+ }
318
+ if (existsSync(approvalFile)) {
319
+ return { taskId: step.id, success: true, summary: `gate approved`, turns: 1 };
320
+ }
321
+ return {
322
+ taskId: step.id,
323
+ success: false,
324
+ summary: `${GATE_BLOCKED_PREFIX} — run \`uap workflow approve <runId> ${step.id}\`, then resume`,
325
+ turns: 1,
326
+ };
327
+ };
328
+ // The orchestrator's governor hard-truncates the assembled prompt at the
329
+ // budget; at the default 6000 a long role prompt would be cut mid-text.
330
+ // Lift the budget by the largest role prompt so the GOAL always survives
331
+ // intact — dependency summaries stay governed (they are what the governor
332
+ // elides first, by design). Reads are bounded separately (16k/file,
333
+ // 48k/step) and documented as such.
334
+ const maxRolePromptChars = Math.max(0, ...[...loaded.rolePrompts.values()].map((p) => p.length));
335
+ const contextBudget = (loaded.def.contextBudgetChars ?? 6000) + maxRolePromptChars;
336
+ const result = await orchestrate({
337
+ mission,
338
+ tasks,
339
+ runTask,
340
+ concurrency: opts.parallel ?? loaded.def.parallel ?? 1,
341
+ ...(loaded.def.maxRepairsPerStep !== undefined ? { maxRepairsPerTask: loaded.def.maxRepairsPerStep } : {}),
342
+ contextBudgetChars: contextBudget,
343
+ ...(opts.initialDone ? { initialDone: opts.initialDone } : {}),
344
+ onProgress: (done) => {
345
+ state.done = done;
346
+ state.updatedAt = new Date().toISOString();
347
+ writeRunState(runDir, state);
348
+ },
349
+ onTask: (task, outcome) => {
350
+ log(` ${outcome.success ? '✓' : '✗'} ${task.id}: ${outcome.summary}`);
351
+ },
352
+ });
353
+ // Blocked gate ≠ failed step — but the distinction must be honest in BOTH
354
+ // directions. A gate in the FINAL failed set (last-entry-wins: an approved
355
+ // retry removes it) makes the run BLOCKED (exit 2, resumable), together
356
+ // with every descendant the skip cascade dropped behind it. A real defect
357
+ // anywhere OUTSIDE that blocked subtree reports failed (exit 1) — a broken
358
+ // step never hides behind a gate.
359
+ const gateIds = new Set(loaded.def.steps.filter((s) => s.kind === 'gate').map((s) => s.id));
360
+ const blockedGates = result.failed.filter((id) => gateIds.has(id));
361
+ let status = 'failed';
362
+ let blockedStep;
363
+ if (!result.success && blockedGates.length > 0) {
364
+ const blockedSubtree = new Set(blockedGates);
365
+ const queue = [...blockedGates];
366
+ while (queue.length > 0) {
367
+ const cur = queue.pop();
368
+ for (const s of loaded.def.steps) {
369
+ if ((s.requires ?? []).includes(cur) && !blockedSubtree.has(s.id)) {
370
+ blockedSubtree.add(s.id);
371
+ queue.push(s.id);
372
+ }
373
+ }
374
+ }
375
+ const realFailures = result.failed.filter((id) => !blockedSubtree.has(id));
376
+ if (realFailures.length === 0) {
377
+ status = 'blocked';
378
+ // Last blocked outcome of the last blocked gate (repair retries emit
379
+ // several; the last one is the operative state).
380
+ const lastBlocked = result.outcomes
381
+ .filter((o) => blockedGates.includes(o.taskId) && o.summary.startsWith(GATE_BLOCKED_PREFIX))
382
+ .pop();
383
+ blockedStep = lastBlocked?.taskId;
384
+ }
385
+ }
386
+ else if (result.success) {
387
+ status = 'succeeded';
388
+ }
389
+ state.status = status;
390
+ state.failed = result.failed;
391
+ state.updatedAt = new Date().toISOString();
392
+ if (status !== 'blocked')
393
+ state.endedAt = new Date().toISOString();
394
+ writeRunState(runDir, state);
395
+ return {
396
+ status,
397
+ exitCode: status === 'succeeded'
398
+ ? WORKFLOW_EXIT.ok
399
+ : status === 'blocked'
400
+ ? WORKFLOW_EXIT.blocked
401
+ : WORKFLOW_EXIT.stepFailed,
402
+ completed: result.completed,
403
+ failed: result.failed,
404
+ ...(blockedStep !== undefined ? { blockedStep } : {}),
405
+ turns: result.turns,
406
+ };
407
+ }
408
+ /** Create the approval marker a gate step polls for. */
409
+ export function approveGate(runDir, stepId) {
410
+ const gates = join(runDir, GATES_DIR);
411
+ mkdirSync(gates, { recursive: true });
412
+ const p = join(gates, `${stepId}.approved`);
413
+ writeFileSync(p, new Date().toISOString() + '\n');
414
+ return p;
415
+ }
416
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/workflow/runner.ts"],"names":[],"mappings":"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"}