Architecture
Architecture Decision Records: Keeping the Reasons Behind a Choice
How an Architecture Decision Record preserves the reasons, alternatives and consequences behind one significant architectural choice, and how teams and…
A team may already have its requirements, a description of the system's architecture, and the system's boundaries described with the C4 model (Context, Containers, Components, Code). These documents can show that the system has a web application and a relational database, and the code can show exactly how a booking is written. But neither the code nor the current schema explains, on its own, why the team chose this particular database, what constraints it was working under at the time, and which alternatives it turned down. An architecture decision record keeps that reason, together with its consequences.
An ADR (Architecture Decision Record) is a short document about one significant decision, the arguments for it and the trade-offs it involves. An ADR is the historical trace of a specific choice, not a guarantee that the choice is still right. Together, the records form an architecture decision log. This unit covers when such a record is worth the effort, how to compare genuine options, what to write about status and consequences, how to keep the history of changes, and how to help agents find and respect the team's decisions.
By the end of this unit you will be able to:
- distinguish a decision from its record, from the discussion about it and from its implementation;
- choose between an ADR, a comment on a pull request, a short note, and no separate document at all;
- describe context, constraints, facts and assumptions so that a future reader can check whether they still hold;
- compare alternatives without setting up a straw-man option that was always going to lose;
- record benefits, losses, operational work, risks and conditions for revisiting;
- keep a superseded decision as history and link it to the new one;
- use ADRs when working with code and with an agent, without letting an automatic model response stand in for the owner's approval.
What an ADR actually records

An architectural decision is a justified choice that has a noticeable effect on the requirements or the structure of a system. It might set a boundary of responsibility, a data store, an external dependency, a protocol, an access model, a recovery approach, or an important trade-off between quality and cost. Significance depends on context: replacing a library may be trivial for one product and risky for another, if compatibility with partners depends on it.
The ADR itself is not the decision and does not make it. It is a document that lets you reconstruct the chain of reasoning. That is why it separates at least three things:
- Circumstances: what problem needs solving, what goals and constraints we have, and what is still unknown.
- Choice: what action or direction the team has decided to take.
- Consequences: what capabilities, costs, risks and obligations appeared as a result of the choice.
This separation keeps you from confusing "we want to avoid double booking" with "we are introducing a transactional constraint in the shared database" and with the result "every operation that changes a slot must now go through this database". The first is a need, the second is a decision, and the third is a consequence that carries a specific obligation.
The public description of ADRs maintained by the adr.github.io community defines an ADR as a record of one architectural decision together with its rationale and trade-offs; the collection of records forms the decision log (ADR definition). In his original 2011 article, Michael Nygard explained why the motives behind decisions need to be kept: otherwise a newcomer must either accept an old choice blindly or change it just as blindly. He recommended short, modular records, which are easier to read and maintain than one bulky architecture book (Documenting Architecture Decisions).
An ADR does not replace a requirements specification, a full Software Architecture Document (SAD), an application programming interface (API) contract, an operations manual, or the discussion on a pull request. It links to them and explains how the choice follows from the context, but it does not copy their content. Migration and recovery steps are described in an executable operational procedure; the ADR keeps the reason for the choice and a link to that procedure.
When an ADR is worth writing

