- DECISIONS.md (4040 строк, 65 тем) → decisions/, файл на тему плюс указатель; - буквенные метки решений заменены сквозными Р1–Р234, следствия получили префикс С при прежних номерах: схема букв выродилась до пятибуквенных и сломалась — `АЕАКЛ` была занята и темой 53, и темой 65; - 42 перекрёстные ссылки переписаны под новые номера и стали живыми; где номер означал тему, а слово стояло «решение», формулировка исправлена.
5.4 KiB
6. Поддержание документов по ходу разработки (2026-08-03)
Что было
Гейт healthlog уже изобрёл нужный механизм для одного документа —
scripts/gate.py:177-181: миграция изменена, а docs/database.md нет → FAIL.
Документ канона сверяется с кодом красным гейтом, а не напоминанием.
Против этого — прямое доказательство, что́ не работает: у adr/ был список
триггеров прозой («выбор технологии, структурные решения, дорогой откат,
намеренный отказ»), и он дал 6 записей на 43 изменения. Прозаический триггер,
который некому проверить, не срабатывает.
Механизируемы три документа из десяти: database.md (миграция), architecture.md
(capability в openspec/specs/ без упоминания в обзоре), tasks/ (tasks.py check). Плюс openspec/specs/ вливает opsx:archive.
Решено
Р21. Принуждённое отрицание в докладе шага синка. Шаг обязан назвать каждый документ канона: обновлён — чем, либо «не требуется, потому что…». Нетронутые группируются одной строкой с общей причиной.
Причина: это тот же приём, что «границы покрытия» в отчёте ревью и «пустой пункт называется пустым» в каноне — и единственный, о котором в этом репозитории есть данные, что он работает. Отличить «не написал» от «написал, что не требуется» можно только тогда, когда отрицание обязательно.
Триггер ADR, окончательная формулировка. Запись заводится, когда верно одно
из трёх: дорогой откат (переделка стоит дороже переписывания одного файла);
намеренный отказ от очевидного подхода; пересмотр прежнего решения — тогда
у старой записи обязателен статус «заменено на». Не заводится для рутины и для
того, что видно из кода и git log. Источник — архивный design.md: ADR его
цитирует и на него ссылается, а не пересказывает.
Р22. docs.py check обязателен в гейте проекта. Скилл canon при адаптации
добавляет шаг и печатает это в отчёте.
Причина: гейт — единственный общий станок, который нельзя пропустить. Проверка, которую зовёт агент, может быть не позвана; прецедент в самом healthlog уже есть.
Сверка «миграция изменена — database.md нет» обобщается: путь миграций
проекта записывается в docs/.pm.json рядом с версией канона, и docs.py делает
эту проверку сам, а не каждый проект заново.
Р23. Остаток чистки помечается маркером и считается числом. Неразобранный
раздел получает <!-- канон: поведение → openspec/specs/<capability> -->,
docs.py считает маркеры и печатает остаток. Закрывается порциями, как
переоценка задач.
Маркеры гейт не красят. Это долг, а не отказ: покрасневший гейт на первом маркере сделал бы постепенный переезд невозможным, а разовый — обязательным. Число печатается и убывает на глазах.
Что из этого следует
С28. Шаг 9 task-pipeline переписывается из четырёх пунктов прозой в
построчный доклад по документам канона.
С29. promote.md, шаг 3, переписывается: «вычеркнуть пункт из брифа,
правило переезжает в перечень механизированного в разделе ## Карта» → перечень
механизированного живёт в conventions/README.md. Брифа нет.
С30. docs/.pm.json держит не только версию канона, но и пути, нужные
проверкам: каталог миграций — как минимум.
С31. docs.py check получает две сверки с кодом, а не только раскладку:
миграции ↔ database.md, capability ↔ упоминание в architecture.md.