Blog · Guide

User story mapping for people who build with coding agents

Dmitrii Bugaev · · 8 min read

You have a coding agent, and it writes code fast. Three weeks into a side project you have a login screen with three sign-in options, half a settings page, and a PLAN.md you last touched a month ago. Every new session starts with a recap. The agent finishes something and asks what to do next, and you type “ok, now do this” for the tenth time today. Then it reports “Done, all tests pass”, and you find the case it skipped.

Most people who build this way already have a plan. What it usually lacks is order. A list of features doesn’t say which ones a user needs first, which one the agent should build next, or what “done” means for each.

This guide covers a product method that answers those three questions on one page. It’s called user story mapping, and you can try it on your own project this afternoon, with or without any tool.

What a story map is

Jeff Patton described the method in his book “User Story Mapping” (O’Reilly, 2014). His argument, roughly: a flat backlog of features loses the story of what the user is trying to do, so lay the work out along that story.

A story map has three parts:

  • Steps across the top. The things a user does with your product, left to right, in the order they do them: “finds the club”, “signs up”, “books a class”. Patton calls this row the backbone.
  • Stories under each step. What the user can do at that step, written from their side. The most essential ones go at the top of the column.
  • Releases as horizontal slices. Draw a line across the whole map. Everything above it is the first release, the next band is the second release, and so on.

The rule that matters most is about the first release. It should be the thinnest version of the product that works end to end, with at least one story under every step. A user should be able to walk the whole journey in it, even if each step is crude.

A list hides gaps like that. On a map, an empty column is easy to spot. If “pays” has nothing above the first line, your first release can’t take money, and you see it before you build the fifth sign-in option.

A worked example: booking classes at a sports club

Say you’re building a booking app for a local sports club. Members book classes, pay, and come back next week. Today the coach keeps a paper list and takes cash at the desk.

The journey has five steps: finds the club, signs up, books a class, pays, comes back. Here are a few stories under each, split into the first release and later ones. On a real map the steps run left to right and the release is a line across; the table below shows the same thing in less width.

Step First release Later
Finds the club Public page with this week’s schedule Coach profiles, reviews
Signs up Sign up with email Sign in with Google, family accounts
Books a class Book a spot, see my bookings Cancel a booking, waitlist when a class is full
Pays Pay at the desk; the coach marks the booking paid Card payments, monthly passes
Comes back Email reminder the day before class Rebook last week’s class, attendance history

Why this cut:

  • Every step has something, so on Monday a real member can find the club, sign up, book, pay and get a reminder. You learn from real bookings in the first week.
  • Paying at the desk looks primitive, but the club already works that way. Card payments mean a payment provider, webhooks, refunds and receipts. That is a release of its own, and it’s worth more once you know people actually book.
  • The waitlist only matters when classes fill up. With twelve members, they won’t.
  • Google sign-in and family accounts are nice to have. Neither stops anyone from booking.

Notice what’s missing from the table: “set up the database”, “add auth middleware”. Those are pieces of work the agent does inside a story. A story is something the user gets.

Acceptance criteria an agent can check

A story says what the user gets. Its acceptance criteria say how you’ll know it works. An agent treats them as its definition of done, so they need to be things it can verify by running a test or the app.

Here is “Book a spot” with weak criteria:

  • Booking works correctly
  • Good user experience
  • Handle edge cases

Each of these makes the agent guess. It will pick some edge cases, test those and report done. You’ll find the one it didn’t pick.

The same story with criteria it can check:

  • A signed-in member sees a “Book” button on each class that has free spots
  • After booking, the class shows up under “My bookings” with its date and time
  • A member can’t book the same class twice
  • When the last spot is taken, the button reads “Full” and a booking attempt is refused, even if two members press “Book” at the same moment

