Skip to content

Architecture Decision Record (ADR) Guide

CIDM 6330/6395 — Student Reference


What Is an ADR?

An Architecture Decision Record captures a single design decision for your project: what you decided, why you decided it, and what the consequences are.

Think of it as a lab notebook entry for software design. Scientists don't just record results — they record what they tried, why they tried it, and what happened. ADRs do the same for architectural choices.

What Counts as an "Architecture Decision"?

Any choice that would be hard to reverse later or that affects how the whole system works:

Decision Why It's Architectural
"We'll use SQLite instead of PostgreSQL" Changes how every database interaction works
"Authentication will use JWT tokens" Affects every endpoint, frontend, and test
"The API will be REST, not GraphQL" Determines how clients consume data
"We'll separate billing into its own service" Changes deployment, testing, and data flow
"Course search will use a local index, not live queries" Affects performance, freshness, and complexity

Things that are not ADRs: bug fixes, code formatting choices, which IDE to use, variable naming conventions. These are important but reversible.


Why Write ADRs?

The Knowledge Loss Problem

You make a design decision today. Three months from now:

  • You forget why you chose that approach
  • A teammate joins and asks "why is it done this way?"
  • You consider changing it but can't remember the tradeoffs

Without an ADR, you either:

  1. Waste time re-discovering the reasoning, or
  2. Make a change that re-introduces a problem you already solved

The Communication Problem

On a team (or with an AI coding assistant), decisions need to be shared and explicit. An ADR ensures everyone — including future-you — knows:

  • What was decided
  • What alternatives were considered
  • What tradeoffs were accepted

The Accountability Problem

When working with AI coding assistants (Claude, Copilot, etc.), the human must remain the architect. ADRs are how you prove you made the design decisions, not the AI.

"The human is index zero — first in priority, final in authority." — gzkit Zero Doctrine


How to Write an ADR

Step 1: State the Intent (2-3 sentences)

What specific problem or capability does this decision address? Connect it back to your PRD.

Weak: "We need a database."

Strong: "Course registration requires persistent storage of student enrollments, schedule conflicts, and course metadata. The storage layer must support concurrent reads during peak registration periods and survive server restarts."

Step 2: Record the Decision

State what you decided as a numbered list of concrete commitments:

Markdown
## Decision

1. Use SQLite as the persistence layer for v1
2. Store the database file at `data/courses.db`
3. Use the repository pattern to abstract database access
4. Support in-memory SQLite for testing

Each item should be specific enough to implement. If a teammate reads this list, they should know exactly what to build.

Step 3: Document Consequences

Every decision has tradeoffs. Be honest about both sides:

Markdown
### Positive
- No external database server to install or manage
- SQLite is included in Python's standard library
- File-based storage simplifies backup and portability

### Negative
- SQLite has limited concurrent write support
- No built-in replication or high-availability
- Will need migration if we outgrow SQLite

Step 4: List Alternatives Considered

What else did you consider, and why didn't you choose it?

Markdown
## Alternatives Considered

- **PostgreSQL** — Better concurrency, but requires server
  setup that adds complexity for a class project
- **MongoDB** — Document model doesn't fit our relational
  course/student data well
- **Plain JSON files** — Too fragile for concurrent access;
  no query capability

This section is critical because it shows you thought through options rather than grabbing the first thing that came to mind.

Step 5: Create a Feature Checklist

Break the decision into observable outcomes — things you can demonstrate or test when the work is done:

Markdown
## Feature Checklist

1. [ ] Database schema created with courses, students, enrollments tables
2. [ ] Repository class with find, save, delete operations
3. [ ] In-memory adapter for unit tests
4. [ ] Migration script for schema changes
5. [ ] CLI command to initialize the database

Each checklist item becomes a task (see Task Guide).


Anatomy of an ADR

