Extended reading, worked examples, common mistakes, and practice exercises for the two most important concepts in the Planning stage.
Before User Stories, most software projects used requirements documents — sometimes hundreds of pages written by business analysts before a single line of code. These documents had a fundamental flaw: they described the system, not the person using it. They told developers what to build but never explained who would use it or why it would matter to them.
A developer reading "The system shall display a sortable, filterable list of items" has no idea whether this matters to anyone. A developer reading "As a restaurant owner, I want to see today's orders sorted by preparation time, so that my kitchen team knows what to prioritise" understands the human problem they are solving. That understanding changes how they build — and what questions they ask when something is unclear.
"The system shall provide a mechanism by which authenticated users may modify the unit price of menu items associated with their registered establishment, with changes reflected to end users within a configurable synchronisation interval."
Nobody wrote this to be unhelpful. But it is written for the system, not the person. A developer reading it builds a mechanism. They don't think about the restaurant owner who is trying to update prices between the lunch and dinner rush, stressed because a customer just complained.
"As a restaurant owner, I want to update my menu prices quickly from my phone, so that customers always see the correct cost and I don't lose money on mispriced items."
The developer now understands who (a restaurant owner), the context (quickly, from a phone), the goal (update prices), and the stakes (losing money on mispriced items). They are more likely to build something that genuinely solves the problem — and to flag it if the proposed solution doesn't.
User Stories do not just change the format of requirements. They change who is centred in the conversation. Traditional requirements centre the system. User Stories centre the person. That shift is not cosmetic — it changes what questions developers ask, what trade-offs they make, and what they build when the spec is ambiguous.
The format looks simple. It isn't. Each part makes a specific demand on the person writing it — and each part is commonly written badly. Here is what each part requires and where teams go wrong.
The user must be specific enough that the team can picture them. "As a user" tells the team nothing. "As a restaurant owner who is also managing the kitchen" tells the team a lot — this person is distracted, under time pressure, and probably using a phone. That context should inform every design decision.
"As a user..." — which user? All users have different needs. A customer ordering food and a restaurant owner managing orders are completely different people.
"As an admin..." — admin of what? Doing what? Admin is a role, not a person with a problem.
"As a restaurant owner managing multiple locations..." — now the developer knows this person is stretched, probably managing by exception rather than detail.
"As a new customer who hasn't ordered before..." — the developer knows not to assume familiarity with the UI or process.
This is where most stories fail. Teams write the feature they have already decided to build, not the goal the user has. The goal should remain open enough that the best solution isn't predetermined.
"...I want a pie chart of my spending by category..."
The team has already decided the solution is a pie chart. But what if a table, or a simple percentage breakdown, would serve the user better and take half the time to build?
"...I want to understand where my money goes each month..."
Now the team can decide whether a pie chart, a bar chart, a category list with percentages, or something else best serves the goal. The user's need drives the solution.
Teams skip the "so that" because they think it is obvious. It almost never is. The "so that" is the team's contract with the user — it is what they are promising to deliver, not just what they are building. If the feature is built and the "so that" is not achieved, the story has failed even if the code works perfectly.
"As a restaurant owner, I want to update my menu prices." — Fine. The developer builds a price editing field. Done.
Now add the "so that": "...so that customers always see the correct cost and I don't lose money on mispriced items." Now the developer knows the price change must propagate to the customer-facing view quickly. They build a sync mechanism. They test that changes appear within an acceptable time. They think about what happens if the sync fails.
The "so that" turns a feature into a responsibility. Writing it forces the PO and developer to agree on what success actually looks like.
Acceptance criteria are the conditions that must be true for a User Story to be considered complete. They are written before development begins — ideally before Sprint Planning, during Backlog Refinement. Without them, "done" is a subjective argument at the end of a Sprint. With them, it is a verifiable fact.
Each criterion should be specific, testable, and written from the user's perspective — not from the developer's. It should describe an observable outcome, not an implementation detail.
Teams use different formats depending on what works for their context. All three are valid — the important thing is that the criteria are specific and testable, regardless of format.
| Format | Structure | Best for |
|---|---|---|
| Given / When / Then | Given [a context], When [an action], Then [an outcome]. | Complex interactions with multiple states or edge cases. Maps directly to automated test cases. |
| The user can... | A simple statement of what the user can do or see. | Straightforward stories with clear outcomes. Fast to write and easy to verify. |
| Scenario list | A numbered or bulleted list of conditions to be satisfied. | Stories with multiple distinct outcomes to verify. Good for QA teams who need a checklist. |
Given / When / Then: Given a restaurant owner is logged in and viewing their menu, When they change the price of an item and click Save, Then the new price appears in the customer-facing menu within 60 seconds.
The user can: The owner can update any item price and see the change reflected on the customer-facing menu within 60 seconds.
Scenario: Price change saves successfully → customer sees updated price within 60 seconds.
Typically three to eight. Fewer than three usually means the story is too vague. More than eight usually means the story is too large — it should probably be split into two or more stories. The criteria should cover the happy path (what happens when everything goes right) and the most important unhappy paths (what happens when something goes wrong).
These are the stories from Session 6, fully written with acceptance criteria. Use them as a reference when writing your own stories.
Most story quality problems trace back to one of six root causes. Recognising them early saves significant rework.
The "I want to" should describe a goal, not a predetermined feature. If you can change the solution without changing the story, you've written a goal. If changing the solution requires rewriting the story, you've written a feature. Write the goal — let the team find the best solution.
Why? To reorder? To dispute a charge? To show a friend? The answer changes what the history page needs to show and how it needs to work. "So that I can quickly reorder my favourite meals without searching from scratch" produces a very different design than "so that I can dispute incorrect charges with my bank."
This is an Epic disguised as a story. "Manage my account" could mean anything — update a password, change an email, set notification preferences, delete the account, link a payment method. Each of those is a story. The test: could two developers finish this in one Sprint? If not, split it.
This is a task, not a user story. Genuine technical work — refactoring, infrastructure, technical debt — should be tracked separately or expressed in terms of user impact where possible. If the refactor genuinely improves something for users (faster checkout, better error messages), write the user-facing improvement as the story.
This produces the most expensive kind of rework: code that is finished but does not meet expectations. Acceptance criteria must be agreed before the Sprint begins — not written after the developer has finished. The conversation about criteria is part of the value; it surfaces ambiguity and misunderstanding before they become code.
Acceptance criteria should be observable by a user or tester without reading the code. "The updated price appears in the customer-facing menu within 60 seconds" is an acceptance criterion. "The API returns 200" is a technical implementation detail that belongs in technical documentation, not in the story.
Splitting is not a sign that a story was badly written. It is a sign that the team's understanding has grown. A story that looked like one thing at the start of a project often reveals itself to be three things by the time the team gets to it. The goal of splitting is to produce stories that are independently deliverable — each one works and delivers value without requiring the others to be completed first.
| Pattern | How to apply it | QuickBite example |
|---|---|---|
| By workflow step | If the story covers multiple steps in a sequence, make each step its own story. The user can complete each step independently. | "Place an order" → Browse restaurants · Select items · Add to cart · Pay · Confirm |
| By user type | If the same feature serves different users differently, give each user their own story. | "View orders" → Customer view (their own orders) · Owner view (today's incoming orders) · Rider view (assigned deliveries) |
| By data type | If the feature handles several types of data, build one type at a time. Each type is independently useful. | "Accept payment" → Pay with credit card · Pay with PayPal · Pay with voucher |
| Happy / unhappy path | Build the success case first. Handle error states and edge cases in a separate story, once the happy path works. | "Pay with card (success)" + "Pay with card — declined or network error handling" |
| MVP slice | Build the simplest version that delivers value first. Add richness in a second story once the basic version is validated. | "Show nearby restaurants (list, sorted by distance)" + "Show nearby restaurants (filtered, sorted by rating or cuisine)" |
After splitting, ask: if we shipped only Story A and not Story B, would Story A still deliver value to a real user? If yes, the split is valid. If Story A is useless without Story B, they are not truly independent — the split is artificial and the stories should be recombined or re-split differently.
The term MVP has been used so loosely in product teams that it has nearly lost its meaning. People use it to describe prototypes, demos, proof-of-concepts, and just "an early version". None of those are MVPs in the original sense. Understanding what the term actually means — and what it demands — is essential to using it correctly.
The smallest set of features that still achieves the goal. Not fewer — the product must be complete enough to work. Not more — every extra feature is a bet that hasn't been validated yet. Minimum is not about cheapness; it is about focus.
The word teams most consistently miss. Viable means users would actually choose to use this over doing nothing or using an alternative. A food delivery app where the customer can browse menus but cannot pay is not viable — they still have to call the restaurant.
A product, not a prototype. It is live, used by real people, and generates real feedback — not hypothetical feedback from a user research session. The feedback that shapes what to build next comes from real behaviour, not stated preferences.
The most famous MVP illustration: if the user's problem is "I need to get across town", do not build a car in four releases — wheel, then chassis, then body, then engine. At no point in that sequence does the user have anything useful. Build a skateboard first.
The skateboard is not the destination. It is the start of learning. A user who skateboards across town discovers things a user who was asked "what do you want?" never would. They might discover the route is too hilly and they want something with a motor. Or that the terrain is too rough and they want larger wheels. Or that they actually want something they can carry onto the train. Each discovery changes the next build — in ways nobody could have predicted without real use.
The QuickBite equivalent: build browse + order + pay first. Not because tracking, reviews, and favourites aren't valuable — they are. But until you know whether customers will actually order food through the app, you don't know whether it's worth building the richer features. The MVP tests the riskiest assumption: will people use this?
The riskiest assumption is the one that, if wrong, makes the entire product worthless. For a marketplace, it is usually bilateral — will suppliers list products, and will buyers purchase them? For QuickBite specifically, the riskiest assumptions are: (1) customers will trust an app to handle food delivery payments, and (2) restaurant owners will list their menus and manage orders through a third-party platform. Everything else is secondary until those two things are confirmed.
This confuses minimum with incomplete. An MVP is not a product with all its features half-built. It is a product with a small number of features fully built. A food delivery app where browsing works but payment doesn't is not an MVP — it is a broken product. Users cannot complete their goal. Real feedback requires real use.
Teams often define the MVP as the first release of their planned product, rather than as the minimum needed to test their riskiest assumption. If the riskiest assumption is "will customers pay for food via an app?", the MVP needs a working payment flow — but not reviews, not favourites, not live tracking. Map the MVP to the assumption, not to the planned roadmap.
Minimum viability includes minimum quality. A product that crashes, loads slowly, or confuses users will not generate valid feedback about whether users want the product — it generates feedback that the product is broken. Users must be able to use the MVP without fighting it. The learning requires genuine use, not charitable use.
An MVP is a phase, not a product type. It is meant to test a specific assumption and then grow based on what was learned. If the riskiest assumption is validated, the team should move to building the next most important thing — informed by real user data. A team that keeps adding to the MVP without a clear thesis for what they are testing has lost the discipline that makes MVPs useful.
Before shipping an MVP, run it through these four questions. If any answer is no, the MVP is not yet viable.
The one-sentence testCan a real user, with a real problem, complete one full goal end-to-end — and would they choose to do so again? If yes, you have an MVP. If no, you have a feature.
Each story below has a problem. Identify the problem and rewrite it so it is well-formed. There are no trick answers — the issues are real ones that appear regularly in real backlogs.
1. The "so that" is circular — it says nothing. A stronger version: "As a hungry customer, I want to search for restaurants by cuisine type, so that I can quickly find the kind of food I'm in the mood for." The goal drives the design of the search — what fields to search, what filters to offer.
2. "Admin" is a role, not a person. "A report" is vague. Before rewriting, you need to know: who specifically needs this? What decision does the report inform? What data must it show? A better version: "As a restaurant owner, I want to see a summary of this week's orders and revenue, so that I can plan staffing for next week."
3. This is a technical task, not a user story. No real user cares about caching — they care about fast load times. If it's worth doing, express the user benefit: "As a customer browsing restaurants, I want the restaurant list to load in under 2 seconds, so that I don't wait and give up." The caching is an implementation decision, not the requirement.
4. "Full account management system" is an Epic. Split by what a user would actually need to do: change password · update delivery address · save a payment method · delete account · update name and email. Each of those is a story. Prioritise which ones matter for the MVP before breaking them all down.
For each story below, write three to five acceptance criteria. Cover the happy path and at least one failure scenario.
Story 1 — Map tracking:
Story 2 — Order notification:
Story 3 — Mark as delivered:
The scenario: A startup wants to build a tutoring marketplace where students post learning requests and independent tutors bid for sessions. The founders have validated that students struggle to find tutors for niche subjects and tutors struggle to find consistent work. They have six weeks of runway to build an MVP.
Riskiest assumption: That tutors will accept lower rates and less certainty (bidding model) in exchange for access to a stream of students — and that students will trust an unknown tutor found through a platform rather than a word-of-mouth recommendation.
MVP scope thinking: The core transaction is: student posts request → tutor bids → student selects → session happens → payment processes. Every one of those steps must be in the MVP or the marketplace cannot function. Features outside the transaction — reviews, tutor profiles, search/filter, recurring sessions, disputes — are Release 2 once the core exchange is validated.
Viability test consideration: A student can only use this over an alternative if there are tutors on the platform who respond to requests quickly. The chicken-and-egg problem means the founders may need to manually recruit the first 10–20 tutors before the MVP launches, to ensure there is supply before demand arrives.