Friday, September 11, 2026

Spec-Driven Development: Building Software from a Clear Specification

See All on GenAI    « Previously

Spec-Driven Development: Building Software from a Clear Specification

A practical guide to SDD, using VS Code and GitHub Copilot, and how it differs from vibe coding.

AI coding assistants have changed the way software is built. Instead of writing every line of code manually, developers can describe what they want and let an AI assistant generate much of the implementation. But there is an important question: what exactly should the AI build?

This is where Spec-Driven Development (SDD) comes in. Rather than starting with code or an informal conversation with an AI assistant, SDD starts with a clear description of the desired behavior, requirements, constraints, interfaces, and acceptance criteria. The specification becomes the source of truth that guides both the developer and the AI coding agent.

The central idea In Spec-Driven Development, you don't primarily tell the AI, "Write some code that does this." You first establish what the software must do, then use the specification to drive the design, implementation, testing, and review.

1. What Is Spec-Driven Development?

Spec-Driven Development is a software development approach in which a written specification acts as the primary guide for creating a feature or system.

The specification describes the intended outcome before implementation begins. Depending on the project, it can contain functional requirements, user stories, API contracts, data models, business rules, constraints, edge cases, non-functional requirements, and acceptance criteria.

The important distinction is that the specification is not merely documentation written after the code. It is an input to the development process.

A simple example

Imagine that you want to add a password-reset feature to an application. A vague instruction might be:

Build a password reset feature.

An AI coding assistant can certainly generate code from this instruction. However, many important questions remain unanswered:

  • How long should a reset link remain valid?
  • Can a reset token be used more than once?
  • What happens when the email address does not exist?
  • How should expired tokens behave?
  • What password rules apply?
  • Should the system reveal whether an email address is registered?
  • What tests must pass before the feature is considered complete?

A specification makes these decisions explicit before implementation.

Feature: Password Reset

Requirements:
1. A user can request a password reset using their email address.
2. The reset token expires after 30 minutes.
3. A token can be used only once.
4. Invalid or expired tokens must be rejected.
5. The system must not reveal whether an email address is registered.
6. The new password must satisfy the application's password policy.

Acceptance criteria:
- Valid reset requests produce a reset email.
- Expired tokens are rejected.
- Reused tokens are rejected.
- Invalid tokens are rejected.
- Successful reset invalidates the token.

Now the implementation has something much more useful than a general instruction: it has a contract to satisfy.

2. Why SDD Matters in AI-Assisted Development

Traditional development already benefits from requirements and design documents. AI-assisted development makes this discipline even more important.

An AI coding assistant can generate code extremely quickly. That is both its strength and its weakness. If the instructions are vague, the assistant can produce a large amount of code that is technically plausible but does not actually solve the intended problem.

SDD addresses this by moving more attention toward the problem definition before asking AI to perform the implementation.

1 Specify Define what must be built.
2 Clarify Resolve ambiguity and edge cases.
3 Plan Decide how the specification will be implemented.
4 Implement Use AI to generate and modify code.
5 Verify Test the implementation against the specification.

Notice that code comes after specification. AI is not removed from the process; instead, its role changes from guessing what you want to implementing a clearly defined requirement.

3. How SDD Can Be Done Using VS Code and GitHub Copilot

VS Code and GitHub Copilot can support an SDD workflow by keeping the specification close to the code and using it as context for AI-assisted planning, implementation, and verification.

The exact Copilot capabilities and interface can evolve over time, but the underlying workflow remains straightforward: write the specification, give the specification to the coding agent, review the plan, implement incrementally, and verify against the requirements.

Step 1: Create a specification

Start by creating a specification file in the repository. The format is less important than the clarity of the content. Markdown is often convenient because it is readable by both humans and AI tools.

docs/specs/password-reset.md

A useful specification should answer questions such as:

  • What problem are we solving?
  • Who is the feature for?
  • What behavior is required?
  • What behavior is explicitly not required?
  • What constraints must be respected?
  • What are the important edge cases?
  • How will we know the implementation is correct?

Step 2: Ask Copilot to analyze the specification

Instead of immediately asking Copilot to write code, ask it to understand and analyze the specification first.

Read docs/specs/password-reset.md.

Analyze the requirements and identify:
- ambiguities
- missing edge cases
- affected parts of the existing codebase
- likely implementation constraints
- tests that will be required

Do not modify any files yet.

This is an important SDD habit: separate understanding from implementation.

Step 3: Ask Copilot for an implementation plan

Once the specification is clear, ask Copilot to create a plan.

Using docs/specs/password-reset.md as the source of truth,
create an implementation plan.

