Authoring workflows
A workflow is a YAML file. It lists the stages to run, what each one does, and how they connect. Because it's a plain file, it lives in your repo and versions with your code. This page is the field-by-field reference; if you just want to see one end to end, jump to Worked examples.
The shape of a workflow
id: spec-and-plan
name: "Spec and Plan"
description: Turn a brief into a reviewed spec, then a plan.
defaultRuntime: claude-code
stages:
- id: spec
name: Write the specification
prompt: prompts/spec.md
validators:
- type: markdown_sections
artifact: specification.md
required: [Overview, Requirements, Non-Goals]
- id: plan
name: Draft the plan
prompt: prompts/plan.md
consumes: [spec]
Top-level keys
| Key | Required | Notes |
|---|---|---|
id | yes | Workflow identifier. Lowercase letters, digits, and hyphens; 1–64 characters; starts and ends alphanumeric. |
name | yes | Human-readable name shown in the app. |
description | no | Longer description of what the workflow does. |
defaultRuntime | no | A runtime ID used by any stage that doesn't name its own. Must be a registered runtime (see Providers & runtimes). |
stages | yes | The list of stages, in order. At least one. |
Stage keys
| Key | Required | Notes |
|---|---|---|
id | yes | Stage identifier, unique within the workflow. Same character rules as the workflow id. |
name | yes | Human-readable stage name. |
description | no | Longer description of the stage. |
prompt | yes | Path to the prompt file, relative to the workflow file (or absolute). Must resolve inside the workspace. |
runtime | conditional | Runtime ID for this stage. If omitted, Ringmaster falls back to defaultRuntime. One of the two must resolve to a registered runtime. |
model | no | A model ID to pin for this stage (for example sonnet, or google/gemma-4-e4b). Left out, the runtime's default model is used. |
consumes | no | Artifacts from earlier stages this stage should receive. See Connecting stages. |
additionalInstructions | no | Extra text appended to the compiled prompt at run time. |
review | no | The review gate. See Review. |
validators | no | Automated checks on the output. See Validation. |
execution | no | Multi-agent strategy. Absent means a single execution. See Multi-agent execution. |
iteration | no | Loop a single-execution stage until it's approved. See Iteration. |
A note on
prompt: the value is a path to a file, not the prompt text itself. Keep your prompts as Markdown files next to the workflow. This keeps the workflow readable and lets prompts version on their own. UseadditionalInstructionsfor short, stage-specific notes you'd rather keep inline.
Prompt files (PML)
A prompt can be any Markdown file. Name it *.pml.md and it gains an optional YAML front matter that declares its inputs and outputs — this is the format every built-in workflow uses, and it's what the Prompt Library renders as documentation:
---
inputs:
- name: focus
description: What this review should concentrate on.
default: correctness and error handling
outputs:
- name: review_md
description: The review, tiered Blocker / Should-fix / Nit.
---
Review the changes with a focus on {{inputs.focus}}.
...
- Inputs become
{{inputs.<name>}}placeholders in the body. At run time each placeholder is replaced with the input'sdefault. An escaped\{{inputs.foo}}passes through literally. - Outputs document what the prompt produces. They're informational today — good documentation for anyone (including the library view) reading the prompt.
- Input and output names must match
[A-Za-z_][A-Za-z0-9_]*— letters, digits, and underscores, not hyphens. Duplicate names and placeholders that reference undeclared inputs are also errors.
A .pml.md file is parsed and validated when the stage runs; a problem fails the attempt with a message naming it. The Prompt Library shows the same problems ahead of time, so you don't have to discover them mid-run. Plain .md prompts skip all of this and are sent as-is.
Connecting stages
Stages run top to bottom. A later stage names earlier ones in consumes to receive their canonical (promoted) output:
stages:
- id: research
name: Research
prompt: prompts/research.md
- id: draft
name: Draft
prompt: prompts/draft.md
consumes: [research] # draft sees research's promoted output
- id: review
name: Review
prompt: prompts/review.md
consumes: [research, draft] # and this one sees both
A reference is just the earlier stage's id. You can also write stage-id.output explicitly; in this version output is the only logical name. References must point backward: a stage can't consume something that runs later, and Ringmaster will tell you at validation time if it does.
Only promoted artifacts flow downstream. If a stage has a review gate, the work it produces isn't visible to later stages until you approve it.
The review gate
By default every stage pauses for review when it finishes: you approve, request a revision, or reject, and approving promotes the output. To let a stage approve itself on a clean run, turn the gate off:
review:
required: false # auto-approve if it succeeds and no blocking validator fails
With the gate off, a stage that succeeds and passes its blocking validators promotes automatically and the run continues. Anything less (a failure, or a blocking validation failure) still stops for you. (You may see the older autoApproveOnSuccess: true in existing workflows; it means the same thing as review.required: false.)
Iteration
A single-execution stage can loop until you approve it, carrying its previous attempt and your feedback into the next try:
iteration:
enabled: true
mode: until-approved
preserveContext: true # include the prior attempt in the next prompt (default)
Iteration applies to single-execution stages only; it can't be combined with a multi-agent execution block.
Identifiers, briefly
Workflow IDs, stage IDs, and specialist role names all follow the same rule: lowercase letters, digits, and hyphens, 1–64 characters, starting and ending with a letter or digit. The name merged is reserved and can't be used as a role.
PML input and output names follow a different rule — [A-Za-z_][A-Za-z0-9_]*, underscores rather than hyphens — because they double as placeholder keys. Easy to trip over when you're used to the kebab-case IDs everywhere else.
Validate before you run
You don't have to run a workflow to find out whether it's well-formed. The CLI checks everything (schema, references, runtime IDs, validator config) and reports problems with line numbers:
ringmaster validate path/to/workflow.yaml
It exits 0 when the workflow is valid and 2 when it isn't, which makes it a natural first step in CI. See The ringmaster CLI.
Worked examples
A two-stage workflow
id: spec-and-plan
name: "Spec and Plan"
description: Turn a brief into a reviewed spec, then a plan that builds on it.
defaultRuntime: claude-code
stages:
- id: spec
name: Write the specification
prompt: prompts/spec.md
validators:
- type: markdown_sections
artifact: specification.md
required: [Overview, Requirements, Assumptions, Non-Goals]
- type: artifact_exists
artifacts: [specification.md]
- id: plan
name: Draft the plan
prompt: prompts/plan.md
consumes: [spec]
review:
required: true
The first stage writes a spec and won't auto-pass unless specification.md exists and contains the four required sections. You review it, approve it, and the second stage (which consumes the spec) becomes runnable.
A stage that fans out across models
- id: draft
name: Draft (three models)
prompt: prompts/draft.md
execution:
mode: parallel
agents:
- runtime: claude-code
model: sonnet
- runtime: openrouter
model: anthropic/claude-opus-4.5
- runtime: ollama
All three run the same prompt at once; you get a comparison and pick the one to promote. The mechanics of each mode (parallel, race, consensus, specialist) are in Multi-agent execution.