Living ADRs: How to Keep Architecture Decisions Up to Date
Architecture Decision Records (ADRs) are one of the most effective ways to capture the why behind technical choices. But most teams that adopt ADRs face the same problem: the records go stale within weeks.
The decision was made six months ago. The context has changed. Nobody updated the ADR. Now it’s actively misleading.
Here’s how to make ADRs a living part of your workflow.
Why ADRs Go Stale
The root cause is always the same: writing the ADR is disconnected from the work it governs. When ADRs live in a wiki, Confluence, or a random Google Doc, they’re invisible during daily development. Nobody thinks to update them because nobody sees them.
Three patterns that kill ADRs:
- Stored outside the codebase — if the ADR isn’t next to the code, developers won’t find it
- No enforcement mechanism — nothing prevents code that violates the decision from being merged
- No status lifecycle — there’s no formal way to supersede or deprecate a decision
ADRs That Live With Your Code
The first fix is simple: store ADRs as markdown files in your repository, alongside the code they govern.
payment-service/
└── docs/
└── adr/
├── ADR-001-use-sqs-for-notifications.md
├── ADR-002-event-sourcing-for-audit-trail.md
└── ADR-003-api-versioning-strategy.md
This gives you version control, pull request reviews, and blame history for free. When someone changes the payment notification logic, the relevant ADR is right there in the same repo.
Adding a Status Lifecycle
Every ADR should have a status field in its frontmatter:
- Proposed — under discussion, not yet binding
- Accepted — the team agreed, this is the standard
- Superseded — replaced by a newer decision (link to it)
- Deprecated — no longer relevant
When a new ADR supersedes an old one, update the old ADR’s status and add a reference. This creates a traceable history of how your architecture evolved and why.
From Documentation to Enforcement
The real power comes when ADRs aren’t just documentation — they’re enforced automatically.
For example, if ADR-001 says “all inter-service communication must use SQS”, you can write a fitness test that scans your CloudFormation templates and fails the build if any service uses synchronous HTTP calls between internal services.
def test_no_direct_http_between_services():
"""ADR-001: Inter-service communication must use SQS."""
for template in find_cloudformation_templates():
resources = parse_resources(template)
for resource in resources:
if resource.type == 'AWS::ApiGateway::Method':
integration = resource.properties.get('Integration', {})
assert integration.get('Type') != 'HTTP', (
f"Direct HTTP integration found in {template}. "
f"Use SQS per ADR-001."
)
This is the concept behind architecture fitness tests. The ADR defines the rule. The fitness test enforces it. CI/CD runs the test on every pull request.
Capturing Decisions from Conversations
The hardest part of ADR adoption isn’t the format — it’s capturing the decision in the first place. Most architecture decisions happen in meetings, Slack threads, or whiteboard sessions. By the time someone sits down to write the ADR, half the context is lost.
This is exactly the problem Noteble solves. Record the conversation, and Noteble generates a structured ADR draft from the recording. The author reviews, edits, and publishes. The decision is captured with full context while it’s still fresh.
Making It Sustainable
A living ADR practice needs three things:
- Low friction to create — use templates and tooling (Noteble, or a simple
adr newCLI script) - Automatic enforcement — fitness tests that reference the ADR they enforce
- Regular review cadence — quarterly architecture reviews to update or supersede stale decisions
The goal isn’t perfect documentation. It’s decisions that stay connected to the code they govern, so your architecture intent doesn’t drift from your architecture reality.
At PuglieseWeb, we help teams establish living ADR practices backed by automated guardrails. See our Architecture Audits & Guardrails service or explore SystemDox for tooling that makes this workflow automatic.