From a6004fc5f3256bfc58e834942e346f298832a7a6 Mon Sep 17 00:00:00 2001
From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com>
Date: Sat, 5 Sep 2026 21:14:15 +0000
Subject: [PATCH] docs: review document for #464
Issue: #464
User-Visible: no
---
docs/reviews/SPEC-REVIEW-464-r1.md | 179 +++++++++++++++++++++++++++++
1 file changed, 179 insertions(+)
create mode 100644 docs/reviews/SPEC-REVIEW-464-r1.md
diff --git a/docs/reviews/SPEC-REVIEW-464-r1.md b/docs/reviews/SPEC-REVIEW-464-r1.md
new file mode 100644
index 00000000..da0fffc0
--- /dev/null
+++ b/docs/reviews/SPEC-REVIEW-464-r1.md
@@ -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(...)` вызывается прямо
+ перед `
` в
+ `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 сегодня: один ``
+ без обводки (`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)`, второй `` вместо SVG-фильтра, локальные
+ уровни 7/8) вынесены в явный раздел §20 «Принятые технические предположения —
+ можно менять на ревью» — это правильная граница §7.1: не продуктовый вопрос
+ владельцу, а решаемая автором и оспариваемая ревьюером деталь. Возражений по
+ существу к перечисленным пяти пунктам нет: способ (второй непрерывный ``
+ той же геометрии) корректно даёт кромку без превращения зазоров в сплошную
+ линию, а `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» не применяются.
+
+## Вердикт
+
+Зелёный. Готово к разработке.
+
+---
+
+
+
+## Материал раунда
+
+- Ветка: `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
+ ```