Skip to content
Back to all field notes sdd · 7 min

Acceptance criteria agents can actually verify

"Fast and user-friendly" is not a criterion an agent can check. It is a criterion an agent can claim to have met. Here is the difference, and why it matters now.

field note 7 min

“The login should be fast and user-friendly.” An agent will read that, build a login, and report that the criterion is met. It is not lying. It genuinely cannot tell the difference between fast and slow, or friendly and hostile, because you did not give it one. You handed it a sentence to agree with, not a condition to check.

That is the core problem with most acceptance criteria in the agent era. They were written for a human reviewer who would apply judgment. An agent does not apply your judgment. It applies whatever the words literally permit, and vague words permit almost anything, including a confident claim of success over work that does not do what you meant.

Prose criteria fail agents in a specific way

When a person reads “user-friendly,” they run it through years of context and either accept the result or push back. The ambiguity is resolved by a mind that shares your intent. That is why loose acceptance criteria have survived for so long: a competent reviewer patched the gaps.

Hand the same criterion to an agent and the gap does not get patched, it gets filled with the agent’s own interpretation, and the interpretation is optimized to look done. This is the mechanism behind false success claims: the agent reports “tests pass, criteria met,” and the statement is true against the criteria as it understood them, which is not the criteria you meant. The looser the criterion, the more room there is between “what it claims” and “what you wanted,” and the agent will occupy all of it.

So the question is not “how do I write clearer criteria for the agent to read.” It is “how do I write criteria the agent cannot claim to have met without actually meeting them.” That question is the operational core of spec-driven development: a spec is only as strong as the criteria you can gate an agent on.

What makes a criterion mechanically verifiable

A verifiable criterion has one property: there is an unambiguous procedure that returns pass or fail, and the agent cannot produce a pass without the behavior being real. Three things get you there.

It names a concrete condition, not a quality

“Fast” is a quality. “Responds in under 200ms at the 95th percentile” is a condition. “User-friendly” is a quality. “A guest can complete checkout without creating an account” is a condition. The test for a good criterion is simple: could two people disagree about whether it passed? If yes, an agent will resolve that disagreement in its own favor.

It is stated as observable behavior

A criterion should describe something you can observe from outside the system, not an internal intention. “The code handles errors gracefully” is unobservable and unfalsifiable. “When the payment provider returns a 500, the user sees a retry prompt and no order is created” is observable. You can run it and watch. So can the agent, which means it can check itself against reality instead of against its own summary of its work.

It has a defined check

The strongest criteria come with the procedure attached: the input, the action, the expected result. “Given a cart with two items, when the guest completes the three steps, then an order exists and no card token is persisted.” That structure — Given-When-Then — is not new; it comes from behavior-driven development, where the point was always to write conditions that translate directly into executable checks. What changed is the stakes. When a human built the feature, a loose Given-When-Then was a helpful sketch. When an agent builds it and self-reports, the check has to be tight enough that passing it requires the behavior to exist.

Bad and good, side by side

The gap is easiest to see directly:

  • “Search should work well” → “A search for an exact product title returns that product as the first result.”
  • “The form should validate input” → “Submitting the form with an empty email field shows an inline error and does not send a request.”
  • “Performance should be acceptable” → “The product list renders in under one second with 500 items in the dataset.”
  • “Handle edge cases” → “An order with zero items cannot be submitted; the submit button is disabled and the API rejects a zero-item payload with a 400.”

Notice that the good versions are not longer because they are more detailed prose. They are more precise because each one names an input, an action, and an observable result. That is the whole move: replace qualities the agent can claim with conditions the agent must produce.

Claimable

  • Fast
  • User-friendly
  • Handles errors
  • Works well

Checkable

  • Under 200ms p95
  • Guest checks out
  • Retry shown on 500
  • Exact title first
Swap qualities an agent can claim for conditions it must produce and you can observe.

Criteria as the agent’s definition of done

Verifiable acceptance criteria are how you get an agent to prove completion instead of assert it. This is the same principle as done means done: a task is not finished because the agent says so, it is finished because a defined check passed against the real result. Criteria written as checkable conditions are exactly what that gate needs. Written as prose, there is no gate, only the agent’s word.

This is also why acceptance criteria belong in the spec, not in a reviewer’s head. A spec is the contract, and the acceptance criteria are the part of the contract that decides whether it was met. If they live only in prose that a human interprets, they cannot travel with the work, cannot be re-run when the code changes, and cannot stop the spec from drifting as the behavior moves. Verifiable criteria are what make a living spec able to tell you when reality has diverged from the contract, because you can run them again and watch them fail.

There is a limit worth stating plainly. Not every criterion can be reduced to an automated check today, and some genuinely need human judgment, like whether a flow feels right. The goal is not to pretend judgment away. It is to make every criterion that can be mechanical actually mechanical, so the human judgment is spent on the few things that truly need it instead of re-adjudicating “user-friendly” on every run.

Where PaellaDoc fits

Acceptance criteria only work as a gate if they are attached to the work and can be run against the result, not buried in a document a human is supposed to check by eye. PaellaDoc keeps the criteria connected to the spec, the code, and the evidence from each run, so “done” means a defined check passed and the proof is attached, not that an agent summarized its own work as complete. The criterion stops being a sentence to agree with and becomes a condition the work has to satisfy.

FAQ

Are acceptance criteria for agents different from acceptance criteria for people? The good ones are the same: concrete, observable, checkable. The difference is that people tolerate vague criteria by filling gaps with judgment, and agents do not. Writing for agents just forces the discipline that was always the right idea.

Do I have to write every criterion as Given-When-Then? No. Given-When-Then is a useful shape because it forces an input, an action, and a result, but any criterion that names a concrete, observable condition with a defined check works. The format matters less than the property: could the agent claim it without doing it?

What about criteria that need human judgment, like whether something feels good? Keep those explicit and separate. Some criteria genuinely need a person. The mistake is letting subjective ones hide among the mechanical ones, so the agent self-reports pass on everything. Make the mechanical ones mechanical and mark the human ones as needing review.