-
Notifications
You must be signed in to change notification settings - Fork 2
Commands
Both tools expose the same nine /sdd-* commands, because both execute the same body file
under .claude/commands/. Claude Code runs those files directly; GitHub Copilot reaches them
through a one-line loader in .github/prompts/.
| Command | Purpose |
|---|---|
/sdd-overview |
Workflow overview, current spec status, command list |
/sdd-setup |
Onboarding wizard: DocLanguage, Memory Bank, first architecture snapshot |
/sdd-specify |
Adaptive product-owner interview → lean spec with testable acceptance criteria |
/sdd-clarify |
Adversarial pass over a spec: contradictions, ambiguity, untestable criteria, missing failure modes |
/sdd-plan |
Spec → persisted baby-step plan file (research, resume, impact analysis) |
/sdd-compile |
Readiness check: verdict, evidence per acceptance criterion, tests, docs sync |
/sdd-architecture-update |
Detect drift, update snapshot + Memory Bank (confirmation gate) |
/sdd-lifecycle |
Spec status and moves between backlog/, active/, done/
|
/sdd-style-update |
Capture coding style preferences into AGENTS.md
|
Recommended flow: /sdd-specify → /sdd-clarify → /sdd-plan → read the plan →
implement → /sdd-compile → /sdd-lifecycle. Run /sdd-architecture-update whenever the
structure changes.
Two things in that flow are not commands. /sdd-clarify is, but the plan review is yours —
and it is the highest-leverage minute in the cycle, because a wrong step produces hundreds of
wrong lines while a wrong line produces one.
And not every change deserves the flow at all. A typo, a rename, a config value, a one-line fix
with an obvious test: take the fast path from AGENTS.md, say that you took
it, and move on.
AGENTS.md says work spec-first for anything that changes behaviour — deliberately not
always. A change smaller than the spec that would describe it is made directly, with no spec
and no plan. The rule is only that the assistant says it is taking the fast path, and notes
anything with regression risk in activeContext.md.
This is part of the method, not a loophole in it. A workflow that demands three Markdown files for a typo teaches people that the workflow is theatre, and then they stop using it for the changes that actually needed it.
It keeps the commands from shadowing Claude Code's built-in commands and groups them into one
autocomplete namespace: type /sdd and you see the whole workflow set.
Every body carries disable-model-invocation: true. A Claude Code command is otherwise
model-invocable, and these are workflows with side effects — they create files, move files and
delete files — so they run only when you invoke them. Copilot prompt files are user-invoked by
design, so the loaders need no equivalent flag.
Both tools append whatever you typed after the command to the invocation, so this works everywhere:
/sdd-plan .specs/active/0007-user-login.md
The bodies deliberately do not use $ARGUMENTS, $0/$1 or !`shell` injection —
Copilot supports none of them. Instead each body says something like "the user may name a spec
path after the command; if none is given, list the candidates and ask." See
Design Decisions.
Argument hint: (none)
Your "where am I" command. It greets you as the repository's SDD assistant and reports the current state:
- the
DocLanguagevalue fromAGENTS.md - which specs sit in
.specs/backlog/,.specs/active/and.specs/done/ - whether the working tree is clean (
git status --short)
If DocLanguage is still the default and the Memory Bank looks unseeded, it suggests
/sdd-setup. It then prints the operating protocol and the command list.
Run it at the start of a session, or whenever you have lost the thread.
Argument hint: [docLanguage] [projectName] [stack] — or just answer the wizard
One-time onboarding. On first invocation it gives a short introduction to Spec-Driven Development, then runs the wizard.
Step 0 is always the same question: "In which language should the project documentation
Markdown files be written?" If you do not answer, it infers the language from the conversation.
The answer is written to DocLanguage in AGENTS.md — the only place it lives.
Then it reads your repository before asking anything else — manifests and lock files for the
stack, the tree's top two levels for entrypoints and modules, CI config and test scripts for
quality gates. Three of the seven wizard steps are things a repository states about itself, so
it pre-fills them and presents them for correction in one turn rather than asking you to
hand-type what package.json already says. Whatever you misremember would otherwise become the
seeded techContext.md that every later command trusts.
The wizard, in order: project name and one-liner · primary users · tech stack (pre-filled) · architecture style · repo entrypoints (pre-filled) · quality gates (pre-filled) · coding preferences.
Architecture style is asked even when it has a guess — it is the one item that needs interpretation rather than reading, so it says what it inferred and lets you correct it.
What it writes:
-
.memory-bank/projectbrief.md— mission and success criteria -
.memory-bank/techContext.md— stack, build/run/test -
.memory-bank/activeContext.md— the compact dashboard structure (see Memory Bank) -
.memory-bank/systemPatterns.md— initial patterns and decisions - the
architecture:snapshot inAGENTS.md, inferred from the real folder layout -
Style & Output Preferences in
AGENTS.md, from what you stated
Anything it had to assume is written down and confirmed with you.
Argument hint: [idea or title] [area/module]
An adaptive interview, not a form. The assistant acts as product owner, requirements engineer and architect, and asks only the questions your particular idea actually needs.
The interview rules are non-negotiable:
- exactly one question per message — never a batch, never a checklist
- always shows progress:
Question 3 of 9 — Data - never asks what the conversation,
.specs/or the Memory Bank already answers - one short confirmation per answer, then the next question
- thin answers are accepted; gaps become assumptions or open points, never invented facts
- what you said is the scope — everything else goes to Out of Scope
Before asking anything it reads the ground it already stands on: existing spec filenames
(for the next number and to avoid duplicates), .memory-bank/techContext.md,
systemPatterns.md, activeContext.md, and the architecture: snapshot. Stack and boundaries
are known, so it does not ask for them.
On brownfield it reads the code too — before the first question. Those Markdown files describe the system; they are not the system, and they drift. So it finds the modules, functions and tests the change would reach and the contracts they already imply — validation, ordering, error shape, persisted format — and brings back a digest of about fifteen lines, not the files themselves. Then it interviews you about the delta against what is actually there, and asks you only for intent and the tacit rules the code cannot state.
This ordering is the whole answer to the most common criticism of spec-driven development: that it works on greenfield and falls apart in a large existing codebase, because the spec keeps missing context the agent never looked at. Explore first, then specify.
Question budget scales with complexity:
| Complexity | Questions |
|---|---|
| Small change | 5–7 |
| Normal feature | 8–12 |
| Complex feature | 12–16 |
| Critical enterprise / compliance / AI feature | 14–20 |
Additional blocks are triggered by what is in the idea — screens and forms pull in UI/UX and error states; login and personal data pull in security and privacy; payment, law or medicine pull in compliance and auditability; LLMs and agents pull in guardrails and human-in-the-loop.
The budget also scales down, and that matters more than it sounds. If the interview reaches the top of that table, the honest answer is usually that this is two or three specs — so it says so and offers to split before writing anything. A spec that outruns your next feedback signal is not a specification, it is a forecast.
Output: .specs/backlog/NNNN-slug.md, always in backlog/, with **Status:** Draft under
the H1 and acceptance criteria in one of five shapes — always-true, event, state, unwanted
behaviour, optional feature — with shall for anything binding and a rejection list for the
words that make a criterion impossible to fail. See
Acceptance criteria for why one shape was not enough.
Say "done", "that's enough" or "write the spec" at any point and it stops asking and writes with what it has. Full document structure: Specs and Plans.
Argument hint: [path to spec]
The adversarial pass. It reads a finished spec as a stranger would — no conversation history, no benefit of the doubt — and returns four lists:
- Contradictions — two statements that cannot both hold. It looks hardest between sections nobody reads together: a business rule against an acceptance criterion, an out-of-scope entry against a functional requirement.
- Terms with more than one meaning — words used in two senses, or domain terms never defined. User, order, active, valid and sync are the usual offenders.
-
Criteria nothing can decide — for each
AC-, the observation that would prove it false. If there isn't one, it says so. - Failure modes the spec never names — missing, malformed or duplicated input; an unreachable dependency; two users at once; a half-succeeded operation.
It lists, it does not resolve. That is the entire design. A model asked to resolve an ambiguity resolves it silently with whatever is statistically plausible — which is the failure this command exists to catch, not to reproduce. It ends with a single question: the item whose being wrong would cost the most. One question, because a catalogue gets skimmed and answered in bulk, which is the same as not asking.
Why a separate command and not a better interview. The context that produced an ambiguity is
structurally the worst placed to find it. /sdd-specify checking its own output is a reviewer
grading its own homework; /sdd-clarify starts cold, and that is its only real advantage. It
does not read the plan either — a plan that already resolved an ambiguity would hide it.
It never edits the spec. Unresolved items belong in Open points, and that call is yours.
Argument hint: [path to spec or plan]
Planning produces a file, not a chat answer. A plan that lives only in the chat is gone when the session ends.
It picks one of three modes automatically:
| Situation | Mode |
|---|---|
| The spec has no plan file yet | A — plan from scratch |
| A plan exists and work is unfinished | B — resume |
| A plan exists but the spec changed | C — re-plan the delta |
Mode A reads the spec, AGENTS.md and the Memory Bank; surveys the code the spec actually
touches (entrypoints, modules, the existing test setup); researches anything it would otherwise
guess; decomposes the work into baby steps; writes the plan file — then stops and hands it
to you. Planning does not change code.
If the survey contradicts the spec, it stops rather than plans around it. A criterion that assumes behaviour the code does not have, or ignores a caller it would break, is a spec defect — it gets reported as one and the command switches to Mode C. Hardening a refuted spec into numbered steps is how a small misunderstanding becomes an expensive one.
Research is mandatory, not optional. Whenever the spec involves a library, framework or API
that cannot be verified from the repo, version-specific behaviour, a protocol or regulation, or
a pattern where the model's knowledge may be stale, it uses its web search or fetch capability
and records every source under ## Research with a link and a retrieval date. No link, no
claim. If no web access is available it says so plainly and marks the affected steps as
assumptions.
Baby steps have a fixed shape: one concern each, small enough to read in one diff, ordered
so the repo keeps working after every step, tied to the acceptance criteria they serve — and
every one carries a Verify: line that is a command whose output decides it. Where no
machine check exists, it reads manual: <what a person looks at> plus the reason. If a step has
no verifiable outcome at all, it is too big and gets split.
Then you read it. The command names the plan, its step count and its riskiest step, and asks which steps look wrong before anything is implemented. This is not politeness: under the leverage ordering that governs agent work, bad research produces thousands of bad lines, a bad plan hundreds, and a bad line one. Two hundred lines of plan is the cheapest review you will do all cycle — and it is the one everybody skips. You are not hunting defects; you are agreeing on the why and the ordering.
Mode B reads the plan first, checks Current step and Session handoff against
git status --short and the real code, and reports in three lines: what is done, what is next,
what blocks it. After each finished step it updates the plan in the same change set as the
code — fill Verified: with the command it ran and what came back, then tick the box, fill
Notes, write real paths and the deciding test into the traceability table, move Current step.
No recorded run, no tick.
Mode C is the impact analysis. It reads the traceability table in reverse: for every changed acceptance criterion it lists the steps and the code paths already built from it, and reports that before editing anything. New steps are appended, existing IDs are never renumbered (they are references), obsolete steps are struck with a one-line reason rather than deleted.
Argument hint: [path-to-spec.md] [runTests:true|false]
The readiness brief. It gathers git status --short and git log --oneline -10, reads the spec,
its .plan.md sibling, AGENTS.md and activeContext.md, then reports:
-
Verdict —
READY·NOT READY·NOT READY — unverified, followed by the blockers - Current goal — from the spec
-
Constraints — from
AGENTS.mdand the spec - Architecture snapshot highlights — the relevant parts
- Acceptance criteria — each one marked satisfied or pending, with evidence
-
Plan state — open vs. finished steps, whether the traceability table names real code paths
and a test per criterion, any criterion no step covers, any finished step whose
Verified:field is empty - Do / Don't — including your Style & Output Preferences
-
Docs sync —
activeContext.md'sLast updatedline against your newest commit; do spec and plan statuses match what it just read - Next 3 steps — concrete and actionable
Evidence has a definition, and it is narrow. A test name plus its pass/fail output, a
command plus its output, or a file:line. A step ID is not evidence. A sentence describing the
implementation is not evidence — it is a restatement of the code by the thing that wrote the
code. A criterion with no machine artifact behind it is pending, and if a human checked it,
that is recorded as pending (manual check by …).
The suite runs unless you decline, and the verdict is NOT READY — unverified whenever it
did not, however good the criteria look. It also re-derives from the repository rather than
summarising the plan: it reads the code and the tests before the plan's claims about them, and
treats a ticked box as a claim to check. If the same session implemented the work, it says so in
one line at the top — the context that produced a gap is the worst placed to find it, and the
least it can do is admit the conflict of interest.
Argument hint: [focus: module|folder|area] (optional)
Reconciles the architecture: snapshot in AGENTS.md with the repository as it actually is.
It inspects the real directory tree (top two levels), compares it with the snapshot, and identifies what matters architecturally: new, moved or removed top-level folders; new entrypoints, apps, services, packages or modules; changed boundaries or shared components.
Then it presents a delta report — what changed, why it matters, what it proposes to update.
There is a confirmation gate. Before writing anything it asks "Is this the change you
expected?" and "Anything else I should include?". Only after you confirm does it update the
snapshot, .memory-bank/systemPatterns.md and .memory-bank/activeContext.md.
The constitution's drift rule spots drift during normal work and proposes the update; this command is where the write happens. There is exactly one gate for that write, and it lives here. An earlier version let "obvious" drift be written immediately while this command asked first — which meant the same change resolved differently depending on which file happened to be in context. One action, one autonomy level.
The drift rule is also scoped to source modules, entrypoints and top-level folders. Writing
a spec, a plan or a Memory Bank file does not trigger it — otherwise every /sdd-specify run
would start a drift check over a Markdown file in backlog/.
Argument hint: [spec path] [newStatus: Draft|In Progress|Implemented|Deprecated]
Moves specs between backlog/, active/ and done/ and keeps their status honest.
The safety rules it enforces:
- No duplicates. A spec exists in exactly one lifecycle folder. Moving means writing to the destination and deleting the original.
- Duplicate check first. Before moving, all three folders are scanned for the same filename. Copies in less-advanced folders are deleted (done > active > backlog).
-
Plans travel with their spec. If
NNNN-slug.plan.mdsits next toNNNN-slug.md, both move and de-duplicate together. A plan must never end up in a different folder than its spec. -
Separate status vocabularies. A spec uses
Draft | In Progress | Implemented | Deprecated; a plan usesNot started | In Progress | Blocked | Done. One never overwrites the other. -
Before
done/: the plan is checked too — every step ticked and itsVerified:field filled, the traceability table filled with real code paths and a test per criterion. It asks for the evidence: a/sdd-compilebrief with aREADYverdict, or theVerified:lines themselves. Ticked boxes with no recorded run are not evidence; it names the criteria that lack it and stops. If steps are still open, it says so and lets you decide. - No plan beside the spec? It asks why and records the answer in the spec. A deliberate fast path is fine; a forgotten plan is not.
-
A change that invalidates an
Implementedspec sets that spec toDeprecatedand names its successor. Adone/folder that contradicts the repository is worse than an empty one.
It always updates .memory-bank/activeContext.md when a spec becomes active or is completed:
## Active Spec is set or cleared, Current phase and ## Next are refreshed.
These rules are deliberately restated inside the command body — see Design Decisions.
Argument hint: [preference] (or list several)
Captures coding-style preferences into the Style & Output Preferences section of AGENTS.md
— the only place they live. It normalises each preference into a short bullet, groups it by
category (Comments, Naming, Formatting, Framework Conventions, Testing, …), applies it
immediately, and shows you the updated bullets.
/sdd-style-update no comments in generated code, prefer file-scoped namespaces, avoid LINQ in hot paths
You rarely need to run this explicitly: the constitution already instructs the assistant to capture any style preference you state in passing — "no comments", "rewrite this without LINQ", "use expression-bodied members" — and append it here on its own. Use the command when you want to state several at once, or reorganise what is already there.
Start here
Reference
Design & interop
- Interop Matrix
- Design Decisions
- Specify Method
- Committing to One Tool
- Migrating from the predecessor
Help