Skip to content

Playbook: MVP Build

Objective

An MVP built as a stack of verified vertical slices on a deployed walking skeleton — where "verified" means you watched each slice work end-to-end, and every subsystem has an explicit, recorded decision about whether it's demo-quality or production-quality. Agents make the typing cheap; this playbook keeps the verification from becoming the bottleneck that silently gets skipped.

When to use

After New Project (rails exist) and Idea to Spec (PLAN.md exists). If either is missing, do it first — an MVP built without gates or specs is where the 80%-demo trap lives.

Inputs required

  • The repo from New Project: gates green, CLAUDE.md in place.
  • specs/PLAN.md with session-sized, verifiable tasks.
  • A demo date or forcing function — it drives the quality-tier decisions below.

Step-by-step process

1. Vertical slices, not horizontal layers

Build "a user can create an invoice and see it in the list" — route, handler, DB, UI, one test — not "the data layer" this week and "the API layer" next week. Two reasons, both agent-specific:

  • Each slice is verifiable end-to-end. You can click it, curl it, demo it. A horizontal layer is only verifiable against your trust in the agent, which is exactly the currency you don't want to spend. Unverified layers stack silent errors that all surface at integration time, in someone else's session, with none of the original context.
  • Each slice fits one session. A layer spans the whole system and exceeds any context window; a slice is naturally scoped. This is why PLAN.md was decomposed into slices in the first place.

2. Walking skeleton first — deployed, with CI

Before slice one: a hello-world that is deployed to the real target with CI running the gates on every push. Deployment is the integration risk most likely to eat a surprise week; buy that knowledge when the system is 50 lines, not 5,000.

text
Read specs/PLAN.md task 1. Set up deployment of the current skeleton to
<target, e.g. Fly.io> : config in the repo, deploy runs from CI on merge to
main, and the health endpoint publicly reachable. Change no application
code beyond what deployment strictly requires. When done, give me the
public URL and the exact command you expect me to run to verify.

Open the URL yourself. The skeleton is done when a stranger could see it.

3. Decide quality tiers per subsystem — explicitly, in writing

The load-bearing step. For each subsystem, decide demo-quality or production-quality before the agent touches it, and record it in PROJECT_CONTEXT.md:

markdown
## Quality tiers (MVP)
| Subsystem | Tier | Meaning |
|---|---|---|
| Auth | Production | Real sessions, hashing, lockout. Never stub. |
| Billing | Stub | `FakeBillingProvider`, logs charges. Interface real, provider fake. |
| Email | Console | Log to stdout. No provider, no queue. |
| Invoice engine | Production | This IS the product. Full edge cases. |

Why written: an agent that doesn't know billing is deliberately a stub will "helpfully" wire in Stripe when a task brushes against it (silent hardening — scope creep plus an unreviewed integration). An agent that sees console-email as precedent will stub auth the same way (silent softening — a security hole). Both moves are locally reasonable; only your recorded intent makes one wrong. With the table in context, tier changes become something the agent must propose, not improvise. See Docs as Memory.

4. One spec'd slice per session

Fresh session per slice, referencing the spec — not a mega-session that accumulates stale context across slices:

text
Read CLAUDE.md, PROJECT_CONTEXT.md, and specs/007-invoice-creation.md.
Implement task 7 exactly as spec'd. Respect the quality tiers table —
billing stays a stub. Stay within this slice: if you find adjacent
problems, list them at the end, don't fix them. When done, run `make check`
and give me the manual verification steps from the spec.

Then run the verification steps yourself before starting slice N+1. This human gate between slices is what keeps errors from stacking.

5. Know when the MVP is done

The MVP is done when the walking-skeleton scenario from your overview spec works for a real user — not when the plan is empty. Leftover PLAN.md tasks are v1.1, and moving them there is a one-line edit, not a failure.

Human review points

  1. Skeleton deployment — you open the public URL (step 2).
  2. Quality-tier table — a product decision; the agent may draft the table, only you fill the Tier column (step 3).
  3. Per-slice verification — you execute each spec's manual check before the next slice starts (step 4).
  4. Tier changes — any promotion (stub → real) or demotion is proposed to you, spec'd, and the table updated first.

Expected artifacts

Deployed walking skeleton with CI · PROJECT_CONTEXT.md with the tier table · one merged, human-verified branch per slice · PLAN.md with tasks checked off · specs updated where reality diverged (Keeping Specs Alive).

Common failures

SymptomRoot causeEarly detectionFix
The 80%-demo trap: demo dazzles, every path off the demo script 500sDemo-quality everywhere by default, no tier decisions ever madeTry three actions the demo script doesn't includeStep 3: explicit tiers; "production" subsystems get spec'd edge cases like anything else
Unverified slices stack; slice 9 breaks and the bug is from slice 4Human verification skipped when gates were greenYou can't remember personally exercising the last sliceThe between-slice gate is non-negotiable; if it lapsed, stop and verify all merged-but-unverified slices now
Scope creep via agent enthusiasm: slice adds retry logic, an admin view, "better" error pagesAgent fills slack with plausible adjacencies; each looks like diligenceDiff touches files the spec never mentions"Stay within this slice; list, don't fix" clause; reject nonconforming diffs — see Scope and Context Failures
Stub silently hardened (real Stripe calls appear) or real subsystem silently stubbedTier decisions absent from agent contextNew dependency or deleted check in a diff that didn't announce itThe tier table in PROJECT_CONTEXT.md, referenced in every implementation prompt
Slice "done" but only unit tests prove itVerification defined as tests-pass, not works-end-to-endSpec's manual check was never written or never runEvery slice spec names a human-executable check; see Verification Checklists

Recovery strategy

If unverified slices have stacked, freeze feature work and bisect: verify each merged slice end-to-end from oldest unverified forward, fixing or reverting per slice in its own session. If demo-quality code has quietly become the whole codebase, run the tier exercise retroactively — the table is even more valuable when the promotion work (stub → production) still has to be scheduled honestly. Full agent-mess recovery is its own playbook: Recovery.

Acceptance criteria

  • [ ] Skeleton deployed and CI-gated before any feature slice
  • [ ] Tier table exists in PROJECT_CONTEXT.md and is cited in implementation prompts
  • [ ] Every merged slice was human-verified end-to-end, not just gate-green
  • [ ] No diff touched subsystems outside its spec without an explicit tier-change decision
  • [ ] The overview spec's walking-skeleton scenario works on the deployed system

A field manual for AI-native software engineering.