AI coding agents are great at producing code quickly. They are much worse at remembering why the code exists, which constraints matter, and where the edges of a feature are. That is where spec-driven development changes the workflow: the specification becomes the source of intent, not an afterthought.

This matters if you are already using tools like Cursor, Copilot, Claude Code, or Codex for real work. Prompting an agent with “build the thing” can work for a prototype. It becomes fragile when the feature touches architecture, security, data models, or product rules.

TL;DR

Spec-driven development is a way to make AI-assisted software delivery more reliable by putting a precise, testable specification before implementation. Instead of asking an agent to infer intent from a loose prompt, you give it a contract: scope, non-goals, business rules, interfaces, acceptance criteria, and guardrails.

The practical shift is simple: spend more time defining the edges and validating the result, and less time manually filling in the middle. The agent still writes code, but the spec tells it what good looks like.

Infographic showing the spec-driven development lifecycle, high-fidelity spec anatomy, agent roles, and specification authority levels

A visual map of the spec-driven development workflow, from planning through validation.

From User Stories to Vibe Coding to Specs

Traditional user stories were designed for humans. A story like “As a user, I want to reset my password so I can regain access” compresses intent into a small sentence. The rest lives in conversations, product intuition, design notes, architecture decisions, and team memory.

That worked better when humans were doing most of the interpretation. A developer could ask the product manager for nuance. A reviewer could spot whether the implementation violated an internal convention. A senior engineer could remember that the auth service has a specific rate-limiting path.

AI changes the failure mode. When a coding agent receives a vague task, it fills in the gaps with plausible defaults. Sometimes those defaults are useful. Sometimes they are wrong in subtle ways: the wrong framework version, duplicated business logic, missing authorization, or a database migration that ignores existing data.

That is the limit of vibe coding. It is fast, but it relies on the model guessing the parts we forgot to say. Spec-driven development moves those assumptions into a document that both humans and agents can inspect.

GitHub’s Spec Kit describes this shift as making specifications “executable” rather than disposable scaffolding, with a workflow that moves from a constitution to specification, planning, tasks, and implementation [1]GitHub. “Spec Kit: Toolkit to help you get started with Spec-Driven Development.” GitHub, 2026.. You do not need to adopt a specific tool to use the idea. The useful part is the discipline: make intent explicit before asking the machine to act.

What Spec-Driven Development Changes

Spec-driven development does not mean writing giant documents. It means writing the kind of document an agent can safely execute against.

A good spec answers four questions:

  • What outcome are we trying to create?
  • What is explicitly out of scope?
  • What contracts and invariants must not be broken?
  • How will we know the implementation is correct?

That last question is the most important one. If the spec cannot be validated, the agent cannot reliably optimize toward it. The result becomes a polished-looking implementation with uncertain behavior.

Think of the workflow as moving effort from the middle to the edges. The middle is code generation, boilerplate, wiring, tests, and documentation updates. Agents are increasingly good at that. The edges are where human judgment still matters: product boundaries, architectural constraints, risk, validation, and trade-offs.

In practice, this changes the prompt from:

Build a subscription system for the newsletter.

To something closer to:

## Objective
Allow visitors to subscribe to the newsletter with an email address.
## Not Included
- No account creation
- No paid subscriptions
- No preference center
## Contracts
- POST /api/newsletter/subscribe accepts { "email": string }
- Invalid emails return 400
- Existing subscribers return 200 with a non-error message
## Business Rules
- Never expose the Mailjet secret key to the client
- Do not send duplicate confirmation emails
- Use the existing Mailjet helper pattern
## Acceptance Criteria
- Given an invalid email, when the form is submitted, then the user sees a validation error
- Given an existing subscriber, when the form is submitted, then the user sees a success state
- Given missing Mailjet credentials in development, when the form is submitted, then the API simulates success

The second version gives the agent fewer opportunities to invent the product.

Start With a Project Constitution

Before writing feature specs, define the rules that apply to every feature. I like the term “project constitution” because it captures the right level of authority. It is not a style guide. It is the set of invariants the agent should treat as non-negotiable.

A constitution might include:

  • The core stack and runtime versions
  • Where business logic belongs
  • Which modules should be reused before creating new ones
  • Security rules, such as where secrets may live
  • Testing expectations
  • Naming conventions and file organization
  • Forbidden patterns

This is the same instinct behind creating effective Cursor rules: persistent instructions beat one-off reminders. If you repeatedly tell an agent “do not put business logic in controllers,” that instruction should live in the repo. The goal is to stop re-explaining decisions that should already be part of the system.

A simple constitution can be enough:

# Project Constitution
## Architecture
- Keep API validation at the route boundary.
- Keep business logic in services.
- Reuse existing components before creating new ones.
## Security
- Never expose server-only environment variables to client code.
- Validate all external input before calling third-party APIs.
## Testing
- Add tests for business rules and regressions.
- Do not add broad snapshot tests as a substitute for behavior tests.
## AI Agent Rules
- Ask before changing public API contracts.
- Ask before introducing new dependencies.
- Never rewrite unrelated files to satisfy formatting preferences.

This does not remove human review. It gives the agent a stable frame so review can focus on behavior rather than repeated housekeeping.

The Seven Load-Bearing Parts of a Feature Spec

A feature spec needs enough structure to prevent the common AI failure modes: overbuilding, drifting from the architecture, mixing framework versions, and missing edge cases.

These are the sections I would make mandatory.

Objective and Scope

