stageflow 0.13.0 → 0.15.0

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 (97) hide show
  1. package/dist/agent/piAdapter.js +5 -2
  2. package/dist/agent/port.d.ts +2 -2
  3. package/dist/cli/initTemplates.d.ts +1 -1
  4. package/dist/cli/initTemplates.js +1 -1
  5. package/dist/cli/migrateYamlCommand.d.ts +18 -0
  6. package/dist/cli/migrateYamlCommand.js +180 -0
  7. package/dist/cli/runOutput.js +26 -18
  8. package/dist/cli/validateCommand.d.ts +1 -0
  9. package/dist/cli/validateCommand.js +2 -0
  10. package/dist/cli.js +15 -1
  11. package/dist/config/browseCatalog.js +1 -1
  12. package/dist/config/createPipeline.d.ts +1 -1
  13. package/dist/config/createPipeline.js +23 -11
  14. package/dist/config/createStage.d.ts +1 -1
  15. package/dist/config/createStage.js +10 -5
  16. package/dist/config/legacyYaml.d.ts +28 -0
  17. package/dist/config/legacyYaml.js +98 -0
  18. package/dist/config/loadOutcome.d.ts +2 -1
  19. package/dist/config/loadOutcome.js +4 -1
  20. package/dist/config/loadPipeline.d.ts +2 -0
  21. package/dist/config/loadPipeline.js +150 -8
  22. package/dist/config/loadStage.d.ts +8 -1
  23. package/dist/config/loadStage.js +138 -29
  24. package/dist/config/loadStageflowManifest.js +10 -0
  25. package/dist/config/loadTask.js +14 -0
  26. package/dist/config/materializeStageModels.d.ts +7 -0
  27. package/dist/config/materializeStageModels.js +35 -0
  28. package/dist/config/mergePipelineIncludes.d.ts +5 -1
  29. package/dist/config/mergePipelineIncludes.js +82 -4
  30. package/dist/config/migrateYaml.d.ts +19 -0
  31. package/dist/config/migrateYaml.js +627 -0
  32. package/dist/config/modelField.d.ts +13 -0
  33. package/dist/config/modelField.js +16 -0
  34. package/dist/config/normalizePipelineStageEntry.js +41 -2
  35. package/dist/config/parseCompletionContract.d.ts +5 -2
  36. package/dist/config/parseCompletionContract.js +16 -3
  37. package/dist/config/parsePreEmitChecks.js +4 -0
  38. package/dist/config/pipelineNeeds.js +3 -3
  39. package/dist/config/pipelineStageKeys.d.ts +11 -0
  40. package/dist/config/pipelineStageKeys.js +14 -0
  41. package/dist/config/printTargetYaml.d.ts +28 -0
  42. package/dist/config/printTargetYaml.js +243 -0
  43. package/dist/config/resolveModel.d.ts +20 -0
  44. package/dist/config/resolveModel.js +35 -0
  45. package/dist/config/validateCatalog.d.ts +5 -1
  46. package/dist/config/validateCatalog.js +36 -6
  47. package/dist/config/validateCompletionContract.js +5 -0
  48. package/dist/config/yamlDialect.d.ts +29 -0
  49. package/dist/config/yamlDialect.js +327 -0
  50. package/dist/envelope/payloadSchema.d.ts +37 -5
  51. package/dist/envelope/payloadSchema.js +272 -22
  52. package/dist/mcp/catalogTools.js +1 -0
  53. package/dist/package-meta.d.ts +1 -1
  54. package/dist/package-meta.js +1 -1
  55. package/dist/runstore/pipelineDagSnapshot.js +2 -0
  56. package/dist/runstore/port.d.ts +1 -0
  57. package/dist/runtime/completionCheckRunner.d.ts +3 -2
  58. package/dist/runtime/completionCheckRunner.js +3 -2
  59. package/dist/runtime/envelopeRouting.d.ts +2 -2
  60. package/dist/runtime/pipelineRunner.d.ts +3 -0
  61. package/dist/runtime/pipelineRunner.js +23 -3
  62. package/dist/runtime/runManager.js +3 -2
  63. package/dist/runtime/stageAttemptBootstrap.d.ts +2 -2
  64. package/dist/runtime/stageRunner.d.ts +2 -2
  65. package/dist/runtime/taskInput.d.ts +7 -0
  66. package/dist/runtime/taskInput.js +60 -0
  67. package/dist/runtime/verifiedStageExecution.js +3 -0
  68. package/dist/types/completion.d.ts +6 -0
  69. package/dist/types/pipeline.d.ts +21 -2
  70. package/dist/types/preEmitCheck.d.ts +4 -6
  71. package/dist/types/stage.d.ts +22 -3
  72. package/dist/types/stageflowManifest.d.ts +2 -0
  73. package/dist/types/task.d.ts +1 -0
  74. package/dist/ui/assets/{index-Yzh42vhf.js → index-GtyiWiZg.js} +1 -1
  75. package/dist/ui/index.html +1 -1
  76. package/package.json +1 -1
  77. package/skills/stageflow-author/SKILL.md +7 -7
  78. package/skills/stageflow-author/assets/examples/branch-decision/hotfix.yaml +9 -1
  79. package/skills/stageflow-author/assets/examples/branch-decision/release-gate.pipeline.yaml +6 -2
  80. package/skills/stageflow-author/assets/examples/branch-decision/run-tests.yaml +9 -1
  81. package/skills/stageflow-author/assets/examples/branch-decision/ship.yaml +16 -1
  82. package/skills/stageflow-author/assets/examples/linear-review/draft.yaml +12 -2
  83. package/skills/stageflow-author/assets/examples/linear-review/publish.yaml +16 -1
  84. package/skills/stageflow-author/assets/examples/linear-review/review-loop.pipeline.yaml +11 -2
  85. package/skills/stageflow-author/assets/examples/linear-review/review.yaml +19 -1
  86. package/skills/stageflow-author/assets/examples/non-sdlc-digest/gather.yaml +9 -1
  87. package/skills/stageflow-author/assets/examples/non-sdlc-digest/research-digest.pipeline.yaml +6 -2
  88. package/skills/stageflow-author/assets/examples/non-sdlc-digest/send.yaml +16 -1
  89. package/skills/stageflow-author/assets/examples/non-sdlc-digest/summarize.yaml +9 -1
  90. package/skills/stageflow-author/references/catalog-mapping.md +30 -28
  91. package/skills/stageflow-author/references/catalog-write-conventions.md +2 -2
  92. package/skills/stageflow-author/references/stage-prompt-template.md +5 -5
  93. package/skills/stageflow-session-capture/SKILL.md +1 -1
  94. package/skills/stageflow-session-capture/assets/example-pipeline/example.pipeline.yaml +2 -1
  95. package/skills/stageflow-session-capture/assets/example-pipeline/implement.yaml +13 -2
  96. package/skills/stageflow-session-capture/assets/example-pipeline/research.yaml +18 -2
  97. package/skills/stageflow-session-capture/references/catalog-authoring.md +2 -2
