Acceptance Criteria
beta · Family delivery-docs · Phase deliver · Sizes lean, full · ~1,000 tokens
Defines the conditions a user story must satisfy to be accepted, so “done” is verifiable and shared rather than left to interpretation.
Fast reference for the Acceptance Criteria bundle. For the full reasoning, history, and sources, read
acceptance-criteria_companion.md.
When to use
Section titled “When to use”- To define, before work starts, the conditions that confirm a specific story is done and correct.
- When QA and engineering need a concrete, shared target.
- When you want “done” to be a fact, not an interpretation.
When NOT to use
Section titled “When NOT to use”- You need a universal, team-wide completion standard. That is the Definition of Done, not AC.
- You need whole-feature scope, metrics, and non-goals. Use a PRD.
- The story is so trivial a one-line note suffices. Do not manufacture ceremony.
Pick a variant
Section titled “Pick a variant”- Lean (default): a rule checklist plus story reference and scope. For straightforward stories.
- Full: adds Given/When/Then scenarios, edge cases, and non-functional criteria. For behavior-heavy or risky stories, and when AC will seed automated tests. Grow lean into full by adding sections; never reorder the shared ones.
The rubric
Section titled “The rubric”Score each 0, 1 or 2. Under 10 out of 14 and “done” will be settled in the review meeting rather than before the work started, which is the one outcome this document exists to prevent.
Which rows apply to what. This bundle ships two variants, and one row grades a section that only the full variant carries, so scoring lean against all seven would penalise the choice of variant rather than the quality of the criteria.
| Variant | Rows that apply | Maximum | Score against |
|---|---|---|---|
| full | all 7 | 14 | 10 |
| lean | 1-5, 7 (it carries no Scenarios section) | 12 | 9 |
Both thresholds sit above two-thirds of the available points; neither is a bare pass mark.
| # | Criterion | 0 | 1 | 2 |
|---|---|---|---|---|
| 1 | Observable outcome, not implementation | Criteria name components, technologies or internal mechanisms | Mostly behavioural, but at least one criterion says how rather than what | Every criterion states something a user could watch happen, and none names a technology |
| 2 | Verifiable pass or fail | Criteria rest on words like “fast”, “intuitive” or “robust” with no bar | Verifiable in principle, but the tester has to choose the bar themselves | A tester who has never met the author can mark every criterion pass or fail without asking anyone |
| 3 | Unhappy paths covered | Happy path only | One or two error cases, chosen because they were easy to think of | The failure this story is most likely to hit in production is named, with what should happen when it does |
| 4 | No overlap with the Definition of Done | Restates universal checks such as tests passing or code reviewed | Mostly story-specific, with one or two DoD items carried in | Every criterion is true of this story and would be meaningless pasted onto the next one |
| 5 | Story-specific non-functional bars | A bar plausibly applies and none is stated | A bar is mentioned without a number or a named standard | A number or a named standard scoped to this story, or an explicit statement that none applies and why |
| 6 | One behaviour per scenario (full only) | One scenario chains several behaviours through repeated “And” steps | Scenarios are separated, but at least one “When” contains more than one action | Every scenario tests one behaviour and its “When” is a single action |
| 7 | Out of scope is stated | No scope statement, so a reader cannot tell an omission from a decision | Scope stated in general terms | Names something a reader would reasonably have expected here and says it is deliberately excluded |
Named anti-patterns (the usual wrecks)
Section titled “Named anti-patterns (the usual wrecks)”- Implementation, not behavior. “Uses a Redis cache” instead of “loads in under one second.”
- Duplicating the Definition of Done. Restating universal checks as story criteria.
- Happy path only. No edge or negative cases.
- Unverifiable criteria. Conditions you cannot mark pass or fail.
- Mega-scenario. One Given/When/Then with many “And” steps testing several behaviors.
- Criteria as afterthought. Written after the code, describing what was built, not what was needed.
The artifacts
Section titled “The artifacts”acceptance-criteria_template-lean.md · ~1,000 tokens
---title: "{{title}}"doc_type: acceptance-criteriasize: leanowner: "{{owner}}"status: draftdoc_version: "{{doc_version}}"created: "{{date}}"updated: "{{date}}"related_links: []source_template: acceptance-criteriasource_template_version: 0.1.1---
<!--LEAN ACCEPTANCE CRITERIA. A short, rule-based checklist for one story: the conditions that must betrue for it to be accepted. Use this for a straightforward story. To grow it into full criteria, ADDsections (see acceptance-criteria_template-full.md); never rename or reorder the ones below (the fullvariant is a strict superset of this one). Write criteria as observable outcomes, from the user'spoint of view, not as implementation steps.
HOW TO FILL THIS IN1. Read the comment under each heading: WHAT it wants, WHY it matters (with a pointer into acceptance-criteria_companion.md for the deep reasoning), guiding questions to ASK, a GOOD and a WEAK example, and the TRAP to avoid.2. Replace each {{placeholder}} with your content.3. If a section does not apply, write "N/A" and one line of why, rather than deleting it.4. Before you ship: self-grade against acceptance-criteria_guide.md, then DELETE every HTML comment. They are guidance, not content.-->
# {{title}}
## Story reference
<!-- WHAT Which user story or backlog item these criteria gate: a link, or the story statement itself. Name the user and the goal. WHY AC are meaningless without the story they accept; "accepted into what" must be unambiguous. Deep dive: acceptance-criteria_companion.md section 3 (Anatomy > Story reference). ASK Which story do these gate? Is it linked or quoted so a reviewer can find it? Are the user and goal clear? GOOD "As a recurring analyst, I want to set one of my saved views as the default for a dashboard, so that the dashboard opens the way I work instead of in its generic default state. (See user-stories_example.md.)" WEAK "Saved views feature." (no user, no goal, no link; a reviewer cannot tell what is being accepted) TRAP Free-floating criteria with no parent story. -->
{{story_reference}}
## Acceptance criteria
<!-- WHAT The rule-based conditions that must hold for the story to be accepted, as a checklist of observable, pass/fail outcomes. WHY Discrete rules are clearest as a list, and each must be markable pass or fail; a criterion you cannot mark is not finished. Deep dive: acceptance-criteria_companion.md section 3 (Anatomy > Acceptance criteria). ASK Is each row a single verifiable claim? Could QA mark it pass or fail as written? Is it what the user observes, not how it is built? GOOD "Marking a new view as default un-marks the previous default automatically." WEAK "Defaults are stored efficiently in a Redis cache." (implementation detail, not an observable outcome the user can verify) TRAP Implementation, not behavior: criteria that describe how it is built rather than what the user can observe. -->
- [ ] {{criterion_1}}- [ ] {{criterion_2}}
## Out of scope and notes
<!-- WHAT What these criteria deliberately do not cover, plus assumptions and links to adjacent stories. WHY It lets a reviewer tell an omission from a decision. Deep dive: acceptance-criteria_companion.md section 3 (Anatomy > Out of scope and notes). ASK What did you choose not to cover? What assumptions do the criteria rest on? Where do adjacent concerns live? GOOD "Out of scope: team-level defaults (a Team Lead setting a default for everyone) are a separate, open decision. Assumes per-user preference storage (shipped Q1)." WEAK Leaving this blank. (silence on scope makes an omission read as a deliberate decision) TRAP No scope statement, so omissions read as decisions. -->
{{out_of_scope_and_notes}}acceptance-criteria_template-full.md · ~1,950 tokens
---title: "{{title}}"doc_type: acceptance-criteriasize: fullowner: "{{owner}}"status: draftdoc_version: "{{doc_version}}"created: "{{date}}"updated: "{{date}}"related_links: []source_template: acceptance-criteriasource_template_version: 0.1.1---
<!--FULL ACCEPTANCE CRITERIA. The comprehensive variant, and a strict superset of the lean checklist:the Story reference, Acceptance criteria, and Out of scope sections appear here unchanged in name andorder, with Scenarios, Edge cases, and Non-functional criteria added between them. Use it forbehavior-heavy, risky, or integration-sensitive stories, and where AC will seed automated tests.Default to the lean checklist and scale up only when scenarios earn their place.
HOW TO FILL THIS IN1. Read the comment under each heading: WHAT it wants, WHY it matters (with a pointer into acceptance-criteria_companion.md for the deep reasoning), guiding questions to ASK, a GOOD and a WEAK example, and the TRAP to avoid.2. Replace each {{placeholder}} with your content.3. Do not pre-fill a section out of diligence. Add a full-only section the moment a real question it answers comes up (a flow needs scenarios, an edge case bites, a performance bar gets contested). If a section does not apply, write "N/A" and one line of why.4. Before you ship: self-grade against acceptance-criteria_guide.md, then DELETE every HTML comment.-->
# {{title}}
## Story reference
<!-- WHAT Which user story or backlog item these criteria gate: a link, or the story statement itself. Name the user and the goal. WHY AC are meaningless without the story they accept; "accepted into what" must be unambiguous. Deep dive: acceptance-criteria_companion.md section 3 (Anatomy > Story reference). ASK Which story do these gate? Is it linked or quoted so a reviewer can find it? Are the user and goal clear? GOOD "As a recurring analyst, I want to set one of my saved views as the default for a dashboard, so that the dashboard opens the way I work instead of in its generic default state. (See user-stories_example.md.)" WEAK "Saved views feature." (no user, no goal, no link; a reviewer cannot tell what is being accepted) TRAP Free-floating criteria with no parent story. -->
{{story_reference}}
## Acceptance criteria
<!-- WHAT The rule-based conditions that must hold for the story to be accepted, as a checklist of observable, pass/fail outcomes. Use this for discrete rules; use Scenarios below for flows. WHY Discrete rules are clearest as a list, and each must be markable pass or fail; a criterion you cannot mark is not finished. Deep dive: acceptance-criteria_companion.md section 3 (Anatomy > Acceptance criteria). ASK Is each row a single verifiable claim? Could QA mark it pass or fail as written? Is it what the user observes, not how it is built? GOOD "Marking a new view as default un-marks the previous default automatically." WEAK "Defaults are stored efficiently in a Redis cache." (implementation detail, not an observable outcome the user can verify) TRAP Implementation, not behavior: criteria that describe how it is built rather than what the user can observe. -->
- [ ] {{criterion_1}}- [ ] {{criterion_2}}
## Scenarios (Given / When / Then)
<!-- WHAT Behavior expressed as scenarios in Given (context) / When (action) / Then (outcome) form, one scenario per distinct behavior. WHY Flows are clearer as scenarios than as rules, and Given/When/Then can double as automated tests. Deep dive: acceptance-criteria_companion.md section 3 (Anatomy > Scenarios, Given/When/Then). ASK Does each scenario test one behavior? Is "When" a single action? Do Given and Then read as precondition and observable outcome? GOOD "Scenario: switching the default. Given 'EMEA, last 30 days' is currently my default, When I mark 'APAC, last 7 days' as the default, Then 'APAC, last 7 days' becomes my default and 'EMEA, last 30 days' is no longer marked default." WEAK "Given I am logged in with saved views, When I save, rename, set a default, and reload, Then everything works." (many actions and behaviors in one scenario, no single outcome to verify) TRAP Mega-scenario: one Given/When/Then with many "And" steps testing several behaviors at once. -->
**Scenario: {{scenario_name}}**- Given {{context}}- When {{action}}- Then {{expected_outcome}}
## Edge cases and negative paths
<!-- WHAT The unhappy paths the rules and scenarios above do not cover: empty input, permission denied, conflict, timeout, missing data. WHY Most production defects live here, not on the happy path; the negative criteria are often the most valuable and the most commonly omitted. Deep dive: acceptance-criteria_companion.md section 3 (Anatomy > Edge cases and negative paths). ASK What happens on empty, denied, conflicting, or missing input? Which failure would bite a real user? Is the recovery behavior specified, not just the failure? GOOD "Given my default view references a filter that has since been deleted, when I open the dashboard, then it loads the still-valid filters and shows a clear message naming the missing filter, rather than failing to load." WEAK "Handle errors gracefully." (names no specific edge and no observable behavior; cannot be marked pass or fail) TRAP Happy path only: no edge or negative cases, so error behavior gets invented during build. -->
- [ ] {{edge_case_1}}
## Non-functional criteria
<!-- WHAT Story-specific quality gates: performance, accessibility, security, or privacy thresholds for this story, each with a measurable bar. WHY A story can pass every functional check and still be unacceptable if it is slow or inaccessible; keep these story-specific. Deep dive: acceptance-criteria_companion.md section 3 (Anatomy > Non-functional criteria). ASK What quality bar is specific to this story? Is each a measurable threshold? Does it belong here or in the team-wide Definition of Done? GOOD "Loading a default view on dashboard open completes within 1 second at p95. The 'set as default' control is keyboard-operable and screen-reader labeled (WCAG 2.2 AA)." WEAK "Must be fast and accessible." (no measurable threshold; cannot be marked pass or fail) TRAP Duplicating the Definition of Done: restating universal quality bars that apply to every story instead of the ones specific to this one. -->
- [ ] {{non_functional_criterion_1}}
## Out of scope and notes
<!-- WHAT What these criteria deliberately do not cover, plus assumptions and links to adjacent stories. WHY It lets a reviewer tell an omission from a decision. Deep dive: acceptance-criteria_companion.md section 3 (Anatomy > Out of scope and notes). ASK What did you choose not to cover? What assumptions do the criteria rest on? Where do adjacent concerns live? GOOD "Out of scope: team-level defaults (a Team Lead setting a default for everyone) are a separate, open decision. Assumes per-user preference storage (shipped Q1). Does not cover sharing, which has its own story." WEAK Leaving this blank. (silence on scope makes an omission read as a deliberate decision) TRAP No scope statement, so omissions read as decisions. -->
{{out_of_scope_and_notes}}acceptance-criteria_example.md
---title: "Acceptance criteria: set a default saved view"doc_type: acceptance-criteriasize: fullowner: "Priya Nair (PM, Reporting)"status: in-reviewdoc_version: "0.1.0"created: "2026-06-22"updated: "2026-06-30"related_links: - "Story: set a default saved view (user-stories_example.md)" - "PRD: Saved Views for Dashboards (prd_example.md)"source_template: acceptance-criteriasource_template_version: 0.1.0---
<!--Worked example for the Acceptance Criteria bundle. These are full acceptance criteria for the "set adefault saved view" story from the user-stories example. It shows rule-based criteria, Given/When/Thenscenarios, an explicit edge case (a missing filter), and a non-functional criterion. Figures marked"illustrative" are made up for the example.-->
# Acceptance criteria: set a default saved view
## Story reference
As a recurring analyst, I want to set one of my saved views as the default for a dashboard, so that thedashboard opens the way I work instead of in its generic default state. (See user-stories_example.md.)
## Acceptance criteria
- [ ] I can mark exactly one of my saved views as the default for a given dashboard.- [ ] Marking a new view as default un-marks the previous default automatically.- [ ] Opening the dashboard loads my default view instead of the generic default state.- [ ] The default is mine alone; it does not change the default for any other user.
## Scenarios (Given / When / Then)
**Scenario: default view loads on open**- Given I have set "EMEA, last 30 days" as my default view for the Sales dashboard- When I open the Sales dashboard- Then it loads with the "EMEA, last 30 days" filters applied, not the generic default
**Scenario: switching the default**- Given "EMEA, last 30 days" is currently my default- When I mark "APAC, last 7 days" as the default- Then "APAC, last 7 days" becomes my default and "EMEA, last 30 days" is no longer marked default
## Edge cases and negative paths
- [ ] Given my default view references a filter that has since been deleted, when I open the dashboard, then it loads the still-valid filters and shows a clear message naming the missing filter, rather than failing to load.- [ ] Given I have no default set, when I open the dashboard, then it loads the generic default state with no error.
## Non-functional criteria
- [ ] Loading a default view on dashboard open completes within 1 second at p95 (illustrative target).- [ ] The "set as default" control is keyboard-operable and screen-reader labeled (WCAG 2.2 AA).
## Out of scope and notes
Out of scope: team-level defaults (a Team Lead setting a default for everyone) are a separate, opendecision and not covered here. Assumes per-user preference storage (shipped Q1). Does not cover sharing,which has its own story.Provenance
Section titled “Provenance”The reasoning, the history and every source, in the repository:
- Companion - the long-form argument: why these sections, where the sources disagree, and what the bundle refuses to claim
- History - what changed in this bundle, and when
- Research log - every source consulted, with what each one actually supports
- Catalog metadata - the machine-readable record this page is generated from
Catalog record: 6 sections across 1 format(s), methodology Agile/BDD, typically owned by Product Owner.