# 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` --- ## Материал раунда - Ветка: `issue/570-isometric-visual-handoff`, коммит `c22c04d6476d` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. - Дерево материала: `97acf02d8a986df2a5dadc9c3cac2c42e549c81b` ``` git log --all --format='%H %T' | grep 97acf02d8a98 ``` - Тело issue: `25492e91e7c0d0796048bf8b821807c8bba46aa17a5886a59e64297cd6d7c376` - Вердикт конвейера: `green` · High 0