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 + ```