Skip to content

Commands

Gregor Biswanger edited this page Aug 26, 2026 · 7 revisions

Commands

Both tools expose the same twelve /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-architecture-scan Deep, resumable analysis of an existing codebase → fingerprint (first run and refresh)
/sdd-lifecycle Spec status and moves between backlog/, active/, done/
/sdd-style-update Capture coding style preferences into AGENTS.md
/sdd-featherspec-update Template version check + safe update from a newer release (customizations preserved)
/sdd-clean Context cleanup: dedupe and compact the persistent markdown safely, with a token report

Recommended flow: /sdd-specify/sdd-clarify/sdd-planread the plan → implement → /sdd-compile/sdd-lifecycle. Run /sdd-architecture-update whenever the structure changes. On a brownfield repository, run /sdd-architecture-scan before the first spec — see Adopting an Existing Codebase.

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.

The fast path

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.

Why the sdd- prefix

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.

Why they never trigger on their own

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.

Passing arguments

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.


/sdd-overview

Argument hint: (none)

Your "where am I" command. It greets you as the repository's SDD assistant and reports the current state:

  • the DocLanguage value from AGENTS.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.


/sdd-setup

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.

Step 1 asks what kind of repository this is. It counts the source files outside the template's own folders, states its guess, then asks: "Is this a new project, or existing software we are adopting?" New project → the wizard below runs unchanged. Existing software → it collects only the answers a human must give (project name, users, coding preferences) and runs /sdd-architecture-scan, which answers the rest from the code — see Adopting an Existing Codebase.

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 in AGENTS.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.


/sdd-specify

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.


/sdd-clarify

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:

  1. 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.
  2. 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.
  3. Criteria nothing can decide — for each AC-, the observation that would prove it false. If there isn't one, it says so.
  4. 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.


/sdd-plan

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. The command puts the model in a software-architect role: it decides the how, grounded in the repository as it is and in source-backed facts — the spec owns the what.

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 — including the quality gates techContext.md records (test, build, lint commands), which the plan names in its Approach block and whose full run is always the final step; 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 and sets the spec's **Plan:** line to link it — 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. Where the tool supports subagents, each lookup is delegated to an isolated agent so only the distilled, source-backed finding enters the planning context. 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. When the pair already sits in done/, the impact report comes first and the command then proposes the reactivation move via /sdd-lifecycle — pair back to active/, spec and plan In Progress; a new slice of work gets a successor spec instead.


/sdd-compile

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:

  • VerdictREADY · NOT READY · NOT READY — unverified, followed by the blockers
  • Current goal — from the spec
  • Constraints — from AGENTS.md and 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 syncactiveContext.md's Last updated line 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.


/sdd-architecture-update

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.

Paired with /sdd-architecture-scan. When reconciliation is not enough — several structures the snapshot cannot place, snapshot paths that no longer exist, a focus area sitting under unmapped: — the delta report recommends the deep scan instead of guessing. In the other direction the scan never writes the snapshot itself: it ends by running this workflow with its distilled findings as the observed state, so this confirmation gate stays the snapshot's only write gate. A confirmed scan merge also sets last deep scan in the snapshot comment, and when .architecture/ maps exist, the affected ones are updated in the same change set.

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/.


/sdd-architecture-scan

Argument hint: [focus path] (optional)

The brownfield entry: a deep, resumable analysis of an existing codebase that ends in the architecture: fingerprint. /sdd-setup runs it for you when you answer existing software; type it yourself for the first scan of an adopted repository, or to refresh a stale fingerprint — with a focus path, only that subtree is re-analyzed and merged. It is token-intensive and says so up front — value, a planning figure and the cost levers — before the first phase runs; numbers in Adopting an Existing Codebase.

The files decide where it resumes, not the conversation. No .sdd-scan/_worklist.md → inventory runs. Worklist with pending units → scouts run. Everything done, or you say "distill what we have" → synthesis runs. Close a session mid-scan and the next invocation continues from the worklist with no repeated work.