A record is valuable when a future reader will not be able to reliably infer the motive from the code or from a short change history. Most often this means that the decision:
- affects several features, teams or releases;
- sets a boundary between systems, services, data stores or data owners that is hard to change;
- introduces a long-term external dependency or narrows the choice of vendors;
- has significant consequences for security, privacy, availability, cost or recovery;
- picks one trade-off among several acceptable alternatives;
- deliberately postpones a major restructuring or automation, because the current option is good enough;
- may need revisiting if specific conditions change.
For example, the decision to store confirmed bookings in a transactional relational database deserves its own record if the team compared it with a document store, agreed to maintain migrations and defined the integrity boundary. It will affect the later data model, backups, concurrent changes and the team's work.
A separate ADR is usually unnecessary for fixing a typo, renaming a local function or making a cosmetic markup change. If the decision is plainly visible from a small pull request and creates no long-term commitment, a description of the change and its reason is enough, with no new file. If the question is still open, it can be tracked as a proposal or discussed in the task. Not every interesting technical idea becomes an architectural decision.
The line is not drawn by the number of lines of code or by the word "architecture" in a title. A practical test: imagine that six months from now someone wants to change the choice. Which facts, risks, boundaries and agreements will that person be unable to reconstruct from the implementation? If the answer matters, write down the motive and the consequences. If the question can be settled from a readable task description, do not create a duplicate.
What a single record is made of

