Files
houseplan-card/docs/reviews/SPEC-REVIEW-447-r2.md
T
2026-09-04 05:48:58 +00:00

138 lines
11 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-447-r2
Материал: `docs/specs/447-exterior-furniture-snap-keyboard-nudge.md` на коммите
[`818ad2d2`](https://github.com/Matysh/houseplan-card/commit/818ad2d2bb2fd35b56bba9f2e07692b03f2a70ba)
(docs-only, класс C).
## Скоуп разбора
Заход r2. Предыдущий вердикт — красный, r1, на коммите
[`a1fbea07`](https://github.com/Matysh/houseplan-card/commit/a1fbea07d2876d51afac3a9df12bfa756424df99),
единственная находка H1 (смешение render-масштаба `gridPitch` и
normalised-масштаба `GRID_STEP_N` в §3/AC4 части 2). SHA r1 назван и в
комментарии владельца, и в блоке «Материал раунда» самого документа r1 —
резолвится, живой.
Дельта раунда — `git diff a1fbea07..818ad2d2`, единственный тронутый файл:
сам ТЗ (37 строк, только §3 «Сдвиг выбранного декора стрелками» и AC4). Часть 1
(наружная поверхность стены, §1–2, AC1–AC3) правка не касается совсем.
Разбор сокращён до дельты: правка локальна (одна формула в одном разделе),
не меняет контракт поведения (видимый шаг остаётся «одна клетка», меняется
только описание внутреннего преобразования в persisted-поля), не задевает
новую подсистему и не сопоставима по объёму с исходной задачей — критерии
«разбирать полностью» (§2.9 PROCESS.md) не выполнены.
## Как проверялось
- Построчно сверил новый текст §3 и AC4 с кодом, который он описывает:
`src/space-geometry.ts` (`NORM_W`, `GRID_N`, `GRID_PITCH`, `GRID_STEP_N`,
`CANVAS_LIMIT`, `clampCanvasN`) и `src/houseplan-editor-runtime.ts`
(`_decorMoveUpdate`, строки 4336–4376) — существующий pointer-move путь,
на соответствие которому ТЗ теперь прямо ссылается.
- Проверил происхождение символа `decorH`, который правка вводит в текст:
`src/houseplan-card.ts:8329` — приватный geттер `_decorH` возвращает ровно
`NORM_W`, то есть равенство `gridPitch / decorH == gridPitch / NORM_W ==
GRID_STEP_N` не оценочное, а тождество на текущем коде.
- Пересчитал арифметику из примера r1 (`x = 0.4`) по новой формуле, чтобы
убедиться, что она даёт `GRID_STEP_N ≈ 0.0041667`, а не порядок `gridPitch`
(≈4.1667).
- Проверил, что правка не тронула ничего вне §3/AC4 (`git diff --stat`
показывает только `docs/specs/447-…md` и публикацию `docs/reviews/
SPEC-REVIEW-447-r1.md` — артефакт шага публикации, не автора).
- Проверил, что AC6 (bounds/`CANVAS_LIMIT`), которую делта не редактирует
текстуально, остаётся корректной *после* фикса: `CANVAS_LIMIT` и
`clampCanvasN` работают в нормализованных единицах (`SANE_LIMIT =
CANVAS_LIMIT * NORM_W`, `src/space-geometry.ts:205,207,240-241`), то есть
клэмп по-прежнему применяется к величине того же масштаба, что теперь
корректно производит §3. Раньше (до фикса r1) это было тем же скрытым
разрывом на один шаг дальше по цепочке — теперь согласовано.
## Закрытие раунда r1
| Находка | Чем закрыта | Где это видно |
|---|---|---|
| H1 — AC4/§3 требовали прибавлять render-`gridPitch` (≈4.1667) напрямую к нормализованным `x/y/x1/y1/x2/y2`, что уводит объект на ~4 ширины холста за одно нажатие | Текст переписан: пользовательский шаг остаётся `gridPitch` в render-координатах, но перед записью в persisted-поля явно делится на `NORM_W` (X) и `decorH` (Y) — то же преобразование, что уже использует `_decorMoveUpdate` для мыши. AC4 отдельно требует, чтобы mutation «прибавляющая `gridPitch` прямо к persisted-полю» красила тест | `docs/specs/447-exterior-furniture-snap-keyboard-nudge.md:142-154` (§3) и `:256-262` (AC4), коммит `818ad2d2`; проверено построчным сопоставлением с `src/houseplan-editor-runtime.ts:4353-4354` (`dx = (anchor[0]-ax0)/NORM_W`, `dy = (anchor[1]-ay0)/this.host._decorH`) |
## Унаследовано из r1
Принято без повторной проверки в этом раунде — дельта их не задевает:
- Диагноз и контракт части 1 (наружная поверхность внешней стены): построчная
сверка `roomFurnitureWallSurfaces`/`snapFurnitureToWall`, инварианты общей/
нулевой/independent стены (AC1–AC3). См.
`docs/reviews/SPEC-REVIEW-447-r1.md`, раздел «Проверено и корректно», на
SHA `a1fbea07`.
- Соответствие 6 видов decor (`line/rect/ellipse/text/furniture/image`)
`DecorKind` в коде — там же, на `a1fbea07`; правка r1→r2 не меняла список
видов, только формулу дельты для всех них одинаково.
- Guard-условия Arrow (AC8, focus/dialog/toolbar) и переиспользование
паттерна `_keyHandler` — там же, на `a1fbea07`.
- Полнота обязательных разделов §7.1 и обоснование full track (критерии
`small` не выполнены) — там же, на `a1fbea07`; правка не добавляла и не
убирала разделы.
- Терминология «Редактор подложки» сверена с `docs/USER-GUIDE.ru.md` — там
же, на `a1fbea07`.
- Отсутствие продуктовых вопросов к владельцу (владелец закрыл Shift-шаг,
подложку и формулировку шага решениями от 04.09.2026 до старта ревью) —
подтверждено в аналитике issue, без изменений в r2.
## Находки текущего раунда
Новых High/Medium в скоупе задачи не найдено. Правка r1→r2 сама по себе не
вносит новых противоречий: формула симметрична по X/Y, использует только
существующие именованные константы кода (`NORM_W`, `decorH`, `GRID_STEP_N`),
и явно называет запрещённую mutation для AC4.
## Проверено и корректно (по дельте)
- Новая формула §3/AC4 даёт identical результат для X и Y на текущем
квадратном холсте (`decorH === NORM_W` тождественно, не приближённо) —
повторное расхождение render/normalised исключено для обеих осей.
- AC6 (bounds/`CANVAS_LIMIT`) остаётся согласованной с обновлённой §3: обе
оперируют нормализованным масштабом.
- Правка не расширила и не сузила скоуп (видимый пользователю шаг — та же
«одна клетка», раздел «Скоуп» получил только уточнение «с явным переводом
в нормализованные persisted-поля», не новый пункт).
- Диф не тронул файлы вне `docs/specs/…` (кроме публикации r1-документа
конвейером).
## Не проверял
- Часть 1 (наружная поверхность стены) — не открывал заново, дельта её не
касается; см. «Унаследовано из r1».
- `typecheck`/`test`/`build`/`check-docs`/model-invariants/смоки — диапазон
этого раунда docs-only, `src/**` не тронут, дешёвые гейты неприменимы к
этому диффу (нечего собирать/тестировать — ТЗ ещё не реализовано). Это же
относилось к r1 на docs-only материале.
- Реализуемость owner-группировки атома «ровно одной комнате» и точную
структуру будущего pure-модуля `src/editors/decor/geometry.ts` — предмет
код-ревью, не спек-ревью.
## Вердикт
Единственная находка r1 закрыта по существу и проверяемо: формула теперь
воспроизводит уже существующий в коде путь пересчёта render→normalised для
decor-координат, а не изобретает новую арифметику. Новых находок дельта не
вносит. Часть 1 не менялась и наследуется из r1 без повторной проверки.
**Вердикт: зелёный · заход r2 · блокирующих циклов 1/4 · High: 0 · Medium: 0**
Документ: docs/reviews/SPEC-REVIEW-447-r2.md
---
<!-- material-anchors: сгенерировано конвейером (#414) -->
## Материал раунда
- Ветка: `issue/447-exterior-snap-keyboard`, коммит `818ad2d2bb2f` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
- Дерево материала: `12298423bb5c53540ed321ce11084c908fbd682f`
```
git log --all --format='%H %T' | grep 12298423bb5c
```
- ТЗ `docs/specs/447-exterior-furniture-snap-keyboard-nudge.md`, блоб `5c0036470b3bd675147ad5dc308b8d760be18b9c`
```
git log --all --find-object=5c0036470b3bd675147ad5dc308b8d760be18b9c -- docs/specs/447-exterior-furniture-snap-keyboard-nudge.md
```