← Back to list

From Vibes to Specs: A Practical Guide to Spec-Driven Development with Claude Code

What spec-driven development is, why it matters, and how to operationalize it across an engineering team — without turning every CSS tweak…

CodeChuckle · 2026-06-13 11:26 · 6 claps · 11.8 min read
#claude-code #spec-driven-development #ai-coding #software-engineering #developer-productivity
Open on Medium ↗
Wiki topics: LLM · Large Language Models 💻 · Programming 🌐 · Web Development ⏱️ · Productivity

From Vibes to Specs: A Practical Guide to Spec-Driven Development with Claude Code

What spec-driven development is, why it matters, and how to operationalize it across an engineering team — without turning every CSS tweak into a three-act play.

TL;DR — Vibe coding is a great way to build a demo and a terrible way to ship a product. Spec-driven development (SDD) puts a written, reviewable, version-controlled artifact between the human’s intent and the agent’s output. With Claude Code, you can do this using primitives the tool already ships with — no framework required, but a few help. This post covers the workflow, the Claude Code primitives that make it work, and how to roll it out to a team without inviting a mutiny.

Part 1: Why “Just Vibe It” Stopped Being Cute

The first six months of agentic coding were a hackathon. You typed a paragraph, the agent typed a thousand lines, you crossed your fingers, and most of the time something compiled. Glorious.

Then we all hit the same wall, in roughly the same order:

  1. The diff looked plausible. It even ran. It was wrong.
  2. We asked for “a small change” and the agent rewrote half of an unrelated module.
  3. We came back two weeks later, asked the same agent to extend the feature, and it built something that contradicted what it had built before.
  4. The PR review devolved into “I trust it” or “I don’t” because nobody — not us, not the reviewer, not the agent — could point at the document that said what we were trying to do.

This is what people now call context rot, spec drift, or my favorite, AI slop. The agent is excellent at producing code; it’s much worse at remembering why. Long sessions degrade as the context window fills. Pivots leave architectural fingerprints nobody documents. And the tribal knowledge — the thing the senior dev usually carries between meetings — is invisible to the agent because it lives in your Slack DMs.

If code is the source of truth, your agent has to read all of it to understand any of it. That doesn’t scale. The fix is to flip the polarity: make intent the source of truth, and let code become a regenerable expression of it — what GitHub’s Spec Kit manifesto cheerfully calls a “last-mile” artifact. That, in one sentence, is spec-driven development.

Part 2: What Spec-Driven Development Actually Means

There’s a useful three-tier ladder, originally framed by Birgitta Böckeler and echoed across most serious writing on the topic:

Most teams should aim for Tier 2 right now. Tier 3 is where the field is heading, but it requires tooling we’re still building. Tier 1 is a trap — what Heeki Park nicely names the “spec-once” failure mode: you write a beautiful spec at kickoff, then immediately abandon it and start vibe-coding off it. Predictably, after three weeks, the spec describes a system that no longer exists.

The canonical SDD loop has converged across GitHub’s Spec Kit, AWS Kiro, BMAD, OpenSpec, Microsoft’s playbook, and the various Claude Code-native flavors (Superpowers, GSD, VSDD). It looks like this:

Constitution → Specify → Clarify → Plan → Tasks → Implement → Verify

Each arrow is a review gate — a stop where a human (or a different agent in a fresh context) can disagree before the next phase amplifies the mistake. The further left you catch a misunderstanding, the cheaper it is. As Solguruz’s writeup puts it: fixing a wrong assumption in a spec costs ten minutes; fixing it in code that’s already merged costs days. (And, I’d add, fixing it in production costs your weekend.)

A few definitions, because pedantry pays:

  • Constitution / CLAUDE.md — the immutable rules of your project: language, security posture, testing philosophy, “we never use mocks for the database.” Loaded into every session.
  • Specwhat and why, deliberately tech-stack-free. “Users can share photos with friends and revoke access” is a spec. “Use S3 presigned URLs and Postgres” is not.
  • Planhow. Stack, data model, contracts, file layout. The bridge between intent and code.
  • Tasks — the plan, decomposed. Dependency-aware, with explicit parallelism markers and acceptance criteria per task.
  • Implementation — the code. Generated, ideally one task per atomic commit.
  • Verification — a runnable signal that the change does what the spec said. Not “the agent says it’s done.”