There is no universal template. Nygard proposed a short record with a title, context, decision, status and consequences. MADR (Markdown Architectural Decision Records) is an extended template with the problem, decision drivers, considered options, consequences, confirmation and links. These are useful options, not mandatory standards (MADR description and template).
A team can start with a minimal record like this:
# ADR-0007. Store confirmed bookings in a relational database
Date: 2026-04-12
Status: proposed
Approval owners: booking owner and platform team
## Context
What problem are we solving; which facts, constraints and assumptions shape the choice?
## Decision
What do we propose to do? Name the specific action and its boundary; once approved, this wording must reflect the choice exactly.
## Options considered
What could realistically have been chosen, including the option of changing nothing?
## Consequences
What becomes simpler, harder, more expensive or riskier?
## Revisit
What change in circumstances should bring us back to this decision?
## Related material
Requirement, SAD, task, pull request, recovery instructions or a newer ADR.
This is a scaffold for explanation, not an instruction to create an ADR for every change. The date is recorded so that you know when the circumstances were assessed; it does not replace version history. If the record changes, the version control system keeps track of who changed it and when. A short title should convey the choice, not just the topic: "Relational database for confirmed bookings" is more informative than "Database".
If the team keeps a separate Revisit field, it too must be checkable. "Revisit in a year" is weak; "reassess if measurements show that the peak number of simultaneous confirmations exceeds the capacity of one node" ties the check to the reason for the choice. The trigger starts an assessment; it does not change the ADR automatically.
The following pairs show what job each field of the minimal record does. They are short teaching phrasings, not a ready-made ADR for a real product:
- Title. Weak: "Database". Strong: "Store confirmed bookings in a shared relational database" — the direction of the choice is visible from the title alone.
- Status. Weak: "Accepted", when the responsible owner has not yet approved the text. Strong: "Proposed; awaiting the booking owner's decision" — the reader understands that the direction is not yet authoritative.
- Context. Weak: "We will soon have a huge number of users." Strong: "According to the 12 April report, there were 1,200 confirmed bookings per month; the peak number of simultaneous writes has not yet been measured, so the figure of 300 in this example is an assumption" — the fact has a source, and the unknown is not dressed up as a forecast.
- Decision. Weak: "We need a reliable and scalable system." Strong: "All confirmations of the last free place are performed as a single transactional operation in the shared relational database" — the action and its boundary can be checked.
- Options considered. Weak: "The other database is slow; a separate service is too complex." Strong: "We compared writing to one relational database, distributed locking and postponing the change against the same criteria: protecting the last place, operational work and recovery; there are no load measurements yet" — the alternatives are plausible, and the limit of the evidence is visible.
- Consequences. Weak: "The decision is fast and reliable." Strong: "A shared transaction protects the place count from two simultaneous confirmations; in exchange, every write goes through one data store, and the team must manage backups and recovery" — both the benefit and the new costs are shown.
Context: facts, assumptions and constraints
The context answers the question "what was known at the time?" It should let the reader picture the same problem without guessing at a hidden backstory. Record only the factors that influenced the choice:
- the goal or requirement that has to be met;
- verified facts, and the source of each important fact;
- assumptions that could not be verified in time;
- constraints of the team, product, environment, licence, budget or deadline;
- the load profile, and what is known or unknown about it;
- the date of the assessment and the people with the authority to make this decision.
Do not record a forecast as a fact. "According to the product owner's report, we have 1,200 confirmed bookings a month" is a verifiable statement with a source; "300 simultaneous changes at peak" is a teaching assumption, not a measurement. "We will soon have a million active users" also remains a forecast unless there is a well-founded calculation behind it. When telemetry or new data appears, compare it with the assumption and mark what needs reassessing.
Constraints can also be social and operational. If the on-call team lacks the skills to support a three-database cluster, that is not a "weak technical argument" to be hidden. It is part of the real cost: who will have to learn, monitor and recover the system when it fails? Nygard advised describing the technological, project and human forces in neutral language; the judgement belongs in the choice and the consequences, not in a slanted description of the facts.
Options: a fair comparison
The list of alternatives is not decoration placed in front of a choice that has already been made. It shows that the team considered the available paths and understood the price of each. "Leave things as they are" or "wait until there is data" is often a real option. If it violates a mandatory requirement, say plainly which one.
Use shared criteria for every option: does it meet the requirement; how much change does it need; what has to be maintained; which properties does it provide or weaken; what is unknown. Do not compare the chosen option by its best features and the alternative by its worst. Do not call a vendor or an approach "not serious" when the real reason is that the team has no time or skills to operate it. That is an operational constraint, and it should be recorded openly.
For small decisions, two or three substantive paragraphs are enough. If the criteria pull against each other, a table or a short list will help the reader see the trade-off. Do not add artificial mathematical precision. Scores of "1–5" do not become objective just because they are numbers. If the team needs a ranking, explain what the scale means and where the weights came from.
Decision and status: what has been agreed
The Decision section should contain one sentence with a checkable action and its boundary: "We choose a relational database for confirmed bookings; every command that changes the last free place uses a single transactional booking operation." That can be checked against the implementation; the phrase "the system must be scalable" does not name a choice.
Status answers a different question: have the authorised people approved the direction, and is it still in force? Teams can agree on the meaning of "proposed", "accepted", "rejected", "deprecated" and "superseded", but this is a local convention, not a universal standard. MADR and Nygard both offer status options, not a mandatory set (MADR template, Nygard on ADR status).
Write down who can change the status and through what process. If the product owner is the approver, their answer through the approved process sets "accepted"; an agent's text, the change author's approval, or the mere existence of a file do not, unless the team's rules say otherwise. A teaching status of "proposed" does not attribute an invented agreement to the team. An accepted decision also does not mean it has already been implemented or deployed: track execution separately, in a task, a pull request or a release.
Consequences and revisit triggers
Record consequences; do not advertise the choice. State:
- what becomes simpler, and which goal that supports;
- what becomes more expensive or more complex;
- what work is needed for development, operations, backups and recovery;
- what risks arise and who watches them;
- which dependencies or data will make a future change expensive;
- which questions still need research, and who is responsible for them by when.
Every significant trade-off should be visible. A relational database gives clear integrity rules, but the team has to update the schema and plan compatible changes. A separate service can isolate responsibility, but it adds a network call, a deployment, monitoring and an on-call procedure. Postponing a change saves time now, but it needs a date or a condition for reassessment. Neal Ford's page describes Software Architecture: The Hard Parts as a book about architectural trade-offs and how to document them; here it supports only the subject of the book, not any specific rule in this section (Neal Ford on the book).
"Revisit in a year" is weaker than a condition tied to the reason for the decision. Better: "return to the choice if the peak exceeds the confirmed budget of one node, or if the team needs to change the booking model independently". A trigger should not automatically cancel the decision; it starts a check of the facts. The old record stays as history until people with the authority decide to replace it.
Full example: store bookings relationally
What follows is an invented teaching ADR. All names, requirements and numbers in it were created for the example. It is not a description of a real product and not a claim about measured load.
# ADR-0007. Store confirmed bookings in a relational database
Assessment date: 2026-04-12
Status: proposed
Approval owners: booking team and product owner
## Context
The teaching booking service stores time slots and customer confirmations. Two requests must not be able to take the last place at the same time.
The example assumes one region and one canonical record per booking; this must be verified before a real product launches. The owner also wants a history of changes, but the choice of a store for current state does not provide one. Task `DATA-HISTORY-01` must define the events, access and retention period; for now this is an open question. Requirements for analytics outside the application have not yet been set.
The record and its status must stay understandable to the on-call team. There are no measurements that would justify a distributed data store or manual sharding of the data.
## Options considered
1. A relational database with a transaction and an integrity constraint.
2. A document store as the primary place of record.
3. Keep the current table in a file and synchronise changes later.
## Decision
Propose a relational database as the canonical store for confirmed bookings. The operation must check availability and take the place within one transactional boundary; the specific mechanism is to be verified for the chosen database and code.
This choice does not solve history storage. The ADR stays proposed until `DATA-HISTORY-01` is defined or the product owner explicitly approves postponing that requirement.
## Why this option fits the context
The relational model lets us express uniqueness and the link between a booking and its slot right next to the data. A transactional operation creates a boundary where the team can require that two competing attempts do not confirm the same last slot. This is an argument about fitness for a specific requirement, not a claim that all relational systems are configured the same way or that any code is automatically protected from a race.
A document database can also support transactions and constraints; the option is not rejected just because of the technology's name. In the teaching context, the team already has experience with a relational store, while the document option would require separately checking the concurrent-write boundary offered by a specific vendor and the queries we need. A file with deferred synchronisation would need an additional coordination mechanism, because on its own it does not protect simultaneous confirmations across several processes.
## Consequences
Positive: the booking and the last-place rule share one transactional boundary. Negative: the team maintains a schema, and the write components depend on one contract.
Before launch, the team must define backups, a recovery time objective and a way to verify a restored copy. It also tests the concurrency scenario for the specific database and code: if reading availability and committing the booking happen in different transactions, the claimed protection will not work. The ADR itself creates no guarantee and does not replace an operational recovery procedure.
Change history does not appear automatically from the choice of database. Task `DATA-HISTORY-01` must define the events, access and retention period; any postponement is approved separately by the product owner.
## Revisit condition and links
Revisit this ADR if writes must become active in several regions, if new requirements for independent data distribution appear, or if measurements show that the current store cannot meet confirmed targets. Exceeding a number from the invented teaching assumption is not, on its own, a production signal.
Link this record to the requirement to prevent double booking, the booking service SAD, the task implementing the transactional operation, the separate task `DATA-HISTORY-01`, the pull request and the backup verification procedure.
The data models and concurrent writes that this record refers to are explained in Data Architecture.
Full example: do not split out a notification service yet
Deliberately keeping the current structure can also be an architectural decision. The absence of a new boundary does not mean the team forgot about the problem. What follows is an invented teaching ADR; the dates, names and load do not describe a real product.
# ADR-0009. Keep notifications as a module of the booking application for now
Assessment date: 2026-04-12
Status: proposed
Approval owners: booking team and operations owner
## Context
The teaching application sends the customer a confirmation after a booking is created. In this example, the current volume is one email after each successful operation. The team wants to avoid losing confirmations, but has no separate team to operate notifications. We have not yet measured the volume of retries, the vendor's latency or the work needed for independent scaling. All numbers and the situation are invented for teaching.
## Options considered
1. Keep sending as a module inside the booking application, and durably store unsent events for reprocessing.
2. Split out a separate notification service now.
3. Send no automatic message and rely on the confirmation page.
## Decision
Propose keeping notification composition and tracking in the same application that writes the booking. After confirmation, store the sending job so that a failure of the mail vendor does not cancel the booking itself. Do not introduce a separate deployment until the revisit conditions of this record are met.
## Comparison
The current module serves one channel and one team; it creates no new network boundary or on-call procedure. Its weak point is that changes to the application can touch the sending code, and scaling the module separately from the rest of the application is not yet possible.
A separate service could have its own pace of change and scaling, but neither a separate team nor such load has been confirmed. The option adds a deployment, a network contract, monitoring, retry management and disaster recovery. The team will postpone this cost until it sees a reason to carry it; this is not a claim that a separate service will never be needed.
Dropping the message is indeed technically simpler still, but it does not meet the agreed requirement to give the customer an email confirmation. We do not choose it, not because of technological weakness, but because it does not fit the product's need.
## Consequences
Positive: the booking and the queuing of the notification job stay together, so the team has one path for changes and one deployment procedure.
Negative: the application is responsible for both booking and resending messages. A vendor outage can create backlogged jobs that will need to be monitored and cleaned up.
Before launch, the team sets the maximum queue size and age, safe retries, an alert and an owner for manual intervention. It also checks that the notification job is stored together with the booking; the ADR itself does not prove this.
## Revisit condition and links
Return to the decision if confirmed measurements show that sending competes for resources with writing bookings; if the product adds several independent channels with their own availability requirements; or if a separate responsible team appears that can operate the service around the clock. The operations owner should review queue metrics and incidents at the scheduled architecture review.
Link this record to the confirmation requirement; describe the reprocessing steps in the operational runbook.
How a decision changes without erasing history

