Skip to content
Back to Blog

Spec-Driven Development in the AI Era

· 8 min read

Last month, I watched a developer spend an entire afternoon wrestling with an AI coding agent. He would prompt it, get 200 lines of code back, realize it misunderstood the requirements, revert, reprompt, get another 200 lines, and repeat. By the end of the day, he had burned through tokens, accumulated frustration, and shipped exactly nothing.

His problem was not the AI. His problem was that he had no spec.

AI coding agents in 2026 are remarkably capable. Claude Code, Cursor, Copilot, Kiro, OpenCode. They can scaffold entire features, refactor complex codebases, and write tests that actually catch bugs. But they all share the same fundamental limitation: they do exactly what you tell them. And most of us are terrible at saying what we actually mean.

Spec-driven development is the practice of writing structured, explicit specifications before you start coding, and it is quickly becoming the most important skill in the AI-assisted development workflow.

What Spec-Driven Development Actually Is

Let me be clear about what I do not mean. I am not talking about waterfall-era requirements documents that take six months to write and are outdated before the first sprint. I am not talking about UML diagrams or 80-page PRDs that nobody reads.

Spec-driven development in the AI era is lightweight, iterative, and designed to be consumed by both humans and machines. A spec is a structured document that answers three questions:

  1. What are we building? (Requirements)
  2. How should it work? (Design)
  3. In what order do we build it? (Tasks)

That is it. The format can be Markdown, YAML, or plain text. The key is that it is explicit, unambiguous, and lives in your repository alongside the code.

Here is a minimal example of what a feature spec looks like:

feature: user-notifications
version: 1.0

requirements:
  - Users receive real-time notifications for mentions
  - Notifications appear in a dropdown from the header
  - Unread count displays as a badge on the bell icon
  - Users can mark individual or all notifications as read
  - Notifications persist for 30 days

design:
  components:
    - NotificationBell: header icon with unread badge
    - NotificationDropdown: scrollable list, max 50 items
    - NotificationItem: individual notification with timestamp
  data:
    store: notifications table in Postgres
    realtime: WebSocket via existing pub/sub infrastructure
  constraints:
    - Must not add more than 50ms to initial page load
    - WebSocket reconnection must be automatic

tasks:
  - id: 1
    description: Create notifications database table and migration
    depends_on: []
  - id: 2
    description: Build NotificationItem component with read/unread states
    depends_on: []
  - id: 3
    description: Build NotificationDropdown with virtual scrolling
    depends_on: [2]
  - id: 4
    description: Build NotificationBell with unread count badge
    depends_on: [3]
  - id: 5
    description: Implement WebSocket subscription for real-time updates
    depends_on: [1]
  - id: 6
    description: Integration tests for full notification flow
    depends_on: [4, 5]

Nothing revolutionary about this document. What is revolutionary is feeding it to an AI agent and watching it execute task by task, with full context of the requirements, design constraints, and dependency order. No ambiguity. No drift. No “I assumed you wanted it this way.”

Why Specs Matter More Now Than Ever

There is a saying in the AI coding community: the spec is the prompt. I think this undersells it. The spec is the contract.

When you work with a human developer, they bring years of implicit context. They know your codebase conventions, they can infer intent from a Slack message, they will ask clarifying questions when something does not make sense. AI agents do none of this unless you explicitly tell them to.

Here is the core problem. AI agents amplify everything, including ambiguity. Give a junior developer a vague requirement and they will build one wrong thing. Give an AI agent a vague requirement and it will confidently build the wrong thing in 30 seconds, complete with tests that validate the wrong behavior. Speed without direction is just faster failure.

I have seen this play out repeatedly:

  • Prompt: “Add authentication to the app.” Result: The agent installs three different auth libraries, creates a custom JWT implementation, and ignores the existing session middleware entirely.
  • Spec: “Add email/password authentication using the existing Express session middleware. Store hashed passwords with bcrypt. Add login, register, and logout routes under /auth. Protect all /api routes with a requireAuth middleware.” Result: Exactly what you asked for, in one pass.

The difference is not intelligence. It is context.

The Tooling Landscape

The industry is waking up to this. Several tools have emerged specifically to support spec-driven workflows with AI agents.

Kiro: Spec-Driven from the Ground Up

AWS launched Kiro as an AI IDE that puts specs at the center of the development experience. Its workflow is explicit: you start with requirements (user stories and acceptance criteria), move to a design document (components, data flow, architecture), then generate an ordered task list. The AI agent executes against those tasks sequentially.

What makes Kiro interesting is that specs are not optional. They are the primary interface. You do not prompt the agent with natural language and hope for the best. You define what you want in a structured format, and the agent follows the plan.

This is a philosophical departure from the “just chat with the AI” approach that most tools default to. It trades spontaneity for predictability, and in production codebases, predictability wins every time.

Spec Kit: Specs for Any Editor

Spec Kit takes a different approach. Instead of building an entire IDE around specs, it provides an open-source framework that works with any AI coding tool. You define specs in your repo, and Spec Kit generates context files that AI agents can consume regardless of whether you use Cursor, Claude Code, Copilot, or anything else.

