| name | spec |
| description | Writes a functional specification for a feature, bug fix, or change. Describes WHAT to build, not HOW. Uses Given/When/Then acceptance criteria. Technology-agnostic. Use when user says "write spec", "specify feature", "define requirements", "what should this do", or pastes a user story / PRD / feature request. Do NOT include implementation details — use /plan for that.
|
| allowed-tools | Read, Glob, Grep, Bash |
| argument-hint | [feature description or user story] |
| metadata | {"author":"roberto-ramirez","version":"1.0.0","category":"sdd","tags":["spec","requirements","acceptance-criteria","sdd"]} |
/spec
You are writing a functional specification: Define WHAT to build, not HOW.
The spec is the functional layer. It describes what the feature does — not how it's implemented. It is technology-agnostic on purpose. Separating functional from technical reduces LLM uncertainty.
Input
The user will provide a user story, PRD, feature request, or bug report:
$ARGUMENTS
If $ARGUMENTS is empty, ask the user to describe the feature, change, or bug they want to address.
Step 0 — Consult the wiki
Before interviewing the user, check the repo-scoped wiki for prior specs on related topics. This avoids redoing work already captured in past sessions.
bash "${CLAUDE_PLUGIN_ROOT}/skills/wiki-ingest/scripts/wiki-query.sh" <keywords from $ARGUMENTS>
Extract 3-6 meaningful keywords from $ARGUMENTS (skip fluff). Run the query:
- Exit 0 (matches found): present the top 3 matches to the user and ask:
"Found related pages in .wiki/. Reuse one, extend one, or ignore and write a fresh spec?"
If the user chooses to reuse or extend, read the selected page(s) and treat them as part of the conversation context for the interview in Step 1.
- Exit 1 (no matches): continue silently to Step 1.
- Exit 2 (no
.wiki/): continue silently to Step 1. Absence of a wiki is not an error.
Do not block the flow. If the query script is missing or errors, continue with Step 1 — the wiki is optional context, not a hard dependency.
Step 1 — Interview the user
Do not guess. Interview the user to eliminate ambiguity before writing anything.
Think Before Coding: The most common LLM failure is silently picking one interpretation and building to it. If "export user data" could mean a file download, an API endpoint, or a background job — present all three and ask. Surface tradeoffs, don't hide them.
If $ARGUMENTS provides only a brief description or user story, use this interview approach:
- Read any existing related code using Glob and Grep to understand the current system.
- List your assumptions explicitly — what you're inferring that the user didn't say. Present multiple interpretations if they exist.
- Ask the user focused questions in a single message covering the gaps below.
- If a simpler approach exists than what the user described, say so. Push back when warranted.
- Wait for answers before proceeding to Step 2.
Questions to cover (skip any the user already answered):
- Scope: What is explicitly in and out of scope?
- Users / Actors: Who interacts with this feature? What roles or permissions apply?
- Core behavior: What should happen in the happy path?
- Edge cases: What happens with invalid input, concurrent access, missing data?
- Error scenarios: What should the user see when something goes wrong?
- Acceptance criteria: How will we know this is done?
- Dependencies: Does this require other features, services, or data to exist first?
If $ARGUMENTS is detailed enough (contains clear scope, actors, behavior, and acceptance criteria), you may skip the interview and proceed directly to Step 2. State what you're assuming so the user can correct you.
Do not proceed until you have enough information to write an unambiguous spec.
Step 2 — Write the functional specification
Output the following structure:
Functional Specification
Feature: [feature name]
Date: [today's date]
Author: [user's name if known, otherwise "—"]
Problem Statement
One paragraph. What problem does this solve? Why does it need to exist? Write from the user's perspective.
Actors
List every user role, system, or external service that interacts with this feature.
- Actor name — what they do in this context
Functional Requirements
Numbered list of requirements. Each one describes observable behavior — what the system does, not how.
- The system shall [behavior]
- The system shall [behavior]
- ...
Acceptance Criteria
Use Given / When / Then format. Each criterion must be testable and unambiguous.
Given [precondition]
When [action]
Then [expected result]
Write criteria for:
- Happy path (main success scenario)
- Edge cases (boundary conditions, empty states, limits)
- Error scenarios (invalid input, unauthorized access, service unavailable)
- Idempotency (if the same action is performed twice, what happens?)
Out of Scope
Explicitly list what this feature does NOT do. This prevents scope creep and agent guessing.
- [thing that might seem related but is not included]
Open Questions
Gotchas
These are common failure modes when writing specs. Watch for them:
- Sneaking in technology. Claude tends to write "store in a database", "expose a REST endpoint", or "use a queue". These are implementation decisions — remove them. The spec says WHAT happens, not with what tool.
- Vague acceptance criteria. "The system handles errors gracefully" is not testable. If you can't write a test from the criterion, it's too vague. Force yourself to specify the exact error, the exact response, and the exact user-visible outcome.
- Parroting the user's words. If the user says "it should be fast", don't write "The system shall be fast." Ask: how fast? Under what load? What's the fallback? Clarify before writing.
- Skipping the interview. When
$ARGUMENTS is brief (one sentence, a vague idea), Claude often jumps straight to writing a spec full of assumptions. If the input is ambiguous, interview first — even if it feels slow.
- Too many acceptance criteria. If you have 15+ Given/When/Then blocks, you're likely specifying implementation behavior, not functional behavior. Group related behaviors and keep criteria at the user-observable level.
- Given/When/Then that tests plumbing, not behavior. "Given the service receives a POST to /api/users" is an implementation detail. "Given an admin wants to create a new user" is behavior. Write from the actor's perspective.
Important constraints
- No technology decisions. Do not mention frameworks, databases, languages, libraries, or architectural patterns. If you catch yourself writing "use X" or "store in Y", remove it.
- No implementation details. Do not describe data models, API routes, file structure, or code patterns. That belongs in
/plan.
- Given/When/Then is mandatory. Every acceptance criterion must follow this format.
- Be specific. "The system handles errors gracefully" is not a requirement. "When the external payment service returns a 503, the system retries 3 times with exponential backoff and shows the user a 'try again later' message" is.
- Think about what the agent will guess. If a behavior seems obvious to you but could be interpreted multiple ways, spell it out. The agent will not ask — it will guess.
Next step
After the spec is reviewed and approved, run:
/plan
The spec you just wrote becomes the input for the technical plan.