cc-os/docs/adr-system/02-external-research.md

11 KiB
Raw Permalink Blame History

External Research: ADR Best Practices & Claude Code Integration

Last updated: 2026-07-03

Two research passes: (1) general ADR best practices independent of any AI tooling, (2) how Claude Code / AI-coding-agent users specifically have integrated ADRs. Gathered by web-research agents, 2026-07-03. Claims marked [unverified] were not independently checked against a primary source in this pass — verify before relying on a specific tool/repo name.


Part A — General ADR Best Practices

1. File/directory organization

Industry consensus favors one-file-per-decision over a monolithic running log, following Michael Nygard's original 2011 convention: sequential numbered files (0001-title.md, …) in doc/adr/, stored alongside code in version control (Cognitect Blog). MADR refines this with timestamped naming for sortability (MADR docs).

Tradeoffs at scale:

  • Advantages: immutable per-decision history, shallow git diffs (no merge conflicts on a shared log file), sequential numbering creates a shared "decision language."
  • Disadvantages: filesystem clutter past ~200 decisions, usually addressed with subdirectory categorization (e.g. decisions/backend/).

Tools handle discoverability differently: adr-tools (bash, Nygard format) has no built-in index, relying on naming discipline; Log4brains (Node.js) auto-generates a searchable dashboard from git metadata with no enforced numbering; Backstage (Spotify's platform) indexes ADRs across many repos for org-wide visibility. Across all of them, the common discoverability mechanism is an overview.md/README.md table (title + status + date) plus explicit Supersedes: / Superseded by: cross-links in each file.

No evidence surfaced of a monolithic single-file ADR log surviving past ~30 decisions in active use [unverified — multiple practitioner blogs, no single primary source]; this is directly relevant to cc-os's own 19-ADR, 601-line file trending toward that threshold.

2. Content template best practices

Three templates dominate:

  • Nygard minimal: Status · Context · Decision · Consequences. Lowest friction, fits one page; weaker audit trail since alternatives aren't a first-class section.
  • MADR (Markdown ADR): adds Decision Drivers, Considered Options (with pros/cons per option), and RACI-style metadata (Deciders, Consulted, Informed). Two pages typical; the de-facto default for teams >15 engineers or audit-sensitive contexts.
  • Y-Statements: one paragraph — "In the context of <use case>, facing <concern>, we decided for <option> and against <alternatives>, to achieve <benefits>, accepting <trade-offs>." Writable in ~90 seconds; a lightweight complement, not a replacement, for per-project decisions that don't warrant a full ADR.

What makes an ADR useful later rather than a wall of text nobody rereads:

  1. Status field (Proposed/Accepted/Rejected/Superseded/Deprecated) — signals actionability at a glance; accepted ADRs are treated as immutable, new insight → new ADR, not an edit.
  2. Alternatives-considered with reasoning — the rejected options are often more valuable to a future reader than the chosen one, because they prevent re-litigating a already-evaluated path.
  3. Strong, short titles ("Use PostgreSQL over MongoDB for user data," not "Database") — enables index-skimming and grep.
  4. Explicit Supersedes: / Superseded by: cross-references — prevents accidentally applying an obsolete decision.
  5. Component/domain tagging (affected-components: [auth, api-gateway]) — enables filtering once ADR count exceeds ~50 [unverified — inferred from MADR template fields].
  6. Deciders/date accountability — prevents orphaned decisions once people leave.

Format-selection heuristic [unverified, single secondary source]: Nygard for <15-person teams; MADR for 1550; MADR + tool-generated index for >50 or regulated industries; Y-Statements for small per-project decision counts.

3. Lifecycle and governance

When to write one (Spotify engineering: "write an ADR whenever a decision of significant impact is made; each team aligns on what 'significant' means" — source): hard-to-reverse decisions, decisions affecting >1 team/service, decisions with real tradeoffs and no obvious right answer, a question that's been re-litigated more than once (a sign of undocumented institutional knowledge), non-functional requirements (security, availability, latency). When not to: routine implementation choices, single-service decisions with no cross-team impact, things already covered by standing policy.

Immutability + supersession (AWS Prescriptive Guidance): once Accepted, an ADR is immutable. A conflicting new decision gets a new ADR in Proposed state with a Supersedes: ADR-NNNN header; once accepted, the old ADR's status flips to Superseded by ADR-MMMM and it stays in version control as history. "Deprecated" is a distinct state (the decision is no longer relevant, e.g. the system was decommissioned) from "superseded" (replaced by a newer decision).

Review: lightweight, PR-comment-style review (1015 min/ADR), not a formal approval board; the author owns the final call rather than requiring full consensus (consensus causes scope creep and decision fatigue).

Keeping adoption high: the #1 adoption barrier is template bloat — "a template that takes an hour to fill out will not get used" (AWS). Practices: store ADRs in the code repo (not a wiki), write them during the decision (not retroactively), markdown-only, provide a copy-paste starting template, and periodically (e.g. quarterly) sweep for stale/undocumented decisions.

Sources: Cognitect/Nygard, Martin Fowler bliki, MADR, AWS Prescriptive Guidance, Spotify Engineering, Log4brains, Y-Statements.


Part B — Claude Code / AI-Agent Integration

1. Existing plugins/skills/MCP servers for ADRs [names unverified — not independently confirmed in this pass]

  • adr-kit (github.com/rvdbreemen/adr-kit) — drop-in Claude Code toolkit; treats ADRs as active guardrails, not passive docs.
  • zircote/adr (GitHub) — lifecycle management across 7 template formats (MADR, Nygard, Y-Statement, Alexandrian, Business Case…), with compliance auditing.
  • claude-plugin-adr (github.com/andronics/claude-plugin-adr) and a plain "architecture-decision-records" skill on a Claude plugin hub — basic creation workflows.
  • An open Claude Code GitHub feature request (issue #13853) asks for native ADR support: auto-loading records from ~/.claude/adr/ the same way CLAUDE.md auto-loads.
  • mcp-adr-analysis-server (github.com/tosin2013/mcp-adr-analysis-server) — an MCP server (agent-agnostic, not Claude-Code-specific) with 15 tools for reading/creating/managing ADRs, using Tree-sitter AST analysis and secret-masking.

2. Triggering ADR creation

Most real-world usage is reactive, driven by an explicit user command (e.g. /record-adr), not autonomous. adr-kit adds a smart-detection layer on top: /adr:review diffs commits against existing ADRs to flag undocumented architectural changes; /adr:init audits an existing codebase for decisions already "in effect" in the code and proposes batching them as backfilled Accepted ADRs. One practitioner write-up (beyondautocomplete.nl) reports the /record-adr flow takes 3060 seconds per decision and asks clarifying questions when context is thin — but complex multi-decision changes still need to be split into separate invocations manually.

3. Selective retrieval (avoiding context bloat)

This is the most directly relevant finding for cc-os's third HMW. Patterns observed:

  • Ranked, task-scoped filtering: adr-kit's adr-context tool returns only the 35 most relevant Accepted ADRs, using weighted signals — file-path/glob match against an ADR's declared "enforcement path" ranked highest, keyword relevance second.
  • In-flight, path-triggered nudges: an adr-watch-style mechanism surfaces an ADR only when an edit touches a path the ADR governs — i.e., deterministic path matching rather than semantic search for the common case.
  • Knowledge-graph retrieval: converting ADRs into graph nodes lets a query find structurally related decisions ("all ADRs that depend on this infra decision"), which is a different (and complementary) axis to keyword/semantic similarity. This is directly relevant to cc-os since Graphify is already the chosen knowledge-layer engine (ADR-010) — an ADR system could plausibly be another node type in the same graph rather than a separate retrieval mechanism.
  • Hook-based conditional injection: a SessionStart/similar hook can filter which ADRs get injected based on what files are about to be touched, keeping the default-context footprint near zero and only pulling in ADRs when a matching path is active — architecturally identical to cc-os's own lazy-freshness pattern (ADR-007).
  • Status-based filtering: only surfacing Accepted ADRs by default; Proposed and Superseded stay out of default retrieval paths.

4. Community sentiment / pain points [incident detail unverified — single source, not independently confirmed]

A recurring tension: ADRs record "why we decided," but an autonomous agent often needs enforceable "what must never happen" constraints, which prose ADRs don't provide — cited as part of the motivation for AGENTS.md-style "project constitution" files that encode operable rules rather than narrative history. A cited (but unverified in this pass) Replit incident from 2025 describes an agent running DROP DATABASE despite an archived freeze decision, offered as an argument that ADRs-as-prose are not a substitute for deterministic guardrails.

Separately, one source (MemU, 2026) claims ~2% context-retention loss per agent step, with tool-definition overhead alone consuming a large share of context on typical MCP setups — cited as the underlying argument for "don't dump ADRs into context, filter them." Treat these specific numbers as [unverified] (single-source, not cross-checked here), but the qualitative point — naive full-ADR-dump retrieval degrades badly as ADR count grows — matches both this repo's own experience (the 601-line 03-architecture-decisions.md file) and the structured-retrieval patterns in item 3 above.

Sources: adr-kit, zircote/adr, claude-plugin-adr, mcp-adr-analysis-server (GitHub repos, names as given, not independently re-verified), Claude Code issue #13853, beyondautocomplete.nl write-up, Graphify/GraphRAG background, Claude Code hooks docs, agentpedia.codes AGENTS.md article, thebcms.com spec-driven-development article.