A Spec Kit extension that makes the implementation phase test-driven, in any language. It turns a feature's acceptance criteria into a test list, drives red-green-refactor one behavior at a time while recording the failure that preceded each fix, then audits the result from cold context: was the test really first, does it assert behavior, and would it actually catch a bug.
Spec-driven development produces a good specification and then hands it to an agent that writes code and tests together. That is where the guarantee leaks: tests written alongside the code they check tend to pass while proving very little, and a green suite reads as done. This extension closes that gap with evidence rather than trust.
once -> /speckit.tdd.setup (the stack, proved by running it)
spec-kit -> /speckit.specify ... /speckit.tasks (the specification)
plan -> /speckit.tdd.plan (criteria become a test list)
loop -> /speckit.tdd.run (red, green, refactor, logged)
rest -> /speckit.implement (whatever was not a behavior change)
audit -> /speckit.tdd.verify (evidence, smells, mutants)
Command names on this page use the dot form of slash-command agents, such as /speckit.tdd.plan. Skills agents such as Claude Code use hyphens, such as /speckit-tdd-plan.
The full guide lives in the project wiki. This README is the front door only.
| Wiki page | When to read |
|---|---|
| Home | Overview and reading order. |
| Getting Started | First install, zero to first red-green cycle in five minutes. |
| Commands | Deep reference for the four /speckit.tdd.* commands and their modifiers. |
| Workflow | Where the loop sits in the spec-kit lifecycle, and the artifacts it keeps. |
| The Loop | The discipline itself: double loop, valid reds, step size, doubles. |
| Test List Format | The test list and cycle log, field by field. |
| Test Quality | The rubric the audit grades against, and how mutation testing is used. |
| Stack Profiles | How the extension stays language agnostic, per ecosystem. |
| Examples | A real test list, cycle log, and verification report. |
| Troubleshooting | Common breakages, refusals, and their fixes. |
| FAQ | Conceptual questions, design rationale, and how it composes. |
| Architecture | What happens when you run a command. |
The wiki is generated from docs/ on every push to main. To browse the same content as plain markdown, open the docs folder.
| Command | What it does | Writes |
|---|---|---|
/speckit.tdd.setup |
Detects the test stack and proves each command by running it. Once per repository. | .specify/memory/tdd-profile.md, constitution (with approval) |
/speckit.tdd.plan |
Turns acceptance criteria and plan components into a test list, then makes the test tasks in tasks.md mandatory and correctly ordered. |
tdd/test-list.md, tdd/cycle-log.md, tasks.md |
/speckit.tdd.run |
Drives the loop: one failing test, red proven and recorded, smallest green, refactor on green, one commit. | tests, source, tdd/cycle-log.md, ticks the tasks it completed |
/speckit.tdd.verify |
Audits from cold context: test-first evidence in git, test smells, mutation testing on the changed files, criteria coverage. Fails closed. | tdd/verification.md, remediation in tasks.md |
Four hooks put the right command at the right moment. plan after /speckit.tasks, verify after /speckit.implement, and plan again after /speckit.converge all prompt and can be declined. run runs before /speckit.implement writes anything and it waits, because a prompt at that point would arrive after the code was already written. The loop ticks the tasks it drove, so /speckit.implement covers only what is left. The plan run after /speckit.converge gives each new behavioral task from converge a behavior id and a test task first, so the loop also builds that work test-first. Disable any hook in .specify/extensions.yml.
- A test exists and was seen failing before the code that satisfies it. The failure output is recorded per cycle, and the audit re-checks it against git history rather than taking the log's word for it.
- A red must be red for the right reason. A test that fails on a typo, or passes the moment it is written, is not evidence. Both have a defined response, including a deliberate-mutant check.
- Tests are never weakened to reach green. No loosened assertion, no widened
tolerance, no skip, no narrowed filter, no lowered threshold. When code and test
disagree,
spec.mddecides which is wrong. - Test strength is measured, not assumed. Mutation testing on the changed files where the ecosystem has a tool, deliberate mutants on the highest-risk behaviors where it does not.
- Every acceptance criterion reaches a test through the real entry point, not only units with doubles at every boundary.
Nothing in the loop knows what ecosystem you are in. /speckit.tdd.setup detects
the stack from the manifests, the scripts, the CI config, and the existing test
layout, runs each command to prove it works, and writes them to one profile
the other commands read. That includes the check that catches the worst failure
mode: a single-test command that exits successfully while running nothing turns
every red into a false green.
Starting points are documented for JS and TS, Python, JVM, .NET, Go, Rust, Ruby, PHP, Swift, Elixir, C and C++, and Dart, with their coverage, mutation, and property-based tooling. Detection always wins over the table.
That is a claim worth checking rather than believing, so the same cycle is driven in five ecosystems side by side. The behavior text on the test list is identical in all five. Three lines per cycle differ, and all three are quoted from the runner rather than composed: the test reference, the red command, and the failure output.
Requires Spec Kit >=0.12.17 initialized in the project (specify init).
Install directly from the latest release:
specify extension add tdd --from https://github.com/d0whc3r/spec-kit-tdd/releases/download/v2.0.1/tdd-2.0.1.zipChange the version in the URL to pin a different release. To update, run the same command with a newer release URL and add --force.
Spec Kit's community catalog is a discovery source. specify extension search tdd and specify extension info tdd show the extension and its release archive. Install from the archive URL as shown above. See Troubleshooting.
For prerequisites and the first-run walkthrough see Getting Started.
This extension owns the loop and the evidence. It deliberately does not reimplement what other Spec Kit extensions already do well, and it reads their output where it exists: Gherkin scenarios as outer-loop behaviors, generated test scaffolds as list items, and existing traceability or coverage-drift reports as corroboration in the audit. See the FAQ for the specifics.
The loop discipline follows established practice: the test-list-first framing of Canon TDD (Kent Beck), double-loop or outside-in TDD for the acceptance and unit cycles, the state-based and interaction-based schools treated as a per-behavior choice rather than a doctrine, and mutation testing as the mechanical answer to "do these tests actually bite". The test-smell catalogue draws on the empirical work on smells in generated unit tests.
See CONTRIBUTING.md at the repo root.
MIT. See LICENSE.