14 KiB
SPEC-REVIEW-359-r2
Issue: #359 — Предпросмотр мебели на плане перед размещением
ТЗ: docs/specs/359-furniture-placement-preview.md
Материал: коммит 842dc373 "docs: prove furniture preview edge cases" (HEAD на
момент разбора; git rev-parse HEAD = 842dc373b193acfc8ed2c8f5940f69c400e4cf3f).
Предыдущий раунд: SPEC-REVIEW-359-r1,
материал 392ef22c "docs: specify furniture placement preview" — SHA назван
явно в самом документе r1 (строка «Материал: коммит 392ef22c»), так что
находки «SHA в вердикте не назван» здесь нет.
Заход: r2. Блокирующих циклов израсходовано 1/4 (израсходован r1 — жёлтый
вердикт с Medium в скоупе).
Скоуп разбора
Второй раунд, дельта не задевает продуктовую рамку: git diff 392ef22c..842dc373 -- docs/specs/359-furniture-placement-preview.md — 24
добавленные и 7 удалённых строк, только в разделах «Критерии приёмки» (добавлены
AC9, AC10), «План автотестов» (пункты 2 и 4, старое обоснование «golden не
требуется» удалено) и «Release-артефакты» (одна строка). Сценарий, проблема,
скоуп/не-скоуп, контракт поведения пп.1-8 и 10, UX, модель данных, i18n, AC1-AC8,
риски (кроме перечисленных правок) и раздел «Принято предположительно» не
менялись — они наследуются из r1 без повторной проверки (раздел ниже).
Это ровно тот случай PROCESS.md §2.10, где объём разбора сокращается до дельты: правки автора точечно отвечают на обе Medium-находки r1 и не меняют контракт, не задевают новую подсистему и по объёму несопоставимы с исходной задачей.
Закрытие раунда r1
| Находка r1 | Чем закрыта | Где это видно |
|---|---|---|
Medium 1 — контракт п.9 (invalid/unknown symbol) не имел ни одного AC/теста-доказательства; риск «Fail dark» был декларацией, не проверкой |
Добавлен AC9 — «неизвестный символ»: явно требует «не создаёт .furniture-placement-preview», «не добавляет предмет в space.decor», «не вызывает исключение», с доказательством «unit-тест resolver на неизвестный id и demo/smoke_furniture.mjs с принудительным invalid palette state» |
docs/specs/359-furniture-placement-preview.md:142-146; синхронно расширен пункт 2 «Плана автотестов» — «fail-dark неизвестного symbol с последующим восстановлением валидного выбора» (строки 157-160) |
Medium 2 — «golden не требуется» обосновано общей фразой «transient = шум», которая опровергается уже существующими hoverRoom/hoverDevice/junction-draft-end-node-dark сценариями того же файла; AC7 (DOM/computed-style) не ловит дефекты z-order/композитинга — ядро ценности фичи |
Добавлен AC10 — «композиция»: ghost виден поверх сохранённого decor и ниже стен в одном composition layer, доказательство — один детерминированный golden-сценарий furniture-placement-preview-light, состояние которого «вооружается» программно (тот же приём, что hoverRoom/draft: true в demo/golden/matrix.mjs), без реального hover-таймера |
docs/specs/359-furniture-placement-preview.md:147-151; план автотестов п.4 (строки 164-170, конкретизирует сценарий и приёмку эталона только через npm run golden:accept -- --reviewed по полному Linux-артефакту); Release-артефакты (строки 202-205) заменили «golden/screenshots не требуются» на обязательство добавить сценарий |
Проверка нового текста, а не только его наличия:
- AC9 технически исполним:
furnitureGraphic(id)вsrc/furniture.ts:362уже сегодня возвращаетnullна неизвестный id — единый resolver, который контракт п.5 требует построить, естественно оборачивает эту проверку. Способ доказательства «принудительное invalid palette state» уже является рабочим паттерном smoke-тестов:demo/smoke_furniture.mjs:49прямо присваиваетc._furnPalette = null/объект, то естьc._furnPalette = { symbol: 'unknown-id', ... }для нового кейса не требует новой инфраструктуры теста. - AC10 технически исполним:
demo/golden/matrix.mjsуже строит сценарии через декларативные флаги без реального pointer-таймера —hoverRoom/hoverDevice(строки 452, 542, 628, 630) иdraft: true(строка 668,junction-draft-end-node-dark). Новый флаг для preview-состояния ложится в тот же механизм. Одиночный-light-сценарий без парного-darkне противоречит практике:decor-over-opaque-hover-lightв том же файле тоже без тёмной пары. Правило принятия эталона (golden:accept --reviewedпо полному Linux CI, не локально «ради зелёного CI») сформулировано в «Плане автотестов» и в «Release-артефактах» одинаково и совпадает с §12 PROCESS.md иdemo/golden/README.md.
Обе находки закрыты по существу, не декларативно: новый текст называет конкретный AC, конкретный способ доказательства и опирается на уже существующий в репозитории код/паттерн, а не на новое обещание.
Унаследовано из r1
Без повторной проверки в этом раунде принято (документ
docs/reviews/SPEC-REVIEW-359-r1.md, SHA 392ef22c, раздел «Что проверено и
корректно»):
- обязательные разделы §7.1 присутствуют полностью, включая обе продуктовые вставки («Сценарий», «Что человек увидит») из AGENTS.md;
- персона/поверхность/сценарий верны и привязаны к J4/J6
docs/SCOPE.md; лок- инвариант, View/kiosk и «Out of scope» не задеты; - touch-контракт (п.10, «Не-скоуп») дословно совпадает с
docs/TOUCH-SUPPORT.md; - магнит к стене и роль
Shift(контракт п.3) совпадают сdocs/CANVAS.md§9.4,docs/USER-GUIDE.ru.md:1305-1311и текущим кодом (_furnPlace,_furnMoveUpdate,snapFurnitureToWall); - единый resolver (контракт п.5) реализуем без новой архитектуры —
_furnPlaceуже сегодня короткая цепочка чистых вызовов; - условие видимости preview (контракт п.1) и его touch-симметрия (п.10)
опираются на существующий
src/pointer-modality.tsиdocs/TOUCH-SUPPORT.md, а не на новый механизм; - терминология UX-раздела («decor composition layer») и значение opacity
0.55— существующий код/визуальный язык проекта, не догадки; - i18n, модель данных/миграция, откат — корректны и не требуют пересмотра;
- открытых продуктовых вопросов не найдено (проверялось отдельно: opacity, отсутствие рамки, гибридные touch+mouse устройства);
- не-скоуп ограничивает риск расползания (multi-stamp, размерные плашки, collision detection, миграция схемы, move/resize/rotate существующей мебели).
Ни один из этих пунктов дельта r1→r2 не задевает: правки лежат только в AC9/AC10, соседних строках плана автотестов и одной строке release-артефактов.
Находки нового раунда
Ни одной находки уровня High или Medium в дельте не найдено.
Low (снята записью, не требует правки). План автотестов, пункт 1
(«…покрыть его unit-тестами для обычной точки, стены, Shift-пути и clamp у
границы», строка 155-156) не упоминает кейс неизвестного symbol, хотя AC9
обещает именно «unit-тест resolver на неизвестный id». Перечисление в пункте 1
не полное относительно AC9, но пункт 2 того же плана прямо называет
smoke-часть этого же кейса, а сам AC9 достаточно однозначен как источник
истины о необходимости unit-теста. Реализация не может «не заметить» этот
случай — он назван в AC. Снимаю без правки текста: расширять перечисление
ради полноты списка, который и так избыточен по отношению к AC, — не стоит
второго цикла ревью.
Что проверено и корректно (новый текст раунда)
- AC9 и AC10 однозначны, каждый называет способ доказательства и не подменяет продуктовое решение техническим вопросом владельцу;
- AC9/AC10 не открывают новых продуктовых вопросов — оба чисто технические (что не создаётся при невалидном вводе; каким тестом ловится z-order);
- новый golden-сценарий не нарушает §12/§11.4: явно назван путь принятия
через
golden:accept --reviewedпо полному CI-артефакту, а не локальное принятие; - нумерация AC (1-10) и плана автотестов (1-5) внутренне непротиворечива, перекрёстные ссылки (AC9→план п.2, AC10→план п.4) на месте.
Чего не проверял
- исполняемость AC9/AC10 в реальном коде — кода ещё нет, это код-ревью на S7;
- всё, что перечислено в «Чего не проверял» документа r1 (Playwright-прогон,
typecheck/test/build/bundle/smoke,
check-docs.mjs, точные формулировки будущих i18n/changelog-записей, реальный перф render-цикла) — дельта этого раунда не меняет применимость этих пунктов, они по-прежнему предмет код-ревью; docs/specs/README.mdне содержит записи про #359 — не проверялось как находка: колонка «Статус ТЗ» в этом файле помечена PROCESS.md §7.3 как уходящая сама по себе, вне рамок этого ревью.
Вердикт
Зелёный: 0 High, 0 Medium. Обе Medium-находки r1 закрыты предметно (AC9, AC10 с исполнимым способом доказательства, опирающимся на существующий код и существующую практику golden-сценариев). Одна Low снята записью без правки текста. Открытых продуктовых вопросов нет. Готово к «Готово к разработке».