Home/Guides/Why does your agent say it's done when…
Guide · 4 min read

Why does your agent say it's done when it isn't?

"Done" set by intention rather than evidence is the quietest way a long run accumulates breakage.

Quick answer

Because nothing forced it to check. An agent marks a task complete when it believes it has finished, and belief is formed from its own last action rather than from the state of the system. The fix is not a better model but a verification step the agent cannot satisfy by asserting: run the test, start the app, make the request. Anything t…

Session six reports that features eleven through fourteen are complete. You open the app. Feature eleven works. Twelve throws on load. Thirteen was never wired to anything. Fourteen is fine.

Nothing lied. This is what "done" means when nobody defined it.

Where the belief comes from

An agent forms its sense of completion from its own recent actions. It wrote the function. It wrote the handler. The code it produced looks like code that implements the feature — and, read on its own terms, it does.

What it did not do is consult the system. Nothing ran. Nothing responded. The judgement is about the work product, not the world, and those come apart precisely when something else in the codebase has moved since.

This gets worse with capability, not better. A more capable model produces more plausible code, which is more convincing to itself, and it is more efficient at producing a lot of it between checks.

Why self-review does not fix it

The natural response is to ask the agent to check its work. This helps less than expected, because a re-read is a re-read of the reasoning, and the reasoning was fine. The error is not in the logic; it is in the gap between the logic and the running system.

Verification has to produce evidence from outside the agent's own head. A command that runs. Output that either matches or does not. A page that loads. Anything the agent cannot satisfy by thinking harder.

Make completion checkable

The structural fix is to write the check before the work, and to make it part of the item rather than a habit. A plan item should carry two things: what to build, and how to prove it. "Users can reset their password" is a description. "POST /reset with a valid token returns 200 and the new password works at login" is a check.

With the check written down in advance, "done" stops being a judgement call. It is a command that passed or did not, and the agent cannot reach it by conviction.

The thirty-second version

If you adopt one thing: start the app at the beginning of every session and exercise one real path. Not the tests — the app.

Most accumulated breakage in a long run is not subtle. It is an import that no longer resolves, a route that 500s, a build that fails. Those are caught by starting the thing, and they are exactly what a session focused on feature fifteen will not notice while editing feature fifteen.

Anthropic's published long-running-agent setup includes this as a startup step for the same reason: the first job of a session is not to make progress, it is to establish that the reported state is real.

Cleaning up after it has happened

If you already suspect a run has drifted, do not re-verify everything at once. Work oldest first: the earliest false "done" is the one everything after it was built on, and fixing it sometimes resolves several later items at once.

Then find where it entered. A progress log that was appended to, plus commit history, will usually name the session. If the log has been rewritten, you have lost that, which is the argument for append-only in one sentence.

Frequently asked questions

Doesn't asking it to double-check work?
Weakly. Asked to review its own work, an agent re-reads its reasoning and finds it sound — which it was, on its own terms. Verification has to consult the system, not the reasoning: a command with output, not a re-read.
What's the cheapest verification that catches most of it?
Start the thing and exercise one path. Most silent breakage is not subtle logic errors; it is the app no longer starting, an import that does not resolve, or a route that 500s. Thirty seconds catches a surprising share.
How do I catch it after the fact?
Re-run the verification for items already marked done, oldest first. The breakage was introduced at a known point, and the progress log plus git history usually identify which session — if the log was appended to rather than rewritten.

Related skill

AI Reasoning

Temporal Reasoning Sleuth

Engineers temporal reasoning capabilities for AI agents — enabling them to trace decision chains, reconstruct causal se…

Turn this guide into a skill your agent can run

Stop re-explaining the same workflow. Loreto packages it as a Claude Code skill from any source.