You Won't Understand Yourself in Three Months: ADRs for Vibe Projects
AI writes code fast; decisions evaporate faster. This guide introduces ADRs (Architecture Decision Records) for solo teams: a real five-part template, the 'only write the irreversible' rule (2–3 per month), a prompt for letting AI draft them, and the quarterly review with superseded archaeology.

Scope first: ADRs own the "why" — they don't compete with the "how"
This site already has an AGENTS.md guide and a spec-driven development guide — those own the "how" (workflows, conventions, execution). This guide owns "why we did it this way": why Postgres instead of SQLite back then? Why JWT instead of sessions? The reasons behind those decisions are unrememberable three months later even by you, let alone by an AI. ADRs (Architecture Decision Records) are a filing cabinet for the "why." This guide covers decision records only; it doesn't repeat workflow conventions.
The faster AI writes code, the faster the "why" evaporates
Vibe coding has a hidden tax: code output got 10× faster, but the half-life of decisions didn't change. You tell the AI "pick a database"; 30 seconds later Postgres is up, migrations run, tests green. You're happy and move on. Three months later, with users growing, a question surfaces: why Postgres, originally? Because you needed JSONB? Or because the AI just picked it? If it's the latter, switching to SQLite could save a server's worth of money — but you don't dare, because you can't remember which options were ruled out or which potholes were hit.
More common is the agent session's "amnesia loop": you open a fresh session, ask the AI to refactor payments, and it asks "why Stripe instead of Paddle here?" You explain; next week another session asks again. Same question, same explanation cost, paid over and over. Code comments say "what," docs say "how to use," but "why this instead of that" — that knowledge has nowhere to live, so it lives in your head, the least reliable storage on the team.
ADRs fix exactly this: in a format light enough not to annoy and heavy enough to matter, record "irreversible decisions and their reasons," and commit them into the repo, versioned alongside the code.
What an ADR looks like: a real template
The classic ADR format comes from Michael Nygard — just five sections. Solo teams can trim it, but not to the bone. Here's a genuinely usable example:
# ADR-007: Choosing Postgres over SQLite
- Status: Accepted (2026-10-16)
- Context: Past 2,000 users, SQLite shows lock contention on concurrent
writes; multi-tenancy planned within 6 months, needs row-level
security (RLS).
- Decision: Postgres 16 in production (Neon managed); keep SQLite for
local dev (zero-config, fast tests), bridged via the Drizzle abstraction.
- Consequences:
- Good: no more write queueing; RLS available; PITR backups.
- Bad: ~$20/month extra hosting; local dev needs Postgres via Docker
(see the devcontainer guide).
- Alternatives:
- Pure SQLite + WAL: rejected — write-concurrency ceiling remains, RLS unsolvable.
- Self-hosted Postgres: rejected — not worth the ops debt to save $20 as a solo team.
- Review: revisit 2027-01; if users < 10k, consider reverting to pure SQLite.
Three things to notice. First, rejected alternatives matter as much as the decision itself — "why not X" is what future-you most wants to know, and where AI most often re-steps on rakes. Second, consequences honestly list the costs — an extra $20/month looks trivial now, but it's $720 over three years; writing it down prevents self-flattery. Third, it carries a review date — a decision is a lease, not a tombstone; it comes up for renewal.
ADR five-part document structure: status, context, decision, consequences, alternatives and review date
Figure 1: The five-part ADR structure — status, context, decision, consequences (costs included), alternatives, and a review date. Rejected alternatives deserve the same care as the decision.
When to write: only the "irreversible," 2–3 per month is plenty for a solo team
The biggest ADR trap is writing too many. One test only: how expensive is it to reverse this decision? Database choice, auth scheme, monorepo vs. polyrepo, build vs. buy SaaS — reversal costs measured in weeks, worth an ADR. Variable naming, code style, one function's implementation — reversal costs measured in minutes, not worth it; let those rot in the git log.
A practical trigger list — write one if any fires: 1) reversing it touches 3+ files; 2) it touches money (costs, pricing, vendors); 3) it touches security or compliance; 4) you've explained the same "why" to an AI twice. Rule 4 is the vibe-era signature: anything you have to re-explain belongs in an ADR.
Where to keep them: docs/adr/, filenames like 0007-postgres-over-sqlite.md (incrementing numbers, slugified titles). Add a docs/adr/README.md as an index: number, title, status, date — four columns. A fresh session's AI reads the index once and inherits three months of your decision memory — more reliable than any "project memory plugin," because it's hand-written by you, with reasons.
Let AI draft the ADR (but you sign it)
The most annoying part of ADRs is "sitting down to write." The vibe-era posture is inverted: let the AI auto-draft after every big refactor or tech choice; you do a 5-minute review and sign-off. The prompt can look like this:
Based on this session's changes, draft an ADR under docs/adr/ with the next number:
1. Mark status "Proposed" — don't sign off for me;
2. Context must state the concrete problem that triggered the change (cite the issue or error);
3. List at least 2 alternatives with their REAL rejection reasons — don't invent;
4. Consequences must include costs (money/complexity/ops burden), not just benefits;
5. Suggest a review date.
The 5-minute review checklist: are the rejection reasons real or AI-invented? (The easiest place to pad.) Are all costs listed? Is the review date sane? Pass all three, flip "Proposed" to "Accepted," commit. Watch rule 3's "don't invent" — AI will hallucinate alternatives you never considered to fill the quota; delete them in review and keep the ADR honest.
ADR five-part document structure: status, context, decision, consequences, alternatives and review date
Figure 2: The ADR lifecycle — Proposed → discussed/signed → Accepted → implemented → review on expiry (keep / revise / mark superseded).
Three ADR anti-patterns (don't write like this)
Anti-pattern 1: writing an implementation log. "10-16 switched the database from SQLite to Postgres, touched 12 files" — that's git log's job, not the ADR's. ADRs answer "why the switch," not "how the switch went." The test: cover the "Decision" section — if what remains is indistinguishable from git log, the ADR is dead weight.
Anti-pattern 2: vapor alternatives. "Alternatives: none," or "Alternatives: keep SQLite (bad)" — that's the same as writing nothing. Alternatives exist to record the real rejection reasons, and real reasons often hide future resurrections: "self-hosted Postgres rejected because a solo team can't carry the ops debt" — the day your team hits 5 people, that rejection reason expires on its own, and the ADR reminds you to revisit. Vapor alternatives bury your own future signposts.
Anti-pattern 3: write once, never review. An ADR without a review date is a write-only document — indistinguishable from nonexistence after three months. Hard rule: every ADR must carry a review date, and any "Accepted" ADR past its review date fails a CI lint — any file under docs/adr with a review date earlier than today turns red. Put discipline in the pipeline and stop relying on memory.
Decisions expire: re-read quarterly
ADRs aren't write-once relics. Every quarter, spend 30 minutes reading docs/adr/ end to end and ask three questions: does the original context still hold? Are we still paying the costs? Has a better option appeared? Three possible outcomes: keep (refresh the review date), revise (write a new ADR referencing the old number; mark the old one superseded), revert (the decision is overturned — record why; the revert record is knowledge too).
The superseded mechanism is ADRs' most underrated design: it preserves a complete archaeological layer of decisions. A year later, when you wonder "why did we move from build to buy," git history holds ADR-003 (build, superseded) and ADR-011 (buy, referencing 003) — the causal chain intact. A hundred times more reliable than digging through three months of chat logs for "who said that back then."
Wiring ADRs into AGENTS.md: feeding the "why" to AI automatically
Committing ADRs under docs/adr/ is step one; step two is getting them into the AI's working memory. It's simple — add three lines to AGENTS.md (or CLAUDE.md): "Before making tech choices, read the index at docs/adr/README.md; if a plan conflicts with an accepted ADR, ask me first instead of switching on your own; after a big refactor, draft a record from the ADR template with status 'Proposed.'" Those three lines turn ADRs from static documents into decision constraints for the agent.
The effect is immediate: instead of re-explaining "why not Paddle" every time, the AI checks ADR-004 before acting, sees "rejected: Paddle's webhook latency exceeded 30 seconds during promotions," and never proposes it again. Go one step further: at each quarterly review, have the AI read all ADRs first and output a "suspected-expired list" (context changed, costs doubled, alternatives gone), leaving you only the final sign-off — even the review itself can be semi-automated. Your decision memory finally has a carrier that doesn't depend on you being in the room. The endgame of solo-team knowledge management isn't "keep it all in your head" — it's "everything in your head has a place to live." ADRs are where the "why" lives.
One sentence: AI runs the "how" at lightning speed; you keep the "why" firmly remembered. An ADR is your external decision hard drive — 2–3 entries a month, 5 minutes of review each, in exchange for never again staring at code asking "which genius chose this."
Comments (0)
Related articles

Your code runs in three different environments: your laptop, a fresh agent session, and CI — and they disagree. This guide standardizes the dev environment for vibe projects: a full devcontainer.json template (Node+Postgres), the nix-flakes endgame, and a 15-minute minimum viable version.

AI-generated code has no concept of reliability — everything is 'feels fast.' This guide gives solo teams the SRE decision layer: SLI/SLO/error-budget in plain terms, two-tier burn-rate alerting, and a minimal implementation (one SQL + one cron + one status-page line) plus the 'budget gone, releases freeze' discipline.

AI-generated checkout code never thinks about concurrency: two users buying at once means negative stock and double-spent balances. This guide starts from three real race-condition scenes, then covers transaction isolation levels, optimistic (version column) vs pessimistic (SELECT FOR UPDATE) locking, idempotency keys against replays, queue serialization for hot rows, and hands-on transaction code in Prisma and Drizzle — plus a rollout checklist.