@studio-foundation/engine 0.4.0-beta → 0.5.2

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 (86) hide show
  1. package/README.md +1 -1
  2. package/dist/__tests__/engine.script-stage.test.js +13 -32
  3. package/dist/__tests__/engine.script-stage.test.js.map +1 -1
  4. package/dist/engine.d.ts +2 -0
  5. package/dist/engine.d.ts.map +1 -1
  6. package/dist/engine.js +134 -1
  7. package/dist/engine.js.map +1 -1
  8. package/dist/events.d.ts +48 -0
  9. package/dist/events.d.ts.map +1 -1
  10. package/dist/events.js.map +1 -1
  11. package/dist/index.d.ts +5 -1
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +4 -0
  14. package/dist/index.js.map +1 -1
  15. package/dist/pipeline/call-input.d.ts +4 -0
  16. package/dist/pipeline/call-input.d.ts.map +1 -0
  17. package/dist/pipeline/call-input.js +28 -0
  18. package/dist/pipeline/call-input.js.map +1 -0
  19. package/dist/pipeline/call-orchestrator.d.ts +21 -0
  20. package/dist/pipeline/call-orchestrator.d.ts.map +1 -0
  21. package/dist/pipeline/call-orchestrator.js +127 -0
  22. package/dist/pipeline/call-orchestrator.js.map +1 -0
  23. package/dist/pipeline/condition-evaluator.d.ts +12 -0
  24. package/dist/pipeline/condition-evaluator.d.ts.map +1 -1
  25. package/dist/pipeline/condition-evaluator.js +27 -9
  26. package/dist/pipeline/condition-evaluator.js.map +1 -1
  27. package/dist/pipeline/context-propagation.d.ts +1 -0
  28. package/dist/pipeline/context-propagation.d.ts.map +1 -1
  29. package/dist/pipeline/context-propagation.js +18 -0
  30. package/dist/pipeline/context-propagation.js.map +1 -1
  31. package/dist/pipeline/contract-loader.d.ts.map +1 -1
  32. package/dist/pipeline/contract-loader.js +67 -0
  33. package/dist/pipeline/contract-loader.js.map +1 -1
  34. package/dist/pipeline/external-validator.d.ts +3 -0
  35. package/dist/pipeline/external-validator.d.ts.map +1 -0
  36. package/dist/pipeline/external-validator.js +65 -0
  37. package/dist/pipeline/external-validator.js.map +1 -0
  38. package/dist/pipeline/external-validator.test.d.ts +2 -0
  39. package/dist/pipeline/external-validator.test.d.ts.map +1 -0
  40. package/dist/pipeline/external-validator.test.js +40 -0
  41. package/dist/pipeline/external-validator.test.js.map +1 -0
  42. package/dist/pipeline/loader.d.ts.map +1 -1
  43. package/dist/pipeline/loader.js +154 -1
  44. package/dist/pipeline/loader.js.map +1 -1
  45. package/dist/pipeline/loader.test.js +30 -0
  46. package/dist/pipeline/loader.test.js.map +1 -1
  47. package/dist/pipeline/map-input.d.ts +13 -0
  48. package/dist/pipeline/map-input.d.ts.map +1 -0
  49. package/dist/pipeline/map-input.js +80 -0
  50. package/dist/pipeline/map-input.js.map +1 -0
  51. package/dist/pipeline/map-orchestrator.d.ts +35 -0
  52. package/dist/pipeline/map-orchestrator.d.ts.map +1 -0
  53. package/dist/pipeline/map-orchestrator.js +223 -0
  54. package/dist/pipeline/map-orchestrator.js.map +1 -0
  55. package/dist/pipeline/output-checker.d.ts +3 -0
  56. package/dist/pipeline/output-checker.d.ts.map +1 -0
  57. package/dist/pipeline/output-checker.js +40 -0
  58. package/dist/pipeline/output-checker.js.map +1 -0
  59. package/dist/pipeline/output-checker.test.d.ts +2 -0
  60. package/dist/pipeline/output-checker.test.d.ts.map +1 -0
  61. package/dist/pipeline/output-checker.test.js +62 -0
  62. package/dist/pipeline/output-checker.test.js.map +1 -0
  63. package/dist/pipeline/stage-executor.d.ts.map +1 -1
  64. package/dist/pipeline/stage-executor.js +48 -9
  65. package/dist/pipeline/stage-executor.js.map +1 -1
  66. package/dist/pipeline/stage-resolver.js +1 -1
  67. package/dist/pipeline/stage-resolver.js.map +1 -1
  68. package/dist/pipeline/strict-fields.d.ts +20 -0
  69. package/dist/pipeline/strict-fields.d.ts.map +1 -0
  70. package/dist/pipeline/strict-fields.js +62 -0
  71. package/dist/pipeline/strict-fields.js.map +1 -0
  72. package/dist/pipeline/task-input.d.ts +14 -0
  73. package/dist/pipeline/task-input.d.ts.map +1 -0
  74. package/dist/pipeline/task-input.js +22 -0
  75. package/dist/pipeline/task-input.js.map +1 -0
  76. package/dist/pipeline/task-input.test.d.ts +2 -0
  77. package/dist/pipeline/task-input.test.d.ts.map +1 -0
  78. package/dist/pipeline/task-input.test.js +33 -0
  79. package/dist/pipeline/task-input.test.js.map +1 -0
  80. package/dist/pipeline/template-interpolation.d.ts +9 -0
  81. package/dist/pipeline/template-interpolation.d.ts.map +1 -0
  82. package/dist/pipeline/template-interpolation.js +33 -0
  83. package/dist/pipeline/template-interpolation.js.map +1 -0
  84. package/dist/state/status-derivation.js +3 -3
  85. package/dist/state/status-derivation.js.map +1 -1
  86. package/package.json +5 -5
