TheProduct Playbook
08 Delivery15 min read

Story Writing Guide

The epic you wrote on the last page is a promise: a few weeks of customer value with a finish line. (That's all an epic is, a chunk of customer value big enough to need its own goal but small enough to finish.) But nobody builds an epic. An epic gets built one story at a time, and the story is where your writing stops being strategy and becomes the thing a builder actually picks up Monday morning.

So what's a story? One specific piece of functionality that delivers value to a user, small enough to finish inside a single sprint, the team's short fixed work cycle, usually one or two weeks. The epic says "automate payment reminders." A story says "a finance lead can set the reminder schedule." One promise, broken into pieces a developer can pick up Monday and demo Friday.

The craft of writing a story comes down to a single discipline. When you write one, you're not prescribing a solution. You're outlining what solves the problem. The person doing the work then gets to decide the best way to build it.

A story tells the team what done looks like, not how to build it. The moment you prescribe the solution, you've turned an engineer into a typist.

Now one word about words. Teams don't all size these the same way, and that trips people up. So here's the baseline this page uses, plain and up front: a story is one to three days of work, and a task is under a day, so a story is the small end of a sprint, not the whole thing. Some teams run stories at a different grain, and some run stories and no tasks at all, and break the work straight into a checklist. None of that is wrong. Just know which size you mean when you say the word, because half the arguments about "is this a story or a task" are really arguments about a definition nobody wrote down. Write yours down. Then this page travels with you no matter how your team slices it.

"But my developers want detail." They do, and you should give them plenty. Detail about the user. Detail about the problem. Detail about what acceptance looks like. All of it, all day. Detail about the implementation is theirs to own. They're closer to the code than you are, and deciding how is most of what makes the work theirs. Marty Cagan drew a line years ago between teams of missionaries, who own the why and decide the how themselves, and mercenaries, who just execute a spec someone handed them. Prescribing the solution is one of the fastest ways to turn a missionary back into a mercenary.

Why does a whole page exist for this? Because of the story that bounces back. A developer picks up the card (the story as it lives on the board, the shared list where the team tracks every piece of work), reads it, and comes back with twelve questions. That one costs you a morning. The story that doesn't bounce back costs you more. The developer guesses, builds exactly what the card says, and what ships is what they guessed. Both failures were written into the card before the sprint ever started.

What makes a story good

Six tests, and they aren't mine. Bill Wake's INVEST checklist has been the standard since 2003, the early days of agile, and it earns the spot:

  • Independent. It can be built and tested on its own, without waiting on another card.
  • Negotiable. The details can still be discussed and refined. The card starts a conversation, it doesn't end one.
  • Valuable. It delivers something a user can feel.
  • Estimable. The team can size it with confidence. (The sizing itself happens in planning poker, the team's estimation game, back on the Agile page.)
  • Small. It fits inside one sprint.
  • Testable. There's a clear way to know it's done.

When a draft story fails one of these, you've usually written one of three other things by accident: a solution, an epic, or a wish. Stick with me, you'll catch all three before this page is done.

The template, top to bottom

Title. The story stated as one line: As a [user type], I can [action] so that [benefit]. Yes, the whole sentence goes in the title field, that's the point. "As a new user, I can sign up with my Google account so that I save time." The title alone tells a stranger who this serves and why they'd care. You're writing for a person, not a ticket number.

Description. The When / As / I want / So that / But formula, one more time: When [the situation hits], As [this user], I want [this], So that [this payoff], But [the friction in the way today]. This is the third level you've watched it travel. It defined the problem back in Part 04, it headlined your epic on the last page, and it opens the story now. Same shape, smaller grain. If you can't fill in the But, you haven't found the friction this story removes, and better you find that out than your developer does.

Solution approach. One or two sentences on direction, and this is where the discipline gets tested. Outline the approach, don't write the spec. The template lists this field above acceptance criteria because that's the order it reads in, but you fill it in second: write the acceptance criteria first, then come back up here, because knowing what done means keeps the approach honest. The minute this section starts naming components and functions, you've started doing the engineer's job, badly.

Technical notes. Constraints, not preferences. The library the team already uses. The case that bit you last quarter. The system this has to play nice with.

Acceptance criteria and definition of done. The heart of the card. I'll break both down for you in a second.

Task breakdown. The story's list of technical pieces, each one a task: the day-sized-or-smaller chunk of work one person can pick up and own. A one-to-three-day story breaks into a handful of them. Writing those tasks, and the hour-sized sub-tasks inside each one, is the next page's job.

Dependencies. What must land first, and what this unblocks. Same courtesy rule as the epic page.

(My template carries a Labels field too: the tags your team uses to filter and group cards. Same call as the epic page. Steal your team's convention, not mine. The field is meant to be flexible.)

Acceptance criteria: what complete means

Acceptance criteria do three jobs. They lock the whole team on the same understanding of what to build before anyone starts. They tell the team when the story is complete. And they give your tests something to verify against, automated or otherwise.

Here are four acceptance criteria from a simple signup form with a payment step:

  1. A user cannot submit the form without completing all the mandatory fields.
  2. Information from the form is stored in the registrations database.
  3. Payment can be made via credit card.
  4. An acknowledgement email is sent to the user after submitting the form.

Read them again. Not one says how. No form library, no schema, no payment provider, no email service. We aren't telling the builder how the work gets done. We're outlining what complete means for the user.

That's the test for every criterion you write. And to catch the bounce-backs before they happen, cover four kinds of scenario, not just one:

  • The happy path. Everything works, the user gets what they came for.
  • The edge cases. The unusual-but-real inputs: the empty cart, the already-paid invoice, the expired link.
  • The error states. Something fails, and the user has to know what and what to do next.
  • The performance bar. It's not enough that it works. It has to work fast enough to be usable.

The happy path is the one everybody writes. The other three are where the twelve questions come from. Write them down, and the questions get answered on the card instead of in your inbox.

When a criterion needs more precision, write it in the Given / When / Then shape, a convention borrowed from behavior-driven development, the practice of writing software behavior as plain-language scenarios anyone can read: Given the setup, When the action, Then the result. You'll see it in the worked example below. And keep all of it implementation-free. Acceptance criteria describe the result a user can verify, never the code that produces it.

Definition of done is sprint-wide

Acceptance criteria belong to one card. Definition of done belongs to every card in the sprint. It's the quality bar the whole team agreed to, the shared answer to one question: could we ship this as is?

Mine runs short. Three questions:

  • Has the work been peer reviewed?
  • Did all the unit tests pass?
  • Did the product lead review it?

Notice the first question says work, not code. Swap in whatever your team produces: a report, an analysis, an architecture document. The bar applies to all of it, which is exactly what separates it from acceptance criteria. Acceptance criteria tell you this one story behaves. Definition of done tells you everything this sprint produced is shippable.

Don't confuse the two and don't skip either. A card can pass its own acceptance criteria and still fail the definition of done because nobody reviewed it. Both gates, every card.

Breaking an epic into stories

An epic becomes stories along one of three seams. By user type: the new user's story, the enterprise user's, the mobile user's. By feature slice: the core flow, the social login, the auto-save. By technical layer: the screens, the plumbing behind them, the connections to other systems.

Pick the seam that lets the stories ship independently. A good cut gives you cards a team can build in parallel and release one at a time. A bad cut gives you a pile of pieces that only mean something once they're all done, which is just the epic again, chopped up for show.

And here are the three accidents from earlier, caught in the wild:

  • The solution. "As a developer, I want to refactor the database" is not a story, it's a technical task wearing a story's clothes. No user wants your refactor. If the refactor matters, it produces something a user can feel: faster signup, fewer failures. Write that, and let the refactor live in the tasks underneath.
  • The epic. "As a user, I can complete the entire onboarding flow" is an epic wearing a story's title. It won't fit in a sprint, and it has no single thing to test. Split it.
  • The wish. "As a user, I want the app to be fast" sounds noble and tests like nothing. There's no way to know when it's done, which means there are no acceptance criteria to write. If you can't write the criteria, you wrote a wish, not a story.

One more trap that isn't a disguise: the dependent chain. If story two can't start until story one finishes, and story three waits on two, you've built a tiny waterfall inside your sprint. Decompose so stories can run in parallel wherever possible. A little dependency is unavoidable. A chain is a planning failure you wrote yourself.

Last page's epic, as stories

Last page ended with an epic: Automate Payment Reminders for Finance Teams, from the playbook's illustrative invoicing case. Break it along the feature-slice seam and you get something like:

  • As a finance lead, I can set a reminder schedule for overdue invoices so that customers get nudged without me typing a single email.
  • As a customer, I can pay an invoice straight from the reminder email so that paying takes one click instead of a login and three screens.
  • As a finance lead, I can see which reminders went out for an invoice so that I know who's been nudged before I pick up the phone.

Notice what's not here: partial payments. The epic's Out of Scope section already carved that work out into a future epic of its own, and this decomposition respects the boundary.

Take the pay-link story one level down and its Description fills in the same formula: When a payment reminder lands in my inbox, As a customer with an overdue invoice, I want to pay straight from the email, So that paying takes one click, But today the link sends me through a login and three screens before I ever see a payment form. The But is doing its job. It names the friction this story removes.

Now the acceptance criteria for the same story, covering all four scenario types:

  • Given an invoice is past due and a reminder email went out, When the customer clicks the pay link, Then they land on a payment page for that exact invoice, and payment can be made via credit card. (Happy path.)
  • Given the invoice was already paid, When the customer clicks an old reminder link, Then they see the invoice marked paid instead of a payment form. (Edge case.)
  • Given a payment fails, When the customer retries, Then they see what went wrong and can try another card without starting over. (Error state.)
  • The payment page loads inside the bar your team sets. (Performance.)

The load-time bar comes from your team's standard, not this page, so the criterion points at that bar instead of naming a number.

Run the thesis test one last time: nowhere did we name the payments provider, the email service, or a single function. What solves the problem is on the card. How is the builder's.

Before you call it ready

The last pass before a story goes in the sprint:

  • User value stated in the title
  • Acceptance criteria cover happy path, edges, errors, and performance
  • Tasks broken out (next page)
  • Dependencies identified, no external blockers
  • Testable by QA, the people who verify the work: not just a clear definition of done on paper, but a way someone other than the builder can actually check it
  • Fits inside one sprint
  • Connected to its parent epic

That last line is the same tripwire the epic page set. A story with no parent epic is work with no why, and it gets the same treatment: back through the loop, or out of the backlog.

So write yours like the builder won't ask, because more and more the builder won't. On my own projects the developer who picks up the story cold is an AI agent. I run a full sprint workflow inside the project, epics, stories, tasks, and bugs, and the agents do the building. I manage them like an in-person product and engineering team, and I built a Jira-like app called AgileMaestro to run the work and watch what the agents are up to in real time. The agent doesn't stop to ask. It just builds what the card says, which means the card that doesn't bounce back ships your guess. And the clearer the story, the better it builds. Take the epic from last page, pick a seam, and break it into stories a stranger could build cold. Write the acceptance criteria before the solution approach. If you catch yourself naming the database, stop and write what done looks like instead.

Then break each story into work one person can finish in a day. That's the next page.