Issue: #641 User-Visible: no
12 KiB
Код-ревью #641 · заход r2
Вердикт: зелёный · заход r2 · блокирующих циклов 0/4 · High: 0 · Medium: 0
Материал: 2b63dd854878d2f24850b7ba4fe1c817e5ae735e (рабочая копия уже на нём). Предыдущий раунд (r1) вынес вердикт на ee6ca4f3c9a8099e066b5d94c9a6815cd3f0c6e7, документ — docs/reviews/CODE-REVIEW-641-r1.md (закоммичен в этой же ветке в bf3e8a9b).
Скоуп раунда
Задача инфраструктурная (WSL-аттестация локальной golden-съёмки), src/** и custom_components/**/*.py диффом не тронуты ни в r1, ни в r2.
Дельта r2 = git diff ee6ca4f3..2b63dd85:
docs/reviews/CODE-REVIEW-641-r1.md | 251 +++++++++++++++++++++++++++
docs/reviews/INDEX.md | 3 +-
test/golden-capture-provenance.test.mjs | 19 ++-
Два первых файла — публикация документа предыдущего раунда (процессный артефакт, не предмет разбора). Единственная содержательная правка — test/golden-capture-provenance.test.mjs: новый параметр captureEnv в фикстуре плюс один новый тест #641: локальная Linux-съёмка без CI и WSL-аттестации отвергается до записи. Продуктовый код (demo/golden/accept.mjs, scripts/golden-wsl-artifact.mjs, scripts/capture-environment.mjs и т.д.) в этом раунде не менялся вообще — значит все выводы r1 по нему, кроме закрываемой находки, наследуются без риска регрессии от самой правки.
Закрытие раунда r1
| находка r1 | чем закрыта | где это видно |
|---|---|---|
Medium (в скоупе): guard в demo/golden/accept.mjs:86-103 — единственный механизм, не дающий обычной Linux-съёмке (golden:capture, без CI-провенанса и без wsl-attestation.json) выдать себя за отрецензированный источник — не был покрыт ни одним тестом, гоняющим настоящий accept.mjs именно в этом сценарии; все фикстуры test/golden-capture-provenance.test.mjs подставляли GITHUB_RUN_ID по умолчанию |
Добавлен тест #641: локальная Linux-съёмка без CI и WSL-аттестации отвергается до записи (test/golden-capture-provenance.test.mjs:130-142), плюс параметр captureEnv в fixture() (test/golden-capture-provenance.test.mjs:30-31, 73), позволяющий собрать отчёт без GITHUB_RUN_ID/GITHUB_SHA |
Тест строит артефакт с captureEnv: {} (нет CI-переменных → provenance.ci ложно) и без wsl-attestation.json (явно проверено assert.equal(existsSync(...), false, ...)), запускает настоящий demo/golden/accept.mjs через execFileSync (не мок) и ожидает отказ с текстом /локальная Linux-съёмка не аттестована/ до записи baselines-index.json (assert.deepEqual(index, before, ...)) |
Проверено не по заявлению автора, а инструментально: я прогнал node --test test/golden-capture-provenance.test.mjs на этом SHA — 8/8 зелёные, включая новый тест. Затем временно (в рабочей копии, не в коммите) заменил условие guard в demo/golden/accept.mjs (строки 100-102) на if (false) {, запустил только новый тест — он упал с тем самым сообщением о непойманном отказе ('приёмка обязана была отказать, а прошла'), после чего восстановил файл из бэкапа и подтвердил чистое дерево (git status --porcelain пусто). Это прямое доказательство: тест реально исполняет guard и умеет падать при его поломке — ровно то, чего требовала находка r1.
Других находок в r1 не было (0 High, финального Medium — 1, он закрыт выше).
Унаследовано из r1
Без повторной проверки в r2 принято (документ docs/reviews/CODE-REVIEW-641-r1.md, SHA ee6ca4f3c9a8099e066b5d94c9a6815cd3f0c6e7), так как продуктовый код этих механизмов в дельте r2 не менялся:
- fail-closed предусловия WSL-съёмки: dirty tree, detached HEAD, расхождение с
origin/<branch>, неподдерживаемая ФС; - самохеширующийся манифест/паспорт аттестации с независимой реконструкцией на приёмке;
- эксклюзивный trailer
Baseline-Reviewed-Local, проверка формата и сверка с индексом baseline; - участие WSL-аттестации в составном CI-proof evidence;
- покрытие AC модульными тестами (dirty tree, stale fingerprint, несовпадающий toolchain, неполная матрица, unexpected diff, подмена SHA) — кроме единственного пробела, закрытого в этом раунде;
- обновления
AGENTS.md,PROCESS.md, документации golden/WSL иdocs/STATUS.md; - соответствие AC ТЗ #641 в целом (все пункты чек-листа issue, кроме проверки самого guard, r1 разобрал по коду и тестам).
Что проверено в r2 (сверх наследования)
- Диапазон дельты.
git log --oneline ee6ca4f3..2b63dd85иgit diff --stat— подтверждено: только тестовый файл + публикация документа r1 + индекс. Продуктовый код не тронут → полный повторный разбор AC не требуется (правка локальна, поведение не меняет, новую подсистему не задевает). - Реальный запуск нового теста и его фикстуры, включая целевой mutation-check (guard отключён → тест падает; guard включён → тест зелёный), см. выше.
- Полный прогон файла тестов —
node --test test/golden-capture-provenance.test.mjs— 8/8, 0 fail, 0 skip (среда — Linux, целевой guard не skip-ится). - Точный SHA Validate.
gh run viewдля обоих упомянутых прогонов:35897181655(из комментария автора) —headSha: 2b63dd854878d2f24850b7ba4fe1c817e5ae735e,conclusion: success;35897805104(из инструкции задания) — тот жеheadSha,conclusion: success,event: workflow_dispatch. Job-лист второго прогона:Фронтенд: типы, юниты, мутанты, синхрон бандла— success (включает изменённый тестовый файл),Мутанты по диффу(все 6 шардов) — success,Предполёт: документация, провенанс, процесс— success;golden,смоки(3 шарда),перф,Бэкенд,Геометрия,HACS,Hassfest— закономерноskipped, т.к.src/**, baselines, geometry и Python диффом не задеты.
node scripts/smoke-select.mjs --base ee6ca4f3 --head 2b63dd85→ «Исполняемого frontend-диффа нет (src/**/*.tsне тронут). Browser-smoke этим диффом не выбираются — выбирать нечего». Смоки не прогонялись, и это корректно: выбирать нечего, а не «пропущено».- Трейлеры.
2b63dd85:Issue: #641,User-Visible: no— верно, изменение только тестового кода, для пользователя карточки невидимо, changelog не требуется. - Чистота рабочей копии после ревью (в т.ч. после временной мутации для проверки теста) —
git status --porcelainпуст,git diffпуст.
Что не проверял и почему
npx tsc --noEmit,npm test(полный набор),npm run buildсо сверкой трёх копий бандла,node scripts/check-docs.mjs— не перегонял: дешёвые гейты уже подтверждены на этом точном SHA (35897805104,success), аsrc/**дельтой r2 не тронут (check-docsне устареет). Свежесть подтверждена напрямую черезgh run view, а не по слову автора.npm run invariants(инварианты модели) — не требовался: дельта не касается геометрии,layout, толщины стен,open_spans.python -m pytest tests_backend -q— не требовался:custom_components/**/*.pyне тронут (и в r1, и в r2).npm run golden:verify, браузерные смоки любых шардов, performance-профиль — не требовались:smoke-select.mjsпрямо подтвердил отсутствие исполняемого фронтенд-диффа; видимый рендер/геометрия/стили не менялись.- Повторная ручная проверка WSL-паспорта,
foreignCaptureRefusal, композитного CI-proof и остальных механизмов r1 — не повторял целиком: продуктовый код этих модулей в дельте r2 не менялся (см. «Унаследовано из r1»); риск регрессии от самой правки r2 (только тест) на них не распространяется.
Итог
Единственная Medium-находка r1 закрыта точным, целевым тестом, который инструментально подтверждён как реально исполняющий боевой accept.mjs и как способный упасть при поломке guard'а. Дельта r2 локальна (тестовый файл + публикация документа), продуктовый код не тронут, точный SHA зелёный в CI. Новых находок не выявлено.
Материал раунда
- Ветка:
issue/641-wsl-golden-attestation, коммит2b63dd854878— ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. - Дерево материала:
ad3826fd48aaf89c6ab66487b18ce9bc590e6180git log --all --format='%H %T' | grep ad3826fd48aa - Тело issue:
1a1d7660a1cab43873f74127511d21fecf30767f7af959c6ecf820e6efbd2a51 - Вердикт конвейера:
green· High 0