End-to-end development scenarios

The end-to-end page gave the command skeletons. This page gives the stories: four realistic development runs narrated turn by turn, with the decisions, the mistakes, the recoveries, and the model and token choices a subject-matter expert actually makes. They assume you know the skills (from the command reference) and the recipes (from the cookbook); here we watch them used under real conditions.

On this page

Scenario 1: a solo founder ships a SaaS MVP (greenfield)

The situation. One developer, a two-week runway, an idea for a "read-later for podcasts" app: save episodes, auto-transcribe, get a searchable feed. Enough epics (accounts, ingestion, transcription, search, billing) that it earns the full method, but a small enough team that ceremony has to earn its place.

Day 1, framing. She opens a fresh chat and, rather than describing the app to the PRD skill cold, starts wider:

bmad-brainstorming
> How should a "read-later for podcasts" differentiate from Snipd and Airr?

The coach pulls forty ideas out of her before organizing; the useful ones cluster around "transcription quality is the moat." She forges the riskiest assumption:

bmad-forge-idea
> Idea: auto-transcribe every saved episode on ingest. Goal: decide if this is
> viable on a solo budget.

The interrogator lands it as Clearer, not Hardened: transcribing everything on ingest is too expensive; transcribe on first open instead. That one exchange saved a month of the wrong architecture. She does not even keep the artifact; the value was the decision.

Day 1, research. The open question is transcription cost and quality. She has a flat-rate chat subscription, so she uses Draft mode rather than burning IDE tokens:

bmad-deep-recon draft a technical research prompt comparing self-hosted Whisper,
OpenAI, Deepgram, and AssemblyAI on cost-per-hour, accuracy, and latency, for Gemini

She runs the drafted prompt in her chat tool, brings the report back, and Processes it into research.md. The report's staleness map flags the pricing claims as aging fast (a technical pack sets versions and pricing to short windows), which she notes for later. Cost so far in IDE tokens: almost nothing.

Days 2 to 3, planning. PRD on the strong tier (Opus), coached discovery, source-extracting the brief. She runs UX too, because how the transcript reads on a phone is the product:

bmad-prd        # Create -> prd.md, FR-4 "transcribe on first open"
bmad-ux         # DESIGN.md + EXPERIENCE.md; the reading journey is the climax beat

Day 4, solutioning, and the first mistake. She skips architecture ("it's just CRUD plus a job queue") and jumps to stories. Halfway through implementing ingestion, the dev agent picks a different job-queue pattern than the one the transcription story assumed, because nothing wrote the decision down. She catches it in code review, and the fix is not to patch two stories: it is to do the solutioning she skipped.

bmad-architecture                    # ARCHITECTURE-SPINE.md: ADR "one queue, Redis+RQ"
bmad-generate-project-context        # project-context.md: the queue rule, the transcribe-on-open rule
bmad-create-epics-and-stories        # re-cut, now consistent
bmad-check-implementation-readiness  # PASS

The lesson she writes into project-context.md: "All async work goes through the single RQ queue; no ad-hoc threads." Every future dev story now inherits it. This is why solutioning matters, learned the expensive way.

Days 5 to 12, implementation. Sprint planning once, then per story in a fresh chat: create-story, dev-story at xhigh, code-review. She runs the bulk of stories on Sonnet 5 to stretch the budget and escalates the one genuinely hard story (the search ranker) to Opus. After the epic, bmad-qa-generate-e2e-tests and a retrospective. The retrospective's lesson ("transcription jobs need idempotency keys; a retry double-charged the API") goes straight into project-context.md.

Day 12, the moving target. The transcription vendor she chose repriced. Rather than re-researching, she refreshes:

bmad-deep-recon
> refresh the technical research

Refresh re-verifies only the stale pricing claims and appends a delta: the vendor is now 20% cheaper, no decision change. It warns that the overturned price fed FR-4's cost model, so she re-opens the PRD under Update, bumps one number, and moves on. Research-to-spec-to-refresh, the whole loop, on a Tuesday afternoon.

What made it work. Framing before searching killed the expensive idea early; Draft mode kept research nearly free; skipping architecture cost a day and taught her why the phase exists; project-context.md turned each mistake into a permanent guardrail. She shipped in twelve days with a spec chain a future hire can read.

Scenario 2: a team adds a feature to a legacy monolith (brownfield)

The situation. Four engineers, a five-year-old Rails monolith nobody fully understands, a mandate to add "team workspaces" (multi-tenant data isolation across a schema that assumed single tenants). High blast radius; several epics that different engineers will implement in parallel. This is exactly where uncoordinated agents make incompatible decisions.

Week 1, ground truth. Before any planning, they make the codebase a citable source:

bmad-document-project            # scans the monolith, writes orientation docs
bmad-generate-project-context    # captures the real conventions: Sequel not AR, service objects, etc.

They commit both. Now every engineer's BMAD refers to the actual system, and a teammate who clones the repo gets the same understanding.

Week 1, research the invisible part. Multi-tenancy in a shared schema is a minefield of options (row-level, schema-per-tenant, database-per-tenant) with real security stakes. They Run a domain-and-technical recon with high validation, and because it is a build-vs-approach decision, the select shape:

