docs: review document for #691

Issue: #691
User-Visible: no
This commit is contained in:
claude[bot]
2026-09-28 14:32:51 +00:00
parent 33ae14a99d
commit 0a09712bc5
+201
View File
@@ -0,0 +1,201 @@
# CODE-REVIEW-691-r2
Материал ревью: `33ae14a99d55b8959e54508c41c3e2eba63a9b33` (`origin/dev..HEAD`,
рабочая копия уже стоит на нём). Заход r2, блокирующих циклов израсходовано
1 из 4 (потрачен r1, жёлтый вердикт).
## Скоуп
Issue #691, продолжение после жёлтого r1
(`docs/reviews/CODE-REVIEW-691-r1.md`). r1 подтвердил продуктовый код
(`src/logic.ts`, `src/room-fit.ts`, `src/houseplan-card.ts` — контракт §6/§7 ТЗ
реализован верно, все 12 AC доказаны автотестом или чтением) и нашёл два
Medium **в скоупе**, оба документационно-тестовые, без продуктовых изменений:
- Medium-1: `docs/USER-GUIDE.ru.md` не обновлён и описывал старый контракт
(мгновенный room-fit, double-tap только по фону, свайп «при масштабе 1:1»
без упоминания края) — канонический источник терминологии для видимого
поведения расходился с кодом.
- Medium-2: `demo/smoke_pan_any_zoom.mjs` (regression-смок из #531, прямое
совпадение по `smoke-select`) реально красный на материале r1 —
`kioskSwipeStillSwitchesFloors`/`kioskHorizontalDragIsNotAPan` ожидали
`true`, получали `false`, потому что тест стартовал drag из середины
стейджа, что по новому контракту (§6 п.5 ТЗ) корректно классифицируется как
pan, а не swipe.
r2 — точечный фикс обоих находок, продуктовый код (`src/**`) не менялся.
Дельта `git diff 53503e0373fe73d54ebccf5e70af8171ca778716..HEAD --stat`:
```
demo/smoke_pan_any_zoom.mjs | 26 ++++++++++++++++----------
docs/USER-GUIDE.ru.md | 12 ++++++------
docs/reviews/CODE-REVIEW-691-r1.md | 286 ++++++++++++++++++++++++++++++++++++
```
(последний файл — публикация ревью-документа предыдущего раунда пайплайном,
не работа автора.)
Два коммита автора/пайплайна поверх материала r1:
- `09f8cf4c` `docs: review document for #691` — публикация
`CODE-REVIEW-691-r1.md`, `Issue: #691`, `User-Visible: no`.
- `33ae14a9` `test(touch): align kiosk smoke and Russian guide (#691)` —
фикс обеих находок, `Issue: #691`, `User-Visible: no`.
`User-Visible: no` корректен: правки не меняют поведение продукта (оно уже
было в материале r1), только приводят документацию/тест в соответствие с уже
выпущенным контрактом — `docs/CHANGELOG.md`/`docs/CHANGELOG.ru.md` в этой
дельте не тронуты, и это ожидаемо.
Дельта локальна: два файла, оба — предметы находок r1, продуктовый код и
тестовые unit/browser-смоки для AC1–AC12 не менялись. Разбор по §2.10 —
только по этим двум находкам; продуктовый контракт (AC1–AC12) переразбору не
подлежит, см. «Унаследовано из r1».
## Как проверялось
Дешёвый набор подтверждён зелёным Validate на этом SHA
(https://github.com/Matysh/houseplan-card/actions/runs/36435141249) —
`tsc --noEmit`, `npm test`, `npm run build`. Полный перегон `npm test`/`tsc`
не повторял — дельта не трогает `src/**`/`test/**`, полагаюсь на Validate
(#343). Прогнал сам только то, что доказывает закрытие двух находок:
| Гейт | Прогнан | Результат |
|---|---|---|
| `npm run bundle:sync` (нужен для запуска demo-смоков локально) | да | success; после проверки бандл/`demo/srv/assets` возвращены в состояние материала (`git checkout -- dist/ demo/srv/assets/` + `git clean -fd dist/`) — рабочая копия сверена `git status --porcelain` (пусто) |
| `node demo/smoke_pan_any_zoom.mjs` | да | **зелёный**: 55/55 проверок `true`, 0 `false`, точное совпадение с числом, заявленным автором в хендоффе («55/55 проверок true») |
| `node scripts/check-docs.mjs` | да | `Documentation checks passed (7 files, 12 external links)` |
| Диффо-сверка `docs/USER-GUIDE.ru.md` против `docs/USER-GUIDE.md` и текста ТЗ §6/§7 | да, чтением | все 4 места, названные в находке Medium-1 r1 (474, 475, 476, 1936/1938), правлены и синхронны с английской версией |
| `node scripts/smoke-select.mjs` | нет | дельта не трогает `src/**`; смок-селектор ориентируется на изменённые продуктовые символы, здесь их нет — не даёт новой информации сверх точечной проверки изменённого файла |
| `node scripts/mutation-gate.mjs` | нет | продуктовый код (`src/logic.ts`/`src/room-fit.ts`/`src/houseplan-card.ts`) не менялся в этой дельте; 4 mutation-witness ID из r1 не затронуты — статус «применимы побайтово» из r1 остаётся в силе (см. «Унаследовано из r1») |
| `npm test` (полный), `npx tsc --noEmit` | нет | подтверждены Validate на этом SHA; дельта не трогает `test/**`/типы |
| `npm run golden:verify` | нет | дифф не меняет геометрию/рендер |
| `npm run invariants` | нет | дифф не меняет геометрию модели |
| `python -m pytest tests_backend` | нет | дифф не трогает `custom_components/**` |
| Performance-профили | нет | не названы в AC |
## AC — доказательства
Продуктовый контракт (AC1–AC12) не менялся этой дельтой — доказательства
из r1 (`docs/reviews/CODE-REVIEW-691-r1.md`, раздел «AC — доказательства»)
остаются в силе без переразбора (см. «Унаследовано из r1»). Единственное,
что меняется относительно AC-доказательств r1: `demo/smoke_pan_any_zoom.mjs`
теперь зелёный, поэтому регрессионное покрытие «pan вне края / swipe только у
края» (пересекается с AC1/AC3) снова осмысленно, а не ложно-красное.
## Находки
Нет находок, переживших верификацию. Обе Medium из r1 закрыты (см. таблицу
ниже).
## Что проверено и корректно
- `docs/USER-GUIDE.ru.md` строки 474–476 и 1936/1938 переписаны и теперь
дословно по смыслу совпадают с `docs/USER-GUIDE.md` и контрактом §6/§7 ТЗ:
350 мс отложенный room-fit, double-tap/double-click по фону, заливке
комнаты и её пассивной подписи (не только по фону), edge-swipe только из
48 CSS px у края с доступным соседом, «drag вне этой зоны панорамирует
план». Клавиатурная активация (`Enter`/`Space`) осталась немедленной, как и
требует §7 п.9 ТЗ (keyboard activation не ждёт 350 мс).
- `demo/smoke_pan_any_zoom.mjs`: положительный kiosk-swipe теперь стартует из
фактического правого края стейджа (`rect.right - 20`, вычислено из
`getBoundingClientRect()`, не хардкод), что попадает в 48 px активную зону
независимо от размера окна; комментарий файла обновлён и больше не
утверждает устаревший инвариант «любой горизонтальный kiosk-drag — свайп».
Остальные проверки того же блока (вертикальный drag — pan; zoom > 1 —
всегда pan) не менялись и не требовали правки — граница находки была
локализована в r1 правильно.
- Прогон на точном SHA материала (33ae14a9, а не на рабочей ветке после
моих локальных операций) даёт 55/55 `true` — совпадает с числом из
хендоффа автора; проверка не является «Verified» без команды — команда и
результат приведены в таблице гейтов.
- Никакого продуктового кода (`src/**`) в дельте нет — риск регрессии AC1–AC12
от этого раунда отсутствует по построению, не только по прогону.
- Рабочая копия после моих локальных `bundle:sync`/`check-docs`/смок-запусков
возвращена к состоянию материала (`git status --porcelain` пуст, `git
rev-parse HEAD` = `33ae14a99d55b8959e54508c41c3e2eba63a9b33`), сгенерированные
файлы не просочились в чужой контекст.
## Чего не проверял
- Полный `npm test`/`tsc --noEmit`/`npm run build` заново — подтверждены
зелёным Validate на этом SHA; дельта не даёт причин ожидать иного
результата (не трогает `src/**`/`test/**`).
- `node scripts/mutation-gate.mjs` — не перегонял; 4 ID из r1 не связаны с
файлами этой дельты, повторная проверка не требуется по объёму дельты
(§2.10). Статус «фактическое красное/зелёное исполнение не воспроизведено
автором ревью» остаётся тем же наследуемым пробелом, что и в r1 — он не
блокирует, так как связан не с этим раундом.
- Ручное тестирование на физическом touch-устройстве — как и в r1, вне
объёма код-ревью; ТЗ §12 требует browser-смоков, они прогнаны.
- `smoke-select.mjs` для этой дельты — не гонял; дельта не трогает `src/**`,
инструмент ориентируется на изменения продуктовых символов и не дал бы
дополнительного сигнала сверх прямой проверки единственного изменённого
demo-файла.
- `golden:verify`, `invariants`, `pytest tests_backend`, performance —
не гонял; дельта не даёт повода (нет изменений геометрии, рендера, Python
или производительности).
## Вердикт
Обе Medium-находки r1 закрыты точечно и без побочных изменений: русский
пользовательский гайд снова совпадает с фактическим контрактом и английской
версией, `demo/smoke_pan_any_zoom.mjs` снова зелёный (55/55, воспроизведено
мной запуском на материале раунда). Продуктовый код не менялся, новых
находок не появилось.
Вердикт: зелёный · заход r2 · блокирующих циклов 1/4 · High: 0 · Medium: 0
---
## Закрытие раунда r1
| Находка | Чем закрыта | Где это видно |
|---|---|---|
| Medium-1 — `docs/USER-GUIDE.ru.md` описывает старый контракт (мгновенный room-fit, double-tap только по фону, свайп «при 1:1» без края) | Коммит `33ae14a9`, правка строк 474–476 и 1936/1938 | `git diff 53503e03..HEAD -- docs/USER-GUIDE.ru.md`: все 4 места переписаны на «350 мс», «фон/заливка/пассивная подпись», «48 CSS px у края с соседом»; сверено построчно с `docs/USER-GUIDE.md` и §6/§7 ТЗ — расхождений не осталось |
| Medium-2 — `demo/smoke_pan_any_zoom.mjs` красный (`kioskSwipeStillSwitchesFloors`/`kioskHorizontalDragIsNotAPan` → `false`) | Коммит `33ae14a9`, drag теперь стартует из `rect.right - 20` (реальная правая краевая зона) вместо середины стейджа | Прогнал `node demo/smoke_pan_any_zoom.mjs` на материале раунда: 55/55 `true`, exit 0 (было 2 `FAILED`, exit 1, на материале r1) |
## Унаследовано из r1
Принято без повторной проверки в этом раунде (продуктовый код не менялся):
- Все 12 AC (AC1–AC12) и их доказательства — таблица «AC — доказательства»
в `docs/reviews/CODE-REVIEW-691-r1.md`, материал того раунда:
`53503e0373fe73d54ebccf5e70af8171ca778716` (дерево
`a7e88993df66e38c08587bda9eff3f757ecce457`).
- Чтение `src/logic.ts` (`spaceSwipeEdgeAt`/`classifySpaceDrag`/
`spaceSwipeTargetForOwner`) и `src/room-fit.ts`
(`PlanTapGestureController`) на предмет буквального соответствия §6/§7 ТЗ —
раздел «Что проверено и корректно» r1.
- Бюджет бандла (`INITIAL_VIEW_GZIP_CEILING` 300 300→301 000,
`scripts/monolith-baseline.json`) — не менялся в r2, число видно один раз,
источник один, как зафиксировано в r1.
- Применимость (побайтовая, статическая) 4 mutation-witness ID
(`double-fit-plan-owner-guard-removed`,
`space-swipe-edge-origin-guard-removed`,
`space-swipe-release-ignores-final-owner`,
`double-fit-interactive-pending-cancel-removed`) к текущему тексту
`src/logic.ts`/`src/room-fit.ts`/`src/houseplan-card.ts` — файлы не
менялись в r2, статус r1 не устарел; фактическое исполнение
`mutation-gate.mjs` по-прежнему не воспроизведено ни в одном раунде
(см. «Чего не проверял»), это тот же наследуемый, не блокирующий пробел.
- 29 зелёных smoke-прогонов из «прямых совпадений» `smoke-select`
(`smoke_editor_gestures.mjs`, `smoke_long_press_gesture.mjs`,
`smoke_isometric_contract.mjs`, `smoke_backdrop.mjs`,
`smoke_edit_walk.mjs` и остальные) — прогнаны и зафиксированы в r1, файлы
не менялись.
---
<!-- material-anchors: сгенерировано конвейером (#414) -->
## Материал раунда
- Ветка: `issue/691-touch-navigation`, коммит `33ae14a99d55` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
- Дерево материала: `2b04171e527bbe29a9f04e40a36f9b74028412f0`
```
git log --all --format='%H %T' | grep 2b04171e527b
```
- Тело issue: `e8f3dd66a656bbca09f4f291c52632feb3ee16759c54dc9dcdd4e328aaf99b7b`
- Вердикт конвейера: `green` · High 0