@@ -35,9 +35,9 @@ Ask until you can name every step, how they sequence, any decision point, and an
35
35
 
36
36
  ## Map
37
37
 
38
- Read [`references/catalog-mapping.md`](references/catalog-mapping.md). Apply those rules to the confirmed structure. Read [`references/stage-prompt-template.md`](references/stage-prompt-template.md) for each stage's `system_prompt`, `model`, and `gate_kinds`. Apply the Anti-patterns section below while mapping. When the human needs hard advance gates, plan `completion` / `recovery` on pipeline entries. When a review can demand changes, include an address-feedback stage before approve/ship.
38
+ Read [`references/catalog-mapping.md`](references/catalog-mapping.md). Apply those rules to the confirmed structure. Read [`references/stage-prompt-template.md`](references/stage-prompt-template.md) for each stage's `system_prompt`, optional `model`, `io`, `verify`, and `gate_kinds`. Apply the Anti-patterns section below while mapping. When the human needs hard advance gates, plan body `verify` and wiring `on_verify_fail`. When a review can demand changes, include an address-feedback stage before approve/ship.
39
39
 
40
- **Done when** you have a pipeline id, one stage id per step, `needs` / `fork` wiring, a prompt plan per stage, and any `completion` / `recovery` / remediation stages the structure requires.
40
+ **Done when** you have a pipeline id, one stage id per step, `needs` / `fork` wiring, a prompt plan per stage, and any `verify` / `on_verify_fail` / remediation stages the structure requires.
41
41
 
42
42
  ## Anti-patterns
43
43
 
@@ -46,14 +46,14 @@ Author these contracts explicitly. They come from long runs that failed after ho
46
46
  | Always do | How |
47
47
  |---|---|
48
48
  | End every attempt on a tool call | Prompt: last call is `emit_stage_envelope`, or `ask_operator` while waiting on HITL. Each clonable instance emits on its own. |
