What are acceptance criteria?
Acceptance criteria are the conditions one task has to meet before it can be closed. Microsoft's guidance for the Agile process in Azure Boards describes the Acceptance Criteria field the same way: "Provide the criteria to be met before the bug or user story can be closed." It adds two practical points. Write them "before work begins", and use them "as the basis for acceptance tests" to judge whether an item is complete (Microsoft Learn, Agile process workflow).
A good criterion describes a result you can observe, not a way of building it. "Submitting [email protected] shows an error and creates no account" is a criterion. "Use a regex for the email check" is an instruction about implementation, and it belongs in the context, if anywhere. Criteria usually sit under a user story, but they work the same way for a bug, a chore or any card on a board.
How are acceptance criteria different from a definition of done?
Acceptance criteria are specific to one task. A definition of done is shared by every task. The 2020 Scrum Guide defines the Definition of Done as "a formal description of the state of the Increment when it meets the quality measures required for the product." The Scrum Guide does not use the term acceptance criteria. It comes from wider agile practice, which is why tools such as Azure Boards define it themselves.
| Point | Acceptance criteria | Definition of done |
|---|---|---|
| Applies to | One task, story or bug | Every item the team finishes |
| Answers | Does this task do what was asked? | Does this work meet our quality bar? |
| Written by | Whoever writes the task, with the person asking for it | The team or the organization, once, then reused |
| Example | "Submitting [email protected] shows an error and creates no account" | "Tests pass, code is reviewed, docs are updated" |
A task is finished when it meets both. Our glossary entry on the definition of done covers the team-wide side. The rest of this post is about the per-task side, and about writing it for an agent.
What formats can acceptance criteria take?
Two common formats are a checklist of rules and Given-When-Then scenarios. Pick the one that makes each criterion easiest to check.
A checklist is a short list of statements, each true or false when the work is done. It suits most cards because it is quick to write and quick to read:
- Submitting "[email protected]" shows "Enter a valid email" under the email field.
- No account is created for an invalid address.
- Valid addresses still sign up as before.
Given-When-Then writes a criterion as a scenario. Martin Fowler's GivenWhenThen note credits it to Daniel Terhorst-North and Chris Matts, who developed it as part of behavior-driven development. In Cucumber's Gherkin reference, Given steps "describe the initial context of the system", When steps "describe an event, or an action", and Then steps "describe an expected outcome, or result". An example rule as a scenario:
Scenario: Reject an email address with no domain name Given the sign-up form is open When someone submits "[email protected]" as their email Then the form shows "Enter a valid email" under the email field And no account is created
Given-When-Then is worth the extra words when the starting state matters, for example a logged-out user, an expired token or an empty board. If your project runs Gherkin files as tests, an agent can turn the scenario straight into a test.
Why do AI agents need acceptance criteria?
Because an agent stops when the work looks done, and acceptance criteria are what turn "looks done" into a check. Anthropic's Claude Code best practices put it plainly: "Claude stops when the work looks done. Without a check it can run, 'looks done' is the only signal available, and you become the verification loop..." Their advice is to give the agent something that produces a pass or fail, such as a test suite, a build exit code, a linter or a screenshot to compare.
GitHub makes a related point about its coding agent. Its guide to getting the best results from Copilot cloud agent lists what an ideal task includes. One item reads: "Complete acceptance criteria on what a good solution looks like (for example, should there be unit tests?)." The guide also says it is useful to "think of the issue you assign to Copilot as a prompt." As of October 2026, both vendors treat the task text as the agent's brief. Anthropic stresses a check the agent can run, and GitHub stresses stating what a good solution looks like.
Criteria matter at least as much for agents as for people. A person who is unsure what done means usually asks. An agent working alone may fill the gap with its best guess and keep going, and you find out at review.
How do you write acceptance criteria an agent can check?
Give every criterion an observable result and the check that proves it. Six rules cover most cards:
- One result per line. If a line has "and" in the middle, it is probably two criteria.
- Name the check. A test file, a command and its expected exit code, a URL and what it should show. "Check: npm test passes" beats "should be tested".
- Include the failure case. Agents can miss failure cases unless you name them. Spell out what should happen with bad input, an empty list or a missing permission.
- Say what must not change. Anthropic's guidance says the most useful specs "name the files and interfaces involved, state what is out of scope, and end with an end-to-end verification step". An "unchanged" criterion keeps a helpful agent from tidying code you did not ask about.
- Point to the place. GitHub's list ends with "Directions about which files need to be changed." A path saves the agent a search and keeps it in the right part of the codebase.
- Mark the judgment calls. Some criteria need a person, such as "the error message reads naturally". Keep them, but label them for the reviewer so the agent does not pretend to have checked them.
Here is an example of how vague criteria turn into checkable ones:
| Vague | Checkable |
|---|---|
| Make the sign-up form better | Submitting "[email protected]" shows "Enter a valid email" and creates no account |
| Add tests | tests/signup.spec.ts has a test for the invalid-email case, and npm test passes |
| Follow our code style | npm run lint exits with code 0 |
| Don't break anything | The existing sign-up tests still pass, and the sign-up API is unchanged |
| Looks good on mobile | At 375 px wide the form fits without sideways scrolling; screenshot in the hand-off comment (reviewer checks) |
Where should acceptance criteria go on a Flux card?
Put them in the card description. A Flux card has a description and a separate checklist section, and not every connection shows an agent both. Here is what each one returns, checked against the Flux server code in October 2026:
| Part of the card | MCP get_card | REST GET /api/cards/{cardId} |
|---|---|---|
| Title, description, priority, due date | Yes | Yes |
| Comments | Yes: text and time, oldest first, without author names | Yes, with author names |
| Checklist items and whether each is done | No | Yes |
| Assignees | No | Yes, as IDs |
So an agent connected through the Flux MCP server (Claude Code, Cursor, Codex and other MCP clients) reads the description but never sees criteria kept in the checklist section. The description editor has its own checklist button, which puts checkboxes inside the description. MCP agents read them as part of the description text. The list_cards tool also returns each card's description, so an agent scanning a column sees the criteria before it opens a card.
Two details to know. Descriptions written in the Flux app are saved as HTML, so an agent reads the text with HTML tags around it. Descriptions sent as Markdown through the API or MCP stay Markdown until someone edits and saves them in the app. The app shows Markdown formatted, with read-only checkboxes.
If your agent is a script or CI job on the REST API instead, it can read the checklist and tick items itself. Checklist changes made through the REST API are recorded in the card's activity log, under the name of the person who created the API key:
# Read the card, including its checklist (API key with the Read scope)
curl -sS https://flux.umin.ai/api/cards/CARD_UUID -H "Authorization: Bearer $FLUX_API_KEY"
# {"id":"CARD_UUID", ..., "checklist":[{"id":"ITEM_UUID","text":"...","done":false, ...}, ...]}
# Tick one item (API key with the Write scope)
curl -sS -X PATCH https://flux.umin.ai/api/cards/CARD_UUID/checklist \
-H "Authorization: Bearer $FLUX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"itemId":"ITEM_UUID","done":true}' A card template for agent tasks
Use one shape for every agent card, so agents always find the criteria in the same place. Paste this into the description, or have the agent that files cards use it with create_card:
## Goal One or two sentences: what changes for the user, and why. ## Context - Where to look: files, routes or pages - Related cards, links or error messages ## Acceptance criteria - [ ] An observable outcome. Check: the command, test or URL that proves it - [ ] The edge or failure case. Check: ... - [ ] What must not change. Check: ... ## Out of scope - Anything the agent should leave alone ## Hand-off Post one comment with each criterion marked pass or fail and its evidence (the command and its output, the test name, a screenshot link). Then move the card to Needs review.
The same template, filled in for an example fix (the file names are placeholders):
## Goal Stop sign-ups with malformed email addresses, so new users get a clear error instead of a confirmation email that never arrives. ## Context - Form: src/signup/SignupForm.tsx - Tests: tests/signup.spec.ts ## Acceptance criteria - [ ] Submitting "[email protected]" shows "Enter a valid email" under the field and creates no account. Check: a new test in tests/signup.spec.ts - [ ] Submitting "[email protected]" still creates the account. Check: the existing happy-path test still passes - [ ] npm test and npm run lint both exit with code 0 - [ ] No change to the sign-up API or the confirmation email ## Out of scope - Checking that the domain can receive mail ## Hand-off Comment with pass or fail per criterion and the test output, then move the card to Needs review.
Then add a matching rule to the agent's instructions, for example in CLAUDE.md or AGENTS.md:
Before you start a card, read it with get_card and find its "Acceptance criteria" section. If a criterion is unclear or has no check you can run, post a comment asking about it and leave the card where it is. When you finish, run every check. Post one comment that starts with your agent name and lists each criterion as pass or fail with its evidence. Then move the card to Needs review. Do not edit the criteria, and never move a card to Done.
The comment is the record of what the agent checked. As of October 2026, changes made over MCP are not written to the Flux activity log, and comments made with an API key appear under the key owner's name. That is why the rule asks the agent to start each comment with its own name and to show evidence. Anthropic's guide gives the same advice for Claude Code: "Have Claude show evidence rather than asserting success."
Who checks the criteria, the agent or a person?
Both, in that order. The agent runs every check it can and reports the results. A person reads the evidence, checks the judgment calls and moves the card to Done. On a Flux board that is a Needs review column between In Progress and Done, the layout we describe in the kanban board for AI agents guide.
Flux's role here is limited. Flux stores the criteria and the evidence, and shows everyone on the board where the card is. It does not read your criteria, run your tests or stop an agent with a write key from moving a card to Done. The review column is a rule in the agent's instructions, not a lock. If you want a check enforced inside the agent itself, Claude Code's best practices describe a Stop hook that runs your check as a script and blocks the turn from ending until it passes, up to a cap on consecutive blocks.
When several agents share one board, clear criteria also make review faster, because every hand-off comment has the same shape. For the rest of that setup, see how to coordinate multiple AI coding agents.