Topic: adr status template
ADR Status Template — Format, Fields, and the Lifecycle Beyond Accepted
Every ADR template ships a Status field. Almost none of them tell you where it should live in the file, what fields belong next to it, when to extend the basic four-state lifecycle, or how to render it as a badge for human readers. This page is the format guide that pairs with the operational protocol at how to update an ADR.
TL;DR
Use YAML frontmatter for the Status field on any ADR directory with tooling — it's the only format that's reliably parseable across templates. Pair Status with five companion fields: Date, Decision-by, Reviewers, Trial-Until (when applicable), and Tags. The base lifecycle is four states (Proposed → Accepted → Superseded, plus Rejected as a terminal); add Trial-Period as a fifth when your team is large enough that "we're adopting this but might revisit in 6 weeks" is a meaningful state distinct from "we're committed forever." Render Status as a shields.io badge under the H1 for human readers; never depend on the badge for tooling — frontmatter is the source of truth. The supersession protocol handles transitions; this page handles the format.
Why a "status template" is a thing on its own
Most ADR template pages tell you "include a Status field." None of them tell you where in the file the field goes, what data type it is, what other fields belong next to it, or how to extend the basic lifecycle for teams whose decisions don't actually fit "Accepted forever or Superseded." The result: every team makes ad-hoc choices about format, every team's tooling breaks differently the first time someone writes Status: Accepted (with caveats), and every team eventually rewrites a fragile regex to handle the variants instead of standardizing on a parseable shape.
This page is the missing format guide. It pairs with three sibling pages: how to update an ADR (the protocol for transitions), the numbering scheme (the directory-level discipline), and the GitHub Action workflow (the CI that enforces both). Together they're the four operational pages every team adopting ADRs needs after they pick a body template.
Where Status lives — three placements, one recommendation
Three valid placements show up in the wild. Tooling implications differ sharply.
| Placement | Example | Tooling | When to use |
|---|---|---|---|
| YAML frontmatter (recommended) | --- |
Parses in 3 lines of yq or any frontmatter library. CI checks, status dashboards, supersession integrity all work cleanly. |
Default for any directory with tooling. MADR's standard format. Required if you're using the four-job GitHub Action workflow. |
| Markdown heading | # Pick Postgres over MongoDB |
Requires regex parsing of the rendered Markdown. Fragile — a Status section that becomes # Status instead of ## Status, or a Status line that wraps to two lines, breaks the parser. |
Nygard's original format. Acceptable for tiny directories (under 30 ADRs) where readability matters more than tooling and you're not planning to add CI. |
| Inline metadata line | # Pick Postgres over MongoDB |
Readable in rendered Markdown but mixes structured data with prose. Parsers have to handle bold/non-bold variants and field-separator variation (• vs |, etc.). | Avoid except as a human-readable echo of the frontmatter (write both, with a CI check that they agree). |
The recommendation is YAML frontmatter as source of truth, with an optional Status line in the body for readers. Frontmatter is the only format that survives a year of growth without breaking some downstream tool.
The full Status block — a copy-paste template
This is the frontmatter block that earns its place on a Nygard- or MADR-shaped ADR. Drop it at the top of every file:
---
id: 0042
title: Adopt CockroachDB for the metrics service
status: Accepted
date: 2026-02-14
decision-by: Platform Lead
reviewers: [Sara Lin, Marcus Ortiz, Jess Chen]
tags: [backend, storage, metrics]
supersedes: []
superseded-by: null
---
# Adopt CockroachDB for the metrics service
<!-- body follows; Context, Decision, Consequences as usual -->
Field-by-field rationale below.
The five companion fields that earn their place
date— the ISO date Status entered its current value- Required, not optional. When Status flips from Proposed to Accepted,
dateupdates to the merge date. When it flips to Superseded,dateupdates to the supersession date. The original Proposed date is recoverable from git history; the current-state date is what tools and humans care about. Always ISO-8601 (2026-02-14) — never US-format (2/14/2026) which sorts wrong and is ambiguous internationally. decision-by— who has authority over this decision- Use a role name, not an individual name (write "Platform Lead," not "Sara Lin"). The reason: ADRs outlive the people who wrote them. When Sara leaves and Marcus takes over Platform Lead, decisions Sara owned are still owned by "Platform Lead" — Marcus, by virtue of the role, can revisit them without the awkwardness of "you're overruling Sara's call." Tag-the-individual ownership creates social friction every time a decision needs revisiting; tag-the-role ownership lets the org function across personnel changes.
reviewers— who weighed in- Names or roles, both work. Reviewers are signals, not authority — they document who in the room had a chance to flag the decision before it landed. The list is for forensic value ("when this decision blew up six months later, who else had reviewed it and what did they raise?"); it's not a sign-off list. If your org needs sign-offs, that's a separate
approved-byfield, used sparingly because it adds bureaucratic weight. trial-until— relevant only when Status is Trial-Period- An ISO date by which the trial decision must be re-evaluated. Concrete dates beat vague intent — "Trial-Period until 2026-03-31" forces a calendar review; "Trial-Period until we have more data" silently becomes permanent. Forty-five to ninety days is the typical interval. When the date passes, a small ritual: revisit the decision, flip Status to Accepted (and remove
trial-until) or Superseded (and write the replacement). Mature teams calendar these reviews; immature teams discover the unreviewed Trial-Period decisions at the next architecture audit. tags— free-form list for filtering- Typical values:
backend,frontend,security,ops,data,billing,observability. Pick a small vocabulary (under 15 tags total) and stick to it — tag sprawl makes filtering useless. Tags are most useful at status-dashboard time ("show me all Accepted decisions taggedsecurityfrom the last quarter") and supersession time ("which Accepted decisions inbillingare over 18 months old and might need a Notes update?"). Don't use tags to encode hierarchy; that's what subdirectories are for.
Two fields to avoid: author (creates a sense of personal ownership that biases later supersessions toward defending the original author rather than re-deciding cleanly — git blame already records who wrote the file if anyone needs to know); confidence (subjective, rarely revisited, and the right calibration on a decision is whether it's been promoted from Trial-Period to Accepted, not how confident the author was at the time).
The lifecycle — and the optional fifth state
The Nygard-original four-state machine is the universal default:
Proposed ──merge──> Accepted ──new ADR──> Superseded
│ │
└───reject───> Rejected (terminal)
└──world changes──> Deprecated (terminal)
Five states total: Proposed, Accepted, Superseded, Rejected, Deprecated. How to update an ADR documents the transitions and the illegal moves (Accepted → Proposed, Superseded → Accepted). For most teams under 20 engineers this is enough.
For larger teams or higher-stakes systems, add a sixth state: Trial-Period.
When Trial-Period earns its place
Trial-Period (sometimes called "Provisional" or "Accepted-Trial") documents "we're adopting this and will revisit in N weeks if it isn't working" — a meaningful distinction from "we're committed forever." Without it, teams either:
- Mark uncertain decisions as Accepted and then write a supersession 30 days later when reality intervenes. The supersession looks like the team changed its mind; in fact the team always intended to revisit, but the binary Accepted/Superseded vocabulary couldn't express it. The audit trail loses the original "we knew this was provisional" intent.
- Hold uncertain decisions in Proposed indefinitely while the trial runs. The PR stays open for weeks; the directory has no record of what's actually being tried in production; reviewers tag the PR for follow-up that never comes. Worse audit trail.
Trial-Period gives you a third option: merge the ADR with Status: Trial-Period and a trial-until date, run the trial in production with the doc as the record of intent, then on the calendar date flip Status to Accepted (the trial worked; remove trial-until) or Superseded (the trial revealed problems; write the replacement ADR).
The threshold: add Trial-Period when you have at least one supersession in the directory's history that should have been documented as a trial — where the team always knew they were taking a risk and the supersession 30 days later was the planned revisit, not a change of mind. If your directory has zero such cases, skip Trial-Period and stay with the four-state machine.
The legal transitions with Trial-Period added
| From | To | Trigger |
|---|---|---|
| Proposed | Trial-Period | Reviewers approve the trial; merge with trial-until set |
| Trial-Period | Accepted | Trial date reached, trial worked; remove trial-until field |
| Trial-Period | Superseded | Trial date reached, trial revealed problems; write replacement ADR + supersession protocol |
| Trial-Period | Rejected | Trial date reached, the team reverted; mark Rejected with a brief Trial-Outcome note in the body |
| any | Trial-Period | illegal — Trial-Period is an entry state from Proposed only; you can't downgrade an Accepted decision back to Trial-Period (write a new Trial-Period ADR if the team wants to re-test the call) |
The shields.io badge variant for GitHub readers
Frontmatter is invisible in GitHub's rendered-Markdown view. Many teams want a visual Status indicator at the top of every ADR for human readers scanning the file in the GitHub UI. The img.shields.io badge approach is portable and zero-dependency.
Static badge (simplest)

Drop the line directly under the H1. The badge renders inline with the title in GitHub's view. Update the badge URL when Status changes (the same edit that flips the frontmatter status: field). The downside: two sources of truth (badge URL + frontmatter) that can drift; the upside: zero infrastructure, works in every Markdown renderer.
Dynamic badge (one source of truth)
For teams that want one source of truth, host a small JSON endpoint that reads the frontmatter and returns shields.io's endpoint format:
{
"schemaVersion": 1,
"label": "Status",
"message": "Accepted",
"color": "green"
}
Reference it from the ADR file as:

The endpoint reads doc/decisions/0042-*.md, parses the frontmatter, and returns the JSON. Hosting can be a tiny Cloudflare Worker, a Vercel function, or a static doc/decisions/status/0042.json regenerated by the same CI job that runs the auto-index in the four-job workflow. The badge can never drift from the frontmatter because the badge IS the frontmatter, rendered.
Color conventions
| Status | Color | shields.io value |
|---|---|---|
| Proposed | Blue | blue |
| Trial-Period | Yellow | yellow |
| Accepted | Green | green or brightgreen |
| Superseded | Light grey | lightgrey |
| Deprecated | Light grey | lightgrey |
| Rejected | Red | red |
Superseded and Deprecated share a color because they share a meaning to a reader scanning the directory: "this isn't the active answer; look elsewhere." The distinction matters in the body (Superseded points at a replacement; Deprecated does not), not in the at-a-glance scan.
Per-template variants — what each ADR template defaults to
Different ADR templates ship different Status conventions. If you're picking from the three-template comparison, here's what each one expects out of the box:
| Template | Default Status placement | Default lifecycle | Companion fields |
|---|---|---|---|
| Nygard | H2 heading (## Status) |
Proposed → Accepted → Deprecated → Superseded (4 states) | None in the original; teams typically add Date |
| MADR 4.0 | YAML frontmatter (status:) |
Proposed → Accepted → Rejected → Deprecated → Superseded (5 states) | Date, Decision-makers, Consulted, Informed, Tags — MADR has the richest default field set |
| arc42 | Section 9 heading (### Status) |
Inherits the Nygard 4-state by default | None standard; section 11.5 (Risks) often supplements |
| Notion (database) | Notion Select property |
4-state by default; trivially extensible via Notion's UI | Date (Date property), Decision-by (Person property), Tags (Multi-select) |
| Confluence | Confluence {status} macro |
4-state; macro values map to colored pills | Decision-date and Decision-by typically in a Confluence Page Properties macro |
If you're starting fresh, MADR 4.0's defaults are closest to the recommendations on this page — frontmatter as source of truth, 5-state machine as default, Date/Decision-by/Reviewers as standard companions. Add Trial-Period if your team needs it; everything else is a one-line frontmatter addition.
What goes wrong without a Status template
Three failure modes show up in directories where Status is unstandardized:
- Variant explosion. Engineers write
Status: Accepted,Status: ACCEPTED,Status: Approved,Status: Live,Status: Done,Status: Accepted (with caveats). The CI check that grep-counts Accepted ADRs returns wildly wrong numbers; status dashboards undercount; supersession-integrity checks pass when they should fail. The fix is mechanical (canonical vocabulary in the template + a CI lint rejecting non-canonical values), but it's the kind of mechanical fix that doesn't get done until the directory is large enough that the variants are painful to clean up. - Date silently rotted. Without a documented
dateconvention, teams write the original Proposed date and never update it on Status changes. A Superseded ADR showsdate: 2024-08-12as if the supersession happened then, when it actually happened in 2026. Status dashboards "this quarter's supersessions" return wrong answers; trend lines mislead. Document Date as the date Status entered its current value, not the date the file was created — git history covers the latter. - Trial-Period absent when needed. A team without Trial-Period marks uncertain decisions as Accepted, then writes a supersession 30 days later when the trial fails. The audit trail looks like the team changed its mind; the truth is the team always intended to revisit, but the vocabulary couldn't express it. Three or more such "we always meant to revisit" supersessions in a directory's history is the signal to add Trial-Period.
How WhyChose fits in
This page is about the format the Status field takes in your ADR files. The harder problem upstream is the decisions that never have a Status field at all — the ones made in a ChatGPT or Claude tab whose rationale walks off in someone's chat history before anyone thought to write an ADR. The WhyChose extractor reads your AI chat exports, surfaces every decision-shaped exchange with its trade-offs, and outputs structured records you can promote into ADRs in your repo. The extractor's output already includes a status field defaulted to Proposed (or Trial-Period when the conversation explicitly framed the decision as a trial), plus the date (the conversation date), the decision-by (extracted from the chat metadata when available), and the trade-offs that became the body's Context section. Drop the extracted record into your doc/decisions/ directory, run the merge-base allocator to assign a number, and the new ADR lands ready for review under whatever Status template this page convinced you to adopt.
Related questions
Should the Status field live in YAML frontmatter or as a Markdown heading?
Use YAML frontmatter when your ADR practice has any tooling — frontmatter is parseable in 3 lines of yq; headings need fragile regex. Use a heading when the directory is small (under 30 ADRs) and rendered-Markdown readability matters more than tool integration. Use both when migrating: write frontmatter as the source of truth and keep a Status: Accepted line under the H1 for human readers; a CI check ensures they agree.
Do I need a Trial-Period status, or is Proposed → Accepted enough?
Trial-Period is an extension that earns its keep on teams above ~20 engineers where decisions get adopted but might not survive contact with reality. Add it when you have at least one supersession in the directory's history that should have been a trial — where the team always knew they were taking a risk and the supersession 30 days later was the planned revisit, not a change of mind.
What other fields belong next to Status?
Five companion fields earn their place: date (the ISO date Status entered its current value), decision-by (a role name, not an individual), reviewers (a list — signals, not authority), trial-until (only when Status is Trial-Period), and tags (free-form list, kept under 15 total values). Avoid author and confidence.
Can I render Status as a GitHub-flavored Markdown badge?
Yes — img.shields.io serves dynamic badges from any text. Static: . For one-source-of-truth, host a JSON endpoint returning the shields.io endpoint schema and reference it as . Color conventions: Proposed=blue, Trial-Period=yellow, Accepted=green, Superseded/Deprecated=lightgrey, Rejected=red.
How does this relate to the supersession protocol?
This page is the format guide; how to update an ADR is the protocol for transitions. The format defines what valid Status values look like and where they live in the file; the protocol defines when each transition is legal and what other files need to change atomically. Together they cover the full lifecycle.
Further reading
- How to update an ADR (without breaking the audit trail) — the operational protocol that pairs with this page's format guide. Status transitions, supersession, and the Notes section.
- ADR numbering scheme — padding, gaps, and collision recovery — the directory-level companion; how to allocate the IDs that end up in the
id:frontmatter field. - The ADR GitHub Action workflow — the four-job CI that lint-checks the frontmatter shape recommended on this page, including required Status values and bidirectional supersession integrity.
- The Nygard ADR template — uses a Markdown heading rather than frontmatter; pair with the migration recommendation on this page.
- MADR (Markdown ADR) template — the ADR template whose frontmatter conventions are closest to this page's recommendations out of the box.
- arc42 ADR template — the section-9 integration; uses Status in the section heading rather than frontmatter.
- ADR template for Notion — Status as a database property; lifecycle is the same, the format is the database column.
- ADR template for Confluence — Status via the Confluence
{status}macro with colored pills. - Architecture decision record template — the three-template comparison page; pick a template, then return here for the Status convention.
- When to write an ADR — the threshold question; the Status field only matters once a decision passes the threshold.
- ADR storage format comparison — Status placement varies by storage layer: YAML frontmatter in Markdown, Page Properties macro in Confluence, Select property in Notion, section heading in arc42. The storage comparison covers when each layer is the right fit and the migration paths between them.
- The open-source extractor — emits decision records with
status: Proposeddefaulted, ready to drop into the directory under whatever template you adopt.