Agile Fundamentals ← Back to course
Session 6 · Supplementary Materials

User Stories & MVP — Going Deeper

Extended reading, worked examples, common mistakes, and practice exercises for the two most important concepts in the Planning stage.

Self-study ~30 min read User Stories · MVP · QuickBite
On this page
Why User Stories exist

The problem with traditional requirements

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.

Traditional requirement

"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.

User Story

"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.

The key insight

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.

Writing stories well

The format — and what each part actually demands

The format
As a [specific type of user], I want to [accomplish a goal], so that [I get this real benefit].

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 "As a" — name a real person

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.

Weak

"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.

Strong

"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.

The "I want to" — describe a goal, not a feature

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.

Feature-centred (weak)

"...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?

Goal-centred (strong)

"...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.

The "so that" — the most skipped, most important part

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.

What happens when the "so that" is missing

"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 in depth

How the team defines "done" before they start

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.

What good acceptance criteria look like

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.

Full story with acceptance criteria — QuickBite menu prices
Restaurant owner
"As a restaurant owner, I want to update my menu prices, so that customers always see the correct cost and I don't lose money on mispriced items."
Acceptance criteria
  • The owner can edit the price of any menu item from their dashboard without assistance.
  • The updated price is visible to customers browsing the restaurant within 60 seconds of saving.
  • The owner sees a success confirmation message immediately after saving a price change.
  • If the save fails (e.g. network error), the owner sees an error message and the original price is preserved.
  • Price changes are logged with a timestamp, visible to the owner in their activity history.

Three formats for writing criteria

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.

FormatStructureBest for
Given / When / ThenGiven [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 listA numbered or bulleted list of conditions to be satisfied.Stories with multiple distinct outcomes to verify. Good for QA teams who need a checklist.
The same criterion in three formats — QuickBite price update

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.

How many criteria per story?

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).

Reference

QuickBite story library — with acceptance criteria

These are the stories from Session 6, fully written with acceptance criteria. Use them as a reference when writing your own stories.

Customer stories

Customer
"As a hungry customer, I want to browse restaurants near me, so that I can find something to order quickly."
Acceptance criteria
  • The customer sees a list of restaurants within a 5km radius of their location.
  • Each restaurant card shows the name, cuisine type, estimated delivery time, and minimum order value.
  • The list loads within 3 seconds on a standard 4G connection.
  • If no restaurants are available, the customer sees a helpful message — not a blank screen.
Customer
"As a customer, I want to add items to my cart, so that I can review my order before paying."
Acceptance criteria
  • The customer can add any menu item to their cart with one tap.
  • The cart persists if the customer navigates away and returns within the same session.
  • The cart shows a running total, including any delivery fee, before checkout begins.
  • The customer can change item quantities or remove items from the cart at any point before paying.
Customer
"As a customer, I want to pay with my saved card, so that checkout is fast and I don't have to re-enter my details."
Acceptance criteria
  • A returning customer can pay with a previously saved card in two taps — confirm order, confirm payment.
  • Card details are stored securely (last four digits displayed only; full number never shown).
  • The customer receives an order confirmation within 10 seconds of payment completing.
  • If payment fails, the customer is shown a clear error and offered an alternative payment method.

Restaurant owner stories

Restaurant owner
"As an owner, I want to pause incoming orders when busy, so that I don't take more orders than my kitchen can prepare."
Acceptance criteria
  • The owner can toggle a "Paused" status from the dashboard in one tap.
  • While paused, customers see the restaurant as "Temporarily unavailable" and cannot place new orders.
  • Orders already in progress when pausing are not affected.
  • The owner can resume accepting orders with a single tap at any time.

Rider stories

Delivery rider
"As a rider, I want to see orders available near me, so that I can accept deliveries efficiently without wasting time on jobs that are too far away."
Acceptance criteria
  • Available orders are sorted by proximity to the rider's current location.
  • Each order card shows the pickup restaurant, estimated pickup time, delivery address, and estimated earnings.
  • The rider can accept or decline an order in one tap.
  • An accepted order is immediately removed from other riders' available order lists.
What to avoid

Common User Story mistakes

Most story quality problems trace back to one of six root causes. Recognising them early saves significant rework.

1. Writing the solution, not the need

"As a user, I want a pie chart of my spending."

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.

2. Skipping the "so that"

"As a user, I want to see my order history."

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."

