warden v0.10.1

Flow files reference

On this page

The flow JSON format, the built-in templates, and every lint rule.

A flow is the list of steps a run goes through. The four built-in flows are called templates. You can also save your own flows in .warden/flows/, or pass a path to a flow file. warden flow check lints a flow, and warden start refuses a flow that does not pass.

Where flows come from#

warden start --template <t> and warden start --flow <x> find the flow in this order:

  1. A template name (do, feature, bugfix, chore): the plugin's own file.
  2. A saved flow: .warden/flows/<x>.json in the current checkout, when <x> matches ^[a-z][a-z0-9-]{1,40}$ and the file exists.
  3. Otherwise a file path, relative to the current folder.

warden flow save <path> --name <name> copies a flow into .warden/flows/<name>.json and adds a line to .warden/flows/INDEX.md. A run keeps a copy of its flow in .warden/state/<task>/flow.json, so changing a flow file never changes a running task.

Format#

json
{
  "schema": 1,
  "name": "migration",
  "description": "Analyze, plan, approve, implement, check, ship.",
  "limits": { "reviewRounds": 2 },
  "steps": [
    { "id": "analyze", "type": "analyze", "variant": "generic" },
    { "id": "plan", "type": "plan", "brainstorm": false },
    { "id": "approve", "type": "approve", "prompt": "Check the plan before any code changes." },
    { "id": "implement", "type": "implement", "instructions": "Write the migration and its down step." },
    { "id": "check", "type": "check", "check": "default" },
    { "id": "ship", "type": "ship" }
  ]
}

Top-level fields#

FieldTypeRequiredRule
schemanumberyesMust be 1
namestringyesMatches ^[a-z][a-z0-9-]{1,40}$
descriptionstringyesNot empty. flow save writes it into INDEX.md
stepsobject[]yes1 to 20 steps
limitsobjectnoSee limits

No other keys are allowed.

Step fields#

Every step has these:

FieldTypeRequiredRule
idstringyesMatches ^[a-z][a-z0-9-]{0,30}$. Unique in the flow
typestringyesOne of analyze, plan, implement, check, review, approve, ship
titlestringnoAt most 80 chars. Shown as the step title. Default: <id> (<type>)
instructionsstringnoAt most 4000 chars. Added to the step's instructions under "Notes for this step"

Extra fields by type. No other keys are allowed on a step.

TypeExtra fieldRule
analyzevariantRequired: generic, reproduce, diagnose or spike
planbrainstormRequired boolean. true: the plan output must compare 2 or more options
checkcheckRequired: the name of a check set in .warden/steps.json
approvepromptRequired, not empty. Shown to the person who approves
implement, review, shipnone—

Step types#

TypeWho does itWhat it doesFiles the step may change in the task worktree
analyze / genericagentRead and record findings, no code change.warden/knowledge/**, .warden/decisions/**
analyze / reproduceagentWrite a failing test for the bug, leave it uncommittedAnything except gate files
analyze / diagnoseagentFind the root cause, at least two links with evidence.warden/knowledge/**, .warden/decisions/**
analyze / spikeagentAnswer a question by investigation; write one note.warden/knowledge/**, .warden/decisions/**, docs/**
planagentWrite a plan of small tasks in waves (the warden:plan skill).warden/knowledge/**, .warden/decisions/**
implementagentMake the change with tests, commit all of itAnything except gate files
checkengineRun a check set; triage a failureNothing
reviewengineRun the reviewer on the branch diffNothing
approvepersonWait for approve or reject: <why>Nothing
shipagentCommit the run record, open the PR or merge, hand inNone. It only commits what warden wrote (the run record). While a merge with conflicts is in progress, the conflicted files may be edited

Gate files are .warden/steps.json, .warden/flows/**, .warden/warden.json, .warden/triage-rules.json, .warden/state/** and .warden/history/**. The locked config (the same config files plus .warden/tools/roles.json) cannot change while any run is live; see Workflows. A fix step (fix-<n>) is added by the engine itself when triage asks for it; you cannot put one in a flow.

An approve step is skipped when the session that runs the task was started with PROJECT_AGENT=1. You cannot turn that on or off in the flow. See environment.

limits#

KeyDefault and maximumWhat it caps
codeStrikes3CODE verdicts before the engine starts a fixer in diagnose mode instead of sending the run back to implement. The count starts again after that fixer
fixerRounds2Fixer runs per task. One more fix needed after that blocks the run
reviewRounds3Review rounds. At the last round, blocking findings no longer send the run back; they become leftovers for the PR description

Each value is a whole number from 1 up to the default. A flow can only lower a limit, never raise it.

Built-in templates#

TemplateStepsUse it for
doimplement → check defaultSmall changes: docs, config, a typo, one obvious edit. No ship step: the run ends done
choreimplement → check default → shipA small change that must be merged
featureplan (brainstorm) → implement → check default → review → shipNew behaviour, many files, API or schema changes
bugfixanalyze/reproduce → analyze/diagnose → plan (no brainstorm) → implement → check default → review → shipA bug in existing code

Lint rules#

warden flow check, warden flow save and warden start all run these rules. Each error has a code, a message and, when it is about one step, the step id.

CodeWhat it checksExample message
F001The flow is a JSON object with schema: 1, a valid name and a non-empty description. In warden flow check, a file that cannot be found or parsed is also F001name must match ^[a-z][a-z0-9-]{1,40}$
F002steps is an array of 1 to 20 steps; each step id is valid and uniqueduplicate step id "check"
F003Each step is an object with a known type and its required field (variant, brainstorm, check, prompt). Type fix is not allowedanalyze needs a variant (generic, reproduce, diagnose, spike)
F004A check step names a check set that exists in steps.json (only when warden can read steps.json)check "e2e" is not in steps.json (found: default)
F005Gate coverage, see below(b) no check step after the last code step "implement"
F007No unknown keys at the top, in limits or on a stepunknown key "timeout"
F009limits is an object; each value is a whole number of at least 1 and not above the defaultlimits cannot be raised (reviewRounds max 3)
F010An approve step has only id, type, title, instructions and promptapprove steps have only id, type, title, instructions, prompt; "skip" is not allowed
F012title is at most 80 chars and instructions at most 4000 charsinstructions is 4210 chars (max 4000)

Codes F006, F008 and F011 are not used.

F005: gate coverage#

A code step is an implement step or an analyze step with variant reproduce.

RuleMeaning
(a)Every check and review step has an implement step before it, so a failure has somewhere to go back to
(b)The last code step is followed by a check step
(c)If the flow has a review step, one comes after the first check that follows the last code step
(d)At most one ship step, and it is the last step

A flow with only an analyze step (variant spike) is valid: it has no code step, so (b) and (c) do not apply.

Output of warden flow check#

json
{ "ok": false, "results": [
  { "flow": "my-flow.json", "errors": [
    { "code": "F005", "message": "(b) no check step after the last code step \"implement\"", "step": "implement" } ] } ] }

See also#

Type to search titles, headings and text.