A few rules that help:

  • One observable behavior per criterion. If a criterion has “and” in the middle, it’s probably two.
  • Write down the edge case you care about. “Two members press Book at once” is checkable. “Handle concurrency” is a wish.
  • Describe what the member sees. “Use a database lock” is an implementation choice; leave it to the story’s description or to the agent.
  • Two to five per story. If you need ten, you have two stories.

How working with the agent changes

With a map and criteria in place, the session loop gets simpler.

One story per session. Start a fresh session and hand the agent one story with its criteria. That’s the whole brief. Nothing important lives in the chat, so compaction can’t lose the plan.

The agent takes the next story of the release. The order comes from the map: through the steps from left to right, top to bottom within each step, first release only. You stop picking the next task by hand, and the agent stops asking.

Criteria get checked as it goes. The agent ticks each criterion once it has verified it. A story counts as done when every criterion is ticked. One unticked criterion keeps it open.

It stops at the end of the release. When the first release has no open stories, the agent says so and stops. It doesn’t wander into “Later” because the waitlist looked related. What comes next is your call.

You review on the map. Done, in progress and not started are visible at a glance, so you always know what step of the plan you’re on. Then you check the finished stories against their criteria, without scrolling back through a chat.

You can run this loop with a plain file. Keep a MAP.md in the repo, with the current release on top:

# Release 1
## Books a class
### Book a spot
- [ ] A signed-in member sees a "Book" button on each class that has free spots
- [ ] After booking, the class shows up under "My bookings" with its date and time
- [ ] A member can't book the same class twice

Then put the rules in your CLAUDE.md or AGENTS.md:

Read MAP.md. Take the first story in Release 1 with an unchecked criterion.
Work on that story only. Check off a criterion in MAP.md only after you have
verified it with a test or by running the app. When every criterion is checked,
stop and report. If Release 1 has no open stories, say so and stop.

The weak point is the same as with any plan file: it stays current only as long as the agent keeps updating it and you keep reading it.

Common mistakes

  • Steps named after screens or modules. “Dashboard”, “Settings” and “Backend” are parts of your app. A step is something the user does, so name it with a verb from their side.
  • Technical tasks as stories. “Set up Postgres” belongs inside the first story that needs it. Once cards describe work the user never sees, the map stops showing progress.
  • A first release that is one step done perfectly. Sign-up with three providers and email verification, and nothing to book. Go wide and thin first.
  • Stories too big for one session. If the agent runs out of context halfway, split the story. “Bookings” as one story is too big; “Book a spot” and “Cancel a booking” each fit a session.
  • Ideas with nowhere to go. If a story fits under no step, ask whether a user needs it at all. Usually not.
  • Treating the map as final. After the first release you’ll know more. Move stories between releases, add steps, drop what you no longer believe in.

Start in 30 minutes

You need one project, one kind of user and something to write on: sticky notes, a whiteboard, a spreadsheet with a column per step, or a markdown file.

  1. Steps, 5 minutes. Write the user’s journey as four to seven steps, left to right. Use verbs: finds, signs up, books, pays, comes back.
  2. Stories, 10 minutes. Under each step, list what the user can do there. Don’t filter yet. If you already have code, add what exists and mark it done; the gaps will show.
  3. The first release, 5 minutes. Draw a line. Above it go the fewest stories that let one real person get through every step. Everything else goes below.
  4. Criteria, 10 minutes. For each story in the first release, write two to five criteria an agent can check. Short on time? Do the first story only.

Then open a fresh session and give the agent the first story. When it reports done, check the criteria yourself before you move on. After two or three stories you’ll know whether your criteria are too loose.

If you’d rather keep the map outside the repo, Slicemap is built for this loop: the map lives in your browser, and Claude Code, Codex or Cursor takes the next story of the release, ticks off acceptance criteria as it checks them and stops when the release is complete. Here is how to connect your agent.

Try it on your own project

Sign-up takes a minute. The beta is free, and everyone who joins now gets three months of the paid plan for free when paid plans start.

Join the free beta