Files
houseplan-card/docs/reviews/CODE-REVIEW-533-r2.md
T
2026-09-11 16:44:22 +00:00

135 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.
# 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