Files
houseplan-card/docs/reviews/SPEC-REVIEW-570-r1.md
T
2026-09-14 11:56:55 +00:00

79 lines
16 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-570-r1
**Issue:** [#570](https://github.com/Matysh/houseplan-card/issues/570) — «Улучшение визуального отображения 3-D плана» (hidden alpha `iso`, Stage 4 визуального направления по цепочке #89 → #122 → #160 → #471)
**Этап:** spec (S4-spec-review) · трек: полный (не `small`) · заход r1 · блокирующих циклов израсходовано 0 из 4
**Материал:** тело issue #570, раздел `## ТЗ`, на SHA репозитория `c22c04d6476d0d387c237b427d0b83e7c1e11f70` (рабочая копия, использована только для чтения текущего кода — сам код этой задачей ещё не тронут)
**Роль:** ревьюер ТЗ, независимая сессия, без контекста автора ТЗ
## Скоуп проверки
ТЗ описывает визуальный редизайн скрытого alpha-режима `iso` (2.5D-вид House Plan): камера, высота стен, стыки/материалы стен, углы и профиль дверей/окон/gate, визуальная коррекция device/room/lock overlays, сохранение Glow/sunlight, деградация и производительность. Изменения строго за флагом `hp_alpha`, `User-Visible: no`; Flat, редакторы и `houseplan-space-card` не меняются. Это продолжение уже одобренного владельцем узкого исключения из `docs/SCOPE.md` (#89) — не новая продуктовая возможность, а следующая итерация того же экспериментального 2.5D-представления.
## Как проверялось
1. Прочитаны `docs/SCOPE.md`, `AGENTS.md`, `PROCESS.md` (целиком, включая §2.3–2.10, §7.1, §8) до разбора ТЗ.
2. Прочитано тело issue #570 целиком (проблема + `## ТЗ`, разделы 1–14) и оба комментария (аналитика P2/feature/polish/полный трек, комментарий «Взял»). Прежних вердиктов ревью на этом issue нет — это первый заход, раздел «Унаследовано из r0» не применим.
3. Сверены канонические документы подсистемы: `docs/ISOMETRIC.md` (Stage 1–3 контракт: камера, `wallBodiesGeometry()`, LRU, деградация), `docs/LIGHT.md` (Glow/sunlight и барьеры окон/дверей), `docs/TOUCH-SUPPORT.md` (44×44 px target, pinch/pan/kiosk). `docs/USER-GUIDE.ru.md` намеренно не содержит `iso`/`hp_alpha` — ожидаемо для скрытого alpha-режима, вне терминологии интерфейса для обычного пользователя.
4. Каждое фактическое утверждение ТЗ о **текущем** поведении сверено с реальным кодом на этом SHA, а не принято на слово автора:
- `ISO_CAMERA` = `{rotDeg: 4, tiltDeg: 20}`, `ISO_WALL_HEIGHT = 64` (`src/iso-projection.ts:23-31`) — совпадает с «сейчас камера уже имеет наклон 20°, но поворот 4° и высоту стен 64» из аналитики;
- `windowBottomRatio: 0.27, windowTopRatio: 0.78` (`src/iso-openings.ts:90-91`) — совпадает с «окно использует диапазон 0.27–0.78»;
- `angle = leaf.turnDeg * amount * Math.PI / 180` с `turnDeg = ±90` для door-leaf (`src/iso-openings.ts:279-286,351`) — подтверждает «дверь раскрывается до 90°» и, соответственно, целевые 50° — реальное сужение, а не косметика;
- `gridVisualUnits()` (`src/grid-scale.ts:17`), уже используется для `ISO_WALL_HEIGHT`/`ISO_FLOOR_EDGE_HEIGHT` (`src/iso-scene-render.ts:440-442,546-548,776-777`) — «существующая scale-aware политика» из §6.2 ТЗ не выдумана, это действующий механизм;
- `openingAmount()` (`src/logic.ts:316-330`): без датчика/при `unknown`/`unavailable` door/gate → 1 (открыто), window → 0 (закрыто) — дословно совпадает с §6.4 ТЗ и с формулировкой из `docs/LIGHT.md` («doors and gates default to open... windows to closed»);
- `docs/LIGHT.md`: «windows: an indoor lamp must not wash the street» и «sunlight still belongs to exterior room windows» — совпадает с §6.6 ТЗ (окно непрозрачно для Glow, не преграда для sunlight);
- все module/test-файлы, названные в плане тестирования (`iso-projection`, `iso-walls`, `iso-openings`, `iso-overlays`, `iso-scene-render`, `isometric-contract`, `live-viewport`, `device-hit-owner`, `light-visibility`, `sun`) реально существуют в `src/`/`test/`;
- именованные в AC17 performance-профили `large-house-isometric` и `isometric-stage3-dense` реально существуют (`demo/performance/budgets-*.json`, `demo/benchmark_large_house.mjs`).
Ни одного случая, где текст ТЗ приписывает существующему коду поведение, которого там нет, не найдено.
5. Отдельно проверено, не выдана ли догадка за решение: числовые параметры камеры/стен/двери (20°/0°/84/50°) присутствуют в исходном тексте issue от лица владельца («How do you imagine it working?») — это не догадка автора ТЗ, а прямая цитата постановки. Более детальные величины (окно 65°, пропорции рамы/створки/стекла, цвета `#c9e4f3`/`#e3f2fa`) в исходном тексте владельца отсутствуют; ТЗ прозрачно относит их к второму по приоритету нормативному источнику — приложенному `HousePlan-3D-production-handoff.zip` (§3), а не выдаёт их за независимо принятое решение. Сам архив я не скачивал и не сверял побайтово (см. «Чего не проверял»), но это не тот случай, когда факт выдан за очевидное без ссылки на источник.
6. Проверены обязательные разделы §7.1 PROCESS.md — присутствуют все: сценарий/персона/поверхность (п.1), что человек увидит до/после (п.1, отдельным абзацем), проблема (п.2), scope и не-scope (п.4–5), контракт поведения/UX (п.6, 7 подпунктов), модель данных и миграция (п.7 — явно «не меняются, миграция не нужна»), i18n (п.8 — явно «новых строк нет»), AC1…AC18 с доказательством у каждого (п.9), план автотестов (п.10), риски (п.11), откат (п.12), release-артефакты (п.13). Плюс необязательный, но полезный блок явных технических допущений (п.14), как и требует §7.1 PROCESS.md для решений, оставленных на усмотрение авторов.
7. Проверен пункт DoR §2.5: `small`-критерии не выполняются (несколько поверхностей, существующий UX-контракт Stage 3 меняется, touch/kiosk и exact-SHA performance budget затронуты) — аналитика явно назвала эти критерии, полный трек обоснован, документный (не только комментарийный) формат ревью ТЗ уместен.
8. Проверено соответствие `docs/SCOPE.md`: задача — не новая функция, а итерация уже одобренного узкого исключения #89 (детерминированное 2.5D-представление той же канонической геометрии/состояний/действий, без второй модели дома, без свободной камеры, без нового пользовательского слоя). §5 «Вне scope» ТЗ прямо запрещает ровно то, что `docs/SCOPE.md` перечисляет как красные линии (WebGL/Three.js, вторая модель, свободная камера, новые Terrace/Porch-сущности). Соответствие подтверждено.
9. Проверено на внутренние противоречия и двусмысленности (по всему тексту ТЗ): численные диапазоны door/window/gate согласованы между §4, §6.4 и AC5/AC6 (50°×amount, 65°×amount, gate отдельно 0–10°); fallback-семантика §6.4 совпадает с AC7; cache-инварианты §6.2/§7 совпадают с AC15. Расхождений не найдено.
## Находки
Находок нет — ни High, ни Medium, ни Low.
## Что проверено и корректно
- Все обязательные разделы §7.1 присутствуют и содержательны, не шаблонные заглушки.
- Каждый из AC1…AC18 сформулирован как проверяемое утверждение и называет способ доказательства (unit/contract/browser smoke/Linux golden/performance/CI); нет ни одного AC без названного метода.
- Продуктовые вопросы к владельцу отсутствуют обоснованно: параметры камеры/стен/двери владелец задал сам в теле issue, остальное — технические решения, явно вынесенные в блок «Принятые технические предположения» (п.14) с пометкой «поменять свободно», как и предписывает §7.1 PROCESS.md.
- Ни одного случая необозначенной догадки: специфические численные детали (окно 65°, пропорции стекла/рамы, цвета) прозрачно приписаны приложенному эталону, а не поданы как независимо выведенный факт.
- Технические утверждения о **текущем** поведении (камера 4°/64, окно 0.27–0.78, дверь до 90°, `openingAmount()` fallback, названия существующих модулей/тестов/performance-профилей) построчно сверены с кодом на SHA `c22c04d6` — расхождений нет.
- Согласованность с каноническими документами подсистемы (`ISOMETRIC.md`, `LIGHT.md`, `TOUCH-SUPPORT.md`) подтверждена по конкретным цитатам, а не по общему впечатлению.
- Соответствие `docs/SCOPE.md` (узкое исключение #89) подтверждено; список «вне scope» закрывает именно те красные линии, которые называет SCOPE.md для этого исключения.
- Трек (полный) обоснован названными критериями §5 PROCESS.md, а не общей фразой «обычный трек».
- Откат: первичный и по-настоящему product-facing путь — немедленное переключение пользователем на Flat — реален и достаточен по §2.5 DoR; вторичное техническое утверждение «один revert-коммит» не проверялось (код ещё не написан) и не является частью пользовательского отката.
## Чего не проверял
- Содержимое `HousePlan-3D-production-handoff.zip` не скачивалось и не сверялось побайтово с манифестом (`MANIFEST.sha256.json`, revision 3) — эта проверка выполнена автором/аналитиком и запись об этом есть в комментарии аналитики; для ревью ТЗ достаточно того, что архив явно назван источником второго приоритета (§3), а не выдан за факт без ссылки. Если в архиве в действительности иные числа, чем перечисленные в §6.4 ТЗ, это всплывёт на код-ревью через golden-артефакт и side-by-side dossier (AC4), а не потеряется молча.
- Визуальное совпадение будущей реализации с эталонным изображением — по определению нечего проверять до кода; ТЗ верно относит это к Linux golden + ручному визуальному сравнению ревьюером кода (AC4), это единственно возможный способ на этапе спецификации.
- Реализуемость числовых constraints (например, будет ли `isometric-stage3-dense` укладываться в существующий бюджет без учёта новых материалов/jamb/reveal геометрии) — вопрос кода, а не текста ТЗ; сам факт, что бюджет фиксирован без права поднять порог, — законное решение риска (п.11 «Cache/performance regression»), последствия проверит код-ревью через AC17.
- Не прогонялись `npx tsc --noEmit`/`npm test`/`npm run build` — на этапе spec-review это неприменимо: продуктовый код ещё не менялся (только чтение текущего дерева для сверки фактов выше), задача ревью ТЗ — текст, а не гейты.
## Вердикт
Зелёный. ТЗ отвечает всем обязательным разделам §7.1, каждый AC проверяем и называет доказательство, продуктовых вопросов, требующих владельца, не осталось, ни одна деталь не выдана за факт без источника, а фактические утверждения о текущем коде подтверждены построчным чтением. Задача может переходить в `S5-ready`.
## Материал раунда
- Ветка: `issue/570-isometric-visual-handoff`
- ТЗ: тело issue #570, раздел `## ТЗ` (актуальное на момент ревью, см. текст, использованный выше)
- SHA рабочей копии на момент ревью: `c22c04d6476d0d387c237b427d0b83e7c1e11f70`
---
<!-- material-anchors: сгенерировано конвейером (#414) -->
## Материал раунда
- Ветка: `issue/570-isometric-visual-handoff`, коммит `c22c04d6476d` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
- Дерево материала: `97acf02d8a986df2a5dadc9c3cac2c42e549c81b`
```
git log --all --format='%H %T' | grep 97acf02d8a98
```
- Тело issue: `25492e91e7c0d0796048bf8b821807c8bba46aa17a5886a59e64297cd6d7c376`
- Вердикт конвейера: `green` · High 0