Files
houseplan-card/docs/reviews/SPEC-REVIEW-544-r1.md
T
2026-09-12 17:30:56 +00:00

161 lines
14 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-544-r1
Issue: #544 · Этап: spec (PROCESS.md §2.4) · Заход: r1 · блокирующих циклов 0/4
Материал: тело issue #544, раздел `## ТЗ`, на момент ревью. Метка `S4-spec-review`,
предыдущих раундов ревью в комментариях issue нет — это первый заход, полный
разбор без раздела «Унаследовано».
Продуктовая постановка (`## Пользовательский дефект` … `## Требуемый результат`)
и `## ТЗ` — один документ одной задачи; расхождений между ними нет, ТЗ прямо
ссылается на тот же механизм и тот же браузерный свидетель (45 396 px).
## Скоуп ревью
Проверялось: полнота обязательных разделов §7.1, однозначность и доказуемость
каждого AC, соответствие продуктовой рамке `docs/SCOPE.md` (J1/J3), соответствие
`docs/TOUCH-SUPPORT.md` (View pan/pinch — release-blocking гарантия) и
`docs/CANVAS.md` §5 (модель камеры/pan не меняется), фактическая проверка
технических утверждений ТЗ по коду на точном SHA `66a6485418c7663d749642c8c5740c95d3c9f490`
(рабочая копия репозитория стоит на этом коммите — сверено `git rev-parse HEAD`).
Продуктовых вопросов к владельцу нет (сценарий и видимое поведение зафиксированы
однозначно); открытых технических вопросов нет — все нетривиальные решения
оформлены явным блоком «Принятые технические предположения — можно менять на
ревью» и разобраны ниже.
## Как проверялось
Это первый заход, поэтому разбор полный, а не по дельте.
1. Прочитаны `docs/SCOPE.md`, `AGENTS.md`, `PROCESS.md` §2.4/§2.9/§7.1/§7.2/§4.
2. Прочитано тело issue #544 целиком и единственный комментарий (S2-аналитика,
`origin/dev` `66a64854`, трек — полный, `small` не выполнен по performance и
touch-контракту).
3. Прочитаны `docs/TOUCH-SUPPORT.md` (пункт «support convenient pan, pinch zoom
and space switching» в разделе release-blocking гарантий) и `docs/CANVAS.md`
§5 (Zoom and pan — «Pinch and pan remain direct 1:1 gestures», модель pan не
входит в скоуп задачи и в не-скоупе прямо исключена).
4. Прочитан `docs/ARCHITECTURE.md`, раздел «Live viewport: a transform per
frame, a `viewBox` on a budget (#531, 2026-09-11)» — канонический текст
подсистемы, которую трогает задача.
5. Прочитан текущий код на точном SHA, названном в issue, и сверен построчно с
техническими утверждениями ТЗ (детали — в разделе «Находки» и «Проверено»).
6. Прочитаны файлы, которые ТЗ называет доказательной базой: `test/live-viewport.test.mjs`,
наличие `demo/smoke_live_pan_viewbox.mjs` и `scripts/mutation-gate.mjs` с
существующими мутантами на `live-viewport.ts`.
Гейты (typecheck/test/build/golden) на этом этапе не прогонялись и не нужны:
этап — ревью ТЗ, продуктового кода ещё нет; предмет проверки — текст, а не
бинарник.
## Находки
Ни одной High или Medium находки. Ниже — то, что специально проверялось и не
подтвердилось как дефект, для прозрачности разбора.
- **Проверено и не является находкой: покрытие К3 для декоративных iso-слоёв.**
`.iso-underlay-svg`, `.iso-shadows-svg`, `.iso-walls-svg`, `.iso-overlays-svg`
уже имеют постоянный `overflow: visible` в `src/styles/plan.styles.ts:255-261`
— то есть контракт К3, применённый к ним по общему селектору
`[data-hp-live-viewbox]`, окажется для них no-op (временная запись/снятие
одного и того же эффективного значения). Это не расходится с К2 («осевший DOM
остаётся тем же, что до задачи») и не создаёт двойной работы для ревьюера
кода: единственные SVG, которые реально нуждаются в исправлении — безымянный
flat/floor SVG (`data-hp-live-viewbox="floor"`, без класса, `houseplan-card.ts:11513`)
и iso-камера (`class="plan-svg"`, `data-hp-live-viewbox="camera"`, та же
строка) — оба без явного `overflow`, то есть с вычисленным `hidden` по
умолчанию для corner SVG. Формулировка К3 «и другим целым сценовым SVG»
достаточна именно потому, что механизм в `paintLiveViewport` уже сейчас
обходит оба атрибута общим `querySelectorAll`, без адресного перечисления —
разработчику естественно расширить тот же общий селектор, а не подбирать
список вручную.
- **Проверено и не является находкой: `vactrail`/`radar-ranges`.** Эти два
корневых SVG тоже несут `data-hp-live-viewbox="camera"`
(`houseplan-card.ts:12412`, `radar-render.ts:46`), но уже имеют постоянный
`overflow: visible` (`devices.styles.ts:555-562`, `plan.styles.ts:1460-1467`)
— они не входят в число реально затронутых SVG и не требуют отдельного
упоминания в не-скоупе; попадание под общий селектор для них так же
безопасно, как и для iso-слоёв выше.
- **Проверено и не является находкой: механизм задачи.** Три ключевых
технических утверждения ТЗ сверены построчно с кодом на названном SHA и
подтвердились: (а) `needsViewBoxRefresh` в `src/live-viewport.ts:93-103`
проверяет только `now - anchor.at`, вызывается исключительно из
`scheduleHouseplanViewport`, которую planner вызывает только в ответ на
реальные события камеры (`_pan`/`_zoomAt`/колесо/жест —
`houseplan-card.ts:6462,6662,6951`), и никакой таймер не запускает
перерисовку сам по себе — значит held-дефект действительно может жить дольше
100 мс, как заявлено в «Механизм»; (б) `setViewBox`/`setLayerProjection`
пишут DOM только на изменение строки, что соответствует заявлению AC1/AC5 о
«нет повторных записей на неизменный кадр»; (в) `docs/ARCHITECTURE.md`
описывает тот же бюджет (100 мс / 15 %) и тот же композиторный transform без
расхождений с ТЗ.
- **Проверено и не является находкой: fake-DOM тесты.** Ссылка ТЗ на
`test/live-viewport.test.mjs#L35` (строки/атрибуты, не пиксели) точна —
прочитан целиком фрагмент `fakeRoot`, он оперирует строковыми `style`/`attrs`,
подтверждая заявленный пробел в текущем оракуле.
## Проверка обязательных разделов (PROCESS.md §7.1)
Все обязательные разделы на месте: сценарий · что человек увидит до/после ·
проблема · скоуп и не-скоуп · контракт поведения (К1–К6) · UX · модель данных и
миграция (нет) · i18n (нет) · критерии приёмки AC1–AC7 с доказательством
(`unit`/`smoke`/`mutation`/`gates`) · план автотестов · риски · откат ·
release-артефакты. Плюс необязательные, но полезные разделы: затронутые файлы,
производительность/бюджеты, «принятые технические предположения».
- **Сценарий/видимое поведение** — обе фразы персона-центричны (домочадец на
touch, admin на desktop), не используют терминов реализации («промежуточный
кадр» и «камера» — уже канонические термины подсистемы по `CANVAS.md`, не
изобретены задачей).
- **AC однозначны и проверяемы.** Каждый AC называет способ доказательства и,
где применимо, отрицательного свидетеля (AC1, AC2, AC5, AC6), как того
требует §7.1/§2.5. AC2 отдельно требует красного текущего `origin/dev` хотя
бы по одному направлению — это то самое условие «тест умеет падать» будущего
код-ревью, зафиксированное уже в самом ТЗ.
- **Скоуп/не-скоуп** согласован с `SCOPE.md` (J1/J3, touch — гарантированная
поверхность View по `TOUCH-SUPPORT.md`) и не расширяет задачу: явно исключены
новая камера-модель, изменение бюджета #531, новые настройки/лейблы, точный
touch для редакторов.
- **Технические предположения** оформлены отдельным блоком «можно менять на
ревью» с обоснованием (диагностический эксперимент 45 396 → 0 px) — это
ровно то разделение «продуктовое решает владелец, техническое — авторы»,
которое требует §7.1. Открытых продуктовых вопросов, замаскированных под
технические, не найдено.
- **Риски** называют именно те места, где предположение может не сработать
(риск 1 — постоянный `overflow:visible` меняет osевший raster; риск 3 — iso
camera/floor не сливать в одну проекцию) — это честные, не декоративные
риски.
## Что не проверялось и почему
- Гейты `typecheck`/`test`/`build`/`golden` — не прогонялись: продуктового кода
ещё нет, предмет этапа — текст ТЗ, а не бинарник.
- Реализация мутанта AC6 и содержимое будущего `demo/smoke_live_pan_coverage.mjs`
— не существуют на этом этапе, поэтому не проверялись; их проверит код-ревью.
- Ручного/физического touch-тестирования не проводилось и не требовалось —
ТЗ прямо и корректно ограничивает это релизным гейтом, не доказательством
этой ветки (К6).
## Вердикт
Зелёный. Спецификация полна, однозначна, каждый AC проверяем и снабжён
доказательством и (где нужно) отрицательным свидетелем, технические
утверждения о механизме дефекта подтверждены прямым чтением кода на названном
SHA, а не приняты на веру. Продуктовых вопросов владельцу нет. Задача может
переходить в «Готово к разработке».
---
<!-- material-anchors: сгенерировано конвейером (#414) -->
## Материал раунда
- Ветка: `dev`, коммит `66a6485418c7` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
- Дерево материала: `0d80c47762ca4c2f97c5de2c705b8128788dd307`
```
git log --all --format='%H %T' | grep 0d80c47762ca
```
- Тело issue: `41fec2c0272d4aa14d3bd714f7664c58f874613196541c14f746ebca2572005d`
- Вердикт конвейера: `green` · High 0