Add ADR system research and design analysis
Research into current ADR practices across projects, external best practices, and design opportunities for the future os-adr plugin.
This commit is contained in:
parent
7ae45c7bf8
commit
5d5145f347
|
|
@ -0,0 +1,24 @@
|
||||||
|
# ADR System — Research Phase
|
||||||
|
|
||||||
|
_Last updated: 2026-07-03_
|
||||||
|
|
||||||
|
This directory captures research for standardizing how Architecture Decision Records (ADRs)
|
||||||
|
are organized and used across the user's projects, as a precursor to building a Claude Code
|
||||||
|
plugin that automates ADR creation and relevance-scoped retrieval. **Nothing here is built
|
||||||
|
yet** — this is the survey/research phase only, requested to answer "what do we have, and what
|
||||||
|
could we have with a little engineering elbow grease."
|
||||||
|
|
||||||
|
- **`01-current-state-survey.md`** — audit of every project under `~/dev/`, `~/clients/`, and
|
||||||
|
`~/projects/` for existing ADR practices (organization, templates, tooling, or absence
|
||||||
|
thereof).
|
||||||
|
- **`02-external-research.md`** — research on ADR best practices generally (Nygard, MADR,
|
||||||
|
Y-Statements, lifecycle/governance) and on how Claude Code / AI-agent users specifically have
|
||||||
|
integrated ADRs into their workflow.
|
||||||
|
- **`03-synthesis-and-opportunities.md`** — synthesis answering the three "how might we" goals
|
||||||
|
(know when to create/query, systematize creation for consistency, and query with high
|
||||||
|
relevance/low bloat) and naming concrete design options for a future `os-adr` plugin.
|
||||||
|
|
||||||
|
Provenance note: `02-external-research.md` cites web sources gathered by research agents in a
|
||||||
|
single pass; several specific tool/repo names and one incident anecdote are flagged inline as
|
||||||
|
**[unverified]** because they were not independently checked against the primary source in this
|
||||||
|
pass. Verify before depending on any specific tool name in that file.
|
||||||
|
|
@ -0,0 +1,189 @@
|
||||||
|
# Current-State Survey: ADR Practices Across `~/dev/` Projects
|
||||||
|
|
||||||
|
_Last updated: 2026-07-03_
|
||||||
|
|
||||||
|
Survey of every project directory under `~/dev/` for existing Architecture Decision Record
|
||||||
|
practices. Read-only audit; no files were changed. Source: agent survey, 2026-07-03.
|
||||||
|
|
||||||
|
## Projects with formal ADRs
|
||||||
|
|
||||||
|
### cc-os
|
||||||
|
- **Organization**: monolithic — `docs/memory-system/03-architecture-decisions.md`, 601 lines,
|
||||||
|
19 ADRs (this repo, before this research phase).
|
||||||
|
- **Naming**: `ADR-NNN` heading per entry within the single file.
|
||||||
|
- **Template fields**: Context · Decision · Rationale · Alternatives rejected · Status.
|
||||||
|
Supersession noted inline ("Superseded by ADR-010", "Refined by ADR-011").
|
||||||
|
- **Tooling**: none; plain markdown. `_Last updated:_` date at top of file.
|
||||||
|
|
||||||
|
### viking-warrior-training-log
|
||||||
|
- **Organization**: one file per decision — `docs/adr/`, 6 files + `README.md` index.
|
||||||
|
- **Naming**: `NNNN-kebab-case-title.md` (e.g. `0001-pocketbase-backend.md`).
|
||||||
|
- **Template fields**: Status · Date · Context · Decision · Consequences · Alternatives
|
||||||
|
considered. Files are 30–41 lines.
|
||||||
|
- **Tooling**: `README.md` index — a table of all ADRs with title + status. Explicitly notes
|
||||||
|
ADRs 0001–0003 were backfilled after the fact; 0004–0006 record refinements after critique.
|
||||||
|
- **This is the only project with both per-file organization AND a maintained index.**
|
||||||
|
|
||||||
|
### delta-refinery
|
||||||
|
- **Organization**: one file per topic (not numbered) — `docs/decisions/`, 12 files, 25–48
|
||||||
|
lines each.
|
||||||
|
- **Naming**: topic-driven kebab-case (`bin-lint-fix.md`, `map-driven-design-system.md`).
|
||||||
|
- **Template fields**: Status · Decided (date) · Decision · Why · What Was Built (artifact
|
||||||
|
table) · Open Questions · **"Delete this document when"** (a sunset/supersession condition
|
||||||
|
instead of an explicit supersedes/superseded-by field).
|
||||||
|
- **Tooling**: none.
|
||||||
|
|
||||||
|
### design-mode
|
||||||
|
- **Organization**: one file, dated — `docs/decisions/2024-12-jsx-conversion-pivot.md` (only 1
|
||||||
|
decision recorded), 78 lines.
|
||||||
|
- **Naming**: `YYYY-MM-topic-kebab.md`.
|
||||||
|
- **Template fields**: Date · Status · Context · Problem · Decision · Implementation
|
||||||
|
(Keep/Remove/Update subsections) · Open Questions · **Lessons Learned** (a retrospective
|
||||||
|
field not seen elsewhere in this survey).
|
||||||
|
- **Tooling**: none.
|
||||||
|
|
||||||
|
### llf-schema
|
||||||
|
- **Organization**: mixed — `docs/decisions/`, 6 files (18–134 lines), but several files
|
||||||
|
embed *multiple* numbered decisions rather than one-per-file.
|
||||||
|
- **Naming**: `YYYY-MM-DD-topic-kebab.md` at the file level; `D-NNN` numbering for individual
|
||||||
|
decisions embedded within a file (at least D-038 through D-043+ found).
|
||||||
|
- **Template fields**: Status · Context · Decision · Consequences; some have an "Open
|
||||||
|
sub-decision" pattern with explicit options + rationale.
|
||||||
|
- **Tooling**: cross-links into the project's `openspec/changes/...` spec-driven change
|
||||||
|
system — the only project doing this. One file (`2026-06-04-plugin-decision-index.md`) acts
|
||||||
|
as a superseded historical index pointing to newer sub-documents.
|
||||||
|
|
||||||
|
### cc-plugins
|
||||||
|
- **Organization**: decisions embedded in prose within larger design docs, not a dedicated
|
||||||
|
ADR directory. `progressive-disclosure/docs/gaps-and-decisions.md` (297 lines) numbers
|
||||||
|
decisions inline ("Decision 26: Single entry point").
|
||||||
|
- **Template fields**: narrative Decision / Why / mechanics — no structured Status/Context
|
||||||
|
fields as distinct headings.
|
||||||
|
- **Notable**: the whole document is marked `(LOCKED)` — a document-level freeze convention
|
||||||
|
instead of a per-decision status field.
|
||||||
|
|
||||||
|
## Projects without formal ADRs
|
||||||
|
|
||||||
|
| Project | Notes |
|
||||||
|
|---|---|
|
||||||
|
| playground | No `docs/`; minimal project. |
|
||||||
|
| remetrics | Has a README; no decision docs. |
|
||||||
|
| ruby-gems | Umbrella dir, 10 sub-repos checked; none have ADRs. |
|
||||||
|
| thinkfast | CLAUDE.md references "architectural decisions" as a task category but no ADR files exist. |
|
||||||
|
| verona-vocab | Has CLAUDE.md; no decision docs. |
|
||||||
|
| websites | Umbrella dir (hyperthrive, hyperthrive-strategy checked); none have ADRs. |
|
||||||
|
| wordpress-dc | No `docs/`. |
|
||||||
|
| hyperthrive_dev | Uses ad hoc `.scratch/active/progress.md` subagent handoff logs instead of ADRs. |
|
||||||
|
| llf-schema-build-tmp | Throwaway build directory, not a persistent project — excluded from future onboarding. |
|
||||||
|
|
||||||
|
## Addendum: `~/clients/` and `~/projects/`
|
||||||
|
|
||||||
|
The first pass covered `~/dev/` only. A second pass surveyed `~/clients/`
|
||||||
|
(inovis-lighting-audit-manager, philly-search-engine-marketing, summit-new-hire-automation,
|
||||||
|
virtuosocontent) and `~/projects/` (niche-automation-prospecting, taxes-swanson). This surfaced
|
||||||
|
a **distinct organizational pattern from `~/dev/`** — worth treating as its own category, not
|
||||||
|
merging into the table above.
|
||||||
|
|
||||||
|
### Client projects (`~/clients/`)
|
||||||
|
|
||||||
|
- **inovis-lighting-audit-manager**: no ADRs, nothing adjacent.
|
||||||
|
- **philly-search-engine-marketing**: monolithic root-level `DECISIONS.md` (236 lines, 14
|
||||||
|
decisions), plus two secondary dated docs for specific incidents. Per-decision fields: date +
|
||||||
|
title heading, `Status:` (Confirmed/Deferred), `Category:` ([Tech]/[Business]), `Source:`
|
||||||
|
(attribution), then narrative Goal/Decision/Reasoning/Residual-or-Deferred-notes. Explicitly
|
||||||
|
referenced from `CLAUDE.md`'s quick-reference table as "Past decisions" — i.e. treated as a
|
||||||
|
canonical, actively-pointed-to file.
|
||||||
|
- **summit-new-hire-automation**: not really an ADR — one post-hoc "decision framework"
|
||||||
|
document (n8n vs Rails) that's a retrospective/lessons-learned analysis of a platform choice
|
||||||
|
already made, including a decision matrix and red-flag checklist for future similar choices.
|
||||||
|
ADR-adjacent, not an ADR.
|
||||||
|
- **virtuosocontent**: monolithic root-level `DECISIONS.md`, but minimal — 10 lines, 2
|
||||||
|
decisions, just a date+title heading and a one/two-line factual statement (no Status,
|
||||||
|
Category, or reasoning fields at all).
|
||||||
|
|
||||||
|
### Personal/internal projects (`~/projects/`)
|
||||||
|
|
||||||
|
- **niche-automation-prospecting**: no dedicated decisions file; decisions are scattered inside
|
||||||
|
timestamped working documents — `logs/increments/2026-05-26-*-decisions.md` and a
|
||||||
|
`PHASE4-DECISION-MEMO.md` — organized by project phase/event (executive summary, tier
|
||||||
|
score-snapshot tables, "clear kills," next steps) rather than as discrete Status-tagged
|
||||||
|
entries. ~20 decisions total across the two files, but as narrative sections, not an ADR list.
|
||||||
|
- **taxes-swanson**: no ADRs, nothing adjacent.
|
||||||
|
|
||||||
|
### What's different here vs. `~/dev/`
|
||||||
|
|
||||||
|
1. **Client projects favor one monolithic root-level `DECISIONS.md`, not a `docs/decisions/` or
|
||||||
|
`docs/adr/` directory** — the opposite of the `~/dev/` majority pattern (one-file-per-decision
|
||||||
|
in a subdirectory). Likely driver: a client-facing single readable log is easier to hand off
|
||||||
|
or reference during a client conversation than a directory of numbered files, and these
|
||||||
|
projects are shorter-lived/smaller in decision count (2–14) than cc-os's 19.
|
||||||
|
2. **Client `DECISIONS.md` files use a `Status:` field (Confirmed/Deferred) that tracks whether
|
||||||
|
a decision is still locked-in — a business/client-relationship framing** distinct from the
|
||||||
|
Accepted/Superseded lifecycle framing used in `~/dev/` (ADR-013/ADR-018-style projects).
|
||||||
|
3. **Internal (`~/projects/`) decision-adjacent docs skip Status entirely** and are organized as
|
||||||
|
phase/incident narratives (a "worklog," not an architectural record) — closer to
|
||||||
|
hyperthrive_dev's `.scratch/active/progress.md` pattern from the `~/dev/` survey than to any
|
||||||
|
ADR convention.
|
||||||
|
4. **The no-ADR baseline holds**: 3 of 6 (`inovis-lighting-audit-manager`, `taxes-swanson`, and
|
||||||
|
arguably `summit-new-hire-automation`) have nothing ADR-like, roughly matching the ~60%
|
||||||
|
no-ADR rate found across `~/dev/`.
|
||||||
|
|
||||||
|
**Implication for plugin design**: a future `os-adr` plugin likely needs **two supported
|
||||||
|
shapes**, not one-size-fits-all — a lightweight monolithic `DECISIONS.md` mode (small
|
||||||
|
decision counts, client-facing/handoff-friendly, business Confirmed/Deferred status framing)
|
||||||
|
alongside the per-file `docs/adr/`+index mode recommended for larger personal/tooling projects.
|
||||||
|
Forcing the `~/dev/`-style per-file convention onto a 2–14-decision client project would likely
|
||||||
|
be over-engineering relative to what those projects need.
|
||||||
|
|
||||||
|
## Cross-project comparison
|
||||||
|
|
||||||
|
**Organization pattern, by frequency:**
|
||||||
|
1. One file per decision in a dedicated directory — viking-warrior-training-log, llf-schema
|
||||||
|
(partially), design-mode (only 1 file so far, same shape). Most common approach once a
|
||||||
|
project has more than a couple of decisions.
|
||||||
|
2. Monolithic single file — cc-os only, and only this repo has reached a high ADR count (19)
|
||||||
|
while staying in one file; still, that file is now 601 lines and prompted this research.
|
||||||
|
3. Embedded in prose within other docs — cc-plugins. Lowest discoverability; no per-decision
|
||||||
|
status field.
|
||||||
|
|
||||||
|
**Naming, by frequency:**
|
||||||
|
- Sequential numeric (`0001-`, `ADR-NNN`, `D-NNN`): cc-os, viking-warrior-training-log,
|
||||||
|
llf-schema — 3 of 6.
|
||||||
|
- Topic-only kebab-case, no number: delta-refinery.
|
||||||
|
- Date-prefixed: design-mode, llf-schema (at the file level).
|
||||||
|
- Inline prose numbering: cc-plugins.
|
||||||
|
|
||||||
|
**Template fields, by prevalence (of the 6 projects with any ADR-like content):**
|
||||||
|
| Field | Count | Projects |
|
||||||
|
|---|---|---|
|
||||||
|
| Decision | 6/6 | all |
|
||||||
|
| Status | 5/6 | all but cc-plugins |
|
||||||
|
| Context | 5/6 | all but cc-plugins |
|
||||||
|
| Consequences | 4/6 | viking-warrior-training-log, design-mode, llf-schema, cc-plugins ("Why") |
|
||||||
|
| Alternatives (rejected/considered) | 3/6 | cc-os, viking-warrior-training-log, design-mode |
|
||||||
|
| Rationale | 2/6 | cc-os, delta-refinery |
|
||||||
|
| Date | 4/6 | viking-warrior-training-log, delta-refinery, design-mode, llf-schema |
|
||||||
|
|
||||||
|
**Key observations:**
|
||||||
|
- **No two projects use an identical template** — field names and ordering vary even where the
|
||||||
|
underlying concept (e.g. "why we rejected X") is the same.
|
||||||
|
- **Supersession handling is ad hoc everywhere**: cc-os uses inline prose notes,
|
||||||
|
delta-refinery uses a sunset condition ("delete this document when…"), viking-warrior-
|
||||||
|
training-log uses a status column in its index, llf-schema uses an explicit
|
||||||
|
open/settled status field. No project has a formal `supersedes:` / `superseded-by:` field.
|
||||||
|
- **Indexing is rare**: only viking-warrior-training-log (README table) and cc-plugins (a
|
||||||
|
locked index-like document) have anything resembling a discoverability index. Every other
|
||||||
|
project relies on `ls`/grep of the directory.
|
||||||
|
- **None of the 6 projects use ADR tooling** (adr-tools, log4brains, etc.) — all are
|
||||||
|
hand-authored markdown.
|
||||||
|
- **9 of 15 `~/dev/` projects have no ADRs at all** — future onboarding candidates once a
|
||||||
|
plugin exists (per this repo's own ADR-013 precedent: build-first, then migrate/onboard one
|
||||||
|
project at a time rather than batch-migrating everyone). Across the `~/clients/`+`~/projects/`
|
||||||
|
addendum, 3 of 6 also have none — a consistent ~55-60% no-ADR baseline across every category
|
||||||
|
surveyed.
|
||||||
|
- **Client-facing and personal/internal projects (see addendum above) use a visibly different
|
||||||
|
shape than `~/dev/` tooling projects**: a single monolithic root `DECISIONS.md` rather than a
|
||||||
|
per-file directory, smaller decision counts (2–14 vs. cc-os's 19), and — for client
|
||||||
|
projects — a business-framed `Status: Confirmed/Deferred` field rather than an
|
||||||
|
Accepted/Superseded lifecycle field. A future plugin needs to support this as a distinct,
|
||||||
|
legitimate mode, not treat it as an under-developed version of the `~/dev/` pattern.
|
||||||
|
|
@ -0,0 +1,178 @@
|
||||||
|
# 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](https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions)). MADR refines
|
||||||
|
this with timestamped naming for sortability ([MADR docs](https://adr.github.io/madr/)).
|
||||||
|
|
||||||
|
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 15–50; 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](https://engineering.atspotify.com/2020/04/when-should-i-write-an-architecture-decision-record)):
|
||||||
|
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 (10–15 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](https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions),
|
||||||
|
[Martin Fowler bliki](https://martinfowler.com/bliki/ArchitectureDecisionRecord.html),
|
||||||
|
[MADR](https://adr.github.io/madr/),
|
||||||
|
[AWS Prescriptive Guidance](https://docs.aws.amazon.com/prescriptive-guidance/latest/architectural-decision-records/adr-process.html),
|
||||||
|
[Spotify Engineering](https://engineering.atspotify.com/2020/04/when-should-i-write-an-architecture-decision-record),
|
||||||
|
[Log4brains](https://github.com/thomvaill/log4brains),
|
||||||
|
[Y-Statements](https://medium.com/olzzio/y-statements-10eb07b5a177).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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 30–60 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 3–5 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](https://www.beyondautocomplete.nl/how-i-use-claude-code-to-keep-my-architecture-decisions-on-track/),
|
||||||
|
Graphify/GraphRAG background, [Claude Code hooks docs](https://code.claude.com/docs/en/hooks),
|
||||||
|
`agentpedia.codes` AGENTS.md article, `thebcms.com` spec-driven-development article.
|
||||||
|
|
@ -0,0 +1,130 @@
|
||||||
|
# Synthesis: What We Have, What We Could Have
|
||||||
|
|
||||||
|
_Last updated: 2026-07-03_
|
||||||
|
|
||||||
|
This draws on the full survey: 15 `~/dev/` projects plus the `~/clients/`/`~/projects/`
|
||||||
|
addendum (4 + 2 more) in `01-current-state-survey.md`.
|
||||||
|
|
||||||
|
## What we have
|
||||||
|
|
||||||
|
- **9 of 21 surveyed projects (~43%)** already write ADR-like content, in **at least 5 distinct
|
||||||
|
organizational shapes** (monolithic ADR-style file, one-file-per-decision, dated single
|
||||||
|
files, prose embedded in design docs, and — newly found in the addendum — a monolithic
|
||||||
|
client-facing `DECISIONS.md`) and **no two identical templates**.
|
||||||
|
- **A clear split by project category emerged from the addendum**: `~/dev/` personal/tooling
|
||||||
|
projects lean one-file-per-decision under `docs/adr/`/`docs/decisions/` with an
|
||||||
|
Accepted/Superseded lifecycle framing; `~/clients/` projects lean a single monolithic
|
||||||
|
`DECISIONS.md` at repo root with a business-framed `Status: Confirmed/Deferred` field, sized
|
||||||
|
for a much smaller decision count (2–14, vs. cc-os's 19); `~/projects/` (personal, non-client)
|
||||||
|
skew toward phase/incident narrative logs with no Status field at all, closer to a worklog
|
||||||
|
than an ADR. A plugin should treat these as legitimate distinct modes, not force one shape
|
||||||
|
onto all three categories.
|
||||||
|
- **cc-os itself is the edge case that triggered this research**: 19 ADRs in one 601-line file
|
||||||
|
— external research found no evidence of a monolithic log surviving much past ~30 decisions
|
||||||
|
in practice, so this file is trending toward the point where it needs to become per-file.
|
||||||
|
- **12 of 21 projects have zero ADRs** (~57%, consistent across every category). These are
|
||||||
|
onboarding candidates for later, not now (per this repo's own build-first/
|
||||||
|
migrate-incrementally precedent, ADR-013).
|
||||||
|
- **No project uses any ADR tooling** (adr-tools, log4brains, etc.) — everything is
|
||||||
|
hand-authored markdown, which means a plugin has a completely clean slate; it isn't competing
|
||||||
|
with or having to migrate off an existing tool.
|
||||||
|
- **Supersession tracking is the weakest point everywhere** — every project invented its own ad
|
||||||
|
hoc mechanism (inline prose note, a "delete this when" condition, a status column in an
|
||||||
|
index, an explicit status field) and none of them is machine-checkable.
|
||||||
|
|
||||||
|
## What we could have (with engineering effort)
|
||||||
|
|
||||||
|
A standardized ADR system, informed by the external research, would need to solve three
|
||||||
|
separate problems — matching the three HMWs in the original request:
|
||||||
|
|
||||||
|
### HMW 1 — Know when to create or query ADRs
|
||||||
|
|
||||||
|
**Deterministic triggers beat AI judgment where possible.** The research surfaced a workable
|
||||||
|
split:
|
||||||
|
- **Query trigger**: path-based, deterministic, cheap. A hook (SessionStart or a
|
||||||
|
pre-edit check, matching cc-os's existing lazy-freshness pattern from ADR-007) matches the
|
||||||
|
file(s) about to be touched against each ADR's declared "affected paths" or component tags,
|
||||||
|
and injects only ADRs that match — no LLM call needed for the common case. This mirrors
|
||||||
|
adr-kit's `adr-watch`/`adr-context` pattern found in the research.
|
||||||
|
- **Create trigger**: harder to make fully deterministic, since "was this decision
|
||||||
|
significant" is a judgment call. The realistic pattern (per Spotify's guidance and the
|
||||||
|
adr-kit `/adr:review` pattern) is a **semi-automated nudge**: a lightweight heuristic (e.g. a
|
||||||
|
diff touching more than N files across more than one module, or touching a path with no
|
||||||
|
covering ADR) flags "this might warrant an ADR," and the AI or user makes the actual
|
||||||
|
create/skip call. Fully automatic creation risks the "ADR spam" pain point noted in the
|
||||||
|
research.
|
||||||
|
|
||||||
|
### HMW 2 — Systematize creation for consistency and quality
|
||||||
|
|
||||||
|
- **Pick one template per mode, not a free-for-all.** The survey shows template drift is the
|
||||||
|
core mess *within* this user's own projects, not just across the industry. A plugin should
|
||||||
|
ship **two canonical field sets**, not one, matching the two legitimate shapes the survey
|
||||||
|
found:
|
||||||
|
- **Tooling/personal-project mode** (`~/dev/`-style): Nygard's minimal fields (Status ·
|
||||||
|
Context · Decision · Consequences) plus an explicit Alternatives-rejected field (valuable
|
||||||
|
in 3/6 `~/dev/` projects and repeatedly emphasized in the external research as the
|
||||||
|
highest-value-per-word field). Full MADR RACI metadata (Deciders/Consulted/Informed) is
|
||||||
|
solo-freelancer overkill.
|
||||||
|
- **Client-project mode** (`~/clients/`-style): a lighter monolithic-file template —
|
||||||
|
date+title heading, `Status: Confirmed/Deferred`, `Category:`, short Reasoning — matching
|
||||||
|
what `philly-search-engine-marketing`'s already-working `DECISIONS.md` does, rather than
|
||||||
|
imposing per-file/`docs/adr/` overhead on a 2–14-decision client engagement.
|
||||||
|
A plugin should pick the mode from project shape (client dir vs. tooling repo, or a simple
|
||||||
|
flag) rather than forcing every project through the same template.
|
||||||
|
- **One-file-per-decision + index for tooling-mode projects; single-file for client-mode.**
|
||||||
|
Tooling-mode should auto-generate the next sequence number and append a row to an index file
|
||||||
|
— mechanical, no LLM needed — matching the pattern that already recurs in
|
||||||
|
viking-warrior-training-log and llf-schema, and that the external research says holds up at
|
||||||
|
scale (cc-os's own monolithic file is the outlier now hitting the predicted wall). Client-mode
|
||||||
|
should keep appending to one `DECISIONS.md`, since the surveyed client files (2–14 decisions)
|
||||||
|
are nowhere near the scale where that becomes a problem.
|
||||||
|
- **Formalize supersession as a real field**, not prose. `supersedes: ADR-NNNN` /
|
||||||
|
`superseded-by: ADR-MMMM` frontmatter, checked/updated mechanically when a new ADR declares
|
||||||
|
`supersedes:` — closing the weakest gap found in every single surveyed project.
|
||||||
|
|
||||||
|
### HMW 3 — Query with high relevance, low bloat
|
||||||
|
|
||||||
|
This is where the research most directly hands cc-os a design option it wasn't otherwise
|
||||||
|
going to consider: **ADRs as another node type in the already-adopted Graphify knowledge graph
|
||||||
|
(ADR-010)**, rather than a separate retrieval mechanism. Concretely, this suggests layering,
|
||||||
|
cheapest-first:
|
||||||
|
1. **Deterministic path/component match** (an ADR's frontmatter declares affected
|
||||||
|
paths/components; a hook filters by the files in the current diff/task) — zero LLM cost,
|
||||||
|
handles the majority case.
|
||||||
|
2. **Status filter** — only `Accepted` ADRs surface by default; `Proposed`/`Superseded` stay
|
||||||
|
out of default context, available on explicit query only.
|
||||||
|
3. **Graph traversal** (once ADRs are indexed alongside code/doc nodes) for the harder case —
|
||||||
|
"what decisions structurally relate to this one," not just "what decisions touch this file."
|
||||||
|
This reuses infrastructure cc-os already has rather than standing up a parallel vector/RAG
|
||||||
|
system.
|
||||||
|
4. **AI relevance judgment as the last resort**, only over the already-narrowed candidate set
|
||||||
|
from steps 1–3 — never over the full ADR corpus. This is the concrete mechanism for "avoid
|
||||||
|
cluttering the context window... without simultaneously suppressing the relevant ones."
|
||||||
|
|
||||||
|
## Open questions to resolve before building
|
||||||
|
|
||||||
|
- Does an `os-adr` plugin apply retroactively to cc-os's own 19-ADR file (a live migration), or
|
||||||
|
ship fresh and get piloted on a new/small project first, per the build-first/
|
||||||
|
migrate-incrementally precedent already established for the vault (ADR-013)? Recommend the
|
||||||
|
latter for consistency.
|
||||||
|
- Should ADR affected-path/component metadata be authored by hand (like Graphify hub notes,
|
||||||
|
per ADR-014's finding that connective structure must be human-authored) or can it be inferred
|
||||||
|
automatically from the diff that prompted the ADR? Given ADR-014's empirical finding that
|
||||||
|
Graphify does not auto-cluster topics, the safer default is human-authored metadata at
|
||||||
|
creation time, not inferred after the fact.
|
||||||
|
- Where does an ADR "index" live if projects don't all use Graphify yet (9 of 15 surveyed
|
||||||
|
projects have never been onboarded) — does the plugin need a project-independent fallback
|
||||||
|
(a plain generated `README.md` table) so it's useful even before Graphify onboarding?
|
||||||
|
- **Resolved by the addendum**: client-owned repos do impose different constraints. Confirmed
|
||||||
|
pattern: client projects favor a single readable `DECISIONS.md`, business-framed
|
||||||
|
Confirmed/Deferred status, and no per-file/subdirectory ceremony — matching a freelance
|
||||||
|
handoff need (a client or collaborator can open one file, no plugin/CLI required to read it).
|
||||||
|
A plugin must not force the `~/dev/` per-file convention onto client engagements.
|
||||||
|
|
||||||
|
## Recommendation
|
||||||
|
|
||||||
|
Treat this as a future OpenSpec change (`openspec-propose`), not something to build ad hoc off
|
||||||
|
this research doc alone. The research here (now including the `~/clients/`/`~/projects/`
|
||||||
|
addendum) is sufficient to write a design doc / ADR of its own (an ADR about how to do ADRs,
|
||||||
|
covering both the tooling-mode and client-mode template/organization split) when that time
|
||||||
|
comes.
|
||||||
Loading…
Reference in New Issue