mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-02 04:38:55 +00:00
@@ -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
|
||||
```
|
||||
Reference in New Issue
Block a user