49
- | Land required files in the attempt artifact dir | Prompt `write_stage_artifact`. Pipeline `completion.checks` with `type: artifact`. `ask_operator` `artifact_backed` references that same path. |
50
- | Make implement stages change the checkout | Pipeline `checkout_changes` + `path_fields`; stage `payload_schema` with required checkout-relative path arrays. Exploration-only is its own stage or a failure emit. |
51
- | Hand successors clean envelopes | `summary` / `payload` = outcomes and artifact pointers only. Name required `payload_schema` fields in the prompt. |
52
- | Give review blockers a place to land | Wire `review → address-feedback → approve/ship`. Put `verdict` / `blocking_findings` (or equivalent) in the review `payload_schema`. |
49
+ | Land required files in the attempt artifact dir | Prompt `write_stage_artifact`. Body `verify` with `type: artifact` and `when` including `after`. `ask_operator` `artifact_backed` references that same path. |
50
+ | Make implement stages change the checkout | Body `verify` `checkout_changes` + `path_fields`; `io.output.schema` with required checkout-relative path arrays. Exploration-only is its own stage or a failure emit. |
51
+ | Hand successors clean envelopes | `summary` / `payload` = outcomes and artifact pointers only. Name required `io.output.schema` fields in the prompt. |
52
+ | Give review blockers a place to land | Wire `review → address-feedback → approve/ship`. Put `verdict` / `blocking_findings` (or equivalent) in the review `io.output.schema`. |
53
53
  | Bind success to the full checklist | If a plan lists N commands, success requires all of them in `commands_run` with exit 0. Cheap checks first; slow suites last or in a verify stage. Size `timeout_ms` to the work. |
54
54
  | Use configured models on every sibling | Same configured `model` family after a fork/fan-out unless the human asks otherwise. Reliable model on publish/PR stages. |
55
55
  | Finish publish in the accept attempt | After `artifact_backed` accept: side effects (commit/push/PR) → final artifact → emit in the same attempt. Fix emit/schema errors by re-emitting. |
56
- | Emit full clone assignments | When `clonable: true`, parent success uses `clone_forks` with full envelopes matching `clone_input_schema`. Leave clonable unset when the clone count is unknown. |
56
+ | Emit full clone assignments | When `clonable: true`, parent success uses `clone_forks` with full envelopes matching `io.input.schema`. Leave clonable unset when the clone count is unknown. |
57
57
 
58
58
  Throwaway checkout deliverables (HTML spike, scratch file): prompt builtin `write` at a checkout-relative path, `artifacts: []` on emit, path in `payload`.
59
59
 
@@ -7,4 +7,12 @@ system_prompt: |
7
7
 
8
8
  When finished, call emit_stage_envelope exactly once with status, summary,
9
9
  artifacts, and a payload describing what you repaired.
10
- model: anthropic/claude-sonnet-4-5
10
+ io:
11
+ output:
12
+ schema:
13
+ type: object
14
+ required:
15
+ - repaired
16
+ properties:
17
+ repaired:
18
+ type: boolean
@@ -1,4 +1,5 @@
1
1
  id: release-gate
2
+ model: anthropic/claude-sonnet-4-5
2
3
  stages:
3
4
  - id: run-tests
4
5
  uses: ./run-tests.yaml
@@ -6,7 +7,10 @@ stages:
6
7
  select: one
7
8
  - id: hotfix
8
9
  uses: ./hotfix.yaml
9
- needs: run-tests
10
+ needs: [run-tests]
10
11
  - id: ship
11
12
  uses: ./ship.yaml
12
- needs: run-tests
13
+ needs: [run-tests]
14
+ on_verify_fail:
15
+ mode: manual
16
+ retry_safety: side_effecting
@@ -10,4 +10,12 @@ system_prompt: |
10
10
  On a success emit, include fork_choice naming immediate successor id(s) that
11
11
  should run. Name only ids listed as this stage's children. select: one →
12
12
  exactly one id: hotfix when the results fail, ship when they pass.
13
- model: anthropic/claude-sonnet-4-5
13
+ io:
14
+ output:
15
+ schema:
16
+ type: object
17
+ required:
18
+ - ready
19
+ properties:
20
+ ready:
21
+ type: boolean
@@ -7,4 +7,19 @@ system_prompt: |
7
7
 
8
8
  When finished, call emit_stage_envelope exactly once with status, summary,
9
9
  artifacts, and a payload describing what you shipped.