A year later the facts, the requirements or the team itself may have changed. That does not make the earlier decision meaningless in hindsight. It was an answer to the context of its time. The team should keep it and record the new reason that changed the direction.
Let's continue the purely teaching notification example. A year later, the notional team has confirmed three circumstances: email and text-message notifications need to evolve independently; measurements point to sending delays that interfere with the product's constraints; and a team with an on-call rotation now exists to own a separate component. It is these new, verified facts — not the calendar on its own — that give grounds to revisit ADR-0009.
In this scenario the team writes a new record, for example ADR-0012:
# ADR-0012. Split notification delivery into a separate service
Assessment date: 2027-04-18
Status: proposed
Supersedes: ADR-0009, if this record is accepted
Approval owners: notifications team, booking team and product owner
## Context
Since ADR-0009, the product has added independent email and text-message channels. In this teaching scenario, over six weeks the team recorded sending delays that interfere with the agreed confirmation time. A separate team with a defined on-call rotation has appeared. These facts and measurements are invented for the example; before a real decision, links to verified reports must be added.
## Options considered
1. Keep the module in the main application and optimise shared resources.
2. Split out a separate delivery service with a clear contract and owner.
3. Hand sending over entirely to a managed vendor, with no queue of our own.
## Decision
Propose a separate service boundary for notification delivery, leaving booking writes in the booking service. The booking service publishes a job after a successful operation; the delivery service is responsible for the delivery attempt, tracking the result and the agreed retry policy. The exact contract, protection against duplicate effects and the failure mode are to be agreed before implementation. This ADR does not change status until the responsible people have accepted the proposal.
## Why we are revisiting ADR-0009
The earlier decision kept a simpler operational model when there was one channel and no separate owner. Now the channel requirements and confirmed latency data have changed the circumstances. The new choice adds a distributed boundary and operational costs, but lets a dedicated team change and monitor delivery on its own. The team re-examined the old arguments rather than rewriting them as if the service had obviously been necessary all along.
## Consequences, commitments and links
Positive: separate channels and telemetry; less impact of delivery delays on booking writes. Costs: a network contract, more deployable parts, a new on-call procedure, and monitoring of consistency between requested and delivered messages.
Before launch, the owners define retries, the queue limit, alerts and recovery. A separate team does not, by itself, guarantee isolation or reliability.
If ADR-0012 is accepted, mark ADR-0009 as superseded without erasing its history. Link the records to each other in both directions and update the current requirement and SAD.
The lifecycle and preservation of a record

