Spec Driven Design
Overview
Turn an existing application into business specifications, fix its architectural problems at the specification level, and regenerate the application from those specifications alone.
The Spec Driven Design (SDD) pipeline is delivered as five agent skills that run in a coding agent (Claude Code or Kiro) against a live vFunction MCP connection. This guide covers the five skills in the order they execute: what each one needs, what it produces, and what to type to invoke it.
Pipeline at a Glance
The five SDD Pipeline Agent Skills are:
- sdd-extract-specs. This is a required step that takes specs from code
- sdd-fix-architecture. This is an optional step that fixes smells in specs
- sdd-sanitize-specs This is a required step that de-biases the tree
- sdd-codegen. This is a required step that takes code from specs
- sdd-apply-changes. This is an as-needed step that applies pending fixes
Put another way, these five SDD Pipeline Agent Skills do the following:
| # | Skill | Turns this | Into this | vFunction MCP needed |
|---|---|---|---|---|
| 1 | sdd-extract-specs |
Application code and runtime analysis | A specs tree | Yes |
| 2 | sdd-fix-architecture |
A specs tree and vFunction TODOs | Proposed change deltas | Yes |
| 3 | sdd-sanitize-specs |
A raw specs tree | A de-biased copy, ready for generation | No |
| 4 | sdd-codegen |
A sanitized specs tree | A runnable codebase | No |
| 5 | sdd-apply-change |
One delta and generated code | The code with that change made | No |
Prerequisites
The following prerequisites are required:
A vFunction Application with a Baseline Measurement
Spec Driven Design (SDD) Pipeline Agent Skills 1 and 2 read the platform’s runtime analysis: domains, entry points, call trees, and architectural TODOs. Domains cannot be fetched until a baseline measurement is set.
The vFunction MCP Server Connected to your Coding Agent
The application must be selected in your workspace configuration. Every tool call resolves the application from that configuration.
The Skills Installed
The skills ship with the vFunction server, separately from the MCP tool surface. The local MCP CLI installs them for you. From the root of the project you are working in:
vf_mcp login # browser OAuth2; credentials go to the OS keychain (once per machine)
vf_mcp workspace # creates .vfunction/vf-mcps.json for this project, if not already present
vf_mcp ping # confirms authentication and server connectivity
vf_mcp download-skill # downloads and installs the skills
Note that the download-skill command installs every skill in the archive into both of these locations, relative to the current directory:
.claude/skills/<skill-name>/ # Claude Code
.kiro/skills/<skill-name>/ # Kiro
Run the command again to update. Each skill folder is deleted and rewritten, so a file removed between versions does not linger. Reload the agent afterwards if the new skills do not appear. Each folder contains a SKILL.md that the agent reads automatically; you never need to open these files yourself.
Some additional notes:
- The install is per project, into the working directory and not into
~. A new checkout needsdownload-skillrun again. - The archive endpoint (
GET /api/v1/mcp/skills/archive) requires an authenticated browser session, so fetching it withcurlwill not work. Usedownload-skill, or download the archive from a logged-in browser.
The Codebase Available Locally
Spec Driven Design (SDD) Pipeline Agent Skills 1 and 2, and (optionally) 3 read the source.
Choosing a specs directory
We recommend keeping specs outside the codebase project, for example ../specs/. When multiple agents extract different domains in parallel, none of them can then read the output of the others. The examples in this guide use ../specs/.
Kiro users
Kiro restricts access to directories outside the project it is working in, which can cause repeated permission problems during a run. When using Kiro, use a sub-directory inside the project instead, such as ./specs/. Claude Code has no such restriction.
Rules That Hold Across The Pipeline
- One specs root, everywhere. Every stage of Step 1 must use the identical directory, or later stages cannot find what earlier ones produced.
- Fix before sanitize. See Step 2. This is the one ordering constraint that is easy to get wrong and expensive to notice late.
- Deltas are proposals until Step 5.
sdd-fix-architecturewrites them,sdd-sanitize-specscarries them through,sdd-codegendeliberately ignores them, andsdd-apply-changeis the only step that makes one real. If you expected generated code to contain a fix and it does not, that is by design. Check the pending list. - Quoted reasons matter. Where a skill reports something it could not resolve, it quotes rather than paraphrases. Those quotes are the content of the decision you now have to make; a summary of a blocker is not something anyone can act on.
SDD Pipeline Skills 1-5
The Spec Driven Design Pipeline implements five skills:
Skill 1: SDD-Extract-Specs
What SDD-Extract-Specs Does
Sdd-extract-specs reverse-engineers the application’s business behavior into OpenSpec specifications, one artifact set per vFunction domain. The skill has three stages that all read from and write to the same specs root. It runs one stage per request: it stops after each stage, reports, and asks before continuing.
| Stage | Produces |
|---|---|
| 1. Extract the specifications | One OpenSpec artifact set per domain |
| 2. Consolidate the ubiquitous language | One cross-domain glossary at the specs root |
| 3. Document the technology stack | technology-decisions.md and technology-decisions-modern.md |
Stage 1 runs in one of three modes:
- All domains. One clean-context sub-agent per domain, in parallel. This includes the domain named Application, which is the application-level domain and is extracted like any other
- One domain. A single named domain. Safe to run against a tree that already holds others
- Codebase only. No runtime data and no domains. The skill discovers endpoints, crawls from them, and files flows into code-derived areas. Use this when the application has no vFunction analysis
SDD-Extract-Specs Example Prompts
Extract the specs for this application into ../specs/
Reverse-engineer the spec for the Billing domain into ../specs/
Extract specs from the codebase alone into ../specs/ (there's no vFunction analysis for this app)
Consolidate the ubiquitous language in ../specs/
Extract and modernize the tech stack for ../specs/
SDD-Extract-Specs What You Get
../specs/
ubiquitous-language.md # after stage 2: the aggregated, cross-domain glossary
technology-decisions.md # after stage 3: the current stack
technology-decisions-modern.md # after stage 3: the recommended target stack
<domain-slug>/
overview.md # domain overview
ubiquitous-language.md # this domain's glossary
domain-data-model.md
external-contracts.md # handoffs to and from other domains
traceability.md # where each claim came from
open-questions.md
specs/<capability-slug>/spec.md # one per business flow
specs/quality-attributes/spec.md
features/<capability-slug>.feature
features/<capability-slug>.evidence.md
changes/establish-baseline/ # the baseline scaffold, always emitted
changes/proposed/ # suggestions this analysis seeded, if any
SDD-Extract-Specs Model Selection
Domain spec extraction needs a large amount of code and information in a single context window. Use a model with a large context window (around 1M tokens), regardless of how strong its reasoning is. This matters even though each sub-agent is told where its domain is bounded. In customer deployments, smaller-context models have produced unreliable results on whole-codebase extraction.
SDD-Extract-Specs Before Moving On
- Stage 2 needs at least two domains in the tree, and works best when applied to all domains together. It consolidates only what is present, so check which domains it reports covering
- Stage 2 does not apply after a codebase-only extraction. That mode writes its own consolidated glossary
- Read the open questions the run reports. Every later step inherits them
Skill 2: SDD-Fix-Architecture
What SDD-Fix-Architecture Does
This step is optional but recommended.
Takes the architectural problems vFunction found and resolves each one in the specifications, not in the code. Every fix is written as a proposed delta under changes/pending/. No baseline spec file and no source file is ever modified. After a run, the specs still describe the architecture as it is, with the fixes alongside as proposals.
One sub-agent works each finding, in parallel by default. Four kinds of finding are covered:
| Smell | What it is |
|---|---|
| Circular flows | A runtime call stack that leaves a domain, passes through others, and re-enters the first |
| Domain dependency cycles | A cycle in the domain dependency graph; the platform picks which edge to remove |
| Cross-domain dependencies | One unwanted dependency from a named domain into another |
| Shared resources | A resource reached from several domains, with one chosen to own it exclusively |
SDD-Fix-Architecture Example prompts
Fix the architecture TODOs in ../specs/ (the codebase is at ./src)
Fix the circular flows in ../specs/, codebase at ./src
Remove the cross-domain dependencies in my specs at ../specs/ (source: ./src)
Fix the shared tables exclusivity issues in ../specs/
The codebase path is required. A fix cannot be judged without seeing the implementation that the specs deliberately omit.
SDD-Fix-Architecture What You Get
../specs/changes/pending/fix-NN-<scope>/ # change-level documents at the root
../specs/<domain>/changes/pending/fix-NN-<scope>/ # the per-domain delta
Each fix reports one of four outcomes, and they mean different things:
- Resolved. A delta covering the whole finding.
- Partly resolved. A delta covering part of the finding and declaring the rest. This is normal, not a failure: a finding decomposes into parts, and a blocker in one part blocks only that part.
- Not resolvable. Every approach was worked and found blocked, and nothing was written. This needs a human decision.
- No prompt obtainable. The finding’s details could not be fetched, so nothing was attempted. This indicates a stale TODO or a lookup failure, not a verdict that the architecture cannot be fixed. Re-run the vFunction analysis and try again.
SDD-Fix-Architecture Before Moving On
Run this step before sdd-sanitize-specs, not after.
The fixers map each finding onto requirements through traceability.md and the *.evidence.md files, which are exactly the files sanitization deletes. Fixing a sanitized tree leaves the fixers working from the codebase alone, which is slower and weaker.
The same specs-directory guidance given in the Prerequisites applies here, including the Kiro recommendation to use a sub-directory such as ./specs/.
Skill 3: SDD-Sanitize-Specs
What SDD-Sanitize-Specs Does
SDD-Sanitize-Specs removes everything in the specs tree that would bias code generation toward the original implementation, so the regenerated code is written from the business requirements rather than from a description of the old code. It strips:
- traceability appendices and per-scenario evidence files
- source-basis tags and open-questions files
- stray vFunction identifiers
- leaked file paths, module names, and package names
Along the way it settles ubiquitous-language conflicts and open questions wherever the evidence in the specs allows, and reports what it could not settle.
Have domain experts settle conflicts and open questions.
Resolving ubiquitous-language conflicts and open questions is best done by domain experts and product managers, not by AI agents. If items are left unanswered, the sanitization step will try to settle them itself, for better or worse.
It writes a sanitized copy; your original tree is never modified. It also writes a findings report. Once started, it runs to completion without asking anything, and unresolved items are collected and surfaced at the end.
Change directories are sorted rather than uniformly stripped:
| Directory | Fate | Why |
|---|---|---|
changes/pending/ |
Kept, sanitized | Not yet in the baseline; applied to generated code later |
changes/spent/ |
Dropped | Already folded into the baseline, so the code will contain it anyway. Reserved for future use; this directory is currently never created. |
changes/proposed/ |
Kept, sanitized | Suggestions from extraction, still yours to decide on |
changes/establish-baseline/ and anything directly under changes/ |
Kept, sanitized | Ordinary content |
SDD-Sanitize-Specs Example prompts
Sanitize the specs in ../specs into ../specs-sanitized
Get these specs ready for codegen: ../specs
Sanitize ../specs (the original codebase is at ./src if you need a tie-breaker)
As in the earlier steps, Kiro users should use a sub-directory inside the project for the specs and the sanitized output.
SDD-Sanitize-Specs What You Get
../specs-sanitized/ # the de-biased tree, ready for Skill 4: sdd-codegen
../specs-sanitized-report.md # the findings report
SDD-Sanitize-Specs Before Moving On
Read the report, in particular:
- Unresolved ubiquitous-language conflicts and unresolved open questions. These still need your decision. Otherwise code generation will settle them by accident.
- Pending Fixes Carried Forward. This decides what you actually get. Code generated from this tree implements the architecture without those fixes; each fix is then applied to the generated code in Step 5. Folding fixes directly into the baseline specs is planned as a future extension of
sdd-fix-architecture.
Skill 4: SDD-Codegen
What SDD-Codegen Does
SDD-Codegen generates the application’s code from the specifications alone. The agent does not read the original source; everything it needs was distilled into the specs. Two modes are available:
- Orchestrated. Every domain, in one coherent runnable application. Domains are ordered bottom-up where possible, and cross-domain contracts are frozen up front so every worker codes to a stable surface. One worker runs per domain, sequentially, and each hand-back is reviewed before the next starts. The application-level domain goes last and assembles the whole
- Single-domain. One named domain, standalone
Generation is from the baseline only. Nothing under any changes/ directory is implemented, and none of it influences the dependency graph, the ordering, or a contract.
SDD-Codegen Example prompts
Generate the code from ./specs-sanitized/ into ./generated/
Generate the Billing domain from ./specs-sanitized/ into ./src/
Build the app from ./specs-sanitized/ using the modern tech stack
If both technology-decisions.md and technology-decisions-modern.md exist, you will be asked which governs the run. This is a run-wide decision made once, so answer deliberately: the current stack reproduces the application as it is, while the modern stack replatforms it.
SDD-Codegen What You Get
./generated/
<the application's source code>
orchestration/
generation-order.md # the order chosen, cycles found, forward references, rationale
handbacks/<domain>.md # each worker's report
summary.md
openspec/
changes-applied.md # which architectural fixes this code contains
implementation-map/<domain>.md # requirement -> the code implementing it
The openspec/ folder matters beyond this run. implementation-map/ is how a later change finds the code behind a given requirement instead of searching for it, and changes-applied.md is how you tell whether the code and the specs still agree.
SDD-Codegen If It Refuses To Run
sdd-codegen stops if the specs tree still carries extraction artifacts: a traceability.md, an *.evidence.md, an open-questions.md, or a source-basis tag such as [Observed] or [Derived]. This means Step 3 was skipped or did not complete successfully. Run sdd-sanitize-specs and point sdd-codegen at the sanitized copy, or complete the sanitization yourself.
Skill 5: SDD-Apply-Change
What SDD-Apply-Change Does
SDD-Apply-Change Applies one prepared change, a delta identified by its slug, to code that has already been generated. This is surgical editing of existing code, not regeneration. The specs are read-only; the run writes only inside the repository: the code, the ledger, and the implementation maps.
Run it once per change. Each run sees the previous run’s edits, which lets it notice a change arriving against code that an earlier one already moved.
SDD-Apply-Change Example prompts
Apply fix-01-orders-shipping to ./generated, specs at ./specs-sanitized
Implement the pending change fix-02-users-table in the generated repo
Bring ./generated up to date with fix-03-payment-retry from ./specs-sanitized
If you name the change loosely, you will be shown the candidates and asked to pick.
SDD-Apply-Change What You Get
- The change made in the code, with tests updated
openspec/changes-applied.mdupdated, so a later run knows this slug is done- Updated implementation maps
The run stops to ask whenever what it finds is not what it expected:
- the delta sits under
changes/spent/rather thanchanges/pending/ - the specs and repository do not look like they belong together
- the code does not match what the delta describes
- the change proves to be partly applied already
Each of these has more than one plausible cause, so the decision is yours, not the agent’s.
Quick Reference
What each skill asks you for
| Skill | Inputs |
|---|---|
sdd-extract-specs |
Specs root; domain name (one-domain mode only) |
sdd-fix-architecture |
Specs tree; codebase (required); which smells to cover (default: all four) |
sdd-sanitize-specs |
Specs tree; output location; codebase (optional); report path |
sdd-codegen |
Specs tree; which technology-decisions file governs; workspace for the generated code |
sdd-apply-change |
Generated repository; specs tree; the change’s slug |
Where each artifact comes from
| Artifact | Written by | Read by |
|---|---|---|
<domain>/ artifact sets |
Step 1, stage 1 | Steps 2, 3, 4 |
ubiquitous-language.md (root) |
Step 1, stage 2 | Steps 3, 4 |
technology-decisions*.md |
Step 1, stage 3 | Steps 3, 4 |
changes/pending/<slug>/ |
Step 2 | Steps 3, 5 |
| Sanitized specs tree | Step 3 | Step 4 |
openspec/changes-applied.md |
Steps 4, 5 | Step 5 |
openspec/implementation-map/ |
Steps 4, 5 | Step 5 |
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| Codegen refuses the tree | Step 3 was skipped | Sanitize it yourself, or run sdd-sanitize-specs and point codegen at the copy |
| Fixers fall back to reading the codebase | Step 2 was run after Step 3 | Fix the raw tree, then sanitize |
| Generated code lacks an expected fix | The fix is pending, by design | Apply it with Step 5 |
| “No prompt obtainable” on a finding | Stale TODO or lookup failure | Re-run the vFunction analysis and retry |
| Glossary looks incomplete | Stage 2 ran on a partial tree | Extract the rest, delete the consolidated glossary, and rerun stage 2 |
| A skill is not offered at all | Skills are not installed in this project | Run vf_mcp download-skill from the project root, then reload the agent |