From 0a09712bc5fdd0330c5ee2ccb5b3523f9bba0d01 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Mon, 28 Sep 2026 14:32:51 +0000 Subject: [PATCH] docs: review document for #691 Issue: #691 User-Visible: no --- docs/reviews/CODE-REVIEW-691-r2.md | 201 +++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 docs/reviews/CODE-REVIEW-691-r2.md diff --git a/docs/reviews/CODE-REVIEW-691-r2.md b/docs/reviews/CODE-REVIEW-691-r2.md new file mode 100644 index 00000000..4e5828bc --- /dev/null +++ b/docs/reviews/CODE-REVIEW-691-r2.md @@ -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, файлы + не менялись. + +--- + + + +## Материал раунда + +- Ветка: `issue/691-touch-navigation`, коммит `33ae14a99d55` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. +- Дерево материала: `2b04171e527bbe29a9f04e40a36f9b74028412f0` + ``` + git log --all --format='%H %T' | grep 2b04171e527b + ``` +- Тело issue: `e8f3dd66a656bbca09f4f291c52632feb3ee16759c54dc9dcdd4e328aaf99b7b` +- Вердикт конвейера: `green` · High 0