Delivery

Writing User Stories and Acceptance Criteria That Survive Contact With Developers

INVEST, Given/When/Then, and the difference between a story that gets estimated and one that gets sent back — with before-and-after examples.

A user story is not a requirements document in a smaller box. It is a placeholder for a conversation — Ron Jeffries' three Cs: Card, Conversation, Confirmation. The card is short on purpose. The conversation is where the understanding happens. The confirmation is the acceptance criteria.

Teams that treat the card as the deliverable end up with either useless one-liners or specifications wearing a story costume. Both fail, differently.

The template, and why the third clause matters most

As a [role], I want [capability], so that [benefit].

The "so that" clause is the one people drop, and it is the one carrying all the value. It is the only part that lets a developer suggest a cheaper way to achieve the same outcome, and the only part that lets anyone judge whether the story is worth its cost.

Compare:

As a user, I want to export to CSV.

versus

As a finance analyst, I want to export the reconciliation view to CSV, so that I can pivot it in Excel for the monthly close without re-keying 200 rows.

The second version tells you the columns matter more than the format, that the export must cover the whole reconciliation rather than the current page, and — usefully — that a built-in pivot view might solve the problem better than an export. The first version tells you nothing and will produce a CSV nobody can use.

"As a user" is almost always a smell

If everyone is "a user", nobody is. Name the actual role: finance analyst, warehouse supervisor, first-time visitor, on-call engineer. Different roles want the same feature for incompatible reasons, and the specific role is what tells you which reason you're serving.

INVEST, applied honestly

Bill Wake's checklist is the standard quality bar. Each letter maps to a real symptom.

LetterMeansSymptom when violated
IndependentCan be built in any orderSprint planning becomes a dependency puzzle
NegotiableDescribes the need, not the implementationDevelopers can't propose anything cheaper
ValuableDelivers something a user or business noticesNobody can explain why it's prioritised
EstimableThe team can size it"It depends" and a lot of shrugging
SmallFits comfortably in one SprintIt rolls over. Twice.
TestableYou can prove it's doneArguments at the Sprint Review

Two of these deserve nuance. Independent is an aspiration, not a rule — some dependencies are real, and pretending otherwise just hides them. Make them visible instead. And Negotiable is the one product managers from a specification background find hardest: the instinct is to remove ambiguity by prescribing implementation, which removes exactly the flexibility the format exists to preserve.

Acceptance criteria: the actual contract

The story says what and why. The acceptance criteria say how we'll know it's done. This is where precision belongs — and where vagueness costs the most, because it surfaces as a disagreement at the Sprint Review with stakeholders watching.

Given / When / Then

The scenario format, borrowed from BDD:

  • Given — the starting state
  • When — the action or trigger
  • Then — the observable outcome

The discipline is that Then must be observable. "Then the system handles it correctly" is not a criterion; it's a hope. "Then an error message reading 'Insufficient funds' appears above the amount field, and the transfer is not created" is a criterion, because a tester can watch for it and either see it or not.

A worked example

The story:

As a customer, I want to reset my password without contacting support, so that I can get back into my account outside business hours.

Weak acceptance criteria:

  • User can reset password
  • Email is sent
  • Should be secure
  • Works on mobile

Every line here is a question in disguise. How long is the link valid? What happens if the email doesn't exist? Can the link be reused? "Should be secure" is not implementable, and "works on mobile" is a whole conversation nobody has had.

Strong acceptance criteria:

  1. Given a registered customer on the sign-in page, when they select "Forgot password" and submit their registered email, then a reset email arrives within 60 seconds and the page shows "If an account exists for that address, we've sent a reset link."
  2. Given an email address with no account, when it is submitted, then the same confirmation message appears and no email is sent. (Identical wording is deliberate — it prevents account enumeration.)
  3. Given a valid reset link, when the customer opens it within 30 minutes and sets a password meeting the policy, then the password is updated, all existing sessions are invalidated, and they are signed in.
  4. Given a reset link older than 30 minutes, when it is opened, then an expiry message appears with a "Send a new link" action.
  5. Given a reset link that has already been used, when it is opened again, then it is rejected as expired.
  6. Given five reset requests for the same address within an hour, when a sixth is submitted, then it is silently rate-limited and no further email is sent.

Six criteria instead of four bullets, and the difference is not length — it is that each one is falsifiable. Criterion 2 in particular is the kind of thing that gets discovered in a penetration test six months later if nobody writes it down now.

Cover three cases minimum

The happy path, the most likely error, and the boundary condition. If your criteria only describe things going well, you have written a demo script rather than a specification.

When Given/When/Then is the wrong shape

Not everything is a scenario. For rule-heavy work, a decision table is clearer and makes gaps visible:

Order valueCustomer tierDelivery charge
Under £25Standard£4.95
Under £25PremiumFree
£25 and overStandardFree
£25 and overPremiumFree

Written as prose, the "exactly £25" boundary gets missed roughly every time. In a table with explicit ranges, the gap is visible at a glance. Use checklists for non-functional constraints, tables for rules, scenarios for behaviour.

Splitting stories that are too big

The commonest reason a story rolls over is that it was never one story. Split by behaviour, never by technical layer — "build the API" and "build the UI" are two halves of nothing deliverable.

Patterns that work:

  • By workflow step — search, then filter, then save the search
  • By business rule — the standard case first, the exceptions after
  • By data variation — UK addresses first, international later
  • By operation — create and read first, update and delete later
  • By effort — the manual version first, automate it once it's proven
  • By platform — desktop web first, mobile after

The test for a good split: could we ship this alone and have someone benefit? If the answer is no, you have made a task, not a story. Tasks are fine — they just belong inside a story rather than replacing it.

Definition of Ready and Definition of Done

Two team agreements that eliminate most story-related friction. Neither is part of the Scrum Guide — Definition of Done is (it is the Increment's commitment), while Definition of Ready is a widely used team practice.

Definition of Ready — a story shouldn't enter Sprint Planning unless:

  • The role, capability and benefit are all present and specific
  • Acceptance criteria exist and cover error cases
  • Dependencies are identified
  • Designs exist if the story is UI-facing
  • The team has estimated it

Definition of Done — a story isn't done unless:

  • Every acceptance criterion passes
  • Code is reviewed and merged
  • Automated tests are written and green
  • It is deployed to a shared environment
  • Documentation and release notes are updated
  • The Product Owner has seen it working
Ready is a guideline; Done is a gate

Used rigidly, Definition of Ready turns into a stage gate that recreates waterfall inside Scrum — stories queue in "not ready" and refinement becomes an approval process. Treat it as a conversation prompt: "this isn't ready, what's missing?" is useful; "rejected, resubmit" is not. Definition of Done, by contrast, is genuinely binary.

The refinement conversation

Backlog refinement is where stories become real, and it works best as dialogue rather than presentation. Four questions worth asking every time:

  1. "What would make this simpler?" Developers routinely see an 80% solution at 20% of the cost. They will only offer it if the story is negotiable.
  2. "What could go wrong?" This generates your error-case criteria faster than writing them alone.
  3. "What are we assuming?" Surfaces the constraints nobody stated.
  4. "How would we test it?" If the team can't answer, the criteria aren't testable yet.

A story that comes out of that conversation is one the team estimated together and understands together — which is the actual point of the format. Ten well-refined stories beat forty written alone at a desk.

For where refinement fits alongside the rest of the cadence, see the five Scrum events from the product manager's seat. For the discovery work that should happen before any of this, see customer interviews that produce decisions.

Keep reading