ADR in simple words: how to fix architectural solutions so that AI does not break the project
Main chat
A chat for vibe coders: news, guides, live cases, marketplace, and finding executors.
Imagine a project where the team stores basic data in PostgreSQL, uses Redis only as a cache, and sends external notifications through a queue. This is not a random set of technologies. Perhaps PostgreSQL was chosen because of transactions, Redis was banned as a source of truth after data loss, and the queue appeared because of an unstable partner API.
Six months later, a new developer or AI agent is connected to the project. It only sees the current code. The reasons for the decisions are unknown to him.
The agent gets the task to speed up the endpoint and suggests:
- transfer the order status to Redis;
- call the partner API directly from the HTTP request;
- remove the “extra” queue;
- combine two similar adapters;
- replace PostgreSQL with a simpler base.
Each sentence can appear logical within a single file. But it violates limitations the team has already discovered in practice.
The problem is not that AI is bad at writing code. The problem is that the code stores the result of the decision, but does not store the course of reasoning.
There are ADRs for that.
**ADR, or Architecture Decision Record, is a short document that captures one significant architectural solution, its context, options and implications. **
ADR answers not only the question of “what we chose,” but also more important questions:
- what problem was solved;
- what restrictions were taken into account;
- what alternatives were considered;
- why did you accept this particular option;
- what price and risk are you consciously taking;
- when the decision needs to be reconsidered.
For development with AI, this is one of the most useful types of documentation. README explains how to start a project. The code shows the current implementation. AGENTS.md sets the rules of operation. ADR explains why architectural boundaries look like this.
What is Architecture Decision Record
The term ADR is commonly associated with Michael Nygard and his paper Documenting Architecture Decisions. The idea is simple: architecturally significant decisions should be stored as small immutable records next to the project.
One file describes one solution. For example:
docs/adr/
├── 0001-use-postgresql-as-source-of-truth.md
├── 0002-send-webhooks-through-outbox.md
├── 0003-isolate-ai-providers-behind-gateway.md
└── 0004-store-user-files-in-s3.md
The ADR does not have to be long. A good record can often be read in two minutes. Its value is not in volume, but in preserved context.
A typical ADR contains:
- Title of the decision.
- Status.
- Context and problem.
- Decision made.
- The consequences.
- Alternatives considered.
**ADR describes the solution, not the entire system.
Why One Code Is Not Enough
Let’s say the project has an interface:
interface TextGenerator {
generate(input: GenerateInput): Promise<GenerateResult>;
}
And two implementations:
class OpenAiTextGenerator implements TextGenerator {}
class LocalTextGenerator implements TextGenerator {}
The code shows that providers are isolated by a common contract. But it is impossible to reliably understand why this was done.
Possible causes:
- the company must be able to disable the external API;
- some data cannot be sent to the cloud;
- the cost of models changes regularly;
- you need a fallback if the provider fails;
- different customers use different models;
- the team has already experienced a complex migration of the SDK.
Without these reasons, an AI agent may decide that the interface is redundant and replace it with a direct SDK call. Tests will remain green, the task will be closed, and important architectural protection will disappear.
Comments in code don’t solve the problem completely either. The commentary explains the local fragment. An architectural solution typically involves multiple modules, infrastructure, operation, and future constraints.
ADR retains the relationship between the problem and the chosen boundary.
What solutions really deserve ADR
There is no need to document each variable and library. ADR is useful for solutions that:
- expensive to cancel;
- affect several parts of the system;
- define a long-term boundary;
- are associated with a noticeable compromise;
- limit future implementations;
- it may cause a dispute again in a few months;
- they look strange without context.
Good candidates:
- selection of the main database;
- rules of separation of monolith and services;
- method of authentication and storage of sessions;
- synchronous or asynchronous event processing;
- public API format;
- multitenant strategy;
- the choice of the source of truth;
- rules for the storage of personal data;
- the boundary between domain logic and external integrations;
- use AI Gateway instead of direct model calls;
- the strategy of deployment and backward compatibility of migrations.
Bad candidates:
- rename the local function;
- selection of the variable name;
- code formatting;
- a small library that can be easily replaced;
- temporary experimentation without affecting the rest of the system;
- the solution is already obvious from the project standards.
Simple filter:
If, after six months, an intelligent developer can remove or modify this design without understanding its underlying cause, the solution is worth fixing.
Finished ADR template
There is no universal mandatory format. For most projects, this template is sufficient:
# ADR-0007: Use PostgreSQL as a source of truth for orders
- Status: accepted
- Date: 2026-07-11
- Authors: backend team
#Context
What problem are we solving? What restrictions, risks and requirements are important?
##The decision
What exactly did you decide to do? Where is the boundary of the solution?
##The consequences
What are the benefits? What are the limitations and limitations?
## Alternatives
What options were considered and why not chosen?
## Conditions of revision
Under what circumstances or changes should the decision be reopened?
The last section is optional, but especially useful. It turns an architectural solution from a dogma into a testable hypothesis.
For example:
## Conditions of revision
Review the decision if:
The volume of records will exceed 50,000 events per second;
- there will be a requirement for autonomous operation without a central database;
the cost of operation will exceed the agreed budget;
PostgreSQL will no longer meet latency requirements after optimization.
Now the future developer understands not only the ban, but also the conditions under which it can be reasonably removed.
A complete example of ADR for an AI project
Consider the decision to isolate model vendors behind an internal interface.
ADR-0003: Isolate AI providers behind the internal gateway
- Status: accepted
- Date: 2026-07-11
#Context
The application uses text generation in three scenarios. Now the code is direct.
It depends on the SDK of one provider. Error format, tool calls and streaming
It spread across business modules.
We need to keep the opportunity:
Change the model without rewriting business logic.
Send sensitive queries to the local model
Add fallback if the main provider is unavailable;
- centrally consider cost, timeouts and traceability.
##The decision
Business modules depend on the internal `TextGenerator` interface.
SDK providers are only allowed inside `infrastructure/ai/providers`.
Gateway normalizes responses, errors, and metrics, but does not contain business prompts.
##The consequences
Positive:
Details of the SDK do not apply to the project;
Providers are replaced locally.
Tests do not require an external API.
Costs and errors occur in one place.
Negative:
- the internal contract will have to be developed;
Not all unique capabilities of the provider are convenient to normalize;
The gateway becomes a critical part of the system.
## Alternatives
1. Direct SDK calls in every scenario: easier at the start, but more connected.
2. External universal proxy: speeds up integration but adds dependency
from a separate service and does not decide the rules for routing the domain.
## Conditions of revision
Revise if the app is left with one provider and one script
The cost of gateway support will be higher than the cost of direct integration.
Such a document gives the AI agent important information. It can change the implementation of a specific adapter, but it doesn’t have to transfer the SDK to business modules without a new architectural solution.
ADR Status and Decision Life Cycle
ADR should not disappear after the architecture changes. The old document preserves history and receives a new status.
Four statuses are usually sufficient:
| Статус | Значение |
|---|---|
proposed |
Решение предложено и обсуждается |
accepted |
Решение принято и действует |
deprecated |
Решение больше не рекомендуется, но еще встречается в системе |
superseded |
Решение заменено другим ADR |
Some commands add rejected for important rejected variants. This is useful if the same argument returns regularly.
Example of substitution:
ADR-0003: Isolate AI providers behind the internal gateway
Status: replaced by ADR-0014
The new document should refer to the old:
ADR-0014: Transfer routing of AI requests to an external gateway
- Status: accepted
- Replaces: ADR-0003
Don’t rewrite the old ADR as if the team always knew the right answer. The value of writing is precisely in preserving the context at the time of decision.
ADR, README, AGENTS.md and Memory Bank
These files solve different tasks.
| Документ | Главный вопрос |
|---|---|
README.md |
Как понять, запустить и использовать проект? |
AGENTS.md |
Как AI-агент должен работать в этом репозитории? |
| Memory Bank | Каков текущий контекст, состояние и ближайшие цели проекта? |
| ADR | Почему принято конкретное архитектурное решение? |
| Task или issue | Что нужно изменить сейчас? |
Example of distribution:
README.md:
The main database of the project is PostgreSQL.
AGENTS.md:
Do not add other permanent repositories without architectural approval.
Before changing the data layer, read docs/adr/0001-use-postgresql.md.
ADR:
PostgreSQL is chosen as the source of truth because of transactions between orders.
Payment and transaction log. Redis is used only as a recoverable cache.
Memory Bank:
Now the payment table is being moved to a new scheme.
The dual write step is included in dev.
You don’t need to copy the same long text into all documents. Short rules and references to the source of context are enough.
More information about the rules of the repository is described in the material «AGENTS.md: единый источник истины для ИИ-агентов», and about the current context in the article про Memory Bank.
How to organize ADR in a repository
For a small project, a simple structure is enough:
docs/
└── adr/
├── README.md
├── 0001-use-postgresql.md
├── 0002-use-s3-for-user-files.md
└── 0003-isolate-ai-providers.md
In docs/adr/README.md, it is convenient to store the index:
Architecture Decision Records
| ADR | Decision | Status |
|---|---|---|
| [0001](./0001-use-postgresql.md) | PostgreSQL as the source of truth | adopted |
| [0002](./0002-use-s3-for-user-files.md) | S3 for user files | accepted |
| [0003](./0003-isolate-ai-providers.md) | Gateway for AI providers | adopted |
Rules of practice:
- use consecutive numbers;
- keep one question in one file;
- write the title as an accepted action, not as a general topic;
- add ADR to the same pull request where the solution is implemented;
- appoint the owner or participants of the discussion;
- do not delete the replaced records;
- link the new ADR to the old one;
- keep documents next to the code and check through regular code review.
The name 0007-database.md is too broad. The name 0007-use-postgresql-as-order-source-of-truth.md immediately communicates the essence and boundary of the solution.
How to Connect ADR to an AI Agent
Simply putting documents in a repository is not enough. The agent may not open them if the task appears local.
In the global or project instructions, you need to add a reading route:
## Architectural solutions
Before changing architecture, storage, queues, API contracts,
For authentication or AI integration, see `docs/adr/README.md`.
Existing ADRs take precedence over assumptions from current code.
Do not violate the ADR with `accepted` status without explicitly offering a new ADR.
For a meaningful solution, first create an ADR with `proposed` status.
Don’t rewrite history: Replace the solution with a new ADR with reciprocal links.
It is also helpful to require the agent to name the affected decisions before editing:
Prior to implementation:
1. Find the ADRs associated with the task.
2. We briefly listed the limitations of these.
3. Indicate whether the proposed plan is consistent with the current decisions.
4. If a conflict arises, stop changing the architecture and propose a new ADR.
This reduces the risk of quiet architectural drift, where each individual change looks reasonable, but the system gradually loses its original boundaries.
How to take ADR with AI
AI is useful not only as a reader, but also as an assistant in preparing a solution. However, you can’t just ask a model to choose the best architecture. It needs to be given criteria and forced to show compromises.
Working request:
Prepare an ADR with proposed status.
Problem: You need to choose how to deliver payment events to an external CRM.
First:
Gather restrictions from code, documentation, and existing ADRs.
- list the decision drivers;
offer at least three realistic options;
- for each assessment reliability, complexity, cost, observability,
Reversibility and impact on current architecture;
Separately listed unknown facts that can change the choice.
Do not choose the option until you show a comparison table.
Once selected, fill in the context, decision, consequences, alternatives
and the terms of the review.
Especially important is the list of unknown facts. AI tends to confidently fill in gaps with assumptions. A good ADR should separate proven limitations from guesswork.
What to Write in Consequences
Weak ADR looks like this:
##The consequences
The architecture will become more reliable and scalable.
It means nothing and does not help the future decision.
Consequences should be specific:
##The consequences
Positive:
An HTTP request is no longer dependent on CRM availability.
Unsent events persist after restart;
Re-delivery is controlled by the idempotency key.
Negative:
- a background worker appears;
Delivery becomes eventual consistent;
- queue monitoring and reprocessing procedure are required;
The order of events for one client will have to be provided separately.
Architecture almost always trades one kind of complexity for another. If the decision has no negative consequences, the author either has not finished the analysis, or writes advertising text instead of ADR.
Frequent errors in ADR management
The decision is recorded after implementation
A document is often used as an excuse for already written code. It is better to create a proposed ADR before a major change and take it along with the implementation plan.
There are no alternatives to ADR
Without alternatives, it is impossible to know whether the choice was conscious. Two or three realistic options with a short explanation are enough.
Only the positive side is recorded
Every architectural solution has a price: delay, complexity of operation, dependency, cost of migration or limitation of opportunities.
One file describes the entire architecture
A large document quickly becomes obsolete and shows history poorly. ADR should be small and dedicated to one solution.
Old records are deleted or rewritten
As a result, the team loses the reasons for the past changes and again discusses the already rejected options.
ADR to be made law forever
An architectural solution works in a specific context. If the context has changed, create a new ADR and replace the old one.
The agent was not told where to look for solutions
Having a docs/adr folder does not guarantee that the model will read it before the local task. The route must be recorded in AGENTS.md or similar instructions.
When ADR won't help
ADR does not replace:
- tests;
- data schemes;
- API specifications;
- runbook for operation;
- tasks and acceptance criteria;
- current code;
- discussion with system owners.
It fixes the decision, but does not prove that the implementation complies with it. If the ADR says “Redis only cache” and the new module stores a single copy of the order, the document itself will not stop anything.
It is useful to add automatic checks where the rule can be formalized. For example, an architecture test may prohibit the import of an AI provider SDK outside the adapter directory. The ADR explains the cause and the test provides the boundary.
Minimal process without bureaucracy
For a small team or personal project, five steps are enough:
- Notice a decision that is expensive to reverse or easy to misunderstand.
- Create a short ADR with
proposedstatus. - Compare alternatives and clearly write down compromises.
- Accept ADR in the same pull request where implementation begins.
- When changing context, create a new ADR and mark the old one as
superseded.
No architectural committee, separate knowledge base or lengthy coordination is required. A single Markdown file on a solution already retains more context than chat correspondence that no one will find in six months.
Checklist of a good ADR
Before accepting the entry, check:
- the title indicates a specific decision;
- the context describes the problem, not the answer;
- requirements are separated from assumptions;
- real alternatives are listed;
- it is clear why this option was chosen;
- positive and negative consequences are recorded;
- the scope of the decision is indicated;
- there are conditions for review;
- the new ADR does not conflict with the existing one without an explicit replacement;
- implementation and testing may be related to the solution;
- An AI agent knows when to read this document.
Frequent questions
What is ADR in simple words?
ADR is a short file that explains one important architectural solution: what problem was solved, what was chosen, what alternatives were rejected, and what consequences were taken.
How does ADR decipher?
ADR stands for Architecture Decision Record, a record of an architectural solution. This is sometimes referred to as the Architecture Decision Log.
Where to store ADR?
For most projects, it is convenient to store ADR next to the code in the docs/adr directory. The documents are then versioned by Git, code reviewed, and available to the AI agent in the same working context.
When should I create an ADR?
ADR is needed for a meaningful, long-term, or cost-effective solution: base selection, service boundary, authentication model, delivery mode, source of truth, or isolation of an external API.
Do I need to update my old ADRs?
Actual typos can be corrected, but the history of the decision is better not to rewrite. If the context has changed, create a new ADR, mark the old as superseded, and link documents with links.
How is ADR different from the technical task?
The technical task describes the required result of a specific work. ADR captures architectural choices and their causes, which can influence many future tasks.
How is ADR useful for AI agents?
The AI agent sees the code, but does not know the history of the discussions and hidden limitations. ADR gives it the reasons for existing boundaries and reduces the risk of removing an important structure as "extra.".
Main conclusion
Architecture is not only destroyed by bad decisions. It also breaks down because good decisions lose their explanation over time.
The code tells you that the system uses a queue. ADR explains that the queue appeared after the loss of webhook when the partner crashed. The code shows the AI-gateway interface. ADR retains privacy, fallback, and cost requirements. The code can be rewritten in one request to the agent. Context without a separate record is much more difficult to restore.
A good ADR does not try to predict the future. He honestly fixes the current problem, the compromise chosen and the conditions under which the solution will no longer be correct.
Start with a single file for the most important project solution. Add a link to it in AGENTS.md and require the AI agent to check valid ADRs before architectural changes. That’s enough for decisions to experience changes in people, tools, and models.
** Main sources:**