For each step:
- identify the files that need to change
- explain what will change
- identify dependencies
- identify tests that should be added

Do not implement the changes yet.

The plan gives the developer an opportunity to catch incorrect assumptions before code is generated.

Step 4: Review the plan

This is where human judgment becomes particularly important.

Ask questions such as:

  • Does the plan actually satisfy every requirement?
  • Did Copilot misunderstand any business rule?
  • Is the proposed design consistent with the existing architecture?
  • Are security and performance constraints being considered?
  • Are the tests sufficient?

If the plan is wrong, fix the specification or clarify it before implementation begins.

Step 5: Implement in small increments

Instead of giving Copilot one enormous request such as "build the entire feature," work through the plan incrementally.

Implement step 1 from the approved plan.

Use the password-reset specification as the source of truth.
Do not modify unrelated functionality.

After making the changes, explain:
- what changed
- which requirements are now satisfied
- what remains to be implemented

Smaller changes make AI-generated code easier to review, test, and revert.

Step 6: Generate and run tests

Tests should not be an afterthought. The acceptance criteria in the specification should translate into concrete verification.

Review the acceptance criteria in
docs/specs/password-reset.md.

Identify any missing automated tests and add them.
Then run the relevant test suite.

Report:
- tests added
- tests executed
- failures
- requirements that remain unverified

This creates a useful feedback loop:

Specification
      ↓
Implementation plan
      ↓
Code
      ↓
Tests
      ↓
Verification against specification
      ↓
Refinement

Step 7: Keep the specification synchronized

Software changes. Requirements can change too. If the implementation evolves but the specification does not, the repository eventually contains two conflicting sources of truth.

Therefore, when a requirement changes, update the specification deliberately and then update the implementation to match it.

A useful rule: If a behavior matters enough to test or review, it probably matters enough to express clearly in the specification.

4. SDD vs. Vibe Coding

Vibe coding generally describes an AI-assisted development style where the developer gives natural-language instructions, accepts generated code, observes the result, and continues prompting based on what happens.

Vibe coding can be surprisingly productive for prototypes, experiments, throwaway projects, and situations where the cost of being wrong is low.

The problem appears when the same approach is used for software that has important requirements, dependencies, security implications, or long-term maintenance needs.

Aspect Spec-Driven Development Vibe Coding
Starting point A defined specification and acceptance criteria. A natural-language idea or desired outcome.
AI's role Implement and verify against explicit requirements. Generate and refine code through conversational prompts.
Planning Planning is explicit and reviewed before implementation. Planning may emerge during the interaction.
Requirements Made explicit and traceable. Often implicit in the conversation.
Verification Measured against defined acceptance criteria. Often based on whether the result appears to work.
Change management Changes can be reflected in the specification first. Changes may happen through successive prompts.
Best suited for Production systems and requirements-heavy work. Prototypes, exploration, learning, and low-risk experiments.

The key difference

The difference is not simply "writing specifications versus talking to AI." The deeper difference is where the source of truth lives.

In a vibe-coding workflow, the developer's evolving conversation with the AI can become the effective source of truth.

In SDD, the specification is deliberately made explicit so that the developer, AI, reviewer, and tests can all refer to the same intended behavior.

SDD does not mean "never vibe." You can use conversational AI during an SDD workflow. The difference is that the conversation operates within clearly defined requirements rather than replacing them.

5. What to Do in Spec-Driven Development

✓ Do

  • Write requirements before implementation.
  • Define acceptance criteria that can actually be verified.
  • Document important business rules and constraints.
  • Identify edge cases explicitly.
  • Ask Copilot to analyze before asking it to implement.
  • Review AI-generated implementation plans.
  • Implement incrementally.
  • Keep tests aligned with the specification.
  • Review generated code instead of blindly accepting it.
  • Update the specification when requirements change.

✗ Don't

  • Assume AI understands unstated business requirements.
  • Write huge specifications full of unnecessary implementation details.
  • Ask AI to change the entire codebase without boundaries.
  • Treat generated code as automatically correct.
  • Skip tests because the AI says the feature is complete.
  • Allow the specification and implementation to drift apart.
  • Ignore security, performance, or compatibility constraints.
  • Use the specification as an excuse to stop thinking critically.
  • Accept a technically elegant solution that violates the requirements.

6. What Makes a Good Specification?

A good specification should be clear enough to remove important ambiguity without becoming an unnecessarily detailed implementation manual.

For example, instead of specifying every class and method that an AI must create, describe the behavior those components must provide.

Less useful:

