Issue: #464 User-Visible: no
16 KiB
CODE-REVIEW-464-r2
- Issue: https://github.com/Matysh/houseplan-card/issues/464
- Ветка:
issue/464-zigbee-topology-layer - Материал:
git diff origin/dev...HEADна SHA87cab133ac345c2283050bbea27ce73534393794(= текущийHEADдетач-чекаута ревьюера, совпадение провереноgit rev-parse HEAD) - Трек: полный (не менялся с r1)
- Заход: r2 · блокирующих циклов израсходовано 1 из 4 (потрачен в r1, жёлтым; зелёный вердикт этого раунда цикл не тратит — §4)
Скоуп раунда
Разбор по дельте (PROCESS.md §2.9): предыдущий раунд (CODE-REVIEW-464-r1.md,
жёлтый, SHA 276bf193) закрыт одной находкой High-1. Дельта этого раунда —
git diff 276bf193..HEAD, 2 коммита (0f7b0dff продукт+тесты+доки,
87cab133 только docs/images/screenshots.json), локальна: правит один CSS-селектор,
расширяет один smoke и добавляет один mutation-gate мутант под уже найденный
дефект. Ребейза на ушедший вперёд dev не было, новая подсистема не задета,
контракт поведения не сменился (AC1 из ТЗ не переписан, только доказан) — полный
разбор не требуется, разбираю дельту плюс всё, до чего она дотягивается.
Файлы дельты (без dist/** и custom_components/houseplan/frontend/**,
класс D — сверены пересборкой, см. гейты):
src/styles/devices.styles.ts— продуктовый фикс (класс A)demo/smoke_zigbee_topology_hover.mjs,scripts/mutation-gate.mjs— тесты (класс B)docs/specs/464-zigbee-topology-layer-order.md,docs/TESTING.md,docs/CHANGELOG.md,docs/CHANGELOG.ru.md,docs/images/screenshots.json— документация (класс C)
Закрытие раунда r1
| Находка | Чем закрыта | Где это видно |
|---|---|---|
High-1: реальный курсор мыши над hovered-source endpoint матчит старое правило :host([data-pointer-hover]) .dev:hover { z-index: 5 } (специфичность (0,4,0)) сильнее нового .dev[data-hp-zigbee-topology-endpoint] { z-index: 8 } (специфичность (0,2,0)); оверлей стоит на z-index: 7 → 5 < 7, линия рисуется поверх маркера-источника |
Добавлено правило той же специфичности что и конфликтующее плюс атрибут endpoint плюс :hover — (0,5,0), что строго выше (0,4,0) и решает каскад в пользу endpoint независимо от порядка объявления |
src/styles/devices.styles.ts:345 — :host([data-pointer-hover]) .dev[data-hp-zigbee-topology-endpoint]:hover { z-index: 8; }. Доказано исполнением: smoke добавил блок с настоящим page.mouse.move (не dispatchEvent) и result.realPointerEndpointWins (demo/smoke_zigbee_topology_hover.mjs:555-579); лично прогнан node demo/smoke_zigbee_topology_hover.mjs → OK, "realPointerEndpointWins": true. Тест умеет падать: новый мутант zigbee-topology-hovered-endpoint-elevation-removed (scripts/mutation-gate.mjs:6067-6076) занижает z-index новой строки до 1; лично прогнан node scripts/mutation-gate.mjs --id=zigbee-topology-hovered-endpoint-elevation-removed → «покраснел, как обязан» |
Других находок в r1 не было (Medium: 0).
Унаследовано из r1
Принято без повторной проверки — делта их не задевает:
- AC2 (ownership/lifecycle/single-projection) и AC3 (casing неизвестного
LQI) — доказаны чтением и исполнением в
CODE-REVIEW-464-r1.mdна SHA276bf193a2bec40a3c2fc823d364cbda00ac10d5; дельта r2 не трогаетhp-zigbee-topology-overlay.ts,zigbee-topology-overlay-bridge.ts,houseplan-card.ts— файлы, где эти AC реализованы. - Ревью ТЗ —
SPEC-REVIEW-464-r1.md, зелёное, SHA спекиaae9efb9. - Гейты
typecheck/test/build/bundle/no-new-any/process-gate/benchmark:zigbee-topologyна SHA276bf193— зелёный Validate (run 33994548645), зафиксировано вCODE-REVIEW-464-r1.md. - i18n, трейлеры структуры коммитов, cleanup-матрица (pointerleave/touch/ pen/mode/space/setting/disconnect) — проверены в r1, дельта их не касается.
Как проверялось в этом раунде
| Гейт | Статус | Как |
|---|---|---|
typecheck / npm test / npm run build + 3 копии бандла |
✅ зелёный, не перегонял отдельно | Validate на точном SHA 87cab133: https://github.com/Matysh/houseplan-card/actions/runs/33996034405 (success) — «дешёвые гейты на этом SHA уже подтверждены». Дополнительно лично прогнал npm run bundle:sync (tsc --noEmit && rollup -c внутри) для собственного воспроизведения — зелёный, git status после чист: пересборка байт-в-байт совпала с закоммиченным dist/**/custom_components/houseplan/frontend/** |
node scripts/check-docs.mjs |
✅ зелёный | Прогнал сам: Documentation checks passed (7 files, 12 external links); diff трогает src/**, отпечаток скриншотов обязателен — коммит 87cab133 обновляет только sourceFingerprint/sourceSha256, все imageSha256 побайтно не изменились (сверено чтением диффа docs/images/screenshots.json) |
node demo/smoke_zigbee_topology_hover.mjs (прямое совпадение smoke-select.mjs) |
✅ зелёный | Прогнал сам после bundle:sync: OK, включая новый realPointerEndpointWins: true |
Мутант zigbee-topology-hovered-endpoint-elevation-removed |
✅ красный при повреждении, как обязан | Прогнал сам: node scripts/mutation-gate.mjs --id=zigbee-topology-hovered-endpoint-elevation-removed → «поймано 1 из 1» |
node scripts/smoke-select.mjs --base origin/dev --head HEAD |
✅ выполнен | Прямое совпадение: только smoke_zigbee_topology_hover.mjs (уже прогнан выше). 29 слабых связей — все по одному распространённому символу _mode; дельта не трогает переключение режимов (только CSS-селектор hover/endpoint и тесты/доки) — решил не гонять, риска регрессии не вижу |
npm run golden:verify |
не гонял | В demo/golden/** нет Zigbee-topology-сценария (проверено чтением demo/golden/matrix.mjs и содержимого demo/golden/); дельта не расширяет видимый в golden рендер, а обновлённый скриншот-фингерпринт уже подтверждён check-docs.mjs и байт-в-байт сверкой imageSha256 |
Остальные 6 из 7 старых мутантов задачи + полный mutation-gate.mjs --check |
не гонял | Не задеты дельтой (файлы мутантов для AC2/AC3 не менялись); наследую зелёный статус r1/хендоффа автора; полный --check — предрелизный объём, несоразмерен точечной правке |
npm run invariants |
не гонял | Дельта не трогает геометрию комнат/стен, layout, marker.space, open_spans — только экранный z-index topology-оверлея |
python -m pytest tests_backend |
не гонял | Диапазон не трогает custom_components/**/*.py |
npm run benchmark:zigbee-topology, bundle:budget, no-new-any, process-gate --issues |
не гонял | Не задеты дельтой; зелёный статус наследую из Validate на 87cab133 и хендоффа автора r2 (перечислены поимённо в его комментарии) |
Что проверено и корректно
- Специфичность CSS разрешает конфликт правильно. Новое правило
:host([data-pointer-hover]) .dev[data-hp-zigbee-topology-endpoint]:hoverвесит(0,5,0)— строго больше конфликтующего:host([data-pointer-hover]) .dev:hover(0,4,0)— независимо от порядка объявления в файле. Проверено и расчётом, и (сильнее) реальным исполнением черезpage.mouse.move. - Нет скрытых конфликтов той же природы. Перепроверил чтением все
z-index-правилаdevices.styles.ts(grep) — единственная другая hover-зависимая пара (.dev:focus-visible { z-index: 5 }) реагирует на клавиатурный фокус, а не на реальный курсор; топология активируется только реальным mouse-hover (зафиксировано ещё в аналитике issue: «touch и kiosk не меняются, топология доступна только admin + mouse hover»), так что этот путь не достижим для endpoint-элементов и не относится к AC1. - Мутант защищает именно новую строку, а не дублирует старый:
find/replaceбьёт по селектору с:hover, отличному от базовогоzigbee-topology-endpoint-elevation-removed;idуникален (grep -c= 1 по всему файлу). - Регрессионный smoke использует настоящий курсор, а не синтетический
dispatchEvent— то же средство, которым сам дефект был найден в r1; ждёт до 5 c появления:hover+ атрибута + отрисованной линии перед сравнениемgetComputedStyle(...).zIndex, что исключает гонку с отрисовкой. - Документация и трейлеры.
CHANGELOG.md/CHANGELOG.ru.mdв одном коммите сUser-Visible: yes(0f7b0dff), формулировка «including the one under the pointer» / «включая маркер прямо под курсором» точно описывает зафиксированное поведение и не расширяет сам контракт.docs/TESTING.mdи ТЗdocs/specs/464-...mdполучили по абзацу, описывающему именно этот инвариант (реальный:hovervs синтетическийpointerover) — согласуется с находкой r1 дословно.87cab133несётUser-Visible: no— корректно, видимых кадров это не меняет (imageSha256 не тронут). - Инварианты модели вне периметра — дельта не касается геометрии, подтверждено чтением диффа: единственный продуктовый файл — CSS-стили.
Чего не проверял
- Полный
mutation-gate.mjs --check(весь проект) и оставшиеся 6 старых мутантов задачи — несоразмерно точечной правке, не задеты дельтой. npm testцеликом иnpm run buildотдельным прогоном юнит-сьюта — положился на зелёный Validate точного SHA87cab133; лично воспроизвёл толькоtsc --noEmit && rollup -cчерезbundle:sync.- 29 смоков со слабой связью по символу
_mode— не гонял, дельта не трогает переключение режимов; решение зафиксировано в таблице гейтов. - Реальное touch/pen устройство за пределами эмуляции
pointerType— тот же довод, что и в r1: различие смок/реальное устройство здесь не той природы, что в закрытой находке (pointerType— явное поле события, не завязано на hit-testing браузера, в отличие от:hover). - Визуальный скриншот итоговой сцены — числовой
getComputedStyle(...).zIndexуже является единственным источником, управляющим порядком отрисовки; дополнительный кадр ничего не добавил бы.
Единый источник числа
Дельта не вводит и не меняет пользователем видимую величину (числовое
значение, дублируемое в двух местах интерфейса) — правится исключительно
порядок отрисовки (z-index), самого числа/значения пользователю не
показывается. test/single-source-numbers.test.mjs не затрагивается дельтой
(файл не менялся, диапазон не относится к value-badge/подписям).
Вывод
High-1 из r1 закрыт: причина (специфичность CSS :hover выше специфичности
endpoint-правила) устранена добавлением правила ещё большей специфичности,
доказано личным исполнением smoke с настоящим курсором и личным исполнением
нового защитного мутанта, который краснеет при откате правки. Других находок
не внесено. AC2/AC3 наследуются из r1 без повторной проверки — дельта их не
касается. Документация и трейлеры в порядке.
Вердикт: зелёный · заход r2 · блокирующих циклов 1/4 · High: 0 · Medium: 0
Материал раунда
- Ветка:
issue/464-zigbee-topology-layer, коммит87cab133ac34— ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. - Дерево материала:
445cc106c18942021aa8209aeac33ac47f1ccbdagit log --all --format='%H %T' | grep 445cc106c189 - ТЗ
docs/specs/464-zigbee-topology-layer-order.md, блоб043ada287e048ed9750080c342b2a2fdb869d9f0git log --all --find-object=043ada287e048ed9750080c342b2a2fdb869d9f0 -- docs/specs/464-zigbee-topology-layer-order.md