If you’ve been doing engineering for more than a couple of years, this should feel suspiciously familiar. SDD is, at its heart, the SDLC your CS professor taught you, ported to a world where the typist is faster than you are. The only thing that’s new is that the agent — not the human — is the one most likely to skip steps, so the rituals have to be enforced, not encouraged.

Part 3: The Workflow, Phase by Phase, in Claude Code

Let me walk through how this actually plays out in a Claude Code session. I’ll keep it concrete.

Phase 0 — Write a constitution once, then leave it alone

In your repo:

.claude/
  CLAUDE.md            # team-shared rules, checked in
  CLAUDE.local.md      # your personal overrides, gitignored
  agents/              # subagents
  skills/              # on-demand domain knowledge
  commands/            # slash commands

A well-pruned CLAUDE.md is the single highest-leverage file in your repo. The trick comes straight from Anthropic’s best-practices guide, which says it plainly: for each line, ask “would removing this cause Claude to make mistakes?” If the answer is no, cut it. Bloated CLAUDE.md files paradoxically get less compliance, because the model treats them as background noise.

Phase 1 — Specify (the part where you resist the urge to start coding)

Open a fresh session. Don’t start with “build me a photo sharing feature.” Start with a paragraph of intent and let Claude interview you. The pattern works because the agent knows what it doesn’t know better than you know what you forgot to mention. Use AskUserQuestion (or any framework's clarify command — /speckit.clarify, /openspec-proposal, etc.) and answer the questions before writing a line of code.

A useful trick from Heeki Park’s writeup: ask Claude to give you multiple-choice options instead of free-form questions. You’ll iterate three times faster, and the model anchors on plausible answers rather than your half-formed first thought.

Save the output to docs/specs/<feature>.md. Commit it. The spec is now the source of truth — the moment it diverges from the code, one of them is wrong, and your job is to figure out which.

Phase 2 — Plan (in plan mode, with the editor open)

Hit Shift+Tab twice to enter plan mode. This is non-negotiable for any change you can't describe in one sentence. Plan mode keeps Claude from touching the working tree while it figures out the how.

Then — and this is the part most people miss — press Ctrl+G to open the plan in your editor. Edit it. Cross out the abstractions you don't want. Add the constraints Claude couldn't have known. The plan is a draft, not a verdict.

If your team uses GitHub Spec Kit, this phase produces plan.md, research.md, data-model.md, and contracts/ automatically. If you're going native, just have Claude write docs/specs/<feature>/plan.md

Phase 3 — Decompose into tasks

Tasks should be small enough that one of them fits in a single atomic commit and small enough that a fresh Claude session can execute it without re-reading the entire codebase. Most frameworks recommend capping a feature at 12–15 tasks; if it’s larger, split the spec.

Mark independent tasks [P] (the Spec Kit convention) so you can fan them out in parallel sessions. Yes, you can run multiple Claude Code sessions in parallel — tmux -CC in iTerm2 is the unfussy way; the various CU-style orchestrators are the fancy way.

Phase 4 — Implement (in a fresh context, every time)

This is the single most underrated anti-rot move — Oscar Llerena’s writeup gives it pride of place, and he’s right: start each task in a fresh session. Hand the new session the spec, the plan, and the one task. Don’t drag the previous session’s drift along for the ride. Atomic commit per task means if a task goes sideways, you git revert cleanly instead of unpicking entangled changes from a megadiff.

For low-risk tasks, run headless: claude -p "execute task 4 from docs/specs/photo-sharing/tasks.md" --allowedTools "Read,Edit,Bash". This is also how you pipeline SDD into CI — more on that below.

Phase 5 — Verify (or go home)

If you can’t verify it, you can’t ship it. Acceptable verification signals:

  • A test you wrote before the implementation that now passes.
  • A screenshot or playback for UI work.
  • A diff against a known-good fixture.
  • A separate Claude subagent, in a fresh context, told to find gaps only where they affect correctness or stated requirements — phrased that way to stop it manufacturing findings to look useful. (Reviewers asked to “find issues” will always find them, even when there are none. That’s how you end up with over-engineered PRs.)

A Stop hook is your friend here. It's a deterministic gate: tests must pass before the session ends. The agent can't sweet-talk its way past a non-zero exit code.

Part 4: The Claude Code Primitives That Carry the Weight

You don’t need to install a framework to do SDD. Claude Code already gives you the primitives. Here’s the mapping:

Part 5: Operationalizing SDD Across a Team

Solo SDD is easy. Team SDD is where most adoptions die — because the second a senior engineer skips the spec to ship a hotfix, three juniors learn that the rules are optional. You need the rituals to be cheaper than not following them.

Here’s the playbook I’ve seen work, distilled across a dozen companies’ writeups:

1. Pilot one feature. Don’t boil the ocean.

Pick a feature that’s medium-sized (2–5 days of work) and unambiguously valuable. Run it through SDD end-to-end with one engineer + one reviewer. Write down what was annoying. That is your real backlog.

2. Write the team constitution together.

Get four people in a room (or a Zoom). Write a 50-line CLAUDE.md with the conventions you actually argue about in PRs. Commit it. Add CLAUDE.local.md to .gitignore so personal overrides don't pollute the team rules.

If you have multiple stacks (Go services + a React frontend), use nested CLAUDE.md files per directory. A monorepo-wide CLAUDE.md quickly becomes a contradictory mess — what one author memorably called "stack contamination."

3. Standardize the spec template.

Five fields, no more: Goal · Non-goals · User stories · Acceptance criteria · Open questions. The “Non-goals” section pays for itself the first time it prevents scope creep — and it always does.

Specs live in docs/specs/<feature>/ next to the code. Branch-per-spec (feature/photo-sharing-spec-2026-q3). Treat spec PRs like any other PR — review, comment, merge.

4. Make spec review a merge gate.

This is the critical move. Until the spec is approved by the relevant humans (eng lead, product, security if relevant), no code generation begins. No exceptions. The whole value of SDD is that mistakes get caught at the cheap end of the pipeline; if you let people skip the spec review, you’ve reinvented vibe-coding with extra ceremony.

5. Bake non-negotiables into hooks, not prose.

Anything you’d write as “please always remember to…” in CLAUDE.md belongs in a hook. Pre-commit hooks for secret scanning. PostToolUse hooks for running the linter. Stop hooks for the test suite. Hooks are deterministic; prose is aspirational.

6. Set up the adversarial reviewer subagent.

Ship a .claude/agents/spec-reviewer.md to the repo. Its job is exactly one thing: read the diff against the spec and flag only gaps that affect correctness or stated requirements. The phrasing matters — without it, the reviewer manufactures concerns to justify its existence, and your engineers learn to ignore it.

7. Wire claude -p into CI.

A nightly job that takes each open spec and validates that the implementation still satisfies the acceptance criteria is — at the cost of a few cents — the closest thing you’ll get to free, continuous architectural review. It’s also the answer to spec drift: when the validator fails, one of the two artifacts is wrong, and you have a forcing function to figure out which.

8. Own the living docs.

Specs only stay alive when somebody owns the synchronization. The pattern that works is owner + sync + gate: each spec has a named owner, the sync is part of the merge ritual, and CI is the gate that blocks divergence. Without all three, your specs degrade into a shrine to your past intentions.

9. Know when not to use SDD.

This is the part the evangelists skip. SDD is overhead. For:

  • Tweaking a CSS value
  • Bumping a dependency
  • Renaming a variable
  • Anything you can describe in a single sentence and verify with a single test

…just do the thing. The break-even point most authors converge on is the fourth or fifth feature in a project. Below that, the spec ceremony costs more than the drift it prevents.

A useful heuristic: if a junior engineer would describe the change in two sentences and a senior in three, you don’t need a spec. If you can’t describe the change without saying “and also,” you do. (DataCamp’s tutorial puts the break-even right around feature four or five — that matches my own experience.)

Part 6: Anti-Patterns I’ve Watched Teams Walk Into

A short, painful tour:

The Spec Once. Beautiful spec, then nobody ever opens it again. Cure: own + sync + gate.

The Bloated Constitution. CLAUDE.md grows to 800 lines, contains the team's snack preferences, and the agent ignores most of it. Cure: ruthlessly prune; if a line wouldn't catch a mistake, delete it.

The Eternal Session. Engineer keeps one Claude session running for three days. By Wednesday, the model is gaslighting itself. Cure: fresh sessions per task; /clear between unrelated work.

The Reviewer That Always Finds Something. Subagent reviewer phrased as “find issues with this code” produces a list of fictional issues for every PR. Junior engineers earnestly implement them. Cure: phrase as “flag only gaps that affect correctness or stated requirements.”

The Vague Spec. “Add photo sharing to my app.” Twelve thousand things go unstated. Cure: clarify-before-plan; the spec is done when the agent stops asking questions, not when you stop typing.

The Mocked Database Test. Tests pass. Migration breaks in prod. Cure: integration tests hit a real database. Yes, even the slow one.

The CSS Spec. Engineer writes a 200-line spec to change a button color. Cure: don’t.

The Two Sources of Truth. CLAUDE.md says one thing, framework config says another, the agent picks "whichever it saw last." Cure: pick one; don't layer frameworks on top of each other unless you understand exactly what wins.

Part 7: A Worked Example, in 60 Seconds

Imagine docs/specs/photo-sharing/ after a real session:

spec.md          # what + why, no stack
plan.md          # data model, endpoints, file layout
tasks.md         # 11 tasks, 4 marked [P]
research.md      # claude's research output
contracts/
  api.openapi.yaml
quickstart.md    # how to run the new feature locally

The spec is reviewed in a PR. The plan is reviewed in a PR. Tasks are executed in fresh sessions, one atomic commit each. A Stop hook runs the test suite. A subagent does a final pass against the spec. CI runs claude -p against the spec to validate alignment. The PR description links to the spec. Future-you, six months from now, opens the spec before changing anything.

That’s it. That’s the whole game.

Part 8: A Final Word

The thing nobody tells you about SDD is that it’s not really about the agent. It’s about you. The agent will happily let you skip every step. The discipline of writing intent down before code, of catching ambiguity at the cheap end, of insisting on a runnable signal before declaring victory — that’s just engineering. We had to remember it because the typist got fast enough to outrun our ability to think.

Or, to borrow Oscar Llerena’s blunt summary: spec hard upfront, execute clean, verify ruthlessly. Everything else is decoration.

If your team picks up exactly two habits from this post, make it these: fresh context per task, and a spec PR that has to be reviewed before the code PR exists. Those two alone will catch more bugs than any reviewer subagent ever will.

Now go write a spec. Or, you know — vibe it. Your prod incident, your call.

If you build something interesting with this — or if you’ve found a SDD anti-pattern I missed — I’d love to hear about it. The field is moving fast enough that this post will probably be half-wrong by next quarter, and that’s the fun of it.


메타데이터
post_id
65b47c9b749a
slug
from-vibes-to-specs-a-practical-guide-to-spec-driven-development-with-claude-code-65b47c9b749a
url
https://medium.com/@codechuckle/from-vibes-to-specs-a-practical-guide-to-spec-driven-development-with-claude-code-65b47c9b749a
canonical_url
https://medium.com/@codechuckle/from-vibes-to-specs-a-practical-guide-to-spec-driven-development-with-claude-code-65b47c9b749a
author_url
https://medium.com/@codechuckle
status
ok
fetched_at
2026-06-15 20:49:13