Files
houseplan-card/docs/reviews/CODE-REVIEW-329-r3.md
T
claude[bot] 2c4b505f1a
Проверка (CI) / Процесс: process.yml идентичен в main и dev (push) Successful in 2m48s
Проверка (CI) / Провенанс коммитов: трейлеры и эталоны (push) Successful in 2m31s
Проверка (CI) / Процессный гейт: диапазон, трейлеры, статусы issue (push) Successful in 2m30s
Проверка (CI) / Классификация изменённых файлов (push) Successful in 36s
Проверка (CI) / HACS: валидация репозитория (push) Skipped
Проверка (CI) / Hassfest: манифест интеграции (push) Skipped
Проверка (CI) / Фронтенд: типы, юниты, мутанты, синхрон бандла (push) Skipped
Проверка (CI) / Переиспользование: это дерево уже проверено (push) Successful in 38s
Проверка (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) / Бэкенд: pytest в Home Assistant (push) Skipped
Проверка (CI) / Документация: гайды, ченджлоги, скриншот-индекс (push) Failing after 47s
docs: review document for #329
Issue: #329
User-Visible: no
2026-08-27 21:49:59 +00:00

13 KiB
Raw Blame History

CODE-REVIEW-329-r3

Этап: code · заход r3 · блокирующих циклов израсходовано 2 из 4

Скоуп раунда

Предыдущий вердикт (code r2, 226-й комментарий issue) — красный, единственная находка r2-H1: мутант junction-limit-backend-raw-baseline в scripts/mutation-gate.mjs был добавлен с guard: 'python3 -m pytest tests_backend/test_junction_limits.py -q', в обход конвенции ВСЕХ прочих бэкенд-мутантов реестра (node scripts/backend-test-guard.mjs <pattern> <file>), из-за чего test/mutation-gate.test.mjs красился на CI.

Вердикт r2 получен на SHA 26c6e870 (Matysh: «Актуальный HEAD ветки для ревью — 26c6e870», непосредственно перед вердиктом). Автор закрыл находку коммитом 273b0d5e, текущий HEAD.

Дельта этого раунда:

git diff 26c6e870..HEAD --stat  (без docs/reviews/*)
 scripts/mutation-gate.mjs   | 4 ++--
 test/mutation-gate.test.mjs | 6 +-----
 2 files changed, 3 insertions(+), 7 deletions(-)

Дельта не затрагивает src/**, бэкенд-продакшен-код, геометрию, документацию пользователя — только реестр мутантов и его контрактный тест. Это ровно то, что запрошено находкой r2-H1, без побочных правок. Разбор по дельте признан достаточным: изменение локально, не является ребейзом, не меняет контракт поведения продукта и по объёму несопоставимо мало относительно исходной задачи (две строки правки guard + возврат теста к исходному виду).

Что проверено (дельта)

  1. Форма guard соответствует конвенции. Новый guard — node scripts/backend-test-guard.mjs test_legacy_baseline_is_judged_after_the_same_migration tests_backend/test_junction_limits.py — совпадает по форме со всеми остальными записями реестра, использующими бэкенд-хелпер (проверено grep -n "backend-test-guard" scripts/mutation-gate.mjs — 16 вхождений, новое неотличимо от прочих).
  2. Контракт теста возвращён к исходному виду. test/mutation-gate.test.mjs снова требует, чтобы guard называл .mjs (убрана временная ветка .py, убран комментарий-объяснение, который её оправдывал). grep подтвердил: других мутантов, называющих .py напрямую (в обход хелпера), в реестре нет — правка не откроет дыру для будущих аналогичных случаев.
  3. Мутант по-прежнему ловит регрессию. Прогнан НЕ ТОЛЬКО --check (проверяет только уникальность якоря патча), а полный цикл конкретного мутанта: node scripts/mutation-gate.mjs --id=junction-limit-backend-raw-baseline →
    ok   чистый прогон: node scripts/backend-test-guard.mjs test_legacy_baseline_is_judged_after_the_same_migration tests_backend/test_junction_limits.py
    ok   junction-limit-backend-raw-baseline: тест покраснел, как обязан
    поймано 1 из 1
    
    То есть подтверждено обеими половинами: код без мутации проходит целевой тест, а с применённым патчем (migrated = config вместо прогона через commit_wall_segment_model) целевой тест красится. Это и есть доказательство «тест умеет падать» для данной находки.
  4. pytest напрямую. python3 -m pytest tests_backend/test_junction_limits.py -q → 8 passed. (pytest в песочнице ревью отсутствовал изначально, установлен pip3 install --user pytest — тот же шаг, что r2 констатировал как разовую особенность окружения, не продукта.)
  5. npm test → # tests 1391 / # pass 1390 / # fail 0 / # skipped 1, совпадает с итогом, который автор указал в коммите 273b0d5e.
  6. npx tsc --noEmit — чисто (дельта не трогает .ts, но прогнан по правилу «всегда»).
  7. npm run build — собрался, dist/houseplan-card.js создан. Сверка бандла: cmp dist/houseplan-card.js custom_components/houseplan/frontend/houseplan-card.js — совпадает побайтово. Третья копия, demo/srv/assets/houseplan-card.js, в дереве отсутствует (она untracked рабочая копия demo-стенда, bundle-sync.mjs создаёт её по требованию) — отсутствие ожидаемо и не связано с этой правкой, дельта фронтенд не трогает.
  8. node scripts/check-docs.mjs → Documentation checks passed (7 files, 10 external links). Формально необязателен (дельта не в src/**), прогнан по инерции — зелёный.
  9. node scripts/smoke-select.mjs --base 26c6e870 --head HEAD → «Исполняемого frontend-диффа нет (src/**/*.ts не тронут). Browser-smoke этим диффом не выбираются — выбирать нечего». Полный прогон смоков не делал — инструмент прямо говорит, что выбирать нечего, а не «неопределённость».

