Зачем это нужно
В прошлом уроке мы описали architecture как набор границ и разрешенных решений. Но архитектурные правила не появляются из воздуха. В какой-то момент команда выбирает подход: как хранить token, как строить auth, где проходит boundary, какой messaging pattern использовать, какие зависимости запрещены.
Если решение не зафиксировать, следующий агент может предложить противоположный подход. Еще хуже: он может сделать это уверенно и с хорошими аргументами, потому что не знает историю выбора.
ADR - Architecture Decision Record - нужен, чтобы важные решения переживали chat history, agent runs и смену контекста.
Основная идея
ADR - это короткий документ, который фиксирует одно архитектурное решение:
- в каком контексте оно принято;
- какое решение выбрано;
- какие альтернативы рассматривались;
- какие последствия команда принимает;
- каков статус решения.
Пример:
ADR-001: Authentication tokens
Status:
Accepted
Decision:
Используем short-lived JWT access token
и server-side refresh token.
Alternatives:
- session cookies
- long-lived JWT
Consequences:
- access token можно проверять stateless;
- refresh token можно отозвать server-side;
- нужна таблица refresh tokens;
- logout должен инвалидировать refresh token.
ADR не заменяет architecture document. Он объясняет, почему архитектура стала такой.
Ключевые термины
| Термин | Значение |
|---|---|
| ADR | Architecture Decision Record: запись одного важного архитектурного решения. |
| Context | Проблема, ограничения и обстоятельства, из-за которых нужно решение. |
| Decision | Выбранный подход. |
| Alternatives | Рассмотренные, но не выбранные варианты. |
| Consequences | Последствия решения: плюсы, минусы, новые обязанности. |
| Status | Состояние ADR: proposed, accepted, deprecated, superseded. |
| Supersedes | Указывает, что новый ADR заменяет старый. |
| Decision Log | Набор ADR, который показывает историю архитектурных выборов. |
Почему ADR особенно полезен для AI agents
Человек может помнить:
Мы уже обсуждали long-lived JWT и отказались от него из-за revocation.
Агент в новой сессии этого не знает.
Если ADR отсутствует, agent может:
- предложить long-lived JWT снова;
- добавить второй способ хранения token;
- изменить auth flow ради локальной задачи;
- не понять, почему старый код устроен именно так;
- считать существующее решение accidental complexity.
ADR превращает историю решения в доступный artifact.
Когда агент выполняет task, prompt может ссылаться на ADR:
Соблюдай ADR-001 Authentication tokens.
Не предлагай long-lived JWT.
Это резко снижает вероятность повторного обсуждения уже закрытого выбора.
Минимальный формат ADR
Для курса достаточно простого шаблона:
# ADR-001: <Title>
## Status
Proposed | Accepted | Deprecated | Superseded
## Context
Какую проблему решаем?
Какие ограничения важны?
Почему решение нужно сейчас?
## Decision
Какой подход выбран?
## Alternatives
Какие варианты рассматривались?
Почему они не выбраны?
## Consequences
Что становится проще?
Что становится сложнее?
Какие новые constraints появляются?
## References
- Related specs
- Related tasks
- Related docs
Правило: один ADR - одно решение. Если документ пытается решить сразу auth, billing, messaging и deployment, он становится слишком широким.
Статусы ADR
| Status | Когда использовать |
|---|---|
| Proposed | Решение предложено, но еще не утверждено. |
| Accepted | Решение принято и должно соблюдаться. |
| Deprecated | Решение больше не рекомендуется, но может еще встречаться в системе. |
| Superseded | Решение заменено новым ADR. |
Пример:
ADR-001: Use JWT access tokens
Status: Superseded by ADR-007
Нельзя молча переписывать историю. Если решение изменилось, лучше создать новый ADR или явно отметить, чем оно заменено.
Какие решения стоит фиксировать
Не каждое изменение требует ADR. ADR нужен, когда решение:
- влияет на несколько модулей;
- меняет dependency direction;
- задает security model;
- выбирает persistence или messaging approach;
- создает долгосрочные constraints;
- будет важно future agents и reviewers;
- дорого откатывать.
Примеры решений для ADR:
| Решение | Почему ADR нужен |
|---|---|
| Access/refresh token strategy | Влияет на auth, security, logout, sessions. |
| Password reset token storage | Влияет на security, DB model, tests. |
| Event-driven notifications | Влияет на architecture flow и reliability. |
| API error format | Влияет на все endpoints и clients. |
| Multi-tenant authorization boundary | Влияет на security всей системы. |
Решения, которым обычно не нужен ADR:
- переименование локальной функции;
- добавление одного unit test;
- мелкое UI copy;
- refactor без изменения architecture constraints;
- исправление isolated bug.
Пример ADR: Password Reset Token
# ADR-002: Password Reset Token Storage
## Status
Accepted
## Context
Нужно реализовать password reset. Token будет отправляться пользователю по email.
Если database будет скомпрометирована, raw reset tokens не должны позволять
захватить аккаунты.
Feature spec требует:
- token действует 15 минут;
- token одноразовый;
- unknown email не раскрывается;
- successful reset пишет audit event.
## Decision
Храним в database только hash reset token.
Raw token показывается пользователю только в reset link.
При подтверждении reset password API хеширует присланный token
и ищет matching active token.
## Alternatives
### Store raw token in database
Проще реализовать и отлаживать, но при утечке database reset tokens можно использовать напрямую.
### Use signed stateless token
Не требует database lookup, но сложнее обеспечить одноразовость и принудительное revocation.
## Consequences
Плюсы:
- database leak не раскрывает usable reset tokens;
- можно отметить token consumed;
- можно отзывать активные tokens.
Минусы:
- нужен repository для token hash lookup;
- нужно аккуратно сравнивать hash;
- нужны tests для expired, consumed и invalid token.
## References
- `specs/password-reset/spec.md`
- `docs/architecture/architecture.md`
Такой ADR помогает агенту не предложить raw token storage через несколько задач.
ADR в workflow курса
ADR появляется не вместо specification, а рядом с ней.
Feature spec:
Что должно работать?
ADR:
Какое важное architecture decision принято?
Design:
Как применить spec + ADR в конкретной реализации?
Task:
Какое маленькое изменение сделать сейчас?
Ссылки должны идти в обе стороны:
spec.md -> mentions relevant ADR
design.md -> uses ADR decision
task.md -> lists ADR as input
review -> checks ADR compliance
Для Password Reset:
spec.md:
Token одноразовый, TTL 15 минут.
ADR:
Token хранится в hashed form в database.
design.md:
ResetTokenRepository ищет token по hash.
task:
Do not store raw reset token.
Практика: написать ADR
Создайте файл:
docs/architecture/adr/ADR-001-password-reset-token-storage.md
Тема:
Как хранить password reset token?
Минимальные требования:
Status = ProposedилиAccepted;- Context содержит ссылку на Password Reset spec;
- Decision выбирает один подход;
- Alternatives содержит минимум 2 варианта;
- Consequences содержит минимум 3 плюса и 3 trade-offs;
- ADR добавляет минимум 2 constraints для будущих tasks.
В конце выпишите:
Agent task constraints derived from this ADR:
- ...
- ...
Типичные ошибки
Ошибка 1. Писать ADR после того, как все уже забыли
ADR полезнее всего в момент принятия решения. Поздняя реконструкция часто теряет контекст и альтернативы.
Ошибка 2. Фиксировать только выбранный вариант
Без alternatives future agent или developer не поймет, почему очевидный другой путь уже был отвергнут.
Ошибка 3. Не писать consequences
Любое архитектурное решение что-то упрощает и что-то усложняет. Последствия нужно назвать явно.
Ошибка 4. Делать ADR слишком большим
Один ADR должен фиксировать одно решение. Большой документ трудно использовать как context.
Ошибка 5. Не связывать ADR с tasks и review
Если ADR нигде не упоминается после написания, агент может его не увидеть. ADR должен попадать в inputs relevant tasks.
Критерии готовности
После урока студент должен уметь:
- объяснить назначение ADR;
- отличить ADR от feature specification и design document;
- написать ADR с context, decision, alternatives и consequences;
- выбрать подходящий status;
- понять, какие decisions требуют ADR;
- сослаться на ADR из spec/design/task.
Краткое резюме
ADR - это память архитектурных решений. Он фиксирует не только "что выбрали", но и "почему выбрали" и "какие последствия приняли".
Для AI Agent Development ADR особенно важен: агент в новой сессии не помнит прошлые обсуждения. Если decision не записан, он может предложить другой подход и создать architecture drift.
Хороший ADR короткий, конкретный и связан с будущей работой через constraints, references и review.
Вопросы для самопроверки
- Почему ADR полезен именно для работы с AI agents?
- Чем ADR отличается от feature spec?
- Какие статусы ADR стоит использовать в курсе?
- Почему alternatives важны не меньше, чем decision?
- Какие consequences есть у решения хранить reset token только в hashed form?
Что дальше
В следующем уроке мы превратим architecture decisions в проверяемые constraints: docs, project rules, static checks, tests и review checklist. Решение должно не просто лежать в ADR, а реально ограничивать действия агента.