Files
houseplan-card/docs/reviews/SPEC-REVIEW-464-r1.md
T
2026-09-05 21:14:15 +00:00

180 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SPEC-REVIEW-464-r1
- **Issue:** https://github.com/Matysh/houseplan-card/issues/464
- **Этап:** ТЗ (PROCESS.md §2.4), трек — полный
- **ТЗ:** `docs/specs/464-zigbee-topology-layer-order.md` на ветке
`issue/464-zigbee-topology-layer`
- **Заход:** r1 (первый), блокирующих циклов израсходовано 0/4
- **Материал ревью:** ветка `issue/464-zigbee-topology-layer`, HEAD
`aae9efb9ff251ef1471cab685dee2c8c785dea5c`, коммит «docs: specify Zigbee
topology layer order» (`Issue: #464` · `User-Visible: no`). Диапазон изменений
от `origin/dev`: только `docs/specs/464-zigbee-topology-layer-order.md`
(новый, 455 строк) и `docs/specs/README.md` (+2/-1). Продуктовый код не
тронут — соответствует хендоффу автора и статусу `S4-spec-review`.
## Скоуп ревью
Задача переведена аналитикой с `trivial` на полный трек: причина названа явно
(изменение публичного контракта слоёв, закреплённого в #54/#457, пересечение
full-card compositor/lazy overlay/live-camera projection) — критерий §5
«нет нового UX-контракта» не проходит, и это названо, а не подразумевается.
Продуктовых вопросов у владельца по существу два, и оба уже закрыты его же
комментарием в issue до написания ТЗ: точный порядок трёх уровней и параметры
окантовки серого пунктира (1 px, `#2e2e2e`, просветы сохраняются). ТЗ проверено
на точное соответствие этому комментарию.
## Как проверялось
1. Прочитаны `docs/SCOPE.md`, `AGENTS.md`, `PROCESS.md` целиком (включая §2.4,
§2.5, §2.10, §5, §7.1, §7.2), тело issue #464 и все пять комментариев (включая
уточнение владельца, две редакции аналитики и хендофф автора).
2. Прочитан документ ТЗ целиком, сверен на присутствие всех разделов §7.1.
3. Проверены на согласованность с ТЗ канонические документы подсистемы —
`docs/specs/054-zigbee-topology-overlay.md`, `docs/specs/457-zigbee-route-arrows.md`,
`docs/ARCHITECTURE.md` (раздел «Contextual Zigbee topology»), `docs/UX-MODES.md`,
`docs/USER-GUIDE.ru.md` (раздел про связи Zigbee).
4. Технические утверждения §3 (root cause) сверены построчно с текущим кодом
`dev` — не как код-ревью, а чтобы отличить подтверждённый факт от догадки,
выданной за решение:
- место монтирования: `renderZigbeeTopologyOverlay(...)` вызывается прямо
перед `<div class="devlayer" data-hp-live-layer="camera">` в
`src/houseplan-card.ts:11827` → `:11839` — подтверждает «overlay — sibling
перед `.devlayer`»;
- `z-index`: `:host` в `src/hp-zigbee-topology-overlay.ts:45` = `5`,
`.devlayer` в `src/styles/plan.styles.ts:1306-1310` = `6` — подтверждает
заявленный конфликт уровней;
- двойная camera-проекция: `data-hp-live-layer="camera"` сейчас стоит и на
host-теге оверлея (`src/zigbee-topology-overlay-bridge.ts:21`), и на
`.devlayer` независимо, а `live-viewport.ts:101,155` перебирает оба
совпадения `querySelectorAll` — подтверждает мотивацию §7.4 «убрать
собственную camera-проекцию у вложенного overlay»;
- контракт unknown-LQI сегодня: один `<line stroke-width=2 stroke-dasharray="5 5">`
без обводки (`src/hp-zigbee-topology-overlay.ts:237-238`), плюс глобальное
`line { vector-effect: non-scaling-stroke }` (строка 47) — подтверждает, что
план «второй совпадающий stroke шире, тот же non-scaling-stroke» технически
реализуем без новых свойств;
- `docs/specs/054-...md:154-155` действительно фиксирует «над
архитектурой/decor, но под device markers» — старый контракт, который #464
заменяет, назван и процитирован верно.
5. Проверена реализуемость заявленного способа доказательства AC, а не только
его название: raster-probe через `createImageBitmap`/`OffscreenCanvas`) — уже
рабочий паттерн в `demo/smoke_device_icon_pixel_alignment.mjs`,
`demo/smoke_active_chain_ink.mjs`, `demo/smoke_grid_scale_invariance.mjs`,
`demo/golden/run.mjs`; `npm run benchmark:zigbee-topology` уже существует в
`package.json`; `scripts/mutation-gate.mjs` уже содержит мутанты для
`zigbee-topology*` (`zigbee-topology-zha-read-starts-scan`,
`zigbee-topology-ambiguous-marker-selected` и др.) — расширение тем же
инструментом, не изобретение нового.
6. Проверены трейлеры коммита (`Issue: #464`, `User-Visible: no` — корректно для
документации без продуктового поведения) и двусторонняя связь issue ↔ ТЗ ↔
`docs/specs/README.md` (запись добавлена, ссылка на файл и issue на месте).
7. Дешёвые гейты не гонялись повторно: диапазон правок — только `docs/specs/**`
(класс C), продуктовый код не менялся, `typecheck`/`test`/`build` не могут
покраснеть от .md-файла. Указанный в контексте зелёный Validate на этом же
SHA (`aae9efb9`) относится к предыдущему код-ревью, а не к этому документу;
для спек-ревью он не требуется и не использовался как замена чтения.
## Находки
Не найдено ни одной блокирующей (High) находки. Находок Medium/Low в скоупе
задачи и вне его — нет.
Ниже — что отдельно проверялось на «догадку, выданную за факт», и почему не
стало находкой:
- Три уровня z-порядка (§4, §7.1) — не придуманы автором, а дословно повторяют
уточнение владельца от 2026-09-05 в комментарии issue. Совпадение точное.
- Параметры окантовки unknown-LQI (§8: `#2e2e2e`, 4 px casing / 2 px core → 1 px
с каждой стороны, сохранённые просветы) — арифметика прямо выводится из
уточнения владельца («обводка 1 px», «сохранение прозрачных промежутков»), а
не изобретена.
- Технические причины, почему «просто поднять z-index» и «снять stacking
context с `.devlayer`» не работают (§3) — подтверждены чтением реального кода,
а не заявлены голословно (см. «Как проверялось», п.4).
- Технические решения реализации (namespaced-атрибут на `.dev`, bounded
`MutationObserver(childList)`, второй `<line>` вместо SVG-фильтра, локальные
уровни 7/8) вынесены в явный раздел §20 «Принятые технические предположения —
можно менять на ревью» — это правильная граница §7.1: не продуктовый вопрос
владельцу, а решаемая автором и оспариваемая ревьюером деталь. Возражений по
существу к перечисленным пяти пунктам нет: способ (второй непрерывный `<line>`
той же геометрии) корректно даёт кромку без превращения зазоров в сплошную
линию, а `childList`-only observer с отключением в `disconnectedCallback`
соответствует уже описанному в §12 требованию «не создавать цикл/leak».
- Открытых продуктовых вопросов к владельцу в тексте ТЗ нет, и в текущем виде
они и не нужны: оба вопроса, которые вообще относятся к продуктовому классу
(§7.1: что видно, какой объём изменений), уже закрыты его же комментарием до
начала написания ТЗ.
## Что проверено и корректно
- Все обязательные разделы §7.1 присутствуют: сценарий (§1) · что человек
увидит до/после (§2) · проблема и подтверждённая причина (§3) · скоуп (§5) и
не-скоуп (§6) · контракт поведения (§7-8) · режимы/touch/доступность (§9) ·
модель данных и миграция (§10) · i18n (§11) · AC1-AC3 с доказательством (§14)
· план автотестов (§15) · риски (§17) · откат (§18) · release-артефакты (§19).
- AC1-AC3 пронумерованы, каждый указывает способ доказательства
(`smoke` + raster + ревью кода / `smoke` + mutation), формулировки однозначны
— можно проверить по конкретным пиксельным точкам и computed stacking level,
а не по общему впечатлению.
- Не-скоуп (§6) корректно отсекает смежные темы (получение snapshot, adapters,
состав incident links/route selection, цветовая шкала известного LQI, любые
config/i18n/backend изменения, touch/kiosk/editors) и явно обязывает вернуть
задачу в `S3-spec`, если потребуется их затронуть.
- Откат (§18) конкретен: один продуктовый коммит убирает namespaced-атрибут,
второй stroke и возвращает overlay в sibling-позицию; данных/config
миграции нет, поэтому откат кода данных не касается.
- Release-артефакты (§19) полны: оба changelog, оба User Guide, ARCHITECTURE.md,
TESTING.md, явная пометка supersede в #54/#457, обоснование отсутствия нового
постоянного golden-эталона (hover — не часть golden matrix), обязательность
`golden:verify`, `bundle:budget`, mutation, полного Linux docs-screenshot цикла
(поскольку меняется `src/**`).
- Производительность (§12) и security/privacy (§13) описаны предметно и не
содержат новых поверхностей: lazy-загрузка не расширяется, endpoint sync
ограничен DOM текущего space, DOM-атрибут не содержит IEEE/entity id.
- Трейлеры коммита корректны (`Issue: #464`, `User-Visible: no`), ветка и имя
файла соответствуют конвенции, `docs/specs/README.md` обновлён и ссылается на
файл, файл ссылается на issue.
## Чего не проверял
- Не проверялся продуктовый код — его не существует в этой ветке на момент
ревью (класс A не тронут ни одним файлом), что и требуется на этапе ТЗ.
- Не прогонялись `npx tsc --noEmit`, `npm test`, `npm run build` — диапазон
правок ограничен `docs/specs/**` (класс C), эти гейты не могут быть
чувствительны к markdown-диффу, и запуск не дал бы дополнительного сигнала.
- Не запускались браузерные смоки, `golden:verify`, `bundle:budget`,
`benchmark:zigbee-topology`, `mutation-gate.mjs` — на этом этапе продукта,
которого они проверяют, ещё нет; их реализуемость и совместимость с
существующей инфраструктурой проверена чтением (см. «Как проверялось», п.5),
а не исполнением, поскольку исполнять пока нечего.
- Не проверялась реализация #457/#459 построчно за пределами тех фрагментов,
что нужны были для сверки цитируемого контракта (§3, §6 «Связано»).
## Материал раунда
- Ветка: `issue/464-zigbee-topology-layer`
- SHA материала: `aae9efb9ff251ef1471cab685dee2c8c785dea5c`
- ТЗ: `docs/specs/464-zigbee-topology-layer-order.md` (новый файл на этом SHA)
- Предыдущего раунда нет — это r1, разделы «Закрытие раунда r0» и
«Унаследовано из r0» не применяются.
## Вердикт
Зелёный. Готово к разработке.
---
<!-- material-anchors: сгенерировано конвейером (#414) -->
## Материал раунда
- Ветка: `issue/464-zigbee-topology-layer`, коммит `aae9efb9ff25` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
- Дерево материала: `0d024bed021c9e5afb86b77757195a1de1034813`
```
git log --all --format='%H %T' | grep 0d024bed021c
```
- ТЗ `docs/specs/464-zigbee-topology-layer-order.md`, блоб `fbefda4d5cf5acf53895d037cf7b0a5a1cf484f2`
```
git log --all --find-object=fbefda4d5cf5acf53895d037cf7b0a5a1cf484f2 -- docs/specs/464-zigbee-topology-layer-order.md
```