Files
houseplan-card/docs/reviews/CODE-REVIEW-641-r2.md
T
claude[bot] 14e56c0399
Проверка (CI) / Классификация изменённых файлов (push) Successful in 47s
Проверка (CI) / HACS: валидация репозитория (push) Skipped
Проверка (CI) / Hassfest: манифест интеграции (push) Skipped
Проверка (CI) / Мутанты по диффу (1/6): затронутые свидетели краснеют (push) Skipped
Проверка (CI) / Мутанты по диффу (2/6): затронутые свидетели краснеют (push) Skipped
Проверка (CI) / Мутанты по диффу (3/6): затронутые свидетели краснеют (push) Skipped
Проверка (CI) / Мутанты по диффу (4/6): затронутые свидетели краснеют (push) Skipped
Проверка (CI) / Мутанты по диффу (5/6): затронутые свидетели краснеют (push) Skipped
Проверка (CI) / Мутанты по диффу (6/6): затронутые свидетели краснеют (push) Skipped
Проверка (CI) / Фронтенд: типы, юниты, мутанты, синхрон бандла (push) Skipped
Проверка (CI) / Предполёт: документация, провенанс, процесс (push) Failing after 58s
Проверка (CI) / Переиспользование: это дерево уже проверено (push) Successful in 1m10s
Проверка (CI) / Смоки в браузере (шард 1 из 3) (push) Skipped
Проверка (CI) / Смоки в браузере (шард 2 из 3) (push) Skipped
Проверка (CI) / Смоки в браузере (шард 3 из 3) (push) Skipped
Проверка (CI) / Смоки: все шарды зелёные (push) Skipped
Проверка (CI) / Golden-кадры против принятых эталонов (push) Skipped
Проверка (CI) / Перф-смок: бюджет времени кадра (push) Skipped
Проверка (CI) / Геометрия: TS/Python parity исполнена (push) Skipped
Проверка (CI) / Бэкенд: pytest в Home Assistant (push) Skipped
Проверка (CI) / Доказательство выполненных проверок (push) Failing after 37s
docs: review document for #641
Issue: #641
User-Visible: no
2026-09-23 17:53:54 +00:00

12 KiB
Raw Blame History

Код-ревью #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 — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
  • Дерево материала: ad3826fd48aaf89c6ab66487b18ce9bc590e6180
    git log --all --format='%H %T' | grep ad3826fd48aa
    
  • Тело issue: 1a1d7660a1cab43873f74127511d21fecf30767f7af959c6ecf820e6efbd2a51
  • Вердикт конвейера: green · High 0