Skip to content

/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

From plugin
sd0x-dev-flow
18699 skills15 agents5 hooks
Install
$ npx -y skills add sd0xdev/sd0x-dev-flow --skill adr --agent claude-code

How 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.md
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 n
Read more
Ships withsd0x-dev-flow

Language: 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.

Get the whole plugin, auto-invoked
Stats
187
Stars
0
Views
24
Forks
Active
Maintenance
JavaScript
Language
MIT
License
9h ago
Last commit
6mo ago
Created

Repo: sd0xdev/sd0x-dev-flow

Other skills on sd0x-dev-flow.