Перейти к содержанию

Версионирование решений и 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. Вопрос «верно ли ещё это решение» закрывается не перечитыванием, а диффом:

  1. Открыть историю версий D-01.
  2. Выписать MAJOR между v1.0 и v3.0 — их обычно один-два.
  3. Проверить только то, что в них названо.

Если 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 (от которого здесь сознательно отступают)