10
- model: anthropic/claude-sonnet-4-5
10
+ io:
11
+ output:
12
+ schema:
13
+ type: object
14
+ required:
15
+ - shipped
16
+ properties:
17
+ shipped:
18
+ type: boolean
19
+ verify:
20
+ - id: ship-notes
21
+ type: artifact
22
+ path: ship.md
23
+ nonempty: true
24
+ when:
25
+ - after
@@ -5,5 +5,15 @@ system_prompt: |
5
5
  Write the draft via write_stage_artifact (for example draft.md).
6
6
 
7
7
  When finished, call emit_stage_envelope exactly once with status, summary,
8
- artifacts, and a payload the next stage can use.
9
- model: anthropic/claude-sonnet-4-5
8
+ artifacts, and a payload the next stage can use. Your last tool call in this
9
+ attempt must be emit_stage_envelope (or ask_operator if waiting on HITL).
10
+ An empty final message is a stage failure.
11
+ io:
12
+ output:
13
+ schema:
14
+ type: object
15
+ required:
16
+ - title
17
+ properties:
18
+ title:
19
+ type: string
@@ -7,4 +7,19 @@ system_prompt: |
7
7
 
8
8
  When finished, call emit_stage_envelope exactly once with status, summary,
9
9
  artifacts, and a payload describing what you produced.
10
- model: anthropic/claude-sonnet-4-5
10
+ io:
11
+ output:
12
+ schema:
13
+ type: object
14
+ required:
15
+ - published
16
+ properties:
17
+ published:
18
+ type: boolean
19
+ verify:
20
+ - id: published-artifact
21
+ type: artifact
22
+ path: published.md
23
+ nonempty: true
24
+ when:
25
+ - after
@@ -1,10 +1,19 @@
1
1
  id: review-loop
2
+ model: anthropic/claude-sonnet-4-5
2
3
  stages:
3
4
  - id: draft
4
5
  uses: ./draft.yaml
5
6
  - id: review
6
7
  uses: ./review.yaml
7
- needs: draft
8
+ needs: [draft]
9
+ on_verify_fail:
10
+ mode: repair
11
+ max_attempts: 3
12
+ retry_safety: idempotent
13
+ include_failed_checks: true
8
14
  - id: publish
9
15
  uses: ./publish.yaml
10
- needs: review
16
+ needs: [review]
17
+ on_verify_fail:
18
+ mode: manual
19
+ retry_safety: side_effecting
@@ -12,4 +12,22 @@ system_prompt: |
12
12
  again with artifact_backed in this same stage. Do not complete yet.
13
13
  4. Call emit_stage_envelope with an advancing success status only after the
14
14
  operator accepts. Never emit before accept.
15
- model: anthropic/claude-sonnet-4-5
15
+ io:
16
+ output:
17
+ schema:
18
+ type: object
19
+ required:
20
+ - verdict
21
+ properties:
22
+ verdict:
23
+ type: string
24
+ verify:
25
+ - id: review-accepted
26
+ type: gate
27
+ kind: artifact_backed
28
+ - id: review-artifact
29
+ type: artifact
30
+ path: review.md
31
+ nonempty: true
32
+ when:
33
+ - after
@@ -6,4 +6,12 @@ system_prompt: |
6
6
 
7
7
  When finished, call emit_stage_envelope exactly once with status, summary,
8
8
  artifacts, and a payload the next stage can use.
9
- model: anthropic/claude-sonnet-4-5
9
+ io:
10
+ output:
11
+ schema:
12
+ type: object
13
+ required:
14
+ - source_count
15
+ properties:
16
+ source_count:
17
+ type: integer
@@ -1,10 +1,14 @@
1
1
  id: research-digest
2
+ model: anthropic/claude-sonnet-4-5
2
3
  stages:
3
4
  - id: gather
4
5
  uses: ./gather.yaml
5
6
  - id: summarize
6
7
  uses: ./summarize.yaml
7
- needs: gather
8
+ needs: [gather]
8
9
  - id: send
9
10
  uses: ./send.yaml
10
- needs: summarize
11
+ needs: [summarize]
12
+ on_verify_fail:
13
+ mode: manual
14
+ retry_safety: side_effecting
@@ -7,4 +7,19 @@ system_prompt: |
7
7
 
8
8
  When finished, call emit_stage_envelope exactly once with status, summary,
9
9
  artifacts, and a payload describing who received the digest.
