Part 3 of 6 in Harness Engineering

An AI Coding Harness, from Three Tmux Panes to Ten Agents

The first version of a multi-agent harness ran three personas in tmux panes, one of them Claude Code itself. It worked, right up until Claude tried to drive the thing headless and hit a wall no amount of retrying could get past. Here's the wall, and the ten-persona pipeline that replaced it.

A single terminal pane splitting and rearranging into a headless pipeline of connected process nodes

The last two parts of this series covered a single-agent harness, one model, four generations of rules and memory, evolving to make that one agent more reliable. This part covers what happens once you stop trying to make one agent smarter and start giving different parts of the work to different agents. That's a different kind of harness problem, and the first version we built for it had the wrong shape.

The starting idea

Claude Code is good at architecture, code review, and holding a project's rules in its head. It's also the most expensive agent in the stack. A lot of what a coding session actually spends tokens on (research, first-draft implementation, mechanical file edits) doesn't need that level of judgment. It needs a competent worker and a strict supervisor, and the supervisor doesn't have to be the expensive model every time.

So our plan was this. Claude stays the entry point and the reviewer, and delegates research and code-writing to cheaper or free models. Research goes to whatever free model a routing layer can reach. Code-writing goes to a separate coding agent, configured to use a free model pool first and a cheap paid one as fallback. Nothing expensive gets spent on a category of task a cheap tool can do just as well.

We built the first working version of that plan with tmux. Claude ran in one pane, the coding agent in another, and a small bridge script passed messages between them. Write a message into the coder's pane, poll for its reply, hand the result back to Claude. A third piece, a plain script with no pane of its own, called out to a free-model router directly for research. It worked. Verified, not assumed. A real task went from Claude, into the coder pane, into written files, back out again, checked by hand.

Where it broke

tmux panes need a terminal. Something has to attach to them, and attaching means an interactive session, a human at a keyboard, or at minimum a process holding a real TTY. That was fine as long as a human was the one starting the session and watching it run.

It stopped being fine the moment the goal shifted to running the whole pipeline unattended. Claude Code itself, invoked non-interactively, with no terminal and no human watching, tried to start the session that would open the coder's pane. The attempt failed immediately. The input device is not a TTY. The exact mechanism built to let Claude delegate work couldn't be driven by Claude running the way it actually runs in an automated pipeline. The one piece of infrastructure meant to make delegation possible required a form of human presence the whole point of delegation was to remove.

That's not a bug in one script. It's the wrong assumption sitting under the entire mechanism, and no amount of patching the message-passing logic fixes an assumption. The panes had to go.

What replaced them

Every persona became a headless script instead of a pane. No TTY, no attaching, no polling a terminal for a reply. Just task <persona> -- "mission", a self-contained instruction in, a structured result out. The coding agent still runs the same underlying tool; it just no longer needs a terminal someone is watching to do it.

That change alone would have been a simple fix if the personas had stayed the same three. They didn't. Once delegation stopped requiring a human to babysit a terminal, it became practical to add more personas instead of asking one coding agent to also verify its own work, which is a conflict of interest a harness shouldn't design around in the first place. The pipeline that emerged has ten distinct personas now.

  • orchestrator, Claude. Plans, dispatches, reviews, writes code only as a last resort.
  • coder implements. The only persona backed by a full file-editing agent rather than a read-only chat model.
  • intern, stateless research. No memory between calls, returns a sourced, dated report or nothing.
  • tester independently re-verifies what coder produced against the actual story, never fixes anything itself.
  • reviewer triages a tester failure into a false positive, a real code defect, or an environment problem. Only runs when tester fails; never on a pass.
  • validator, the final gate. Rule compliance, architecture, security, the call on anything ambiguous.
  • consolidator, assembler, verifier are generic, added later once a non-code project needed the same shape of work (merge several results, build a structured deliverable from collected data, check a finished thing against its source) without any of the code-specific vocabulary the first four personas carry.
  • runner executes one named, deterministic command and nothing else.

The loop is fixed. coder hands off to tester; a failure routes through reviewer for classification; a pass or a confirmed false positive moves to validator; anything real routes back to coder with the classified report attached, not a raw unfiled complaint. No persona ever contacts another persona directly. Every result comes back to the orchestrator first, and the orchestrator decides what happens next at every junction. It's the same discipline the earlier generations of this harness applied to a single agent's rules, now applied to which agent gets to act at all.

What carries over from the earlier generations

The core lesson from the single-agent era doesn't change with more agents in the loop. If anything it gets sharper. A rule without a mechanism behind it gets dropped under pressure, whether the agent reading it is the one model this series started with or one of ten personas in a pipeline. The next part of this series covers what happens when a harness writes the right rule, in the right place, and the model reads it, understands it, and takes the shortcut anyway.


— Delaa