tasks: закрыта задача go-1-26-upgrade, заведён урожай ревью
- четыре задачи из находок ревью и заметки владельца: проверки shellcheck и hadolint с тестом скрипта сверки версий, закрепление рантайм-базы образа, коды выхода шагов гейта, настройка конвейера ревью - INBOX разобран целиком и очищен
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
# 🧹 Завести недостающие проверки: shellcheck, hadolint и тест скрипта сверки версий
|
||||
|
||||
- **Тип:** chore
|
||||
- **Категория:** Очередь
|
||||
- **Зачем:** Скрипты оболочки и Dockerfile машина не проверяет: shellcheck и hadolint не заведены, lefthook смотрит только gitleaks, а единственный исполняемый скрипт проекта на shell — scripts/check-go-version.sh — разбирали на ревью глазами построчно, потому что машине его показать нечем.
|
||||
|
||||
Собрана из двух источников: заметки владельца от 2026-08-12 про lefthook и
|
||||
находки N-1 ревью `go-1-26-upgrade` про непроверенный скрипт сверки версий.
|
||||
Собраны вместе, потому что правятся одним заходом: и то и другое — недостающие
|
||||
проверки на файлы, которых сегодняшний гейт не видит.
|
||||
|
||||
Цена shellcheck замерена на прогоне 2026-08-12: shell-файлов в репозитории два,
|
||||
в гейте из них один, единственное замечание — ложный `SC1007` на идиому
|
||||
`CDPATH= cd`, и оно уже подавлено в скрипте директивой. То есть шаг стоит одной
|
||||
строки.
|
||||
|
||||
Отдельная половина — **скрипт сверки версий не проверен ничем.** Его норма
|
||||
(`openspec/specs/toolchain/spec.md`) описывает девятнадцать сценариев, а гейт
|
||||
гоняет скрипт ровно на согласованном дереве, то есть проверяет один из них — тот,
|
||||
где всё сошлось. Остальные восемнадцать подтверждены разовыми ручными прогонами
|
||||
2026-08-12 и после первой же правки образца перестанут выполняться молча.
|
||||
|
||||
Проверки go (`go vet`, `gofmt`) в гейте уже есть; в заметке речь о том, чтобы
|
||||
часть из них ловил и pre-commit, не дожидаясь полного прогона.
|
||||
|
||||
## Затрагивает
|
||||
|
||||
- `lefthook.yml` — набор предкоммитных проверок;
|
||||
- набор шагов `task gate` в `Taskfile.yml`;
|
||||
- новый тест-скрипт для `scripts/check-go-version.sh`;
|
||||
- `Dockerfile` — как объект проверки hadolint, не правкой содержимого;
|
||||
- семантика гейта в `CLAUDE.md`, раздел «Гейт», подраздел «чего в гейте
|
||||
намеренно нет»;
|
||||
- таблица «Механизировано» в `docs/conventions/README.md`.
|
||||
|
||||
## Критерии приёмки
|
||||
|
||||
- `shellcheck` краснеет на негодном скрипте оболочки. Оракул — внести в
|
||||
`scripts/check-go-version.sh` неэкранированную переменную и прогнать шаг: он
|
||||
краснеет; вернуть — зеленеет.
|
||||
- `hadolint` краснеет на негодном `Dockerfile`. Оракул — тот же приём: снять
|
||||
закрепление версии базового образа и прогнать шаг.
|
||||
- Каждый сценарий нормы `toolchain` проверяется машиной, а не памятью. Оракул —
|
||||
тест-скрипт мутирует дерево по одному сценарию за прогон; снять любую проверку
|
||||
из `check-go-version.sh` — тест краснеет и называет сценарий.
|
||||
- Предкоммитные проверки не дублируют гейт молча. Оракул — `CLAUDE.md`, раздел
|
||||
«Гейт», называет, что именно ловит pre-commit и что остаётся только гейту.
|
||||
- Гейт зелёный целиком. Оракул — `task gate`.
|
||||
|
||||
## Рамки
|
||||
|
||||
Мутационный тест работает на временной копии дерева: `t.TempDir()`-подход, в
|
||||
`data/` не писать, рабочее дерево после прогона обязано остаться нетронутым.
|
||||
|
||||
Заметка владельца называет проверки go в lefthook, но полный набор `task gate` в
|
||||
pre-commit не переносится: он идёт минуты, а pre-commit обязан быть быстрым.
|
||||
Что именно из него дублировать — решение этой задачи, и его надо назвать.
|
||||
@@ -0,0 +1,35 @@
|
||||
# 🧹 Привести коды выхода шагов гейта к общему словарю
|
||||
|
||||
- **Тип:** chore
|
||||
- **Категория:** Очередь
|
||||
- **Зачем:** CLAUDE.md объявляет словарь кодов общим для четырёх проверочных шагов и описывает код 3 как «каталог или файл не найден», но все четыре обёртки в Taskfile.yml при отсутствующем скрипте отдают 1 («дрейф»), из-за чего читатель кода идёт искать разъехавшееся там, где просто неполно дерево.
|
||||
|
||||
Расхождение старое и повторено всеми четырьмя обёртками одинаково — дефектом
|
||||
одного изменения оно не является. Сами скрипты словарю следуют: при пропавшем
|
||||
источнике `scripts/check-go-version.sh` выходит с кодом 3, проверено прогоном
|
||||
2026-08-12.
|
||||
|
||||
Развилка тут есть, и решать её придётся: либо обёртки приводятся к 3, либо из
|
||||
описания кода 3 в памятке убирается «или файл не найден» и `exit 1` объявляется
|
||||
нормой для «скрипта шага нет». Второй вариант меняет только текст памятки, а не
|
||||
код всех четырёх обёрток, и тоже не расходится с фактами.
|
||||
|
||||
## Затрагивает
|
||||
|
||||
- шаги `docs`, `tasks`, `openspec` и `go-version` в `Taskfile.yml`;
|
||||
- словарь кодов в `CLAUDE.md`, раздел «Гейт».
|
||||
|
||||
## Критерии приёмки
|
||||
|
||||
- Один и тот же исход даёт один и тот же код у всех четырёх шагов. Оракул —
|
||||
убрать по очереди каждый из четырёх скриптов и прогнать его шаг: коды
|
||||
совпадают между собой и с тем, что обещает памятка.
|
||||
- Памятка и поведение сошлись. Оракул — прочитать словарь в `CLAUDE.md` и
|
||||
сверить с четырьмя прогонами выше поимённо.
|
||||
- Гейт зелёный целиком. Оракул — `task gate`.
|
||||
|
||||
## Рамки
|
||||
|
||||
Скрипты плагинов (`docs.py`, `tasks.py`, `openspec.py`) не правятся: они живут
|
||||
вне репозитория, и их коды уже следуют словарю. Правятся только обёртки в
|
||||
`Taskfile.yml` и текст памятки.
|
||||
@@ -1,53 +0,0 @@
|
||||
# 🧹 Обновить Go до 1.26 и сверять версию шагом гейта
|
||||
|
||||
- **Тип:** chore
|
||||
- **Категория:** Очередь
|
||||
- **Зачем:** Модуль объявляет go 1.25.0, образ собирается на golang:1.25-alpine, на машине разработки стоит 1.26.5, и расхождение этих чисел не ловит ни один шаг гейта: разъехавшийся Dockerfile прошёл весь конвейер зелёным.
|
||||
|
||||
Задача собрана из двух: заметки владельца от 2026-08-12 про обновление и находки
|
||||
ревью `pocketbase-storage` про несверяемые версии. Собраны вместе, потому что
|
||||
правятся одним заходом: поднимать число в трёх местах и не заводить сверку
|
||||
значит завести то же расхождение заново на следующей зависимости.
|
||||
|
||||
Версия 1.25 в модуле появилась не выбором, а требованием PocketBase: `go mod
|
||||
tidy` поднял директиву сам, а образ подтянули следом. То есть сегодняшнее число
|
||||
никем не назначено.
|
||||
|
||||
Случай расхождения записан журналом дефектов `docs/review.md` за 2026-08-12:
|
||||
`go mod tidy` поднял директиву до 1.25, `Dockerfile` остался на
|
||||
`golang:1.24-alpine` с `GOTOOLCHAIN=local`, и шесть проходов ревью вместе с
|
||||
восемью шагами гейта показали зелёное. Нашлось случайным свойством прогона, а не
|
||||
устройством проверок.
|
||||
|
||||
Сборку образа в гейт не заводим — она дорога. Дешёвая замена: сравнение двух
|
||||
строк.
|
||||
|
||||
## Затрагивает
|
||||
|
||||
- директива `go` в `go.mod`;
|
||||
- сборочный слой `Dockerfile`;
|
||||
- строка стека в `CLAUDE.md` и в `README.md`;
|
||||
- набор шагов `task gate` в `Taskfile.yml`;
|
||||
- семантика гейта в `CLAUDE.md`, раздел «Гейт».
|
||||
|
||||
## Критерии приёмки
|
||||
|
||||
- Модуль, образ и документы называют одну версию Go. Оракул — `grep` по четырём
|
||||
местам: `go.mod`, `Dockerfile`, `CLAUDE.md`, `README.md`; все дают одно число.
|
||||
- Сборка на объявленной версии проходит. Оракул — `task image` и
|
||||
`CGO_ENABLED=0 go build ./...` на чистом дереве.
|
||||
- Расхождение версий роняет гейт. Оракул — прогон `task gate` на дереве, где
|
||||
версия в `Dockerfile` понижена на минор: шаг краснеет и называет оба числа.
|
||||
- Совпадение гейт не роняет, а сам шаг не требует docker и работает без сети.
|
||||
Оракул — `task gate` на неизменённом дереве и прогон с
|
||||
`DOCKER_HOST=/dev/null`.
|
||||
- Гейт зелёный целиком. Оракул — `task gate`.
|
||||
|
||||
## Рамки
|
||||
|
||||
Версию выбирает человек: обновление до неподдерживаемой ещё зависимостями версии
|
||||
ломает сборку молча. Выкладку не запускаем.
|
||||
|
||||
Сравнение строковое: `Dockerfile` называет `golang:<major>.<minor>-alpine`, а
|
||||
`go.mod` — `<major>.<minor>.<patch>`. Сверяются мажор и минор; патч сборочного
|
||||
образа своей жизнью живёт законно.
|
||||
@@ -0,0 +1,42 @@
|
||||
# 🧹 Закрепить версию рантайм-базы образа
|
||||
|
||||
- **Тип:** chore
|
||||
- **Категория:** Очередь
|
||||
- **Зачем:** Финальный слой Dockerfile собирается на alpine:latest, а task image идёт с --pull, поэтому два образа из одного коммита с разницей в неделю несут разный ffmpeg — регрессия конвертации после такой пересборки выглядит как задачи в failed при пустом диффе репозитория, и откат на прежний коммит её не чинит.
|
||||
|
||||
Класс тот же, ради которого задача `go-1-26-upgrade` завела шаг сверки версий:
|
||||
объявленное и собранное расходятся, а сверять некому. Разница в том, что там
|
||||
расходились числа внутри репозитория, а здесь репозиторий вообще не называет
|
||||
числа — версия рантайм-базы задана словом «последняя».
|
||||
|
||||
Цена названа условием, а не замером: сколько именно и как часто меняется
|
||||
`ffmpeg` в `alpine:latest`, никто не мерил. Известно, что он в таблице отказов
|
||||
`docs/architecture.md` стоит со столбцом «Отдаёт мусор»: «Выходной файл пуст,
|
||||
отказ вылезет на распознавании».
|
||||
|
||||
Перечень мест, где объявлена версия Go, эта задача не расширяет: он закрыт
|
||||
решением `go-1-26-upgrade`, и рантайм-база — другой предмет.
|
||||
|
||||
## Затрагивает
|
||||
|
||||
- финальный слой `Dockerfile` — тег базового образа;
|
||||
- раздел «Деплой» в `docs/architecture.md`.
|
||||
|
||||
## Критерии приёмки
|
||||
|
||||
- Репозиторий называет версию рантайм-базы числом, а не словом «последняя».
|
||||
Оракул — `grep` по `Dockerfile`: тег финального слоя содержит мажор и минор.
|
||||
- Два образа, собранные из одного коммита, несут один `ffmpeg`. Оракул — собрать
|
||||
`task image` дважды с интервалом и сравнить `ffmpeg -version` внутри обоих.
|
||||
- Решение записано там, где его найдёт разбор отказа конвертации. Оракул —
|
||||
раздел «Деплой» `docs/architecture.md` называет закреплённую базу и причину.
|
||||
- Гейт зелёный целиком. Оракул — `task gate`.
|
||||
|
||||
## Рамки
|
||||
|
||||
Версию базы выбирает человек: перескок на минор новее может принести другой
|
||||
`ffmpeg` ровно с тем же исходом, ради предотвращения которого задача и заведена.
|
||||
Выкладку не запускаем.
|
||||
|
||||
Если решено оставить `latest`, задача кончается записью принятого остатка в
|
||||
`docs/architecture.md`, а не правкой `Dockerfile`. Это законный исход.
|
||||
@@ -0,0 +1,48 @@
|
||||
# 🧹 Настроить конвейер ревью по итогам прогона go-1-26-upgrade
|
||||
|
||||
- **Тип:** chore
|
||||
- **Категория:** Очередь
|
||||
- **Зачем:** Прогон вскрыл две прорехи настройки: «Типовые узлы» знают только рантайм и не знают рода «проверочный шаг набора проверок», а «Триггеры метки» не видят оси «изменение трогает канон» — и именно она дала обе блокирующие находки.
|
||||
|
||||
Обе прорехи одного рода — настройка конвейера, живущая в `docs/review.md`, — и
|
||||
правятся одним заходом.
|
||||
|
||||
**Род узла.** Сегодня перечень покрывает шаг конвейера, транспорт, клиент
|
||||
внешнего сервиса, репозиторий и обёртку над внешним процессом. Скриптов гейта в
|
||||
проекте четыре, и свойства у них свои: отличает ли шаг расхождение от сломанного
|
||||
окружения, есть ли исход функция коммита, а не машины, покрыт ли шаг мутационным
|
||||
прогоном. Без этого рода находка «шаг набора проверок не проверен ничем»
|
||||
добывается заново каждый раз.
|
||||
|
||||
**Ось метки.** Два прохода независимо сказали, что метка `medium` занижена:
|
||||
изменение заводило новую capability и новый каталог верхнего уровня. Триаж
|
||||
проверил и подтвердил — по записанному правилу разметка была верна, потому что
|
||||
такой оси в правиле нет вовсе, а обе блокирующие находки прогона пришли именно
|
||||
по ней.
|
||||
|
||||
Провенанс обоих — отчёт
|
||||
`openspec/changes/archive/2026-08-12-go-1-26-upgrade/review/report.md`,
|
||||
кандидаты в правило P-2 и P-5.
|
||||
|
||||
## Затрагивает
|
||||
|
||||
- раздел «Типовые узлы» в `docs/review.md`;
|
||||
- раздел «Триггеры метки» в `docs/review.md`.
|
||||
|
||||
## Критерии приёмки
|
||||
|
||||
- Проверочный шаг набора проверок описан родом со своими свойствами. Оракул —
|
||||
открыть «Типовые узлы» и найти род; свойств не меньше трёх, и каждое
|
||||
сформулировано проверяемо.
|
||||
- Правило выбора метки видит заведение новой capability и нового каталога
|
||||
верхнего уровня. Оракул — приложить правило к прогону `go-1-26-upgrade` задним
|
||||
числом: метка выходит выше `medium`.
|
||||
- Гейт зелёный целиком. Оракул — `task gate`.
|
||||
|
||||
## Рамки
|
||||
|
||||
Правится только настройка конвейера в `docs/review.md`. Устав самого конвейера
|
||||
живёт в плагине `av-dev-code` и этой задачей не трогается: проект вправе
|
||||
настраивать свои темы и триггеры, но не переписывать чужой скилл.
|
||||
|
||||
Журнал дефектов в том же файле не трогается — записи неизменяемы.
|
||||
Reference in New Issue
Block a user