# Architecture Decision Records (ADRs)

An Architecture Decision Record (ADR) captures a significant architectural decision, its context, and consequences. ADRs create a decision log that provides project context and design rationale.

---

## Why ADRs Matter

- **Institutional memory** — Decisions outlast the people who made them
- **Onboarding** — New team members understand *why*, not just *what*
- **Accountability** — Explicit trade-offs prevent "I didn't know" later
- **Change management** — Superseded ADRs show evolution of thinking
- **Audit trail** — Required in regulated environments

> "Your architecture is the accumulation of its decisions, so the ADR is effectively a record of how and why the system came to be its current shape." — Microsoft Azure Well-Architected

---

## ADR Lifecycle

```
PROPOSED → ACCEPTED → SUPERSEDED (by new ADR)
              ↓
           DEPRECATED (if abandoned without replacement)
```

- **Never edit an accepted ADR** — it's immutable history
- If a decision changes, write a new ADR that supersedes the old
- Link the new ADR from the old one (and vice versa)

---

## Standard ADR Template (Michael Nygard)

```markdown
# ADR-XXX: [Title describing the decision, not the problem]

## Status
Proposed | Accepted | Superseded | Deprecated

## Context
What is the situation? What forces are at play?
- Technical constraints
- Business priorities
- Team skills/organization
- Timeline pressures
- Regulatory requirements

## Decision
What are we doing? Be specific and assertive.
- "We will use..."
- "We will adopt..."
- "We will not..."

## Consequences
### Positive
- Benefit 1
- Benefit 2

### Negative
- Cost/risk 1
- Cost/risk 2

### Neutral / Trade-offs
- Trade-off 1

## Alternatives Considered
| Alternative | Why Rejected |
|---|---|
| Option A | Reason |
| Option B | Reason |

## Related Decisions
- Supersedes: ADR-XXX
- Superseded by: ADR-YYY
- Related: ADR-ZZZ

## Metadata
- Date: YYYY-MM-DD
- Author(s): [names]
- Reviewers: [names]
- Confidence: High | Medium | Low
```

---

## Lightweight Template (For Simpler Decisions)

```markdown
# ADR-XXX: [Decision Title]

**Status**: Accepted
**Date**: YYYY-MM-DD

## Context
[1-2 paragraphs: what problem are we solving?]

## Decision
[The decision in one clear sentence]

## Consequences
- **Pros**: [...]
- **Cons**: [...]
- **Risks**: [...]

## Alternatives
[Brief list of what else was considered]
```

---

## ADR Process Best Practices

### 1. Keep Meetings Short & Focused
- 30-45 minutes maximum
- Time-boxed readout (10-15 min reading, then discussion)
- Written comments on specific sections

### 2. Cross-Functional but Lean
- Invite reps from affected teams
- Keep total participants < 10
- Diverse perspectives, efficient decisions

### 3. One Decision Per ADR
- Split if multiple decisions emerge
- Concentrate on one thing at a time
- Reference design docs for exploration details

### 4. Separate Design from Decision
- Design docs explore options
- ADR records the *chosen* option
- Reference design docs from ADR

### 5. Resolve All Comments
- Incorporate changes OR discuss to consensus
- No unresolved comments at acceptance
- Demonstrates ownership and commitment

### 6. Push for Timely Decisions
- 1-3 readouts should suffice
- Most decisions are "two-way doors" (reversible)
- Better to decide and try than endlessly discuss

### 7. Centralize Storage
- Store in version control (Git) near the code
- Common location: `docs/adr/` or `architecture/decisions/`
- Accessible to all project members

---

## When to Write an ADR

Write an ADR for decisions that:
- Affect system structure or key quality attributes
- Are difficult or expensive to reverse
- Involve significant trade-offs
- Impact multiple teams or components
- Set precedent for future decisions

**Don't write ADRs for**:
- Daily operational calls
- Implementation details within a settled architecture
- Decisions that don't affect architecture

---

## ADR File Organization

