/adr
Write an Architecture Decision Record (ADR) for a feature — Context / Decision / Status / Consequences / Alternatives, filed as docs/features/<feature>/adr-<NNN>-<title>.md with a 3-digit zero-padded number. Handles the Superseded case: bidirectional linking when a new ADR
$ npx -y skills add sd0xdev/sd0x-dev-flow --skill adr --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/adr
Context preview
The summary Claude sees to decide when to auto-load this skill.
Write an Architecture Decision Record (ADR) for a feature — Context / Decision / Status / Consequences / Alternatives, filed as docs/features/<feature>/adr-<NNN>-<title>.md with a 3-digit zero-padded number. Handles the Superseded case: bidirectional linking when a new ADR
SKILL.md
adr.SKILL.mdname: adr
description: "Write an Architecture Decision Record (ADR) for a feature — Context / Decision / Status / Consequences / Alternatives, filed as docs/features/<feature>/adr-<NNN>-<title>.md with a 3-digit zero-padded number. Handles the Superseded case: bidirectional linking when a new ADR replaces an old one. Use when: recording why an architectural approach was chosen, documenting a decision so it doesn't get re-litigated, marking a prior decision as superseded. Not for: feature-level technical design (use /tech-spec), task progress tracking (use /create-request), bulk backfill of historical decisions (a separate request — this skill writes one ADR at a time)."
allowed-tools: Read, Grep, Glob, Write, Edit, Bash(node:*), AskUserQuestion
ADR — Architecture Decision Record
Trigger
- Keywords: ADR, architecture decision record, decision record, record a decision, why did we choose, 架構決策, 決策紀錄
When NOT to Use
| Scenario | Alternative | |----------|------------| | Feature-wide technical design (components, data flow) | `/tech-spec` | | Task progress / acceptance-criteria tracking | `/create-request` | | Bulk backfill of decisions already made in the past | Separate request — this skill writes one ADR per invocation, not a batch |
Workflow
Phase 1: Resolve feature → shared feature-context resolution
Phase 2: Compute number → scan root + archived/, numeric max + 1, zero-pad to 3 digits
Phase 3: Gather content → Context / Decision / Status / Consequences / Alternatives
Phase 4: Write ADR → fill references/template.md, write to docs/features/<key>/
Phase 4b: Superseded link → (only if this ADR supersedes an existing one) edit both files
Phase 5: Report → path written, number assigned, links updated
Phase 1: Resolve Feature
Reuse the shared cascade — do not re-derive it here: `@skills/tech-spec/references/feature-context-resolution.md` (the canonical copy — `skills/create-request/references/`'s copy is a documented sync duplicate and has already drifted), canonical implementation `scripts/lib/feature-resolver.js`, CLI `node scripts/resolve-feature-cli.js [--feature <key>]`.
**The gate below checks the directory (and the confidence), not `key` alone.** For Levels 1–3 (explicit `--feature` with a valid slug, branch `feat/<x>`, or a changed path under `docs/features/<key>/`), `resolveFeatureContext` returns a non-null `key` with `confidence: "high"` or `"medium"` even when `docs/features/<key>/` does not exist on disk — it only probes the directory to enrich the result, never to invalidate it (`scripts/lib/feature-resolver.js:57-93`). An explicit `--feature` value that fails the case-insensitive slug pattern (`/^[a-z0-9][a-z0-9._-]*$/i`, e.g. `--feature ../evil`) is rejected at line 59 before it ever reaches `key`. Level 3b (a changed path under `skills/<key>/`, line 85-93) only returns when `probe()` finds the directory; on a miss it falls through — to Level 4 if `docs/features/` has **exactly one** subdirectory (returns that directory's name as `key` anyway, `source: "single_dir"`, `confidence: "low"` — a guess, not a match on the actual change), otherwise to Level 5 (`key: null`). `resolve-feature-cli.js` prints the **full result object** in the null case, e.g. `{"key":null,"source":"none",...}` — a bare `{}` means something else entirely (no git root, or the CLI itself threw). A typo'd `--feature` value is the likelier failure and does **not** produce a null key (Level 1 still returns it with `confidence: "high"`), so gating on `key` alone silently creates a bogus feature directory instead of asking:
| Result | Action | |--------|--------| | `key` resolved, `confidence` is `"high"` or `"medium"`, **and** `docs/features/<key>/` exists | Continue to Phase 2 | | `key` resolved but `docs/features/<key>/` does not exist (check with `node -e "process.exit(require('fs').existsSync(process.argv[1])?0:1)" "docs/features/<key>"` — this skill's `allowed-tools` has no general `Bash`, only `Bash(node:*)`) | **Gate: Need Human** — confirm this is really a new feature directory the user wants created; do not silently write into a typo'd path | | `confidence` is `"low"` (`source: "single_dir"`) | **Gate: Need Human** — this is a guess ("only one feature directory exists"), not a match on the actual change; confirm it's the right one before writing into it | | `key` is `null` (`resolve-feature-cli.js` prints the full object, e.g. `{"key":null,"source":"none",...}`) | **Gate: Need Human** — ask which feature this ADR belongs to; do not guess |
Phase 2: Compute the Number
Scan **both** the feature's root directory **and** its `archived/` subdirectory for existing `adr-*.md` files. `rules/docs-numbering.md` § Ancillary docs defines the `adr-<number>-<title>.md` filename pattern but says nothing about `archived/` — that convention lives in `scripts/lib/doc-classifier.js` (`scanFeatureDocs`, which skips directories named `archived` at any depth when building its *live* doc inventory). A number retired there is still taken, so this scan is deliberately broader than that inventory — building the live-doc list and computing the next free number are different purposes.
Run `skills/adr/scripts/next-adr-number.js` — do not hand-apply the max. Numeric max, not lexical sort: string-sorting `adr-9-...` after `adr-10-...` would collide, which is exactly the bug that shipping this as an unexecuted prose pin would miss.
node skills/adr/scripts/next-adr-number.js docs/features/<key>
(paths are repo-root relative, matching every other path in this skill). The function itself (`nextAdrNumber`, exported for direct unit testing — `test/skills/adr.test.js` exercises it against real temp directories, not just a prose pin):
function nextAdrNumber(featureDir) {
let max = 0;
for (const dir of [featureDir, path.join(featureDir, 'archived')]) {
let entries;
try { entries = fs.readdirSync(dir); } catch { continue; }
for (const nRead more
name: adr description: "Write an Architecture Decision Record (ADR) for a feature — Context / Decision / Status / Consequences / Alternatives, filed as docs/features/<feature>/adr-<NNN>-<title>.md with a 3-digit zero-padded number. Handles the Superseded case: bidirectional linking when a new ADR replaces an old one. Use when: recording why an architectural approach was chosen, documenting a decision so it doesn't get re-litigated, marking a prior decision as superseded. Not for: feature-level technical design (use /tech-spec), task progress tracking (use /create-request), bulk backfill of historical decisions (a separate request — this skill writes one ADR at a time)." allowed-tools: Read, Grep, Glob, Write, Edit, Bash(node:*), AskUserQuestion
ADR — Architecture Decision Record
Trigger
- Keywords: ADR, architecture decision record, decision record, record a decision, why did we choose, 架構決策, 決策紀錄
When NOT to Use
| Scenario | Alternative | |----------|------------| | Feature-wide technical design (components, data flow) | `/tech-spec` | | Task progress / acceptance-criteria tracking | `/create-request` | | Bulk backfill of decisions already made in the past | Separate request — this skill writes one ADR per invocation, not a batch |
Workflow
Phase 1: Resolve feature → shared feature-context resolution Phase 2: Compute number → scan root + archived/, numeric max + 1, zero-pad to 3 digits Phase 3: Gather content → Context / Decision / Status / Consequences / Alternatives Phase 4: Write ADR → fill references/template.md, write to docs/features/<key>/ Phase 4b: Superseded link → (only if this ADR supersedes an existing one) edit both files Phase 5: Report → path written, number assigned, links updated
Phase 1: Resolve Feature
Reuse the shared cascade — do not re-derive it here: `@skills/tech-spec/references/feature-context-resolution.md` (the canonical copy — `skills/create-request/references/`'s copy is a documented sync duplicate and has already drifted), canonical implementation `scripts/lib/feature-resolver.js`, CLI `node scripts/resolve-feature-cli.js [--feature <key>]`.
**The gate below checks the directory (and the confidence), not `key` alone.** For Levels 1–3 (explicit `--feature` with a valid slug, branch `feat/<x>`, or a changed path under `docs/features/<key>/`), `resolveFeatureContext` returns a non-null `key` with `confidence: "high"` or `"medium"` even when `docs/features/<key>/` does not exist on disk — it only probes the directory to enrich the result, never to invalidate it (`scripts/lib/feature-resolver.js:57-93`). An explicit `--feature` value that fails the case-insensitive slug pattern (`/^[a-z0-9][a-z0-9._-]*$/i`, e.g. `--feature ../evil`) is rejected at line 59 before it ever reaches `key`. Level 3b (a changed path under `skills/<key>/`, line 85-93) only returns when `probe()` finds the directory; on a miss it falls through — to Level 4 if `docs/features/` has **exactly one** subdirectory (returns that directory's name as `key` anyway, `source: "single_dir"`, `confidence: "low"` — a guess, not a match on the actual change), otherwise to Level 5 (`key: null`). `resolve-feature-cli.js` prints the **full result object** in the null case, e.g. `{"key":null,"source":"none",...}` — a bare `{}` means something else entirely (no git root, or the CLI itself threw). A typo'd `--feature` value is the likelier failure and does **not** produce a null key (Level 1 still returns it with `confidence: "high"`), so gating on `key` alone silently creates a bogus feature directory instead of asking:
| Result | Action | |--------|--------| | `key` resolved, `confidence` is `"high"` or `"medium"`, **and** `docs/features/<key>/` exists | Continue to Phase 2 | | `key` resolved but `docs/features/<key>/` does not exist (check with `node -e "process.exit(require('fs').existsSync(process.argv[1])?0:1)" "docs/features/<key>"` — this skill's `allowed-tools` has no general `Bash`, only `Bash(node:*)`) | **Gate: Need Human** — confirm this is really a new feature directory the user wants created; do not silently write into a typo'd path | | `confidence` is `"low"` (`source: "single_dir"`) | **Gate: Need Human** — this is a guess ("only one feature directory exists"), not a match on the actual change; confirm it's the right one before writing into it | | `key` is `null` (`resolve-feature-cli.js` prints the full object, e.g. `{"key":null,"source":"none",...}`) | **Gate: Need Human** — ask which feature this ADR belongs to; do not guess |
Phase 2: Compute the Number
Scan **both** the feature's root directory **and** its `archived/` subdirectory for existing `adr-*.md` files. `rules/docs-numbering.md` § Ancillary docs defines the `adr-<number>-<title>.md` filename pattern but says nothing about `archived/` — that convention lives in `scripts/lib/doc-classifier.js` (`scanFeatureDocs`, which skips directories named `archived` at any depth when building its *live* doc inventory). A number retired there is still taken, so this scan is deliberately broader than that inventory — building the live-doc list and computing the next free number are different purposes.
Run `skills/adr/scripts/next-adr-number.js` — do not hand-apply the max. Numeric max, not lexical sort: string-sorting `adr-9-...` after `adr-10-...` would collide, which is exactly the bug that shipping this as an unexecuted prose pin would miss.
node skills/adr/scripts/next-adr-number.js docs/features/<key>
(paths are repo-root relative, matching every other path in this skill). The function itself (`nextAdrNumber`, exported for direct unit testing — `test/skills/adr.test.js` exercises it against real temp directories, not just a prose pin):
function nextAdrNumber(featureDir) {
let max = 0;
for (const dir of [featureDir, path.join(featureDir, 'archived')]) {
let entries;
try { entries = fs.readdirSync(dir); } catch { continue; }
for (const nLanguage: English | 繁體中文 | 简体中文 | 日本語 | 한국어 | Español The harness layer for Claude Code. Let the model choose the path. Keep "done" verifiable. Full control plane on Claude Code. Skills-only distribution for Codex CLI and other compatible agents.
Repo: sd0xdev/sd0x-dev-flow
Other skills on sd0x-dev-flow.
- /architecture
Architecture design and documentation. Produces 3-architecture.md with component diagrams, data flow, integration points, and architecture decisions. Reads existing tech-spec as input. Use when: designing system architecture, documenting component interactions, creating
Open skill - /ask
Context-aware Q&A with auto context gathering. Use when: user has a quick question about codebase, git history, rules, docs, or skills during development. Not for: code changes (use feature-dev), code review (use codex-review-fast), deep research (use deep-research), full code
Open skill - /best-practices
Industry best practices conformance audit with mandatory adversarial debate. Produces audit artifact: verdict (OK/WARN/FAIL) + gap roadmap + debate proof. Use when: auditing current implementation against industry standards, checking compliance with best practices, benchmarking
Open skill - /bug-fix
Bug fix workflow. Use when: fixing bugs, resolving issues, regression fixes. Not for: new features (use feature-dev), understanding code (use code-explore). Output: fix + regression test + review gate.
Open skill - /bump-version
Bump package and plugin version in sync. Updates package.json, .claude-plugin/plugin.json, and install-state manifest to the same version. Use when: user says 'bump version', 'update version', '更新版本', '版本 +1', or /bump-version
Open skill - /check-coverage
Comprehensive assessment of Unit / Integration / E2E three-layer test coverage, identify gaps and provide actionable recommendations.
Open skill