@@ -0,0 +1,127 @@
1
+ // CallOrchestrator — executes a one-shot `call` stage.
2
+ //
3
+ // A call stage runs a named pipeline once and exposes its output to later parent
4
+ // stages under the stage name. It is `map` with the iteration removed: the same
5
+ // in-process RunSpawner path (structured output, no log scraping), for when the
6
+ // shape is a sequence rather than a fan-out — chaining top-level pipelines like
7
+ // wiki-extraction → wiki-resolution → wiki-preparation → pages-export in one
8
+ // YAML, which `run_wiki.py` otherwise sequences outside Studio.
9
+ import { randomUUID } from 'node:crypto';
10
+ import { evaluateCondition } from './condition-evaluator.js';
11
+ import { buildCallInput } from './call-input.js';
12
+ function errorMessage(err) {
13
+ return err instanceof Error ? err.message : String(err);
14
+ }
15
+ export class CallOrchestrator {
16
+ config;
17
+ constructor(config) {
18
+ this.config = config;
19
+ }
20
+ async run(call, context, stageIndex, totalStages, runId, depth, signal) {
21
+ const pipeline = call.pipeline ?? call.call;
22
+ const startedAt = new Date().toISOString();
23
+ const stageRun = {
24
+ id: randomUUID(),
25
+ stage_name: call.call,
26
+ status: 'running',
27
+ started_at: startedAt,
28
+ tasks: [],
29
+ };
30
+ const finish = (status, output, skippedReason) => {
31
+ stageRun.status = status;
32
+ stageRun.completed_at = new Date().toISOString();
33
+ if (output !== undefined)
34
+ stageRun.output = output;
35
+ if (skippedReason)
36
+ stageRun.skipped_reason = skippedReason;
37
+ this.config.events?.onStageComplete?.({
38
+ stage_name: call.call,
39
+ stage_index: stageIndex,
40
+ total_stages: totalStages,
41
+ status,
42
+ attempts: 1,
43
+ duration_ms: Date.now() - new Date(startedAt).getTime(),
44
+ ...(output !== undefined ? { output } : {}),
45
+ ...(skippedReason ? { skipped_reason: skippedReason } : {}),
46
+ });
47
+ this.config.emitter.emit({ type: 'stage_complete', stageId: stageRun.id, stageName: call.call });
48
+ return { status, stageRun, output };
49
+ };
50
+ // Technical/child failure — record the reason as a failed task so it surfaces
51
+ // in `studio status`, the run JSONL, and the CLI's "Errors:" line.
52
+ const failWith = (reason) => {
53
+ const now = new Date().toISOString();
54
+ const taskRun = {
55
+ id: randomUUID(),
56
+ task_name: call.call,
57
+ status: 'failed',
58
+ started_at: startedAt,
59
+ completed_at: now,
60
+ agent_runs: [{
61
+ id: randomUUID(),
62
+ agent_name: `call:${pipeline}`,
63
+ attempt: 1,
64
+ status: 'failed',
65
+ tool_calls: 0,
66
+ started_at: startedAt,
67
+ completed_at: now,
68
+ error: reason,
69
+ }],
70
+ };
71
+ stageRun.tasks = [taskRun];
72
+ return finish('failed');
73
+ };
74
+ this.config.events?.onStageStart?.({
75
+ stage_name: call.call,
76
+ stage_index: stageIndex,
77
+ total_stages: totalStages,
78
+ max_attempts: 1,
79
+ });
80
+ this.config.emitter.emit({ type: 'stage_start', stageId: stageRun.id, stageName: call.call });
81
+ // Condition — skip the call if false.
82
+ if (call.condition !== undefined) {
83
+ const shouldRun = evaluateCondition(call.condition, {
84
+ input: context.input,
85
+ stageOutputs: context.stageOutputs,
86
+ });
87
+ if (!shouldRun) {
88
+ return finish('skipped', undefined, `condition not met: ${call.condition}`);
89
+ }
90
+ }
91
+ if (signal?.aborted)
92
+ return finish('cancelled');
93
+ // A call stage spawns a child run — it needs a spawner.
94
+ if (!this.config.spawner) {
95
+ return failWith(`Call stage '${call.call}' requires a run spawner, but none is configured. ` +
96
+ `Sub-pipeline calls spawn a child run; construct the engine with a 'spawner'.`);
97
+ }
98
+ // Depth guard — mirror map/studio_run's recursion limit.
99
+ if (depth + 1 > this.config.maxDepth) {
100
+ return failWith(`Call stage '${call.call}' would spawn a run at depth ${depth + 1}, exceeding maxDepth ${this.config.maxDepth}. ` +
101
+ `Recursive sub-pipeline calls are not allowed at this nesting level.`);
102
+ }
103
+ let input;
104
+ try {
105
+ input = buildCallInput(call, context);
106
+ }
107
+ catch (err) {
108
+ return failWith(errorMessage(err));
109
+ }
110
+ try {
111
+ const spawn = await this.config.spawner.spawnAndWait({
112
+ pipeline,
113
+ input,
114
+ parentRunId: runId,
115
+ depth: depth + 1,
116
+ });
117
+ return finish('success', spawn.output);
118
+ }
119
+ catch (err) {
120
+ // Cancelled mid-flight → cancelled, not a real failure.
121
+ if (signal?.aborted)
122
+ return finish('cancelled');
123
+ return failWith(errorMessage(err));
124
+ }
125
+ }
126
+ }
127
+ //# sourceMappingURL=call-orchestrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"call-orchestrator.js","sourceRoot":"","sources":["../../src/pipeline/call-orchestrator.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,EAAE;AACF,iFAAiF;AACjF,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAChF,6EAA6E;AAC7E,gEAAgE;AAEhE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAiBjD,SAAS,YAAY,CAAC,GAAY;IAChC,OAAO,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,OAAO,gBAAgB;IACP;IAApB,YAAoB,MAA8B;QAA9B,WAAM,GAAN,MAAM,CAAwB;IAAG,CAAC;IAEtD,KAAK,CAAC,GAAG,CACP,IAAe,EACf,OAAwB,EACxB,UAAkB,EAClB,WAAmB,EACnB,KAAa,EACb,KAAa,EACb,MAAoB;QAEpB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC;QAC5C,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,QAAQ,GAAa;YACzB,EAAE,EAAE,UAAU,EAAE;YAChB,UAAU,EAAE,IAAI,CAAC,IAAI;YACrB,MAAM,EAAE,SAAS;YACjB,UAAU,EAAE,SAAS;YACrB,KAAK,EAAE,EAAE;SACV,CAAC;QAEF,MAAM,MAAM,GAAG,CAAC,MAAmB,EAAE,MAAgB,EAAE,aAAsB,EAAiB,EAAE;YAC9F,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC;YACzB,QAAQ,CAAC,YAAY,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACjD,IAAI,MAAM,KAAK,SAAS;gBAAE,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC;YACnD,IAAI,aAAa;gBAAE,QAAQ,CAAC,cAAc,GAAG,aAAa,CAAC;YAC3D,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,EAAE,CAAC;gBACpC,UAAU,EAAE,IAAI,CAAC,IAAI;gBACrB,WAAW,EAAE,UAAU;gBACvB,YAAY,EAAE,WAAW;gBACzB,MAAM;gBACN,QAAQ,EAAE,CAAC;gBACX,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE;gBACvD,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC3C,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC5D,CAAC,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YACjG,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;QACtC,CAAC,CAAC;QAEF,8EAA8E;QAC9E,mEAAmE;QACnE,MAAM,QAAQ,GAAG,CAAC,MAAc,EAAiB,EAAE;YACjD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACrC,MAAM,OAAO,GAAY;gBACvB,EAAE,EAAE,UAAU,EAAE;gBAChB,SAAS,EAAE,IAAI,CAAC,IAAI;gBACpB,MAAM,EAAE,QAAQ;gBAChB,UAAU,EAAE,SAAS;gBACrB,YAAY,EAAE,GAAG;gBACjB,UAAU,EAAE,CAAC;wBACX,EAAE,EAAE,UAAU,EAAE;wBAChB,UAAU,EAAE,QAAQ,QAAQ,EAAE;wBAC9B,OAAO,EAAE,CAAC;wBACV,MAAM,EAAE,QAAQ;wBAChB,UAAU,EAAE,CAAC;wBACb,UAAU,EAAE,SAAS;wBACrB,YAAY,EAAE,GAAG;wBACjB,KAAK,EAAE,MAAM;qBACd,CAAC;aACH,CAAC;YACF,QAAQ,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC;YAC3B,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC1B,CAAC,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC;YACjC,UAAU,EAAE,IAAI,CAAC,IAAI;YACrB,WAAW,EAAE,UAAU;YACvB,YAAY,EAAE,WAAW;YACzB,YAAY,EAAE,CAAC;SAChB,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAE9F,sCAAsC;QACtC,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YACjC,MAAM,SAAS,GAAG,iBAAiB,CAAC,IAAI,CAAC,SAAS,EAAE;gBAClD,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,YAAY,EAAE,OAAO,CAAC,YAAY;aACnC,CAAC,CAAC;YACH,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,OAAO,MAAM,CAAC,SAAS,EAAE,SAAS,EAAE,sBAAsB,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;YAC9E,CAAC;QACH,CAAC;QAED,IAAI,MAAM,EAAE,OAAO;YAAE,OAAO,MAAM,CAAC,WAAW,CAAC,CAAC;QAEhD,wDAAwD;QACxD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACzB,OAAO,QAAQ,CACb,eAAe,IAAI,CAAC,IAAI,oDAAoD;gBAC5E,8EAA8E,CAC/E,CAAC;QACJ,CAAC;QAED,yDAAyD;QACzD,IAAI,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YACrC,OAAO,QAAQ,CACb,eAAe,IAAI,CAAC,IAAI,gCAAgC,KAAK,GAAG,CAAC,wBAAwB,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI;gBACjH,qEAAqE,CACtE,CAAC;QACJ,CAAC;QAED,IAAI,KAA8B,CAAC;QACnC,IAAI,CAAC;YACH,KAAK,GAAG,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;QACrC,CAAC;QAED,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC;gBACnD,QAAQ;gBACR,KAAK;gBACL,WAAW,EAAE,KAAK;gBAClB,KAAK,EAAE,KAAK,GAAG,CAAC;aACjB,CAAC,CAAC;YACH,OAAO,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QACzC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,wDAAwD;YACxD,IAAI,MAAM,EAAE,OAAO;gBAAE,OAAO,MAAM,CAAC,WAAW,CAAC,CAAC;YAChD,OAAO,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;CACF"}
@@ -3,4 +3,16 @@ export declare function evaluateCondition(condition: string, context: {
3
3
  input: PipelineInput;
4
4
  stageOutputs: Map<string, unknown>;
5
5
  }): boolean;
