147 lines
9.0 KiB
Markdown
147 lines
9.0 KiB
Markdown
|
|
# PRD: `os-adr` Plugin
|
|||
|
|
|
|||
|
|
_Last updated: 2026-07-03_
|
|||
|
|
|
|||
|
|
Product requirements for the `os-adr` Claude Code plugin — the "what and why," to direct a
|
|||
|
|
future `openspec-propose` when the user is ready to implement. Built on the research
|
|||
|
|
(`01`–`03`), the locked requirements (`04-plugin-requirements.md`), and a review pass from Fable
|
|||
|
|
(external reviewer consult, 2026-07-03) that shaped the gaps and sequencing called out below.
|
|||
|
|
Do not silently narrow or reverse anything in `04-plugin-requirements.md` — this doc specifies
|
|||
|
|
*how* those requirements get built, not a re-decision of *what* they are.
|
|||
|
|
|
|||
|
|
## Problem statement
|
|||
|
|
|
|||
|
|
~43% of this user's own projects have ADR-like content, in 5+ mutually-incompatible shapes; the
|
|||
|
|
rest have none. No project uses ADR tooling. The user works with AI agents across every one of
|
|||
|
|
these projects, not just themselves — so decision records need to be discoverable and writable
|
|||
|
|
*consistently* by an agent that has never seen a given project before, which no current project
|
|||
|
|
provides. `cc-os`'s own 19-ADR/601-line file is already near the point research says monolithic
|
|||
|
|
logs stop working. This plugin exists to fix that, once, and mechanically enough that it doesn't
|
|||
|
|
become another bespoke-per-project thing.
|
|||
|
|
|
|||
|
|
## Goals
|
|||
|
|
|
|||
|
|
- One template, one location convention, enforced the same way in every project.
|
|||
|
|
- New ADRs get written (by the AI, largely unprompted) using that template with no per-project
|
|||
|
|
relearning.
|
|||
|
|
- Existing ADR content in every project — no matter its current shape — converts into the new
|
|||
|
|
template non-destructively.
|
|||
|
|
- An AI agent working in any onboarded project surfaces the *correct* relevant ADR without being
|
|||
|
|
told to look, and recognizes when its own in-progress decision warrants a new one.
|
|||
|
|
|
|||
|
|
## Non-goals (explicit, out of scope for this PRD)
|
|||
|
|
|
|||
|
|
- Per-project or per-client template variants (rejected in `04-plugin-requirements.md`; not
|
|||
|
|
revisited here).
|
|||
|
|
- Multi-editor / handed-off-repo governance. This plugin assumes the user is the primary ADR
|
|||
|
|
author (directly, or via their AI agents) in every project it's installed in. A repo where
|
|||
|
|
other humans independently maintain ADR conventions is out of scope for Phase 1 — flag this
|
|||
|
|
assumption in the plugin's own docs rather than silently breaking there.
|
|||
|
|
- Mirroring ADRs into an enforceable-constraints surface (AGENTS.md-style hard rules). The
|
|||
|
|
research surfaced this as a real tension (ADRs record "why," not "must never happen"), but nothing
|
|||
|
|
today gives ADRs a severity field or an enforcement mechanism. Note as a candidate Phase 2 if a
|
|||
|
|
severity field gets added later and high-severity decisions accumulate — not part of this build.
|
|||
|
|
- Retrofitting `cc-os`'s own ADR file as part of building the plugin. Per the README's build
|
|||
|
|
order note: build first against a small pilot, retrofit cc-os and everything else after.
|
|||
|
|
|
|||
|
|
## Requirements → build phases
|
|||
|
|
|
|||
|
|
### Phase 1 — Template + location (mechanical, no LLM)
|
|||
|
|
|
|||
|
|
- Ship the customized-Nygard template and `docs/adr/NNNN-title.md` + index file convention from
|
|||
|
|
`04-plugin-requirements.md`, as a copy-paste-ready generator (`os-adr:new` or similar skill).
|
|||
|
|
- Index file is maintained mechanically (append/update on every write) — never hand-edited.
|
|||
|
|
|
|||
|
|
### Phase 2 — SessionStart existence-check hook
|
|||
|
|
|
|||
|
|
- Deterministic only: check for `docs/adr/` + index file. No LLM call in the hook itself.
|
|||
|
|
- Present → inject the smallest possible context note (existence + one-line "how to use it").
|
|||
|
|
Budget this like `os-doc-hygiene`'s reminder: near-zero tokens.
|
|||
|
|
- Absent → notify the user, suggest running the setup/migration skill. **Needs a suppression
|
|||
|
|
mechanism** (flagged by Fable review) so a project that deliberately has no ADR system yet
|
|||
|
|
doesn't re-nag every session — a per-project dismiss flag (e.g. a marker file or config line),
|
|||
|
|
same shape as `os-doc-hygiene`'s snooze state.
|
|||
|
|
|
|||
|
|
### Phase 3 — Non-destructive migration
|
|||
|
|
|
|||
|
|
This is the highest-friction requirement (Fable review flags it as the one with the most edge
|
|||
|
|
cases) — resolve these before implementation starts, not during:
|
|||
|
|
|
|||
|
|
- **Detection**: what counts as "an existing ADR" in an unknown project must be defined per
|
|||
|
|
known shape from `01-current-state-survey.md` (numbered per-file dirs, dated single files,
|
|||
|
|
monolithic multi-decision files, prose-embedded-in-other-docs) — plus a fallback path for
|
|||
|
|
shapes not yet seen.
|
|||
|
|
- **Field-mapping threshold** (mechanical vs. LLM boundary — the vaguest part of requirement 4a
|
|||
|
|
as originally stated): define a concrete rule before build, e.g. *heuristic-fill fields that
|
|||
|
|
are structurally unambiguous (Status/Date via frontmatter or clear heading), LLM-fill only
|
|||
|
|
fields requiring interpretation (Consequences, Alternatives-rejected) with the result flagged,
|
|||
|
|
never silently invent a Decision or Context field from nothing.*
|
|||
|
|
- **Flagging format**: a single, consistent surface for uncertain guesses — a per-file frontmatter
|
|||
|
|
field (e.g. `migration_confidence: low`) plus one migration report file, not scattered
|
|||
|
|
inline comments. Decide the exact shape during build, but it must be one mechanism, not
|
|||
|
|
several.
|
|||
|
|
- **Non-destructiveness**: old ADR content is never deleted or moved during migration — new files
|
|||
|
|
are written alongside it under `docs/adr/`. Deletion of the old system happens only on an
|
|||
|
|
explicit, separate user-approved step.
|
|||
|
|
- **Pilot before shipping broadly**: run the migration on 2-3 real projects (candidates: the ones
|
|||
|
|
already surveyed with ADR content — viking-warrior-training-log, delta-refinery, llf-schema)
|
|||
|
|
and check the uncertain-flag rate before treating the heuristic as good enough. If a large
|
|||
|
|
share of fields end up flagged, tighten the heuristic before wider rollout — this is a build-phase
|
|||
|
|
gate, not a shipped feature.
|
|||
|
|
|
|||
|
|
### Phase 4 — Retrieval (deterministic-first, per the research's layering)
|
|||
|
|
|
|||
|
|
1. Path/component match against each ADR's `affected-paths`/`affected-components` frontmatter.
|
|||
|
|
2. Status filter — only `Accepted` by default.
|
|||
|
|
3. Graph traversal via Graphify once ADRs are indexed as graph nodes (reuses the `os-vault`
|
|||
|
|
infrastructure rather than a parallel retrieval system).
|
|||
|
|
4. AI judgment only over the already-narrowed candidate set from 1-3 — never the full corpus.
|
|||
|
|
|
|||
|
|
## Deferred: unprompted-behavior evaluation (requirements 4d/4e)
|
|||
|
|
|
|||
|
|
Per the locked sequencing in `04-plugin-requirements.md`: this is a distinct stage *after* the
|
|||
|
|
plugin is built and believed correct, not concurrent with the build. However, per Fable's review,
|
|||
|
|
sketch (not implement) the held-out test scenarios **before** finalizing the plugin skeleton, so
|
|||
|
|
Phase 4's retrieval surfaces aren't accidentally missing something the eval will need later.
|
|||
|
|
Two example scenario shapes to sketch now:
|
|||
|
|
|
|||
|
|
- **Write-trigger scenario**: give the AI a task that touches a decision of real consequence
|
|||
|
|
(irreversible, cross-cutting, contested) without saying "write an ADR" — check whether it
|
|||
|
|
proposes one unprompted.
|
|||
|
|
- **Retrieval scenario**: give the AI a task or question that conflicts with an already-written,
|
|||
|
|
Accepted ADR without naming the ADR or the constraint directly — check whether it (a) surfaces
|
|||
|
|
the ADR system at all, and (b) retrieves the *specific correct* one, not merely a plausible one.
|
|||
|
|
|
|||
|
|
If sketching these surfaces a plugin surface Phase 1-4 doesn't yet provide (e.g. a query tool
|
|||
|
|
callable mid-task, not just at SessionStart), fold that surface into the initial build. Do not
|
|||
|
|
fold the *evaluation itself* in — that stays a separate, later stage using the `autoresearch`
|
|||
|
|
skill's modify→verify→keep/discard loop against held-out scenarios, per the locked sequencing.
|
|||
|
|
|
|||
|
|
## Architecture / implementation style
|
|||
|
|
|
|||
|
|
- Object-oriented, Sandi Metz principles (small classes/methods, single responsibility,
|
|||
|
|
dependency injection over globals, tell-don't-ask, duck typing over type-checks) —
|
|||
|
|
see the [[ruby-and-sandi-metz-oop-preference]] memory.
|
|||
|
|
- Ruby preferred; Python acceptable for hook entry points where it's the more native fit
|
|||
|
|
(matching the existing `os-vault`/`os-doc-hygiene` Python hook pattern) — decided
|
|||
|
|
per-component, not as a global language choice. A Python hook script may thinly wrap an
|
|||
|
|
OO-designed Ruby or Python core.
|
|||
|
|
|
|||
|
|
## Success criteria
|
|||
|
|
|
|||
|
|
- Every surveyed project with existing ADR content converts with zero data loss (old system
|
|||
|
|
fully intact until user-approved deletion).
|
|||
|
|
- Migration uncertain-flag rate stays low enough to be trustworthy (define and check an explicit
|
|||
|
|
threshold during the Phase 3 pilot — do not ship on an unmeasured guess).
|
|||
|
|
- SessionStart hook overhead is near-zero-token and adds no perceptible session-start latency.
|
|||
|
|
- A new ADR can be written, correctly templated and indexed, in one skill invocation.
|
|||
|
|
- (Deferred, Eval stage) unprompted write-trigger and retrieval accuracy measured against a
|
|||
|
|
held-out scenario set — no numeric target set yet; the held-out methodology itself is the
|
|||
|
|
Phase 5 deliverable.
|
|||
|
|
|
|||
|
|
## Rollout order
|
|||
|
|
|
|||
|
|
Matches the README's locked build order: build and pilot this plugin on a small/clean project
|
|||
|
|
first, then use it to retrofit `cc-os` itself, then other `~/dev/` projects, then
|
|||
|
|
`~/clients/`/`~/projects/`, then any project encountered going forward — one at a time.
|