Start with one to three sentences. The objective should be narrow enough that a reviewer can tell whether the implementation fits.

Bad objective:

Improve onboarding.

Better objective:

Add a first-run checklist that helps new users connect a data source, invite one teammate, and publish their first dashboard.

Not Included

This is the most underrated section. Agents are helpful by default, and helpful agents expand scope. A “Not Included” section tells the agent where to stop.

For example:

## Not Included
- No billing changes
- No new user role model
- No migration of existing dashboards
- No redesign of the settings page

Tech Stack and Versions

Models can mix old and new APIs, especially when a framework has changed recently. If the feature depends on specific versions, write them down.

This is not just about avoiding compile errors. It also protects architectural consistency. A React 19 app, an Astro SSR app, and a Spring Boot service all have different conventions. The agent should not infer those from memory when the repo can state them directly.

Input and Output Contracts

Use machine-readable contracts where possible. OpenAPI exists specifically to describe HTTP APIs in a way that both humans and computers can understand without reading source code or inspecting network traffic [1]OpenAPI Initiative. “OpenAPI Specification v3.2.0.” OpenAPI Initiative, 2026..

For internal services, that contract might be OpenAPI, JSON Schema, Protocol Buffers, SQL constraints, or typed interfaces. The specific format matters less than the principle: prose should not be the only description of data shape.

Business Rules

Business rules are the facts that make the implementation correct or incorrect.

Examples:

  • Trial users can create at most three projects.
  • A cancelled invoice must never be retried.
  • A user cannot delete the last admin from a workspace.
  • Late fees block checkouts until paid.

These rules should be deterministic. If a rule cannot be tested, rewrite it until it can.

Acceptance Criteria

Acceptance criteria translate the spec into checks. The classic Given/When/Then format still works well because it separates state, action, and outcome.

## Acceptance Criteria
- Given a workspace with one admin, when that admin is removed, then the API rejects the request.
- Given a workspace with two admins, when one admin is removed, then the request succeeds.
- Given a user without admin rights, when they remove another user, then the API returns 403.

Good acceptance criteria are boring. That is a feature. They should make it hard for the agent, the reviewer, or the future maintainer to misunderstand the intended behavior.

Guardrails

Guardrails tell the agent how much autonomy it has.

I like three groups:

  • Always: required behavior
  • Ask first: decisions that need human judgment
  • Never: forbidden behavior

For example:

## Guardrails
### Always
- Reuse the existing auth middleware.
- Add regression tests for permission checks.
### Ask First
- Adding a new dependency
- Changing the database schema
- Changing a public API response
### Never
- Store secrets in client-side code
- Bypass authorization checks in tests
- Rewrite unrelated modules

This is where spec-driven development becomes practical. The spec does not try to predict every implementation detail. It defines the decision boundaries.

Validate Agentic Work With a Harness

Once agents are generating more of the code, validation has to become more explicit. Human review alone is too slow and too inconsistent for every generated change.

The simplest harness is:

  • A spec
  • A task list
  • Automated tests
  • A verifier pass that compares the implementation against the spec

The verifier can be human, automated, or another AI agent. The key is independence. The same agent that implemented a feature is often too eager to declare it done. A separate verifier should ask:

  • Did the implementation satisfy every acceptance criterion?
  • Did it update the relevant tests?
  • Did it violate any project constitution rule?
  • Did it add behavior that was listed as out of scope?
  • Did it change contracts without approval?

For more controlled agent workflows, state-machine based orchestration can help. LangGraph, for example, documents interrupts that pause execution for external input and persist graph state through checkpointing, which supports human-in-the-loop review at defined points [1]LangChain. “Interrupts.” LangGraph Documentation, 2026..

You do not need that level of machinery on day one. Start smaller: make the agent produce an implementation checklist from the spec, then review the checklist before writing code. After implementation, ask for a spec compliance report before opening a pull request.

A Practical Adoption Path

The easiest way to adopt spec-driven development is not to redesign your whole delivery process. Start with one high-risk feature and write a spec before implementation.

Use this lightweight template:

# Feature Spec: <name>
## Objective
<1-3 sentences>
## Not Included
- <explicit non-goal>
## Existing Context
- <files, modules, APIs, prior decisions>
## Contracts
- <routes, schemas, types, events, database constraints>
## Business Rules
- <deterministic rule>
## Acceptance Criteria
- Given <state>, when <action>, then <outcome>
## Guardrails
### Always
- <must do>
### Ask First
- <requires approval>
### Never
- <forbidden>

Then ask the agent to do three passes:

  • Find ambiguities in the spec.
  • Create an implementation plan.
  • Implement only after the ambiguities are resolved.

That sequence is slower than a one-shot prompt, but it is faster than debugging a confident implementation of the wrong idea.

This also connects with how I use AI day to day. In my AI workflow, the useful pattern is supervision, not blind delegation. Spec-driven development makes that supervision concrete. You are not micromanaging every line. You are defining the contract the work must satisfy.

Conclusion

AI coding agents make code cheaper to produce. That does not automatically make software cheaper to change. Without clear specifications, agents can generate a lot of plausible code that still misses the product, architecture, or security intent.

Spec-driven development is the corrective. It turns the spec into the control plane for AI-assisted delivery: scope, contracts, rules, acceptance criteria, and guardrails. The better the spec, the less the agent has to guess.

Start small. Write a project constitution. Add a “Not Included” section to your next feature request. Convert business rules into acceptance criteria. Then let the agent write code against something more durable than a vibe.

References