User Stories and Acceptance Criteria
Purpose
Stories get rejected in review for two reasons: they are horizontal slices that
deliver nothing observable on their own, and their acceptance criteria describe
intent rather than verifiable behaviour. This skill enforces vertical slicing and
a criteria format that a tester can execute — including the negative paths, which
is where most defects and most mid-sprint clarification requests come from.
Prerequisites
- Inputs: an agreed requirement source — a PRD, epic, or written request —
identifying the user, the problem, and the priority. Stories written from a
verbal instruction acquire the ambiguity of the instruction.
- Access: whoever can answer behaviour questions (the product owner), and the
existing system behaviour where the story modifies it.
- Also required: the definition of ready and definition of done your team
uses. If the team has none, the checklists below are the minimum.
If the requirement's expected behaviour on failure or edge input is unknown, ask
before writing criteria. Inventing a plausible error behaviour puts a decision
into the backlog that nobody made.
Data classification
Internal. Do not put real customer data, account numbers, credentials, or
personal identifiers into stories, criteria, or test data examples. Use
obviously synthetic values. If someone supplies a real record to illustrate a
case, flag it and replace it with a synthetic equivalent before the story is
saved.
Story shape
Format: As a [specific user role], I want [capability], so that [outcome].
| Element |
Valid |
Invalid |
| Role |
A specific role with different needs or permissions from other roles |
"As a user" |
| Capability |
Something the role can do or observe |
A technical task: "add an index" |
| Outcome |
Why it matters, in the role's terms |
"so that the feature is complete" |
A story is ready when it satisfies all of: independent enough to be built without
another unstarted story, negotiable in its implementation, valuable to someone
outside the team, estimable by the people who will build it, small enough to
finish in a single iteration, and testable by the criteria attached.
Splitting rules
Split vertically — each slice must produce observable behaviour end to end. Use
the first rule that applies:
| Situation |
Split by |
| Story handles several input or data types |
One type per story, simplest first |
| Story covers create, read, update, delete |
Individual operations |
| Story has complex business rules |
The simple rule first, then each variation |
| Story spans several user roles |
One role per story |
| Story has a happy path plus extensive error handling |
Happy path first, then each error class |
| Story has performance or scale requirements |
Working behaviour first, then the performance story with its own criteria |
| Story includes an optional or configurable behaviour |
Default behaviour first, configuration second |
| Story is large because of an unknown |
A time-boxed investigation with a decision as its output, then the build story |
Never split by layer — a story for the database, another for the API, another for
the interface leaves nothing demonstrable until the last one lands.
Acceptance criteria
Use Given / When / Then: given a starting state, when an action occurs, then
an observable result. One scenario per criterion.
Every story's criteria must cover:
- The happy path, with concrete values, not placeholders.
- Each business rule boundary — at the limit, just under, and just over.
- Invalid input, stating the specific message or behaviour the user gets.
- Empty and absent states — no records, no permission, no prior data.
- Failure of anything the story depends on — a downstream call fails or times
out; state what the user sees and what the system records.
- Permission variations, where roles differ in what they may do or see.
- Anything explicitly out of scope, listed so it is not built or tested.
Procedure
- Confirm the requirement source and the priority. Without a source, stop and
go to
product-requirements-doc.
- Identify the roles the requirement touches, and what differs between them.
- Write the story or stories, applying the splitting table until each fits an
iteration and delivers observable behaviour.
- Write the happy-path criterion first, with real values. Vague values are
where testers and developers diverge.
- Walk the coverage list above and add a criterion for each applicable line.
Where a line does not apply, say so explicitly rather than skipping silently.
- Apply the ambiguity test. Read each criterion and ask whether two competent
people could implement it differently. Words that fail this test: fast, easy,
properly, appropriate, handle, support, intuitive, as expected, robust. Replace
each with an observable condition or a number.
- Apply the observability test. Every "then" must be something a person or a
test can see: a message, a state change, a stored value, a recorded event. "The
system processes the request correctly" is not observable.
- Attach the non-functional criteria that genuinely apply — response time
with a figure and a load condition, accessibility conformance, audit or logging
requirements, data retention. Only where they apply; a copied block on every
story is ignored on every story.
- Review with a developer and a tester before the story is ready. The
question to ask is not "is this clear?" but "what would you have to ask me
before starting?" Every such question becomes a criterion.
- Record open questions on the story with an owner. A story with an open
behavioural question is not ready and should not be pulled into an iteration.
Failure modes
- Horizontal slicing. Layer-by-layer stories produce a sprint with nothing
demonstrable.
- Criteria that restate the story. "Then the user can export the report"
merely repeats the capability; it does not say what a correct export contains.
- Happy path only. The error and empty cases become defects found in
production, or design decisions made silently by whoever implements them.
- Criteria written as implementation. "Then a row is inserted into the orders
table" couples the test to a design that may change; state the user-observable
effect and, where the data is the deliverable, the interface it is read through.
- Placeholder values. "Given a valid amount" hides the boundary the story
exists to define.
- Stories carrying a technical task. Refactoring and infrastructure work is
legitimate but is not a user story; track it as its own item rather than
disguising it with a fictional user role.
Boundaries
- Writing the requirements, goals, and non-goals — use
product-requirements-doc.
- Communicating scope and dates to stakeholders — use
product-roadmap-communication.
- Recording a technical approach decision — use
engineering-decision-record.
- Writing or reviewing the automated tests themselves — use
engineering-code-review with the delivery team.
Hand-offs
- Receives from:
product-requirements-doc (agreed requirements, priorities,
non-goals).
- Routes to:
engineering-code-review and the delivery team for
implementation, data-analytics-metric-definition when a story introduces a
metric or event, and back to product-requirements-doc when splitting exposes a
requirement the PRD never decided.
1---2name: product-user-story-acceptance-criteria3description: Splits requirements into vertically sliced user stories and writes acceptance criteria a tester could execute without asking the author a question — observable, bounded, and covering the negative and edge paths, not just the happy path. Use when turning a PRD, epic, or feature request into backlog items, or when a story is rejected as unclear or untestable; trigger on 'write user stories', 'break this epic down', 'acceptance criteria for X', 'this ticket isn't clear enough', 'refine the backlog'. Not for authoring the requirements document itself (use product-requirements-doc), not for stakeholder-facing timelines (use product-roadmap-communication), and not for writing the test automation (that is an engineering task).4---56# User Stories and Acceptance Criteria78## Purpose910Stories get rejected in review for two reasons: they are horizontal slices that11deliver nothing observable on their own, and their acceptance criteria describe12intent rather than verifiable behaviour. This skill enforces vertical slicing and13a criteria format that a tester can execute — including the negative paths, which14is where most defects and most mid-sprint clarification requests come from.1516## Prerequisites1718- **Inputs:** an agreed requirement source — a PRD, epic, or written request —19 identifying the user, the problem, and the priority. Stories written from a20 verbal instruction acquire the ambiguity of the instruction.21- **Access:** whoever can answer behaviour questions (the product owner), and the22 existing system behaviour where the story modifies it.23- **Also required:** the definition of ready and definition of done your team24 uses. If the team has none, the checklists below are the minimum.2526If the requirement's expected behaviour on failure or edge input is unknown, ask27before writing criteria. Inventing a plausible error behaviour puts a decision28into the backlog that nobody made.2930## Data classification3132**Internal.** Do not put real customer data, account numbers, credentials, or33personal identifiers into stories, criteria, or test data examples. Use34obviously synthetic values. If someone supplies a real record to illustrate a35case, flag it and replace it with a synthetic equivalent before the story is36saved.3738## Story shape3940Format: **As a [specific user role], I want [capability], so that [outcome].**4142| Element | Valid | Invalid |43| --- | --- | --- |44| Role | A specific role with different needs or permissions from other roles | "As a user" |45| Capability | Something the role can do or observe | A technical task: "add an index" |46| Outcome | Why it matters, in the role's terms | "so that the feature is complete" |4748A story is ready when it satisfies all of: independent enough to be built without49another unstarted story, negotiable in its implementation, valuable to someone50outside the team, estimable by the people who will build it, small enough to51finish in a single iteration, and testable by the criteria attached.5253## Splitting rules5455Split vertically — each slice must produce observable behaviour end to end. Use56the first rule that applies:5758| Situation | Split by |59| --- | --- |60| Story handles several input or data types | One type per story, simplest first |61| Story covers create, read, update, delete | Individual operations |62| Story has complex business rules | The simple rule first, then each variation |63| Story spans several user roles | One role per story |64| Story has a happy path plus extensive error handling | Happy path first, then each error class |65| Story has performance or scale requirements | Working behaviour first, then the performance story with its own criteria |66| Story includes an optional or configurable behaviour | Default behaviour first, configuration second |67| Story is large because of an unknown | A time-boxed investigation with a decision as its output, then the build story |6869Never split by layer — a story for the database, another for the API, another for70the interface leaves nothing demonstrable until the last one lands.7172## Acceptance criteria7374Use **Given / When / Then**: given a starting state, when an action occurs, then75an observable result. One scenario per criterion.7677Every story's criteria must cover:78791. **The happy path**, with concrete values, not placeholders.802. **Each business rule boundary** — at the limit, just under, and just over.813. **Invalid input**, stating the specific message or behaviour the user gets.824. **Empty and absent states** — no records, no permission, no prior data.835. **Failure of anything the story depends on** — a downstream call fails or times84 out; state what the user sees and what the system records.856. **Permission variations**, where roles differ in what they may do or see.867. **Anything explicitly out of scope**, listed so it is not built or tested.8788## Procedure89901. **Confirm the requirement source and the priority.** Without a source, stop and91 go to `product-requirements-doc`.922. **Identify the roles** the requirement touches, and what differs between them.933. **Write the story or stories,** applying the splitting table until each fits an94 iteration and delivers observable behaviour.954. **Write the happy-path criterion first,** with real values. Vague values are96 where testers and developers diverge.975. **Walk the coverage list above** and add a criterion for each applicable line.98 Where a line does not apply, say so explicitly rather than skipping silently.996. **Apply the ambiguity test.** Read each criterion and ask whether two competent100 people could implement it differently. Words that fail this test: fast, easy,101 properly, appropriate, handle, support, intuitive, as expected, robust. Replace102 each with an observable condition or a number.1037. **Apply the observability test.** Every "then" must be something a person or a104 test can see: a message, a state change, a stored value, a recorded event. "The105 system processes the request correctly" is not observable.1068. **Attach the non-functional criteria that genuinely apply** — response time107 with a figure and a load condition, accessibility conformance, audit or logging108 requirements, data retention. Only where they apply; a copied block on every109 story is ignored on every story.1109. **Review with a developer and a tester before the story is ready.** The111 question to ask is not "is this clear?" but "what would you have to ask me112 before starting?" Every such question becomes a criterion.11310. **Record open questions on the story with an owner.** A story with an open114 behavioural question is not ready and should not be pulled into an iteration.115116## Failure modes117118- **Horizontal slicing.** Layer-by-layer stories produce a sprint with nothing119 demonstrable.120- **Criteria that restate the story.** "Then the user can export the report"121 merely repeats the capability; it does not say what a correct export contains.122- **Happy path only.** The error and empty cases become defects found in123 production, or design decisions made silently by whoever implements them.124- **Criteria written as implementation.** "Then a row is inserted into the orders125 table" couples the test to a design that may change; state the user-observable126 effect and, where the data is the deliverable, the interface it is read through.127- **Placeholder values.** "Given a valid amount" hides the boundary the story128 exists to define.129- **Stories carrying a technical task.** Refactoring and infrastructure work is130 legitimate but is not a user story; track it as its own item rather than131 disguising it with a fictional user role.132133## Boundaries134135- Writing the requirements, goals, and non-goals — use `product-requirements-doc`.136- Communicating scope and dates to stakeholders — use137 `product-roadmap-communication`.138- Recording a technical approach decision — use `engineering-decision-record`.139- Writing or reviewing the automated tests themselves — use140 `engineering-code-review` with the delivery team.141142## Hand-offs143144- **Receives from:** `product-requirements-doc` (agreed requirements, priorities,145 non-goals).146- **Routes to:** `engineering-code-review` and the delivery team for147 implementation, `data-analytics-metric-definition` when a story introduces a148 metric or event, and back to `product-requirements-doc` when splitting exposes a149 requirement the PRD never decided.