Point a capable coding agent at "build me a chat app" and watch it work for twenty minutes. It scaffolds a project, writes a login page, wires up a message list, and then — somewhere around the point its context window fills — announces the app is complete. It is not complete. It has maybe fifteen percent of what you asked for. Start it again in a fresh session and it will happily re-implement the login page it already built, because the new session begins with no memory that the old one existed.
Neither of those is a reasoning failure. The model can write every one of those features correctly. What it can't do is remember, across the hard boundary of a context reset, what it already did and what it still owes you. That gap — not raw intelligence — is what stops agents from finishing multi-hour builds. Anthropic's engineering team calls the machinery that closes it a harness, and the interesting design work of long-running agents lives almost entirely there rather than in the prompt.
A harness is the code around the model, not the model
A harness is the loop, the file layout, the tools you expose, and the rules about who writes what — the scaffolding a model operates inside. A one-line prompt is not a harness. The moment work spans more sessions than fit in a single window, you are designing one whether you admit it or not, and that design decides whether the agent converges or spins.
The key observation: each session is disposable but the filesystem is not. So the harness's whole job is to make project state legible from cold — legible enough that an agent booting into an empty context can reconstruct "where am I, what's done, what's next" in the first few tool calls.
Split the first session from all the others
The first pattern is deceptively small: use a different prompt for the very first context window than for every one after it.
The first agent — the initializer — never writes application features. Its specialized prompt asks it to set up the environment: create the repository, make an initial git commit showing what was scaffolded, drop an init.sh that starts the dev server, and, above all, write down the full scope of the job before any of it is built. Every session after that runs the coding agent prompt: read the current state, make incremental progress on one thing, leave structured updates behind, commit.
"Set up the world" and "make progress in the world" are different jobs with different failure modes; collapsing them into one prompt gets you an agent that half-scaffolds, half-builds, and tracks neither well.
Make the scope a checklist the agent can't argue with
The initializer's most valuable output is an exhaustive feature list. In Anthropic's clone of the claude.ai interface, that list ran to over 200 features, each a plain-language user story like "a user can open a new chat, type in a query, press enter, and see an AI response." Every entry starts marked as failing:
{
"category": "functional",
"description": "A user can open a new chat, type a query, press enter, and see an AI response",
"steps": ["click New chat", "type into the composer", "press Enter", "assert a response bubble appears"],
"passes": false
}
This does two things at once. It defeats the "declare victory early" instinct — an agent staring at 200 "passes": false entries cannot honestly call the project done — and it gives each fresh session an unambiguous menu: pick one failing feature, make it pass, verify, commit. The guarding instruction is blunt: "It is unacceptable to remove or edit tests because this could lead to missing or buggy functionality." Otherwise a stuck agent quietly deletes the failing check and moves on.
Crucially, "verify" means acting like a user, not running unit tests in a vacuum. The harness hands the agent browser automation over MCP and asks it to run a basic end-to-end test before implementing a feature, then again after. State that survives a reset lives in exactly two places: the git history, and a running claude-progress.txt log of what past sessions did and learned.
Roles that can't grade their own work
For builds where quality matters as much as coverage, a second structure appears: separate the agent that decides what to build from the one that builds it from the one that judges it. A planner takes a one-to-four-sentence brief and expands it into an ambitious spec. A generator implements against a conventional stack. An evaluator drives the running app through Playwright and grades it on product depth, functionality, visual design, and code quality — then sends it back. The generator and evaluator negotiate what "done" means up front and iterate until they agree.
They never share a context window. Handoff is by artifact:
Communication was handled via files: one agent would write a file, another agent would read it.
Files as the interface is the same insight as claude-progress.txt, scaled up. A file is legible to a cold-booted agent, survives a reset, and forces each role to state its output explicitly instead of relying on conversational memory the next agent won't have.
The harness is expensive, so treat it as a dial
None of this is free. The same task built solo in one pass ran roughly 20 minutes and $9; run through the full planner/generator/evaluator loop it took about 6 hours and $200 — a twentyfold cost increase to buy reliability the model couldn't deliver on its own. That trade only pays when the task sits genuinely beyond what the model does reliably in one shot.
Which points at the real design principle:
Every component in a harness encodes an assumption about what the model can't do on its own.
Read that as an instruction to prune. The per-session reset fights "context anxiety" — a model watching its window fill and rushing to wrap up. Sprint decomposition exists because the model couldn't hold the whole plan at once. Both are load-bearing against a specific weakness, and when a stronger model stops having that weakness, the scaffolding becomes pure overhead. Anthropic's team deleted their sprint construct and their forced resets outright once a model generation arrived that no longer needed them.
So the takeaway is not "add these three agents." It is: before you add any piece of harness, name the exact model limitation it compensates for, and write that assumption down next to it. When a limitation goes away, the code that guarded it should go too. A harness you can't shrink is one you no longer understand — and the whole point was to build the smallest structure that lets a forgetful worker finish a job bigger than its memory.
Sources: Effective harnesses for long-running agents — Anthropic, Harness design for long-running application development — Anthropic