Skip to content
Dataforge

Insights

AI Spec-Driven Development: The Definitive Architectural Guide

Discover how AI Spec-Driven Development (SDD) mitigates the verification tax and architecture drift when scaling AI coding agents in engineering teams.

9 min read

AI coding agents write hundreds of lines in seconds. That is the easy part. The hard part is everything after: reading the code, checking it does what was meant, and keeping the architecture intact when a dozen agent-written pull requests land in a week. Writing code faster does not, on its own, ship better software.

The research says the same thing, with nuance. In three field experiments with 4,867 developers at Microsoft, Accenture and a Fortune 100 company, an AI coding assistant raised completed tasks by 26.08%. But a randomized trial with experienced open-source maintainers, working in large codebases they knew well, found the opposite: with AI tools allowed, tasks took 19% longer.

more completed tasks with an AI coding assistant
26.08%
4,867 developers, 3 field experiments
longer per task for experienced maintainers using AI
19%
METR randomized trial, 246 tasks
speed-up those same maintainers had expected
24%
METR, forecast before the study
Same tools, different systems: the effect depends on the codebase and the people.

The gains are also uneven by experience. In the same field experiments, recent hires and junior developers increased output by 27% to 39%, while senior developers gained 8% to 13%.

  • Recent hires and junior developers27–39%

  • Senior developers8–13%

Output gains from AI coding assistants, by developer experience.

The J-curve of AI adoption

Delivery performance

Time since adopting AI coding agents

  • Specs, small batches and gates
  • Unconstrained generation
Illustrative shape, not measured data. The dip is where the verification tax lands; specs, small batches and automated gates make it shallower and shorter.

Spec-driven development (SDD) is how teams get through that dip. It is also the engineering standard we work by at Dataforge, on client projects and on this website. This guide covers the principles, a ten-phase workflow, a reusable spec template, a worked example and the metrics that tell you whether it's working.

What is spec-driven development?

Spec-driven development is an engineering discipline that makes the specification a first-class, version-controlled artifact. The spec is readable by people and parseable by tools, and it is written before the code, not after. In an AI workflow it is the executable contract: it tells the agent what to build, which constraints to respect and how the result will be tested.

  1. IntentHuman architect

    Business goal, domain rules and security constraints.

  2. Executable specificationHuman + AI agent · gate

    A versioned .md file: requirements, acceptance criteria and contracts.

  3. ImplementationAI coding agent

    Code, unit tests and migrations, generated in small batches.

  4. Automated checksCI pipeline · gate

    Static analysis, linters, contract and unit tests.

  5. Code reviewHuman engineer · gate

    Architecture and conventions; approves the merge.

The SDD pipeline. Gates are points where work stops until a person or a check says yes.

How SDD compares to existing practices

Ad-hoc prompting, PRDs, TDD and SDD compared by artifact, location and weak spot
DisciplinePrimary artifactWhere it livesWeak spot with AI agents
Ad-hoc AI promptingChat contextA chat windowContext drift, code you can't reproduce, a high verification tax
Traditional PRDProse documentConfluence or NotionDrifts from the code quickly; tools can't read it
Test-driven developmentUnit testsThe test suite (red → green)Covers micro-behaviour, not architecture or context
Spec-driven developmentMachine-readable spec (.md / .yaml)The repository, versionedNeeds discipline up front and specs kept current

SDD doesn't replace TDD or DevOps. It sits above them and connects architectural intent to generated code. Tests still prove behaviour; the spec says which behaviour matters and why.

Six principles of AI spec-driven development

Testable requirements
Every requirement is a statement you can check, not open-ended prose.
Explicit constraints
Security boundaries, latency budgets, thread safety and dependency limits are written down before generation starts.
Small batches
Work in small batches is one of the seven capabilities DORA found to amplify AI's benefits. Specs split features into isolated tasks an agent can finish and a person can review.
Traceability
Requirement → spec assertion → generated code → test. Each link can be followed both ways.
Human governance
Agents propose plans and implementations; engineers approve the design and the merge.
Continuous validation
CI checks, contract tests and static analysis verify the spec against the running system on every change.

The ten-phase SDD workflow

