Documentation Index
Fetch the complete documentation index at: https://gump.build/docs/llms.txt
Use this file to discover all available pages before exploring further.
State & Variables
The state is how steps communicate. Every step writes its outputs and metrics to a shared key-value store. Other steps read from it via template variables.
Basics
After a step executes, its results are available to all subsequent steps:
steps:
- name: decompose
type: split
get:
prompt: "Decompose {spec} into tasks."
run:
agent: claude-opus
gate: [schema]
- name: review
type: validate
get:
prompt: |
Review the plan:
{decompose.output}
run:
agent: claude-opus
{decompose.output} resolves to the JSON plan produced by the decompose step. No steps. prefix needed — variables use short names.
Fully-qualified keys
The state is a flat map[string]string with fully-qualified keys:
Examples:
decompose.output — the JSON plan
build/task-1/converge.output — the diff from task 1
build/task-1/converge.diff — the git diff
build/task-1/converge.agent — the agent that executed (e.g., claude-opus if escalated)
build/task-1/converge.cost — estimated cost USD
build/task-1/converge.tokens_in — input tokens
build/task-1/converge.status — pass/fail/fatal
build/task-1/converge.gate.compile — bool
build/task-1/converge.gate.review.comments — string
What each step writes
Every completed step writes these keys:
| Key | Description |
|---|
{<step>.output} | Main output: diff (code), tasks JSON (split), bool (validate) |
{<step>.diff} | Git diff (code steps) |
{<step>.agent} | Agent that actually ran (reflects escalation) |
{<step>.session_id} | Agent session ID |
{<step>.status} | pass, fail, or fatal |
{<step>.attempt} | Final attempt number |
{<step>.duration} | Duration in milliseconds |
{<step>.cost} | Estimated cost in USD |
{<step>.turns} | Number of cognitive turns |
{<step>.tokens_in} | Input tokens consumed |
{<step>.tokens_out} | Output tokens produced |
{<step>.gate.<name>} | Bool result of a specific gate |
{<step>.gate.<name>.comments} | Validator comments |
Task variables (each block)
Inside an each block, task-level variables are available:
| Variable | Description |
|---|
{task.name} | Current task name (from the split JSON) |
{task.description} | Current task description |
{task.files} | Current task blast radius (file list) |
Retry variables
On retry (attempt > 1), the failed attempt’s context is available:
| Variable | Description |
|---|
{error} | Error output from the failed gate (truncated to 2000 chars) |
{diff} | Diff from the failed attempt (truncated to 3000 chars) |
{attempt} | Current attempt number |
{gate.<name>} | Bool result of a specific gate |
{gate.<name>.comments} | Comments from a workflow validator |
{gate.<name>.error} | Stderr from a deterministic gate |
{prev.output} | Output from the previous retry iteration |
{prev.gate.<name>.comments} | Validator comments from previous iteration |
Dynamic agent reference
{<step>.agent} returns the agent that actually executed a previous step. If the step was escalated (agent overridden in retry), the variable returns the final agent, not the declared one. This enables the idiom:
- name: smoke
type: code
run:
agent: {converge.agent}
get:
session: from: converge
Scope resolution
Variables resolve by strict scope: step local → each scope → workflow scope. If a variable name is ambiguous (same step name in different scopes), --dry-run will reject the workflow with an error listing available paths.
There is no implicit resolution by proximity. For cross-scope references, use the fully-qualified path: {build/task-1/converge.output}.
Run-level metrics
The {run.*} variables from v0.0.3 have been removed. Run-level metrics (total cost, duration, tokens) are in the ledger and accessible via gump report. The global bounds (max_budget, max_timeout, max_tokens) replace {run.*} for control purposes.
If a prompt needs the cost of a specific step, use {<step>.cost}.
State persistence
The state is serialized to .gump/runs/<uuid>/state.json as a flat JSON dictionary. It’s reloaded on --resume and --replay.
At retry, the previous iteration’s keys are copied under the prev namespace. The original keys are overwritten by the current iteration.