```
docs/
└── adr/
    ├── 0001-use-postgresql.md
    ├── 0002-adopt-hexagonal-architecture.md
    ├── 0003-api-versioning-strategy.md
    ├── 0004-event-driven-order-processing.md
    ├── 0005-supersede-0002-use-modular-monolith.md
    └── README.md          # Index with links and status summary
```

**Naming**: `NNNN-short-description.md` (zero-padded for sort order)

**Index (README.md)**:
```markdown
# Architecture Decision Records

| ID | Title | Status | Date |
|---|---|---|---|
| 0001 | Use PostgreSQL as Primary Database | Accepted | 2024-01-15 |
| 0002 | Adopt Hexagonal Architecture | Superseded | 2024-02-01 |
| 0003 | API Versioning Strategy | Accepted | 2024-02-10 |
| 0004 | Event-Driven Order Processing | Accepted | 2024-03-01 |
| 0005 | Use Modular Monolith (supersedes 0002) | Accepted | 2024-04-15 |
```

---

## Example: ADR-0002

```markdown
# ADR-0002: Adopt Hexagonal Architecture for Core Domain

## Status
Accepted (superseded by ADR-0005)

## Context
We're building the Order Management bounded context. The domain has complex business rules around pricing, discounts, and fulfillment. We need:
- High testability of domain logic
- Ability to swap persistence (PostgreSQL → DynamoDB for scaling)
- Clear separation from infrastructure

## Decision
We will implement the Order Management bounded context using Hexagonal Architecture (Ports & Adapters). The domain core will define inbound ports (use cases) and outbound ports (repositories, event publishers). Infrastructure adapters will implement these ports.

## Consequences
### Positive
- Domain logic testable without database/message broker
- Can swap PostgreSQL for DynamoDB by implementing new repository adapter
- Clear boundaries align with DDD bounded context

### Negative
- More boilerplate (interfaces, adapters, mappers)
- Indirection can obscure flow for new developers
- Initial setup slower than layered architecture

### Trade-offs
- Accepting initial velocity cost for long-term maintainability
- Team needs onboarding on pattern

## Alternatives Considered
| Alternative | Why Rejected |
|---|---|
| Layered Architecture | DB changes ripple to domain; hard to test in isolation |
| Clean Architecture | More layers than needed; similar benefits with more ceremony |
| Transaction Script | Doesn't handle domain complexity; leads to anemic model |

## Related Decisions
- Superseded by: ADR-0005 (Use Modular Monolith)
- Related: ADR-0001 (PostgreSQL), ADR-0004 (Event-Driven Processing)

## Metadata
- Date: 2024-02-01
- Author: Jane Architect
- Reviewers: Team Leads (Backend, QA, DevOps)
- Confidence: High
```

---

## ADR Anti-Patterns

| Anti-Pattern | Fix |
|---|---|
| **No ADRs** | Start with first architectural decision |
| **ADR as design doc** | Keep ADR focused on decision; link design docs |
| **Editing accepted ADRs** | Write new superseding ADR instead |
| **Vague consequences** | Be specific: "adds 200ms latency" not "may impact performance" |
| **Missing alternatives** | Document what was considered and why rejected |
| **Orphaned ADRs** | Always link related/superseded ADRs |
| **Private ADRs** | Store in shared repo; make visible to all |

---

## Tooling

| Tool | Purpose |
|---|---|
| `adr-tools` (nathanleclaire) | CLI for creating/managing ADRs |
| `adr-log` | Generate index from ADR files |
| GitHub/GitLab | Native rendering of markdown ADRs |
| Wiki (Confluence, Notion) | Alternative for non-technical stakeholders |

---

## Related Notes

- [[Architecture/Architectural-Styles]] — Decisions often choose between styles
- [[Architecture/Domain-Driven-Design]] — Bounded contexts drive ADRs
- [[Documentation/Documentation-Principles]] — ADRs as living documentation
- [[Methodologies/Engineering-Culture]] — Blameless culture needs decision records

---

*Sources: Michael Nygard (ADR origin), AWS Prescriptive Guidance, Microsoft Azure Well-Architected, Google Cloud Architecture Center, Thoughtworks Technology Radar, adr.github.io*