In practice SDD is a pipeline that alternates human direction with agent execution. Filter by who's involved to see where your engineers' time goes: the agent does the volume, people own the gates.

  1. Scope framing

    Define the business objective, the scope and the technical context.

    Human

  2. Requirement clarification

    The agent reads the existing code and lists missing edge cases, ambiguities and conflicting dependencies.

    Human + AI agent

  3. Spec authoring

    Write the spec in Markdown or YAML: requirements, data models, API schemas.

    Human + AI agent

  4. Spec reviewGate

    An engineer audits the spec before any production code exists.

    Human

  5. Task planGate

    The agent orders the work (migration → models → handlers → tests); a person approves the plan.

    AI agent + Human

  6. Implementation

    The agent works through the plan in small, separately reviewable batches.

    AI agent

  7. Automated checksGate

    Linters, unit tests, static analysis and security scanners run on every batch.

    CI

  8. Code reviewGate

    Quality, modularity and team conventions. Only code that passed CI gets here.

    Human

  9. Spec sync

    Anything that changed in review goes back into the spec, so the spec never drifts.

    Human + AI agent

  10. Telemetry

    Production metrics and error logs confirm the non-functional requirements hold.

    Ops

Phases marked as a gate stop the flow until someone approves.

Writing specs that agents can use

A good spec gives an agent enough context to make the right choices without dictating every line. Specify behaviour, contracts and constraints; leave the internal structure to the implementation and the review.

A reusable feature spec template

feature.spec.mdMarkdown
# Feature specification: [feature name]

## 1. Objective and context
- **Goal**: [1–2 sentences: the business or technical problem this solves]
- **Consumer**: [primary user role or calling service]

## 2. Functional requirements and acceptance criteria
- [ ] **REQ-1**: [one unambiguous statement of behaviour]
  - *AC-1.1*: Given [state], when [action], then [observable outcome].
- [ ] **REQ-2**: [next requirement]

## 3. Constraints (non-functional)
- **Performance**: [e.g. p95 latency < 200 ms at 1,000 RPS]
- **Security**: [e.g. JWT auth; RBAC enforced on the endpoint]
- **Dependencies**: [e.g. reuse the Redis cache; no new npm packages]

## 4. Contracts and data
```json
// JSON Schema or OpenAPI fragment
{
  "type": "object",
  "properties": {
    "order_id": { "type": "string", "format": "uuid" },
    "amount": { "type": "number", "minimum": 0.01 }
  },
  "required": ["order_id", "amount"]
}
```

## 5. Edge cases and errors
- **EC-1**: Duplicate submission (idempotency key).
- **EC-2**: Database timeout mid-transaction → HTTP 503 with the standard error body.

## 6. Testing
- **Unit**: > 90% coverage of domain logic.
- **Integration**: mock the payment gateway (approved, declined, timeout).

From a vague requirement to a measurable one

Most bad agent output starts with a sentence that sounds like a requirement but can't be tested. Rewriting it adds four things the agent would otherwise guess.

Vague

The system should process user order requests quickly and securely.

Measurable

The POST /v1/orders endpoint must validate payloads against the OpenAPI schema, enforce idempotency via the X-Idempotency-Key header, stored in Redis for 24 hours, authorize the card within 250 ms at p95 and return HTTP 400 with an RFC 7807 problem body for invalid input.

  1. Contract: what valid input is
  2. Idempotency: what a retry does
  3. Latency budget, with a percentile
  4. Error contract: what failure looks like

Worked example: an order-creation API

Here is SDD on a small backend endpoint in Python with FastAPI and Pydantic: the spec first, then the tests the agent writes from it, then the implementation.

Step 1: the specification

order-creation.spec.mdMarkdown
# Spec: order creation endpoint

## Requirements
- Endpoint: `POST /v1/orders`
- Idempotency: require the `X-Idempotency-Key` header.
- Validation: the customer must exist; the order total must be above 0.
- Responses: 201 Created, 400 Bad Request, 409 Conflict on a reused idempotency key.

Step 2: the agent writes the tests first

test_order_service.pyPython
import pytest
from fastapi.testclient import TestClient
from main import app

client = TestClient(app)

def test_create_order_success():
    headers = {"X-Idempotency-Key": "unique-uuid-1234"}
    payload = {"customer_id": "cust_888", "amount": 49.99, "items": ["item_1"]}
    response = client.post("/v1/orders", json=payload, headers=headers)
    assert response.status_code == 201
    assert "order_id" in response.json()

def test_create_order_duplicate_idempotency():
    headers = {"X-Idempotency-Key": "duplicate-uuid-5555"}
    payload = {"customer_id": "cust_888", "amount": 20.00, "items": ["item_2"]}

    # First request
    res1 = client.post("/v1/orders", json=payload, headers=headers)
    assert res1.status_code == 201

    # Same key again
    res2 = client.post("/v1/orders", json=payload, headers=headers)
    assert res2.status_code == 409
    assert res2.json()["detail"] == "Duplicate request processed"

Step 3: the agent writes the implementation

order_service.pyPython
from fastapi import FastAPI, Header, HTTPException, status
from pydantic import BaseModel, Field, PositiveFloat
import uuid

app = FastAPI()

# In-memory idempotency store (see the review notes below)
PROCESSED_KEYS = set()

