mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
docs: review document for #464
Проверка (CI) / Классификация изменённых файлов (push) Successful in 29s
Проверка (CI) / Предполётные проверки: документация, провенанс, процесс (push) Failing after 1m9s
Проверка (CI) / Переиспользование: это дерево уже проверено (push) Successful in 42s
Проверка (CI) / HACS: валидация репозитория (push) Failing after 26s
Проверка (CI) / Hassfest: манифест интеграции (push) Failing after 31s
Проверка (CI) / Бэкенд: pytest в Home Assistant (push) Failing after 8m56s
Проверка (CI) / Фронтенд: типы, юниты, мутанты, синхрон бандла (push) Failing after 11m56s
Проверка (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) / Классификация изменённых файлов (push) Successful in 29s
Проверка (CI) / Предполётные проверки: документация, провенанс, процесс (push) Failing after 1m9s
Проверка (CI) / Переиспользование: это дерево уже проверено (push) Successful in 42s
Проверка (CI) / HACS: валидация репозитория (push) Failing after 26s
Проверка (CI) / Hassfest: манифест интеграции (push) Failing after 31s
Проверка (CI) / Бэкенд: pytest в Home Assistant (push) Failing after 8m56s
Проверка (CI) / Фронтенд: типы, юниты, мутанты, синхрон бандла (push) Failing after 11m56s
Проверка (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
Issue: #464 User-Visible: no
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
# CODE-REVIEW-464-r2
|
||||
|
||||
- **Issue:** https://github.com/Matysh/houseplan-card/issues/464
|
||||
- **Ветка:** `issue/464-zigbee-topology-layer`
|
||||
- **Материал:** `git diff origin/dev...HEAD` на SHA `87cab133ac345c2283050bbea27ce73534393794`
|
||||
(= текущий `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` на SHA
|
||||
`276bf193a2bec40a3c2fc823d364cbda00ac10d5`; дельта 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` на SHA `276bf193`** — зелёный 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` получили по абзацу, описывающему именно этот
|
||||
инвариант (реальный `:hover` vs синтетический `pointerover`) — согласуется
|
||||
с находкой r1 дословно. `87cab133` несёт `User-Visible: no` — корректно,
|
||||
видимых кадров это не меняет (imageSha256 не тронут).
|
||||
- **Инварианты модели вне периметра** — дельта не касается геометрии,
|
||||
подтверждено чтением диффа: единственный продуктовый файл — CSS-стили.
|
||||
|
||||
## Чего не проверял
|
||||
|
||||
- Полный `mutation-gate.mjs --check` (весь проект) и оставшиеся 6 старых
|
||||
мутантов задачи — несоразмерно точечной правке, не задеты дельтой.
|
||||
- `npm test` целиком и `npm run build` отдельным прогоном юнит-сьюта — положился
|
||||
на зелёный Validate точного SHA `87cab133`; лично воспроизвёл только
|
||||
`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**
|
||||
|
||||
---
|
||||
|
||||
<!-- material-anchors: сгенерировано конвейером (#414) -->
|
||||
|
||||
## Материал раунда
|
||||
|
||||
- Ветка: `issue/464-zigbee-topology-layer`, коммит `87cab133ac34` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
|
||||
- Дерево материала: `445cc106c18942021aa8209aeac33ac47f1ccbda`
|
||||
```
|
||||
git log --all --format='%H %T' | grep 445cc106c189
|
||||
```
|
||||
- ТЗ `docs/specs/464-zigbee-topology-layer-order.md`, блоб `043ada287e048ed9750080c342b2a2fdb869d9f0`
|
||||
```
|
||||
git log --all --find-object=043ada287e048ed9750080c342b2a2fdb869d9f0 -- docs/specs/464-zigbee-topology-layer-order.md
|
||||
```
|
||||
Reference in New Issue
Block a user