Acceptance Criteria
Given, When, Then for outcomes a neutral reader can verify. The line between completeness and over-specification, and how to keep implementation notes out of the AC list.
Inventory page shows out-of-stock items
Inventory page shows out-of-stock items
'Implemented properly' and 'the UX is good' are not acceptance criteria, they are reassurance. Two engineers will reasonably disagree on whether the bar is met, and the disagreement will surface in review.
Each criterion is observable. A reader who has not seen the code can open the page and confirm. The before/after is binary, which means QA, design, and the PM can all sign off independently.
Users with expired sessions are redirected to sign-in
Users with expired sessions are redirected to sign-in
The left list is implementation steps. They might be correct, but they describe how the engineer will write the code, not what behavior the user will observe. QA cannot test 'check the session in the middleware'.
Given/When/Then forces the writer to name the precondition, the action, and the outcome. There is no ambiguity for QA, no implementation language, and the negative case (valid session) is named explicitly.
Customer pays with a saved card at checkout
Customer pays with a saved card at checkout
Happy-path-only acceptance criteria leave the failure modes to be discovered. They will be discovered by users, then filed as bugs, then patched, then re-broken on the next change.
Real systems fail. Naming the expired-card and provider-down paths in advance gives engineering a real spec and gives QA a real test plan. The cart preservation rule comes out of the conversation, not the bug report.
Activity feed prepends new items in real time
Activity feed prepends new items in real time
A bullet list of implementation hints is a tech-design doc, not acceptance criteria. The team will probably do those things, but the story is now unverifiable by QA and the implementation is locked in before refinement.
Acceptance criteria describe what the user observes. Implementation choices (WebSocket channel, ring buffer, animation reuse) are subtask material. Keep them separate so the story can be reviewed by people who do not know the codebase.
Customer exports their order history
Customer exports their order history
Without an out-of-scope clause, every reviewer assumes a different boundary. PDF and email exports will be raised in standup, the work will balloon, and the story will not finish in the sprint.
Naming what is out is as important as naming what is in. During refinement someone will ask 'what about PDFs?' and the story already answers. The team does not get pulled into scope creep mid-sprint.
Search returns results quickly on cellular
Search returns results quickly on cellular
'Feels fast' is unverifiable and unprotectable. The next refactor will land, the response time will drift, and nobody will notice until users start complaining again.
Numbers anchor performance work. The defined connection profile, percentile thresholds, and regression test mean future changes either preserve the bar or fail visibly. Without those, performance work decays back to where it started within two sprints.
User profile page shows verified-email indicator
User profile page shows verified-email indicator
Given/When/Then is a forcing function for unambiguous state, action, and outcome. For 'three visual variants on a static page' it adds line count without information. The bullets read faster.
Format matters less than the property. For a simple list of constraints, three bullets are cleaner than three identical Given/When/Then blocks. Use Given/When/Then when state and timing matter; use bullets when they don't.