class OrderRequest(BaseModel):
    customer_id: str = Field(..., min_length=1)
    amount: PositiveFloat
    items: list[str] = Field(..., min_length=1)

class OrderResponse(BaseModel):
    order_id: str
    status: str

@app.post("/v1/orders", status_code=status.HTTP_201_CREATED, response_model=OrderResponse)
def create_order(
    order: OrderRequest,
    x_idempotency_key: str = Header(..., alias="X-Idempotency-Key"),
):
    if x_idempotency_key in PROCESSED_KEYS:
        raise HTTPException(
            status_code=status.HTTP_409_CONFLICT,
            detail="Duplicate request processed",
        )

    PROCESSED_KEYS.add(x_idempotency_key)
    order_id = f"ord_{uuid.uuid4().hex[:8]}"
    return OrderResponse(order_id=order_id, status="confirmed")

Project structure and context

AI tools find specs when they live in a predictable place. Keep them in the repository, next to the code they describe.

Repository layoutTree
my-application/
├── .spec/
│   ├── ARCHITECTURE.md          # global rules and invariants
│   ├── ADRs/                    # architecture decision records
│   └── features/
│       ├── order-creation.spec.md
│       └── payment-processing.spec.md
├── docs/
│   └── openapi.yaml             # API contracts
├── src/
│   ├── domain/
│   └── api/
└── tests/
    ├── unit/
    └── integration/

Give agents access to your internal context

AI-accessible internal data is one of the seven capabilities in DORA's AI Capabilities Model: connecting AI tools to internal documentation and codebases is what turns a generic assistant into a useful one. When architecture and conventions live only in people's heads, agents fill the gap with plausible, redundant code. Specs in the repository give Claude Code, Cursor or GitHub Copilot the same ground truth your engineers read.

Our current standard at Dataforge

Spec-driven development is how Dataforge works today: it is our company engineering standard, not a pilot. This website follows it too. A specs folder holds the architecture invariants as MUST rules: no hard-coded copy, every page ships metadata and structured data, motion is progressive enhancement. Every non-trivial change starts as a numbered change spec with a goal, a scope, acceptance criteria and the specs it will update. An AGENTS.md file sends every coding agent to the specs before it touches code, and a written definition of done decides when a change is finished. This article went through the same process.

It's also how we run outsourced software projects: you approve the spec, and the price is fixed per milestone against it.

Failure modes and how to avoid them

Specs don't remove every problem. These are the four we see most often when teams scale AI agents.

  • Failure mode: Specification bloat

    Specs that dictate every line turn into paperwork nobody updates.

    Mitigation: Limit specs to business rules, API and data contracts, security constraints and edge cases.

  • Failure mode: Oversized agent tasks

    One huge prompt overloads the context window: hallucinated dependencies, missing logic.

    Mitigation: Split work into small batches that can be reviewed one at a time.

  • Failure mode: Unreviewed agent plans

    The agent runs off-plan and the architecture drifts.

    Mitigation: Require a human sign-off on the task plan before any code is generated.

  • Failure mode: The verification tax

    Senior engineers spend hours reviewing low-quality AI pull requests.

    Mitigation: Run pre-commit hooks, linters and tests in CI so bad code never reaches a reviewer.

Metrics: is SDD working?

SDD turns quality control from bug-hunting at the end into continuous verification. Measure it with the delivery metrics you probably already know from DORA, plus two that show the cost of review.

Throughput
Lead time for changes and deployment frequency. Is AI speed reaching production, or piling up in review?
Instability
Change failure rate and failed deployment recovery time. Is generated code causing incidents?
Review effort
Reviewer comments and approval rates per pull request. Does agent code pass review smoothly?
Rework rate
How often you ship unplanned fixes for something you just shipped.

Conclusion

Spec-driven development turns AI coding agents from fast, unpredictable code generators into disciplined members of the delivery pipeline. AI makes raw code cheap; that makes system design, domain modelling and human judgment about trade-offs worth more, not less.

Write testable specs, gate every change with automated checks, keep batches small, and the J-curve gets shallower: you keep the speed and keep the codebase healthy.

The agent writes the code. The spec decides what correct means.

If you want to try SDD on a real project without building the process yourself, book a 30-minute call. We'll show you a spec from one of our projects and tell you honestly whether the approach fits yours.

Sources

  1. [1]METR (2025). Measuring the Impact of Early-2025 AI on Experienced Open-Source Developer Productivity
  2. [2]DORA, Google Cloud (2025). 2025 State of AI-assisted Software Development
  3. [3]Google Cloud blog (2025). Introducing DORA's inaugural AI Capabilities Model

Have a project in mind?

Book a free 30-minute call. We'll get to know your business and tell you honestly where we can help.