Закрытие раунда r2

Находка Чем закрыта Где это видно
r2-H1: guard бэкенд-мутанта в обход конвенции .mjs-хелпера, контрактный тест красный на CI scripts/mutation-gate.mjs: guard мутанта junction-limit-backend-raw-baseline переписан на node scripts/backend-test-guard.mjs test_legacy_baseline_is_judged_after_the_same_migration tests_backend/test_junction_limits.py; test/mutation-gate.test.mjs: контракт every guard command points at a file that exists возвращён к проверке только .mjs, временная ветка для .py и оправдывающий её комментарий убраны Коммит 273b0d5e; npm test 1390/0 (было 1389 passed/1 failed на 0824e510); точечный прогон node scripts/mutation-gate.mjs --id=junction-limit-backend-raw-baseline — «поймано 1 из 1»

Унаследовано из r2 (и, транзитивно, из r1)

Без повторной проверки исполнением приняты — дельта r3 их не касается кодом, которого они доказывают:

  • H1 (бэкенд мигрирует обе стороны перед сравнением) — доказано в r1, подтверждено закрытым в r2 тестом test_legacy_baseline_is_judged_after_the_same_migration и мутантом. Документ: docs/reviews/CODE-REVIEW-329-r2.md, раздел «Закрытие раунда r1», SHA 26c6e870.
  • M1 (мёртвый код apexCaps/clipPolygonOutsideCap/degenerateApexCaps удалён) — docs/reviews/CODE-REVIEW-329-r2.md, SHA 26c6e870.
  • M2/M3 (дубль раздела USER-GUIDE устранён, канал Resize описан верно) — там же, SHA 26c6e870.
  • M4 (AC10, Optimize не создаёт новых нарушений, доказан двумя юнитами) — там же, SHA 26c6e870.
  • Остальные AC (П1–П5 юниты и границы, §4 честная вершина + golden, AC5a/b, AC7a через реальный pointer-жест, AC7b, паритет AC9, скоуп применения AC8) — впервые проверены и признаны корректными в docs/reviews/CODE-REVIEW-329-r1.md, подтверждены неизменными в r2 (дельта r1→r2 их не трогала за вычетом перечисленных выше M1–M4 и H1); дельта r2→r3 тем более их не трогает (единственные изменённые файлы — scripts/mutation-gate.mjs и test/mutation-gate.test.mjs, не пересекающиеся с производственным кодом junction-limits, рендером или бэкендом). Документ: docs/reviews/CODE-REVIEW-329-r1.md, SHA e1df015d; golden/invariants/мутанты для этих AC — из отчёта r1 («что прогнано»).
  • Полный HA-harness backend не прогоняется — унаследованный пробел окружения, констатирован ещё в r1 (недоступны homeassistant/voluptuous), подтверждён в r2, в r3 не переоценивался — дельта его не касается.

Чего не проверял в этом раунде и почему

  • npm run golden:verify — не прогонял. Дельта не трогает рендер, геометрию, стили, слои; полная матрица (~80 сцен) уже прогнана и зелёная в r2 на коде, который в r3 не менялся.
  • npm run invariants — не прогонял. Дельта не трогает рёбра комнат, записи толщины, layout, marker.space, open_spans — инварианты модели здесь неприменимы.
  • Браузерные смоки — не прогонял ни одного. smoke-select.mjs для диапазона 26c6e870..HEAD прямо сообщает «выбирать нечего»: единственные изменённые файлы — scripts/mutation-gate.mjs и test/mutation-gate.test.mjs, оба вне src/**, ни один смок такой диапазон не оценивает даже как слабую связь.
  • python -m pytest tests_backend -q (полный набор) — прогнал только файл test_junction_limits.py, целевой для находки; полный бэкенд-набор не запускал, так как дельта не трогает бэкенд-продакшен-код (только тест и реестр мутантов на фронтенде/CI), а test_junction_limits.py — тот файл, контракт которого проверяет закрытие r2-H1.
  • Performance-профили — не прогонял, в AC не названы и дельта их не задевает.
  • Полный .github/workflows/mutation-gate.yml (пересборка бандла на каждого мутанта) — не прогонял; это предрелизный гейт (PROCESS.md §8), несоразмерен точечной правке одной записи реестра. Точечный прогон именно этого мутанта сделан отдельно (см. выше) и достаточен как доказательство.

Вывод

Единственная находка r2 (High) закрыта по существу и подтверждена исполнением: guard мутанта следует конвенции, контракт реестра не ослаблен, мутант по-прежнему доказанно ловит регрессию H1 (1/1), npm test и pytest tests_backend/test_junction_limits.py зелёные. Новых находок delta не создаёт — правка изолирована в тестовой инфраструктуре, не пересекается с продакшен-кодом или пользовательским поведением. Trailer коммита (Issue: #329, User-Visible: no) корректен для чисто тестового изменения; changelog не тронут — верно, правок не требовалось.

Вердикт: зелёный.