Why Coding Agents Fail in Hour Two, Not Hour One
Understand why coding agents perform well early on but fail during longer sessions by examining how context window, verification processes, and definitions of done degrade over time. Learn to identify key reliability gaps and the importance of harness engineering to manage scope, persist state, and improve dependable agent work across multiple files and sessions.
On Tuesday morning, staff at Wrenfold Physiotherapy Clinic found two patients waiting for the same 3:00 PM slot with one physiotherapist. Both had valid booking confirmations. The booking system had created two valid reservations for one time slot.
The night before, a coding agent received CLIN-482, a ticket in the clinic’s issue tracker to add recurring appointments to the booking API. At first glance, the implementation appeared complete. It added the new endpoint, wrote tests, and passed the test suite. It then marked the task as complete. The resulting booking system still allowed conflicting reservations.
This booking API is the codebase used throughout the course, so the double-booking is not just an introductory example. It is the failure mode the rest of the course is designed to prevent.
To understand why it happened, we need to look at how the coding session unfolded. The agent worked for just under two hours. During the first hour, everything looked good. It found the right part of the codebase, implemented a reasonable solution, and got the tests passing. The problems appeared during the second hour.
The important part is that nothing obviously looked wrong as it happened. The agent kept working, the code kept looking plausible, and there was no clear moment where the session suddenly "failed."
That is the reliability problem we are going to study: a coding agent can start well, make steady progress, and still leave the repository in a broken state by the time it says it is done.
Why did the first hour go so well?
Three conditions hold at 00:04 but become less reliable as the task continues. Only the first is directly related to context, although context management is often treated as the cause of all three:
How much relevant information the agent can retain in context.
How efficiently the agent can retrieve the information it needs.
How quickly the agent can detect an incorrect result.
These are three different systems, and they break down differently.
Four minutes in, the agent’s context contains the ticket, the route file, and little unrelated information. Nearly all of the information in context is relevant. As the session continues, that changes. More files are read, unsuccessful paths are explored, and tool outputs accumulate within the same limited context window. At 00:04, the agent is reasoning from a small set of relevant inputs. At 01:30, it is reasoning from a much larger history of interactions and tool outputs.
This degradation is a context-management problem.
Early in the task, the verification loop is also short: write the handler, run npm test, and confirm that the tests pass. The change-to-feedback cycle may take only fifteen seconds. If something is wrong, the agent detects the error before it propagates into subsequent changes.
This failure mode is not about context management. It is about verification.
Hour One | Hour Two | |
What the task needs | One file, named in the ticket | A module nobody mentioned |
Where the answer lives | In the ticket, or one grep away | In a convention, or someone’s head |
Time until feedback | Fifteen seconds | Never, unless you built the gate |
What correct means | The endpoint returns 201 | The schedule stays coherent |
Who can check it | The agent, alone | Something outside the agent |
That first column is also close to what many coding benchmarks measure: a clear issue, a fix limited to one or two files, and a test that already defines success. Models have become dramatically better at that kind of work.
CLIN-482 was only one sentence. Nothing in the tests said that appointments must never overlap, because that rule lived in src/availability/ and partly in someone’s head. So the agent chose its own definition of success: the unit tests were green.
That is why both things can be true at once: benchmark scores keep improving, and real systems can still fail on Tuesday morning.
What changes in hour two?
The three advantages from hour one start disappearing, each in a different way:
The context runs out. Earlier decisions fall out of view, and the agent may not realize what it has forgotten. Anthropic, the company behind Claude, also found in one of their tests that agents can change their behavior when they sense the context window getting full, sometimes rushing to finish early. They call this context anxiety. The agent is not being lazy. It thinks time is running out.
The map runs out. In hour two, the agent may need a module it has never seen in a directory it has no reason to inspect. So it does something reasonable: it builds its own solution. Now the clinic has two overlap checks that disagree, and the new one does not know about provider time off.
The definition of done runs out. “The tests pass” is no longer the same as “the task is complete,” but nothing tells the agent that. It ends up judging its own work using the same limited view it used to create it. Anthropic found that agents often rate their own work too positively, even when a human would spot obvious problems.
These are not mainly reasoning failures. There are failures in the environment around the reasoning.
Is this a limitation of the model itself?
Probably not. Anthropic demonstrated this with a side-by-side experiment.
In one Anthropic experiment, the same prompt and model were tested in two different execution setups to build a retro video game using Claude Opus 4.5. Without the harness, the run lasted twenty minutes and cost nine dollars, and the resulting game did not respond to input. With the harness, the same model ran for six hours and cost two hundred dollars, producing a functional game that supported player interaction.
Same model, same prompt, same task. One failed implementation and one functional application.
Scale it up and it stops being a demo. Over five months, three OpenAI engineers shipped a beta product of roughly a million lines with no manually written source code, driving Codex through about 1,500 merged pull requests.
So a more expensive model is the priciest option available and usually the wrong one. A stronger model reads the same silent repository and hits the same three walls.
Three names for what you just read
All three have already appeared in this lesson without being clearly defined, and the rest of the course relies on them throughout. It is worth defining them clearly now:
Harness: The working environment wrapped around the model: what a session can reach, what actions it may take, the state it works against, how its result is judged, and what survives into the next session. In a repository, that environment becomes concrete through files, commands, permissions, checks, and saved progress. The model supplies capability; the harness turns that capability into repeatable work.
Verification gap: The distance between an agent’s confidence and its actual correctness. In our example, that gap was the whole failure: “all tests pass” was true, “the work is done” was false, and nothing could tell them apart.
Definition of done: Conditions a machine can check. This is the one that ran out in hour two. If you have not written one, your agent will invent one, and it will be generous.
Those three sit on one side of a line, which is the line this course is built on.
Capability is what the model can do. Reliability is what your system lets it finish.
Every technique in the course answers one question: what does the system need to provide so that a capable model can finish?
Same model, same ticket, two outcomes
Below are two runs of the same session. Both runs use the same model, ticket, and starting commit. The only difference is that the second run uses a harnessed execution environment. Pay attention to the timeline because the two runs behave similarly for the first thirty-eight minutes.
Notice when the two runs diverge. They diverge not at the start, where an initial prompt issue would appear, but at 01:12. Observing only the first twenty minutes would miss the failure entirely.
The harnessed run was also slower, including an additional minute spent running and failing a test that the unharnessed run never executed. Those additional fifteen minutes represent the trade-off: more verification during execution and less failure discovery during code review.
What to do instead of swapping the model?
When a session fails, do not ask whether the model is good enough. Ask which layer failed: was the task underspecified, the context missing, the environment broken, the verification absent, the state lost?
The thing worth doing today is writing a definition of done. Not in the ticket: CLIN-482 can stay one sentence. Put it in the repository, where every session finds it without being told, and end it with a command:
Done when all of the following hold:- POST /appointments/recurring accepts { patient_id, provider_id,start, weeks } and returns 201 with the created appointment ids- No created appointment overlaps an existing one for that provider,including provider time-off blocks- All stored times are UTC, converted at the request boundary- npm run test: e2e passes, including tests/e2e/booking.test.ts
Add recurring appointments cannot fail. That list can, and its last line fails by running. A definition of done that cannot fail is not one.
That placement is the difference between a better prompt and a harness: one helps the session you are about to run; the other is read by every session after it.
What this course is not and who is it for
It is not prompt engineering, model evaluation, or MLOps, and it is not a framework tour. For majority of this course, you will not use one, because reaching for orchestration before you have a navigable repository is the standard way to spend a month and improve nothing.
You will get the most from it if you already work with a coding agent and have watched a promising session end somewhere disappointing. If you are good at reading TypeScript, using git, navigate logs, and familiar with the terminal, you should have a good time.
Identify the equivalent 01:12 in another failed session. In a transcript from a session that produced an incorrect or incomplete result, mark the first point where the agent required information that was not available from the repository, then count how many subsequent decisions depended on that missing information. Failed sessions often have a pivotal decision point that occurs well after the session begins.
What’s next?
You have the distinction and a name for the reliability side, but not its anatomy. The next lesson breaks the harness into five layers and hands you an ablation simulator: take away what the session can reach, or what it carries, or who judges it, and watch the same session break in five distinctly different ways.