Specification-driven development index. Defines spec structure, REQ format, Status semantics, the @impl source-anchor and @test test-anchor conventions (per-AC, at parity), three autonomy modes, and routes to sub-command skills (sdd-init for bootstrap, sdd-clean for rescue). Holds the small sub-commands (edit, add, mode), Plan Mode integration, test discipline, templates. Invoked via /sdd.
Installs into .claude/skills of the current project.
Are you the author of Spec Driven Development?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/nikolanovoselec-spec-driven-development)
---
name: spec-driven-development
description: Specification-driven development index. Defines spec structure, REQ format, Status semantics, the @impl source-anchor and @test test-anchor conventions (per-AC, at parity), three autonomy modes, and routes to sub-command skills (sdd-init for bootstrap, sdd-clean for rescue). Holds the small sub-commands (edit, add, mode), Plan Mode integration, test discipline, templates. Invoked via /sdd.
version: 5.3.0
---
# Spec-Driven Development
A product specification (`sdd/`) is the single source of truth for **what the product does and why**. It is not a record of what the code currently does. It is not a bug tracker. It is not a changelog of every commit.
The full enforcement layer lives in the `spec-discipline` rule (loaded automatically). This skill describes the workflow on top of those rules.
## How it works at a glance
The user runs `/sdd init` once to bootstrap. After that, they "vibe code" — write code, push, walk away. The `spec-reviewer` and `doc-updater` agents auto-detect the `sdd/` folder and enforce discipline on every PR-boundary event, in the mode set by `sdd/config.yml` (`interactive`, `auto`, or `unleashed`).
**Mutation ownership:** every `/sdd` sub-command executes in the root session. `/sdd init` and `/sdd clean` invoke enforcement skills inline and use the root's file and Git tools; they never spawn report-only PR-boundary reviewer agents to apply changes. Reviewer autonomy mode affects findings at review boundaries, not mutation ownership.
The user only invokes `/sdd` directly to:
- Bootstrap a new project (`/sdd init` → invokes the `sdd-init` skill)
- Manually add or modify requirements (`/sdd edit`, `/sdd add` — body below)
- Rescue a rotted spec (`/sdd clean` → invokes the `sdd-clean` skill)
- Switch autonomy mode (`/sdd mode` — body below)
## Sub-commands
| Command | Skill / body |
|---|---|
| `/sdd` | Help screen (the `/sdd` command file) |
| `/sdd init [idea]` | Invoke the `sdd-init` skill (greenfield, import, resume) |
| `/sdd edit {domain}` | This skill, § /sdd edit |
| `/sdd add {domain}` | This skill, § /sdd add |
| `/sdd clean` | Invoke the `sdd-clean` skill (mode-aware spec rescue) |
| `/sdd mode {interactive\|auto\|unleashed}` | This skill, § /sdd mode |
## Spec structure (nested layout, canonical)
```
sdd/
├── README.md # Vision, principles, actors, domain index, "Out of Scope" section
└── spec/
├── {domain}.md # Requirements per feature area
├── glossary.md # Canonical term definitions
├── constraints.md # Technology stack, cross-cutting CON-* constraints
├── changes.md # Semantic changelog (≤2 sentences per entry, user-facing only)
├── config.yml # mode, enforce_tdd, test_globs, src_globs (defaults to "src/** lib/** app/** pkg/** cmd/** internal/**" minus test/build dirs when unset; see spec-enforce-truth § Inputs), allowlists
├── .init-triage.md # Import Mode triage queue (only present during transition)
└── .review-queue.md # Findings escalated for human review (replaces .review-needed.md)
documentation/
├── README.md # Lane index + glossary-with-synonyms + related pointers
├── lanes/
│ ├── architecture.md # universal lane
│ ├── api-reference.md # emit only when source has HTTP routes
│ ├── api-reference-admin.md # emit only when source has admin endpoints
│ ├── configuration.md # emit only when source has env vars / config files
│ ├── deployment.md # emit only when project is deployable
│ ├── security.md # emit only when source has auth / CSRF / CSP code
│ ├── observability.md # emit only when source has logging / metrics
│ ├── troubleshooting.md # emit only when commit history references incidents
│ └── {project-lane}.md # optional first-level lane explicitly indexed by documentation/README.md
└── decisions/
└── README.md # ADR ledger (kept as sibling of lanes/)
```
Project root also has:
```
README.md # Links to sdd/ and documentation/
tests/ # Tests (each test references a REQ ID for spec-reviewer to verify)
pending.md # In-flight work and known gaps (NOT requirements)
```
**Dual-layout support during migration window.** Skills detect layout via `test -d sdd/spec`. Projects on flat layout (`sdd/{domain}.md` directly) keep working; `/sdd clean` migrates flat → nested on demand. The flat layout will be deprecated after one release cycle; no new flat-layout projects should be created.
**Layout is exhaustive (binding).** The tree above is the COMPLETE allowed shape under `sdd/` and `documentation/` on the nested layout. The seven standard lane names, `api-reference-*` siblings, and first-level project lanes explicitly linked from `documentation/README.md` are allowed; anything else is a violation:
- No `sdd/spec/README.md` — the single comprehensive index is `sdd/README.md` (Vision + Actors + Design Principles + Domains table linking to `spec/{file}.md` + Out of Scope, plus one-line links to constraints/glossary/documentation/changelog).
- No `documentation/lanes/README.md` — the lane index is `documentation/README.md` (Jump-TOC + Lane ownership + REQ backlinks + Synonym glossary + Reading order + Related).
- No extra subdirectories under `sdd/spec/`, `documentation/lanes/`, or `documentation/decisions/`.
The enforcement check (one walk, one rule) lives in `doc-enforce-lanes` § Layout conformance.
**Dotfile reduction.** The nested schema consolidates four prior dotfiles (`.review-needed.md`, `.coverage-report.md`, `.last-clean-run.md`, `.review-decisions.md`) into one `.review-queue.md`. `/sdd clean` audit lives in commit history (`git log --grep='\[sdd-clean\]'` + commit bodies). `/review` cross-run dedup, when needed, is derived from `git log --grep='\[review\]'`.
## REQ format
**Canonical shape: see `references/templates/req-shape-example.md`.** That file is the single source of truth — a fully-rendered two-REQ example with every field, blank lines, numbered ACs, source-anchor comments, and the empty-field (`None.`) rendering. Every Active REQ in `sdd/{domain}.md` (or `sdd/spec/{domain}.md` on the nested layout) MUST copy that shape verbatim. Deviations are MEDIUM, auto-fixed by re-rendering (mechanics in `spec-enforce` § REQ rendering template).
**Hard rules (scannable mid-write — the full exemplar is in the template):**
- Heading is `### REQ-{DOMAIN}-{NNN}: {Title}` (H3, never H2).
- Field order is locked: **Intent → Applies To → Acceptance Criteria → Notes (optional) → Constraints → Priority → Dependencies → Verification → Status**. Status is the LAST field, never the first.
- **Required fields** (every REQ): Intent, Applies To, Acceptance Criteria, Constraints, Priority, Dependencies, Verification, Status. Constraints and Dependencies render the literal `None.` when empty; omitting them entirely is MEDIUM `req-missing-required-field`.
- One blank line between every `**Field:**` line. Stacking two label lines on consecutive lines collapses them on GitHub render — MEDIUM `trailing-fields-collapsed`.
- ACs are **numbered** (`1. 2. 3.`), never bulleted (`-`) — MEDIUM `ac-bullets-not-numbered`. Maximum 7 ACs per REQ.
- CON-* and REQ-* IDs inside Constraints/Dependencies render as markdown anchor links, not plain text — MEDIUM `cross-reference-not-linked`.
- Every AC describing observable behaviour ends with `<!-- @impl: <path>::<symbol> -->`. ACs asserting a concrete value use `<!-- @impl: <path>::<symbol> = <value-pattern> -->`. Validators in `spec-enforce-truth` (CQ-SOURCE) read these comments and verify symbol + value against source. AC bullets without an anchor are valid but generate `ac-missing-source-anchor` findings (MEDIUM); ACs carrying `<!-- @manual -->` are exempt. Same convention applies to ADR `Context:` blocks.
- **Test-anchor parity (gated by `enforce_tdd`).** When `enforce_tdd: true`, every AC describing observable behaviour ALSO ends with at least one test anchor `<!-- @test: <path> (<describe/it title>) -->` naming a test block that proves it (the anchors sit alongside the `@impl` anchor on the same AC line). Multiple `@test` anchors are permitted when verification spans blocks or files, and validators in `spec-enforce-truth` (CQ-TEST) verify every declared anchor resolves. An AC without a test anchor is `ac-missing-test-anchor` (MEDIUM), the test parallel of `ac-missing-source-anchor`; a test anchor whose block cannot be found is `spec-test-anchor-orphaned` (HIGH), the parallel of `spec-anchor-orphaned`. ACs carrying `<!-- @manual -->` are exempt. When `enforce_tdd: false` the project has opted out of test verification, so these are informational only (never Status-mutating, never blocking).
- **Manual-verification markers (per-AC, never REQ-level).** An AC whose behaviour genuinely cannot be verified by an automated test ends with `<!-- @manual -->` (bare) or `<!-- @manual: <procedure> -->` (when a dedicated manual procedure exists) instead of the anchors. The marker exempts that one AC from both anchor requirements; anchors present on a `@manual` AC are still validated as supplemental evidence. The REQ's `Verification:` field derives from the markers: `Manual check` when every AC carries `@manual`, else `Automated test` — disagreement is MEDIUM `verification-field-marker-drift`.
- **Notes** is OPTIONAL — only two shapes (see `spec-enforce` § Rule B): Partial-explanation (`Status: Partial` only, ≤3 sentences) or Doc-pointer (any status, ≤2 sentences, MUST contain a markdown link to `documentation/**` or `sdd/**`). Sibling-REQ cross-references go in `Dependencies:`.
- Each REQ ends with `---` on its own line, blank lines either side.
- **Deprecated REQs are deleted, not tombstoned.** No `Replaced By:`, no `Removed In:`. Out-of-scope ideas go to `## Out of Scope` in the domain README.
## Source-anchor convention (binding, single source of truth)
The `@impl` HTML comment is the framework's anchor format for the Truth guarantee.
**Form:**
```
<!-- @impl: <path>::<symbol> -->
<!-- @impl: <path>::<symbol> = <value-pattern> -->
```
- `<path>` is a repo-relative file path (forward slashes regardless of host OS).
- `<symbol>` is the function, class, constant, route, or other named site that implements the AC. Multi-segment symbols use `.` (e.g., `ClassName.methodName`).
- `<value-pattern>` (optional) is the literal value the AC asserts (e.g., `50`, `"oauth-callback"`, `30 * 60`). For non-trivial patterns use a substring the validator can grep.
**Examples:**
```
<!-- @impl: lib/services/auth_service.dart::login -->
<!-- @impl: lib/services/activity_service.dart::_maxActivities = 50 -->
<!-- @impl: cloudflare-oauth-redirect/src/worker.js::handleCallback -->
<!-- @impl: src/middleware/admin-auth.ts::adminGate -->
```
**Detection regex:** `<!--\s*@impl:\s*([^:]+)::([^\s=]+)(?:\s*=\s*(.+?))?\s*-->`
**Validation contract (CQ-SOURCE in `spec-enforce-truth`, Pass 15 in `doc-enforce-truth`):**
1. Resolve `<symbol>` via `mcp__graphify__get_node` against the unified graph. Fallback: grep `<symbol>` in `<path>` when graphify cannot resolve.
2. Symbol not resolved → HIGH `spec-anchor-orphaned` (or `doc-anchor-orphaned`).
3. If `<value-pattern>` present: grep symbol body for literal pattern. Not found → HIGH `spec-value-drift` (or `doc-value-drift`).
4. If `<value-pattern>` absent: confirm symbol body contains ≥3 AC-token overlap. Not found → MEDIUM `spec-behavior-orphaned`.
**Drift behaviour:** symbol renames or deletions break the anchor and force a spec update on the next PR-boundary review — correct, because renames change the contract. Line moves within a file do NOT break the anchor (graphify indexes by symbol identity, not line number).
**This validation runs ALWAYS** — both `enforce_tdd: true` and `enforce_tdd: false`, both Greenfield and Import Mode, both inside and outside SDD transition. `enforce_tdd` gates only the test-anchor check (`Implemented` defaulting on test absence); it never gates source-anchor truth-check.
## Test-anchor convention (parity with source anchors, gated by `enforce_tdd`)
The `@test` HTML comment is the test parallel of `@impl`: it ties each AC to the specific test block that proves it, so coverage is checked AC-by-AC rather than only "some test names the REQ ID" (REQ-level). It is enforced when `enforce_tdd: true`; a project that opts out of automated testing (`enforce_tdd: false`) is exempt, exactly as the REQ-level test pass is.
**Form:**
```
<!-- @test: <path> (<describe/it title>) -->
```
- `<path>` is a repo-relative test-file path (forward slashes) matched by `test_globs`.
- `<describe/it title>` is the title of a `describe`/`test`/`it` block that exercises the AC, copied verbatim (it may itself contain parentheses). Every anchor sits ALONGSIDE the AC's `@impl` anchor on the same AC line. An AC carries **at least one** `@test` anchor; multiple anchors are valid when distinct behavioral blocks jointly verify the same AC. Each declared anchor is independent evidence and must resolve.
**Examples:**
```
<!-- @test: src/__tests__/lib/auth.test.ts (login describe) -->
<!-- @test: packages/node-agent/internal/agent/config_test.go (TestLoadConfigBackfillsDashboardToken) -->
```
**Detection regex:** `<!--\s*@test:\s*(\S+?)\s*\((.*?)\)\s*-->` with global matching — capture groups `<path>`, `<block-title>`. The comment-bounded non-greedy title preserves nested parentheses while allowing adjacent anchors. The executable parser is `spec-enforce-truth/references/parse-test-anchors.mjs`.
**Validation contract (CQ-TEST in `spec-enforce-truth`), gated by `enforce_tdd: true`:**
1. Every declared `<path>` must be a `test_globs` file that exists. Missing → HIGH `spec-test-anchor-orphaned`.
2. Every declared `<block-title>` must appear in its `<path>` as a `describe`/`test`/`it` block title (substring of a block-name line; not a comment or fixture path). Not found → HIGH `spec-test-anchor-orphaned` (the test parallel of `spec-anchor-orphaned`).
3. An AC describing observable behaviour with NO `@test` anchor → MEDIUM `ac-missing-test-anchor` (the parallel of `ac-missing-source-anchor`). ACs carrying `<!-- @manual -->` are exempt.
**Gating:** when `enforce_tdd: false`, all three are informational only — written to the `## Coverage gaps` section of the layout-resolved triage file, never Status-mutating, never blocking — mirroring the REQ-level CQ-TEST false-branch. `@impl` / CQ-SOURCE is NEVER gated this way: tests are opt-out-able, source truth is not.
## Manual-verification convention (@manual, per-AC)
**Form:**
```
<!-- @manual -->
<!-- @manual: <procedure> -->
```
- The marker sits at the end of the AC bullet, in place of the anchors. Bare form for ACs with no bespoke guidance — never pad it with filler prose ("verify every acceptance criterion" is not a procedure). The `<procedure>` payload carries dedicated manual-verification steps when they exist.
- **Detection regex:** `<!--\s*@manual(?::\s*(.+?))?\s*-->`
- Granularity is strictly per-AC. There is NO REQ-level manual exemption, no Notes doc-pointer requirement, and no external checklist: `grep -rn '@manual' sdd/` IS the project's manual-verification inventory.
- Anchors present on a `@manual` AC are still validated as supplemental evidence; the marker lifts the anchor *requirement*, never the truth of what is written. Retrofitting an anchor and deleting the marker is the standard coverage-improvement path; adding `@manual` to dodge a failing anchor check is `finding-downgraded-to-skip` (HIGH).
- The `Verification:` field derives from the markers, categorically: `Manual check` ⇔ every AC carries `@manual`; otherwise any automated-verification value (`Automated test`, or a linked/labelled test-file value). Enforced as MEDIUM `verification-field-marker-drift` by `spec-enforce-truth`.
## Status semantics
| Status | Meaning |
|---|---|
| `Proposed` | Being drafted, not yet committed to spec |
| `Planned` | Committed to spec, not yet built |
| `Partial` | Built but some AC unmet OR no automated test verification found |
| `Implemented` | Built AND tests verify the acceptance criteria |
**One word, no prose.** No commit SHAs, no file paths, no "Partial — missing X, Y, Z". Use the optional `Notes:` field (≤3 sentences) for Partial only. Use `pending.md` for implementation tracking.
**Default Status when source exists but no test references the REQ ID:**
- `enforce_tdd: true` → `Partial`.
- `enforce_tdd: false` → `Implemented` (opted out of test-based verification; demoting every REQ would falsely brand the spec incomplete). Each `sdd/{domain}.md` file (per domain, not `sdd/README.md`) appends `_Verification: code-only (no automated coverage)._` at the bottom when this branch fires.
**Removed and never-built REQs.** When a REQ stops being the contract — feature removed, replaced, scope dropped — delete it from `sdd/{domain}.md`. Do not tombstone with `Status: Deprecated`. Never-built ideas go to `## Out of Scope`.
## Three autonomy modes
| Behavior | interactive | auto | unleashed |
|---|---|---|---|
| Where work lands | Current branch | Current branch | Current branch |
| SAFE fixes (strip non-ADR-index strikethrough, truncate prose Status, generate backlinks, move forbidden content) | Confirm → apply | Apply silently | Apply silently |
| RISKY fixes (truncate changes.md, mass moves, bulk operations) | Confirm + backup + apply | Backup + apply | Backup + apply |
| JUDGMENT calls (doc-vs-spec conflict, oversized REQ, fake-Deprecated) | Escalate to user, pause | Escalate to layout-resolved triage file (`sdd/spec/.review-queue.md` nested OR `sdd/.review-needed.md` flat legacy), continue | Auto-resolve conservatively, continue |
| `enforce_tdd` default | per layout-resolved config (`sdd/spec/config.yml` nested OR `sdd/config.yml` flat; default true) | same | **Forced true** |
| Output | Inline confirmations | Inline reports | Inline reports; per-category commits |
The fundamental difference is **how JUDGMENT is handled**. All modes push to the current branch. No PR, no new branch, no artificial change limits.
Conservative JUDGMENT auto-resolution rules live in the `sdd-clean` skill (that's where they apply).
## Auto-detection — when SDD enforcement runs without /sdd
Once `sdd/` exists, the workflow runs automatically:
- At PR-boundary events for PRs targeting `main`, `master`, or `develop` (PR open OR push to a branch with such a PR open), all required reviewers run **in parallel** and return structured reports without writing files. The root persists deferred findings and applies fixes.
- Both `sdd/`-lane agents detect `sdd/` exists → SDD-strict mode.
- **Layout detection:** `test -d sdd/spec` → nested (canonical); else flat (legacy, in migration window). Skills' file globs branch on this detection. `sdd/config.yml` lives at `sdd/spec/config.yml` (nested) or `sdd/config.yml` (flat).
- Both agents read `config.yml` → know whether to be interactive/auto/unleashed.
- Findings are auto-fixed per mode.
If `sdd/` doesn't exist, `spec-reviewer` exits silently. `doc-updater` runs in `docs-only` mode.
**SDLC requirements for autonomous review:** the pipeline gates on PR base = `main`, `master`, or `develop`. PRs into other integration branches (for example `staging`) are deferred until that branch opens or syncs a PR to one of those bases. Trunk-based projects using another base name get no review. `gh` CLI must be installed + authenticated. Upstream tracking on the working branch must resolve (`git rev-parse @{u}`). Strongly recommended: GitHub branch protection on `main` requiring PR before merge.
The hooks fail-safe in the right direction: if `gh` is missing or transiently fails, the Stop hook errs toward enforcement; the PostToolUse directive errs toward emission. Either way, the user can invoke review agents manually via the Task tool.
## /sdd edit — adding or modifying requirements
Always interactive. The agent:
1. Reads `sdd/README.md`, `sdd/constraints.md`, `sdd/glossary.md`, and the target domain file.
2. Asks the user what they want to add or change.
3. Drafts new/modified REQs in proper format.
4. Validates against discipline rules (forbidden content, length, AC quality).
5. Confirms with user.
6. Writes the updated domain file.
7. Updates glossary if new terms were introduced.
8. Adds a changelog entry to `sdd/changes.md`.
User-authored content gets one full pass before LOW-severity cleanup applies. Agent never blocks user input on style grounds.
**Post-edit hard gate:** if the new/modified REQ is `Planned` or `Partial`, next action MUST be entering Plan Mode (see § Plan Mode integration).
## /sdd add — creating a new domain
Same as `/sdd edit` but creates a new domain file:
1. Asks the user what the domain covers.
2. Proposes 5-15 initial requirements.
3. Creates `sdd/{domain}.md`.
4. Updates the domain index in `sdd/README.md`.
5. Updates glossary and changelog.
**Post-add hard gate:** enter Plan Mode before any source/test/config edits.
## /sdd mode — switching autonomy
```bash
/sdd mode interactive # default; agent asks before every fix
/sdd mode auto # agent silently applies safe fixes
/sdd mode unleashed # agent does everything without asking
/sdd mode # show current mode
```
The setting is persistent in `sdd/config.yml` and travels with the project. Per-command overrides via `--interactive`, `--auto`, `--unleashed` flags on `/sdd clean`.
**Transition gate on `unleashed`:** `/sdd mode unleashed` is rejected while `sdd/config.yml` carries `transition: true` (open triage items). Unleashed runs blind and auto-resolves JUDGMENT; triage items need user judgment by construction. Drain the queue via Resume Mode first. `auto` and `interactive` are both allowed during transition.
## Test discipline
Every REQ marked `Status: Implemented` should have at least one test file that references its REQ ID. Test discovery uses `test_globs` from `sdd/config.yml`. Detection is binary: the REQ ID literally appears in a test (in a test name, comment, or assertion message).
**Why REQ IDs in test files:** lets `spec-reviewer` verify which Implemented REQs have automated coverage without ambiguous prose matching.
```typescript
test('REQ-AUTH-001: rejects expired JWT tokens', () => {
// ...
});
```
When `enforce_tdd: true` (default), REQs without test references get downgraded to `Partial` with `Notes:`, and REQs whose source exists but lacks tests get flagged + auto-promoted `Planned → Partial`. Projects that genuinely cannot admit automated testing (pure visual design systems) opt out with `enforce_tdd: false`.
**Bug fix discipline:** write a failing test that reproduces the bug BEFORE writing the fix. The `tdd-guide` agent enforces this.
## TDD coverage targets
Recommended defaults, configurable per project:
| Layer | Target |
|---|---|
| Pure functions / utilities | 100% |
| API routes / handlers | 100% |
| Component rendering | 80% |
| Page-level integration | 80% |
| Default | 70% |
Guidance, not enforcement. The auto-demote rule is the only hard enforcement (binary: test exists per REQ or it doesn't).
## Plan Mode integration
**Plan Mode is mandatory on every spec→code transition:** after `/sdd init`, `/sdd edit` (if new REQ is `Planned`/`Partial`), or `/sdd add`. Next action MUST be `EnterPlanMode`. Hard gate. "build now" / "go" / "execute" / "ship it" authorize *starting*, never skipping.
The plan must:
1. Read all of `sdd/`, enumerate REQs by Status.
2. Filter to `Status: Planned` and `Status: Partial`.
3. Topo-sort by `Dependencies:`.
4. **Phase RED**: one failing test per AC via `tdd-guide`. Test name: `REQ-{DOMAIN}-{NNN}: {AC summary}`.
5. **Phase GREEN**: minimal impl, one REQ at a time, in dependency order.
6. **Phase VERIFY**: push, let `spec-reviewer` promote `Planned`→`Implemented` on next run.
7. Name the test framework from the stack (vitest, jest, pytest, go test, rspec, xctest, etc.); add Phase 0 if none exists.
**Informal proposal ≠ formal Plan Mode.** A detailed prose proposal + user "execute" / "go" / "fine" is *informal* approval. Still enter Plan Mode and re-present the same plan as a formal artifact.
**Legitimate skip:** only if the user, after seeing a plan proposal, explicitly says "skip plan mode" or "no plan". Record in feedback memory. Mark affected REQs `Partial` until tests exist.
## What is NOT a requirement
- **Bugs** → GitHub issues. The spec describes target state; bugs are the delta.
- **TODOs / known gaps** → `pending.md`. Status: Partial flags incompleteness; prose detail there.
- **Spec churn / "we tried X then Y"** → git history. No strikethrough or "Superseded:" annotations.
- **Build environment quirks** → `documentation/[lanes/]troubleshooting.md` (flat or nested layout).
- **Out-of-scope ideas** → `## Out of Scope` section in the relevant README.
## Templates location
All scaffolding templates live in `references/templates/` within this skill. The `sdd-init` skill reads them on demand. Bundled with the skill — no external dependencies.
| Template | Used by |
|---|---|
| `req-shape-example.md` | Read-only exemplar — canonical shape every REQ MUST copy. NOT emitted as a file; consulted before every REQ write. |
| `root-readme.md` | `/sdd init` → `README.md` |
| `sdd-readme.md` | `/sdd init` → `sdd/README.md` |
| `sdd-glossary.md` | `/sdd init` → `sdd/spec/glossary.md` |
| `sdd-constraints.md` | `/sdd init` → `sdd/spec/constraints.md` |
| `sdd-changes.md` | `/sdd init` → `sdd/spec/changes.md` |
| `sdd-config.yml` | `/sdd init` → `sdd/spec/config.yml` |
| `documentation-readme.md` | `/sdd init` → `documentation/README.md` |
| `documentation-architecture.md` | `/sdd init` → `documentation/lanes/architecture.md` (universal lane) |
| `documentation-api-reference.md` | `/sdd init` → `documentation/lanes/api-reference.md` (when source has HTTP routes) |
| `documentation-configuration.md` | `/sdd init` → `documentation/lanes/configuration.md` (when source has env vars / config) |
| `documentation-deployment.md` | `/sdd init` → `documentation/lanes/deployment.md` (when project is deployable) |
| `documentation-security.md` | `/sdd init` → `documentation/lanes/security.md` (when security boundaries exist) |
| `documentation-observability.md` | `/sdd init` → `documentation/lanes/observability.md` (when operational signals exist) |
| `documentation-troubleshooting.md` | `/sdd init` → `documentation/lanes/troubleshooting.md` (when incident evidence exists) |
| `documentation-project-lane.md` | `/sdd init` → an indexed first-level project lane when no canonical lane owns the concern |
| `documentation-decisions-readme.md` | `/sdd init` → `documentation/decisions/README.md` |
Placeholders use `{PLACEHOLDER_NAME}` format. The bundled `sdd-init` renderer selects lane templates and index rows; the agent then substitutes content placeholders from verified project evidence.
## Template conventions
Templates follow `documentation-discipline.md` from the first commit. Conventions baked in:
- **One-line table cells.** Every cell stays on a single line; the 50-word per-cell budget enforced by `doc-updater` Pass 1 begins at scaffolding. If a row needs more than about 50 words, write the long form as body prose and replace the cell with a concise summary and link.
- **Self-contained ADR index rows.** The canonical ledger uses `ID | Decision | Summary | Category | State`. The rendered Decision label is at most 90 characters. Summary is one sentence of 40–180 rendered characters that names the concrete subject and choice plus a body-supported driver or consequence. It never repeats the label or starts with an unexplained pronoun. Historical states name and link the successor, retained scope, or redirect destination.
- **No file-level line budget.** Lane size follows evidenced project complexity; per-element budgets and collection shape remain authoritative.
- **REQ backlinks pre-wired** in `Implements` columns using nested-layout links into `../../sdd/spec/{domain}.md`; flat legacy links remain readable during `/sdd clean` migration.
- **Lane-correct content placeholders.** `architecture.md` template never has an "API endpoints" section (that's `api-reference.md`'s lane).
- **ADR template carries the "What is NOT an ADR" guardrail and explicit state rendering.** `documentation-decisions-readme.md` distinguishes Active, Superseded, Partially superseded, and Redirect anchor records. Fully superseded index IDs and decisions are struck through while their sections remain; redirect anchors name and link their merged or reclassified destination instead of using ambiguous parenthetical shorthand. Every active ADR retains `Alternatives considered:` and `Consequences:`.
- **Security source maps use resolvable references.** Every decision identifier and requirement-domain reference links directly to its ADR anchor or specification file; shorthand such as `Operations SDD` is not emitted.