Harnesses
A harness is a named chain of agents you select for one conversation. A planner hands to an implementer, which hands to a tester, which hands back when the tests fail. It all happens in one session — same transcript, same worktree, same run-lock — so each stage reads everything that came before it, and a single Stop cancels the whole thing.
{
"harness": {
"review-loop": {
"description": "Build, then review what was built",
"chain": ["implement", { "agent": "test", "on_failure": "implement" }, "review"]
}
}
}Select it from the composer's dropdown, under HARNESSES, and describe the work. The chain starts at the first stage and advances itself; the picker follows along as each stage takes over.
Why chains exist
The failure mode of an agent given a large, open-ended task is not that it can't write code. It's that it holds too many things at once: the design it hasn't committed to, the file it's editing, the test it hasn't run, and the definition of done it never wrote down. Small open-weight models hit that wall early and hard — they will do very well on "write this component to this spec" and come apart on "build me a website".
A harness removes the load rather than asking the model to carry it. Each stage gets one job, a brief written by the stage before it, and a stated finish condition. Nothing is being held in reserve for later, because later is somebody else's stage. Failure has a defined destination instead of a retry: a test stage that fails hands backwards to the implementer, and an acceptance gate decides whether the chain may advance at all.
This is why harnesses exist, and it is the case where they matter most: they are what makes a smaller, cheaper, privately-hosted model viable for work you would otherwise have to send to a frontier model.
The same structure helps a frontier model too — it just moves from necessary to useful. Shorter briefs, an explicit definition of done per stage, a repair loop with a budget, and a transcript that shows which stage produced what are not small-model crutches. They're the difference between an agent that ran for twenty minutes and an agent whose twenty minutes you can audit.
Two ways a chain advances
The chain itself is deterministic and fires even if the model never asks for it. It advances only at a clean turn end — after the plan-mode guards and the continuation guard have all declined to intervene. A stage that stalls or leaves work unfinished gets nudged, not chained past.
The agent_handoff tool lets the model decide, including to an agent outside the chain. The chain is a default route, not a cage.
Both draw on one hop budget, so they can't compound.
Runs
A harness is the chain you selected. A run is one pass through it — and the distinction is what decides where your next message goes.
- The run finished — it reached the last stage and that stage answered cleanly. Your next message starts a new run at stage one. You picked a pipeline; you get the pipeline.
- The run didn't finish — you pressed Stop, or the hop budget ran out, or a stage stopped validating. Your next message resumes at the stage it stopped on, with a fresh hop budget.
The stage is stamped on each message, so the transcript is the state. There is no hidden server-side variable to get out of sync with what you're reading.
What a selected harness changes
Only what's described here. With no harness selected, a session behaves exactly as it did before the feature existed: the chain never advances, and agent_handoff isn't offered to the model at all. Defining a harness is safe on its own — it only makes it available to pick.
Plan mode is a separate flow with its own approval gates and is unaffected either way.
Next
- Quickstart — run the built-in React JS harness end to end.
- Build a harness — chains, repair targets, acceptance gates.
- Reference — every key, every halt reason, the limits.