3. Writing stories that are too large

"As a user, I want to manage my account."

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.

4. Writing technical stories

"As a developer, I want to refactor the payment module for better testability."

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.

5. No acceptance criteria

Story card says "Done" but nobody agreed what done looked like before the Sprint started.

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.

6. Writing criteria from the developer's perspective

"The API endpoint returns a 200 status code with the updated price in the response body."

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.

When a story is too big

Splitting stories — the five patterns

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.

PatternHow to apply itQuickBite 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)"
The test for a well-split story

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 MVP concept

What Minimum Viable Product actually means

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 three words matter equally

Minimum

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.

Viable

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.

Product

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 skateboard analogy — why it works

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?

What makes an assumption "riskiest"

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.

Identifying your riskiest assumption — a process
  1. List every assumption your product makes about user behaviour.
  2. For each assumption, ask: if this is wrong, does the product still work? If not, it is a critical assumption.
  3. Among the critical assumptions, ask: which one is least proven by existing evidence?
  4. Design the MVP to test that assumption specifically — not the features you're most excited about, not the ones that are technically interesting, not the ones stakeholders have asked for most loudly.
What to avoid

Common MVP mistakes

1. The "MVP" with no viability

Shipping the first release of every feature, half-finished, and calling it an MVP.

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.

2. Building for the roadmap, not the assumption

The MVP contains every feature on the first sprint plan, justified as "the minimum we need."

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.

3. Skipping quality because it's "just the MVP"

"It's fine if it's a bit rough — it's just the MVP."

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.

4. The MVP that never graduates

The product stays at "MVP phase" for twelve months because there's always something more to validate.

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.

How to evaluate yours

The viability test — four questions

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.

Apply it yourself

Practice exercises

User Stories~15 min

Exercise 1 — Rewrite these stories

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. "As a user, I want a search bar, so that I can use it." — What is wrong, and what would a better version look like?
  2. "As an admin, I want to generate a report." — What is missing, and what questions would you need answered before rewriting?
  3. "As a developer, I want to add caching to the restaurant list endpoint, so that page load is faster." — What type of work is this really, and how should it be handled?
  4. "As a customer, I want a full account management system, so that I can manage my account." — What is wrong and how would you split this?

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.

Acceptance Criteria~15 min

Exercise 2 — Write acceptance criteria for these QuickBite stories

For each story below, write three to five acceptance criteria. Cover the happy path and at least one failure scenario.

  1. "As a customer, I want to track my delivery on a map in real time, so that I know exactly when to expect it and can be ready at the door."
  2. "As a restaurant owner, I want to see a notification when a new order arrives, so that I can start preparing immediately without watching the screen."
  3. "As a delivery rider, I want to mark an order as delivered, so that the customer is notified and I'm ready to accept the next delivery."

Story 1 — Map tracking:

  • The customer sees the rider's location on a map, updated at least every 30 seconds.
  • The map shows the rider's current position and the customer's delivery address.
  • The estimated arrival time is displayed and updates dynamically based on the rider's progress.
  • If location data is unavailable, the customer sees an estimated arrival time without the map, not an error screen.
  • Tracking is only visible after the order has been picked up by a rider.

Story 2 — Order notification:

  • The owner receives a push notification on their phone within 10 seconds of a new order being placed.
  • The notification shows the order total and estimated preparation time needed.
  • Tapping the notification opens the order detail view directly.
  • If the owner's phone is offline, the notification is delivered within 30 seconds of reconnection.

Story 3 — Mark as delivered:

  • The rider sees a "Mark as delivered" button that is only active when they are within 200m of the delivery address.
  • Tapping the button sends an in-app notification to the customer that their order has arrived.
  • The order disappears from the rider's active deliveries and moves to their completed history.
  • The rider is shown their earnings for the completed delivery immediately after marking it done.
MVP~20 min

Exercise 3 — Define the MVP for a new product

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.

  1. What is the riskiest assumption in this product? Write it in one sentence.
  2. List the stories needed for a student to complete one full transaction (post a request → receive bids → select a tutor → have a session).
  3. For each story you listed, decide: MVP or Release 2? Justify each decision in one sentence.
  4. Apply the viability test: can a student complete a full goal end-to-end with your MVP? Would they choose to use it over an alternative?
  5. Write one User Story with acceptance criteria for the most important MVP feature.

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.