Text Only
ADR-NNN: Title
   ├── Metadata ...................... ID, status, date, author
   ├── Intent ........................ WHAT problem are we solving?
   ├── Decision ...................... WHAT did we decide?
   ├── Consequences .................. WHAT are the tradeoffs?
   │     ├── Positive
   │     └── Negative
   ├── Alternatives Considered ....... WHAT else did we consider?
   ├── Feature Checklist ............. WHAT are the observable outcomes?
   └── Approval ...................... WHO reviewed and agreed?

ADR Lifecycle

An ADR moves through these states:

Text Only
Draft ──→ Proposed ──→ Accepted ──→ Completed
                          └──→ Superseded (replaced by a newer ADR)
                          └──→ Abandoned (decision reversed)
Status Meaning
Draft Still being written; not ready for review
Proposed Ready for review by instructor/team
Accepted Approved; implementation can begin
Completed All checklist items done and verified
Superseded Replaced by a newer ADR (link to it)
Abandoned Decision was reversed; record why

Common Mistakes

Mistake Why It Hurts Fix
Too many decisions in one ADR Hard to track status; partial completion is ambiguous One decision per ADR
No alternatives section Looks like you didn't think it through Always list at least 2 alternatives
Vague decision statements "Use a good database" — which one? How? Numbered, specific commitments
Skipping consequences You'll forget the tradeoffs you accepted Be honest about negatives
Never updating status ADRs rot; nobody knows what's current Update status as work progresses
Writing ADRs after implementation It becomes documentation, not a decision record Write the ADR before you code

ADRs in Practice: A Small Example

Suppose your PRD says: "Students need to search for courses by department, time slot, and instructor."

ADR-001: Course Search Implementation

  • Intent: Enable students to search courses using multiple criteria without requiring a full-text search engine.
  • Decision:
  • Implement search as filtered SQL queries against the courses table
  • Support filtering by department, time slot, and instructor name
  • Return results sorted by course number
  • Limit results to 50 per page
  • Positive consequences: Simple, no external dependencies, fast for our data size (~500 courses)
  • Negative consequences: Won't scale to full-text search; no fuzzy matching
  • Alternatives: Elasticsearch (overkill), whoosh (extra dependency), in-memory filtering (slow for large datasets)
  • Checklist:
  • Search repository method with filter parameters
  • Unit tests for each filter type
  • CLI or API endpoint for search
  • Results pagination

Creating an ADR in gzkit

gzkit provides both CLI commands and skills for ADR creation.

CLI (terminal):

Bash
gz plan 0.1.0 --title "Course Search Implementation"

Skill (Claude Code session):

Text Only
/gz-plan

The /gz-plan skill is strongly recommended — it runs 20+ design forcing-function questions (pre-mortem analysis, constraint archaeology, reversibility assessment) that the raw CLI skips entirely. These questions surface risks and alternatives before you commit to a decision.

For design exploration before committing to an ADR:

Text Only
/gz-design

The /gz-design skill runs a collaborative design dialogue that produces ADR artifacts after structured brainstorming.


From ADR to Tasks

Once an ADR is accepted, each checklist item becomes a task (called an OBPI — One Brief Per Item — in gzkit):

Text Only
ADR-001: Course Search Implementation
  ├── Task 1: Search repository method with filter parameters
  ├── Task 2: Unit tests for each filter type
  ├── Task 3: CLI or API endpoint for search
  └── Task 4: Results pagination

In gzkit, decompose checklist items into OBPI briefs:

CLI Skill What it does
gz specify slug --parent ADR-0.1.0 --item 1 /gz-obpi-specify Create and semantically author the OBPI brief

The /gz-obpi-specify skill performs lane resolution from the ADR's WBS table and validates decomposition scorecard alignment — raw CLI generates thin placeholder briefs that require manual authoring.

See: Task Guide for how to structure these.


Template

A ready-to-use ADR template is available at: templates/adr-template.md


Video Companion

See Part 3 of the video tutorial series for a narrated walkthrough of the ADR template, the decomposition scorecard, and the reading list example.

Further Reading