In almost every project I know, there's a wiki somewhere with diagrams from three years ago. Nobody trusts them, so nobody reads them, so nobody maintains them.
The consequences are always the same. People who only touch a project now and then don't know what the goal is, what was decided and why. So they hesitate to touch the code. And when something goes wrong, there's no basis for a factual conversation: was the decision wrong back then, or did only the circumstances change?
Coding agents make this worse, because the code changes faster than ever. In part 1 I showed why I built my own harness sparc. This part is about how it keeps the documentation current. I'd like to start with a decision that didn't last 24 hours.
A decision that replaced itself
Architecture Decision Records (ADRs) capture what was decided with which knowledge. I described the basics two years ago in Architecture Decision Records. In sparc, a strict rule applies on top: the content of a decided ADR doesn't change anymore. An ADR that gets quietly "corrected" afterwards loses exactly the information you need when something goes wrong.
But a rule only helps if someone checks it. My first solution (ADR-0004) was a hash over the content of every decided ADR, stored in a separate locked field. It worked. But after every decision someone had to set the hash again, and the field isn't part of the standard format MADR.
The next day came the obvious insight: git already knows every version of an ADR. So ADR-0004 was replaced by ADR-0008, exactly the way the rule demands. The new ADR also records what the decision costs:
Chosen option: "Compare with the first committed version that has a decided
status", because git already holds the data. The ADR files stay in the MADR format.
- Good, because there is no `--lock` step and no field outside MADR.
- Good, because the check also protects `decision-makers`, `consulted`,
`informed` and committed amendments.
- Bad, because a project without git loses the protection. The check reports this.
- Bad, because the protection starts only with the first commit of the decision.
ADR-0004 didn't disappear. It's still in the repository, with the status superseded by ADR-0008. Anyone who wants to know why there's no lock hash anymore finds the whole story. For me, that's the best proof that the rule works: it cleanly replaced its own first implementation.
Amend or supersede
What happens when something about a decision changes? The agent asks a single question: Does the change affect the context, the options, the decision or its consequences? If yes, a new ADR is created and the old one is superseded. If no, it's an amendment, which I have to approve explicitly:
### 2026-10-22: Warn one time for the same findings
Approved by: [@sventropy](https://github.com/sventropy), chat
A live test showed that a warning makes the agent reply one more time.
The hook keeps the digest of the last findings for each project.
That's all the status model you need: proposed, accepted or rejected, later amended, deprecated or superseded. And not every decision needs an ADR. A decision is relevant when it's hard to change later or affects more than one part of the system.
What matters most to me is the "Bad, because". Every decision has a price. Writing it down builds acceptance, because when exactly that price comes due later, it was known and consciously accepted.
One home per fact
ADRs are only part of the documentation. The basic idea for the rest is simple: every fact lives in exactly one place. All other documents link to it. A fact that lives in two places will contradict itself sooner or later. With agents that write a lot and fast, sooner.
That's why every sparc project has the same fixed set of documents: README, AGENTS.md, backlog, changelog, specs, C4 diagrams, canvas and ADRs. Every document has a role as its owner, and it's defined what it's the home for. The architecture section in the README, for example, has at most three sentences and links to diagrams, canvas and ADRs instead of repeating them.
C4 diagrams as text
For the architecture overview, sparc uses two levels of the C4 model: system context and container. The diagrams are Mermaid text in the repository, so agents can change them, git shows the differences in review and GitHub renders them without extra tools:
C4Context
title System Context: sparc
Person(dev, "Developer", "Starts changes and approves them")
System(sparc, "sparc", "Claude Code plugin for spec-driven work with agents")
System_Ext(openspec, "OpenSpec CLI", "Manages specs and changes")
Rel(sparc, openspec, "Calls")
The price is in the ADR: Mermaid C4 is less complete than Structurizr, and the two diagrams share no common model. So that nobody forgets the diagram, every change's design must name its "C4 impact", or explicitly state "No C4 impact".
The canvas: one page for the conversation
C4 shows the structure. For people who don't want to read diagrams, sparc uses the Architecture Communication Canvas: goals, stakeholders, quality requirements, core decisions and risks on one page, understandable for management too. I described how to phrase quality requirements in a measurable way in What Makes Software Good?.
One section has a special role: "Core Risks and Missing Information". Everything an agent can't prove ends up here. A hidden hallucination becomes a visible question, and the canvas shows at any time what the team doesn't know yet.
Find drift instead of hoping for discipline
A fixed set of documents is useless if nobody maintains it. In sparc, maintenance is therefore part of every step: when a change is proposed, it goes into the backlog. When it's completed, changelog, README, canvas and ADRs are updated.
On top of that comes a script without an LLM and without dependencies. It checks required sections, placeholders, sentences that are too long, changelog and version, and the ADR rules, and it delivers the same result every time. A hook in Claude Code runs it as soon as an agent finishes. There's a deliberate decision here too: the hook warns, but it doesn't block. In the middle of a task the docs are often intentionally out of sync, and a blocking hook would force the agent into a loop. The check becomes binding only when a change is completed.
Takeaway: an ADR on one page
If you take only one thing from this post, take this structure. It follows MADR, is cut down to the essentials and works with or without an agent:
---
status: proposed
date: YYYY-MM-DD
---
# Short title of the problem and the solution
## Context and Problem Statement
2 or 3 sentences: the situation and the question.
## Considered Options
- Option 1
- Option 2
## Decision Outcome
Chosen option: "Option 1", because <reason>.
- Good, because <consequence>
- Bad, because <consequence>
## Amendments
<!-- Only approved additions. Never change the text above after the decision. -->
The two rules that go with it: always write at least one "Bad, because". And never change a decided ADR; amend or supersede it instead.
Conclusion
Current architecture documentation isn't a matter of discipline but of structure. When every fact has a home, maintenance is part of every work step and a deterministic check reports drift right away, the documentation keeps pace with the code, even when an agent writes the code.
The third part (coming November 8, 2026) covers the workflow behind it, and an architecture that looked perfect on paper and still disappeared again.
