Files
houseplan-card/docs/reviews/CODE-REVIEW-400-r2.md
T
2026-08-31 05:22:03 +00:00

171 lines
13 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-400-r2
- Issue: https://github.com/Matysh/houseplan-card/issues/400
- ТЗ: `docs/specs/400-beta-polish.md` (r1), ревью ТЗ зелёное (комментарий 2026-08-31T04:44:56Z)
- Ревью r1: `docs/reviews/CODE-REVIEW-400-r1.md`, вердикт жёлтый, SHA `73ecfbd1d74a6d194f62e8e83766294018f8eb81`, опубликовано коммитом `f07e3c54` (2026-08-31T05:06:35Z)
- Диапазон материала r2: `origin/dev...HEAD`, HEAD на момент разбора и на момент вердикта — `f07e3c54ffea88b0d77b12065bf318fc820d0ebf`
- Заход r2, блокирующих циклов израсходовано **1 из 4** до этого вердикта
## Дельта раунда (§2.10)
Предыдущий вердикт получен на SHA `73ecfbd1`. Дельта:
```
$ git diff 73ecfbd1..HEAD --stat
docs/reviews/CODE-REVIEW-400-r1.md | 196 +++++++++++++++++++++++++++++++++++++
1 file changed, 196 insertions(+)
```
Это **единственный** коммит между r1 и r2 — публикация документа r1-ревью самим
конвейером. `git diff 73ecfbd1..HEAD -- src/ scripts/ demo/` пуст. Ни один файл
кода, теста или мутанта не изменился с момента r1.
Однако в issue после публикации r1 есть комментарий автора (2026-08-31T05:14:07Z,
**позже** документа r1 на 5:06:35Z): *«Medium закрыт, HEAD обновлён»*, описывающий
конкретную правку — именованную константу `HANDLE_PAINT_ORDER = ['edges',
'corners']`, изменённый патч мутанта, замену `handles[3]` на выбор ручки по роли
в `smoke_furniture`. Это и есть предмет разбора r2: делает ли фактический
репозиторий то, что утверждает комментарий.
**Ответ: нет.** Ни одна из трёх заявленных правок не существует ни в одном
коммите ни одной ветки:
```
$ git grep -l "HANDLE_PAINT_ORDER" $(git rev-list --all) -- src/
(пусто — по всей истории репозитория)
$ for b in $(git branch -a --format='%(refname)' | grep issue/400); do git log $b --oneline -3; done
f07e3c54 docs: review document for #400
73ecfbd1 build: refresh bundle trees and the doc capture for #400
fe3b85c0 fix: the corner handle wins on small furniture, guides exclude the real drag (#400)
(других веток с #400 нет)
$ grep -n "handles\[3\]" demo/smoke_furniture.mjs
360: const se = handles[3] || stageEl(); // SE — четвёртый угол
```
`git fetch origin issue/400-beta-polish` не принёс новых коммитов — `HEAD` на
удалённой ветке совпадает с локальным. Единственное отдалённо связанное действие
после комментария — коммит `f07e3c54`, но это публикация r1-ревью, а не фикс.
## Закрытие раунда r1
| Находка r1 | Чем закрыта | Где это видно |
|---|---|---|
| **M1** — мутант `furniture-edge-handles-steal-the-corner` правит только текст JS-комментария, не порядок отрисовки; регрессию AC1 не ловит | **Не закрыта.** Автор заявил фикс в комментарии, но код не изменился | `git diff 73ecfbd1..HEAD -- src/ scripts/` пуст; повторный прогон ниже даёт тот же результат, что в r1 |
Повторный прогон того же гейта, что дал находку в r1:
```
$ node scripts/mutation-gate.mjs --id=furniture-edge-handles-steal-the-corner
ok чистый прогон: node demo/smoke_furniture_polish.mjs
FAIL furniture-edge-handles-steal-the-corner: тест остался зелёным на сломанном коде
поймано 0 из 1
```
Идентично записи в CODE-REVIEW-400-r1.md. Патч мутанта в
`scripts/mutation-gate.mjs:756-759` по-прежнему меняет только строку внутри
`/* ... */`.
## Унаследовано из r1
Всё, что предметно не связано с M1, дельта не задевает (дельта нулевая), поэтому
принимается без повторной проверки по документу `docs/reviews/CODE-REVIEW-400-r1.md`,
SHA `73ecfbd1`:
- AC1/AC2 (угловая ручка выигрывает хит на мелкой мебели) — доказаны живым
браузерным смоком `smoke_furniture_polish.mjs` (`smallFurnitureCornerWinsTheHit:
true`, `largeFurnitureKeepsBothHandles: true`), прогнано вживую в r1.
- AC4/AC5 (`_alignCandidates` исключает по `_deviceDrag`) — доказаны смоком
`smoke_align_guides.mjs` и вторым мутантом (`align-guides-exclude-dead-source`,
«поймано 1 из 1»); перепрогнан в r2 с тем же результатом (см. таблицу гейтов).
- AC3/AC6 (решение по 38 help-строкам в `docs/ARCHITECTURE.md`, бюджет
285 425 / 300 000) — подтверждены в r1 чтением записи и прогоном `bundle:budget`;
в r2 бюджет перепрогнан и даёт то же число (см. ниже) — код не менялся, значит
и вывод не мог измениться.
- Трейлеры четырёх содержательных коммитов (`60c211c8`, `532743b0`, `fe3b85c0`,
`73ecfbd1`) — проверены в r1, дельта их не касается.
- Смок-выборка `scripts/smoke-select.mjs --base origin/dev --head HEAD` и 9
зелёных прямых совпадений — не перезапускались в r2: набор файлов, который они
покрывают, не изменился (дельта r2 — один docs-файл).
## Как проверялось (r2)
Дешёвые гейты гоняются в каждом раунде независимо от локальности дельты (§2.10).
Диапазон src/scripts не менялся, но числа сверены заново, а не унаследованы вслепую.
| Гейт | Команда | Результат |
|---|---|---|
| typecheck | `npx tsc --noEmit` | чисто |
| unit | `npm test` | 1668 tests, 1667 pass, 0 fail, 1 skipped — совпадает с r1 |
| build | `npm run build` | успешно, 15.6s |
| сверка трёх копий бандла | `npm run bundle:sync` | `git status --porcelain` пуст до и после — `dist`, `custom_components/houseplan/frontend`, `demo/srv/assets` уже синхронизированы, дрейфа нет |
| бюджет | `npm run bundle:budget` | initial 285 425 / 300 000, тот же варнинг про запас < 15 000 Б (#367, фоновый, не следствие этой задачи) — число идентично r1 |
| мутант (предмет M1) | `node scripts/mutation-gate.mjs --id=furniture-edge-handles-steal-the-corner` | **красный, как в r1**: поймано 0 из 1 |
| мутант (контроль) | `node scripts/mutation-gate.mjs --id=align-guides-exclude-dead-source` | зелёный: поймано 1 из 1, без изменений |
Не прогонялось (дельта — один docs-файл, ничего из перечисленного её не
задевает и было закрыто в r1): `check-docs.mjs` (diff r2 не трогает `src/**`),
`no-new-any.mjs` (нет новых строк кода), `smoke-select.mjs` (набор символов не
менялся), `model-invariants.mjs` (diff не про геометрию), `golden:verify`,
`pytest tests_backend`, performance-профили, полный набор смоков.
## Находки
### Medium (в скоупе задачи — по-прежнему открыта из r1)
**M1 (перенесена из r1, не закрыта).** Мутационный гейт
`furniture-edge-handles-steal-the-corner` всё ещё не воспроизводит регрессию
AC1: патч правит текст JS-комментария в `src/houseplan-card.ts`, физический
порядок отрисовки `sides`/`corners` не меняется, «поймано 0 из 1» —
воспроизведено исполнением, идентично r1.
Дополнительно к находке r1: комментарий автора от 2026-08-31T05:14:07Z
заявляет закрытие с конкретными деталями (константа `HANDLE_PAINT_ORDER`,
переписанный патч мутанта, замена `handles[3]` на роль в `smoke_furniture.mjs`),
которых нет ни в одном коммите ни одной ветки репозитория — проверено
`git diff`, `git grep` по всей истории и `git fetch` удалённой ветки. Это не
новый дефект по существу (функциональность AC1/AC2 по-прежнему работает и
доказана живым смоком, унаследовано из r1), а расхождение между тем, что
записано в issue, и тем, что лежит в git. Возможные причины — потерянный push,
работа в незакоммיтированной рабочей копии, коммит на изолированной среде,
которая не долетела до `origin`. Это не блокирует зелёный вердикт сверх того,
что уже блокировала находка M1 сама по себе, но без исправления **само
исправление M1 остаётся фактически не начатым**, и владельцу до следующего
раунда стоит убедиться, что описанная в комментарии правка вообще существует
где-то за пределами текста комментария.
**Почему Medium, а не High**: тот же довод, что в r1 — сама функциональная
правка AC1/AC2 верна и доказана живым браузерным смоком, ломается только
постоянная защита от будущего отката (мутационный гейт), а не текущее
поведение продукта.
**Ожидаемо** (не изменилось с r1): патч мутанта должен реально возвращать
`corners` перед `sides` (или иным способом менять фактический порядок
рендера). Проверка приёмки: `node scripts/mutation-gate.mjs
--id=furniture-edge-handles-steal-the-corner` → «поймано 1 из 1», и это должно
быть видно в `git diff` этой ветки, а не только в тексте комментария.
## Что проверено и корректно
- Все AC, кроме предмета M1, — без изменений с r1, унаследовано с указанием
источника выше.
- Дешёвые гейты r2 воспроизводят те же числа, что в r1 (tsc чист, 1667/0 тестов,
бюджет 285 425/300 000, три копии бандла синхронизированы) — ожидаемо, так как
дельта нулевая по коду.
- Контрольный мутант `align-guides-exclude-dead-source` по-прежнему ловит свою
регрессию (1 из 1) — AC4/AC5 не деградировали.
- Ветка `issue/400-beta-polish` — единственная с материалом по #400; других
мест, где могла бы жить заявленная правка, не найдено.
## Чего не проверял
- Не искал вне git (например, в артефактах CI-запусков или локальных стейджах
автора) заявленную правку — ревью материалом считает только репозиторий, как
предписано; если правка существует где-то ещё, её нужно закоммитить и
запушить, тогда она попадёт в следующую дельту.
- Не прогонял `check-docs.mjs`, `no-new-any.mjs`, `smoke-select.mjs`,
`model-invariants.mjs`, `golden:verify`, `pytest tests_backend`,
performance-профили и полный набор смоков — дельта r2 их не касается
(единственный файл дельты — docs), и они были закрыты в r1 на том же коде.