diff --git a/docs/reviews/CODE-REVIEW-508-r2.md b/docs/reviews/CODE-REVIEW-508-r2.md new file mode 100644 index 00000000..7ef3ecd9 --- /dev/null +++ b/docs/reviews/CODE-REVIEW-508-r2.md @@ -0,0 +1,193 @@ +# CODE-REVIEW-508-r2 + +Issue: #508 — «Сводная панель: в диалоге настроек не работает прокрутка — колесом мыши и touch на мобильных» +Материал: `6ac513caa09a8e583869879412aa3a0c67d04488` (рабочая копия уже на нём). Ветка приведена конвейером к +`dev` до ревью: `e23d742c → 6ac513ca`, поверх легло 1 коммит `dev` (несвязанный — `docs: review document +for #502`). +Заход: r2 · блокирующих циклов израсходовано 0 из 4. Ребейз на ушедший вперёд `dev` формально делает +дерево другим (§7.2) → разбор полный, а не по дельте. + +## Почему вообще r2, если r1 был зелёным без находок + +Код-ревью r1 (`docs/reviews/CODE-REVIEW-508-r1.md`, материал `768e1281`) уже завершилось вердиктом +«зелёный, находок нет» с исчерпывающим личным прогоном гейтов, мутантов, смоков и подтверждением автора +на живом стенде HA. Сразу после публикации вердикта автор сообщил в issue: «Автоматическое ревью не +отработало» — статусная метка не переставилась, конвейер оставил задачу на месте. Затем конвейер +перебазировал ветку на успевший уйти вперёд `dev` (там landing получил несвязанный коммит с ревью-доком +для issue #502) и передал её на повторное ревью уже под новым SHA. Автор с момента r1 в код и ТЗ не +вносил ничего — это не возврат на правки, а техническое повторение ревью из-за сбоя механики метки плюс +ребейз. Поэтому раздела «находка → возврат → правка» в этом раунде по существу нет: проверка ниже — +подтверждение, что ребейз не изменил и не сломал ничего, а не разбор чьих-то правок. + +## Скоуп + +Не изменился с r1: один функциональный коммит (`e38beed7`, экс-`768e1281`) — класс A (`src/hp-dialog.ts`, +`src/summary-panel-editor.ts`) + класс B (новый смок `demo/smoke_summary_dialog_scroll.mjs`, контрактный +юнит-тест `test/hp-dialog-contract.test.mjs`, два мутанта в `scripts/mutation-gate.mjs`) + класс C +(`docs/ARCHITECTURE.md`, оба CHANGELOG) + класс D (пересобранный бандл во всех копиях, +`docs/images/screenshots.json` — только фингерпринт). `hp-dialog` получает opt-in булев атрибут +`flex-content` (`?flexcontent` на `ha-dialog`, обе HA-ветки рендера); нативная ``-ветка не тронута. +Диалог настроек сводной панели его объявляет — единственный из десяти вызывающих ``. + +J1 (`docs/SCOPE.md`) — обзорная сводная панель входит в «show the whole home at a glance»; чистый +баг-фикс регресса после #505, скоуп не расширен, продукт не меняет договор. + +## Как проверялось (это не дельта — это независимая перепроверка «ничего не изменилось») + +Первый шаг — не поверить заявлению «ребейз ничего не тронул», а доказать его: + +``` +git diff 768e1281 e38beed7 --stat # r1-материал vs текущий фикс-коммит +``` + +Результат: единственная разница — файл `docs/reviews/SPEC-REVIEW-502-r1.md` (несвязанный коммит `dev` для +issue #502). Все файлы продукта — `src/hp-dialog.ts`, `src/summary-panel-editor.ts`, +`test/hp-dialog-contract.test.mjs`, `docs/ARCHITECTURE.md`, оба CHANGELOG, `scripts/mutation-gate.mjs`, +`demo/smoke_summary_dialog_scroll.mjs`, весь пересобранный бандл — побайтово идентичны материалу r1. +`docs/images/screenshots.json` проверен построчно (`grep imageSha256` на диффе): изменились только +`sourceFingerprint`/`sourceSha256`-контекст, ни один `imageSha256` не сдвинулся. + +Это и определило объём: код доказанно тот же, что уже получил зелёный вердикт с личными прогонами гейтов, +мутантов и смоков (не только заявлением автора — заявление в r1 тоже было перепроверено исполнением). Все +выводы AC1–AC6 из r1 остаются в силе автоматически, потому что применяются к тому же байт-в-байт коду. Тем +не менее раунд объявлен «полным» (ребейз, §7.2), поэтому ниже — не просто ссылка на r1, а собственный +прогон части гейтов на текущем SHA `6ac513ca`, чтобы исключить эффекты самого ребейза (окружение сборки, +конфликт слияния бандла и т. п.), а не только идентичность текста диффа. + +### Дешёвые гейты + +Validate на `6ac513ca` зелёный (дано в задаче ревью, https://github.com/Matysh/houseplan-card/actions/runs/34397342070) +— `tsc`, `npm test` (2436/2436), `npm run build` со сверкой бандла уже подтверждены конвейером на этом +самом SHA, повторно не гонял. + +### Прогнано лично на `6ac513ca` (не на материале r1 — на текущем SHA) + +| Гейт/смок | Результат | +|---|---| +| `node --test test/hp-dialog-contract.test.mjs` (AC1 текстовая часть, AC4) | 3/3 pass | +| `node scripts/check-docs.mjs` (диф трогает `src/**`) | «Documentation checks passed (7 files, 12 external links)» — совпадает с числом из r1 | +| `node scripts/bundle-sync.mjs` (пересборка + раскладка по трём местам: `dist`, `custom_components/houseplan/frontend`, `demo/srv/assets`) | выполнено; `git status --porcelain` после — пусто (отслеживаемые копии не разошлись с коммитом) | +| `node demo/smoke_summary_dialog_scroll.mjs` (AC1/AC2, прямое совпадение) | `OK` | +| `node demo/smoke_summary_panel_polish.mjs` (AC3, прямое совпадение — файл смока не менялся) | `OK` | +| `node demo/smoke_dialog_modal_recovery.mjs` (зарегистрированная связь: общий `hp-dialog`) | `OK` | +| `node demo/smoke_esc_dialogs.mjs` (зарегистрированная связь) | `OK` | +| `node demo/smoke_dialog_footer_width.mjs` (зарегистрированная связь) | `OK` | +| `node scripts/mutation-gate.mjs --id=summary-dialog-drops-flex-content` | чистый прогон OK → мутация: «тест покраснел, как обязан» → поймано 1 из 1 | +| `node scripts/mutation-gate.mjs --id=hp-dialog-ignores-flex-content` | то же → поймано 1 из 1 | +| `node scripts/smoke-select.mjs --base origin/dev --head HEAD` | «НЕОПРЕДЕЛЁННОСТЬ» — 2 файла `src/**`, 0 символов на изменённых строках (тот же результат, что в r1); выбор смоков выше сделан вручную: прямое совпадение (диалог панели) + зарегистрированные связи (общий `hp-dialog`) | +| `grep -rn "`-ветка не содержит `flexcontent`/связанных селекторов — регресс на неё исключён и + тестом (`smoke_summary_panel_polish`), и построчным чтением. +- `docs/TOUCH-SUPPORT.md:48–49` называет «simple settings form» сводной панели гарантированной View-touch- + поверхностью — включение touch в скоуп не расширение, а обязательное соответствие контракту. +- Терминология CHANGELOG.ru.md («сводной панели», «настроек») совпадает с `docs/USER-GUIDE.ru.md:264` + («Настройки сводной панели»). +- `docs/images/screenshots.json`: только `sourceFingerprint`/`sourceSha256`; все 11 `imageSha256` + идентичны — докс-скриншоты не изменились по существу. +- Один коммит (`e38beed7`), трейлеры `Issue: #508` и `User-Visible: yes` на месте. +- После `bundle-sync` рабочая копия чиста (`git status --porcelain` пуст) — три копии бандла (`dist`, + `custom_components/houseplan/frontend`, `demo/srv/assets`) согласованы с закоммиченным. +- Ребейз сам по себе не внёс никакого продуктового изменения — доказано диффом, а не заявлено. + +## Находки + +Нет. High: 0, Medium: 0, Low: 0. + +## Чего не проверял и почему + +- `npm run golden:verify` — атрибут opt-in, `?flexcontent=` в Lit убирает атрибут целиком при `false`, + разметка прочих `hp-dialog` не меняется ни на байт; golden-сцен диалога сводной панели в репозитории нет + (снято ещё в `SPEC-REVIEW-508-r1.md` M1). Риск нулевой, решение то же, что в r1, переподтверждено тем же + рассуждением на идентичном коде. +- `python -m pytest tests_backend` — диф не касается `custom_components/houseplan/**/*.py`. +- Полная матрица смоков (237 шт.) и перф-профили — не названы в AC; `smoke-select` вернул + «НЕОПРЕДЕЛЁННОСТЬ» (2 файла `src/**`, 0 символов на изменённых строках, порог «широкого» — 47 смоков). + Выбор сужен вручную до прямого совпадения (`smoke_summary_dialog_scroll`, `smoke_summary_panel_polish`) и + зарегистрированных связей на общий `hp-dialog` (`smoke_dialog_modal_recovery`, `smoke_esc_dialogs`, + `smoke_dialog_footer_width`) — все пять прогнаны лично, все зелёные. +- `npm run invariants` — диф не трогает геометрию/рёбра комнат/`layout`/`marker.space`/`open_spans`, гейт не + применим. +- Полный `npm test` (все 2436 юнитов) — не переигрывал повторно вживую: Validate CI уже подтвердил его + зелёным на этом самом SHA `6ac513ca` (ссылка выше), а не на другом; вместо повторного полного прогона + лично выполнен целевой `test/hp-dialog-contract.test.mjs`. + +## Вердикт + +Зелёный. Разбор — полный (ребейз, §7.2), но не «с нуля»: доказано диффом, что код байт-в-байт идентичен +уже одобренному материалу r1, и это доказательство переподтверждено собственными прогонами гейтов, смоков +и мутантов на текущем SHA `6ac513ca`, а не принятием чужого вердикта на веру. Находок нет. Раунд не +образует цикл (§4) — вердикт зелёный. + +--- + + + +## Материал раунда + +- Ветка: `issue/508-summary-dialog-scroll`, коммит `e23d742cd508` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. +- Дерево материала: `5fc02b5d1de102ed9770f28fc5eb3a41098cbc11` + ``` + git log --all --format='%H %T' | grep 5fc02b5d1de1 + ``` +- Вердикт конвейера: `green` · High 0