TL;DR
Code shows what was built. It does not show the options that were rejected or the constraint that forced the choice, so people and coding agents guess. Write a short record for each choice a capable newcomer would otherwise undo: context, options and why they lost, decision, consequences, and the condition that reopens it. Keep it in the repository, point to it from the code and the agent's instructions, mark replaced records superseded instead of deleting them, and let only a person's review accept one.
A long comment, or a file nobody opens
A method could have been written three obvious ways. Its author picked the third, because the first two had downsides that only appeared after trying them, one of them a third-party library that turned out to be poorly maintained. Explaining that beside the method would bury the code under a block of comment. Moving it to a separate file, the author worried, meant it would never be read. That was a question on Software Engineering Stack Exchange in 2018, and the most upvoted answer was to put the documentation "in the place where it is most likely to be found."
Coding agents sharpen both halves of that problem. An agent reads the code and whatever its instruction files lead it to, so a record that nothing points to is as invisible to the agent as it is to a hurried colleague. And when someone asks an agent why the code is built a certain way, it will produce an explanation from the code itself, whether or not anyone made that decision for that reason.
People are already adapting. In July 2026 a developer on Hacker News described keeping decision records under app/docs/adr, with an index file the agent checks before designing a feature, and asked whether others did the same. The one reply pointed to AGENTS.md files and warned about drift. That leaves four things to settle: what goes into a record, where it lives, how it is retired, and how anyone tells an approved choice from a plausible explanation.
Which choices earn a record
Most code needs no record; the code and its tests say enough. Write one when any of these is true:
- A capable newcomer would change it back. The obvious approach was tried or considered and lost, and the reason is not visible in the code.
- The deciding constraint lives outside the code: a legal or contractual requirement, a budget, another team's system, an earlier incident.
- Reversing it is expensive: a storage format, a public interface, a dependency, a data model.
- Something was deliberately left out. A decision not to add a cache or a retry leaves no line of code to comment on.
Michael Nygard's 2011 post on documenting architecture decisions gives each record a title, context, decision, status and consequences, one or two pages at most. For records an agent will read, four more fields earn their place: the options considered and why each lost, the paths in the repository the decision affects, who approved it, and a "revisit if" line naming the condition that would reopen it. The rejected options matter most, because they are exactly what a well-meaning agent will propose next.
Put the pointer where the work happens
Keep the records in the repository, reviewed in the same pull request as the code they explain. An agent working in the checkout can read them; a wiki is reachable only if the session has been given a connection to it. Then make sure something leads to them at the moment of work:
Comparison
| Pointer | When it is seen |
|---|---|
A one-line Why: comment naming the record, above the code it governs | Whenever a person or an agent reads that code |
A Claude Code path-scoped rule in .claude/rules/ with paths: src/invoices/** | When Claude reads, writes or edits a matching file |
A line in the root AGENTS.md saying where records live and how to read their status | Codex builds its instruction chain once when it starts, from the repository root down to its working directory, so a nested file helps only when Codex starts there |
| An index of every record with its status | When the agent is told to read the index first |
Claude Code's documentation says it treats its instruction files as context rather than enforced configuration, so a pointer improves the odds that the record is read and guarantees nothing. The article on making an AI agent use the right rules for each part of a monorepo compares how the tools decide which directory's instructions to load.

One decision, from proposal to replacement
To see what retrieval looks like after a revision, one made-up decision was followed through a throwaway Git repository on 6 October 2026: should an invoice service render each PDF on request, or store it when the invoice is issued? It was recorded twice, as Markdown files in docs/decisions/ and as Paqad decision packets (paqad-ai 1.95.0). One Git identity stood in for the coding agent and another for the architect.
- The agent committed record 0001, "render on request", with
Status: Proposed, and opened a decision packet. - The architect changed the status to
Accepted, resolved the packet, and added theWhy:comment and a path-scoped rule in the same commit. - A new requirement then met 0001's "revisit if" line: finance must reproduce the exact invoice that was sent. The agent proposed record 0002, "store when issued", which names 0001 as the record it supersedes, and opened a second packet.
- The architect accepted 0002, changed one line of 0001 to
Status: Superseded by 0002, and changed the code and its comment in the same commit.
Retrieval then started from the code:
Retire a decision without erasing it
Nygard's rule from 2011 still works: when a decision is reversed, keep the old record and mark it superseded. Change only its status line and leave the reasoning as written, because that reasoning explains the code people will still meet in older branches, releases and bug reports. The new record names what it replaces and which condition changed, ideally the old record's own "revisit if" line. adr-tools automates both status changes with adr new -s 9.
Update the code's Why: comment in the same commit, so blame leads to the current record and the old one stays one link away. The article on updating a specification halfway through AI-assisted development makes the same move for a specification.

Approved by a person, or explained by a model
An "Approved by" line can be typed by anyone, including the agent. In the demonstration the resolved packet's rationale began "Accepted by the architect", but that was text supplied with the resolve command; the packet has no field for who answered. Evidence of approval has to come from something the agent cannot produce for itself. On GitHub, a CODEOWNERS entry for docs/decisions/ requests the owners' review automatically, and the "Require review from Code Owners" branch protection makes that approval a condition of merging. A record whose status became Accepted in a merge an owner approved is an approved choice.
Treat any account of why the code is built a certain way as a hypothesis until it cites a record and that record's status. If no accepted record covers the question, the honest answer is that the reason was never recorded, and the useful next step is a proposed record for a person to accept.
Paqad turns some of these choices into decision pauses. On Claude Code and Codex CLI, code edits are blocked while a packet waits in .paqad/decisions/pending/, and resolved packets are files the team can commit with the change they justify. In 1.95.0 a packet records the choice, the rationale and the time, not who answered or what it replaced, so the superseded status still belongs in the record people read, and approval still comes from review. Paqad's documentation sets out where the decision pause gate holds an edit and how a waiting decision is answered.
Frequently Asked Questions
How should we record design decisions so humans and AI agents know why the code is built this way?
Start with the next decision rather than a backfill of history. Each time a review asks "why is it like this?" and nobody can answer from the repository, write one short record and give it the next number. Never reuse or renumber, so links from code, commits and older records keep pointing at the same decision.
Which choices need their rationale, constraints and rejected options recorded?
Use a newcomer test: given only the code and the tests, would a capable engineer or an agent probably change this? If yes, record it. Constraints that expire, such as a contract term or a vendor limit, deserve a date or a condition in the "revisit if" line so the record can be reopened on purpose rather than by accident.
Where should that record live so it is found during work on the affected code?
In the repository, with its "Affects" paths kept current. When code moves, a stale path silently breaks every pointer to the record. A small check in continuous integration that every Why: comment names a file that exists, and every record's paths still exist, catches the break before an agent meets it.
How do we mark a decision as superseded without losing the history behind it?
Distinguish replaced from withdrawn. Nygard allows a changed or reversed record to be marked deprecated or superseded, with a reference to its replacement; keeping deprecated for a decision that simply stopped applying, and superseded for one with a successor, tells the reader whether to look for a newer record. If only part of a decision changes, write a new record that restates what still holds rather than editing the old one, so neither record has to be read alongside a diff.
How can a future reviewer distinguish an approved architectural choice from an agent's unsupported explanation?
Ask for the record number and its status line, then open it; the citation is cheap to check and an invention is not. Let the agent draft records, but have them say "Proposed by: coding agent" and stay proposed until a person merges them, so an agent-written rationale is never mistaken for an accepted one.
