From backend-skills
Create, update, or fact-check Feature Design Docs that capture product design decisions for downstream code agents. Especially useful after vibe-coding sessions.
How this skill is triggered — by the user, by Claude, or both
Slash command
/backend-skills:feature-design-docThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
A Feature Design Doc (FDD) is the **source of design decisions** for a feature — the artifact a code agent should read first to understand *what the feature is and why*. It earns its keep whether written before implementation or right after a feature was built: in iterative work, the doc saved at the end of one session is the decision source for the next.
A Feature Design Doc (FDD) is the source of design decisions for a feature — the artifact a code agent should read first to understand what the feature is and why. It earns its keep whether written before implementation or right after a feature was built: in iterative work, the doc saved at the end of one session is the decision source for the next.
This skill creates, updates, or fact-checks an FDD against a fixed template, and protects the boundary between design decisions and implementation actions. That boundary is the single most common failure mode for this artifact, so most of the guidance below is about defending it.
Feature Design Doc is the decision source. Implementation Plan derives task ordering from it. Task Breakdown comes out of the Implementation Plan.
Concretely, an FDD captures:
It does not capture:
pnpm test", "edit auth.ts")When in doubt: would a code agent reading this doc need to make a product decision, or take a coding action? FDD is about the first; everything else is downstream.
Scope gate before anything else: this skill documents a single product feature. If the request is actually a system/architecture design doc, a DB or API schema design, an RFC, an implementation plan, or a README, say that the FDD format does not fit and stop — do not force the template onto a non-feature subject.
When invoked, identify which mode applies. Each mode has a different shape of output:
| Mode | Trigger signal | What to produce |
|---|---|---|
| Create (default) | User describes a new or just-built feature, gives a problem statement, or asks to "write/draft/generate" a doc — or the signal is ambiguous | A complete Markdown FDD saved to docs/FDD/<kebab-case-feature-name>.md |
| Update | An FDD already exists for the feature and the user asks to reflect new decisions, changed behavior, or a just-modified implementation | The same file revised in place (append-oriented — see "Update workflow") plus a new Revision History entry |
| Fact-check | User points at an existing doc and asks to "review/validate/audit/check"; or attaches a doc path explicitly | A findings report grouped by severity, citing affected section names and external sources |
| Normalize | User has a doc that mixes design + implementation, or sections are mislabeled — usually surfaced from a Fact-check first | A revised doc plus a short prose summary of what moved where |
Default to Create when uncertain — but if a file already exists at the target path, default to Update instead. Only ask which mode to use if there is literally no feature signal and no document attached (e.g., the user just typed "기능 문서" with no context). For everything else, infer and proceed — wrong-mode cost is recoverable, but interrogation is not.
Load references/feature_design_doc_template.md before creating or fact-checking. That file is the canonical structure; this SKILL.md only adds how to use it well.
Section optionality:
full profile (see "Profiles" below).14. Platform Design is required when the feature is cross-platform, OS-sensitive, hardware-sensitive, browser-sensitive, runtime-sensitive, or platform API-heavy. Otherwise omit — but keep the remaining section numbers unchanged; never renumber.15. Result Semantics is required when the feature has meaningful operation states (partial success, restore results, sync states, migration outcomes, user-visible failures). Otherwise omit.16. Future Extensions is for plausible future product directions only. Do not duplicate every Out of Scope bullet here.Revision History is optional at first save, required from the first update onward (see "Update workflow").Appendix is for supporting material that does not belong in the main narrative, including the non-normative Code Map (see the leakage exception below).The frontmatter profile key selects the required-section contract; the validator enforces whichever is declared.
profile: full (default) — sections 1–13 required as listed above.profile: compact — for small features. Sections 2, 3, 4, 7, 8, 9, 10, 12, 13 stay required; 1, 5, 6 become optional; section 11 stays required but may be condensed to one line per concern (- Security: Not applicable: <reason>). Section numbers never change — omit, don't renumber.Use compact only when ALL of these hold:
If any fails, use full. When unsure, use full — compact exists to keep small docs honest, not to make big docs cheap.
The hardest mistake to catch is putting the right content in the wrong section. The three sections most often confused are Feature Definition, Non-Goals, and Scope. Use this map to keep them separate:
| Statement type | Belongs in |
|---|---|
| "This is a kind of X" / "This is not a kind of Y" (identity) | Feature Definition → "This feature is" / "This feature is not" |
| "We could have done X but chose not to" (rejected aspiration) | Goals & Non-Goals → "Non-Goals" |
| "Not in v1.0, planned later" (release boundary) | Scope → "Out of Scope for [Version]" |
| "We considered approach X but chose Y" (rejected design path) | Alternatives Considered |
| "When situation is ambiguous, decide this way, because..." (rule with rationale) | Policy Decisions |
| "The system needs to handle this failure category" (design-level) | Design → "Failure Handling" |
| "User-visible outcome state" (success/partial/failed) | Result Semantics |
If the same statement seems to fit multiple sections, re-read this map. It almost always belongs in only one.
Create has two entry paths. Pick one before doing anything else:
Before drafting, settle the 5 minimum decisions:
In the post-implementation path, fill all five from the session and the code first; the "batch" becomes a single confirmation message ("here is what I inferred — correct anything wrong") rather than five questions.
When you do need to ask, group everything into one round. AskUserQuestion accepts at most 4 questions per call, so either reduce the open items below five first (infer what you can) or split 4+1; free-text items (name, definition, problem statement) work better as a single grouped plain message than as option lists. Do not interrogate one-by-one — that frays the conversation and the user already knows roughly what they want to tell you. If the user's initial message already answers some of these, only ask for the gaps.
If no live user is reachable (subagent, CI, automation), do not stall in Phase 1: fill the five from available sources, mark inferences explicitly, and use [NEEDS INPUT: ...] for true unknowns — Phase 4 defines how marked drafts hand off.
For item 5, solo or continuous-delivery work with no release train defaults the boundary to as implemented (YYYY-MM-DD).
After Phase 1, do targeted research in parallel so the draft isn't built on speculation. Scope the research by what the feature actually touches.
Post-implementation features — read the implementation first. The just-written code is the primary source of truth: extract Behavior, Policy Decisions, and Failure Handling from what the code actually does, not from memory of the discussion. Where the session decided one thing and the code does another, surface the mismatch — ask the user when interactive, otherwise record it in Risks & Open Questions as a known deviation. Mine the session conversation for approaches that were tried or discussed and dropped; they feed Alternatives Considered (evidence gate in Phase 3). The research below still applies, but it grounds a record of what was built rather than speculation about what might be.
Always do — codebase research:
Relationship to Existing Features and verify they exist in the repo. Use Serena/Grep to find their primary modules.The point of codebase research is to ground the FDD in what is actually true now, so design decisions reference reality rather than guesses.
Conditional — web research:
Do web research only when the feature touches a well-known external standard or protocol. Examples that warrant it:
If the feature is purely internal (e.g., "Q4 internal reporting dashboard", "admin-only user search panel"), skip web research. It introduces hallucinated "best practices" that don't match the actual product, and the cost is real.
## 1. through ## 16., the Cross-cutting subsections ### 11.1 through ### 11.6, and the literal ## Appendix / ## Revision History headings. The validator keys on the H2 section numbers/titles and the 11.x subsection numbers; keeping the numbered skeleton in English keeps it stable for the validator and for downstream agents.### 9.1 [Policy Area] as a placeholder), the platform names under section 14, the alternative names under section 10 — should match the team's natural vocabulary. The validator only inspects the numbered skeleton, so this does not break anything.Feature Definition, that's a Scope statement; move it.Not applicable: <short reason> — with the colon and a real reason. The validator flags both colonless - Not applicable and reasonless - Not applicable: forms. The Not applicable marker itself stays in English even in non-English documents — the validator only recognizes the English form; the reason text may be in the user's language.[NEEDS INPUT: <what's missing>] rather than hallucinating. Phase 4 resolves these.feature-name, profile, created and last-verified (today), verified-against (git rev-parse --short HEAD), tags, and related (paths of FDDs this feature touches). Future agents use these to judge freshness and to find the doc.[NEEDS INPUT: ...] marker as a single follow-up batch — ask all gap-fills together in one round. If no live user is reachable (subagent, CI, automation), the draft with [NEEDS INPUT] markers is itself the deliverable: do not loop trying to ask, just hand off the marked draft so the downstream caller (or a future interactive pass) can fill them.scripts/validate_fdd.py, next to this SKILL.md — resolve the path from wherever the skill is installed (for marketplace installs that is NOT the project repo):
python3 <skill-directory>/scripts/validate_fdd.py docs/FDD/<kebab-case-feature-name>.md
The authoritative list of what it checks is the script's docstring (frontmatter and freshness metadata, required sections per profile, empty sections, duplicate/misplaced headings, Cross-cutting answers). It is structural only — content judgement is yours. If python3 or the script is unavailable in the environment, skip it and check the structure against the template manually; do not block on the tool.PASS (N major unresolved) is not a clean pass.docs/FDD/<kebab-case-feature-name>.md. Create docs/FDD/ if it does not exist. If a file with that name already exists, that is almost always an Update, not a Create — switch to the Update workflow instead of forking copies. Never create -v2 or date-suffixed duplicates: parallel versions of the same FDD destroy discoverability and leave future agents guessing which one is current.docs/FDD/index.md (create it if missing) with one line per document: feature name (linked), one-sentence definition, profile, status, last-verified. This is how future agents find the right FDD without grepping every file.Use when an existing FDD must reflect new decisions or a changed implementation — the most common lifecycle event when a feature evolves across sessions.
Update is append-oriented: factual sections are corrected in place; decision history is never erased.
Design, Primary User Flows, Scope, Result Semantics, Platform Design): update in place to match current reality.Policy Decisions, Alternatives Considered): never delete or rewrite an existing entry. Mark a replaced decision [superseded YYYY-MM-DD — see Revision History] where it stands, and add the new decision alongside it.Revision History entry: date, type (updated / superseded / deviation), one-line summary. Record any known doc-vs-code deviations you are not resolving now — an honest deviation note beats a doc that silently lies.last-verified (today) and verified-against (current commit). Update the doc's line in docs/FDD/index.md if the definition or status changed.These patterns indicate the doc is drifting into being a task list or PR plan. Remove or relocate them:
auth.ts, src/components/Login.tsx, UserService (unless the public API itself is part of the design contract)validateToken(), handleSubmit (same exception as above)npm test", "Edit package.json"Scope and Future ExtensionsLeakage is not always wrong — sometimes a file boundary is a design contract. The test is: would removing this detail still let the reader understand the design? If yes, remove it.
Exception — the Appendix Code Map. Code anchors (entry-point paths, key identifiers, module names) are navigation metadata, not design content. They are allowed in exactly one place: the Appendix, under a Code Map heading, marked non-normative and paired with the commit they were verified against (verified-against). A dated, possibly-stale anchor is far cheaper for a future agent than no anchor at all — but the moment anchors creep into sections 1–16, the leakage rule applies in full.
Fact-check has two layers:
Both layers matter. A doc that is internally consistent but factually wrong is worse than one that is structurally messy but accurate — the former misleads the next code agent with false confidence.
scripts/validate_fdd.py inside this skill's installed directory — not the project repo):
python3 <skill-directory>/scripts/validate_fdd.py <path>
python3 <skill-directory>/scripts/validate_fdd.py <path> --format json # for machine consumption
If python3 or the script is unavailable, fall back to a manual check against the template structure.Beyond what the validator catches:
Alternatives Considered exists and is meaningful if any design decision is non-obvious. A doc with zero alternatives is suspicious — either the space was trivial, or rejected paths were not recorded.Different sections need different verification sources. Do not waste cycles verifying narrative sections.
| Section | Verification source | What to check |
|---|---|---|
| Background / Problem | none | Narrative — not verifiable externally |
| Feature Definition, Goals, Non-Goals | none | Reflects user intent |
| User Model & Core Concepts | codebase (vocabulary) | Are the named concepts already used elsewhere with the same meaning? |
| Relationship to Existing Features | codebase | Do the named existing features actually exist? Are the relationships ("extends", "replaces") accurate? |
| Design → Behavior / Data Model | codebase | Do referenced schemas, models, types match reality? Any contradiction with current code? |
| Policy Decisions | codebase | Are referenced config keys / feature flags real? Does current code already implement a conflicting policy? |
| Alternatives Considered | none | Historical decision record |
| Cross-cutting → Security / Privacy / A11y / i18n | codebase + web (conditional) | Do security/privacy claims hold against current code? Does the design satisfy the relevant external standard (when one applies — same conditional-web rule as Create mode)? |
| Scope, Risks, Open Questions | none | Reflects user / team decisions |
| Platform Design | codebase + web (conditional) | Are platform capability claims accurate against documented platform APIs? |
| Result Semantics | codebase | Do enumerated states match current error/status taxonomy if one exists? |
For each finding from this step, cite the source:
file/path.ext:LINE (or a range)Findings without a citation are weaker than the structural ones the validator produces — do not present them with the same confidence.
Group findings by severity, in the user's primary language. Localize severity labels (Korean: 심각/중요/사소; English: critical/major/minor):
Format:
[severity] [section name]
finding: <one-sentence statement>
evidence: <file:line | URL | "validator output">
suggestion: <how to fix>
Lead with critical findings. Do not bury them under structural minutiae.
When the user's doc mixes design and implementation, or sections are mislabeled:
Feature Definition → Scope; removed 2 file-path references from Design → flagged for Implementation Plan").<name>-normalized.md and say so in the summary.references/feature_design_doc_template.md); body content (prose, bullets, table cells, examples) is written in the user's primary language. This keeps the validator and downstream code agents working off a stable structural skeleton while the substantive content stays natural for the team that owns it.docs/FDD/<kebab-case-feature-name>.md. Create the directory if missing. An existing file at the target path means Update mode, not a silent overwrite — see "Decide the mode first".[NEEDS INPUT: ...] markers in the draft for anything that cannot be inferred, then resolve them in a single follow-up batch. A hallucinated policy in an FDD propagates into implementation, which is far more expensive to undo than asking.scripts/validate_fdd.py — structural validator. Stdlib-only Python (3.9+). Runs in milliseconds. It lives inside this skill package; invoke it via the skill's installed path, not a project-relative one.
python3 <skill-directory>/scripts/validate_fdd.py docs/FDD/<file>.md
python3 <skill-directory>/scripts/validate_fdd.py docs/FDD/<file>.md --format json
python3 <skill-directory>/scripts/validate_fdd.py docs/FDD/<file>.md --strict # majors also fail the exit code
Exit codes: 0 (clean at the chosen threshold), 1 (critical findings — or major findings with --strict), 2 (invocation error). The script's docstring is the authoritative list of checks: frontmatter (doc-type, created, last-verified, profile), required sections per profile, empty required sections, duplicate/misplaced numbered headings, section order, heading title drift, Cross-cutting answers (subsections or the compact condensed form), code-fence-aware parsing. Semantic checks (responsibility map, leakage, factual accuracy) remain LLM-side because they need judgement.
npx claudepluginhub buyoung/skills --plugin devops-skillsTechnical design documents — problem analysis, solution exploration, architectural decisions. Invoke whenever task involves any interaction with design documents — creating, updating, reviewing, comparing options, or capturing architectural decisions.
Guides architecture design via Socratic questioning, generates technical docs like overview.md, domain-model.md, and ADR for new features, systems, or project structuring.
Creates design documents using CAFleet-native orchestration with Director/Drafter/Reviewer team. Invoke when user requests a design doc, specification, or technical spec.