Create a PasswordResetService class with a ResetPassword()
method that uses a Dictionary to store tokens.

More useful:

Requirements:
- Generate a cryptographically secure reset token.
- Associate the token with the requesting account.
- Expire the token after 30 minutes.
- Permit a token to be consumed only once.
- Reject invalid and expired tokens.

The second version describes what must be true while leaving room for the implementation to choose an appropriate design.

A practical specification structure

# Feature: Password Reset

## Problem
Users need a secure way to regain access to their account.

## Goal
Allow users to reset their password without administrator intervention.

## Functional Requirements
- ...
- ...
- ...

## Constraints
- ...
- ...
- ...

## Edge Cases
- ...
- ...
- ...

## Acceptance Criteria
- ...
- ...
- ...

## Out of Scope
- ...
- ...

## Verification
- Unit tests
- Integration tests
- Security checks

This structure is simple enough for humans to maintain and structured enough to provide useful context to an AI coding agent.

7. Keep the Specification Focused on Outcomes

One of the easiest mistakes in SDD is turning the specification into a detailed description of the code you have already imagined.

Specifications are generally more valuable when they focus on behavior, requirements, constraints, and outcomes.

For example:

Good:
"The API must return HTTP 404 when the requested product does not exist."

Less useful:
"Create ProductController.GetProduct(), then call ProductRepository.Find()
and return NotFound()."

The first statement defines an externally observable requirement. The second prescribes one particular implementation.

This distinction gives both the developer and AI more flexibility while preserving correctness.

8. SDD Is Not About Writing More Documentation

It is tempting to think that SDD simply means producing more documents. That misses the main point.

The purpose of a specification is to create a shared, explicit contract between the problem, the developer, the AI agent, and the verification process.

A short specification containing ten precise requirements can be more useful than a fifty-page document containing vague prose.

The goal is not documentation for documentation's sake. The goal is to reduce ambiguity.

9. A Practical SDD Workflow for Everyday Development

For a typical feature, you can use the following lightweight workflow in VS Code:

  1. Create a feature specification. Describe the problem, requirements, constraints, edge cases, and acceptance criteria.
  2. Ask Copilot to review it. Have it identify ambiguity, missing cases, and affected parts of the codebase.
  3. Resolve questions. Update the specification until the intended behavior is clear.
  4. Generate an implementation plan. Ask Copilot to propose changes without modifying files.
  5. Review the plan. Confirm that it addresses the specification and fits the existing architecture.
  6. Implement incrementally. Give Copilot one logical part of the approved plan at a time.
  7. Test continuously. Add and run tests derived from the acceptance criteria.
  8. Perform a final specification review. Check that every requirement has been implemented and verified.

This approach preserves one of the biggest advantages of AI coding assistants—speed—while reducing the risk that speed turns into uncontrolled complexity.

10. The Human Developer Still Matters

SDD should not be interpreted as handing the specification to an AI and stepping away.

The developer remains responsible for deciding what the software should do, evaluating trade-offs, understanding the architecture, reviewing the generated implementation, and determining whether the result is safe and correct.

In fact, AI-assisted SDD can make the developer's role more strategic. Instead of spending all of their time typing implementation details, developers can spend more time defining problems, making design decisions, reviewing results, and validating behavior.

Think of the division of labor this way: The human defines the desired outcome and constraints. The AI helps explore and implement solutions. Tests and reviews provide evidence that the implementation actually satisfies the specification.

11. Final Takeaway

Spec-Driven Development is a natural evolution of software development in an age where AI can generate code much faster than humans can manually write it.

The bottleneck increasingly shifts from "How quickly can we write the code?" to "How clearly have we defined what the code should accomplish?"

SDD answers that question by putting the specification at the center of the workflow:

Define the problem
       ↓
Write the specification
       ↓
Clarify requirements
       ↓
Create an implementation plan
       ↓
Review the plan
       ↓
Implement with AI assistance
       ↓
Test
       ↓
Verify against the specification
       ↓
Iterate

Vibe coding can be excellent for discovering possibilities and quickly creating prototypes. But when correctness, maintainability, security, and predictable behavior matter, relying on an evolving conversation alone can become risky.

Spec-Driven Development does not eliminate the speed of AI-assisted coding; it gives that speed direction.

The One-Sentence Definition

Spec-Driven Development is an AI-assisted development approach in which a clear, explicit specification defines the intended behavior first, and the implementation, tests, and review are driven by that specification.


See All on GenAI    « Previously

Too Old at 59, Driving at 72: Vidya Kaur’s Inspiring Journey

See All Articles


