Spec-Driven Development: the end of vibe coding, and why your AI needs a signed contract before it touches your repo

By Kike Gandia · AI & Security · 9 min read

Illustration of a specification document with a check mark, sending glowing traces toward a neural network over a navy-blue grid
"If the spec is right, the code will be right. If the code is wrong, fix the spec first."

There is a statistic doing the rounds among teams that have spent more than a year putting AI agents into production, and it should make everyone who earns a living from secure code uncomfortable:

Between 12% and 65% of LLM-generated code contains vulnerabilities that can be classified as CWEs. SQL injection (CWE-89), hardcoded credentials (CWE-798), insecure deserialization (CWE-502), broken cryptography (CWE-327), XSS (CWE-79), buffer overflows (CWE-120/787)... the entire OWASP catalog repainted by a model trained on all the mediocre code GitHub has swallowed over fifteen years.

And yet we keep prompting as if this were a WhatsApp chat.

There is a discipline that has been quietly changing this since late 2025. It is not new (its roots lie in formal methods, BDD and API-first design), but for the first time AI infrastructure has matured enough for it to work at product speed. It is called Spec-Driven Development, and if you are building software with agents (Claude Code, Cursor, Copilot, Kiro, Codex), it is worth understanding why this is probably the most important methodological shift since TDD.

The problem: vibe coding doesn't scale (and security pays first)

Let's call it what it is: most teams using AI agents are doing vibe coding. They prompt, get output, patch the errors, repeat. It is a loop whose quality degrades as the complexity of the codebase grows. It produces three specific pathologies:

1 Intent drift
The agent produces plausible code that drifts away from what you actually wanted. It doesn't fail the unit tests, but it violates architectural patterns, breaks API contracts, or introduces security anti-patterns that only surface in production.
2 Unverifiable output
Without explicit acceptance criteria, there is no way to know whether the agent's code is "right". Reviews drag on forever. A 200-line PR turns into a 40-comment thread.
3 Architectural decay
Every new feature is built on implicit assumptions that the next prompt knows nothing about. The system turns into a Frankenstein. By February 2026, more than 110,000 AI-introduced issues had survived in production repositories.

The three pathologies produced by the prompt, patch, repeat loop.

The critical point for cybersecurity: LLMs replicate the vulnerable code they were trained on. Ask for "an AES function in Python" and there is an alarming probability you will get ECB mode with zero padding and hardcoded keys, because that is what StackOverflow is full of. Studies of Copilot report ~40% insecure completions in real-world scenarios.

12–65%
of LLM-generated code contains vulnerabilities that can be classified as CWEs
~40%
insecure completions in real-world scenarios (studies of Copilot)
110,000
AI-introduced issues still alive in production repositories (February 2026)

The figures the article itself cites to size up the problem.

The problem is not AI. It is the lack of a disciplined framework for communicating intent to the agent. And this is where SDD comes in.

What Spec-Driven Development (really) is

Working definition: SDD is a methodology in which an executable specification, versioned in Git, is the single source of truth. The code is a derivative. If the requirements change, you edit the spec and regenerate whatever is affected.

This sounds obvious. It isn't. The difference from traditional specs is radical:

Traditional specExecutable spec (SDD)
Read by a humanExecuted by a machine as a validation gate
Documents intentIs the intent, authoritative
Drifts out of sync with the codeThe code is regenerated from it
Word/ConfluenceMarkdown versioned in Git
OptionalMandatory: no spec, no code

The line that has caught on among serious teams is: "the spec is the prompt". But a versioned, reviewable prompt, with acceptance criteria, technical constraints, architectural decisions and (this is key) explicit security constraints mapped to CWEs.

It is not TDD. It is not BDD. It is not waterfall. It is the missing link between human intent and machine execution.

Why 2026 is the year this takes off

Three forces converged:

a) AI code generation scaled, and so did its vulnerabilities. If the agent's output is 10x faster, the validation gates have to be executable, not PRs reviewed by tired humans.

b) Agents became good enough to follow long specs. Models with large context windows and extended reasoning can process 5,000-word specs without losing coherence. Two years ago, that was unthinkable.

c) Tools appeared that formalize the workflow. GitHub Spec Kit (open source, MIT), AWS Kiro, BMAD-METHOD, OpenSpec, Tessl, Google Antigravity, and Claude Code-specific harnesses such as claude-kiro or cc-sdd. The ecosystem is covered.

The business case is compelling: AWS internally documented features dropping from 40 hours to under 8 hours of human time when they were authored as specs first. GitHub reports that with Spec Kit, teams go through roughly an order of magnitude fewer "regenerate from scratch" cycles.

40 h → <8 h
of human time per feature when it is authored as a spec first (AWS internal measurement)
1 order
of magnitude fewer "regenerate from scratch" cycles (GitHub, with Spec Kit)

