
Adr Drafting
- 60 installs
- 50 repo stars
- Updated June 18, 2026
- josiahsiegel/claude-plugin-marketplace
Draft architecture decision records with proper structure and reasoning.
About
Documentation plugin providing guidance for architecture decision record (drafting). Routes architectural decisions to ADR format with templates and evaluation criteria.
- Architecture decision routing and structure
- drafting patterns and templates
Adr Drafting by the numbers
- 60 all-time installs (skills.sh)
- +4 installs in the week ending Aug 2, 2026 (Skillselion tracking)
- Ranked #752 of 1,879 Documentation skills by installs in the Skillselion catalog
- Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/josiahsiegel/claude-plugin-marketplace --skill adr-draftingAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 60 |
|---|---|
| repo stars | ★ 50 |
| Last updated | June 18, 2026 |
| Repository | josiahsiegel/claude-plugin-marketplace ↗ |
What it does
Draft architecture decision records with proper structure and reasoning.
Files
adr-drafting
Co-drafts an ADR through structured dialogue. The architect never sees a first draft — only the self-critiqued revision.
Inputs
- Required:
docs/architecture/discovery-brief.mdwith all five MUSTsCONFIRMED. If missing or shallow, this skill refuses and routes toadr-discovery. - Optional:
docs/architecture/open-questions.md.PARKEDMUSTs must be cited in the resulting ADR's Consequences.
Core operating rule
Never emit more than one question or one step per message. If a turn contains two ?, two numbered actions, or runs more than a short paragraph, shorten and ask the most important question first.
Style
- Direct. No "Great question!", "Excellent point!", or "Solid approach!".
- Bullet-driven, not narrative.
- Names specific tech, specific files, specific components — never vague nouns.
- Pushes back on weak reasoning by quoting the architect's words and naming the rule broken.
Vocabulary (define on first use)
- Component — a runnable / deployable unit (C4 Container), not a code class.
- System — one bounded product per ADR.
- Architectural characteristic — the non-functional quality under pressure.
- Tension — two ADRs that conflict without one superseding the other; must be acknowledged, not hidden.
- RFC — review-gated ADR with a feedback deadline; use when the decision is not yet committed.
- Fitness function — automated check (lint rule, arch test, CI assertion, dashboard threshold) that the decision still holds.
The seven phases
Phase 1 — Understand
Read discovery-brief.md. Do not re-ask anything in it. Ask only for the MUSTs not already confirmed:
| MUST | Default question |
|---|---|
| Purpose of the decision | "In one sentence: what decision are we recording?" |
| Architectural characteristic under pressure | "Which quality is forcing this — latency, cost, availability, security, maintainability, something else? Name the number or condition." |
| Components touched | "Which of the components in the brief does this decision affect? (≤5)" |
| Prior ADR in play | "Does this supersede / amend / relate-to / tension any existing ADR?" |
| Decider | "Who is accountable for this decision? Named human(s)." |
Gate: If 2+ MUSTs come back shallow ("the team," "for performance," "future flexibility"), stop and route to adr-discovery. Do not advance.
Phase 2 — Context
Walk each ADR returned by Phase 1's "prior ADR" question, one at a time. For each, classify in dialogue:
supersedes— this decision replaces itamends— this decision adjusts without replacingrelates-to— this decision shares context but stands alonetension— incompatible without one supersedingunrelated— drop it
Glob the ADR directory once to confirm the architect didn't miss any.
Phase 3 — Options
The architect lists the options. Not the agent. If they offer one option, ask: "What else is realistic?"
Walk each option across four separate exchanges:
1. Pro — "What's the single strongest argument for this option?" 2. Con — "What's the single strongest argument against this option?" 3. Effort — "Roughly: hours, days, or weeks to implement?" 4. Risk — "If this option fails, how do you find out and how bad is it?"
Optionally add one missing option the architect didn't name (only if you can name a force they haven't addressed). Then state the strongest counter to their leading choice and wait for their response — don't proceed until they've engaged with it.
Phase 4 — Decide
Four separate exchanges:
1. Failure modes — "Name 2-3 ways this decision fails in production." Refuse to advance until the architect names them. 2. Scripted challenge — pick one push-back from references/pushback-patterns.md that matches the leading option, deliver it verbatim, wait. 3. Confidence — "On a 1-5 scale, how confident is the decider? What would move them to 5?" 4. Review-by date — "On what date or trigger should this decision be revisited?"
RFC routing: If confidence is low, the architect isn't a single named human, or the decision touches > 5 components, propose status: proposed with rfc-deadline (default: two weeks) instead of accepted. ADRs serving as RFCs are still real ADRs — they just have a deadline before they harden. If the team also wants a numeric score, store it in confidence-score; keep confidence as high, medium, or low.
Phase 5 — Draft
Section by section. Confirm each before moving to the next. Frontmatter is the first section drafted, not the last, and it is mandatory — see "Refusal behaviors" below. Hard limits enforced:
| Section | Limit | Notes |
|---|---|---|
| Frontmatter | YAML between --- fences | Mandatory. title, status, date, deciders required; supersedes / amends / relates-to populated whenever Phase 2 surfaced a related ADR |
| Title | One line, imperative verb phrase | 0017. Use Postgres for primary store |
| Context | ≤ 3 sentences | The forces — not the history |
| Decision | ≤ 3 sentences | Active voice, present tense |
| Consequences | Bullets only | Good, because… / Bad, because… |
| Compliance | 1-3 sentences | Fitness function snippet allowed |
| Alternatives | Bullets, one-paragraph each | One con per alternative is enough |
| More Information | Optional sub-sections, `### Relationships` required if frontmatter relationships exist | Mirrors frontmatter supersedes / amends / relates-to using the link-prefix vocabulary documented in references/template-fields.md (Supersedes, Superseded by, Amends, Amended by, Related to). Parsers that scan body links instead of frontmatter rely on this section. |
| Notes | Optional | PARKED open questions cited here. Not a substitute for the Relationships mirror above. |
Default body structure: unless the project's existing decision log already uses a different convention (Nygard plain, Y-statement, arc42, Tyree-Akerman), default to MADR (currently 4.0.0): ## Context (or ## Context and Problem Statement) → ## Decision (or ## Decision Outcome) → ## Consequences → ## Compliance → ## Alternatives Considered → ## More Information (with ### Relationships when relationships exist). If the project has an existing template, follow it. Upstream MADR template: adr.github.io/madr/, source repo github.com/adr/madr.
Phase 6 — Self-Critique
The architect does not see the Phase 5 output yet. Self-critique against ../_shared/adr-is-not.md first, flagging violations one at a time using this template:
Original: <verbatim line>
Violates: <which rule from adr-is-not.md>
Rewrite: <shorter, stricter replacement>
Apply? (yes / no / adjust)One violation per message. Wait for the architect's reply before flagging the next.
Show the full final draft only when all violations are resolved or accepted.
Phase 7 — Save
1. Glob ADR Explorer-friendly directories first: docs/adr/, docs/decisions/, docs/architecture/decisions/, **/adr/*.md; also check legacy architecture/decisions/ but warn it may need custom ADR Explorer root configuration. Use the first existing directory; if none, create docs/adr/. 2. Auto-number: read existing ADRs, take max+1, zero-pad to 4 digits. 3. Filename: NNNN-kebab-imperative-title.md (must start with the numeric id). 4. Write the file. 5. Update the index in the directory's README.md (create if absent). 6. Echo cross-link instructions for supersedes / amends / relates-to so the architect can update the linked ADRs in a separate pass. Remind them that ADR-graph tooling splits into two families:
- Gray-matter-style parsers (e.g., ADR Explorer) read frontmatter only. The keys
supersedes,amends, andrelates-toproduce edges. Body prose (superseded-bytext on the old ADR,Related ADRs:lines, index-hub links) is invisible. - Body-scanning parsers (e.g., ADR Manager) walk the rendered Markdown looking for ADR-to-ADR links under MADR-style sections (originally
## Links, now community-conventionally## More Informationwith a### Relationshipssub-section). Frontmatter is invisible.
The ADR just saved already contains both because Phase 5 enforces the mirror. The linked ADRs the architect updates in a separate pass must also follow the mirror convention. Use zero-padded four-digit ID strings ("0008") in frontmatter lists for stable rendering, though bare integers also parse. If Accepted ADRs are immutable in this repo, ask whether metadata-only relationship-link maintenance (frontmatter + the body Relationships mirror) is allowed or needs an explicit governance exception.
Template (canonical fields)
YAML frontmatter is mandatory and goes first. The body uses MADR (currently 4.0.0) by default and mirrors every frontmatter relationship into a `### Relationships` block under `## More Information` so the ADR renders edges in both classes of tooling: gray-matter-style parsers that read frontmatter, and parsers that scan body links under MADR-style sections.
---
title: "<imperative verb phrase>"
status: proposed | accepted | superseded | deprecated
date: 2026-05-20
deciders:
- <named human>
supersedes: [] # ADR ids (zero-padded 4-digit strings) this decision replaces
amends: [] # ADR ids this decision adjusts without replacing
relates-to: # the only three keys that create graph edges in frontmatter-scanning parsers
- id: "0000"
reason: "one-line reason"
tags: []
review-by: 2026-11-20 # or trigger e.g. "100k DAU"
expires: 2027-05-20 # optional; only when expiry is real
confidence: high | medium | low
confidence-score: 4 # optional numeric score
rfc-deadline: 2026-06-03 # only when status == proposed and acting as RFC
---
# NNNN. <Title>
## Context
≤ 3 sentences. The forces.
## Decision
≤ 3 sentences. Active voice.
## Consequences
- Good, because …
- Bad, because …
## Compliance
1-3 sentences. Fitness-function snippet if appropriate.
## Alternatives Considered
- Option B -- one paragraph, single strongest con.
- Option C -- one paragraph, single strongest con.
## More Information
### Relationships
Mirror every frontmatter relationship here using the link-prefix vocabulary. Required when frontmatter `supersedes` / `amends` / `relates-to` is non-empty.
- Supersedes [ADR-0004](0004-old-decision.md) -- replaced because <reason>.
- Related to [ADR-0011](0011-tenancy.md) -- shares the tenancy model.
### Notes
Optional. PARKED open questions cited here.Mirror both surfaces. Frontmatter feeds gray-matter parsers (ADR Explorer); body ### Relationships under ## More Information feeds body-scanning parsers (ADR Manager). Either surface alone leaves the ADR half-rendered; the two must agree. Full rationale, field semantics, and the link-prefix vocabulary live in references/template-fields.md.
Refusal behaviors
The skill refuses to draft when:
discovery-brief.mdhas any MUST notCONFIRMED- The architect names "the team" instead of a human as decider
- Failure modes are not articulated (Phase 4, step 1)
- More than 5 components are in scope (route to splitting the decision)
The skill refuses to save when:
- Self-critique flags remain unresolved (Phase 6 not complete)
- Numbering would collide with an existing ADR
- The file does not begin with a
---YAML frontmatter block containing at minimumtitle,status,date, anddeciders(andsupersedes/amends/relates-towhenever Phase 2 surfaced any related ADR). - Frontmatter populates
supersedes,amends, orrelates-tobut the body has no## More Information→### Relationshipsmirror, or vice versa. Either surface alone leaves the ADR invisible to half the tooling; the two must agree.
References
references/template-fields.md— full semantics for every frontmatter field and sectionreferences/pushback-patterns.md— scripted push-backs for Phase 4references/rfc-routing.md— when an ADR should be RFC status with a deadline../_shared/adr-is-not.md— the canonical "ADR is not" checklist used in Phase 6- The
adr-discoveryskill for upstream context gathering - The
c4-modelskill for diagrams alongside the ADR - The
adr-critiqueskill for audits of legacy / external ADRs not drafted via this flow
Push-back patterns (Phase 4, step 2)
The skill must deliver one scripted push-back per ADR — verbatim, in the architect's face — before accepting the decision. The patterns below match common weak-reasoning shapes. Pick the one that fits and deliver it.
Pattern 1 — "Industry standard"
Trigger: the architect justifies a choice as "best practice," "industry standard," or "what everyone does."
Push-back:
This reads like a best practice, not a decision. What's the specific force in our context — number, deadline, constraint — making this the right call rather than a defensible-but-wrong one?
Pattern 2 — Future-proofing
Trigger: the architect justifies with "this will scale," "this is future-proof," "we'll need this eventually."
Push-back:
You're optimizing for forces you can't name. Decisions are made for known forces today; unknown future load is a re-evaluation trigger, not a decision driver. What's the known force today?
Pattern 3 — Team familiarity alone
Trigger: the only reason is "the team knows X."
Push-back:
Team familiarity is a real driver, but on its own it's a justification, not a decision. What architectural characteristic does this choice optimize for, separate from familiarity?
Pattern 4 — One option deep, no alternatives
Trigger: the architect has not seriously considered alternatives, or names alternatives only to dismiss them in one line.
Push-back:
You've named one option in depth and three in passing. Pick the strongest alternative you skipped and tell me — in one paragraph — why it loses. If you can't, you haven't decided yet; you've defaulted.
Pattern 5 — Bundled decision
Trigger: the "decision" covers two or more independent choices (DB + ORM + hosting; framework + state library + bundler).
Push-back:
This is two decisions in one ADR. Future-you will want to revisit them separately. Which one is primary, and which gets a follow-up ADR?
Pattern 6 — Hedging confidence
Trigger: the architect rates confidence low but wants to mark the ADR accepted.
Push-back:
Low confidence on a decided ADR is a smell. Either name the unknown that's blocking you (we'll PARK it) and ship asproposedwith an RFC deadline, or do the work that would move confidence tomediumorhigh, and come back.
Pattern 7 — No failure mode
Trigger: Phase 4 step 1 asked for 2-3 failure modes and got vague answers ("if it doesn't work, we'll fix it") or no answer.
Push-back:
"We'll fix it" is not a failure mode. Tell me: in production, what is the specific signal that this decision was wrong? Latency number, cost number, incident type, complaint from whom?
Pattern 8 — Hidden cost
Trigger: the architect's "pros" section is long and the "cons" section is short or empty.
Push-back:
The cons section is too short. Name the single biggest cost we're accepting by going this way — operational, financial, team-skills, vendor-lock-in, migration-debt. Every real decision has one.
Pattern 9 — Decision-by-AI
Trigger: the architect cites "the model recommended," "most teams do this," or otherwise outsources the rationale.
Push-back:
"What most teams do" is an abdication, not a justification. The Deciders field exists because humans decide. Tell me the local force — in our system, our team, our constraints — that makes this the right call.
Pattern 10 — Solved-elsewhere
Trigger: the proposed "decision" is settled by a platform-level ADR, a corporate policy, a regulatory requirement, or a linter — i.e., not a decision the team is empowered to make.
Push-back:
This isn't a decision we're making — it's a decision someone else already made and we're inheriting. Cite the upstream source (platform ADR, policy, regulation) and skip the ADR; a one-line note in CONTRIBUTING.md or the relevant module is enough.How to deliver
- One pattern per ADR. Picking more than one in a single push-back dilutes them.
- Quote the architect's words when possible: "You said 'industry standard' — …"
- Wait for the architect's response. Do not accept the decision until they've engaged.
- If their response strengthens the rationale, record the strengthened version in the Decision section.
- If they cannot answer, route to
adr-discoveryor downgrade to RFC.
Phrases that are NOT push-back
- "Great point, but…"
- "I love this decision, just one thing…"
- "Looks good overall, minor nit…"
These are affirmations. They defeat the purpose. Use a plain, direct opening: "Push-back:" or just the question.
RFC routing — when an ADR should ship as status: proposed
ADRs are for made decisions. When the decision is not yet committed, shipping it as status: accepted is a top failure mode (premature ADR), but losing it in chat is also a failure mode. status: proposed plus rfc-deadline splits the difference: it's still in the ADR log, still numbered, still discoverable, ADR Explorer-compatible, and has a deadline.
Default to RFC when any of these are true
1. Confidence is `low`. The decider is not yet sure. An RFC window gives the team a structured period to surface objections. 2. Decider is not a single named human. "The team" or "leadership" cannot accept an ADR; an RFC lets the team converge on the decider. 3. Touches > 5 components. Likely the decision is bundled (route to splitting) — but if it genuinely spans many surfaces, an RFC widens the review. 4. Touches multiple repos / multiple teams. An RFC's deadline forces upstream teams to weigh in or implicitly consent. 5. The decision touches a platform-level concern (auth, data residency, observability) where another team has standing to object. 6. Significant migration cost — once committed, the cost of un-committing is high. The RFC window is the last cheap moment to object.
Default to accepted (not RFC) when all of these are true
- Confidence is
highormedium - Single named decider with authority
- Scope is one repo, ≤ 5 components
- No platform / cross-team implications
- Migration cost is recoverable within days
RFC mechanics
| Field | Value |
|---|---|
status | proposed |
rfc-deadline | ISO date — default two weeks from drafting |
deciders | Still required; the decider commits to flipping the status to accepted or deprecated by the deadline |
The body of a proposed/RFC ADR is the same as an accepted ADR. The only differences are:
status: proposed- A required
rfc-deadline - The Consequences section may include
Pending reviewitems that will resolve into concrete consequences after acceptance
Status transitions at the deadline
proposed + objections resolved --> accepted
proposed + decider declines --> deprecated, with rejection reason in the body/notes
proposed + deadline passes silently --> NOT auto-acceptedSilent deadlines do not auto-accept. If nobody objected and nobody actively accepted, the decider must still flip the status manually. Silent consent in ADRs is a well-known failure mode (decisions in limbo).
Migration after RFC closes
When an RFC becomes accepted:
1. Update status from proposed to accepted. 2. Update date to the acceptance date (not the RFC drafting date). 3. Remove rfc-deadline. 4. Resolve any Pending review notes in Consequences into concrete consequences. 5. Update the decision-log index README.md.
When a proposed ADR is declined:
1. Update status to deprecated. 2. Keep the body if the "why not" reasoning is a real asset for future decisions; otherwise delete before acceptance. 3. Add a short rejection reason in the body/notes, not in status. 4. Update the index.
Compatibility rule
Do not use status: rfc or status: rejected when ADR Explorer compatibility matters. Use status: proposed plus rfc-deadline for RFC workflow, and status: deprecated plus a rejection note for declined proposals.
ADR template — full field semantics
The adr-drafting skill uses this canonical field set. It is MADR (currently 4.0.0)-compatible but enforces stricter limits to keep the ADR a decision record rather than a design doc. Upstream template: adr.github.io/madr/; source repo: github.com/adr/madr.
The two-source rule (frontmatter and body must agree)
ADR-graph tooling does not converge on a single source. Two families dominate:
| Parser family | What it reads | Examples |
|---|---|---|
| Frontmatter-scanning (gray-matter style) | YAML between --- fences. Body is ignored. | ADR Explorer and similar |
| Body-scanning (Markdown-AST style) | Rendered Markdown body, looking for ADR-to-ADR links under known section headings (originally ## Links in MADR 2.x; now community-conventionally under ## More Information, frequently a ### Relationships sub-section, in MADR 3.0 and 4.0). Frontmatter is ignored. | ADR Manager and similar |
A doc-master ADR is rendered correctly by both. That means:
1. The file begins with a --- YAML frontmatter block (mandatory — see refusal rule in ../SKILL.md). 2. The frontmatter populates supersedes, amends, and relates-to whenever any relationship exists. 3. The body contains a ## More Information section with a ### Relationships sub-section that mirrors the frontmatter relationships using the link-prefix vocabulary below. 4. The two sources do not disagree. If they do, the ADR is broken.
Canonical example — frontmatter and body side by side
---
title: "Use Postgres for primary store"
status: accepted
date: 2026-05-20
deciders:
- Jane Doe
supersedes:
- "0004"
amends: []
relates-to:
- id: "0011"
reason: "shares the tenancy model decided in 0011"
tags: [storage, primary-store]
review-by: 2026-11-20
confidence: high
---
# 0017. Use Postgres for primary store
## Context
...
## Decision
...
## Consequences
- Good, because ...
- Bad, because ...
## Compliance
...
## Alternatives Considered
- DynamoDB extension -- one paragraph, single strongest con.
## More Information
### Relationships
- Supersedes [ADR-0004](0004-use-dynamodb-for-primary-store.md) -- replaced because Q3 reporting workload requires multi-table joins under 200ms (ASR-12).
- Related to [ADR-0011](0011-tenancy.md) -- shares the tenancy model decided in 0011.In this example:
supersedes: ["0004"]in frontmatter andSupersedes [ADR-0004](...)in body must both be present. Either one alone leaves the relationship invisible to half the tooling.relates-to: [{id: "0011", reason: ...}]in frontmatter andRelated to [ADR-0011](...)in body are likewise paired.- If the architect adds a body line
Amended by [ADR-0023](...)later, they must also add"0023"to the superseding ADR'samends:list — not to this file's frontmatter (which is now immutable ifaccepted). See "Status transitions" below for the immutability rule.
Link-prefix vocabulary (doc-master convention)
The body ### Relationships section uses these link prefixes. Each prefix corresponds to a frontmatter key or its inverse, so a mechanical mirror is always possible. The exact strings:
| Body link prefix | Frontmatter key (new ADR) | Frontmatter key (old ADR) | Direction |
|---|---|---|---|
Supersedes [ADR-NNNN](...) | supersedes: ["NNNN"] | (none — old ADR is immutable) | Forward |
Superseded by [ADR-NNNN](...) | (none — already in old ADR's frontmatter via the new ADR's supersedes list) | reverse note for human readers | Backward |
Amends [ADR-NNNN](...) | amends: ["NNNN"] | (none) | Forward |
Amended by [ADR-NNNN](...) | (none) | reverse note for human readers | Backward |
Related to [ADR-NNNN](...) | relates-to: [{id: "NNNN", reason: "..."}] | (none — symmetric, but only one side needs it) | Symmetric |
Notes:
- These prefixes are the doc-master convention, distilled from MADR 3.0/4.0 community practice and the older MADR 2.x
## Linkslexer (which tokenized## Linksas the relationship heading). They are not a formal MADR specification — the upstream MADR 4.0 template only suggests "Links to other decisions and resources might appear here" under## More Information. doc-master codifies the prefix names so frontmatter and body can always be mirrored mechanically. Upstream MADR template: github.com/adr/madr/tree/4.0.0/template. - Use a Markdown link with a path relative to the ADR (e.g.,
[ADR-0004](0004-old-decision.md)), not a bare ID. - The
— reasontrailing dash-clause is optional but recommended; forrelates-toit should match the frontmatterreasonfield. - Reverse-direction prefixes (
Superseded by,Amended by) are human-only courtesy notes added to the old ADR's header. They do not produce graph edges; the edge always lives in the new ADR's frontmattersupersedes/amendslist.
Status vocabulary
The lowercase status lifecycle is proposed, accepted, superseded, deprecated. Do not overload status with rfc, rejected, backfilled, or explanatory strings — those break gray-matter-based filters. For RFC routing, use status: proposed with a separate rfc-deadline: field.
Frontmatter
| Field | Required? | Notes |
|---|---|---|
title | yes | Imperative verb phrase: "Use Postgres for primary store". No period. |
status | yes | ADR Explorer-compatible value: proposed, accepted, superseded, or deprecated. Do not overload with rfc, rejected, or backfill text. |
date | yes | ISO 8601 (YYYY-MM-DD). Stamp at acceptance, not first draft. |
deciders | yes | YAML array of named human(s). "The team" is not a value. |
supersedes | optional | YAML list of ADR ids this decision replaces (e.g., ["0004"]). This list creates the graph edge; do not rely on superseded-by / superseded by text on the old ADR alone, and do not rely on prose Related ADRs: body lines — explorers read frontmatter only. |
amends | optional | YAML list of ADR ids this decision adjusts without replacing. Graph-bearing; frontmatter only. |
relates-to | optional | YAML list of objects: {id: "0004", reason: "one-line reason"}. Graph-bearing; frontmatter only. |
tags | optional | Free-form, lowercase, hyphenated. |
review-by | recommended | ISO date or named trigger (e.g., 100k DAU). A fossil trigger ("revisit annually") is worse than no trigger. |
expires | optional | ISO date for decisions that should stop applying unless renewed. Use only when expiry is real. |
confidence | recommended | high, medium, or low. Used by the skill to suggest RFC routing. If a numeric score is desired, add separate confidence-score. |
rfc-deadline | conditional | Required when the ADR is serving as an RFC with status: proposed. Date the RFC window closes. |
How ADR Explorer-style parsers read these fields
ADR Explorer-style tools extract relationships from YAML frontmatter only:
- The frontmatter block is parsed with
gray-matter. The Markdown body is not scanned for relationship links. - Exactly three keys produce ADR-to-ADR graph edges:
relates-to,supersedes,amends. Any other custom key (e.g.,related,links,see-also) is ignored unless the team also wires it into their own tooling. - ID values are normalized with the regex
/(\d+)/— the first digit run is captured and zero-padded to four characters. So8,"08","0008", and"ADR-0008"all collapse to the node0008. - Recommendation: write IDs as zero-padded four-digit strings (
"0008") in every list. Bare integers parse correctly, but quoted four-digit strings sort, diff, and render predictably across tools.
Minimal canonical frontmatter that renders cleanly in a graph view:
---
title: "Use Postgres for primary store"
status: accepted
date: 2026-05-20
deciders:
- Jane Doe
supersedes:
- "0004"
amends: []
relates-to:
- id: "0011"
reason: "shares the tenancy model decided in 0011"
---Lines such as Related ADRs: [ADR-0011](0011-tenancy.md) in the body are for human readers — they do not appear in the graph.
Sections
Title (# NNNN. <Title>)
- Number is zero-padded, four digits.
- Numbering is monotonic. Never reuse a number, even for a rejected ADR.
- Numbers reflect creation order, not acceptance order.
Context (≤ 3 sentences)
The forces that make this decision necessary now. Not the history of the project. Not the team's biography. Not a tutorial about the domain.
| Good | Bad |
|---|---|
| "Cross-entity reporting and audit search arrive in Q3. Both require multi-table joins over the user dataset. Current DynamoDB-based aggregation runs at p95 600ms; ASR-12 requires < 200ms." | "Our company has been growing rapidly over the last several quarters. We have many features in our pipeline. One of these is reporting…" |
Decision (≤ 3 sentences)
Active voice. Present tense. Names the choice directly.
| Good | Bad |
|---|---|
| "We use Postgres on RDS for the primary store." | "It has been decided that Postgres will be adopted as our database of choice going forward." |
Consequences (bullets only)
Prose paragraphs are a smell. Use Good, because… and Bad, because… markers. Include follow-up work this decision triggers.
- Good, because join workloads land on the engine designed for them.
- Good, because the team's existing SQL experience applies.
- Bad, because we lose DynamoDB's auto-scaling read pattern; manual capacity planning required.
- Follow-up: ADR 0017 will record deployment topology (single vs multi-region).Compliance (1-3 sentences)
How is conformance to this decision verified? A fitness function is allowed here — a one-liner of code or a dashboard reference — but no broader implementation.
| Good | Bad |
|---|---|
"CI enforces no @aws-sdk/client-dynamodb import outside /legacy. Latency dashboard dashboards/db-latency.json must show p95 < 200ms." | (A 40-line migration script) |
Alternatives Considered (bullets)
Realistic options only. At the same level of abstraction — don't compare "a technology" to "a protocol." Each gets a one-paragraph "why not." Skip pseudo-alternatives like "do nothing."
More Information
The MADR 4.0 catch-all section. doc-master pins one required sub-section and allows optional siblings.
Relationships (required when frontmatter relationships exist)
Mirror every populated frontmatter relationship into this body section using the link-prefix vocabulary above. This is the section body-scanning parsers (ADR Manager and similar) read. Example:
### Relationships
- Supersedes [ADR-0004](0004-use-dynamodb-for-primary-store.md) -- replaced because <reason>.
- Related to [ADR-0011](0011-tenancy.md) -- shares the tenancy model.If frontmatter supersedes, amends, and relates-to are all empty, this sub-section may be omitted. If any is populated, the sub-section is mandatory; the adr-critique skill flags ADRs that have one source but not the other.
Notes (optional)
PARKEDopen questions cited here, with the reason for parking.- Provenance links to other docs that are not ADRs (explanations, runbooks, architecture diagrams):
Related docs: [Architecture](../explanation/architecture.md)- Anything that didn't fit but matters for the record. Resist using this section as overflow.
Do not put ADR-to-ADR links here. They belong under ### Relationships above, using the link-prefix vocabulary. A Related ADRs: line in this section is a smell — it's the legacy form adr-critique flags for promotion.
Status transitions
proposed ----accept----> accepted ----change----> superseded
|
+--no longer applies--> deprecated- Use
status: proposedfor ADRs serving as RFCs; addrfc-deadlineinstead of inventingstatus: rfc. - If a proposal is rejected, either delete it before acceptance or keep it as
status: deprecatedwith a clear rejection note; do not usestatus: rejectedwhen ADR Explorer compatibility matters. - An accepted ADR's body is append-only. Header-only reverse links are allowed for human readers, but ADR Explorer graph rendering depends on the new ADR's
supersedeslist. - Supersession is recorded by the new ADR setting
supersedes: ["NNNN"]in its frontmatter. The old ADR may also receive a human-readablesuperseded byheader note, but that note is not the graph edge and is not parsed by ADR Explorer-style tools.
Numbering and filenames
- Format:
NNNN-kebab-imperative-title.md. Examples:0017-use-postgres-for-primary-store.md,0021-deprecate-event-sourcing.md. - Filenames must start with the numeric ADR id for ADR Explorer indexing.
- Lowercase, hyphenated. No spaces, no underscores.
- Never
decision-7.mdordatabase-stuff.md. - Preferred ADR Explorer discovery paths:
docs/adr/,docs/decisions/,docs/architecture/decisions/, and**/adr/*.md. A barearchitecture/decisions/directory may require custom ADR Explorer root configuration.