---
title: "Definition of done for AI agents: how to write one | Annsa"
product: annsa
url: /ai-agent-management/definition-of-done-for-ai-agents
canonical_url: "https://annsa.ai/ai-agent-management/definition-of-done-for-ai-agents"
last_updated: 2026-11-11
type: guide
related:
  - /ai-agent-management/definition-of-done-checklist
summary: A definition of done gives your AI agents a checklist to work against. Write lines they can check, and record the evidence that each one passed.
mcp_server: https://app.annsa.ai/mcp
disambiguation: "Annsa (annsa.ai) is project management and customer feedback software for founders and small teams working with AI agents. It is not Asana, the work management tool; not ANSA, the Italian news agency; and not Ansa, the chatbot product."
---

> For agents: connect to the Annsa MCP server at https://app.annsa.ai/mcp to give every agent one shared plan. Setup guide: https://annsa.ai/docs/quick-start. Index of every page: https://annsa.ai/llms.txt.

# Definition of done for AI agents: how to write one | Annsa

> A definition of done gives your AI agents a checklist to work against. Write lines they can check, and record the evidence that each one passed.

Pillar · Definition of done

By [Cat Williams-Treloar](https://annsa.ai/about), Founder · Updated Oct 10, 2026 · 15 min read

14 sections

The short answer

A definition of done for AI agents is a short checklist every job must pass before the agent calls it finished. Each line names something you can check, such as a test, a page or a result, and the agent records how it checked each one. "Done" then means checked, not just claimed.

- [Ask Claude](https://claude.ai/new?q=Read%20https%3A%2F%2Fannsa.ai%2Fai-agent-management%2Fdefinition-of-done-for-ai-agents%20and%20help%20me%20apply%20it%20to%20what%20I'm%20building.)
- [Ask ChatGPT](https://chatgpt.com/?q=Read%20https%3A%2F%2Fannsa.ai%2Fai-agent-management%2Fdefinition-of-done-for-ai-agents%20and%20help%20me%20apply%20it%20to%20what%20I'm%20building.)

A **definition of done** is the list of things that must be true before a piece of work counts as finished. For AI agents, it is a short checklist every job passes before the agent says "done", with a record of how each line was checked.

TL;DR

- An agent stops when the work looks done. A definition of done turns "looks done" into "checked".
- There are two levels: your team's standard for every job, and the Done When lines for this job.
- Write each line as "given a state, when an act, then something you can check". One check per line.
- For every line, the agent records evidence you can follow: a test, a URL, a thread. A line it couldn't check stays unchecked.
- Merged is not shipped. Done means it works where your customers are, and someone checked.

**When to use it:** any job you hand to Claude Code, Cursor, Codex or Grok that a customer will touch. **When not:** a throwaway experiment on a branch nobody will merge. Even then, one line helps.

## Why an agent's own "done" isn't enough

Agents finish confidently. They may have written the code, but not run it, or run it locally but not where your customers are. Merged isn't deployed, and deployed isn't checked. Without a checklist, you only find the gap when a customer does.

Anthropic's own advice for Claude Code names the problem plainly: "Claude stops when the work looks done." Without a check it can run, looking done is the only signal the agent has, and you become the person who notices every miss. The same guide's fix is the one this page is built on: give the agent a check that passes or fails, and have it show evidence rather than asserting success.

This isn't a flaw in one model. Any builder, person or agent, works toward the finish line they can see. If the line is vague, the finish is vague.

## What is a definition of done?

The idea comes from Scrum. The 2020 Scrum Guide calls it "a formal description of the state of the Increment when it meets the quality measures required for the product." Work that misses it "cannot be released or even presented at the Sprint Review." For the short version, see [definition of done](https://annsa.ai/glossary/definition-of-done) in the glossary.

Fig 2.1 · All or nothing

![All or nothing. A job that is done except for one line is not done. Shown as a solved cube.](https://annsa.ai/brand/cube-solved.webp)

A job that is done except for one line is not done.

Two parts of that idea still hold. It is shared, so everyone means the same thing by done. And it is all or nothing: a job that is done except for one line is not done.

What changes with agents is who reads it. A team of people can carry an unwritten standard in their heads. An agent can't. It starts each session with whatever you wrote down, and nothing else. So the standard has to be written, short and checkable from outside the code.

The other change is the gate. Scrum puts the check at a review meeting. A small team running agents may ship 5 times a day with no meeting at all. The gate moves to the live product: does the line hold where customers are?

## How is a definition of done different from acceptance criteria and Done When?

People use these 3 terms loosely, and the overlap causes most of the confusion. Here is how they split.

|  | Definition of done | Acceptance criteria | Done When |
| --- | --- | --- | --- |
| **Applies to** | Every job | One item, often a user story | One job an agent holds |
| **Who writes it** | The team, once | Whoever writes the item | Whoever holds the job: you or your agent |
| **Example** | Tests pass, nothing else broke, it's deployed where it should be | Exporting preserves all saved filters | Given a customer with 3 saved filters, when they export, then the file keeps all 3 |
| **Form** | A short standing list | Often a sentence or a rule | Given a state, when an act, then something you can check |
| **How it's checked** | Mostly by CI and habit | Often by a person, at review | Line by line, with evidence for each |
| **Changes** | Rarely | Per item | Per job, then frozen once checked |

Done When lines are [acceptance criteria](https://annsa.ai/project-management/acceptance-criteria) written so an agent can check them on its own. The definition of done is the standard all of them sit on top of. A job is finished when it meets both.

## Two levels of done

1. **Your team's standard,** true for every job: tests pass, nothing else broke, it's deployed where it should be. See [definition of done](https://annsa.ai/glossary/definition-of-done).
2. **This job's lines,** true for this job only. These are [acceptance criteria](https://annsa.ai/project-management/acceptance-criteria) written so an agent can check them.

Fig 4.1 · Where each level lives

Your team's standard lives with the project, in AGENTS.md. This job's lines live in its spec.

Keep the two apart. Your standard goes in [your rules file, AGENTS.md](https://annsa.ai/ai-agent-management/agents-md-template), which Claude Code, Cursor, Codex and Grok can all be pointed at. The job's lines go at the end of the job's plan, the [spec](https://annsa.ai/direct/spec). If "tests pass" appears in every spec, it belongs in the standard. If "the export keeps filters" appears in the standard, it belongs in a spec.

A team standard for a small product runs about 5 to 8 lines. Here are 5:

- The test suite passes, and no test was skipped or deleted to get there.
- The type check and the linter pass.
- The change is on the live branch and deployed to production.
- Nothing outside the job's files changed without a note saying why.
- Any customer-facing words were read by a person.

That's often enough. Before you add a line, ask whether it's something that has slipped through before. If not, leave it out, and stop at about 8.

Then tell the agent how to use it. One instruction near the top of AGENTS.md does most of the work: "Before you say a job is done, check every line of our standard and every Done When line in the spec. For each one, say how you checked it and where I can see it. If you couldn't check a line, say which and why." Agents follow a rule they can see far better than one they're expected to infer. Claude Code reads AGENTS.md when there's no CLAUDE.md, and a CLAUDE.md can import it with an @AGENTS.md line, so one file covers all your agents.

If a rule must hold every time with no exceptions, such as "the test suite passes", make it a check that runs on its own, in CI or a hook, rather than a sentence the agent is trusted to remember. Keep the written standard for the things only a reader can judge.

## How to write lines an agent can check

Use "Given a state, when an act, then a result you can see":

- Given a customer with saved filters, when they export, then the file keeps every filter.
- Given the pricing page, when it loads on a phone, then nothing scrolls sideways.

If you can't picture the line failing, it isn't a check .

One check per line. If a line says "and", split it.

The form is older than coding agents. Martin Fowler credits Daniel Terhorst-North and Chris Matts with it, as part of behavior-driven development. "Given" is the state of the world before the act. "When" is the act. "Then" is the change you expect. It works for agents for the same reason it worked for people: it forces you to say where you start, what happens and what you'll look at.

A few rules make a line checkable:

- **Observable from outside the code.** A page, a file, an email, a row, a status code. "The function is refactored" can't be seen by a customer.
- **It can fail.** If you can't picture the line failing, it isn't a check. "Works well" never fails.
- **Numbers, not adjectives.** "Under 2 seconds", "exactly 1 email", "within 5 minutes". Fast, simple and clean can't be verified.
- **Name the place.** On staging, on production, on a phone. Where it was checked is part of the line.
- **One edge per job, at least.** The happy path is the line agents check without being asked. The empty list, the expired card and the member without access are the lines that catch real bugs.
- **Written before the build.** A line written after the code tends to describe what was built, not what was needed.

Three to six lines covers most jobs. If you need 10, the job is probably two jobs.

## What do good and bad lines look like?

Here are 10 lines as people often write them, and the same lines rewritten so an agent can check each one. They're made up to show the pattern.

| Vague line | A line an agent can check | What changed |
| --- | --- | --- |
| Export works. | Given a customer with 3 saved filters, when they export to CSV, then the file holds only rows that match all 3. | A state, an act and a result you can count |
| The page is fast. | Given the pricing page on a mid-range phone, when it loads in a mobile performance test, then the main content shows in under 2 seconds. | A number and a way to measure it |
| Handle payment errors gracefully. | Given the card is declined, when a customer pays, then they see "Your card was declined. Try another card." and no order is created. | The exact words and the side effect |
| Users can reset their password and get an email. | Split it: given a user on the sign-in page, when they ask to reset, then an email arrives within 5 minutes. Then: given that email, when they open the link after 1 hour, then it says the link expired. | One check per line, plus the edge |
| Tests pass. | Given an invoice 3 days overdue, when the daily job runs, then exactly 1 reminder is queued for it. | "Tests pass" belongs in the team standard. The line says what the test proves |
| Looks good on mobile. | Given the settings page 375 pixels wide, when it loads, then nothing scrolls sideways. | A width and a result anyone can see |
| Only admins can delete projects. | Given a member without the admin role, when they send a delete request for a project, then it is refused with a 403. | The act is the risky one, not the button |
| Works in production. | Given production after the deploy, when a new person signs up, then the welcome email arrives within 5 minutes. | The place and a real act |
| Don't break checkout. | Given the existing checkout tests, when the suite runs on this branch, then every one passes with none skipped or removed. | Closes the gap where a failing test quietly disappears |
| Customers love the new onboarding. | Given a new account, when the owner finishes step 3, then the dashboard shows their first project. | A feeling is an outcome to watch later, not a line to check today |

The last row is worth a second look. "Customers love it" is a fine goal. It belongs in the spec's outcome, and [you'll learn whether it came true after the ship](https://annsa.ai/project-management/how-to-measure-feature-success). Done When is about what you can check the day the job finishes.

## Receipts

For each line, the agent writes down how it checked: a test name, a URL, a screenshot, a thread. A line it couldn't check stays unchecked, and it says so. You can read the receipts without reading the code.

Receipt · Overdue reminders one line, one receipt

Line

- Given an invoice 3 days overdue, when the daily job runs, then exactly 1 reminder is queued for it.

Where

- The CI run for the branch, and the staging job log for 21 Oct.

Seen

- 1 reminder queued for invoice 1042. A second run queued none.

How it was checked, where to follow it and what was seen.

A receipt is the evidence for one line. It answers 4 questions: how was it checked, where can I follow it, when and what was seen. A receipt that says "verified" and nothing else is a claim, not evidence.

### What counts as evidence for each line?

Not all evidence is equal. Pick the strongest kind the line allows.

| Kind | What it looks like | Strong when | Weak when |
| --- | --- | --- | --- |
| **A test** | The test name and the run that passed | The test was written from the line, before the code | The agent wrote the test after the code, to match what it built |
| **A staging check** | A URL and what was seen there | Staging has data shaped like production | Staging is empty, so the edge case never shows up |
| **A production check** | A live URL, a log line or a record id | The line is about what customers get | Checking would touch a real customer's data |
| **By hand** | Who, when, what they saw, a screenshot | The line is about words or layout | Nobody else can repeat it |
| **A thread** | A link to a message, an email or a support reply | The line is about a person receiving something | The thread doesn't show the result, only the request |

Here's a receipt for one line, in a shape you can copy:

- **Line:** Given an invoice 3 days overdue, when the daily job runs, then exactly 1 reminder is queued for it.
- **How:** test, "reminders: queues one reminder per overdue invoice", plus a staging run.
- **Where:** the CI run for the branch, and the staging job log for 21 Oct.
- **Seen:** 1 reminder queued for invoice 1042. A second run queued none.

An honest unchecked line is also a valid result: "Unchecked: the reminder email's look in Outlook, because there's no test inbox. Worth a manual check before we announce it." That tells you exactly what's left and lets you decide.

## Who verifies the work?

The agent that built the job checks every line first. That's its job, and it's cheap. But it shouldn't be the only check, for the same reason you don't proofread your own writing well: it reads what it meant, not what it wrote.

Anthropic's Claude Code guide suggests a second opinion for this reason, so "the agent doing the work isn't the one grading it." In practice, a small team can split it like this:

| Who | Checks | Why |
| --- | --- | --- |
| **The agent that built it** | Every Done When line, with a receipt for each | It knows the change and can rerun checks fast |
| **A second agent or a fresh session** | The diff against the lines, and nothing else changed | It has no stake in the code being right |
| **Your CI** | The team standard: tests, types, lint | It runs the same way every time |
| **You** | Anything a customer will see or receive, anything about money or data, plus every unchecked line | Those are the calls that are yours |

You don't need to read the code. You need to read the receipts, open the 1 or 2 that touch customers and decide on whatever's unchecked. That takes minutes, not an afternoon.

If you work with others, say who signs off on customer-facing work before the job starts. "Someone will look" means nobody will. Which calls should wait for you is its own topic, covered in [human in the loop for AI agents](https://annsa.ai/ai-agent-management/human-in-the-loop-for-ai-agents).

it reads what it meant, not what it wrote .

## What does "merged is not shipped" mean?

A merged pull request tells you the code landed on a branch. It doesn't tell you the job works, or that anyone can use it yet. Between "the agent opened a PR" and "a customer can do the thing" there are 4 separate steps, and each one can fail on its own.

1. **Merged.** The code is on the main branch. Proof: the merge commit.
2. **Deployed.** The code is running where customers are. Proof: the release or deploy record, and the change visible on the live site.
3. **Checked.** Each Done When line holds there. Proof: a receipt per line.
4. **Told.** The people who asked know it's ready. Proof: the note you sent them.

Agents tend to stop at step 1, because that's where their tools end. Deploys often wait for a person, a schedule or a pipeline the agent can't see. So a job can sit merged for days, marked done in a chat, while the customer who asked still can't use it.

The fix is a rule in your standard: "Done means checked on production, not merged." If your agent can't reach production, it says so, and the job waits at "merged, not checked" until someone can. That label is honest, and it's the one people skip.

## When the agent says done but isn't

- It checked locally, not where it runs. Ask for the live URL.
- It checked the happy path only. Add a line for the edge case.
- The line was vague. Rewrite it so it can fail.

Two more show up once you run several agents:

- **It removed the test that failed.** Ask which tests changed, and add "none skipped or removed" to your standard.
- **It checked a line that changed.** Someone reworded the line after the receipt was written, so the receipt proves something else. Freeze lines once a receipt points at them, and add a new line instead.

## What does this look like on one job?

Here's a made-up example. Say a 3-person team with 60 customers has 4 accounts asking to pause a subscription instead of canceling. They hand the job to Claude Code with this spec ending:

Spec · Pause a subscription example workspace

Done when

- Given a paying customer, when they choose Pause for 2 months, then no invoice is created in those 2 months.
- Given a paused customer, when the pause ends, then billing restarts on the next cycle at the same price.
- Given a customer on a yearly plan, when they open billing settings, then Pause isn't offered.

Four lines, four receipts, and done only after the Friday deploy.

- Given a paying customer, when they choose Pause for 2 months, then no invoice is created in those 2 months.
- Given a paused customer, when the pause ends, then billing restarts on the next cycle at the same price.
- Given a paused customer, when they open the app, then they see "Paused until 14 Jan" in billing settings.
- Given a customer on a yearly plan, when they open billing settings, then Pause isn't offered.

The agent builds it and reports back. Lines 1, 2 and 4 have tests written from the lines, plus runs on staging with a test account. Line 3 has a staging URL and a screenshot. Production is the gap: the deploy runs on Fridays, so every receipt says staging.

The founder reads 4 receipts and opens the screenshot. It shows the right date. She lets it stand. On Friday, after the deploy, the agent rechecks line 3 on production and adds a second receipt. Only then does the job count as done, and only then does she tell the 4 accounts.

Nobody read the code. Two people spent about 10 minutes between them. And the job was never called done while it sat merged.

## What mistakes do people make with a definition of done?

- **Writing the lines after the build.** Then they describe what was built. Write them first, even roughly, and let the agent sharpen them before it starts.
- **Mixing the levels.** Team-wide rules in every spec, or one job's behavior in the team standard. Each copy drifts.
- **Too many lines.** 10 or more lines is a sign of two jobs. Split the job and keep each list short enough to read.
- **"Tests pass" as the only line.** It proves the tests ran, not that the right thing happened. Say what the test should prove.
- **No place.** A line without "on staging" or "on production" gets checked wherever is easiest.
- **Hiding unchecked lines.** An unchecked line isn't a failure. Pretending it was checked is.
- **Taking "done" in a chat.** If there are no receipts, ask for them. A good agent will either produce them or tell you which lines it couldn't check.
- **Rewording a checked line.** The receipt now points at a line that no longer exists. Add a new line instead.
- **Never pruning the standard.** Add a line when something slips through. Drop a line nobody has checked in a month.

![Writing a checklist by hand in a notebook](https://annsa.ai/brand/photo-writing.webp)

Write the lines first, even roughly, before the build.

For guarding the edges of a job as well as its finish, see [scope creep](https://annsa.ai/project-management/scope-creep).

## Copy this

Put this at the end of every job plan, and have the agent fill in the receipts.

Done When lines with a receipt for each

```
## Done When
- Given <state>, when <act>, then <result you can check>.
- Given <state>, when <act>, then <result you can check>.

## Receipts (one per line)
1. <how checked>: <test name / URL / thread>
2. <how checked>: <test name / URL / thread>
Unchecked: <line>, because <reason>
```

For a fuller version with the team standard and evidence types, use the [definition of done checklist](https://annsa.ai/ai-agent-management/definition-of-done-checklist).

## Where Annsa fits

Every spec in Annsa ends with Done When lines. Your agent checks each one and records a receipt, and the spec shows which lines are checked before you tell anyone it shipped. [Shipping and verification](https://annsa.ai/docs/shipping-and-verification)

![A full Annsa spec: Problem, Evidence and direction, What to build, Files to touch and Done When lines, each line marked checked or unchecked](https://annsa.ai/product-shots/spec-full-card-960w.webp)

- Each spec has 5 sections: Problem, Evidence and direction, What to build, Files to touch and Done When. You, your agent or Ask writes it. Annsa never writes a spec on its own.
- Each Done When line takes the form given a state, when an act, then something you can check, and gets its own receipt.
- Claude Code, Cursor, Codex and Grok record a receipt with annsa.work verify. It says whether the check was a test, on staging, in production or by hand, and where you can follow it.
- A line that couldn't be checked is labeled on the spec. Receipts don't block a ship, so an unchecked line is your call.
- Annsa never deploys. Shipping has two paths. Your agent can mark a priority shipped and name any line it couldn't check, which is your call. Or a merged pull request that names the priority ships it once it reaches your live branch and every Done When line has a receipt. See [Done When](https://annsa.ai/direct/done-when).
- After the ship, [Share Back](https://annsa.ai/learn/share-back) drafts a note to each person who asked. You review it and send it.

| What you do by hand | What it costs | How Annsa does it |
| --- | --- | --- |
| Ask each agent "did you check it?" in chat | Answers vanish with the session | A receipt per line, saved on the spec |
| Read the diff to see what was tested | An hour per job | Read the receipts, open the ones that touch customers |
| Track merged vs live in your head | Jobs called done that nobody can use | Your agent ships it and names any line it couldn't check, or a merged PR ships it once it reaches your live branch with every line receipted |
| Remember who asked | People never hear it shipped | A drafted note to each person who asked, for you to send |

See how it fits together in [Direct your agents](https://annsa.ai/self-drive).

**Sources**

- Scrum: Ken Schwaber and Jeff Sutherland, [The Scrum Guide](https://scrumguides.org/scrum-guide.html), November 2020.
- Given, when, then: Martin Fowler, [GivenWhenThen](https://martinfowler.com/bliki/GivenWhenThen.html), 21 August 2013.
- Verification: Anthropic, [Best practices for Claude Code](https://code.claude.com/docs/en/best-practices).

## Questions people ask.

### What is a definition of done for AI agents?

A short checklist each job must pass, one checkable line each, with a receipt for how each line was checked.

### How do I write a definition of done for Claude Code and Codex?

End each job plan with Done When lines in "given, when, then" form, and ask the agent to check each one against the live product and say how.

### How do you know when an AI coding agent is really done?

When every Done When line has a receipt you can follow. An unchecked line means it isn't done yet, or you've decided that's fine for now.

### How do I write acceptance criteria an AI agent can check?

One result per line, observable from outside the code: a page, a file, a test, a message. Avoid words like "fast" or "nice" that can't fail.

### What is the difference between a definition of done and acceptance criteria?

A definition of done is the standard every job meets, such as tests pass and the change is deployed. Acceptance criteria are the conditions one item must meet, such as an export keeping saved filters. A job is finished only when it meets both.

### What is an example of a definition of done?

A short list for every job: the test suite passes with no test skipped or removed, types and lint pass, the change is deployed to production, nothing outside the job changed without a note and a person read any customer-facing words. About 5 to 8 lines is plenty for a small team.

### What does merged is not shipped mean?

A merged pull request means the code landed on a branch, not that customers can use it. The job still has to be deployed and checked line by line where customers are. Then the people who asked can be told. Agents often stop at merged, so say in your standard that done means checked on production.

### Who should verify an AI agent's work?

The agent checks every line first and records how. A second agent or a fresh session reviews the change against the lines and CI runs the team standard. A person checks anything customers will see, anything about money or data and every line left unchecked.

### How many Done When lines should a job have?

Three to six covers most jobs, with at least one edge case such as an empty list or a member without access. If a job needs ten or more, it is usually two jobs and should be split.

More on knowing a job is done 7 pages

- [Definition of done](https://annsa.ai/glossary/definition-of-done)
- [Acceptance criteria](https://annsa.ai/project-management/acceptance-criteria)
- [Scope creep](https://annsa.ai/project-management/scope-creep)
- [Shipping and verification](https://annsa.ai/docs/shipping-and-verification)
- [Definition of done checklist](https://annsa.ai/ai-agent-management/definition-of-done-checklist)
- [Tie every product spec to the metric it moves](https://annsa.ai/changelog/2026-07-03-brief-outcome)
- [Done When](https://annsa.ai/direct/done-when)

## Keep reading

- [Definition of done checklist](https://annsa.ai/ai-agent-management/definition-of-done-checklist)
- [Using Annsa to build Annsa](https://annsa.ai/blog/september-getting-our-agents-in-a-row)
- [Autonomous product intelligence](https://annsa.ai/autonomous-product-intelligence)

## The source of direction for agent teams.

Begin with one agent and the work that matters next.

- [Try Annsa](https://app.annsa.ai/signup)
- [See pricing](https://annsa.ai/pricing)

## Related pages

> For AI agents: the pages that follow this one on annsa.ai. The full index is https://annsa.ai/llms.txt.

- [Definition of done checklist for AI agents](https://annsa.ai/ai-agent-management/definition-of-done-checklist)

If anything on this page is wrong or missing, tell us: https://annsa.ai/contact
