Spec-Driven Development with GitHub Spec Kit: specify first, generate code later

Features requiring multiple man-days that are handed over to a coding agent via ad-hoc prompts will sooner or later turn into vibe coding. Spec Kit provides a 4-phase process to ensure that the spec — not the prompt — is the single source of truth.

Reading progress 0%
Spec-Driven Development with GitHub Spec Kit: specify first, generate code later

You assign Claude Code a feature requiring 3-4 man-days: an API key management module for an internal system. The first prompt runs fine. By the fifth prompt, the agent starts forgetting constraints mentioned in the second prompt. By the third day, you discover it changed the key hashing method halfway through, leaving half the codebase using the old method and the other half using the new one. You delete everything and start over from scratch.

That is not a model error. It is a process error: you are managing a long-term task using fragmented context pieces drifting through the chat history. The numbers reflect the general sentiment — 92% of US devs use AI coding daily, but only 29% trust the code it generates.

Why ad-hoc prompting fails for large features

Ad-hoc prompting works well when the entire requirement fits within a single conversation: fixing a bug, writing a function, or adding a simple endpoint. It breaks when a feature spans multiple sessions, for three reasons:

  • Context evaporation. The decision "use Argon2, not bcrypt" you made on day two does not exist in the session on day four. The agent only knows what is within the current context window.
  • No single source of truth. When requirements are scattered across 40 prompts, no one — not even you — knows the "correct" state of the feature. Code reviews are performed based on... memory.
  • One wrong move destroys the entire build. Discovering a missing requirement on day three means regenerating almost from scratch, because there is no anchor to return to other than "prompting more skillfully."

GitHub reports that teams using Spec Kit reduce the number of "regenerate from scratch" cycles by about 10x. The mechanism behind that number is simple: instead of editing the conversation, you edit the documentation.

Four phases: Spec → Plan → Tasks → Implement

Spec Kit (github/spec-kit, over 90k GitHub stars by 2026) install this workflow as slash commands in your current agent. Each phase generates a Markdown artifact, and that artifact is the input context for the next phase — not the chat history.

graph LR
    A["/specify<br/>spec.md"] --> B["/plan<br/>plan.md"]
    B --> C["/tasks<br/>tasks.md"]
    C --> D["/implement<br/>code + tests"]

Go through each phase with an API key module example:

1. /specifyspec.md. You describe what and why, do not describe how. "Users can create API keys with scope, keys are displayed only once, revocation takes effect within 60 seconds, and there is an audit log." The Agent will ask back about ambiguous parts — do keys expire? is rate limit per key or per user? — and write everything into spec.md. This is where you argue with yourself about requirements, when the cost of fixing it is equal to the cost of fixing a single sentence.

2. /planplan.md. Load spec.md as context, agent proposes technical architecture: table api_keys Store hashes instead of keys, use Argon2, prefix keys for fast lookup, and revoke via cache invalidation. Review this plan as if reviewing a design doc — because it is a design doc. The decision "Argon2, not bcrypt" is now in a file, not in anyone's memory.

3. /taskstasks.md. The plan is hashed into a list of small tasks with dependency ordering: migration first, model before service, service before handler, and tests accompanying each task. Each task is small enough for an agent to complete in one turn and for you to review in a few minutes.

4. /implement. The Agent executes tasks one by one, always maintaining spec.md and plan.md in the context. When it attempts to "innovate" in a hash way, the spec acts as a guardrail to pull it back.

Key point: when missing requirements are detected during the implementation phase, do not use a quick-fix prompt. Modify spec.md and rerun. /plan for the affected parts, and the diff between two plan versions to show you exactly what needs to be redone. The repair loop is targeted, instead of being rambling in chat.

Tool-agnostic: switching agents mid-way results in no loss.

Spec Kit is not tied to any model or agent. It supports over 30 agents — Claude Code, GitHub Copilot, Codex, Gemini CLI, Cursor... — because the entire project "state" consists of Markdown files located within the repo.

Pragmatic consequence: you can use Claude Code for the spec and plan phase (where long reasoning is required), then switch to another agent for the implement phase, or change tools entirely when the team changes licenses — spec, plan, and tasks stay with the repo, not the subscription. In the context of 2026 where models and tools are released every few months, the fact that artifacts outlive tools is not a minor detail. It is the reason Thoughtworks Radar vol.34 put the SDD tool group under serious evaluation instead of treating it as a trend.

Spec, ADR, AGENTS.md: a three-tier documentation system.

If you already have ADR and AGENTS.md in the repo, spec does not replace them — the three things answer three different questions, at three different time scales:

Documentation Answers questions Lifecycle Who reads
ADR What architectural decision, why, and what are the trade-offs Year Human + agent (via MCP)
AGENTS.md When modifying code in this repo, what must not happen Quarter Primarily agent
Spec (Spec Kit) What this feature must do, what the technical plan is Feature Human + agent

ADR says "we choose PostgreSQL, not DynamoDB, because X". AGENTS.md says "all queries must go through the repository layer, do not import ORM directly in the handler". Spec says "the API key module needs these behaviors, implement according to this plan". The best agent is an agent that reads all three: ADR for long-term boundaries, AGENTS.md for repo rules, and spec for the current task.

And spec.md should not be discarded after shipping. It is architectural documentation live of the module — something that, six months later, when a dev (or an agent) opens the module to fix it, will answer the question "what is this designed for" faster than any code comment.

When SDD is NOT needed

To be blunt: writing a spec for a two-line bug fix is a waste. There is only one deciding rule — the cost of writing the spec must be less than the expected cost of rework.

No SDD needed when:

  • Small fixes, local refactors, tasks encapsulated within a single session.
  • Throwaway prototypes — the goal is to learn fast, not to code correctly; vibe coding here is the right tool.
  • You don't know what you want yet: a spec written during ambiguity is just freezing ambiguity into a file. Prototype first, spec later.

SDD is needed when a feature spans multiple days, touches multiple modules, involves more than one person (or an agent), or when errors cause real costs — auth, billing, data migration.

The boundary between vibe coding and engineering has never been about who types the code. It lies in whether the source of truth is a document that people can review, diff, and edit — or a chat history scroll that no one dares to re-read. Spec Kit does only one thing: it forces you to answer the question "what am I building" before the machine starts answering for you.

Done — check your inbox.
Something went wrong. Please try again.