Spec-Driven Software Development

Ahmad Vegah

In the 1950s and 1960s, there was an explosion of innovation in programming languages. Programmers went from programming in assembly language and machine code, to writing programs in higher-level, portable, languages. Pioneers like John Backus, Jean Sammet, and Grace Hopper had the foresight to see what is now common knowledge: software is at the core of technology, and improving the speed and cost of software development would accelerate the rise of computing, and rise of the world’s economy.

Generative and Agentic AI are poised to bring about a new wave of change. For the first time, there are tools developers can use to translate common-sense descriptions of desired program behavior into real, working systems. Many developers are using these tools already. Prompt-by-prompt, step-by step, they describe the system they want to build to AI code generators. This vibe coding approach to development has already been proven to be a powerful tool. But its power is limited because it is missing one important piece: a full vision of the bigger picture of what a program should do, and why it should do that.

Enter specification

Product Requirements Document

An example of Product Requirements Document (Specification) built using GitHub Spark.

A specification is simply a description of what a program should do, and what needs it should meet. Developers are used to working with specifications every day. The names and forms differ, from tickets, to requirements documents, to hallway conversations with colleagues. The languages differ too: from simple text descriptions, to UI sketches and mockups, all the way to formal mathematical definitions.

A specification is the bigger picture. It’s what those prompts are driving towards, step by step. It is, at its core, the whole point of the program a developer or team is building.

That’s why rethinking specifications — not as static documents, but as living, executable artifacts that evolve with the project. Specs become the shared source of truth. When something doesn’t make sense, you go back to the spec; when a project grows complex, you refine it; when tasks feel too large, you break them down.

Spec Kit makes your specification the center of your engineering process. Instead of writing a spec and setting it aside, the spec drives the implementation, checklists, and task breakdowns. Your primary role is to steer; the coding agent does the bulk of the writing.

Let’s jump in.

main.md: AI coding agent specification

The example app, GitHub Summary, is a command-line tool.

main.md is the actual source code of the app: the Markdown instructions file. Whenever I need to add features or fix bugs, I edit this file. Here’s the opening of the example app’s main.md:

# GitHub Brain MCP Server

AI coding agent specification. User-facing documentation in [README.md](README.md).

## CLI

Implement CLI from [Usage](README.md#usage) section. Follow exact argument/variable names. Support only `pull` and `mcp` commands.

## pull

- Resolve CLI arguments and environment variables into `Config` struct:
  - `Organization`: Organization name (required)
  - `GithubToken`: GitHub API token (required)
  - `DBDir`: SQLite database path (default: `./db`)
- Use `Config` struct consistently, avoid multiple environment variable reads
- Pull items: Repositories, Discussions, Issues, Pull Requests, Teams
- Use `log/slog` custom logger for last 5 log messages with timestamps in console output

...main.md continues...

compile.prompt.md: AI coding agent prompt

compile.prompt.md uses GitHub Copilot’s prompt file format. This repeatable prompt tells the agent to compile main.md into main.go. Here’s compile.prompt.md from the example app:

---
mode: agent
---

- Update the app to follow [the specification](../../main.md)
- Build the code with the VS Code tasks. Avoid asking me to run `go build` or `go test` commands manually.
- Fetch the GitHub home page for each used library to get a documentation and examples.

The workflow to bring this all together

The development loop is straightforward:

  1. Edit the specification in main.md or README.md.
  2. Ask the AI coding agent to compile it into Go code.
  3. Run and test the app. Update the spec if something doesn’t work as expected.
  4. Repeat.