The canonical workflow: four phases

  1. Phase 1 — Constitution
    The project's immutable principles: coding standards, testing policy, error handling and mandatory security constraints. Every agent session starts by reading that file.
  2. Phase 2 — Spec
    What needs to be built, in EARS notation: acceptance criteria that can be turned into test cases, technical constraints, explicit non-goals and a CWE-mapped checklist.
  3. Phase 3 — Plan
    How it is going to be built. The agent proposes the technical approach before writing a single executable line, and a human approves it: that gate is what sets SDD apart from autopilot.
  4. Phase 4 — Tasks and implementation
    The plan is broken down into atomic tasks that the agent executes one by one, each tied to an acceptance criterion in the spec.

The sequence followed by almost every serious SDD implementation.

Almost every serious implementation follows a variant of this sequence:

Phase 1: Constitution (the immutable principles)

A file (typically constitution.md or .cursorrules) containing the project's non-negotiable rules: coding standards, testing policy, error handling, mandatory security constraints. Every agent session starts by reading it.

Example constitution for a Python project:

# Constitution: Project Flavia (data intelligence)

## Stack
- Python 3.12+, FastAPI, async-first
- PostgreSQL 16 + pgvector, Redis 7, MinIO
- Pydantic v2 with strict mode mandatory
- Strict typing (mypy --strict)

## Security (non-negotiable)
- Input sanitization: ALL external input goes through Pydantic validators
- Secrets: ONLY via env vars or vault. Literals in code forbidden (CWE-798)
- SQL: ONLY parameterized queries. f-strings in SQL forbidden (CWE-89)
- Crypto: cryptography library, AES-GCM, never ECB (CWE-327)
- Logs: never log PII, tokens, or full request bodies
- Deserialization: never pickle from external sources (CWE-502)

## Style
- Functions <50 lines, cyclomatic complexity <10
- Google-style docstrings mandatory on the public API
- pytest tests with minimum 85% coverage on core modules

This file is not changed lightly. It is the higher-order control plane: the AI executes, humans legislate.

Phase 2: Spec (what needs to be built)

For each feature, a spec.md file in EARS notation (Easy Approach to Requirements Syntax):

WHEN [condition] THE SYSTEM SHALL [expected behavior]

Every EARS requirement can be turned directly into a test case. Zero ambiguity.

Example for an authentication endpoint:

# Spec: Endpoint POST /auth/login

## Acceptance criteria (EARS)
- WHEN the body contains a valid email and password
  THE SYSTEM SHALL return 200 with {access_token, refresh_token, expires_in}
- WHEN the email does not exist in the DB
  THE SYSTEM SHALL return 401 with a generic message (do NOT reveal existence)
- WHEN the password is incorrect
  THE SYSTEM SHALL return 401 with the same generic message (anti user enumeration)
- WHEN >5 failed attempts are received within 60s from the same IP
  THE SYSTEM SHALL return 429 and log an event to the SIEM

## Technical constraints
- JWT: HS256 with a >=256-bit secret from an env var
- Refresh token: opaque, stored in Redis with TTL=7d
- Password hashing: argon2id (no bcrypt, no PBKDF2)
- Rate limiting: slowapi with Redis backend

## Non-goals
- Do not implement OAuth/OIDC in this iteration
- Do not implement MFA (separate feature)

## Security checklist (mapped CWEs)
- [ ] CWE-307: Brute force mitigated via rate limit
- [ ] CWE-204: Identical responses in error cases
- [ ] CWE-522: Password hashing with argon2id
- [ ] CWE-798: Secrets from env, never hardcoded

Explicit non-goals. What does NOT get built matters as much as what does. It keeps the agent from over-engineering and prevents scope creep.

Phase 3: Plan (how it is going to be built)

The agent's "Plan" or "Architect" mode. The AI proposes the technical approach before writing a single executable line. You review it: are there architectural flaws? Security risks nobody considered? Is it aligned with the constitution?

Only once you approve does it move on to the next phase. This human approval gate is what sets SDD apart from autopilot.

Phase 4: Tasks + Implementation

The plan is broken down into atomic tasks. The agent executes them one by one. Each task references an acceptance criterion in the spec. When they all pass and the green tests match the EARS requirements, the feature is done.

SDD as a cybersecurity instrument: the angle almost nobody talks about

This is where it gets interesting for those of us who do this for a living.

The paper "Constitutional SDD" (arXiv, Feb 2026) formalizes something we had been sensing for months: embedding security constraints with explicit CWE mappings in the project's constitution. When you do, the agent literally cannot write the vulnerable pattern without bypassing a visible gate.

In practice, this gives you five compound controls that used to be impossible without SAST and heavy tooling:

