The State Bag
The state bag 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.decompose.output} resolves to the JSON plan produced by the decompose step. The review step sees the full plan as context.
What each step writes
Every completed step writes these keys:| Key | Description |
|---|---|
{steps.<n>.output} | The step’s main output (patch for diff, JSON for plan, text for artifact, JSON for review) |
{steps.<n>.files} | Files changed (for diff steps) |
{steps.<n>.status} | pass, fail, or fatal |
{steps.<n>.duration} | Duration in milliseconds |
{steps.<n>.cost} | Estimated cost in USD |
{steps.<n>.turns} | Number of cognitive turns |
{steps.<n>.retries} | Number of retries executed |
{steps.<n>.tokens_in} | Input tokens |
{steps.<n>.tokens_out} | Output tokens |
{steps.<n>.cache_read} | Cache read tokens |
{steps.<n>.cache_write} | Cache write tokens |
{steps.<n>.session_id} | Agent session ID |
{steps.<n>.check_result} | Gate result: pass, fail, none |
Run-level variables
Aggregate metrics for the entire run:| Key | Description |
|---|---|
{run.cost} | Total cost so far |
{run.duration} | Elapsed time |
{run.tokens_in} | Total input tokens |
{run.tokens_out} | Total output tokens |
{run.retries} | Total retries |
{run.status} | running, pass, fatal, aborted |
Foreach variables
Inside aforeach block, item-level variables are available:
| Key | Description |
|---|---|
{item.name} | Current item name |
{item.description} | Current item description |
{item.files} | Current item blast radius |
Retry variables
On retry, the failed attempt’s context is injected:| Key | Description |
|---|---|
{error} | Error output from the failed gate (truncated to 2000 chars) |
{diff} | Diff from the failed attempt (truncated to 3000 chars) |
Resolution by proximity
When you write{steps.impl.output}, Gump resolves it by searching the closest scope first — same group, then parent, then root. This means you can use short names when there’s no ambiguity:
build group, {steps.impl.output} refers to the impl step in the same group. If the name is ambiguous (same step name in different groups), --dry-run will reject the workflow.
Hierarchical state bag
When aworkflow: step completes, its entire state bag is grafted into the parent under the step’s namespace:
{steps.validate.steps.review.output} — the review step’s output from inside the security-check sub-workflow. There’s no explicit “return” — the entire state bag is the interface.
Persistence
The state bag is saved to.gump/runs/<uuid>/state-bag.json at the end of the run. It’s reloaded on --resume and --replay.