16 KiB
CODE-REVIEW-651-r2
Материал раунда: git log --oneline origin/dev..HEAD / git diff c40266431ca1335ed09ebbaace9656b55ee84e23..HEAD, SHA
e73e56dd943675846fd3de91d98d55d1cbd7c148 (рабочая копия уже на нём). Один
коммит в дельте: e73e56dd (test(2.5D): cover rigid group boundaries and fallback, Issue: #651, User-Visible: no).
Скоуп
Дельта r1 → r2 — ровно два файла: test/iso-overlays.test.mjs (+60 строк, два
новых теста) и scripts/mutation-registry.mjs (+27 строк, два новых мутанта).
Продуктовый код (src/iso-overlays.ts, src/iso-scene-render.ts,
src/houseplan-card.ts), документация 2.5D и оба changelog не менялись —
это подтверждает и трейлер User-Visible: no на единственном коммите.
Дельта строго локальна (PROCESS.md §2.10): она закрывает ровно две находки
CODE-REVIEW-651-r1 и не задевает ничего, что было прочитано и принято в r1.
Разбор ниже ограничен AC1 и AC4 — единственными AC, которые эта дельта
задевает.
Закрытие раунда r1
| Находка r1 | Чем закрыта | Где это видно |
|---|---|---|
| Medium-1 — AC1 «другая комната исключена» не доказан ни тестом, ни мутацией | Новый тест rigid overlay groups never join close markers owned by different rooms (test/iso-overlays.test.mjs:149) ставит два близких значка по разные стороны общей стены в разные комнаты и требует nudgeCss разных знаков/значений; новый мутант iso-rigid-groups-cross-room-boundary (scripts/mutation-registry.mjs) снимает точно ту же проверку owner.id, что была найдена в r1 (src/iso-overlays.ts:1738) |
Перечитал патч и воспроизвёл вручную: применил патч мутанта к рабочей копии, тест упал (AssertionError: the right-room marker clears the shared wall into its own room); откатил патч — тест снова зелёный. Тот же мутант зелёно пойман в CI (Мутанты по диффу 1–6/6, run 36209228318) |
| Medium-2 — AC4 «деградированный fallback группы» не доказан ни тестом, ни мутацией | Новый тест rigid fallback prioritizes room, then wall, then overlap inside the 48px cap (test/iso-overlays.test.mjs:169) проверяет status/reason/nearWallAfter/nudgeDistanceCss деградированного размещения; новый мутант iso-rigid-fallback-drops-room-wall-overlap-priority вырезает найденную в r1 цепочку приоритетов roomViolations → wallViolations → overlapPenalty в rigidFallbackOrder (src/iso-overlays.ts:1690), оставляя только сортировку по расстоянию |
Воспроизвёл вручную: применил патч мутанта, тест упал (expected: 'overlay-collision', actual: 'nudge-cap' — без приоритета алгоритм выбирает более короткий, но упирающийся в 48 px кандидат вместо кандидата, сохраняющего стену/комнату); откатил патч — тест снова зелёный. Тот же мутант зелёно пойман в CI |
| Low — неточная формулировка «проверяется существующими Linux golden-сценами» в комментарии автора к реализации | Снята ревьюером r1 без правки («не меняет вердикт и не требует действий») | docs/reviews/CODE-REVIEW-651-r1.md, раздел «Low» — решение зафиксировано, новых действий в r2 не требовалось и не предпринималось |
Обе Medium-находки были в скоупе задачи (собственный тестовый план §10.1 уже одобренного ТЗ) — не отдельные issue.
Унаследовано из r1 (без повторной проверки)
Продуктовый код не менялся между c4026643 и e73e56dd, поэтому следующее
принято из docs/reviews/CODE-REVIEW-651-r1.md (материал: SHA c4026643,
дерево 7afb4dcc4787...) без повторного разбора:
- AC2/AC3 (один вектор на группу, инвариантность к zoom/pan/remount) —
подтверждено в r1 чтением, unit-тестами и двумя браузерными смоками
(
desktopZoomKeepsOverlayScene,touchPinchKeepsOverlayScene). - AC5/AC6 (desktop и touch/kiosk сценарии) — те же браузерные смоки, r1.
- AC7 (визуальный контракт) — полный
golden:verify(245 сценариев) прогнан и разобран вручную в r1; 5 ожидаемыхdifferent, новый baseline не принят (верно по AC7). Дельта r1→r2 не трогает рендер, поэтому golden не перегонялся повторно. - AC8 (перформанс) — оба профиля прогнаны на точном SHA
c4026643в r1; дельта r1→r2 не меняет исполняемый код в горячем пути. - AC9 (отсутствие побочных изменений: room labels, vacuum, glow, проёмы, Flat, редакторы) — подтверждено чтением в r1.
- Три копии бандла (
dist/,custom_components/.../frontend/,demo/srv/assets/) синхронны — подтверждено в r1; дельта r1→r2 не трогаетsrc/**, пересборка не требовалась. - Трейлеры и changelog исходного функционального коммита
4ab7ecb4— проверены в r1.
Как проверялось (гейты этого раунда)
Validate на точном SHA e73e56dd зелёный —
https://github.com/Matysh/houseplan-card/actions/runs/36209228318 (проверено
gh run view: headSha совпадает, conclusion: success). Это подтверждает
дешёвые гейты и все 6 шардов «Мутанты по диффу», включая оба новых мутанта
#651. Дифф раунда не трогает src/** за пределами scripts/mutation-registry.mjs
(не продуктовый код) и не меняет демо/рендер — golden, browser-смоки,
perf-профили и check-docs.mjs из r1 остаются в силе без перегона.
| Гейт | Статус | Кем/чем подтверждено |
|---|---|---|
npx tsc --noEmit / test-build |
🟢 | прогнан лично (tsc -p tsconfig.test.json && fix-test-build.mjs), 0 ошибок; тот же прогон подтверждён Validate |
npm test (полностью) |
🟢 (не дублировал целиком) | зелёный job «Фронтенд…» в Validate на этом SHA; лично прогнал целиком test/iso-overlays.test.mjs + test/iso-scene-render.test.mjs — 52/52 (совпадает с заявкой автора), и отдельно test/mutation-gate.test.mjs + test/mutation-guard-outcome.test.mjs — 89/89 |
| Мутационные свидетели r1 (2 новых) — «чем краснеет» | 🟢, проверено исполнением | вручную применил оба патча мутантов по очереди к рабочей копии, пересобрал test-build, прогнал целевые тесты — оба упали с ожидаемой ошибкой (см. таблицу закрытия выше); откатил патчи, рабочая копия чиста (git status пуст) |
npm run build + сверка 3 копий бандла |
не прогонял отдельно | дифф раунда не трогает src/**; сборка не может измениться, и Validate это же подтверждает (задача «синхрон бандла» в общем job) |
node scripts/check-docs.mjs |
не прогонял | дифф раунда не трогает src/** |
| Browser smoke / golden / perf | не перегонял | дифф раунда не меняет исполняемый продуктовый код и рендер; актуальны прогоны r1 (см. «Унаследовано») |
node scripts/smoke-select.mjs |
не прогонял | нет нового диффа в src/**/демо между r1 и r2; смоки уже отобраны и разобраны в r1 для функционального коммита |
npm run invariants |
не прогонял | геометрия/конфигурация не меняются (как и в r1) |
python -m pytest tests_backend |
не прогонял | нет диффа custom_components/**/*.py |
Находки
Нет. Обе Medium из r1 закрыты именно предписанным способом — новым тестом, доказавшим падение через названную мутацию с показанным результатом прогона (требование «чем краснеет», REVIEWER.md), а не переформулированы и не сняты как «не требуется». High-находок не было и не появилось.
Что проверено и признано корректным
- Тесты действительно проверяют заявленное, а не самоочевидную геометрию.
Прочитал оба новых теста построчно: первый использует общую стену между
двумя равными по размеру, но разными по
preferredRoomIdкомнатами и проверяет знаки/неравенство векторов сдвига; второй использует две комнаты с идентичной геометрией (чтобы изолировать порядок приоритетов от побочных эффектов формы комнаты) и проверяет конкретные поля деградации (status,reason,nearWallAfter,nudgeDistanceCss ≤ 48). - «Тест умеет падать» — не по описанию автора, а по личному эксперименту. Оба мутанта применены к рабочей копии вручную (не полагался на CI как на единственное доказательство), оба целевых теста упали с содержательной, а не случайной ошибкой, оба отличаются от «просто assert false» — диагностика показывает, что без защиты алгоритм выбирает геометрически другое (неверное) размещение.
- Мутанты синтаксически и структурно корректны.
test/mutation-gate.test.mjstest/mutation-guard-outcome.test.mjs(89/89) подтверждают, что оба новыхguardсовпадают с реальными именами тестов и не ломают реестр.
- Изоляция дельты.
git diff c4026643..e73e56dd --statпоказывает толькоtest/iso-overlays.test.mjs,scripts/mutation-registry.mjsи ранее опубликованныйdocs/reviews/CODE-REVIEW-651-r1.md/INDEX.md— никакой продуктовый файл не тронут, что делает «унаследовано из r1» законным сокращением объёма, а не догадкой. - Трейлеры. Единственный коммит
e73e56ddнесётIssue: #651иUser-Visible: no— верно, т.к. тестовый/registry-only коммит не меняет видимое поведение, changelog не тронут заслуженно. devне ушёл вперёд.git merge-base origin/dev HEAD=ec2b8c15, тот же коммит, что был базой на момент r1 — ребейза не было, дельта не расширена внешними изменениями.
Чего не проверял и почему
- Полный
npm testцеликом одним прогоном — не дублировал; полагаюсь на зелёный job Validate этого точного SHA плюс личный целевой прогон задетых и registry-тестовых файлов (52 + 89 тестов). npm run build/bundle:sync,check-docs.mjs, golden, browser smoke, perf-профили — не перегонял в этом раунде: дельта r1→r2 не трогаетsrc/**, демо или рендер, поэтому результаты r1 на функциональном коммитеc4026643/4ab7ecb4остаются в силе без повторного исполнения (объём разбора по дельте, PROCESS.md §2.10).npm run invariants,pytest tests_backend,smoke-select.mjs— как и в r1, не применимы: геометрия/конфигурация и Python-код не менялись ни в функциональном коммите, ни в этой дельте.
Вердикт
Обе Medium-находки r1 закрыты предписанным способом: новые тесты с явно показанным падением при снятии именно той защиты, которая была найдена отсутствующей, плюс зарегистрированные мутанты, зелёные в Validate на точном SHA и лично воспроизведённые здесь. Дифф раунда локален, продуктовый код не менялся, унаследованные из r1 доказательства (AC2/AC3/AC5–AC9, golden, перформанс, трейлеры) остаются в силе. Новых находок нет. Вердикт — зелёный.
Документ: docs/reviews/CODE-REVIEW-651-r2.md
Материал раунда
- Ветка:
issue/651-iso-device-layout-stability, коммитe73e56dd9436— ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. - Дерево материала:
79735984216c7cb6d1a8f3bef707d3e990f912d0git log --all --format='%H %T' | grep 79735984216c - Тело issue:
699e063899bf674ad775879fc1a0c889489a2f90b14fde467497787cc8f69442 - Вердикт конвейера:
green· High 0