The philosophy is that specs should be editor-agnostic. Your specifications are a property of your project, not your IDE.

AGENTS.md and the Convention File Pattern

Perhaps the most organic development in this space is the emergence of convention files. Claude Code reads AGENTS.md. Cursor reads .cursorrules. OpenCode reads AGENTS.md as well. GitHub Copilot reads .github/copilot-instructions.md.

These files are specs, even if nobody calls them that. They tell the AI agent how the codebase works, what patterns to follow, and what to avoid. A well-written AGENTS.md file is a spec for the entire project:

## Project Configuration

- **Language**: TypeScript
- **Package Manager**: npm
- **Framework**: SvelteKit 2 with Svelte 5 (runes)

## Conventions

- Use Svelte 5 syntax only ($props, $derived, $effect, $state)
- All UI strings must use paraglide-js m.message_key() pattern
- All internal links must use localizeHref() for locale-prefixed URLs
- CSS custom properties for theming (var(--accent), var(--text-heading))
- Blog posts are .svx files with YAML frontmatter

## Do NOT

- Use Svelte 4 legacy syntax (no export let, no $: reactive statements)
- Install new dependencies without explicit approval
- Modify the i18n configuration

This is a spec. It is lightweight, it lives in the repo, and it dramatically improves the quality of AI-generated code. Every team using AI coding tools should have one.

A Practical Workflow for Teams

Here is how I recommend teams adopt spec-driven development without drowning in process.

Step 1: Start with a One-Pager

Before touching any code, write a one-page document that covers:

  • Problem: What user problem are we solving?
  • Solution: What are we building, in plain language?
  • Scope: What is explicitly out of scope?
  • Acceptance criteria: How do we know it is done?

This takes 15 minutes. It saves hours. The acceptance criteria alone will prevent half the back-and-forth with the AI agent.

Step 2: Write the Design Constraints

Not a full architecture document. Just the constraints:

  • What existing systems does this touch?
  • What patterns should the implementation follow?
  • What are the performance requirements?
  • What are the edge cases we already know about?

These constraints are gold for AI agents. An agent that knows “this must work with our existing Redis cache layer” will produce fundamentally different code than one that does not.

Step 3: Break It Into Tasks

This is where spec-driven development pays off the most. Break the feature into ordered, atomic tasks. Each task should be completable in a single AI agent session. Each task should have a clear done condition.

## Tasks

1. [ ] Create database migration for notifications table
   - Done when: migration runs successfully, table has correct schema
   
2. [ ] Build NotificationItem component
   - Done when: component renders with mock data, has read/unread visual states
   
3. [ ] Build NotificationDropdown component
   - Done when: displays list of NotificationItems, supports virtual scrolling
   - Depends on: task 2

Now you can hand each task to an AI agent with the full context of the spec. The agent knows what it is building, why, and what constraints to respect. It also knows what comes before and after its task, so it can make appropriate interface decisions.

Step 4: Execute, Review, Iterate

Feed the spec and current task to your AI agent. Review the output. If the output is wrong, the question is not “how do I prompt better?” but “what is missing from my spec?” Update the spec, re-run. The spec improves over time as you discover what the AI needs to know.

This is the key mindset shift. When AI output is wrong, the bug is in the spec, not the AI.

When NOT to Write Specs

I want to be honest about the tradeoffs. Spec-driven development adds overhead, and that overhead is not always justified.

Skip specs when you are exploring. If you do not know what you are building yet, a spec is premature. Prototype first. Vibe code. Explore the solution space. Then write the spec when you know what the right approach is.

Skip specs for trivial changes. Fixing a typo, updating a dependency, changing a color value. These do not need structured specifications. Use common sense.

Skip specs when you are solo and the feature is small. If the entire feature fits in your head and you are the only one working on it, the overhead of a formal spec might not be worth it. A mental model is a spec too, it is just not shareable.

Do write specs when:

  • Multiple people (or AI agents) will work on the feature
  • The feature touches multiple systems or has complex requirements
  • You need the work to be reviewable and auditable
  • You want to hand a task to an AI agent and walk away with confidence

The Bigger Picture

Spec-driven development is not a new idea. What is new is the audience. For decades, specs were written for human developers. Now they are written for AI agents that are literal-minded, tireless, and incapable of reading between the lines.

The teams that will ship the fastest with AI are not the ones with the best prompting skills. They are the ones that can clearly articulate what they want in a structured, unambiguous format. That is specification writing. That is an engineering skill, not a prompting trick.

The tools are converging on this. Kiro builds it into the IDE. Spec Kit makes it portable. Convention files like AGENTS.md make it accessible. The pattern is clear: the future of AI-assisted development is not better prompts. It is better specs.

Start with an AGENTS.md file in your repo today. Write down how your project works, what conventions to follow, what to avoid. That alone will improve every AI interaction you have. Then, for your next feature, try writing a requirements and task spec before you start coding.

You will be surprised how much faster “slow” planning makes you.

Related Posts