Skip to main content
The complete field reference for plan YAML files. Concepts and worked examples live in the Plans section; this page is the lookup table. Every field name in a plan file is snake_case, at every depth — top level, steps, control-step grammar, and an agent step’s input alike. That is the one spelling to author in, and what everything writing a plan emits: graph plan show (including --json), the authoring commands, and the workbench’s save. The planner uses camelCase internally (toolName, queryToAnswer) because that is the schema the model is taught. You never see it: a plan it drafts is normalized to snake_case before it reaches disk. The camelCase spellings stay accepted on the way in, so a plan authored before this settled still loads — and rewriting it with any authoring command normalizes it. Optional fields you never set are omitted rather than written as null/[].

Top level

solver and output are mutually exclusive; declaring neither makes the plan silent (side effects only).

solver

Steps

Control steps

Seven reserved tool_names are executor-intercepted, never dispatched to a registry. Their input is the control grammar — snake_case like everything else, and the only part of a step’s input graph normalizes, since every other tool’s arguments belong to that tool:

exitend the plan early

decidefork into one of two branches

filterpartition a list

Legal everywhere, including inside decide branches and map/reduce bodies — the one nestable control step (it makes no tool call). Inside a body its {{item}}/{{index}} shadow the enclosing body’s within the gate.

map / reducerun a body per item

agentdelegate an open-ended sub-task

Legal everywhere, including inside decide branches and map/reduce bodies.

askput a question to the user

Legal everywhere, including inside decide branches and map/reduce bodies. Whether a human is reachable depends on the host, not the plan, so when_unanswered is what keeps one plan runnable both interactively and in CI.

Gate grammar (when / if / where)

A single comparison: { value, op, to }, where value is usually a template (typed splice keeps numbers numeric).

Body grammar (then / else / do)

Either form:
  • A single tool call{tool_name, input}, no id. Any catalog tool, including plan__* and plan_and_execute.
  • An inline step list — normal steps with ids, run in order, with same-branch/same-iteration dataflow. Body ids must not reuse top-level ids and are invisible outside the body.
Bodies must not contain decide, map, or reduce (branches may contain exit; map/reduce bodies may not). agent, ask, and filter are legal in any body. For other nested control flow, call a plan__* sub-plan — cycles are detected and nesting is capped at 8.

Step results of control steps