Statuses should briefly explain what happened to a proposal. A team might use this convention:
- Proposed — the text is still under discussion; it does not allow the choice to be treated as agreed.
- Accepted — the named decision owners have approved the direction according to the team's process.
- Rejected — the proposal was considered and not chosen; the reason for rejection remains available.
- Deprecated — conditions have changed, or the owners decided to stop relying on the record; explain whether a current replacement exists.
- Superseded — another ADR describes the new decision; name its number and link back.
This is an example status vocabulary, not a mandatory external classification (MADR, Nygard on ADR status). In a small project three values are enough; in a regulated one you may need separate statuses for approval, entry into force and completion of implementation. Explain your local terms, and do not change a status just because code has appeared or because the file has not been edited for a long time.
A decision can pass through separate stages: the proposal is discussed; a responsible person approves it; implementation begins; the changes go into production; later, a new context forces a review. An ADR's status describes the decision itself, according to the team's rules. A task tracks the work, and a release or deployment system tracks the actual rollout. One label should not pretend to stand for all of these facts.
Do not rewrite an accepted ADR as if the team had always had the new knowledge. If you fix a typo or add a link, the version history will show the clarification. If the choice itself has changed, create a new record: state briefly what it supersedes; record the new context, alternatives and consequences; and, once approved, mark the previous record as superseded. Do not delete the old one, and do not reuse its number for another decision. This kind of history helps you tell an implementation mistake apart from a deliberate change of direction.
Nygard advised keeping the earlier ADR and marking it superseded rather than throwing it away. Real logs also show partial supersession: in the pinned decision log of the Model Context Protocol (MCP), a record dated 16 April 2026 marks the URI (Uniform Resource Identifier) rules as "partially superseded", because individual rules changed while the structure stayed the same. A record dated 16 July narrows the first version of the extension and explicitly lists which rules were replaced and which were kept (decision on the URI scheme, decision on the first version). This preserves both the history and the exact scope of the change.
Links to requirements, the SAD, tasks and operations