10
- model: anthropic/claude-sonnet-4-5
10
+ io:
11
+ output:
12
+ schema:
13
+ type: object
14
+ required:
15
+ - sent
16
+ properties:
17
+ sent:
18
+ type: boolean
19
+ verify:
20
+ - id: sent-record
21
+ type: artifact
22
+ path: sent.md
23
+ nonempty: true
24
+ when:
25
+ - after
@@ -6,4 +6,12 @@ system_prompt: |
6
6
 
7
7
  When finished, call emit_stage_envelope exactly once with status, summary,
8
8
  artifacts, and a payload the next stage can use.
9
- model: anthropic/claude-sonnet-4-5
9
+ io:
10
+ output:
11
+ schema:
12
+ type: object
13
+ required:
14
+ - headline
15
+ properties:
16
+ headline:
17
+ type: string
@@ -16,7 +16,7 @@ Collision handling lives in [`catalog-write-conventions.md`](catalog-write-conve
16
16
 
17
17
  ## Sequencing
18
18
 
19
- `needs` is a single parent stage id, or an array of at least two parent ids when one step waits for several earlier steps. Strings default to `on: [succeeded]`. `{ id, on }` accepts a non-empty unique subset of `succeeded` | `failed` | `skipped`.
19
+ `needs` is a parent stage id, or a non-empty array (length ≥ 1). Strings default to `on: [succeeded]`. `{ id, on }` accepts a non-empty unique subset of `succeeded` | `failed` | `skipped`.
20
20
 
21
21
  | Human says | Pipeline shape |
22
22
  |---|---|
@@ -42,19 +42,19 @@ When the human wants a review that can demand changes, then a later approve/ship
42
42
 
43
43
  Do not wire approve/ship as the immediate child of review. Pipelines are forward-only; without an address-feedback stage, blocking findings have nowhere to land. The address-feedback stage is the only post-review editor; the approve stage is the backstop.
44
44
 
45
- ## Completion and recovery
45
+ ## Verify and on_verify_fail
46
46
 
47
- Put `completion` / `recovery` on the **pipeline** stage entry (the `uses:` wrapper), not on the stage body. Use when the human needs a hard gate before advance:
47
+ Put `verify` on the **stage body** (the `uses:` file or inline entry). Put `on_verify_fail` on the **pipeline** stage entry (the `uses:` wrapper). Use when the human needs a hard gate before advance:
48
48
 
49
- | Need | Pipeline wiring |
49
+ | Need | Catalog |
50
50
  |---|---|
51
- | Required file under the attempt artifact dir | `completion.checks` with `type: artifact`, `path`, usually `nonempty: true` |
52
- | HITL must complete | `type: gate` with `kind` that appears in the stage's `gate_kinds` |
53
- | Implement must change the checkout | `type: checkout_changes` with `path_fields` naming required arrays in `payload_schema` |
54
- | Auto-retry after verification fail | `recovery: { mode: repair, max_attempts: N, retry_safety: idempotent, include_failed_checks: true }` |
55
- | Side-effecting publish / ship | `recovery: { mode: manual, retry_safety: side_effecting }` |
51
+ | Required file under the attempt artifact dir | `verify` with `type: artifact`, `path`, usually `nonempty: true`, `when: [after]` |
52
+ | HITL must complete this attempt | `type: gate` with `kind` that appears in the stage's `gate_kinds` (default `when: [emit]`) |
53
+ | Implement must change the checkout | `type: checkout_changes` with `path_fields` naming required arrays in `io.output.schema` |
54
+ | Auto-retry when after-phase verify fails | `on_verify_fail: { mode: repair, max_attempts: N, retry_safety: idempotent, include_failed_checks: true }` |
55
+ | Side-effecting publish / ship | `on_verify_fail: { mode: manual, retry_safety: side_effecting }` |
56
56
 
57
- `completion.mode` is `all`. Check `id` values must be unique within the stage. Wire these for writer stages and final gates; prompts alone do not enforce them.
57
+ `on_verify_fail` requires at least one after-phase `verify` item. Check `id` values must be unique within the stage. Check discriminator is `type:` (gate widgets still use `kind:`). Wire these for writer stages and final gates; prompts alone do not enforce them.
58
58
 
59
59
  ## Clonable successors
60
60
 
@@ -64,7 +64,7 @@ When the human explicitly wants N parallel instances of **one** successor catalo
64
64
 
65
65
  - On that successor pipeline entry: `clonable: true` and `clone_cap` (integer ≥ 2).
66
66
  - That successor must have at least one child (a join / address-feedback / collect stage). It cannot be a DAG leaf.
67
- - Parent success emit uses `clone_forks` for that successor (not `fork_choice`). Each clone assignment is a full envelope; validate assignments with `clone_input_schema` on the clonable stage body.
67
+ - Parent success emit uses `clone_forks` for that successor (not `fork_choice`). Each clone assignment is a full envelope; validate assignments with `io.input.schema` on the clonable stage body.
68
68
  - Join stages that wait on the clonable parent read clone-list `priorEnvelopes`, not `priorEnvelopesByStage`.
69
69
 
70
70
  `fork` + `fork_choice` picks which **branch stage ids** run. `clone_forks` spawns **N instances** of one successor id.
@@ -81,18 +81,19 @@ Three sequential steps; the middle one is a sign-off. Reject/revise stays inside
81
81
 
82
82
  ```yaml
83
83
  id: review-loop
84
+ model: anthropic/claude-sonnet-4-5
84
85
  stages:
85
86
  - id: draft
86
87
  uses: ./draft.yaml
87
88
  - id: review
88
89
  uses: ./review.yaml
89
- needs: draft
90
+ needs: [draft]
90
91
  - id: publish
91
92
  uses: ./publish.yaml
92
- needs: review
93
+ needs: [review]
93
94
  ```
94
95
 
95
- `review` carries `gate_kinds: [artifact_backed]`. Full set: [`../assets/examples/linear-review/`](../assets/examples/linear-review/).
96
+ `review` carries `gate_kinds: [artifact_backed]` and emit-phase `verify` `type: gate`. Full set: [`../assets/examples/linear-review/`](../assets/examples/linear-review/).
96
97
 
97
98
  ### Review with separate fix stage
98
99
 
@@ -104,16 +105,17 @@ stages:
104
105
  uses: ./implement.yaml
105
106
  - id: review
106
107
  uses: ./review.yaml
107
- needs: implement
108
+ needs: [implement]
108
109
  - id: address-feedback
109
110
  uses: ./address-feedback.yaml
110
- needs: review
111
+ needs: [review]
111
112
  - id: approve
112
113
  uses: ./approve.yaml
113
- needs: address-feedback
114
+ needs: [address-feedback]
114
115
  ```
115
116
 
116
117
  Do not make `approve` / `ship` `needs: review` when blockers are expected.
118
+
117
119
  ### Release gate (fork, select one)
118
120
 
119
121
  One deciding step, then exactly one successor.
@@ -127,10 +129,10 @@ stages:
127
129
  select: one
128
130
  - id: hotfix
129
131
  uses: ./hotfix.yaml
130
- needs: run-tests
132
+ needs: [run-tests]
131
133
  - id: ship
132
134
  uses: ./ship.yaml
133
- needs: run-tests
135
+ needs: [run-tests]
134
136
  ```
135
137
 
136
138
  Full set: [`../assets/examples/branch-decision/`](../assets/examples/branch-decision/).
@@ -146,10 +148,10 @@ stages:
146
148
  uses: ./gather.yaml
147
149
  - id: summarize
148
150
  uses: ./summarize.yaml
149
- needs: gather
151
+ needs: [gather]
150
152
  - id: send
151
153
  uses: ./send.yaml
152
- needs: summarize
154
+ needs: [summarize]
153
155
  ```
154
156
 
155
157
  Full set: [`../assets/examples/non-sdlc-digest/`](../assets/examples/non-sdlc-digest/).
@@ -164,10 +166,10 @@ stages:
164
166
  uses: ./intake.yaml
165
167
  - id: collect-quotes
166
168
  uses: ./collect-quotes.yaml
167
- needs: intake
169
+ needs: [intake]
168
170
  - id: collect-notes
169
171
  uses: ./collect-notes.yaml
170
- needs: intake
172
+ needs: [intake]
171
173
  ```
172
174
 
173
175
  No `fork` field. Both siblings run.
@@ -182,10 +184,10 @@ stages:
182
184
  uses: ./clarify.yaml
183
185
  - id: research
184
186
  uses: ./research.yaml
185
- needs: clarify
187
+ needs: [clarify]
186
188
  - id: validation
187
189
  uses: ./validation.yaml
188
- needs: clarify
190
+ needs: [clarify]
189
191
  - id: synthesize
190
192
  uses: ./synthesize.yaml
191
193
  needs:
@@ -193,7 +195,7 @@ stages:
193
195
  - validation
194
196
  ```
195
197
 
196
- `needs` array length is ≥ 2. The join reads `priorEnvelopesByStage`, not clone-list `priorEnvelopes`.
198
+ `needs` array length ≥ 2 is keyed fan-in. The join reads `priorEnvelopesByStage`, not clone-list `priorEnvelopes`.
197
199
 
198
200
  ### Fork, select subset
199
201
 
@@ -207,10 +209,10 @@ stages:
207
209
  select: subset
208
210
  - id: email
209
211
  uses: ./email.yaml
210
- needs: choose-channels
212
+ needs: [choose-channels]
211
213
  - id: post
212
214
  uses: ./post.yaml
213
- needs: choose-channels
215
+ needs: [choose-channels]
214
216
  ```
215
217
 
216
218
  The success emit names one or more of those successor ids in `fork_choice`.
@@ -18,9 +18,9 @@ One directory (or the project root) holds:
18
18
  | File | Required fields |
19
19
  |---|---|
20
20
  | `<pipeline-id>.pipeline.yaml` | `id` matching the filename stem; `stages:` object entries |
21
- | `<stage-id>.yaml` | `id`, `system_prompt`, `model`; `gate_kinds` when the step is gated |
21
+ | `<stage-id>.yaml` | `id`, `system_prompt`; `model` when not inherited; `io` / `verify` / `gate_kinds` when the step needs them |
22
22
 
23
- Each pipeline stage entry has `id` and `uses: ./<id>.yaml` (path relative to the pipeline file). Non-root stages add `needs: <parent-id>`, or `needs:` as an array of at least two parent ids (strings or `{ id, on }`) when the stage waits for several parents. A deciding stage adds `fork:`. Filename stem matches `id` on every file.
23
+ Each pipeline stage entry has `id` and `uses: ./<id>.yaml` (path relative to the pipeline file). Non-root stages add `needs: <parent-id>` or `needs: [<parent-id>, …]` (length ≥ 1; strings or `{ id, on }`). A deciding stage adds `fork:`. Put `on_verify_fail` on the pipeline entry when after-phase `verify` should repair or wait for an operator. Filename stem matches `id` on every file. Optional pipeline-root `model` fills stages that omit `model`.
24
24
 
25
25
  ## Collisions
26
26
 
@@ -1,6 +1,6 @@
1
1
  # Stage prompt template
2
2
 
3
- Every external stage file has `id`, `system_prompt`, and `model`. Filename stem matches `id`. Default `model` is `anthropic/claude-sonnet-4-5`. When the human names a different model, write that string verbatim. Before writing models, confirm at least one provider is `configured` (see the skill Provider gate). Sibling stages after a fork should use the same configured model family unless the human asks otherwise.
3
+ Every external stage file has `id` and `system_prompt`. Filename stem matches `id`. `model` is optional when the pipeline or `stageflow.yaml` supplies it — otherwise set it on the stage. Default when writing a concrete string is `anthropic/claude-sonnet-4-5`. When the human names a different model, write that string verbatim. Before writing models, confirm at least one provider is `configured` (see the skill Provider gate). Sibling stages after a fork should use the same configured model family unless the human asks otherwise.
4
4
 
5
5
  ## Base
6
6
 
@@ -22,11 +22,11 @@ model: anthropic/claude-sonnet-4-5
22
22
 
23
23
  The prompt has no `ask_operator` line. It ends on the `emit_stage_envelope` instruction. Call `emit_stage_envelope` once per attempt.
24
24
 
25
- When the pipeline entry will carry `completion.checks` with `type: artifact`, add this line after the goal:
25
+ When the pipeline entry will carry after-phase `verify` with `type: artifact`, add this line after the goal:
26
26
 
27
27
  ```
28
28
  Required files must be created with write_stage_artifact. Checkout write/edit
29
- does not satisfy completion checks.
29
+ does not satisfy after-phase verify.
30
30
  ```
31
31
 
32
32
  When the stage must change the project checkout (implement, patch, edit source), add:
@@ -54,7 +54,7 @@ artifact pointers only. Do not repeat this stage's prohibitions in summary —
54
54
  downstream will obey them literally.
55
55
  ```
56
56
 
57
- When `payload_schema` is on the stage file, name the required fields in the prompt so the emit matches.
57
+ When `io.output.schema` is on the stage file, name the required fields in the prompt so the emit matches.
58
58
 
59
59
  ## Gated
60
60
 
@@ -108,7 +108,7 @@ When a successor is `clonable: true`, the parent success emit uses `clone_forks`
108
108
  ```
109
109
  On success, include clone_forks covering every clonable successor exactly once.
110
110
  Each clone entry is a full envelope with status, summary, artifacts, and payload
111
- matching that successor's clone_input_schema — not a stub object.
111
+ matching that successor's io.input.schema — not a stub object.
112
112
  ```
113
113
 
114
114
  Clonable child stages use the base (or gated) prompt. Remind them they are one clone among others and must emit independently.
@@ -74,7 +74,7 @@ Read [`references/catalog-authoring.md`](references/catalog-authoring.md) before
74
74
  `node scripts/resolve-catalog-id.mjs --text "<phrase>" --dir <write-dir> --kind pipeline|stage`
75
75
 
76
76
  Use the printed `{"id":"..."}`.
77
- 3. Write one external stage YAML per phase (`id`, `system_prompt`, `model`). End every `system_prompt` with an `emit_stage_envelope` footer. Omit `gate_kinds`. Filename stem must match `id`.
77
+ 3. Write one external stage YAML per phase (`id`, `system_prompt`, optional `model`). End every `system_prompt` with an `emit_stage_envelope` footer. Omit `gate_kinds`. Filename stem must match `id`.
78
78
  4. Write one pipeline YAML that wires the stages with `uses:` and `needs:` in dependency order.
79
79
 
80
80
  Do not write a `*.task.yaml`.
@@ -1,7 +1,8 @@
1
1
  id: example
2
+ model: anthropic/claude-sonnet-4-5
2
3
  stages:
3
4
  - id: research
4
5
  uses: ./research.yaml
5
6
  - id: implement
6
7
  uses: ./implement.yaml
7
- needs: research
8
+ needs: [research]
@@ -4,5 +4,16 @@ system_prompt: |
4
4
  there. Prefer what already worked in the source session.
5
5
 
6
6
  When finished, call emit_stage_envelope once with status, summary, artifacts,
7
- and a payload describing what you produced.
8
- model: anthropic/claude-sonnet-4-5
7
+ and a payload describing what you produced. Your last tool call in this
8
+ attempt must be emit_stage_envelope. An empty final message is a stage failure.
9
+ io:
10
+ output:
11
+ schema:
12
+ type: object
13
+ required:
14
+ - changed_files
15
+ properties:
16
+ changed_files:
17
+ type: array
18
+ items:
19
+ type: string
@@ -4,5 +4,21 @@ system_prompt: |
4
4
  unknown, and the next useful work.
5
5
 
6
6
  When finished, call emit_stage_envelope once with status, summary, artifacts,
7
- and a payload the next stage can use.
8
- model: anthropic/claude-sonnet-4-5
7
+ and a payload the next stage can use. Your last tool call in this attempt must
8
+ be emit_stage_envelope. An empty final message is a stage failure.
9
+ io:
10
+ output:
11
+ schema:
12
+ type: object
13
+ required:
14
+ - known
15
+ - unknown
16
+ properties:
17
+ known:
18
+ type: array
19
+ items:
20
+ type: string
21
+ unknown:
22
+ type: array
23
+ items:
24
+ type: string
@@ -10,7 +10,7 @@ Resolve collision-safe ids with `scripts/resolve-catalog-id.mjs` (`--text`, `--d
10
10
 
11
11
  ## External stage file
12
12
 
13
- Required fields: `id`, `system_prompt`, `model`. Filename stem must match `id` (`research.yaml` → `id: research`).
13
+ Required fields: `id`, `system_prompt`. Filename stem must match `id` (`research.yaml` → `id: research`). `model` is optional when the pipeline or manifest supplies it.
14
14
 
15
15
  Every `system_prompt` ends with a mandatory `emit_stage_envelope` footer, for example:
16
16
 
@@ -28,7 +28,7 @@ Worked example: `assets/example-pipeline/research.yaml` and `assets/example-pipe
28
28
 
29
29
  ## Pipeline file
30
30
 
31
- `id` plus `stages:` entries with `id`, `uses:` (path relative to the pipeline file), and `needs:` for every non-root stage. Linear chain: each stage `needs` the previous id.
31
+ `id` plus `stages:` entries with `id`, `uses:` (path relative to the pipeline file), and `needs:` for every non-root stage. Linear chain: each stage `needs` the previous id (scalar or a one-item array). Optional pipeline-root `model` fills stages that omit `model`. Put body contracts (`io`, `verify`) on stage files; put `on_verify_fail` on the pipeline entry when after-phase verify should repair or wait for an operator.
32
32
 
33
33
  Worked example: `assets/example-pipeline/example.pipeline.yaml`.
34
34