docs: review document for #609

Issue: #609
User-Visible: no
This commit is contained in:
claude[bot]
2026-09-23 01:08:16 +00:00
parent e8e5c863e4
commit 61292c9ea0
+188
View File
@@ -0,0 +1,188 @@
# CODE-REVIEW-609-r2
Issue: #609 · Этап: code · Заход: r2 · Блокирующих циклов израсходовано: 1 из 4
Материал: `e8e5c863e474ea70f5567510c96587f90eeafcfa` (рабочая копия на нём; `git status` чист)
Validate на этом SHA: success — https://github.com/Matysh/houseplan-card/actions/runs/35804202890
## Скоуп раунда
r1 (материал `4b27268e`) закрыт жёлтым вердиктом с единственным Medium: диагностика
`verify_ha_form_shell_609.mjs` не переключала тему/масштаб текста, а
`demo/srv/demo.html` жёстко задаёт тёмную палитру, так что AC5 не был доказан
исполнением, только заявлен. Один Low снят без цикла (мутанты ссылались на
несуществующий «AC8»).
Дельта r1→r2 — ровно один коммит, `e8e5c863` (`test(dialog): cover HA theme and
enlarged text`, `Issue: #609`, `User-Visible: no`):
```
demo/helpers/README-ha-dialog-505.md | 7 +-
demo/verify_ha_form_shell_609.mjs | 54 ++++++
docs/design/600-settings-dialogs/ACCEPTANCE.md | 6 +-
.../pairs/room-ha-dark-text-200.png | Bin 0 -> 57909 bytes
.../600-settings-dialogs/pairs/room-ha-light.png | Bin 41120 -> 47927 bytes
.../pairs/room-ha-mobile-light.png | Bin 30218 -> 33659 bytes
docs/reviews/CODE-REVIEW-609-r1.md | 194 +++++++++++++++++++
scripts/mutation-registry.mjs | 4 +-
```
**`src/**` не тронут** — продуктовый код идентичен материалу r1. Это подтверждено
`git diff --stat 4b27268e..e8e5c863` (список выше, ни одного файла класса A) и
делает объём разбора локальным: единственная подсистема, которую задевает
дельта, — диагностика/доказательства #609 (класс B) и её документация (класс C).
Рёбра комнат, `layout`, `marker.space`, `open_spans`, толщина стен дельтой не
затронуты — geometry-инварианты не в скоупе r2.
## Как проверялось
Дешёвые гейты (`npx tsc --noEmit`, `npm test`, `npm run build` + сверка бандла)
не перегонялись: они входят в зелёный Validate на этом же SHA, а дельта их не
касается (ни одного файла с типами или исполняемым продуктовым кодом).
Прогнал сам, целиком по делу этого раунда:
1. **`node demo/verify_ha_form_shell_609.mjs`** (без `--capture`, чтобы не менять
рабочую копию) — green. Снял фактические значения из JSON-вывода:
- light desktop: `cardBackground rgb(255,255,255)`, `formBodyBackground
rgb(231,234,238)`, `colorScheme light`, `rootFontSize 16px`, panel 560×940,
один `scrollOwners` (`.body.ha-scrollbar`);
- dark + 200%: `cardBackground rgb(32,33,38)`, `formBodyBackground
rgb(43,45,51)`, `colorScheme dark`, `rootFontSize 32px`, panel по-прежнему
560×940 (±1px), один scroll-owner, `horizontalOverflow: false`, footer в
границах панели.
Оба набора чисел совпадают с тем, что автор привёл в комментарии передачи —
не «на слово», а по фактическому stdout.
2. **Тест умеет падать.** Временно вырезал первый вызов `setPresentation({theme:
'light', ...})` (эмуляция ровно того бага, который нашёл r1: демо остаётся на
жёстко зашитой тёмной палитре) и перезапустил — тест упал на
`desktop.cardBackground`: `actual 'rgb(28, 37, 48)'` (буквально
`--card-background-color:#1c2530` из `demo/srv/demo.html:9`) против `expected
'rgb(255, 255, 255)'`. Это тот самый регресс, который r1 требовал исключить.
Файл восстановлен из бэкапа, `git status` после — чист.
3. **`node demo/smoke_ha_form_shell_parity.mjs`** (дешёвый Validate-свидетель,
файл не входит в дельту, но зависит от той же CSS-цепочки) — green.
4. **`node scripts/mutation-gate.mjs --check`** — все мутанты `ok`, включая три
формо-оболочечных: `ha-form-shell-width-falls-back-to-generic`,
`ha-form-shell-loses-canvas`, `ha-form-shell-mobile-keeps-desktop-inset`
(последние два — с исправленным в дельте r2 комментарием).
5. **`node scripts/check-docs.mjs`** — `Documentation checks passed (7 files, 12
external links)`. Формально дельта не трогает `src/**`, поэтому отпечаток
документации не обязан быть перепрогнан по правилам раунда — прогнал всё
равно, т.к. дельта меняет `docs/design/**` и README рядом; green.
6. **`npm run bundle:sync`** перед пунктом 1 (диагностике нужен свежий бандл) —
`git status` до и после идентичен: бандл уже был синхронизирован, новых
изменений в `dist/**`/`custom_components/houseplan/frontend/**`/`demo/srv/assets/**`
не появилось.
7. Прочитал производственный CSS, который делает возможным сам трюк
`setPresentation`: `src/hp-dialog.ts:211-217` (`.content` канва —
`--secondary-background-color`) и `src/styles/dialogs.styles.ts:568-583`
(`hp-dialog[form-shell] .body` — `--hpf-canvas`, который сам фолбэчит на
`--secondary-background-color`; `src/styles/form-kit.styles.ts:544`). Тест
переопределяет ровно эти custom properties на `documentElement`, инлайн-стиль
которого перебивает захардкоженный `:root{}` в `demo.html` — механизм фикса
соответствует продуктовому коду, а не подгоняет тест под цифры.
**Не прогонял и почему:** `npx tsc --noEmit`, `npm test`, `npm run build` (с
трёхкратной сверкой копий бандла) и `npm run golden:verify` — покрыты зелёным
Validate на этом же SHA, а дельта их зону не задевает (нет продуктового TS, нет
изменений, видимых golden). `npm run invariants` — дельта не трогает геометрию.
Полный список browser smoke (`demo/smoke_*.mjs`) — дельта касается ровно одной
подсистемы (#609 form-shell диагностика), прогон всех остальных не добавил бы
доказательной силы; `scripts/smoke-select.mjs` не запускал отдельно, т.к. годный
кандидат (`smoke_ha_form_shell_parity.mjs`) уже очевиден по имени и уже
прогнан. `python -m pytest tests_backend` — дельта не трогает
`custom_components/**/*.py`.
## Закрытие раунда r1
| Находка r1 | Чем закрыта | Где это видно |
|---|---|---|
| **Medium** — AC5 не доказан исполнением: диагностика не переключает тему/шрифт, `demo.html` жёстко задаёт тёмную палитру, светлая тема физически не возникает | `demo/verify_ha_form_shell_609.mjs` получил `setPresentation()`, который инлайн-стилем на `documentElement` перебивает захардкоженные HA-токены `demo.html`, плюс новый desktop-кейс `dark + root font 32px` | `demo/verify_ha_form_shell_609.mjs:99-114` (функция), `:147-186` (вызовы и ассерты для light и dark/200%); исполнено мной — см. п.1 «Как проверялось», реальные rgb-значения совпадают для обеих тем, а откат первого вызова `setPresentation` воспроизвёл именно старый баг (п.2) |
| **Low** (снят без цикла) — два мутанта в `mutation-registry.mjs` ссылаются на несуществующий «AC8» | Ссылки исправлены на реальные пункты ТЗ | `git diff 4b27268e..e8e5c863 -- scripts/mutation-registry.mjs`: `#609 AC1/AC8` → `#609 AC1`, `#609 AC4/AC8` → `#609 AC4`; `mutation-gate.mjs --check` подтверждает оба мутанта по-прежнему `ok` |
## Унаследовано из r1
Без повторной проверки в r2 принято (документ `docs/reviews/CODE-REVIEW-609-r1.md`,
SHA `4b27268e`, вердикт жёлтый · High 0 · Medium 1):
- **AC1** (desktop 560×940, канва, один scroll-body, footer) — доказано
исполнением `verify_ha_form_shell_609.mjs` на закреплённом
`home-assistant-frontend==20260729.7`.
- **AC2** (mobile fullscreen 480×800 и 390×844, без переполнения) — то же.
- **AC3** (пять потребителей form-shell + отрицательный generic-контроль) —
`smoke_ha_form_shell_parity.mjs` + `test/form-shell-consumers.test.mjs`
(r1 лично снял `form-shell` у room-settings-dialog.ts и увидел падение).
- **AC4** (13 golden-сцен диалогов не меняются) — `golden:verify` зелёный на
Linux; инфраструктурно golden-харнес не регистрирует `ha-dialog`, поэтому
CSS для этой ветки не может задеть пиксели нативной ветки.
- **AC6** (мутанты ловят потерю ширины/канвы/fullscreen) — три мутанта
зарегистрированы и проверены по отдельности на настоящую регрессию.
- **AC7** (фикстура #505 без внешних запросов/WebSocket/ошибок) —
`fixture.assertClean()` в диагностике, проверено r1.
- Продуктовый код `src/hp-dialog.ts` и `src/styles/dialogs.styles.ts` в части
#609 — прочитан r1 построчно и не менялся с тех пор (подтверждено пустым
`git diff --stat 4b27268e..e8e5c863` по `src/**`), поэтому в r2 не перечитывал
заново весь файл — только фрагменты, нужные для проверки механизма
`setPresentation` (п.7 «Как проверялось»).
Не наследую слепо: пересчитал заново именно то, что задевает дельта — AC5 и
оба Low-мутанта, см. таблицу выше.
## Находки
Нет находок, оставшихся в скоупе после закрытия r1. Продуктовых, архитектурных
или новых замечаний к самой дельте (диагностика + документация) не нашёл:
логика переопределения тем соответствует реальным CSS-переменным продукта
(проверено чтением и исполнением), числа в тесте и в комментарии автора
совпадают буквально, тест доказанно падает при откате фикса.
## Что проверено и корректно
- Механизм `setPresentation` не подделывает результат: он переопределяет ровно
те custom properties, которые продукт уже читает (`--card-background-color`,
`--secondary-background-color`, `--ha-card-background`), а не создаёт
параллельную систему цветов.
- «Одно число — один источник»: `cardBackground` и `formBodyBackground`
снимаются с реальных DOM-узлов (`getComputedStyle`) после `card.updateComplete`,
а не задаются тестом напрямую — сравнение честное, не тавтология.
- Скриншоты-доказательства (`room-ha-light.png`, `room-ha-mobile-light.png`,
новый `room-ha-dark-text-200.png`) пересняты в момент, когда фикстура
действительно в заявленной теме (byte-diff трёх файлов это подтверждает —
старые два не идентичны новым, значит не переиспользованы вслепую).
- Трейлеры коммита `e8e5c863`: `Issue: #609`, `User-Visible: no` — верно,
продуктовое поведение не изменилось; изменений в `demo/golden/baselines/**`
нет, поэтому `Release:`/`Baseline-Reviewed:` не требуются; changelog не
тронут, что согласуется с `User-Visible: no`.
- Класс изменений выдержан: `demo/**` и `scripts/**` — класс B (issue
переиспользован, как разрешено), `docs/**` — класс C, часть DoD issue; ни
один файл класса A/D не в дельте кроме уже подтверждённого пустого diff
бандла после `bundle:sync`.
## Чего не проверял
- Полный набор `npm test` / `tsc --noEmit` / `npm run build` — не перегонял,
положился на зелёный Validate этого SHA (дельта их зону не задевает).
- `golden:verify` в этом раунде — не перегонял; продуктовый CSS не менялся, а
r1 уже подтвердил, что golden-харнес не видит `ha-dialog`-ветку в принципе.
- Полный список `demo/smoke_*.mjs` — прогнал только адресный
`smoke_ha_form_shell_parity.mjs`; остальные не относятся к дельте (только
диагностика и docs одного issue).
- `npm run invariants` — дельта не меняет геометрию/рёбра/`layout`.
- `python -m pytest tests_backend` — дельта не трогает Python.
- Живой настоящий HA вручную (браузером) — по правилам процесса ручного
тестирования в цикле нет; доказательство — исполнение диагностики на
закреплённой офлайн-фикстуре #505, что и было сделано.
---
<!-- material-anchors: сгенерировано конвейером (#414) -->
## Материал раунда
- Ветка: `issue/609-ha-form-shell-parity`, коммит `e8e5c863e474` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
- Дерево материала: `8b68353a33207d127ff8a4789c3bbd38150751d3`
```
git log --all --format='%H %T' | grep 8b68353a3320
```
- Тело issue: `b08b9257ed688a47f3a0f422cdddc1bfc7cf7c511e81ada3ceeac8c2ce354d51`
- Вердикт конвейера: `green` · High 0