ADR writing
A decision nobody can read was not recorded. This skill governs the shape of
every file under docs/adr/ and of docs/ARCHITECTURE.md: how the file is
named and retired, how the sections run, when to draw instead of explain, and
what must hold before the document lands. When a change needs an ADR and what
an agent owes the ADRs in force is .claude/rules/adr.md, loaded in every
session; this skill does not repeat it.
Every sentence must pass one test: would someone meeting this codebase for
the first time understand it without asking a question? If not, the fix
belongs in the writing, not in the reader.
What an ADR is for
An ADR records an architecture-level decision: what was chosen, which
alternatives were dropped and why, and what shape the code must now take. The
reader is an agent or a person who will build against this decision months
from now, not the author and not today's reviewer.
- Enough context, and no more. A line survives only if that reader would
act differently for having read it.
- Never narrate your thinking. Deliberation, reversals, what an earlier
draft said, what you worried about — none of it belongs. State the fact, the
option, or the decision.
- The document never talks about itself. No "covered in the last section",
no "this document does not decide X". Say the thing or delete it.
- Link outward instead of retelling. When the context lives in another
ADR, a source file, a Jira issue, or an upstream document, cite it and
reproduce only the sentence the reader must act on.
- Name the scope boundary once. What is out of scope gets one line — never
the reasoning for deferring it, never a sketch of the deferred design.
After reading, does the reader know what was chosen, what was rejected, and
what shape the code must take? If any of the three is missing it is a memo,
not a decision record.
ADR file conventions
This is the definition of how an ADR file is named, titled, and retired. The
one other copy is .github/instructions/adr.instructions.md, which restates
the points Copilot needs because it cannot load a skill; keep the two in step.
- Filename —
NNNN-title.md, for example
0001-explicit-project-prop-contract.md. The next number is the highest
NNNN in docs/adr/ plus one. Numbers are never reused, so when the
sequence has a gap the deleted number stays retired; git log -- docs/adr
shows it.
- Title —
# NNNN — <English noun phrase> (T1–T6). A Jira key goes in
the sources section, never in the title. A supersede pointer goes on its
own line, never in the title.
- No status field. An ADR on
main is a decision in force — landing it
there, merged and human-approved, is the record. A draft under review is
proposed by virtue of sitting in an unmerged PR, and nothing marks it in the
file. The one marker a file ever carries is reversal.
- Reversing a decision — do not edit the existing ADR's reasoning. Either
keep the file and add a top line
> superseded by NNNN naming what replaced
it, or delete it outright. Both are allowed, and deleting is usually
right once the decision and the code it described are both gone, because a
retired file is then a trap a reader has to disprove. Git history holds
what it said. Convert inbound references in surviving documents and source
comments to plain ADR NNNN mentions.
- Partial replacement — if the new ADR replaces only part of the old,
keep the old file, say so in the new ADR, and add a scoped pointer line
rather than the blanket supersede marker.
- Mention form — documents and PR bodies write
ADR NNNN. Source
comments written before this convention say ADR-NNNN; they are corrected
when the file is next edited, never swept.
- Language — the title is English; the body is Korean, with English
technical terms and identifiers written as they appear in the code. An ADR
that landed before this convention keeps its body language; a document is
revised only when its content changes, never translated for its own sake.
Section headings follow the body language, as
references/document-shape.md fixes.
Phase 0 — Gather what the document must agree with
Read these before writing, so the draft does not contradict what already
landed.
- The ADRs this decision touches, including the ones it supersedes or
narrows, and their rows in
docs/ARCHITECTURE.md.
- The source files the decision names, so identifiers in the text match the
code — component names, hook names, atom names, ESLint rule ids.
- The Jira issue the work belongs to, so the sources section can cite it.
- Sibling ADRs written in the same increment, so terminology stays shared.
Phase 1 — Draft against the rule catalogues
Two reference files hold the rules, and both cite by id — "T1 violation",
"fixed S4", "D2 missing".
| file |
ids |
what it governs |
| references/writing-rules.md |
T1–T6, L1–L5, S1–S10, D1–D2 |
the title, the terms, the sentences and bullets, the Summary a body opens with, and the diagram a flow gets |
| references/document-shape.md |
D3–D4 |
the section skeleton, the heading language, the increment overview, the one-diagram floor, and the mermaid syntax traps |
Write the sections in the order D3 fixes: title, Summary, Context, diagrams,
Decision, alternatives with the reason each was rejected, Consequences,
sources, glossary.
Phase 2 — Reread as a first-time reader
Work the reread list at the end of
references/writing-rules.md, then these three
checks, which only a document can fail:
- A sibling document draws the same components with a different decomposition
(D2), or the increment has no overview document (D4).
- A section from the D3 skeleton is missing, or a heading is in the wrong
language for the body.
- A Decision item stacks several decisions that should be
### N.
subsections.
Phase 3 — Adversarial review before landing
Self-review does not catch narration: the author cannot see their own. Before
landing, dispatch one reviewer agent with the document path and this
instruction, and fix everything it returns. Ask for defects, not a verdict:
- Padding. Every line a reader building from this would not act on —
narrated thinking, restatements, deferral rationale, the document describing
itself — with its line number.
- Gaps. What an agent implementing against this would still have to ask:
a chosen shape with no type, no prop contract, no invariant, no file it
lives in.
Verify the findings before acting — a reviewer that is wrong about the code
is common. Check the file it cites.
Phase 4 — Land
- Read the document once on GitHub's rendering of the branch. A broken
mermaid diagram shows there as a syntax error; no CI check catches it.
- Add or update the ADR's row in
docs/ARCHITECTURE.md in the same change.
- Verify every cross-reference resolves to a file that exists, and when an
ADR was retired, grep for its filename so no link points at it.
1---2name: adr-writing3description: Write and revise the ADRs in `docs/adr/` and their index `docs/ARCHITECTURE.md` so a first-time reader understands them alone. Covers the file conventions (name, title, no status field, how a decision is retired), the section skeleton, the writing rules for titles, terms, and sentences, mermaid usage and its syntax traps, and the checks a document passes before it lands. Use before authoring a new ADR, before revising one, and before landing any change under `docs/adr/`. Trigger on "ADR 써줘", "결정 기록 남겨줘", "write an ADR", "architecture decision record", or when an implementation needs a decision no ADR in force covers. When a change needs an ADR, and what an agent owes the ADRs in force, is `.claude/rules/adr.md`.4---56# ADR writing78A decision nobody can read was not recorded. This skill governs the shape of9every file under `docs/adr/` and of `docs/ARCHITECTURE.md`: how the file is10named and retired, how the sections run, when to draw instead of explain, and11what must hold before the document lands. When a change needs an ADR and what12an agent owes the ADRs in force is `.claude/rules/adr.md`, loaded in every13session; this skill does not repeat it.1415Every sentence must pass one test: **would someone meeting this codebase for16the first time understand it without asking a question?** If not, the fix17belongs in the writing, not in the reader.1819## What an ADR is for2021An ADR records an architecture-level decision: what was chosen, which22alternatives were dropped and why, and what shape the code must now take. The23reader is an agent or a person who will build against this decision months24from now, not the author and not today's reviewer.2526- **Enough context, and no more.** A line survives only if that reader would27 act differently for having read it.28- **Never narrate your thinking.** Deliberation, reversals, what an earlier29 draft said, what you worried about — none of it belongs. State the fact, the30 option, or the decision.31- **The document never talks about itself.** No "covered in the last section",32 no "this document does not decide X". Say the thing or delete it.33- **Link outward instead of retelling.** When the context lives in another34 ADR, a source file, a Jira issue, or an upstream document, cite it and35 reproduce only the sentence the reader must act on.36- **Name the scope boundary once.** What is out of scope gets one line — never37 the reasoning for deferring it, never a sketch of the deferred design.3839After reading, does the reader know what was chosen, what was rejected, and40what shape the code must take? If any of the three is missing it is a memo,41not a decision record.4243## ADR file conventions4445This is the definition of how an ADR file is named, titled, and retired. The46one other copy is `.github/instructions/adr.instructions.md`, which restates47the points Copilot needs because it cannot load a skill; keep the two in step.4849- **Filename** — `NNNN-title.md`, for example50 `0001-explicit-project-prop-contract.md`. The next number is the highest51 `NNNN` in `docs/adr/` plus one. Numbers are never reused, so when the52 sequence has a gap the deleted number stays retired; `git log -- docs/adr`53 shows it.54- **Title** — `# NNNN — <English noun phrase>` (T1–T6). A Jira key goes in55 the sources section, never in the title. A supersede pointer goes on its56 own line, never in the title.57- **No status field.** An ADR on `main` is a decision in force — landing it58 there, merged and human-approved, is the record. A draft under review is59 proposed by virtue of sitting in an unmerged PR, and nothing marks it in the60 file. The one marker a file ever carries is reversal.61- **Reversing a decision** — do not edit the existing ADR's reasoning. Either62 keep the file and add a top line `> superseded by NNNN` naming what replaced63 it, or **delete it outright**. Both are allowed, and deleting is usually64 right once the decision and the code it described are both gone, because a65 retired file is then a trap a reader has to disprove. Git history holds66 what it said. Convert inbound references in surviving documents and source67 comments to plain `ADR NNNN` mentions.68- **Partial replacement** — if the new ADR replaces only part of the old,69 keep the old file, say so in the new ADR, and add a scoped pointer line70 rather than the blanket supersede marker.71- **Mention form** — documents and PR bodies write `ADR NNNN`. Source72 comments written before this convention say `ADR-NNNN`; they are corrected73 when the file is next edited, never swept.74- **Language** — the title is English; the body is Korean, with English75 technical terms and identifiers written as they appear in the code. An ADR76 that landed before this convention keeps its body language; a document is77 revised only when its content changes, never translated for its own sake.78 Section headings follow the body language, as79 [references/document-shape.md](references/document-shape.md) fixes.8081## Phase 0 — Gather what the document must agree with8283Read these before writing, so the draft does not contradict what already84landed.8586- The ADRs this decision touches, including the ones it supersedes or87 narrows, and their rows in `docs/ARCHITECTURE.md`.88- The source files the decision names, so identifiers in the text match the89 code — component names, hook names, atom names, ESLint rule ids.90- The Jira issue the work belongs to, so the sources section can cite it.91- Sibling ADRs written in the same increment, so terminology stays shared.9293## Phase 1 — Draft against the rule catalogues9495Two reference files hold the rules, and both cite by id — "T1 violation",96"fixed S4", "D2 missing".9798| file | ids | what it governs |99|---|---|---|100| [references/writing-rules.md](references/writing-rules.md) | T1–T6, L1–L5, S1–S10, D1–D2 | the title, the terms, the sentences and bullets, the Summary a body opens with, and the diagram a flow gets |101| [references/document-shape.md](references/document-shape.md) | D3–D4 | the section skeleton, the heading language, the increment overview, the one-diagram floor, and the mermaid syntax traps |102103Write the sections in the order D3 fixes: title, Summary, Context, diagrams,104Decision, alternatives with the reason each was rejected, Consequences,105sources, glossary.106107## Phase 2 — Reread as a first-time reader108109Work the reread list at the end of110[references/writing-rules.md](references/writing-rules.md), then these three111checks, which only a document can fail:112113- A sibling document draws the same components with a different decomposition114 (D2), or the increment has no overview document (D4).115- A section from the D3 skeleton is missing, or a heading is in the wrong116 language for the body.117- A Decision item stacks several decisions that should be `### N.`118 subsections.119120## Phase 3 — Adversarial review before landing121122Self-review does not catch narration: the author cannot see their own. Before123landing, dispatch one reviewer agent with the document path and this124instruction, and fix everything it returns. Ask for defects, not a verdict:125126- **Padding.** Every line a reader building from this would not act on —127 narrated thinking, restatements, deferral rationale, the document describing128 itself — with its line number.129- **Gaps.** What an agent implementing against this would still have to ask:130 a chosen shape with no type, no prop contract, no invariant, no file it131 lives in.132133Verify the findings before acting — a reviewer that is wrong about the code134is common. Check the file it cites.135136## Phase 4 — Land137138- Read the document once on GitHub's rendering of the branch. A broken139 mermaid diagram shows there as a syntax error; no CI check catches it.140- Add or update the ADR's row in `docs/ARCHITECTURE.md` in the same change.141- Verify every cross-reference resolves to a file that exists, and when an142 ADR was retired, grep for its filename so no link points at it.