Skip to content
Back to all field notes verify · 8 min

Done means done: making agents prove completion

To an agent, 'done' means it wrote something that looks finished. To you, it means the behavior changed and nothing else broke. Close that gap or you close nothing.

field note 8 min

The task comes back marked complete. “Done. Implemented the retry logic, all tests pass.” You didn’t watch it run. You have a diff and a sentence. Somewhere between that sentence and reality is a gap, and how wide it is decides how much of your day you spend re-checking work that was already reported finished.

“Done” is the most overloaded word in agent work. It hides two definitions that quietly disagree, and every false completion lives in the disagreement.

Two definitions of done

To an agent, done tends to mean: I produced code that looks like it satisfies the request. The implementation exists, it is plausible, it reads like something a competent person would write. That is a real accomplishment and it is not the same as the job being finished.

To you, done means three things at once. The behavior you asked for actually changed. The behavior you did not ask about did not break. And there is something you can point at to prove both of those without redoing the work yourself.

Those are different bars. The agent clears the first one and reports success in good faith, because from inside its context the first bar looks like the whole thing. You are left holding the distance between “looks finished” and “is finished, and I can see why.” Making done mean done is the work of collapsing that distance until the agent’s definition and yours are the same.

Why the gap is structural, not lazy

It would be easy to read this as the agent cutting corners. It is not. A model completes the most probable text for a situation, and after a finished-looking implementation the probable next sentence is a report of success. The claim is generated, not observed. That is the anatomy of a false success claim, and it means the confident-sounding “all tests pass” can sit on top of a test suite that never executed.

So begging the agent to be more careful does not fix it. You cannot prompt your way out of a structural default. What changes the outcome is changing who gets to declare success. Right now the agent is both the worker and the judge of its own work. Take the judging away.

Proof is a demonstration, not a checkbox

If a claim is cheap, then completion has to cost a demonstration. The agent should not be able to say done. It should have to show done.

What counts as a demonstration? Concretely:

  • A command that actually ran. Not “the tests should pass” but the invocation and its exit code.
  • The output it produced. The lines the run printed, captured, not summarized into “looks good.”
  • The version of the contract it ran against. Which acceptance criteria, at which revision, so a later green does not silently refer to yesterday’s requirements.

A checkbox is a claim wearing the costume of proof. It says “done” with a satisfying visual and carries no information about whether anything happened. Replace the checkbox with the three things above and the entire class of confident-but-empty completions disappears, because there is nowhere for it to hide.

This is the same lesson spec-driven development learned the hard way: a green build is not a correct feature. The build compiling and the feature being right are two separate claims. Completion has to check the second one, and it can only check it against criteria written down before the work started.

What “not done” wearing done’s clothes looks like

The dangerous completions are the ones that look finished from every angle except the one nobody checked. A few shapes recur often enough to name:

  • The task done, the adjacent thing broken. The feature works. A behavior three files away that quietly depended on the old code no longer does. The agent had no reason to look there and you had no evidence forcing the question, so “done” shipped a regression.
  • The happy path done, the boundary ignored. The demo input works. The empty list, the timeout, the second concurrent call, the malformed field, none were exercised. The implementation is real and the contract it satisfies is narrower than the one you meant.
  • The code done, the run imagined. The most common one. The implementation exists, the report says the tests pass, and the tests were never invoked. Nothing is wrong with the code except that no one confirmed it.

Every one of these passes a casual read. The diff looks reasonable, the summary sounds right, the surface is clean. That is precisely why “looks done” is not a category you can afford to trust: the failures that survive to production are the ones that look like success, because the ones that look like failure get caught. Done that means done is the specific defense against completions whose only flaw is that the missing check was never run.

Write the demonstration before the work

Here is the move that makes this practical. Decide what would prove the task is done before the agent starts, not after. What behavior must be observable? What command, run against the result, would show it? What must still hold that could plausibly break?

Those questions are acceptance criteria, and their value is that they are worthless to fake. If “done” is defined as “this specific command prints this specific result against this contract,” the agent cannot satisfy it with a sentence. It has to produce the run. You have turned completion from a self-report into a test the agent has to pass, and you wrote the test while you still remembered what you actually wanted.

The cheapest version of this is to agree on the shape of the proof at the same time you agree on the task. It costs a few minutes up front and removes the far more expensive work of discovering, three merges later, that “done” meant nothing.

Done at speed

The objection is always speed. If every task has to carry a demonstration, doesn’t that slow the whole thing down, exactly where agents were supposed to make it fast?

It does the opposite, past the first few tasks. The expensive thing is not producing proof. The expensive thing is not having it: re-reading diffs to reconstruct whether something works, re-running tests by hand because you don’t trust the last green, discovering breakage in production that a captured run would have caught. Building with agents means the volume of “done” reports is enormous. When each one is just a sentence, the reports are worthless and you verify everything by hand. When each one carries its demonstration, you can trust the report and spend your attention on the few that fail. That is the whole reason trust, not output, is the bottleneck: completion you can believe is what lets you keep moving.

Where PaellaDoc fits

In PaellaDoc, a task does not reach done because an agent said so. It reaches done when the acceptance contract defined before the work has been executed against the real result and the evidence sits next to the change. The agent stops being the judge of its own completion and becomes the party that has to produce the demonstration. “Done” goes back to meaning what you always meant by it: it works, it didn’t break anything, and here is the proof.

The agents will keep reporting success in fluent, confident prose. Your job is to make that prose cost a demonstration. Done means done when the agent has to show it, not say it.

Frequently asked questions

Why do AI agents say a task is done when it isn’t?

Because “done” means different things to each of you. To the agent, done means it produced code that looks like it satisfies the request. To you, it means the behavior changed, nothing else broke, and there is proof of both. The agent clears its own bar in good faith and reports success, leaving you to cover the distance between “looks finished” and “is finished.”

How do I force an agent to prove it completed the task?

Take away its role as judge of its own work. Define, before the work starts, what would demonstrate completion: what command run against the result, printing what output, against which contract. Then have something other than the agent run that check and capture the result. The agent can still write “done,” but it no longer gets to decide whether that sentence is true.

What counts as proof that an agent finished the work?

Three things captured together: a command that actually ran, with its exit code; the real output it printed, not a summary like “looks good”; and the version of the acceptance contract it ran against. A checkbox is a claim wearing the costume of proof. A demonstration carries information about whether anything actually happened.

Does requiring proof of completion slow development down?

Past the first few tasks, it speeds it up. The expensive work is not producing proof, it is not having it: re-reading diffs, re-running tests by hand because you don’t trust the last green, catching breakage in production a captured run would have caught. When each “done” carries its demonstration, you trust the report and spend attention only on the few that fail.