bmad-deep-recon
> help me choose between row-level tenancy, schema-per-tenant, and db-per-tenant
> for a Rails+Sequel monolith at our scale; verification high

The selection matrix, re-weightable, lands on row-level with a Postgres RLS policy, with the runner-up (schema-per-tenant) and the conditions under which it would win instead. The red-team pass surfaces the strongest counter-argument (RLS is easy to bypass with a raw connection), which becomes an architecture constraint rather than a surprise in production.

Week 2, plan and pre-empt conflicts. The PRD (John) turns the decision into requirements; the architecture (Winston) writes the ADRs that keep four engineers consistent: the tenancy key, where it is injected, the RLS policy, the naming convention for tenant-scoped tables. These ADRs are the shared context every implementer reads first, so engineer A's epic and engineer C's epic make the same choices without a meeting. The readiness gate returns CONCERNS ("no story covers the raw-connection bypass the red-team found"); they add one, and it goes to PASS.

Weeks 3 to 4, parallel implementation. Each engineer owns an epic, branches per story, and runs create-story / dev-story / code-review in their own IDE. They coordinate through git and PRs, not through BMAD (which has no built-in multi-human coordination), and put hand-off notes in the stories themselves. The shared sprint-status.yaml, committed, is the one ledger everyone reads. Mid-sprint, product changes the requirement ("workspaces need per-seat billing too"). Instead of four engineers patching four epics, the PM runs:

bmad-correct-course
> add per-seat billing to the workspaces epic; reconcile the plan

which reconciles the PRD and re-routes the stories, then the change propagates. One engineer's half-built story is now wrong; they revert it (git revert HEAD) and re-create it from the corrected plan.

What made it work. document-project stopped the agents from inventing an architecture; the select-shape recon with a red-team pass turned a security minefield into written constraints; the architecture ADRs let four people (and their agents) build in parallel without colliding; correct-course absorbed the mid-sprint change at the source instead of in four places.

Scenario 3: a production hotfix under pressure

The situation. 11pm page: the feed is returning duplicate items after a deploy. One on-call engineer, needs a fix now, cannot afford a wrong one. This is Quick Flow territory, not the full method.

The fix. Fresh chat, intent as a bug-tracker link:

bmad-quick-dev
> https://linear.app/acme/issue/FEED-812  (feed shows duplicates since the 10pm deploy)

Quick Dev compresses the intent, asks one clarifying question ("dedup by item id or by story cluster?"), and because the change touches the ranker (not zero-blast-radius) it writes a short spec, gets her one-line approval, then implements against that boundary. It self-reviews, defers an unrelated nit it noticed (a slow query) to deferred-work.md rather than scope-creeping the hotfix, and commits locally.

The review, in comprehension order. At 11pm she does not want to read a diff in file order. She says:

checkpoint

bmad-checkpoint-preview walks her through the change by concern ("the dedup key now includes story_id"), flags the one highest-blast-radius spot ([ranking] the change to the sort comparator), and suggests how to observe it manually (hit the staging feed, confirm no dupes). She verifies, approves, and it helps open the PR.

The recovery that wasn't needed, and the one that was. The fix deploys clean. Two days later the deferred slow-query note surfaces in bmad-loop-sweep's triage of the deferred ledger, and becomes a proper story in the next sprint. Had the hotfix itself gone wrong, the recovery was one command away: git revert HEAD undoes a Quick Dev change cleanly because it committed as one unit.

What made it work. Quick Flow skipped the ceremony a page couldn't wait for, the spec boundary kept the fix from wandering, checkpoint-preview made the 11pm review fast and safe, and deferral kept the hotfix a hotfix instead of a refactor.

Scenario 4: an autonomous overnight epic (the loop)

The situation. A well-specified epic of twelve small, independent stories (add API endpoints for a dozen resource types, all following the same pattern). The team wants them implemented overnight, human on the loop rather than in it.

Setup. They already have the epic's stories as an ordered stories.yaml (produced by bmad-spec). They install the loop and choose an oversight level they trust for this low-risk, repetitive work:

bmad-loop-setup
# gates.mode = per-epic  (pause between epics, not between stories)
bmad-loop run

The loop is deterministic Python driving the sequence pick -> implement -> adversarially review -> verify -> commit, with each step a fresh coding-agent session so no anchoring bias carries between dev and review. Via the mux they point implementation at their strongest coding model and the adversarial review at a different agent, so the reviewer is genuinely independent. They set a task budget so the loop paces itself and cannot run away with tokens.

Overnight. Ten stories go green. Story 7 comes back blocked: an intent gap (the resource has a soft-delete the spec did not mention). The loop does the right thing: it halts that story, saves the attempted change as a patch, and moves on to the stories that do not depend on it. blocked is a routing signal, not a crash, so the run does not die; it parks the ambiguous one and keeps going.

Morning. The engineer reads sprint-status.yaml: ten done, one blocked, one pending on it. He resolves the escalation:

