docs: review document for #533

Issue: #533
User-Visible: no
This commit is contained in:
claude[bot]
2026-09-11 16:44:22 +00:00
parent 73c13e37b4
commit e09bb2faee
+134
View File
@@ -0,0 +1,134 @@
# CODE-REVIEW — issue #533, заход r2
**Материал:** `73c13e37b4f81ebac42777a6ad7a50d16b7da69b` (рабочая копия уже на
нём). Предыдущий вердикт — r1, жёлтый, на SHA `acea695069075fb1bd7592f3f2b38853bc9f4c32`
(документ `docs/reviews/CODE-REVIEW-533-r1.md`). SHA не был назван автором
явно в тексте ответа — найден по цепочке `acea6950 -> 73c13e37` в
`git log --oneline origin/dev..HEAD`.
**Дельта:** `git diff acea6950..73c13e37 -- demo/smoke_room_resize.mjs`
(+20/-20 строк, один файл). Дельта закрывает ровно находку r1 и не выходит
за её границы — правка того же вида на оставшихся местах, без изменения
условий `pointer()`, `sent()`, `mapping_stable`. Разбор в этом раунде сужен
до дельты плюс всего, до чего она дотягивается: сами имена проверок, которые
дельта добавляет.
## Закрытие раунда r1
| находка r1 | чем закрыта | где это видно |
|---|---|---|
| Medium: `sent()` стояла на 3 из 22 вызовов `pointer()` (только главный сценарий); 19 вызовов (`mixed_role`, `owner_boundary`/`range_role`-блок, `corner_clamped`, `preflight`, `commit_preflight`, `cancel`, disabled-блок) отбрасывали возвращаемое значение молча | каждый оставшийся `await pointer(...)` обёрнут в `sent('<scenario>.<event>_sent', ...)` | `demo/smoke_room_resize.mjs`, коммит `73c13e37`; проверено `grep -c "await pointer("` = `grep -c "sent("` = 23 (совпадает) — ни одного голого вызова не осталось |
Подтверждено самостоятельно, тем же приёмом, что и автор: временно испортил
цель `pointerdown` в disabled-сценарии (`cx: 331` → `cx: 999`, восстановлено
`git checkout --` сразу после), прогнал `node demo/smoke_room_resize.mjs` —
раньше немой `find` дал бы зелёный `OK`, сейчас красная строка
`owner_boundary.pointerdown_sent: expected true, got false` (файл
восстановлен, `git status` чист).
## Унаследовано из r1
Без повторной проверки приняты факты, которых дельта не касается (документ
`docs/reviews/CODE-REVIEW-533-r1.md`, SHA `acea6950`):
- **AC1, перевод координат внутри кадра события** — `pointer()` переводит
план → экран внутри того же `page.evaluate`, что и диспетч события; функция
не менялась в дельте r1→r2 (только точки её вызова обёрнуты снаружи).
- **AC1, прицел `pointermove`/`pointerup` в ту же ручку, что и `pointerdown`**
— через `cx/cy`, во всех сценариях; не менялось.
- **AC2, `safe_resize.mapping_stable`** — допуск `1e-6`, обе величины и оба
размера стейджа в сообщении; строки не в дельте.
- Продуктовый код не тронут, класс B (гейты/инструментарий), трейлеры
`Issue: #533` / `User-Visible: no` на обоих коммитах r1 и r2 — не требуют
ченджлога; повторно свёл `git log -1 --format=%B` на `73c13e37`, трейлеры
на месте.
## Новая находка (в дельте r2)
**Medium, в скоупе. Два из 22 новых `sent()`-лейблов называют не свой
сценарий**, что напрямую противоречит заявленной цели правки: «имя проверки
называет сценарий и тип события», «следующий случай на раннере читается с
первой строки» (AC2 того же духа применён автором и к AC1).
1. `demo/smoke_room_resize.mjs:212` — блок про `aria-disabled`-ручку (все
соседние проверки названы `safe_resize.disabled_*`: `disabled_no_drag`,
`disabled_zero_history`, `disabled_zero_write`) обёрнут как
`sent('owner_boundary.pointerdown_sent', ...)` — чужое имя сценария.
2. `demo/smoke_room_resize.mjs:263-265` — блок, чьи проверки названы
`safe_resize.owner_boundary_clamped/topology/no_mixed_role/cm_preserved`,
обёрнут как `sent('range_role.pointerdown_sent'/…)` — имя `range_role` не
совпадает ни с одной проверкой этого или соседнего блока вообще.
**Воспроизведение (эксперимент см. выше, «Закрытие раунда r1»):** испортил
`cx` в disabled-блоке — красная строка называется `owner_boundary.*`, хотя
упавший жест относится к disabled-сценарию, а не к owner_boundary. Будущий
разбор красного раннера прочитает не тот блок кода с первой строки — именно
то, чего AC2/AC1 обязаны были избежать.
**Не High:** ни один AC не ломается — `check()` по-прежнему верно
детектирует недоставленное событие (`result.sent`), обе проверки красные
именно тогда, когда должны быть красными; страдает только текст диагностики.
**В скоупе:** правка — переименовать две строки-лейблы
(`owner_boundary.pointerdown_sent` → `disabled.pointerdown_sent`;
`range_role.*` → `owner_boundary.*`), без изменения логики.
## Что проверено и как
- **AC1 (полнота `sent()`)** — `grep -c "await pointer("` и `grep -c "sent("`
в `demo/smoke_room_resize.mjs` дают одинаковое число (23); каждый вызов
проверен построчно (см. таблицу закрытия r1). Негативный прогон — см. выше.
- **AC2** — унаследовано из r1, дельта не касается.
- **AC3 (смок зелёный, мутант ловится)** — прогнал сам: `npm run build &&
npm run bundle:sync` (локальный `dist/houseplan-card.js` был собран на
более старом коде, демо не грузилось без пересборки), затем
`node demo/smoke_room_resize.mjs` → `OK`, 0 провалов, `mapping_stable`
сошёлся (`scale` `0.6144...` на `down` и `move`), `safeResizeResult`
`[450, 450, 450, 0.45]`. Плюс уже зелёный Validate на этом самом SHA
`73c13e37` (https://github.com/Matysh/houseplan-card/actions/runs/34622809175)
— покрывает раннер и штатный мутант `safe-resize-commit-preflight-bypassed`,
подтверждённый автором в ответе на r1.
- Дешёвые гейты `tsc --noEmit` / `npm test` / `npm run build` (сверка бандла)
не перегонял отдельно — Validate на `73c13e37` зелёный, диф не трогает
`src/**`, так что `check-docs.mjs` не требуется. Геометрия/модель не
затронуты — инварианты не применимы. `golden`, `pytest`, perf-профили — вне
диффа, не запускал.
- `demo/smoke-select.mjs --base acea6950 --head 73c13e37` не запускал: дельта
— правка того же файла-свидетеля тем же приёмом, что уже разобран в r1
(диффа продукта нет, смок сам себя не проверяет через другие смоки); выбор
смоков по инструменту относится к продуктовым диффам, здесь неприменим.
## Чего не проверял
- Остальные 5 сценариев смока (`safe_resize` главный, `mixed_role`,
`corner_clamped`, `preflight`, `commit_preflight`, `cancel`) на предмет
мисматча лейблов — построчно сверены (см. таблицу выше), несовпадений не
нашёл, но повторно не гонял с намеренной порчей `cx` на каждом — ограничился
одним репрезентативным экспериментом на дельте (`owner_boundary`/disabled).
- Полный набор `npm run golden:verify`, `pytest`, perf — не в скоупе диффа,
не запускал.
- Устойчивость `mapping_stable` на реальном CI-раннере при плывущей
раскладке — воспроизвести флуктуацию раскладки локально не пытался,
полагаюсь на зелёный Validate `73c13e37` как на прямое свидетельство того,
что гейт больше не мигает на этом материале.
## Вывод
AC1–AC3 выполнены. Находка r1 закрыта корректно и полно (23/23 вызовов).
Новая Medium-находка в дельте r2 — два лейбла `sent()` называют чужой
сценарий, что противоречит собственной заявленной цели правки
(понятная диагностика с первой строки). В скоупе задачи, чинится
переименованием двух строк без риска для AC. Возврат автору, жёлтый.
---
<!-- material-anchors: сгенерировано конвейером (#414) -->
## Материал раунда
- Ветка: `issue/533-resize-witness-mapping`, коммит `73c13e37b4f8` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
- Дерево материала: `0b69a7dd77e802de09b50798d0384291f1acbf5a`
```
git log --all --format='%H %T' | grep 0b69a7dd77e8
```
- Тело issue: `ae465893153dbb7ba1b9d991e2d5cf4a05c8f526b51ae2f2b74e6e2c566805d9`
- Вердикт конвейера: `yellow` · High 0