# ADR-2026-08-12. Объявленную версию Go шаг гейта читает из репозитория, а не спрашивает у инструмента - **Дата:** 2026-08-12 - **Источник:** [openspec/changes/archive/2026-08-12-go-1-26-upgrade/design.md](../../openspec/changes/archive/2026-08-12-go-1-26-upgrade/design.md), раздел `Decisions`, Решения 1 и 6 ## Решение Шаг сверки версий добывает числа чтением файлов и **не зовёт `go` ни в каком виде** — ни `go mod edit -json`, ни `go list -m`, ни `go env`. Директива `toolchain` в `go.mod` при этом запрещена: её наличие роняет шаг. Дословно из источника: > Способ это не самый удобный: разбор директивы через `go mod edit -json` короче > и надёжнее регулярного выражения. Он же и опасный: вызов `go` тянет за собой > `GOTOOLCHAIN`, `$PATH` и установленный тулчейн, а при непустом `GOTOOLCHAIN` > `go` вправе полезть в сеть за нужной версией — то есть требование «без сети» > перестало бы выполняться. Хуже того, исход шага стал бы зависеть от машины, а > не от коммита. ## Почему Причина не в аккуратности, а в том, что **ровно этой подменой и держался дефект, ради которого шаг заведён**. 2026-08-12 требование модуля уехало на 1.25, сборочный образ остался на 1.24, образ перестал собираться — и восемь шагов гейта с шестью проходами ревью показали зелёное, потому что `go build ./...` шёл на хостовом Go. Проверка судила по тому, что стоит на машине, вместо того что записано в коммите. Шаг, зовущий `go`, воспроизвёл бы ту же подмену внутри себя: зелёный там, где стоит нужная версия, и другой ответ на другой машине. Отсюда же запрет `toolchain`. Директива — штатный механизм Go и очевидное решение задачи расхождения: она заставила бы Go скачать нужную версию самому, и сверять стало бы нечего. Отвергнута намеренно: > Директива `toolchain` заставила бы Go скачивать нужный тулчейн сам, и > расхождение с образом перестало бы ломать сборку. Но она же превращает сборку > образа в сетевую операцию, а сборочный слой качает тулчейн при каждой сборке. > Дороже и менее предсказуемо, чем строка сравнения. Вдобавок она вводит **пятое место**, называющее версию, — то, которого закрытый перечень из четырёх мест не знает: при `toolchain go1.27.0` четыре объявленных числа сойдутся, а собирать будет пятое. ## Последствия - `+` исход шага есть функция коммита. Проверено прогоном: с `PATH`, где нет `go`, шаг даёт тот же код выхода и тот же вывод. - `+` требование «без сети» выполняется по построению, а не обещанием: под `strace` шаг не делает ни одного сетевого вызова. - `+` пятое место закрыто: `toolchain` в `go.mod` роняет шаг с названной причиной. - `−` разбор держится на регулярных выражениях `sed`/`awk` вместо готового разбора, который дал бы сам `go`. Это дороже в сопровождении и хрупче: правка образца ломает смежный случай беззвучно. - `−` запрет `toolchain` придётся снять или пересмотреть, если зависимость однажды потребует версию выше той, что стоит у нас. Тогда эта запись пересматривается, а не обходится. - `−` проверять сам скрипт нечем: `shellcheck` в гейт не заведён, тестов у него нет. Из девятнадцати сценариев нормы машина гоняет один — тот, где всё сошлось. Остаток объявлен и уехал отдельной задачей.