6
+ /**
7
+ * Resolve a context reference to its value. Shared by the condition evaluator
8
+ * and the fan-out `over:`/`{{...}}` resolution so both read context identically.
9
+ * Supported forms:
10
+ * input.<field.path>
11
+ * stages.<stage-name>.output.<field.path>
12
+ * Returns undefined for any unknown prefix or unreachable path.
13
+ */
14
+ export declare function resolveContextPath(ref: string, context: {
15
+ input: PipelineInput;
16
+ stageOutputs: Map<string, unknown>;
17
+ }): unknown;
6
18
  //# sourceMappingURL=condition-evaluator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"condition-evaluator.d.ts","sourceRoot":"","sources":["../../src/pipeline/condition-evaluator.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAM9D,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE;IAAE,KAAK,EAAE,aAAa,CAAC;IAAC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GACpE,OAAO,CAyBT"}
1
+ {"version":3,"file":"condition-evaluator.d.ts","sourceRoot":"","sources":["../../src/pipeline/condition-evaluator.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAM9D,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE;IAAE,KAAK,EAAE,aAAa,CAAC;IAAC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GACpE,OAAO,CAyBT;AASD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE;IAAE,KAAK,EAAE,aAAa,CAAC;IAAC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GACpE,OAAO,CA6BT"}
@@ -30,26 +30,44 @@ export function evaluateCondition(condition, context) {
30
30
  return compare(lhsValue, operator, rhsValue);
31
31
  }
32
32
  function resolveLhs(lhs, context) {
33
- if (lhs.startsWith('input.')) {
34
- const fieldPath = lhs.slice('input.'.length);
33
+ return resolveContextPath(lhs, context);
34
+ }
35
+ /**
36
+ * Resolve a context reference to its value. Shared by the condition evaluator
37
+ * and the fan-out `over:`/`{{...}}` resolution so both read context identically.
38
+ * Supported forms:
39
+ * input.<field.path>
40
+ * stages.<stage-name>.output.<field.path>
41
+ * Returns undefined for any unknown prefix or unreachable path.
42
+ */
43
+ export function resolveContextPath(ref, context) {
44
+ if (ref === 'input')
45
+ return context.input;
46
+ if (ref.startsWith('input.')) {
47
+ const fieldPath = ref.slice('input.'.length);
35
48
  if (typeof context.input !== 'object' || context.input === null)
36
49
  return undefined;
37
50
  return traversePath(context.input, fieldPath);
38
51
  }
39
- if (lhs.startsWith('stages.')) {
40
- // Format: stages.<stage-name>.output.<field.path>
41
- // Stage names can contain hyphens — split on first '.output.' occurrence
42
- const rest = lhs.slice('stages.'.length);
43
- const outputMarker = '.output.';
52
+ if (ref.startsWith('stages.')) {
53
+ // Format: stages.<stage-name>.output(.<field.path>)?
54
+ // Stage names can contain hyphens — split on first '.output' occurrence
55
+ const rest = ref.slice('stages.'.length);
56
+ const outputMarker = '.output';
44
57
  const markerIdx = rest.indexOf(outputMarker);
45
58
  if (markerIdx === -1)
46
59
  return undefined;
47
60
  const stageName = rest.slice(0, markerIdx);
48
- const fieldPath = rest.slice(markerIdx + outputMarker.length);
61
+ const afterMarker = rest.slice(markerIdx + outputMarker.length);
49
62
  const stageOutput = context.stageOutputs.get(stageName);
50
63
  if (stageOutput === undefined || stageOutput === null)
51
64
  return undefined;
52
- return traversePath(stageOutput, fieldPath);
65
+ // "stages.foo.output" → the whole output; "stages.foo.output.a.b" → nested
66
+ if (afterMarker === '')
67
+ return stageOutput;
68
+ if (!afterMarker.startsWith('.'))
69
+ return undefined;
70
+ return traversePath(stageOutput, afterMarker.slice(1));
53
71
  }
54
72
  return undefined;
55
73
  }
@@ -1 +1 @@
1
- {"version":3,"file":"condition-evaluator.js","sourceRoot":"","sources":["../../src/pipeline/condition-evaluator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"condition-evaluator.js","sourceRoot":"","sources":["../../src/pipeline/condition-evaluator.ts"],"names":[],"mappings":"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"}
@@ -24,5 +24,6 @@ export declare function setGroupFeedback(context: PipelineContext, feedback: Gro
24
24
  export declare function clearGroupFeedback(context: PipelineContext): void;
25
25
  export declare function buildContextKeys(agentContext: AgentContext, previousOutputSizes: Map<string, number>): Record<string, number>;
26
26
  export declare function buildContextContent(agentContext: AgentContext): Record<string, unknown>;
27
+ export declare const CONTEXT_INCLUDE_DIRECTIVES: readonly ["input", "previous_stage_output", "all_stage_outputs", "stage_name", "group_feedback", "previous_stage_tool_results", "all_stage_tool_results", "repo_files", "repo_structure", "pipeline_start_context"];
27
28
  export declare function getContextForStage(context: PipelineContext, stage: StageDefinition, previousStageName?: string): AgentContext;
28
29
  //# sourceMappingURL=context-propagation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"context-propagation.d.ts","sourceRoot":"","sources":["../../src/pipeline/context-propagation.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAE9D,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE7D,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,aAAa,CAAC;IACrB,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,eAAe,CAQ7F;AAED,wBAAgB,cAAc,CAC5B,OAAO,EAAE,eAAe,EACxB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,OAAO,GACd,eAAe,CAIjB;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,eAAe,EACxB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,QAAQ,EAAE,GACpB,eAAe,CAGjB;AAED,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,aAAa,GACtB,IAAI,CAEN;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,CAEjE;AAED,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,YAAY,EAC1B,mBAAmB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GACvC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAwCxB;AAED,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,YAAY,GACzB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAgCzB;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,eAAe,EACxB,KAAK,EAAE,eAAe,EACtB,iBAAiB,CAAC,EAAE,MAAM,GACzB,YAAY,CAkFd"}
1
+ {"version":3,"file":"context-propagation.d.ts","sourceRoot":"","sources":["../../src/pipeline/context-propagation.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAE9D,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE7D,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,aAAa,CAAC;IACrB,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,eAAe,CAQ7F;AAED,wBAAgB,cAAc,CAC5B,OAAO,EAAE,eAAe,EACxB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,OAAO,GACd,eAAe,CAIjB;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,eAAe,EACxB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,QAAQ,EAAE,GACpB,eAAe,CAGjB;AAED,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,aAAa,GACtB,IAAI,CAEN;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,CAEjE;AAED,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,YAAY,EAC1B,mBAAmB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GACvC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAwCxB;AAED,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,YAAY,GACzB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAgCzB;AAQD,eAAO,MAAM,0BAA0B,qNAW7B,CAAC;AAEX,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,eAAe,EACxB,KAAK,EAAE,eAAe,EACtB,iBAAiB,CAAC,EAAE,MAAM,GACzB,YAAY,CAkFd"}
@@ -85,6 +85,24 @@ export function buildContextContent(agentContext) {
85
85
  }
86
86
  return content;
87
87
  }
88
+ // Every directive `getContextForStage` implements below. A `context.include`
89
+ // entry outside this set is config-theatre: the switch has no case for it, so it
90
+ // is silently dropped — the user believes a context is wired that never arrives
91
+ // (STU-593). The loader validates against this at load time. KEEP IN SYNC with
92
+ // the switch cases below: a case added here without an entry is rejected at load;
93
+ // an entry added without a case is silently ignored, the bug this closes.
94
+ export const CONTEXT_INCLUDE_DIRECTIVES = [
95
+ 'input',
96
+ 'previous_stage_output',
97
+ 'all_stage_outputs',
98
+ 'stage_name',
99
+ 'group_feedback',
100
+ 'previous_stage_tool_results',
101
+ 'all_stage_tool_results',
102
+ 'repo_files',
103
+ 'repo_structure',
104
+ 'pipeline_start_context',
105
+ ];
88
106
  export function getContextForStage(context, stage, previousStageName) {
89
107
  const agentContext = {};
90
108
  const includes = stage.context?.include ?? ['input'];
@@ -1 +1 @@
1
- {"version":3,"file":"context-propagation.js","sourceRoot":"","sources":["../../src/pipeline/context-propagation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"context-propagation.js","sourceRoot":"","sources":["../../src/pipeline/context-propagation.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"contract-loader.d.ts","sourceRoot":"","sources":["../../src/pipeline/contract-loader.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAEnE,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,cAAc,CAAC,CAWzB;AAED,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,cAAc,CAiB1F"}
1
+ {"version":3,"file":"contract-loader.d.ts","sourceRoot":"","sources":["../../src/pipeline/contract-loader.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAuBnE,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,cAAc,CAAC,CAWzB;AAED,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,cAAc,CA6C1F"}
@@ -2,6 +2,26 @@
2
2
  import { readFile } from 'node:fs/promises';
3
3
  import { join } from 'node:path';
4
4
  import * as yaml from 'js-yaml';
5
+ import { assertKnownFields } from './strict-fields.js';
6
+ // Every field the kernel implements for contracts, per block (see OutputContract).
7
+ // A field listed nowhere here is config-theatre and must be rejected, not ignored.
8
+ const CONTRACT_FIELDS = [
9
+ 'name', 'version', 'schema', 'tool_calls', 'validators',
10
+ 'custom_rules', 'post_validation', 'expected_outputs',
11
+ ];
12
+ const SCHEMA_FIELDS = ['required_fields', 'fields'];
13
+ const FIELD_SPEC_FIELDS = ['type', 'enum', 'required_fields', 'fields', 'items'];
14
+ const EXPECTED_OUTPUTS_FIELDS = ['files'];
15
+ const TOOL_CALLS_FIELDS = [
16
+ 'minimum', 'maximum', 'required_tools', 'required_tool_groups', 'counted_tools',
17
+ ];
18
+ const VALIDATOR_FIELDS = ['name', 'command', 'timeout_ms'];
19
+ const CUSTOM_RULE_FIELDS = ['name', 'description', 'check'];
20
+ const POST_VALIDATION_FIELDS = ['rejection_detection'];
21
+ const REJECTION_DETECTION_FIELDS = [
22
+ 'field', 'rejected_values', 'approved_values',
23
+ 'details_field', 'summary_field', 'reject_if_non_empty',
24
+ ];
5
25
  export async function loadContract(name, contractsDir) {
6
26
  const path = join(contractsDir, `${name}.contract.yaml`);
7
27
  let content;
@@ -25,6 +45,53 @@ export function parseContractYaml(yamlContent, sourcePath) {
25
45
  if (parsed.version === undefined) {
26
46
  throw new Error(`Contract missing required field 'version'${context}`);
27
47
  }
48
+ const inContract = `of contract '${parsed.name}'`;
49
+ assertKnownFields(parsed, CONTRACT_FIELDS, `contract '${parsed.name}'`, context);
50
+ const check = (block, allowed, what) => {
51
+ if (block && typeof block === 'object' && !Array.isArray(block)) {
52
+ assertKnownFields(block, allowed, `${what} ${inContract}`, context);
53
+ }
54
+ };
55
+ check(parsed.schema, SCHEMA_FIELDS, 'schema');
56
+ const schemaFields = parsed.schema?.fields;
57
+ if (schemaFields && typeof schemaFields === 'object' && !Array.isArray(schemaFields)) {
58
+ checkFieldSpecs(schemaFields, 'schema.fields', inContract, context);
59
+ }
60
+ check(parsed.tool_calls, TOOL_CALLS_FIELDS, 'tool_calls');
61
+ check(parsed.expected_outputs, EXPECTED_OUTPUTS_FIELDS, 'expected_outputs');
62
+ check(parsed.post_validation, POST_VALIDATION_FIELDS, 'post_validation');
63
+ const rejectionDetection = parsed.post_validation
64
+ ?.rejection_detection;
65
+ check(rejectionDetection, REJECTION_DETECTION_FIELDS, 'post_validation.rejection_detection');
66
+ if (Array.isArray(parsed.validators)) {
67
+ for (const v of parsed.validators)
68
+ check(v, VALIDATOR_FIELDS, 'validators entry');
69
+ }
70
+ if (Array.isArray(parsed.custom_rules)) {
71
+ for (const r of parsed.custom_rules)
72
+ check(r, CUSTOM_RULE_FIELDS, 'custom_rules entry');
73
+ }
28
74
  return parsed;
29
75
  }
76
+ /**
77
+ * Fail-loud strict check for `schema.fields`: every field spec, and every nested
78
+ * spec inside `fields`/`items`, may only carry keys the validator implements. A
79
+ * stray key here (e.g. `min_items`, `pattern`) is config-theatre — it must be
80
+ * rejected at load time, not silently ignored, exactly like the top-level blocks.
81
+ */
82
+ function checkFieldSpecs(fields, path, inContract, context) {
83
+ for (const [name, spec] of Object.entries(fields)) {
84
+ if (!spec || typeof spec !== 'object' || Array.isArray(spec))
85
+ continue;
86
+ const specObj = spec;
87
+ assertKnownFields(specObj, FIELD_SPEC_FIELDS, `${path}.${name} ${inContract}`, context);
88
+ if (specObj.fields && typeof specObj.fields === 'object' && !Array.isArray(specObj.fields)) {
89
+ checkFieldSpecs(specObj.fields, `${path}.${name}.fields`, inContract, context);
90
+ }
91
+ if (specObj.items && typeof specObj.items === 'object' && !Array.isArray(specObj.items)) {
92
+ // `items` is itself a single field spec; check it under a one-entry map.
93
+ checkFieldSpecs({ '[]': specObj.items }, `${path}.${name}.items`, inContract, context);
94
+ }
95
+ }
96
+ }
30
97
  //# sourceMappingURL=contract-loader.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"contract-loader.js","sourceRoot":"","sources":["../../src/pipeline/contract-loader.ts"],"names":[],"mappings":"AAAA,wCAAwC;AAExC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,IAAI,MAAM,SAAS,CAAC;AAGhC,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAY,EACZ,YAAoB;IAEpB,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,EAAE,GAAG,IAAI,gBAAgB,CAAC,CAAC;IAEzD,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,4BAA4B,IAAI,QAAQ,IAAI,KAAM,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7F,CAAC;IAED,OAAO,iBAAiB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,WAAmB,EAAE,UAAmB;IACxE,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,CAA4B,CAAC;IACjE,MAAM,OAAO,GAAG,UAAU,CAAC,CAAC,CAAC,UAAU,UAAU,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAE1D,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,4CAA4C,OAAO,EAAE,CAAC,CAAC;IACzE,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CAAC,yCAAyC,OAAO,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,4CAA4C,OAAO,EAAE,CAAC,CAAC;IACzE,CAAC;IAED,OAAO,MAAmC,CAAC;AAC7C,CAAC"}
1
+ {"version":3,"file":"contract-loader.js","sourceRoot":"","sources":["../../src/pipeline/contract-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ExternalValidator, ValidationResult } from '@studio-foundation/contracts';
2
+ export declare function runExternalValidators(output: unknown, validators: ExternalValidator[] | undefined, cwd: string): Promise<ValidationResult>;
3
+ //# sourceMappingURL=external-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external-validator.d.ts","sourceRoot":"","sources":["../../src/pipeline/external-validator.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAIxF,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,OAAO,EACf,UAAU,EAAE,iBAAiB,EAAE,GAAG,SAAS,EAC3C,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,gBAAgB,CAAC,CAU3B"}
@@ -0,0 +1,65 @@
1
+ // Run external (out-of-process) validators against a stage's real output.
2
+ //
3
+ // Each validator is a shell command that receives the output as JSON on stdin and
4
+ // prints `{ "valid": boolean, "errors": string[] }` on stdout. This is the binary
5
+ // validation hook for what the declarative schema cannot express (cross-field rules,
6
+ // computed constraints) and the way to reuse a validator written in another language.
7
+ // Field-level types, enums and nested shape now live in schema.fields. Because it
8
+ // validates the ACTUAL output — not agent-reported tool arguments — the agent cannot
9
+ // fake it. The result flows into the RALPH loop like any other validator.
10
+ import { spawn } from 'node:child_process';
11
+ const DEFAULT_TIMEOUT_MS = 30_000;
12
+ export async function runExternalValidators(output, validators, cwd) {
13
+ if (!validators || validators.length === 0) {
14
+ return { valid: true, errors: [], warnings: [] };
15
+ }
16
+ const errors = [];
17
+ for (const validator of validators) {
18
+ errors.push(...(await runOne(validator, output, cwd)));
19
+ }
20
+ return { valid: errors.length === 0, errors, warnings: [] };
21
+ }
22
+ /** Run a single validator. Resolves to its error strings (empty = valid). Fails closed. */
23
+ function runOne(validator, output, cwd) {
24
+ return new Promise((resolve) => {
25
+ const child = spawn('sh', ['-c', validator.command], { cwd });
26
+ let stdout = '';
27
+ let stderr = '';
28
+ const timer = setTimeout(() => child.kill('SIGKILL'), validator.timeout_ms ?? DEFAULT_TIMEOUT_MS);
29
+ child.stdout.on('data', (d) => (stdout += d));
30
+ child.stderr.on('data', (d) => (stderr += d));
31
+ child.on('error', (err) => {
32
+ clearTimeout(timer);
33
+ resolve([`validator '${validator.name}' failed to start: ${err.message}`]);
34
+ });
35
+ child.on('close', (code) => {
36
+ clearTimeout(timer);
37
+ let parsed;
38
+ try {
39
+ parsed = JSON.parse(stdout.trim());
40
+ }
41
+ catch {
42
+ const detail = stderr.trim() || `${stdout.trim().slice(0, 200)} (exit ${code})`;
43
+ resolve([`validator '${validator.name}' produced unparseable output: ${detail}`]);
44
+ return;
45
+ }
46
+ const result = parsed;
47
+ if (result.valid === true) {
48
+ resolve([]);
49
+ return;
50
+ }
51
+ const errs = Array.isArray(result.errors) && result.errors.length > 0
52
+ ? result.errors.map(String)
53
+ : [`validator '${validator.name}' rejected the output (exit ${code})`];
54
+ resolve(errs);
55
+ });
56
+ // A validator that ignores stdin and exits immediately (e.g. `echo ...`)
57
+ // closes the pipe's read end before we finish writing, so this write emits
58
+ // EPIPE. That's benign — the validator's verdict is captured in 'close' — but
59
+ // without a listener the error is unhandled and crashes the process. Swallow it.
60
+ child.stdin.on('error', () => { });
61
+ child.stdin.write(JSON.stringify(output));
62
+ child.stdin.end();
63
+ });
64
+ }
65
+ //# sourceMappingURL=external-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external-validator.js","sourceRoot":"","sources":["../../src/pipeline/external-validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=external-validator.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external-validator.test.d.ts","sourceRoot":"","sources":["../../src/pipeline/external-validator.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,40 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { runExternalValidators } from './external-validator.js';
3
+ // A validator (run via node, always available in the test env) that reads the
4
+ // output JSON from stdin and approves only when bucket === 'A'.
5
+ const approveOnlyA = {
6
+ name: 'only-a',
7
+ command: `node -e "let s='';process.stdin.on('data',d=>s+=d);process.stdin.on('end',()=>{` +
8
+ `const o=JSON.parse(s);const ok=o.bucket==='A';` +
9
+ `process.stdout.write(JSON.stringify({valid:ok,errors:ok?[]:['bucket must be A']}));` +
10
+ `process.exit(ok?0:1)})"`,
11
+ };
12
+ describe('runExternalValidators', () => {
13
+ it('is valid when there are no validators', async () => {
14
+ const res = await runExternalValidators({ bucket: 'B' }, [], process.cwd());
15
+ expect(res.valid).toBe(true);
16
+ expect(res.errors).toEqual([]);
17
+ });
18
+ it('passes the output JSON on stdin and accepts a valid output', async () => {
19
+ const res = await runExternalValidators({ bucket: 'A' }, [approveOnlyA], process.cwd());
20
+ expect(res.valid).toBe(true);
21
+ expect(res.errors).toEqual([]);
22
+ });
23
+ it('reports the validator errors when the output is rejected', async () => {
24
+ const res = await runExternalValidators({ bucket: 'B' }, [approveOnlyA], process.cwd());
25
+ expect(res.valid).toBe(false);
26
+ expect(res.errors).toContain('bucket must be A');
27
+ });
28
+ it('fails closed when the command output is not parseable JSON', async () => {
29
+ const bad = { name: 'bad', command: "echo 'not json'" };
30
+ const res = await runExternalValidators({ bucket: 'A' }, [bad], process.cwd());
31
+ expect(res.valid).toBe(false);
32
+ expect(res.errors.length).toBeGreaterThan(0);
33
+ });
34
+ it('aggregates errors across multiple validators', async () => {
35
+ const res = await runExternalValidators({ bucket: 'B' }, [approveOnlyA, approveOnlyA], process.cwd());
36
+ expect(res.valid).toBe(false);
37
+ expect(res.errors.filter((e) => e === 'bucket must be A')).toHaveLength(2);
38
+ });
39
+ });
40
+ //# sourceMappingURL=external-validator.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external-validator.test.js","sourceRoot":"","sources":["../../src/pipeline/external-validator.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/pipeline/loader.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAA0E,MAAM,8BAA8B,CAAC;AAE/I,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAS5E;AAED,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,kBAAkB,CAAC,CAG7B;AAED,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,kBAAkB,CA8E9F"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/pipeline/loader.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAA+F,MAAM,8BAA8B,CAAC;AAkFpK,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAS5E;AAED,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,kBAAkB,CAAC,CAG7B;AAED,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,kBAAkB,CAsG9F"}