Reference
Config keys
Under harness.<id> in ~/.config/podcode/config.json or a workspace .podcode/config.json.
| Key | Default | Meaning |
|---|---|---|
chain | required | Ordered stages. A bare string is an agent id; the object form adds on_failure and acceptance. |
description | the chain, arrow-joined | Shown in the picker. |
max_hops | 4 | Handoffs allowed per user turn, across both the chain and the agent_handoff tool. |
A stage object
| Key | Meaning |
|---|---|
agent | The stage's agent. Must be registered with mode primary or all. |
on_failure | Where this stage hands back when it can't finish. Must itself be a stage in the chain. |
acceptance | { agent, check, max_retries } — a gate that must pass before the chain advances. |
Acceptance checks
| Check | How it's evaluated |
|---|---|
tests-pass | Runs the project's test script in the workspace; passes on exit 0 |
typecheck-clean | Runs the project's typecheck script; passes on exit 0 |
ui-renders | Requests the resolved dev-server URL and asserts HTTP 200 with real content |
Stage-eligible agents
Built-in: build, plan, orchestrator, implement, debug, test, review, social, and the four React stages react-architect, react-scaffold, react-runner, react-qa-brief.
Custom agents qualify with mode: primary or mode: all.
explore, research, and general are sub-agents only — reach them with task, not a chain.
Why a run halts
A chain that stops before its last stage records a harness-halt notice, which renders under the answer that turned out to be the end. Four designed reasons:
| Reason | What happened |
|---|---|
| Hop budget exhausted | The turn used its max_hops. Your next message resumes with a fresh budget. |
| Acceptance retries exhausted | A gate kept failing until max_retries ran out. |
| Repair stopped converging | A gate failed twice with identical evidence, so the remaining budget was worthless. |
| Gate could not be evaluated | There was no verdict to act on in either direction. |
All four end the turn on an ordinary assistant message. The notice is what tells you which one it was.
Limits
- Context grows across stages. Every stage inherits the whole transcript, so a long chain compacts mid-run. Compaction no longer costs a stage its identity — the pipeline, the stages already run, the ones still owed, and the current stage's brief are rebuilt from the store into a per-turn reminder, so they survive a summary that never mentions them. What compaction still costs is the detail of earlier stages' work. Very long chains are better split across user turns.
- A custom agent's
toolsallow-list isn't enforced in-session. It applies totaskchildren only. A custom agent used as a stage is gated by its permission ruleset. Deny what must not run. - Sub-agents cannot hand off.
agent_handoffis filtered out of every child's tool set and denied in their rulesets: a delegated turn belongs to the parent that requested it. - The agent a client sends alongside a harness is advisory. An agent that is a stage of the selected chain is indistinguishable from the picker's leftover selection, so it's ignored and the run decides. An agent outside the chain is a deliberate override and is honoured.
Selecting from the terminal
The TUI's /agent autocomplete lists pickable agents, and harness-only agents are excluded from it by design — so /agent react-architect reports "Unknown agent" client-side even though the runtime will happily advance a chain through it. Select the harness itself, not its stages.
Next
- Providers — chains are most useful when the cheap stages run on a model you host.