01 Prevention at the source
The agent knows the forbidden CWEs before it generates anything. It won't generate cursor.execute(f"SELECT... {user_input}") because the constitution explicitly forbids it, citing CWE-89.
02 Regulatory traceability
Every decision is recorded in Git: spec → approved plan → commit. For NIS2 or ENS audits, or ETSI EN 303 645 certification processes, this is gold. You have the complete trail of why each decision was made.
03 Acceptance criteria as security tests
Every EARS requirement in the spec is a test. Security tests stop being a separate artifact and become part of the functional contract.
04 Reproducible threat models
Threat modeling no longer lives in a forgotten Visio file. It lives in threat-model.md next to the spec, and any spec change triggers a review.
05 Compliance gates as code
Extensions such as Architecture Guard let you add pre-merge checks: "no endpoint can go to production without rate-limiting acceptance criteria", "all PII handling must reference the GDPR spec".

The five compound controls that used to require SAST and heavy tooling.

If you do pentesting or secure development consulting, SDD is the first methodology that gives you security inspection points at the process level, not just the code level. Audit-friendly by design.

Anti-patterns: how SDD breaks

It is not magic. These are the failure modes we have already seen:

1 "Big-bang spec"
The 50-page monster spec nobody is going to read. ThoughtWorks flagged it as an anti-pattern. Rule: if the spec can't be reviewed in <5 minutes, split it.
2 Spec divorced from the code
You write the spec, generate, and never go back to the spec. The moment you edit the code by hand without updating the spec, you are back to vibe coding with extra steps.
3 Vague specs dressed up as formal ones
"The system must be secure" is not an acceptance criterion. EARS or bust.
4 Forgetting the non-goals
Without a "what we are NOT doing" list, the agent reinvents authentication, adds caches you didn't ask for, and pulls in unnecessary dependencies.
5 Skipping the human Plan gate
If you let the agent go straight from spec to code without reviewing the plan, you have bought a car without testing the brakes.
6 Constitution rot
The constitution gets written on day 1 and nobody ever updates it. It has to be a living document. Every incident, every lesson learned, every newly relevant CWE should feed back into it.

The six failure modes already seen in real teams.

When NOT to use SDD

Let's be honest. SDD has overhead. Don't apply it to:

  • One-shot scripts under 100 lines that you will throw away tomorrow
  • Exploratory technical spikes where the goal is to discover, not deliver
  • Pre-product/market-fit prototypes where speed matters more than correctness
  • Hotfixes for production incidents (you write the spec afterward, in the post-mortem)

But for any system that will touch sensitive data, cross a regulatory boundary, or live in production for more than six months, SDD more than pays for its overhead.

Start this week: a 5-step protocol

  1. Create your constitution.md. Don't copy it from the internet. It is the distillation of the principles you already defend in code reviews. Include 10-15 security rules mapped to CWEs.
  2. Pick a small feature you need to build this week. Not the most important one. A well-scoped one, ideally with a clear security surface.
  3. Write the spec in EARS before you touch the editor. Acceptance criteria, non-goals, technical constraints, security checklist. Timebox: 30 minutes.
  4. Hand the spec to your agent (Claude Code with Spec Kit, or whichever harness you prefer). Ask it for a plan. Review it as if it were a PR. Don't rubber-stamp it.
  5. Let it execute. Compare the output against the spec, not against your gut. If something doesn't add up, fix the spec first, then regenerate.

Do it three times. By the fourth, you won't want to go back.

Wrapping up

The underlying shift is this: we are moving from the era of the programmer as author to that of the programmer as editor and legislator. The agent writes. You decide what gets written, under which rules, against which criteria. SDD is the contractual language of that new relationship.

And for those of us who have spent years in cybersecurity, there is some good news hidden in here: the discipline the industry has been asking for for decades ("specify before you code, model threats, map controls to standards") finally has a vehicle that developers adopt willingly. Not because we force it on them, but because it is faster.

Vibe coding was fun. But frameworks stop being optional when the cost of a failure is a data breach, a NIS2 fine, or a critical service going down.

The spec is the contract. The spec is the contract. The contract is security. And this time, security comes built into the speed.

References and recommended reading

  • arXiv 2026: "Spec-Driven Development: From Code to Contract in the Age of AI" (Feb 2026)
  • arXiv 2026: "Constitutional SDD" (Feb 2026), CWE mappings in specs
  • GitHub Spec Kit: github.com/github/spec-kit (MIT, v0.1.12+)
  • InfoQ (January 2026): analysis of executable specs as a control plane
  • ThoughtWorks Technology Radar Vol. 33: SDD in "Assess"
  • CWEval (Columbia): security benchmark for LLM-generated code
  • DeepLearning.AI: "Spec-Driven Development with Coding Agents" course

Related service

AI and LLM pentesting

Keep reading

Audit our AI systems