docs: review document for #464

Issue: #464
User-Visible: no
This commit is contained in:
claude[bot]
2026-09-05 21:14:15 +00:00
parent aae9efb9ff
commit a6004fc5f3
+179
View File
@@ -0,0 +1,179 @@
# 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
```