В src/** сейчас 1034 вхождения явного any в 49 файлах — больше, чем называл
аудит (330), потому что монолит с тех пор разделился и его обвязка уехала в
houseplan-editor-runtime.ts. Разовая замена такого объёма — месяц риска ради
нуля пользовательской ценности, поэтому долг снимается при плановом извлечении
подсистем (#34). Задача гейта одна: не давать долгу расти.
Судятся только добавленные строки диапазона. Изменённая строка со старым any
выглядит в диффе добавленной, и это намеренно: тронул — либо типизируй, либо
обоснуй на той же строке `// any-ok: <причина>`. Голый маркер, пустая причина и
шаблоны вроде todo, hack, потом не проходят.
Ложных срабатываний нет по построению, а не по старанию: текст разбирается
парсером TypeScript, и нарушением считается узел AnyKeyword. Регулярка по строке
ловила бы слово any в прозе внутри шаблона html и в комментариях; здесь
комментарии, строковые литералы, многострочные шаблоны и идентификаторы
company, anyOf, manyRooms узлами такого вида не являются вовсе.
Проверено исполнением на настоящем дереве, а не только юнитами: пробные коммиты
в src/wall-thickness.ts показали, что добавленный any падает с файлом и строкой,
типизированная строка в файле с 122 старыми any проходит, any-ok с конкретной
причиной проходит, а голый и «todo» — нет, и что any в прозе, строке и
идентификаторах не даёт ни одного срабатывания.
В job frontend checkout получил полную историю без блобов: diff-aware проверке
нужен диапазон, а содержимое старых ревизий — нет.
Заодно закрыта ловушка в test/validate-workflow.test.mjs: имя job искалось через
indexOf(' frontend:'), а эта строка встречается внутри ` frontend: ${{ ...
}}` в outputs job changes, поэтому срез уходил не туда. Теперь имя ищется с
начала строки.
Четыре мутанта проверены руками, два добавлены в реестр: гейт, судящий все
строки, и гейт, принимающий голый маркер.
Issue: #342
User-Visible: no
Полный клон — 215 МБ .git, blobless — 26 МБ, история коммитов и теги в обоих
полные (замер в #345). Две job Validate качают историю целиком: preflight и
changes. Первой нужны сообщения коммитов, трейлеры и имена изменённых файлов,
второй — только `git diff --name-only`. Содержимое старых ревизий не читает ни
одна из них ни на одном шаге.
Коммиты и деревья по-прежнему скачиваются полностью, поэтому диапазоны и
merge-base работают как раньше. Единственная догрузка блоба по требованию —
`git show origin/main:.github/workflows/process.yml` в шаге сверки, один файл.
Браузерным job фильтр не нужен: у них глубина по умолчанию, истории они не
касаются вовсе.
Тест закрепляет и обратную сторону: --depth=1 сюда подставлять нельзя, он того
же размера, но без merge-base, а на нём стоят процессный гейт, smoke-select и
каждый диапазон origin/dev..HEAD. Два мутанта проверены руками — снятый фильтр и
подмена на depth=1, — каждый убит.
Issue: #345
User-Visible: no
Бандл собирался пятью job независимо: три шарда смоков, golden, перф-смок —
каждая гоняла `bundle:sync`, то есть `tsc --noEmit` плюс rollup. Теперь его
собирает `frontend` и выкладывает артефактом, остальные скачивают и раскладывают
`bundle-sync.mjs`. Подмену артефакта отдельной проверкой ловить не нужно:
assertFreshDemoBundle сверяет вшитый в бандл отпечаток с sourceFingerprint
выкачанного дерева, и каждая браузерная job делает это перед первым кадром.
`npm ci` остаётся во всех: браузерным job нужен playwright из node_modules, а не
только бандл. Артефакт node_modules был бы медленнее `npm ci` с тёплым кэшем.
docs, process-workflow-sync, provenance и process-gate стали шагами одной job
`preflight`. Независимость сохранена намеренно: у каждого шага
continue-on-error, вердикт в конце падает и перечисляет всё упавшее сразу.
Прежняя запись «краснеет сам и не роняет остальные» продолжает действовать — на
уровне шагов, с той же гранулярностью в логе.
hacs и hassfest не тронуты: предложение сузить их до dev и тегов уже выполнено
классификатором `changes` — на ветках задач они и так идут только при правке
манифестов, а на dev фильтров нет намеренно (гейт беты требует, чтобы «зелёный
Validate» значил одно и то же).
test/validate-workflow.test.mjs закрепляет то, что в диффе строк не видно:
висячая зависимость `needs` не роняет YAML, а молча пропускает job навсегда.
Три мутанта проверены руками — висячая зависимость, вернувшаяся вторая сборка,
шаг без continue-on-error, — каждый убит.
Issue: #336
User-Visible: no