17 KiB
SPEC-REVIEW — issue #160 · заход r1
- Issue: https://github.com/Matysh/houseplan-card/issues/160
- Этап: spec (PROCESS.md §2.4)
- Заход: r1 · блокирующих циклов израсходовано 0 из 4
- Материал: тело issue #160 + 6 комментариев (аналитика 2026-08-15,
вопросы владельцу, ответы дизайнера 2026-08-16, повторная актуализация
2026-08-31, актуализированная аналитика 2026-09-05, хендофф ТЗ), файл
docs/specs/160-isometric-stage3.mdна коммитеd82be48d(docs(issue): specify isometric stage 3),docs/specs/README.mdтого же коммита. - Ветка:
issue/160-isometric-stage3, HEAD =d82be48d. - Трек: полный (владелец прямо отверг
small/trivialв аналитике 2026-08-15 и подтвердил 2026-09-05: нарушены критерии сложности ≤3, одной поверхности, отсутствия нового UX-контракта и отсутствия влияния на performance/touch). ТЗ вdocs/specs/, отдельного файла в теле issue — корректно для полного трека.
Скоуп ревью
Проверялись: обязательные разделы ТЗ по PROCESS.md §7.1, однозначность и
доказуемость каждого AC, отсутствие догадок, выданных за решения, соответствие
docs/SCOPE.md (какую строку Core user jobs закрывает), соответствие
трейлеров коммита и корректность обновления docs/specs/README.md.
Реализации нет — код-уровневые гейты (typecheck/test/build/golden/smoke/
performance) к этапу spec не относятся и не запускались.
Как проверялось
- Прочитаны
docs/SCOPE.md,AGENTS.md,PROCESS.md§2.4/§7.1/§7.2/§4/§5. - Прочитано тело issue #160 и все 6 комментариев по порядку, включая полные тексты Q1–Q8 и ответов дизайнера/владельца.
- Прочитан файл ТЗ
docs/specs/160-isometric-stage3.mdцеликом (867 строк). - Факты о «текущем состоянии», заявленные в ТЗ как решённые (не как догадки),
сверены с реальным кодом и документами, а не приняты на слово:
ISO_CAMERA(rotDeg:0, tiltDeg:20, xyScale:1, zScale:1),ISO_WALL_HEIGHT=64—src/iso-projection.ts:22-29— совпадает с §0/D1.LABS_FLAGS/LabsFlagвsrc/labs.tsне содержитsince/expires— подтверждает заявление ТЗ, что срок действияiso-флага снят #448.ALPHA_STORAGE_KEY = 'houseplan_card_alpha_v1'(src/labs.ts:9) иLS_VIEW = 'houseplan_card_view_v1'(src/houseplan-card.ts:499,src/houseplan-editor-runtime.ts:612) — совпадают с §9.docs/ISOMETRIC.mdуже фиксирует безсрочныйhp_alpha, тот же projector для SVG/HTML иprojectedFrame()— совпадает с §7.1/§0.- LRU cap 8 (
lruWrite(this._isoGeometryCache, source.key, value, 8),src/houseplan-card.ts:6129) — совпадает с §7.2/AC12. openingAmount()существует как общая функция (src/logic.ts:316, используется вhouseplan-card.ts,space-render.ts,glow-scene.ts) — совпадает с D5/AC6 про «единственный live amount».renderZigbeeTopologyOverlay/hp-zigbee-topology-overlay.ts:169-174читает позицию маркера из живого DOM (marker.style.left/top,getBoundingClientRect()на.dev[data-id]) — подтверждает точное техническое утверждение D2, что топология обязана продолжать брать фактические DOM-позиции, а не проецировать floor point заново; это не догадка, а описание существующего кода.demo/smoke_isometric_contract.mjs,demo/smoke_isometric_live_touch.mjs,demo/performance/budgets-large-house-isometric.json— существуют, совпадают с §12.2/§14/§10.- Stage 2 ТЗ (
docs/specs/122-isometric-stage2.md) действительно уже описывает ambient/contact/leaf shadows и matte materials — «что есть сейчас» в аналитике 2026-08-15 не преувеличивает состояние Stage 2. - #124, #168, #448 закрыты (проверено
gh issue view) — совпадает с заявлениями актуализации 2026-09-05. docs/SCOPE.md: узкое 2.5D-исключение действительно одобрено для #89 и покрывает «ту же J1/J2/J3-состояние, действия и геометрию, без второй модели и свободной камеры» — Stage 3 (§0 ТЗ) укладывается в эту рамку буквально, не расширяя её.
- Проверены трейлеры коммита
d82be48d(Issue: #160,User-Visible: no) — корректно для документации, не входящей в DoD видимого поведения (функция скрыта, changelog не трогается — соответствует §15 ТЗ). - Проверено обновление индекса
docs/specs/README.md— строка#160добавлена, дата актуальности сдвинута — корректно. - #122 и #89 — оба
CLOSED, подтверждая, что предыдущие стадии того же узкого исключения уже прошли процесс без отдельного обновленияdocs/SCOPE.mdпод каждую стадию — значит отсутствие правки SCOPE.md в этом ТЗ не является новым отклонением от прецедента.
Проверка §7.1 (обязательные разделы)
| Раздел §7.1 | Где в ТЗ |
|---|---|
| Сценарий (персона/поверхность/момент) | §1 — продвинутый пользователь/тестировщик с hp_alpha=1, View/kiosk |
| Что человек увидит до/после | §2, одной фразой без терминов реализации |
| Проблема | §3 |
| Скоуп и не-скоуп | §5, §6 |
| Контракт поведения | §4 (D1–D8), §7 |
| UX | §8 |
| Модель данных и миграция | §9 (явный отрицательный контракт) |
| i18n | §9 (явно: новых ключей нет) |
| AC1…ACn с доказательством | §11, AC1–AC15, у каждого поле Evidence |
| План автотестов | §12 |
| Риски | §17 |
| Откат | §18 |
| Release-артефакты | §15 |
Все обязательные разделы присутствуют и содержательны, ни один не является переформулировкой issue без добавленной информации.
Проверка «какую строку Core user jobs это закрывает»
docs/SCOPE.md резервирует для #89 «узкое 2.5D-исключение… то же состояние
J1/J2/J3, действия и геометрия, без второй модели дома и свободной камеры».
ТЗ §0 и аналитика 2026-09-05 явно называют это основанием и не расширяют
исключение: камера остаётся одной фиксированной ортографической матрицей
(D1), никакая новая модель дома, свободная камера, WebGL/3D-мебель не
вводится (§6). Это соответствует правилу SCOPE.md буквально, а не по
касательной.
Проверка на догадку, выданную за решение
Каждое числовое/поведенческое решение D1–D8 (rotDeg=+4°, tiltDeg=20°,
raised-list из D2, 44×44 px, visualOffset, отсутствие glass/handles у
проёмов, привязка теней к фиксированному light vector, продление жизни через
hp_alpha вместо expires) прослежено до конкретного ответа дизайнера
(комментарий
https://github.com/Matysh/houseplan-card/issues/160#issuecomment-5316071365)
и/или прямого решения владельца в аналитике 2026-09-05 — не изобретено
автором ТЗ. Единственные значения, не зафиксированные владельцем буквально
(visualOffset, safety gap, nudge cap — конкретные числа 4/4/48), correctно
вынесены в §19 «Принятые технические предположения» с пометкой «не новые
продуктовые вопросы, можно уточнять реализацией/ADR» — это именно тот
паттерн, который требует PROCESS.md §7.1, а не скрытая догадка.
Находки
Low — «Workflow boundary» (§16) ссылается на устное решение владельца, не отражённое в issue
В §16 ТЗ и в последнем комментарии автора («ТЗ готово к независимому
ревью») утверждается: «По прямой команде владельца после реализации нельзя
инициировать код-ревью… остановиться на S6-in-progress». Ни в теле issue,
ни в одном из 6 комментариев такого поручения нет — это не продуктовый вопрос
из тех, что решает владелец по PROCESS.md §7.1 (что видит/делает человек,
какой объём видимых изменений в issue), и не спор автора с ревьюером,
разрешаемый вердиктом. Это самостоятельное процессное утверждение,
непроверяемое по доступному следу.
Почему не High/Medium: раздел явно называет себя паузой, а не отменой
код-ревью («Это пауза перед код-ревью, а не его отмена»), и не меняет ни один
AC, скоуп или технический контракт — код-ревью всё равно остаётся
обязательным (AGENTS.md: «Code review is never skipped on either track»)
перед S8/бетой. Ложность этого утверждения не создаёт дефекта в продукте,
только временную путаницу в маршруте после S6.
Как закрыть: низкая серьёзность позволяет либо снять с запиской, либо
поправить. Рекомендация — при выходе в S6-in-progress продублировать это
поручение отдельным issue-комментарием от лица владельца (или сослаться на
внешний канал, если оно дано вне GitHub), чтобы следующий агент видел
основание в трассируемом виде, а не в теле ТЗ. Блокирующим для зелёного
вердикта не является.
Других находок (High/Medium, в скоупе или вне скоупа) не выявлено.
Что проверено и корректно
- Полнота обязательных разделов §7.1 — да, см. таблицу выше.
- Однозначность и доказуемость всех 15 AC — у каждого явный Evidence, формулировки не оставляют открытого «как понять, что сделано».
- Соответствие 13 пунктов Scope (§5) и AC (§11) — все пункты scope покрыты хотя бы одним AC (сверено построчно).
- Отсутствие непомеченных догадок — все нормативные числа/решения D1–D8 прослежены до комментариев с ответами дизайнера/владельца; единственные неподтверждённые владельцем числа явно помечены как предположения в §19.
- Технические факты о «текущем состоянии» (камера, LRU cap, storage keys, Labs-контракт, поведение zigbee-topology-overlay, состояние #124/#168/#448) подтверждены чтением кода/issues, а не приняты на слово автора.
- Трейлеры коммита
d82be48d(Issue: #160,User-Visible: no) корректны для документационного изменения, не входящего в DoD видимого поведения. - Обновление
docs/specs/README.md(индекс, дата) корректно. - Негативный контракт данных/i18n/security (§9, §13, AC13) явный и проверяемый чтением на этапе код-ревью.
- Раздел «откат» (§18) и «риски» (§17) присутствуют и специфичны для задачи, не шаблонны.
Чего не проверял (и почему не нужно на этом этапе)
npx tsc --noEmit,npm test,npm run build,npm run bundle:sync, golden/smoke/performance — код ещё не написан, класс A/B-файлы не менялись этим коммитом (менялся толькоdocs/specs/**, класс C); гейты реализации относятся к этапу code review, не к spec review.node scripts/check-docs.mjs— не требуется: diff не касаетсяsrc/**.npm run invariants— не требуется: diff не касается геометрии/ссылок в коде, только текст ТЗ.- Golden/browser smoke, названные в плане автотестов ТЗ (§12), — это план на будущую реализацию, а не факт; они не могут быть прогнаны сейчас и не являются частью этого ревью.
- Не проверялась реализация Stage 1/2 построчно за пределами тех фактов, которые ТЗ Stage 3 использует как «текущее состояние» (см. раздел «Как проверялось») — этого достаточно, чтобы подтвердить отсутствие догадок в Stage 3.
Вердикт
Зелёный. ТЗ полное, все обязательные разделы на месте, каждый AC однозначен и снабжён способом доказательства, все нормативные решения прослежены до ответов дизайнера/владельца, а не изобретены. Единственная находка — Low, не блокирует, снимается с запиской выше.
Материал раунда
- Ветка:
issue/160-isometric-stage3, коммитd82be48dfbe7— ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. - Дерево материала:
c224cbd2cee2cf653280a13a6e372148c60e26c1git log --all --format='%H %T' | grep c224cbd2cee2 - ТЗ
docs/specs/160-isometric-stage3.md, блоб837f05545baf1a85ae03a1452d887827f4351a22git log --all --find-object=837f05545baf1a85ae03a1452d887827f4351a22 -- docs/specs/160-isometric-stage3.md