bmad-loop-resolve FEED-807
> soft-delete: exclude deleted rows from list, 404 on get, hard-delete after 30 days

which disambiguates the frozen spec; the loop re-dispatches story 7 and the one that waited on it. He reviews the ten committed stories with bmad-checkpoint-preview (the loop committed but never pushed), spot-checks the independent review's findings, and pushes. The retrospective notes the missing soft-delete convention, which goes into project-context.md so the next batch generates it correctly from the start.

What made it work. A deterministic control loop with no LLM in the driver's seat made it debuggable and free to run; fresh context per step kept review honest; the mux gave real reviewer independence; blocked parked the one ambiguous story instead of failing the batch; and the human's attention went where it mattered (one disambiguation and a morning review) rather than to twelve identical implementations.

The common thread

Hands-on: reproduce the 11pm hotfix, command by command

Scenario 3 as an exact sequence. Paste it, swap the URL, and you have a disciplined hotfix under pressure. BMAD and Claude Code are not installed on the box that wrote this page, so commands are given verbatim and every transcript is labeled illustrative.

1. Fresh chat, fresh branch. A page-time change should not inherit a stale context window. Cut a branch first so the revert later is clean:

git switch -c hotfix/FEED-812

2. State the intent as the ticket. Open a new chat, invoke bmad-quick-dev (the Quick Flow entry from the command reference), and hand it the bug-tracker URL rather than a paraphrase; the ticket carries the repro:

bmad-quick-dev
> https://linear.app/acme/issue/FEED-812  (feed shows duplicates since the 10pm deploy)

3. Answer the one question; approve the spec. Because the change touches the ranker (not zero-blast-radius), Quick Dev asks one disambiguation, writes a short spec, and waits:

Illustrative (run it in your own repo; not machine-verified here).

Q: dedup by item id, or by story cluster?
> by story cluster

Spec: add story_id to the dedup key in rank_feed(); no other call sites touched.
Approve? (one line)
> approved

4. Let it implement and commit locally. It works against that spec boundary, self-reviews, defers the unrelated slow-query nit to deferred-work.md rather than scope-creeping, and commits as one unit. Do not push yet.

5. Review by concern, not by file. At 11pm you read for blast radius:

checkpoint

bmad-checkpoint-preview walks the diff grouped by concern and flags the hot spot:

Illustrative (run it in your own repo; not machine-verified here).

[dedup]   dedup key now includes story_id      low risk
[ranking] sort comparator changed              HIGHEST blast radius  (verify)
observe:  hit staging feed, confirm no dupes

6. Confirm on staging, then open the PR.

curl -s https://staging.acme.internal/feed | jq '[.items[].id] | length - (unique | length)'  # want 0
gh pr create --fill --base main

7. Safety net. If it regresses in prod, one command undoes it cleanly, because the fix is a single commit:

git revert HEAD

What makes it safe: the spec boundary stops the fix wandering, deferral keeps a hotfix a hotfix, checkpoint-preview puts the riskiest line first, and single-commit discipline makes git revert HEAD a guaranteed undo.

Under Claude Code: the four runs, host-side

BMAD's four runs map onto Claude Code the same way; the end-to-end skeletons stay, dialed by host controls.

Solo SaaS greenfield. Frame and plan in plan mode: Shift+Tab cycles to plan (or launch claude --permission-mode plan), read-only exploration that proposes before it edits any source. Run the bulk stories cheap and escalate the search ranker with /model (/model sonnet for volume, /model opus for the hard one; the switch saves to user settings, so flip it back after). Watch spend with /usage (the old /cost): session cost, wall-vs-API duration, and a per-model breakdown.

Team brownfield monolith. Pull the legacy tree into scope with /add-dir <path> (or claude --add-dir at launch), which also loads that directory's .claude/skills/. Commit a shared .claude/: settings.json, skills/, agents/, rules/, .mcp.json, so four engineers' agents inherit one set of conventions from git. Make the raw-connection ban enforced, not advisory: a PreToolUse hook matching Bash returns {"permissionDecision":"deny"} on the bypass command.

11pm hotfix. Fast local loop with claude --permission-mode acceptEdits: edits and common filesystem commands auto-approve while you review. If it goes wrong, /rewind (Esc-Esc on an empty prompt) restores Claude's own Read/Edit/Write changes; it is session undo, not git, so land one commit and keep git revert HEAD as the real fallback (rewind touches neither committed history nor bash side effects).

Overnight epic. Headless: claude -p "..." --bare --permission-mode acceptEdits --max-budget-usd N --max-turns M, one story per run, so a stuck story cannot drain the whole budget. Chain with --resume or start a fresh session between stories. In the morning, read the cost with /usage and the run itself from the transcript (/export).

Across all four: frame before you build, spend model capability and effort in proportion to the stakes, catch wrong turns at the cheapest layer, and turn every mistake into a line in project-context.md. The method is the same tool dialed from a one-command hotfix to an overnight autonomous epic; what changes is how much of it the work justifies. The last thing that separates a team that gets value from BMAD from one that drowns in it is knowing which mistakes to avoid, which is the next and final page. 👉