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:
jared 2026-07-03 11:55:12 -04:00
parent 7ae45c7bf8
commit 5d5145f347
4 changed files with 521 additions and 0 deletions

View File

@ -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.

View 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 3041 lines.
- **Tooling**: `README.md` index — a table of all ADRs with title + status. Explicitly notes
ADRs 00010003 were backfilled after the fact; 00040006 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, 2548
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 (18134 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 (214) 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 214-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 (214 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.

View File

@ -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 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](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 (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](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 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](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.

View File

@ -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 (214, 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 214-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 (214 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 13 — 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.