# Walk a chain by hand

`explorer → planner → coder → reviewer`, one command at a time, with you
deciding between two steps what happens next - which agent, on which model, from
which output.

```
/step explore     how usage is measured
/step planner     three steps at most, no refactor
/step coder
/step reviewer    is anything missing
/quote                                     # only now does this session read it
```

A chain a [flow](flows.md) could hold, with one difference: our code does not
walk it, you do. That buys you the join between two steps - reading the
plan before the coder sees it, running the reviewer twice, dropping a step that
went nowhere - at the cost of typing each one.

## Why it is not `/run`

`/run` puts its answer **in the conversation**, deliberately: an exploration is
read and then asked about, and a report you have to send back yourself before
the model knows anything about it is a report in the wrong place.

That is the wrong default for a chain you are walking. pi hands a custom message
to the model as a *user* message, so the session reads the explorer's report and
acts on it: it becomes an orchestrator, and every later step is chosen against
what it has already concluded. When the main window is meant to be a console,
whatever reaches it changes an answer you did not want changed.

So `/step` does the opposite on that one point, and nothing else:

| | `/run <flow>` | `/step <flow\|agent>` |
| --- | --- | --- |
| Runs | a flow, end to end | one stage, and stops |
| The answer | in the conversation | drawn in the transcript, **not** in context |
| The next step | the model's to suggest | yours to type |
| Carried output | between the flow's nodes | between your commands, in the relay |

## The commands

| Command | What it does |
| --- | --- |
| `/step <name> <instruction>` | Runs one flow or agent on the previous step's output plus what you typed. |
| `/step --from <id\|last\|none>` | Carry that step instead of the last one. `last` is the default, `none` starts from scratch. |
| `/step --model <pattern>` | This step only. Plan on a large model, code on a small one. |
| `/step --agent <name>` | When a flow and an agent share a name, run the agent. |
| `/chain` | The steps walked so far, what each carried, and where they exported. |
| `/chain export` | Write the chain into `chain.md`, in its folder. |
| `/chain reset` | Drop it. The next `/step` starts a new chain, in a new folder. |
| `/quote [id]` | Put one step into this conversation, attributed. Default: the last. |

`<name>` is resolved against the flows first, then the agents - a stage of a
chain is often a whole flow, `explore` being a fan-out and a synthesis. A name
held by both runs the flow and says so; `--agent` runs the other one. A flow
is checked whole and held to this terminal before anything is spawned, as
`/run` holds it, and a broken flow file is refused rather than fallen past to
an agent of the same name.

A flow stage runs in the step's folder, which is its [run
directory](flows.md#the-run-directory): the snapshot, the journal and the
transcripts. A flow stage that stops says where, and what `/run resume` would
do with it: `step: explore failed at <visit>: <why> - the chain is unchanged,
/run resume <folder> picks it up at <visit>`.

`/run resume <that folder>` carries it on, and its answer lands in the
conversation as any `/run`'s does; the chain does not learn it. `/run resume`
alone looks only at the runs directly under `runs/`, so a step's run is
named by its path.

## What a step is handed

The first step gets your instruction, verbatim. Every later one gets two
sections, what you typed and what it carries:

```markdown
## Request

three steps at most, no refactor

## Output of step `explore`

Usage is collected in src/usage.ts:40 …
```

A flow stage reads that text as its `input`. When a chain is worth keeping,
write it down as a [flow](flows.md), and `/run` it or `/step` it.

An instruction is optional once something is carried: `/step reviewer` on its own
means "review that". With nothing carried and nothing typed, the step is refused
rather than sent to answer about nothing.

## What it leaves behind

One `runs/<timestamp>/` for the chain, one subfolder per step -
`1-explore/`, `2-planner/` - each with that step's transcripts and its
`usage.json`, exactly as [a run exports one](export.md). Each step names its
folder when it ends, and `/chain` names the chain's and totals the turns.

pi's own `/export` shows none of this. A step stays out of the session's
context, and pi's HTML export leaves out what the context leaves out. Use
`/chain export` instead. It writes `chain.md` into the chain's folder: the steps
in order, with what each was asked, what it carried and answered, what it
cost, and links to its transcripts. Run it again after more steps and it
rewrites the file.

`/swarm` is a step too, of kind `swarm`: several agents on one goal, named
after the agent when they are copies of one and `swarm` when they are not, recorded like any other so `/chain`, `/quote` and `--from` reach it. See
[Swarms](swarm.md).

A step that **fails** leaves the chain untouched. It produced nothing to carry,
and recording it would hand the next agent an error message as its input; what
ran is still on disk, and the same command can be retried on another model.

## What the session does not know

Nothing a step produces reaches the model until `/quote`. That is the point, and
it has a consequence: ask the session about the work and it will answer from a
conversation where none of it happened.

The screen has to carry that, because the next command is typed on a belief
about it. A finished step is drawn with its own header and its body indented
under it:

```text
◇ scout agent  1 turn  outside this conversation - /quote puts it in
  The ledger records obligations, which are "things that must happen before
  the work is finished" (src/review/ledger.ts:31).
  …
```

Looked at in a real pi, the first version of that header said the same thing in
the same muted grey as the turn count, above a report drawn flush left at full
width - which is exactly how an answer the session gave is drawn. The phrase
carries the theme's warning colour now, and the indent makes the block read as
an aside before a word of it is read.

`/quote` is the way out, one step at a time. It arrives attributed -
``Result of the `planner` step of the chain, asked to: …`` - because an
unattributed report in a user slot reads as an instruction.

Subagents never had this problem: one **never** inherits the parent session's
context, walked by hand or not ([Agents](agents.md)). The relay is the only
thing that crosses from one step to the next, and it carries a `Result`, not a
conversation.
