How to Write Acceptance Criteria for an AI Coding Agent

A vague ticket lets an agent guess. Here is a real before/after rewrite that turns "make it work well" into acceptance criteria an agent can actually check.

Steve Jefferson
Steve Jefferson
Developer Advocate
15 August 20261 min read

How to Write Acceptance Criteria for an AI Coding Agent

Acceptance criteria for an AI coding agent are the specific, testable conditions that define when a task is actually finished, not vague direction like "make the login flow better" or "handle errors properly." Hand an agent a task without them and you get code that compiles, looks plausible in a diff, and quietly does the wrong thing. The fix is to write criteria the way you'd write test assertions: concrete inputs, concrete expected outputs, edge cases named up front. Below is a real before and after rewrite, a reusable template, and why this step matters more with an agent than it ever did with a human teammate.

Why "make it work well" doesn't work on an agent

A vague ticket handed to a human developer usually survives contact with reality. They read between the lines, they message you to ask what "handle errors better" actually means, and they notice when a requirement contradicts how the rest of the app behaves before writing a line of code. An AI coding agent does none of that by default. It reads the ticket, picks the most statistically plausible interpretation of your words, and starts writing code, confidently, all the way through to a finished diff.

That's the core difference this guide is built around. Ambiguity given to a person becomes a question. Ambiguity given to an agent becomes an assumption, and the assumption ships. The agent isn't being careless. It did exactly what you asked, it just didn't know what you meant, and nothing in the process told it that mattered.

Before and after: the same bug, two different tickets

Here's a ticket that looks completely normal, the kind of one-liner typed into a tracker between meetings.

Before: "Improve checkout error handling. Users sometimes see a blank screen when payment fails. Make it work well and show a helpful message."

That reads like direction to a person. To an agent it's close to no direction at all. Which error, specifically? What counts as "helpful"? Does the cart survive the failure, or does the user start over? The agent has to invent answers to all three, and it will, without telling you it did.

Here's the same task rewritten with acceptance criteria an agent can check line by line:

After: Fix checkout so payment failures show a specific, recoverable error state instead of a blank screen.

  1. Given a Stripe decline (error code card_declined), the checkout page shows: "Your card was declined. Try a different payment method or contact your bank." No blank screen, no unhandled exception in the browser console.

  2. Given a payment request that times out (no response within 10 seconds), the page shows: "Something went wrong processing your payment. No charge was made. Please try again," and re-enables the Pay Now button.

  3. Given a dropped network request (fetch throws before a response), the same timeout message from criterion 2 displays.

  4. In every error case above, the cart contents and entered shipping address are preserved. The user does not re-enter them.

  5. Each error path has a test in checkout.spec.ts that mocks the failure and asserts the correct message renders.

  6. No error path leaves the Pay Now button spinner running indefinitely.

Six lines longer than the original ticket, and every one of them is something you, or the agent, can check mechanically: run this scenario, look for this string, confirm this behavior. Nothing in the after version depends on taste.

How to write acceptance criteria an AI coding agent can actually check

Good acceptance criteria share a shape regardless of the task: given a specific input or action, then a specific, observable result. That's the same given, when, then structure test writers have used for years, and it maps directly onto how an agent evaluates its own work, because it can write a test straight from the sentence.

  • Name the exact trigger. Not "when something goes wrong" but "when the Stripe request returns card_declined."

  • Name the exact observable output. Not "a helpful message" but the literal string, or the literal UI state that should appear.

  • Cover what happens around the happy path: what survives an error, what resets, what the user sees next.

  • Say what must not change. Agents will refactor adjacent code more readily than most human developers would; an explicit non-goal stops that before it starts.

  • Attach a way to verify each criterion, whether that's a specific test file, a manual repro script, or a screen to check by hand. If you want the agent to add coverage as part of the task, say so directly, the same way you would when writing tests that catch real bugs rather than tests that just confirm whatever the code already does.

A template you can paste into any ticket

You don't need to write this from scratch every time. A short template covers most tasks, and you can drop sections that don't apply to a given ticket.

Task: one sentence describing the change.

Context: why this matters, and which file, flow, or component it touches.

Acceptance criteria: a numbered list, each one a given, when, then statement with a concrete, checkable result.

Out of scope: what the agent should leave alone, named explicitly rather than assumed.

Definition of done: tests added and passing, existing tests still green, no new console errors, lint passes.

