diff --git a/docs/ADRs/0000-adr-template.md b/docs/ADRs/0000-adr-template.md index 8e27c851b7..75c4a85cd4 100644 --- a/docs/ADRs/0000-adr-template.md +++ b/docs/ADRs/0000-adr-template.md @@ -15,6 +15,11 @@ Date: YYYY-MM-DD {Proposed | Undecided | Accepted | Deprecated | Superseded} + + ## Context What is the issue that we're seeing that motivates this decision or change? diff --git a/docs/architecture.md b/docs/architecture.md index 36db8d47fc..72ef21c085 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -2,6 +2,13 @@ What are the components of the agent execution stack? +> **This is a living document.** It must always reflect the current state of +> architectural decisions. When an ADR is accepted (or superseded), this +> document is updated to match. ADRs are point-in-time records and are not +> modified after acceptance; this document is where the *current* truth lives. +> A reader should be able to understand the system's architecture from this +> document alone, without tracing a chain of ADRs. + This document names the parts of the system without deciding how they work. It establishes shared vocabulary that the [problem documents](problems/) can reference when discussing design choices. Each component gets a responsibility statement and open questions — implementation decisions live in the problem docs and will crystallize into [ADRs](ADRs/) as they mature. This is not exhaustive. Not every problem doc maps to a component here, and not every component here has a corresponding problem doc yet. diff --git a/docs/problems/architectural-invariants.md b/docs/problems/architectural-invariants.md index 13aba428ce..41b9b054c3 100644 --- a/docs/problems/architectural-invariants.md +++ b/docs/problems/architectural-invariants.md @@ -109,7 +109,7 @@ Architectural invariants aren't permanent. They evolve — sometimes an ADR supe - **Creating invariants** — follows the existing architecture repo process (PR with ADR, 2 peer approvals) - **Modifying invariants** — same process, with explicit documentation of what changed and why -- **Superseding invariants** — ADRs already have a supersession mechanism. Agents need to recognize which ADRs are current vs. superseded. +- **Superseding invariants** — ADRs already have a supersession mechanism. When a new ADR supersedes an older one, the old ADR's status is updated and a link to the successor is added, but its content remains unchanged (ADRs are point-in-time records). `docs/architecture.md` is then updated to reflect the current decision. Agents need to recognize which ADRs are current vs. superseded. - **Temporary exceptions** — sometimes a PR needs to violate an invariant with a plan to address it later. How is this represented? A time-bounded exception in the architecture repo? A label on the PR? This lifecycle is a [governance](governance.md) concern — who can create, modify, and grant exceptions to invariants. But the representation and enforcement mechanism belongs here. @@ -130,4 +130,4 @@ This lifecycle is a [governance](governance.md) concern — who can create, modi - Can drift detection be bidirectional — if the code has drifted from the docs, maybe the docs are wrong? How do we distinguish "code drifted from intent" from "intent was never updated to match a legitimate evolution"? - What's the priority ordering when invariants conflict? (e.g., a security invariant vs. a performance invariant) - How do agents handle ADRs that reference context outside the repo (Slack discussions, meeting decisions, JIRA tickets mentioned in the ADR's context section)? -- Should agents that detect invariant violations be able to propose ADR amendments, or should that always be human-initiated? +- Should agents that detect invariant violations be able to propose new superseding ADRs, or should that always be human-initiated? (Note: ADRs are not amended after acceptance — proposing a change means writing a new ADR that supersedes the existing one.) diff --git a/skills/writing-adrs/SKILL.md b/skills/writing-adrs/SKILL.md index 637a76263a..9d3f1c0c3e 100644 --- a/skills/writing-adrs/SKILL.md +++ b/skills/writing-adrs/SKILL.md @@ -14,6 +14,36 @@ An ADR records exactly **one** decision. Problem docs explore; ADRs decide. `docs/architecture.md` and problem docs are the current state (mutable). ADRs are point-in-time records (immutable once accepted). +### ADRs are immutable records + +Once an ADR is accepted, its content is frozen. It captures the decision, the +context that existed at that time, and the consequences as understood then. When +new information arrives or circumstances change, write a **new** ADR that +supersedes the old one -- do not edit the original's Context, Decision, or +Consequences sections. + +**Acceptable modifications to an accepted ADR:** + +- Changing its `status` (e.g., from Accepted to Deprecated or Superseded) +- Adding a link or note pointing to a newer ADR that supersedes it + +**Not acceptable:** + +- Rewriting the Context to reflect updated understanding +- Editing the Decision to match a revised approach +- Modifying Consequences based on what actually happened + +If a decision turned out to be wrong, that is exactly what supersession is for. +The original ADR remains as a historical record of what was decided and why. + +### docs/architecture.md is always current + +Unlike ADRs, `docs/architecture.md` is a **living document**. It must always +reflect the current state of architectural decisions. When a new ADR is accepted +(or when an ADR supersedes an older one), `docs/architecture.md` must be updated +to reflect the latest decision. It is the single place a reader can go to +understand what is true *now*, without tracing a chain of ADRs. + ## When to Use - A specific decision has emerged from discussion in a problem doc @@ -141,6 +171,8 @@ If the ADR partially answers a question, add a parenthetical: - You're rewriting a section of architecture.md -- make a surgical edit instead - `relates_to` lists more than 3 problem docs -- the decision may be too broad - You didn't run `make lint` -- stop and run it +- You're editing the Context, Decision, or Consequences of an accepted ADR -- + write a new superseding ADR instead ## Common Mistakes @@ -153,3 +185,5 @@ If the ADR partially answers a question, add a parenthetical: | Rewriting existing doc sections | Make surgical additions only | | Skipping linters | Run `make lint` before committing | | Wrong ADR number | Check existing files in `docs/ADRs/` first | +| Editing an accepted ADR's content | Write a new ADR that supersedes it | +| Forgetting to update architecture.md | It must always reflect current decisions |