Files
transcriber/docs/adr/ADR-2026-08-12-spec-norms-build-toolchain.md
T
av 09228f23d8 Go обновлён до 1.26, а расхождение версий теперь роняет гейт
- шаг go-version в task gate сверяет объявленную версию в go.mod, Dockerfile,
  CLAUDE.md и README.md; судит по репозиторию, go не зовёт, docker и сети не
  требует
- заведена capability toolchain: до сих пор спеки нормировали только поведение
  сервиса, теперь и инструмент сборки. Причина и цена — в двух ADR
- закрыт дефект 2026-08-12: образ на golang:1.24-alpine разошёлся с go.mod и
  перестал собираться, а восемь шагов гейта и шесть проходов ревью были зелёными
2026-08-12 10:57:50 +03:00

5.3 KiB
Raw Blame History

ADR-2026-08-12. Спекой нормируется и инструмент сборки, а не только поведение сервиса

Решение

Заведена capability toolchain — четвёртая, и первая, которая описывает не поведение сервиса для его потребителей, а поведение инструмента, которым сервис собирают. Потребитель у неё другой: тот, кто собирает.

Требование о согласованности объявленной версии Go живёт нормой в openspec/specs/toolchain/spec.md, а не прозой в памятке.

Почему

Три существующие capability — intake, pipeline, storage — все про то, что сервис делает для своих потребителей, а преамбула architecture.md прямо говорила «поведение системы здесь не описывается — нормативно оно живёт в openspec/specs/». Согласованность версий сборки под это определение не подходит, и натяжение признано прямо в источнике:

Признаём натяжение: три существующие capability описывают поведение сервиса для его потребителей, а toolchain описывает поведение инструмента разработки. Потребитель у него другой — тот, кто собирает сервис. Правило config.yaml говорит «поведение или домен системы»; инструмент сборки — домен, и именно как домен он здесь и назван.

Очевидные пути отвергнуты оба:

Отвергнуто: дописать в pipeline. pipeline нормирует прогон воркера и захват задачи — поведение работающего сервиса. Версия сборщика с ним не меняется вместе.

Отвергнуто: обойтись без дельта-спеки. Изменение вводит проверяемое требование — «расхождение роняет набор проверок», — и требование без дома проверяется только памятью того, кто его завёл. Обещание «образ собирается» уже один раз жило в трёх документах и во всех трёх было неверным.

Последнее и есть довод, перевесивший чистоту определения: дефект 2026-08-12 случился именно потому, что утверждение о версии сборки жило только прозой, в трёх местах сразу, и никто не отвечал за его истинность.

Последствия

  • + у правила о версиях есть нормативный дом со сценариями, и по нему видно, что проверено, а что оставлено человеку. Три требования, двадцать два сценария.
  • + следующая задача про инструмент сборки знает, куда дописывать, и не заводит вторую спеку о том же.
  • определение capability в проекте стало шире, чем «поведение сервиса», и граница теперь проходит по слову «домен». Следующее пограничное решение будет ссылаться на этот прецедент — в том числе тогда, когда ссылаться не стоило бы.
  • асимметрия: четыре однородных шага гейта живут в двух разных домах. У трёх плагинных (docs.py, tasks.py, openspec.py) нормативного дома нет вовсе, только строка в памятке; у четвёртого есть спека. Либо дома появятся у остальных, либо асимметрия останется навсегда.
  • имя toolchain выбрано в том числе из-за настройки среды разработчика: первая редакция звалась build, и глобальный запрет чтения каталогов с таким именем сделал спеку нечитаемой для проходов ревью. Имя, выбранное под ограничение инструмента, а не под предмет, — слабое основание, и при следующем пересмотре его стоит перепроверить.