You won't need all five sections for a five-minute typo fix. But acceptance criteria and out of scope earn their keep on almost anything bigger than that, because they're the two things a human teammate would infer on their own and an agent won't.

Definition of done vs. acceptance criteria for AI agent tasks

The two get used interchangeably, but they answer different questions. Acceptance criteria describe the specific behaviors that must be true for this task: the checkout error messages, the preserved cart, the specific test file. A definition of done is the general bar every task has to clear no matter what it is: tests pass, lint is clean, no regressions in existing behavior, no unrelated files touched.

Keep the definition of done as a standing checklist, worth putting in your AGENTS.md file so it applies to every task without you retyping it, and write acceptance criteria fresh each time, because they're specific to whatever you're asking for right now.

Why this matters more for agents than for human developers

A confused human teammate stops and asks. They might message you, they might flag the ticket as unclear in standup, or they might just make a reasonable guess and mention it in the pull request so you can correct it early. An agent treats confusion as an instruction to fill the gap, silently, and keep going. There's no pause where the ambiguity becomes visible.

That gap compounds with scale. An agent can generate a lot of code fast, so a single wrong assumption at the top of a task doesn't stay contained to one function, it threads through every file the agent touches while building out the feature. By the time you're reviewing the diff, the wrong interpretation is load-bearing across the whole change, not a one-line fix.

This is also why acceptance criteria are a different tool from a bug report for an AI coding agent. A bug report documents something that's already broken, after the fact. Acceptance criteria are written before any code exists, to keep the wrong thing from getting built in the first place. Spend the extra five minutes upfront and you write far fewer bug reports later.

Common mistakes when writing acceptance criteria for AI agents

  • Vague adjectives instead of assertions. "Clean," "robust," and "works well" describe a feeling, not a check. An agent can satisfy the words without satisfying your intent.

  • No edge cases named. If you only describe the happy path, the agent builds the happy path and calls the task done, because nothing told it there was more to handle.

  • No stated non-goals. Without them, an agent will often "improve" unrelated code it happens to pass through, which turns a small task into a sprawling diff.

  • No verification step. If success is decided by reading the diff and hoping, you've quietly moved the acceptance criteria into your own head instead of onto the ticket.

  • Too many criteria at once, with the two or three that actually matter buried in a list of ten. Order them by what would actually break the feature if missed.

FAQ

What's the difference between acceptance criteria and a definition of done for AI agent tasks?

Acceptance criteria are specific to one task, the exact behaviors that make this change correct. A definition of done is a standing checklist that applies to every task regardless of what it is, things like tests passing and no new lint errors. Most tickets need both.

How specific should acceptance criteria be for an AI coding agent?

Specific enough that someone else could write a test from the sentence alone, without asking you a follow-up question. Use exact error codes, exact strings, exact field names, not adjectives. If a criterion could be satisfied two different ways and you'd only be happy with one of them, it isn't specific enough yet.

Can I just ask the agent to write its own acceptance criteria?

You can use it to draft a first pass, and it's often a decent starting point. But an agent writing its own acceptance criteria tends to describe whatever it would naturally build, which defeats the purpose. Have a human read and edit the draft before the agent starts implementing against it.

How do I spec a task for an AI coding agent when I don't know all the details yet?

Write down what you do know as concrete criteria, and mark the open questions explicitly, for example "confirm the exact error message copy with design before implementing." An agent treats silence as permission to assume, not as a signal to stop and ask, so an unmarked gap gets filled with a guess instead of a pause.

Do acceptance criteria replace code review for AI-generated code?

No. They narrow what review needs to check for intent, since you can verify each criterion directly instead of guessing whether the agent understood the ask. You still need a human pass for security, architecture, and the kind of judgment calls that don't fit in a checklist, the same way you'd want a human reviewing an agent's plan before it runs rather than trusting the plan blind. And picking the right AI coding agent for the job in the first place makes all of this easier, since some tools follow structured specs far more reliably than others.

How did this land?

About the author

Steve Jefferson
Steve Jefferson

Developer Advocate

Steve builds something with Swarmz every week and writes up what worked, what broke, and what he'd do differently. Tutorials and hands-on guides are his lane.

Share

Get the next post in your inbox

One email a month. Product updates, engineering posts, and the best of Built with Swarmz.

I agree to receive emails about AI building tips and Swarmz product news. Unsubscribe any time.