Proposal: Managing Architecture Decision Records via GitHub
💡
The ADR proposal was accepted and is now in use.
1. Context
A team often lacks a unified mechanism for recording architecture decisions (Architecture Decision Records, ADRs). As system complexity and team size grow, the absence of a queryable and traceable record of technical decisions creates friction for onboarding, cross-team collaboration, and AI Coding Agent integration.
During tool evaluation, a rich-text collaboration platform (such as Notion) was considered, but its characteristics present structural mismatches with ADR management requirements (see Section 3).
2. Decision
Establish a dedicated GitHub repository to centrally manage all ADRs as Markdown files, with automated quality gates via GitHub Actions.
2.1 Scope: When to write an ADR
ADRs record pure technical architecture decisions only. Business logic, product requirements, and process guidelines are explicitly out of scope.
Within that subject-matter scope, a decision is ADR-worthy when both of the following hold:
- Precedent — it establishes (or breaks) a pattern that other code, tables, services, or modules will follow.
- Reversibility cost — undoing it later requires changes in multiple places, not just one.
If only one holds — or neither — it’s normal PR work, not an ADR. The bar is deliberately on the higher side: ADRs exist to capture decisions a future reader will benefit from finding searchably a year from now, not to log every technically interesting change.
A useful gut check: “would I tell a new hire about this on day one?” If yes, it’s probably an ADR. If you’d only mention it when they happened to touch that exact file, it isn’t.
Considered-but-rejected decisions
A decision to not adopt something is ADR-worthy when the same two-part test holds — typically when the rejected option has been, or is likely to be, re-proposed, and recording the rationale prevents repeated re-litigation. The Decision sentence reads “We will not adopt X because…”; status is still Accepted (the decision is settled, even though no system change follows from it).
Granularity: one ADR per cohesive decision set
A bundle of related rules belongs in a single ADR (e.g., schema naming conventions covering five rules at once). Independent decisions belong in separate ADRs, even if they land in the same week. The test: can each rule be reversed without the others? If yes, they’re independent and should be split.
Examples
| Decision | ADR? | Why |
|---|---|---|
Add a feature_x_settings table for one feature | No | Local; follows existing conventions |
Adopt soft-delete (deleted_at) as a workspace-wide convention | Yes | Cross-cutting precedent |
Migrate primary keys from bigserial to uuid system-wide | Yes | One-way door; propagates everywhere |
Rename a column or change varchar → text on one table | No | Local schema change |
| Adopt React Query as the frontend data-fetching library | Yes | Establishes pattern |
Refactor one component to use useMemo | No | Local optimization |
| Move all frontend packages into a monorepo | Yes | Structural; hard to reverse |
| Switch one service from REST to gRPC | Depends | First such switch → yes (precedent); follows existing convention → no |
| Evaluated server-sent events for live updates, decided to stay on polling | Yes, if recurrence likely | Records a rejected option to prevent re-litigation |
| When in doubt: picture the reader a year from now. If you can’t see them benefiting from this being searchable, it’s probably not an ADR. |
3. Considered Alternatives
| Dimension | GitHub Repository (this proposal) | Rich-text platform (e.g. Notion) |
|---|---|---|
| Version history | Native Git support — all changes are diffable and traceable | Limited version history, not intuitive |
| Agent access | Readable/writable via standard Git protocol or GitHub API | Requires third-party integrations with additional authorization overhead |
| Automation | GitHub Actions supports quality gates and scheduled tasks | Weak automation capability, depends on external tooling |
| Format | Standard Markdown — natively friendly to both engineers and AI agents | Proprietary rich-text format with inconsistent AI tool support |
| Immutability enforcement | Enforceable via branch protection + CI diff checks | No technical means to restrict editing |
| Core reason for rejecting a rich-text platform: Its closed format and weak version control make it unable to satisfy ADR immutability requirements, and unsuitable for structured access by AI agents. |
4. Repository Structure
A standalone repository (org/architecture-decisions) is recommended to support cross-service architectural decisions.
docs/adr/
├── README.md # ADR index (maintained by CI)
├── template.md # ADR authoring template
├── AGENTS.md # Explains repo structure and reading rules to AI agents
├── 0001-use-github-for-adr.md
├── 0002-use-postgresql-as-primary-db.md
└── 0003-migrate-to-aurora.mdNaming convention: {four-digit-incremental-id}-{kebab-case-title}.md. Dates are not included in filenames — they are recorded in the frontmatter and Git commit history.
5. File Format & Template
Each ADR consists of a structured YAML frontmatter block and a standardized Markdown body.
5.1 YAML Frontmatter
---
id: "0002"
title: "Use PostgreSQL as Primary Database"
date: 2026-04-19
status: "Accepted" # Proposed | Accepted | Deprecated | Superseded
supersedes: null # If this supersedes another, fill in its number
tags: [database, persistence, infrastructure]
deciders: ["@alice", "@bob"]
---Rationale for frontmatter: Structured metadata allows AI agents to filter and index ADRs by status, tags, and supersedes without full-text parsing, significantly reducing hallucination risk.
5.2 Body Template
# ADR-{id}: {title}
## Status
{status}
## Context
## Decision
## Considered Alternatives
| Alternative | Reason for rejection |
|---|---|
| … | … |
## Consequences
### Positive
-
### Negative / Trade-offs
-
### Neutral
-
## References
6. Status Lifecycle
ADRs progress through the following states:
| Status | Meaning |
|---|---|
| Proposed | PR submitted, under review |
| Accepted | PR merged, decision in effect — enters immutable history |
| Deprecated | Decision no longer applicable, but not replaced by a new ADR |
| Superseded | Explicitly replaced by a new ADR; original file preserved as-is |
PR ↔ Status linkage: The PR itself is the Proposed phase. The author updates status to Accepted in the same PR before merging. Merge = the moment the decision takes effect. Post-merge body edits are blocked by CI. |
7. Immutability Policy
An Accepted ADR is a settled fact, not a living document. The immutability policy exists so that any reader — human or agent — can open an ADR and trust it reflects exactly what was decided, without needing to verify the edit history. Version control provides recovery capability; immutability provides trust.
Concretely, once an ADR is merged:
- Body content is permanently fixed. Reasoning, decision text, alternatives considered, and consequences must not change.
- Frontmatter is fixed except for
status.statusmay be updated as part of the lifecycle (e.g.,Accepted→Deprecated, orAccepted→Superseded). All other frontmatter fields —id,title,date,supersedes,tags,deciders— are fixed at merge time. - Decision changes happen via new ADRs. When a decision is revised, create a new ADR referencing the old one via
supersedes. The old ADR’s body is never touched; only itsstatusis updated toSuperseded. The reverse relationship (superseded_by) is derived by CI when generating the index — it is not stored in source files. - Permitted exception: Minor wording corrections (typos, grammar) that do not change meaning are allowed, with a note in the PR description.
- Technical enforcement: CI diff checks block any PR that modifies the body — or any non-
statusfrontmatter field — of anAcceptedADR (see Section 8).
8. Automation & Quality Gates
On PR open / update
| Check | Description |
|---|---|
| Frontmatter completeness | Validate that id, title, date, status are present and well-formed |
| Markdown lint | Enforce heading hierarchy, table formatting, and style conventions |
| Reference integrity | Verify that any ADR number referenced in supersedes actually exists |
| Immutability guard | Fail CI if the PR modifies the body or any non-status frontmatter field of an Accepted ADR |
| Merge gate | Fail CI if the PR merges a new ADR whose status is still Proposed |
| Index consistency | Fail CI if the committed README index does not match what would be regenerated from current supersedes declarations |
Scheduled tasks (optional, recommended weekly)
| Task | Description |
|---|---|
| Index refresh | Regenerate README.md with the latest ADR list |
| Stale proposal check | Flag ADRs that have remained in Proposed state beyond a defined threshold |
9. Agent Accessibility
AI Coding Agents are treated as a first-class reader audience. The following design decisions support this:
AGENTS.mdat the repository root explains the repo structure, how to read ADRs, and the standard process for submitting a new one.- YAML frontmatter allows agents to filter by
tagsandstatuswithout reading every file in full. - Self-contained ADRs: Each ADR must be independently understandable — avoid cross-file references that inflate context window usage.
Considered Alternatives** section:** Records rejected options and their reasons, preventing agents from repeatedly proposing already-evaluated approaches.- No unexplained abbreviations: Internal system names and acronyms must be spelled out on first use — equally important for agents and new team members.
- Service repo pointers: Each service repo’s
AGENTS.md(or symlinked equivalent forCLAUDE.md,.github/copilot-instructions.md,.cursor/rules/*.mdc) includes a brief pointer toorg/architecture-decisions, instructing agents to consult relevant ADRs before proposing significant technical changes.
10. Consequences
Positive
- Complete, auditable decision history — new team members can quickly build technical context.
- AI Coding Agents can read ADR constraints directly, reducing out-of-bounds suggestions and hallucinated architectures.
- CI/CD automation enforces format standards and immutability, reducing manual review overhead.
Negative / Trade-offs
- Requires the team to build and sustain ADR authoring habits — non-trivial adoption cost in the early phase.
- GitHub Actions configuration adds a small amount of infrastructure maintenance overhead.
Neutral
- ADR language is standardized to English (consistent with the codebase) — may require adjustment for non-native speakers.
- A
template.mdand short authoring guide are recommended to lower the barrier to entry.
11. References
- Michael Nygard — Documenting Architecture Decisions
- MADR — Markdown Architectural Decision Records
- adr-tools
- Docs as Code — Write the Docs
- llms.txt specification
Pending Revision: Decoupling Decision Process from Decision Record
💬 Proposed revision to Sections 3, 6, and 9. Not yet adopted.
Core idea. An ADR records the outcome of a technical decision, not the process that produced it. The proposal should regulate how outcomes are stored, but stay silent on where discussions happen.
Why this matters. The current Section 6 implicitly treats the PR as the discussion venue, which raises a fair concern: GitHub may not suit every kind of stakeholder conversation, and PMs in particular may prefer lighter-weight tools. A two-system workflow (rich-text draft → GitHub archive) addresses this, but introduces real costs: migration overhead, split-brain risk, and authors forgetting to drain comments before promotion. This revision instead keeps GitHub as the single source of truth and lets discussions happen wherever the team finds natural.
How it works. A decision may take shape in a rich-text doc, Slack, a design doc, a meeting, or PR comments — wherever fits the moment. Once the decision is reached, the proposer opens a PR adding the ADR. PR review focuses on accuracy and clarity of the recording, not on re-litigating the decision. Linking back to the prior discussion (the source doc, meeting notes, etc.) in the PR description is recommended when applicable.
Tradeoffs.
- The proposal stops short of being a full decision-making methodology. Teams that want one will need to define it elsewhere.
- “Decision is settled” becomes the proposer’s judgment call. Reviewers should still push back if a PR feels premature.
- ADR PRs may merge quickly for decisions discussed off-platform — that’s expected, not a sign of insufficient review.
If adopted, Sections 3 (rich-text comparison), 6 (Status Lifecycle), and 9 (Agent Accessibility) will need light edits to match.
Back to AI Workflow Sharing