Inventory is git-only, so it works wherever the repository does: git ls-files for tree shape and manifests, git rev-list --count per folder for change frequency as a priority signal. Facts go to .sdd-scan/_inventory.md, proposed analysis units to .sdd-scan/_worklist.md — and then it stops at the worklist gate: unit boundaries need human interpretation, so it says what it guessed and asks what to merge, split or defer. It never proceeds on an unconfirmed worklist. That is the only gate this command adds.

Scouts — one isolated sdd-scout agent per pending unit, at most three in parallel — each analyze exactly one unit reading file heads by default (full files only on budgeted triggers, audited in the report header), write one report under .sdd-scan/reports/ in DocLanguage, and return at most five summary lines. A unit too large for one honest report is split into child units on the worklist instead (depth capped at 3). Environments that cannot delegate fall back to one unit per turn, worklist updated each time.

Synthesis merges reports bottom-up under strict curation — nothing an agent can infer from the code in seconds, path patterns over path lists, documented commands executed once (network-reaching ones ask first), the why into systemPatterns.md, the facts into techContext.md. If the snapshot cap would evict navigation facts, per-module detail cascades into .architecture/<unit>.md maps.

It grades itself before handing over: ten navigation questions, answered blind from the distilled result, then verified against the repository — the score goes into the delta report. The snapshot itself is written only by /sdd-architecture-update, which the scan runs at the end exactly as if you had typed it. After a confirmed merge it asks once whether to delete the raw .sdd-scan/ analysis.

Full walkthrough with a transcript: Adopting an Existing Codebase.


/sdd-lifecycle

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.md sits next to NNNN-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 uses Not started | In Progress | Blocked | Done. One never overwrites the other.
  • Before done/: the plan is checked too — every step ticked and its Verified: field filled, the traceability table filled with real code paths and a test per criterion. It asks for the evidence: a /sdd-compile brief with a READY verdict, or the Verified: 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 Implemented spec sets that spec to Deprecated and names its successor. A done/ 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.


/sdd-style-update

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.


/sdd-featherspec-update

Argument hint: [check | target version] (optional — default: latest)

Checks the installed FeatherSpec version and updates the template wiring safely from a newer release. check reports the version only and writes nothing; a version like 1.3.0 targets that release; nothing means the latest release.

The safety model in short. It fetches your base version and the target as real trees into .sdd-update/ and classifies every file by a three-way comparison — base, target, yours — then previews everything before anything is written. Conflicts are asked, never assumed (keep mine · take template · merge · review manually · rename mine), a backup branch featherspec-backup/pre-<target> is your rollback, and the version stamp moves last, so an interrupted run resumes cleanly from its files.

After an update that added prompt files, VS Code needs a full restart to discover them (Claude Code does not). Full walkthrough: Updating & Versioning.


/sdd-clean

Argument hint: [focus file] (optional — default: everything in scope)

Persistent markdown is a paid resource: every line loads into future context windows. This command keeps the Memory Bank and the curated architecture maps at as little as possible, as much as necessary — and it is the only place cleanup happens; other commands may recommend it, never perform it as a side effect.

What it checks, per file and in order: misplaced content (moved to its declared home, not deleted) · duplicated knowledge (one canonical home) · stale claims (spot-checked against the repository — git history is the archive) · inventories rediscoverable from the code in seconds · finished episodes lingering in activeContext.md · verbosity that adds no meaning · the file's own size budget. It judges semantic usefulness, not raw size.

What it never does: remove architectural decisions, constraints, business rules, security requirements, conventions or non-obvious knowledge just to save tokens — unsure means keep and list for your review. Snapshot drift hands over to /sdd-architecture-update's gate; specs and plans get report-only findings.

How it runs: analyze → present the cleanup plan with an estimated token count (tokens ≈ bytes ÷ 4, stated as an estimate) → one yes for the listed edits, every uncertain item asked individually → apply by replacing and consolidating, never appending → validate and report before/after tokens with the reduction. Re-running after a cleanup is safe: already-optimized files are left untouched.

Clone this wiki locally