Версионирование решений и ADR#
Версия: 1.4 · 2026-09-22
Зачем#
Документ решения меняется: добавляется дисквалификатор, уточняется ось, пересматривается рыночный слой. ADR, написанный год назад, остаётся верным для своих условий — но читатель не может этого проверить, если не знает, по какому методу он написан.
Версия отвечает на один вопрос: что нужно перепроверить в старом решении, а что можно не трогать. Без неё ответ один — перепроверять всё, то есть на практике не перепроверять вовсе.
Что версионируется#
| Что | Как обозначается | Меняется после публикации |
|---|---|---|
00-template.md — мастер-шаблон |
vX.Y |
Да |
01-adr-template.md — шаблон ADR |
vX.Y плюс совместимость с мастером |
Да |
D-NN — документ решения |
vX.Y плюс совместимость с мастером |
Да |
Рыночный слой внутри D-NN |
Дата съёмки, не номер | Да, пересъёмкой |
ADR-NNNN — принятое решение проекта |
Не версионируется — статус и замена | Нет, см. ниже |
Две цифры, а не три#
- MAJOR (
X) — метод изменился так, что прежнее решение могло бы выйти другим: добавлен или убран дисквалификатор, добавлена или убрана ось, изменился состав обязательных разделов, изменилось правило заполнения. - MINOR (
Y) — формулировки, примеры, пояснения, новые источники, уточнение подсказок «что записывать в ячейку».
Уровня patch нет намеренно: различение «мелкая правка» и «совсем мелкая» не меняет ни одного действия читателя, а спорить о нём можно бесконечно. Это сознательное отступление от Semantic Versioning 2.0.0, где MAJOR определён через несовместимость интерфейса; здесь интерфейса нет, зато есть исход решения, и граница проводится по нему.
Рыночный слой живёт по своим часам. Его актуальность обозначается датой съёмки, а не номером: пересъёмка — это MINOR по методу, но исход она изменить может. Поэтому дата попадает в ADR отдельным полем, рядом с версией документа.
Запись в ADR#
Каждый ADR в поле «Метод» указывает цепочку целиком:
Метод: D-01 v1.0 · рыночный снимок 2026-09-16 · шаблон ADR v1.0
Этого достаточно, чтобы через год восстановить метод, даже если все три документа ушли вперёд. Решение без рыночного слоя (D-02) указывает две позиции вместо трёх.
Как этим пользуются#
Ради этого сценария всё и делается.
ADR-0007 написан по D-01 v1.0. Сегодня D-01 — v3.0. Вопрос «верно ли ещё это решение» закрывается не перечитыванием, а диффом:
- Открыть историю версий
D-01. - Выписать MAJOR между v1.0 и v3.0 — их обычно один-два.
- Проверить только то, что в них названо.
Если v2.0 добавила дисквалификатор «юрисдикция хранения данных», проверить надо одно условие, а не решение целиком. Отсюда требование к записи в истории версий: она отвечает на вопрос «что перепроверить», а не «что автор поправил».
| Плохо | Хорошо |
|---|---|
| Уточнён раздел 2 | MAJOR: добавлен дисквалификатор — юрисдикция хранения данных. Старым ADR: проверить, проходит ли по нему выбранное хранилище |
| Поправлены формулировки, добавлен пример | MINOR: примеры и формулировки. Перепроверять нечего |
Строка истории версий, из которой непонятно, что делать читателю старого ADR, эквивалентна её отсутствию.
Почему ADR не версионируется#
Версия у ADR означала бы, что содержание можно переписать, — и тогда запись перестаёт быть записью о том, что решили тогда и при каких условиях.
Вместо версии у ADR статус:
| Статус | Что означает | Содержание |
|---|---|---|
| Предложен | Обсуждается | Меняется свободно |
| Принят | Решение действует | Заморожено, проставлена дата принятия |
| Отменён | Решение отменено без замены | Заморожено, дописаны причина и дата |
| Заменён ADR-NNNN | Решение пересмотрено | Заморожено, дописана ссылка вперёд |
Изменение принятого решения — это новый ADR, отменяющий старый, а не правка старого. Единственное, что дописывается в принятый ADR, — строка статуса и ссылка на замену. Это то же правило, по которому заполненная матрица копируется в ADR снимком, а не прикладывается ссылкой: и там, и там нельзя допустить, чтобы прошлое молча менялось.
Совместимость#
D-NN и 01-adr-template.md объявляют, какой версии мастер-шаблона они соответствуют. Расхождение по MAJOR означает, что документ не приведён в соответствие: в нём может не быть обязательного раздела или правила.
Проверяется скриптом вместе с остальной целостностью документа. Версия, которую никто не проверяет, перестаёт обновляться примерно на третьем изменении.
Обновление заявленной совместимости — не пересмотр#
Каждый документ решения объявляет в шапке, по какому мастер-шаблону он написан. Когда мастер-шаблон набирает MAJOR, эту строку надо обновить во всех документах — но это не делает их новыми версиями, если изменение мастера не касается того, как в них принимается решение.
| Что изменилось в мастер-шаблоне | Документам нужен свой MAJOR? |
|---|---|
| Правила заполнения разделов, состав обязательных полей | Да. Прежнее решение могло выйти другим |
| Правила о том, заводить ли документ вообще, и о форме записи связанных решений | Нет. Метод внутри документа не изменился — обновляется только строка совместимости |
Практика: при MAJOR мастер-шаблона автор проходит по документам и отвечает на вопрос «изменился ли мой метод». Если нет — правится одна строка в шапке, история версий не пополняется. Если да — документ получает свой MAJOR с записью о том, что перепроверить.
Переименование — не пересмотр#
Отдельный случай, впервые встретившийся при переходе карточек со сквозной нумерации на коды по темам (2026-09-17).
Неизменяемость ADR защищает рассуждение и исход, а не написание имени цели. Если у документа, на который ADR ссылается, изменился код или заголовок, а сам документ остался тем же, — правка ссылки в принятом ADR не является его пересмотром: статус не меняется, история версий не пополняется, замещающий ADR не заводится.
| Что изменилось | Это пересмотр? |
|---|---|
| Код или имя цели, сама цель та же | Нет. Правится ссылка, запись остаётся принятой |
| Версия документа решения, по которому принят ADR | Нет. Поле «Метод» указывает на старую версию и остаётся верным |
| Условия, при которых решение принималось | Да. Нужен новый ADR, замещающий этот |
| Исход решения | Да. Новый ADR |
Соответствие старых имён новым хранится постоянно — 97-card-map.md. Ссылки живут и вне репозитория, и там их никто не поправит.
Указатель на соседа — не пересмотр#
Добавление в шапку ссылки на соседний документ — в строку «не решает» или «не путать с» — версии не даёт. Метод внутри документа не меняется, из старого ADR перепроверять нечего: читатель, принявший решение по прежней редакции, принял бы его так же.
Правило введено 2026-09-21, когда сплошная сверка шапок нашла десять односторонних ссылок: документ знал соседа, сосед о нём — нет. Заводить под каждую по строке истории значило бы заполнить истории одиннадцати документов записями, не отвечающими ни на один вопрос читателя.
Что при этом обязательно. Указатель взаимен: если шапка X называет Y, шапка Y называет X. Иначе список нужных документов, который по правилу мастер-шаблона собирается по шапкам до начала работы, зависит от того, с какого документа начали. Взаимность проверяется машиной — tools/check.py.
Что машина при этом не проверяет. Она сверяет взаимность существующих ссылок и об отсутствующей паре сказать не может ничего: два документа, не знающие друг о друге, для неё неотличимы от двух несвязанных. Зелёная проверка означает «нет односторонних ссылок», а не «граф полон». Недостающую пару находит только применение — на прогоне U-02 пятый дисквалификатор D-10 столкнулся с выбором из D-01, и выяснилось, что ни одна шапка о другой не знает, хотя сплошная сверка была зелёной. Отсюда правило: пара, обнаруженная столкновением на прогоне, заводится в тот же день — машина о ней не напомнит.
Чем это не является. Не разрешением менять шапку молча: строка «не решает» задаёт границу предмета, и её изменение — обычный MINOR, а при переносе предмета к соседу и MAJOR. Бесплатен только указатель: тот же предмет, тот же адресат, добавлена ссылка.
История версий#
| Версия | Дата | Изменение |
|---|---|---|
| 1.4 | 2026-09-22 | MINOR, по итогам прогона U-02, правка Р8 плана ревизии. К правилу о взаимности дописано, чего машина не проверяет: взаимность существующих ссылок — да, отсутствующую пару — нет, и зелёная проверка означает «нет односторонних ссылок», а не «граф полон». Поводом стало столкновение D-10 с D-01 на прогоне при зелёной сплошной сверке. Сами правила версионирования не изменились |
| 1.3 | 2026-09-21 | MINOR, по итогам вычитки Ш1. Добавлен раздел «Указатель на соседа — не пересмотр»: взаимная ссылка между шапками версии не даёт, но обязана быть взаимной, и взаимность проверяется машиной. Поводом стали десять односторонних ссылок, найденных сплошной сверкой |
| 1.2 | 2026-09-17 | MINOR. Добавлен раздел «Обновление заявленной совместимости — не пересмотр»: MAJOR мастер-шаблона обязывает обновить строку совместимости во всех документах, но своих MAJOR им не даёт, если изменение мастера не касается их метода. Поводом стал мастер-шаблон v5.0, чьи правки — о том, заводить ли документ, и о форме записи связанных решений |
| 1.1 | 2026-09-17 | MINOR. Добавлен раздел «Переименование — не пересмотр»: правка ссылки в принятом ADR, когда у цели изменился код или заголовок, а сама цель та же, не меняет его статуса и не требует замещающего ADR. Поводом стал переход карточек со сквозной нумерации на коды по темам. Старым ADR перепроверять нечего |
| 1.0 | 2026-09-16 | Введено версионирование. Предыдущая история 00-template.md, D-01 и D-02 осталась в git: до этого момента на них не ссылался ни один ADR, поэтому восстанавливать номера задним числом незачем |
Источники: Michael Nygard — Documenting Architecture Decisions (статусы и неизменяемость) · ADR GitHub organization · Semantic Versioning 2.0.0 (от которого здесь сознательно отступают)