5 Key Takeaways

  • Age should not be treated as a barrier to pursuing a long-held dream.
  • After being rejected by a driving school at 59 for being too old, Vidya Kaur bought a car and learned with a neighbor's help.
  • She practiced consistently and mastered driving fundamentals in about a month.
  • At 72, she drives independently through Jammu, including crowded markets and parallel parking.
  • Her story shows that learning continues throughout life and asking for help can help turn dreams into reality.



Rejected at 59 for Being ‘Too Old to Drive,’ Vidya Kaur Now Drives Through Jammu at 72

At 59, Vidya Kaur walked into a local driving school in Jammu hoping to learn how to drive. She walked out with a rejection: she was considered too old to handle busy roads. Thirteen years later, at 72, she is behind the wheel and driving independently through those same streets. Her story has become a striking example of how personal dreams do not have to expire with age.

A career in education and a long-held dream

For more than four decades, Vidya Kaur built a career in education. She worked as a teacher and later became a school principal, shaping the lives of hundreds of students along the way. But even with such a demanding and fulfilling professional life, she carried a personal dream for years: she wanted to learn how to drive.

At 59, she decided to stop waiting for the “right time.” Instead of allowing her age to hold her back, she took the first step toward a goal she had carried for years. Her journey went on to prove a simple but powerful truth: it is never too late to learn something new or chase a dream.

Rejected for being ‘too old’

When Vidya approached a local driving school, she expected guidance. Instead, she received rejection. She was told that she was too old to handle busy roads. For many people, hearing something like that at 59 might have been enough to give up on the idea. Vidya, however, did not see the rejection as the end of her dream.

She found another way. She bought her own car and asked a neighbour to teach her how to drive. It was a simple decision, but one that required enormous confidence. She had spent most of her adult life meeting responsibilities, working in education, and caring for others. Now she decided to invest time in something she wanted for herself.

Learning from scratch

Vidya did not simply sit behind the wheel and expect confidence to appear. She practised. With the help of her neighbour, she worked on the basics of driving: controlling the clutch, changing gears, braking, and steering. She kept practising until she became comfortable with the car.

The Better India reported that she mastered the fundamentals within about a month. That may not sound like a long time, but for someone starting at 59, it represented serious focus and consistency. Her story is particularly inspiring because she did not have the advantage of starting young. She began learning at an age when society often expects people to slow down rather than take on something completely new.

But Vidya’s approach was different. She focused on learning rather than worrying about what people might say.

Confidence on Jammu’s roads

Today, at 72, Vidya drives through the streets of Jammu independently. She has gone from being told that she might not be able to manage busy roads to confidently handling them herself. She drives through crowded markets, manages intersections, picks up friends, and even parallel parks.

The transformation is remarkable. The woman who was once considered “too old” to learn is now comfortable behind the wheel and enjoys the freedom that driving gives her. For Vidya, driving is not simply about operating a car. It represents independence. It means being able to decide where she wants to go and getting there herself.

No expiry date on personal dreams

Vidya’s journey also shows why it is important not to put an expiry date on personal dreams. People often associate certain milestones with particular ages. Learn to drive when you are young. Start a new career early. Travel when you have fewer responsibilities. Try something new before you get older.

But life does not always work according to these timelines. Vidya had spent more than four decades working in education before she seriously pursued driving. She could have told herself that the opportunity had passed. Instead, she decided that if she still wanted something, it was worth trying. Her story is not about proving that age does not matter at all. It is about refusing to let someone else’s opinion decide what is possible for you.

Lessons beyond driving

There is another important lesson in Vidya’s story: learning does not stop when formal education ends. She spent her professional life teaching students. Later, she became the learner herself. She had to develop a new skill, make mistakes, practise repeatedly, and build confidence over time. In many ways, she approached driving with the same patience she may have encouraged in her students.

Her experience also shows that asking for help is not a sign of weakness. When the driving school turned her away, she found someone who could teach her. She accepted guidance, practised, and eventually became independent. That combination of determination and willingness to learn helped her turn a long-held wish into reality.

Choosing her own road

Vidya Kaur’s story is ultimately about much more than driving. It is about refusing to believe that certain dreams belong only to younger people. At 59, she was told she was too old. At 72, she is driving confidently through Jammu. The years between those two moments were filled with practice, patience, and the courage to ignore a limitation someone else had placed on her.

Her journey offers a message worth remembering: you may not always control when life gives you the chance to pursue a dream, but you can decide whether you are willing to try when that chance arrives. For Vidya, the dream waited for years. She eventually got behind the wheel and chose to drive toward it.


Read more