An ADR is a junction between the reason, the description of the system, and the work that carries out the choice. A short chain might look like this:
Requirement 021: do not confirm two bookings for the same last place
→ ADR-0007: use a transactional write in the shared data store
→ SAD, section 4.2: responsibility of the booking container and write boundaries
→ Implementation task: safe schema change and recovery
→ Pull request: implementation and verified concurrency scenarios
→ Operator runbook: backup verification and recovery
The names and numbers here are invented. They show the direction of the links, not real tasks in this course or in any project. An ADR does not copy the linked documents: it is enough to name their role and give a direct link.
Check each link against its purpose. A requirement explains what must be true for the user or the product. An architecture document shows the boundary, the structure and the dependencies. A task has an owner and a piece of work. A pull request explains a specific set of changes. An operations manual guides the operator through normal work or a failure. If a decision changes, update the documents that describe the current state, but keep the historical ADR with a link to its replacement.
The notional abbreviations used for such links: REQ (Requirement) marks a record of expected behaviour; SAD (Software Architecture Document) is the architecture description; A1M is the teaching key of a Jira task; PR (pull request) is a set of changes submitted for review; RUN (Runbook) marks a procedure for the operator.
In a large log, search should take into account titles, area, owner, status, date and related requirements. A static index or a list by component is more convenient than one file holding dozens of decisions. When the team chooses numbering, names or folders, let the format help preserve links and history. For example, MADR supports sequential numbers in file names, but states explicitly that the folder structure does not have to follow its particular scheme. Do not mix up the features of one tool with the definition of an ADR.
What open examples show
In the version of the ext-skills repository's decision log pinned to commit 81f55b67, there are records of very different lengths. A short accepted record dated 14 February 2026 chooses to keep the documentation as Markdown files in the repository rather than publish it as a separate site. It records the context, a single choice, a few reasons — a low barrier to contribution, no extra infrastructure — and a condition for returning to the topic if the group grows or navigation becomes difficult. It is brief because the scope of the decision and the trade-off are narrow (the record on the documentation format).
A decision dated 16 March 2026 in the same log is much more detailed. It analyses a proposal submitted through pull request (PR) #60, the feedback on it, the risk of duplicated information, premature optimisation, an alternative place for semantic data, the boundaries of a future namespace and the sources for verification. Its length is justified by several interrelated boundaries and the consequences for extending the protocol. Both records are marked "accepted", but neither length is a recipe for every team (the record on metadata, PR #60 discussion).
These examples do not prove that the chosen approaches are best for other products. They show how the authors tied decisions to the constraints they had and to a possible future review. A URL containing the commit hash pins exactly the text of the log we are analysing; a link to the current branch could show a different version.
MADR also keeps its own decision to "add a status field". In it, the maintainers compare ways of marking status — metadata, a badge, a line of text, a heading, a table — and describe the pros and cons of each. The example itself has no explicit status field in the body of that decision page; do not mistake it for mandatory compliance with a newer template. It is a useful illustration that format rules are decisions too, but that the format and its historical records evolve (MADR: decision on the status field).
How an agent should work with the decision log
An agent that changes code should first read the agreements currently in force. This reduces the risk of repeating a proposal that was already rejected, or of changing a system boundary without a known argument. At the same time, the existence of a text file does not entitle the model to assume that every record has been accepted. The agent checks the status, the date, any link to a superseding record, and whether the context matches the current task.
For a tool-using agent, the following order is useful:
- Find the pointer to the log and the ADR directories; review the files related to the system or component in the task.
- For each candidate, check its status, last update, any superseding ADR, its sources and the decision owner.
- Separate an accepted direction from a proposal, a rejected choice, an outdated description and an unconfirmed implementation.
- Compare the ADR's context with the task: are the requirements, constraints, environment, load, vendor and system boundary the same?
- If the planned change contradicts an accepted decision, explain the conflict, name the exact record and put it to the responsible owner for review. Do not quietly rewrite the implementation or the status.
- If the change requires a new significant choice, prepare a draft ADR with genuine alternatives, explicitly marked unknowns, consequences and links.
- Leave the status as "proposed" until an authorised person approves the decision through the team's process. Report separately what has been implemented and what is still awaiting a decision.
The absence of a relevant ADR does not prove that an architectural choice is open or automatically approved. The agent must establish the facts in the code, the documents and the project history, and separate them from assumptions. If a record's currency cannot be confirmed, that is a reason to flag the uncertainty, not to invent a review date.
An AI (artificial intelligence) agent can plan several steps and propose a tool call, but the action is carried out by the client application or the vendor's service. OpenAI's documentation describes agents that plan and carry out tasks with tools and keep context between steps. In Claude Managed Agents, the always_ask policy pauses an action for human confirmation, and under auto the evaluation can also return ask or deny. These are mechanisms of specific APIs, not ADR approval: status is set by the project owner's process (OpenAI agents documentation, Claude Platform: how tool use works, Claude Managed Agents: permission policies).
A practical way to phrase the task for an agent:
Before changing code, find the decisions related to the component and check their statuses, dates and links to superseding records. Compare the decisions' context with the task requirements and name any possible contradictions, with links to the files. Do not change an ADR's status and do not present a draft as approved. If a new significant decision is needed, propose a separate ADR with alternatives, consequences and unknowns, and get the responsible owner's approval before making any change that violates an accepted decision in force.
This rule concerns the architecture process, not every action the agent takes. Each change must separately respect access boundaries, permissions, repository instructions and security rules. The text of an ADR cannot widen those powers, switch off safeguards or turn an unknown into a fact. The agent should quote the record it read, report uncertainty, and leave the authoritative decision to the responsible person.
Common mistakes
Recording only the outcome. "We chose PostgreSQL" does not help anyone understand which problem was being solved. Add the drivers, alternatives and trade-offs; do not rewrite the product documentation.
Describing every other option as incapable. This hides the real reason for the choice and makes the document untrustworthy. Compare against the same criteria and explain the rejections.
Turning assumptions into data. Mark a teaching number, an unknown load and a forecast separately from measured facts with a source.
Listing only positive consequences. Every significant choice brings new work or a new dependency. Write it down, name its owner and how it will be monitored.
Calling a proposed decision accepted on the owner's behalf. Record the process, who approves, and what evidence shows the approval.
Confusing accepted with deployed. Approving a direction does not confirm that the task is finished, that it is running in production, or that recovery has been tested.
Editing the past after the context changes. Keep the old reasoning, create a new ADR and link them. Later facts do not prove that the original choice was careless.
Keeping a procedure in the wrong place. An ADR explains the motive; the exact steps for backup, migration or recovery belong in an operational runbook and must remain executable.
Creating an ADR for every change. An excess of records buries the more important decisions. For a local fix, a description of the change and its reason is usually enough.
Treating the format as a guarantee of quality. Filled-in headings do not prove that the alternatives were honest or that a number is true. The owner must check the claims, the authority and the current context.
Summary
An ADR preserves one significant architectural decision and the reasoning that the code may not explain. A good record separates facts, assumptions, constraints, alternatives, the choice, the consequences and the revisit condition. The template should be small enough to maintain but specific enough to check later. Its status, its approval and its implementation are different things. When the team changes direction, it keeps the earlier history and creates a new record that links to what it supersedes. An agent first finds the decisions currently in force, explains conflicts and may prepare a proposal; the responsible person decides on it according to the team's rules.
Sources and further reading
Materials were checked on 23 September 2026. The dates and statuses of the public examples below belong to the text of the log or its pinned version; they are not independent confirmation of the implementation state of third-party systems.
- Michael Nygard. Documenting Architecture Decisions, 15 November 2011. The original text on modularity, context, decision, status, consequences, and keeping a record after it has been superseded.
- Architectural Decision Records, adr.github.io. Definition of an architectural decision and an ADR, the decision log, and the community's reference links.
- MADR: Markdown Architectural Decision Records. Description and the full, variable template; used as an alternative to Nygard's short format, not as a universal norm.
- MADR decision 0008: Add Status Field. An example in which the authors compare several ways of showing status. The body of this historical record has no explicit status of its own.
- Model Context Protocol, ext-skills contributors. Decision log at commit 81f55b67. Used: the accepted records of 14 February and 16 March, the partially superseded record of 16 April, and the accepted decision on the first version of 16 July 2026; statuses and wording were analysed only in this version of the file.
- Model Context Protocol, ext-skills contributors. PR #60. History of the metadata proposal referenced by the ADR of 16 March 2026.
- Neal Ford, Mark Richards, Pramod Sadalage, Zhamak Dehghani. Software Architecture: The Hard Parts, O'Reilly Media, 2021. Neal Ford's bibliographic page. Checked for authors, publisher, subject of the book and its emphasis on trade-offs; the full text of the book was not used, and no pages or quotations are attributed.
- OpenAI. Agents API: official guide. Used to describe the context, tools and limits of agentic systems; the guide does not define an ADR approval process.
- Anthropic. How tool use works, Claude Platform documentation; checked 23 September 2026. Distinguishes tools executed by the client application from the vendor's server-side tools.
- Anthropic. Permission policies, Claude Managed Agents documentation; checked 23 September 2026. Distinguishes the policy types
always_allow,always_askandauto, and the evaluation resultsallow,askanddeny; underask, a call may wait for human confirmation. This is an API-specific beta feature, not a universal policy for all agents.