docs: review document for #639
Проверка (CI) / Классификация изменённых файлов (push) Successful in 43s
Проверка (CI) / HACS: валидация репозитория (push) Skipped
Проверка (CI) / Hassfest: манифест интеграции (push) Skipped
Проверка (CI) / Мутанты по диффу (1/6): затронутые свидетели краснеют (push) Skipped
Проверка (CI) / Мутанты по диффу (2/6): затронутые свидетели краснеют (push) Skipped
Проверка (CI) / Мутанты по диффу (3/6): затронутые свидетели краснеют (push) Skipped
Проверка (CI) / Мутанты по диффу (4/6): затронутые свидетели краснеют (push) Skipped
Проверка (CI) / Мутанты по диффу (5/6): затронутые свидетели краснеют (push) Skipped
Проверка (CI) / Мутанты по диффу (6/6): затронутые свидетели краснеют (push) Skipped
Проверка (CI) / Фронтенд: типы, юниты, мутанты, синхрон бандла (push) Skipped
Проверка (CI) / Предполёт: документация, провенанс, процесс (push) Failing after 1m2s
Проверка (CI) / Переиспользование: это дерево уже проверено (push) Successful in 1m9s
Проверка (CI) / Смоки в браузере (шард 1 из 3) (push) Skipped
Проверка (CI) / Смоки в браузере (шард 2 из 3) (push) Skipped
Проверка (CI) / Смоки в браузере (шард 3 из 3) (push) Skipped
Проверка (CI) / Смоки: все шарды зелёные (push) Skipped
Проверка (CI) / Golden-кадры против принятых эталонов (push) Skipped
Проверка (CI) / Перф-смок: бюджет времени кадра (push) Skipped
Проверка (CI) / Геометрия: TS/Python parity исполнена (push) Skipped
Проверка (CI) / Бэкенд: pytest в Home Assistant (push) Skipped
Проверка (CI) / Доказательство выполненных проверок (push) Failing after 31s

Issue: #639
User-Visible: no
This commit is contained in:
claude[bot]
2026-09-23 09:21:53 +00:00
parent a3397329d5
commit b1f1f6b754
+179
View File
@@ -0,0 +1,179 @@
# CODE-REVIEW · issue #639 · заход r2
Материал: `a3397329d53487d0c8b78df02fadd161475c9cb9` (рабочая копия на нём).
Заход r2, блокирующих циклов ревью израсходовано 1 из 4 (жёлтый вердикт r1
цикл не тратит — бюджет §4 списывается с жёлтых/красных, а r1 сам был
жёлтым; счётчик 1/4 в шапке задачи относится к другому событию конвейера,
не к этому ревью).
Предыдущий раунд: r1, вердикт **жёлтый**, материал `0ac08434b5cd12848ce8b18aa17a6343b83b6653`
(SHA назван в служебном блоке «§2.10 материал раунда» под комментарием r1 —
сам вердикт его в тексте не повторяет). Документ: `docs/reviews/CODE-REVIEW-639-r1.md`
(закоммитирован в этой же ветке как `368ea35f`).
## Дельта r2
`git diff origin/dev...HEAD --stat` относительно r1 показывает три файла в
ветке; из них к дельте раунда относится только один — `368ea35f` (сам
документ r1, публикуемый конвейером) и `9cf848c1` (`scripts/smoke-links.mjs`)
уже были материалом r1. Новый по отношению к r1 — единственный коммит:
```
a3397329 test(smoke): коммитить размер шрифта пространства через DOM (#639)
demo/smoke_space_settings_form.mjs | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
```
Это ровно правка по единственной находке r1 (M1). Объекты старого материала
`0ac08434`/`71e8dc29` в текущем дереве недоступны (веб ветки после ребейза
переписал историю — автор описал это в возврате r2: «исходные исправления
room/device уже оказались в актуальном `dev`»), поэтому дельта сверялась не
`git diff <SHA>..HEAD`, а прямым `git show a3397329` — единственный коммит
после материала r1, содержимое совпадает с тем, что описывает возврат
автора.
Диапазон дельты локален: один файл, тестовая инфраструктура, тот же смок,
что и в r1. Полный повторный разбор не требуется — расширяю его только до
границ, которые эта дельта задевает (сам смок и подтверждающий его код
`form-kit.ts`/`space-form.ts`), остальное наследую из r1.
## Закрытие раунда r1
| находка | чем закрыта | где это видно |
|---|---|---|
| **M1** (Medium, в скоупе): запись `smoke-links.mjs` для `rangeLine`/`unitInput` заявляла, что `smoke_space_settings_form.mjs` «drives … space card font … through the DOM», хотя код присваивал `c._spaceDialog.cardFontScale` напрямую, минуя `#space-card-font` | `demo/smoke_space_settings_form.mjs:139-145` (коммит `a3397329`): вместо прямого присваивания драфта — `cardFontInput.value='150'` → `dispatchEvent('input')` → assert `fontDraftWaitsForChange` (черновик НЕ коммитится на `input`) → `dispatchEvent('change')` → assert `fontNumberCommitsThroughDom` (`cardFontScale===1.5`, Reset разблокирован) | Diff коммита `a3397329`; воспроизвёл падение, откатив ровно эти строки к варианту r1 (прямое присваивание) — `fontDraftWaitsForChange: expected true, got false`, `FAILED (1)`. Восстановил файл, дерево чистое |
Текст записи `smoke-links.mjs:47-49` не менялся этим коммитом (и не должен
был) — теперь он просто перестал быть ложью: `smoke_space_settings_form.mjs`
действительно ведёт число через DOM ровно как заявлено.
## Как проверялось (только то, что задевает дельта)
1. Прочитал diff `a3397329` целиком (8 строк) — единственное изменение в
`demo/smoke_space_settings_form.mjs`.
2. Прочитал по коду путь коммита, который смок теперь проверяет:
`src/editors/space-form.ts:428-431` — `#space-card-font` собран через
`rangeLine({ min:50, max:300, step:5, slider: port.rangeInput(...), onInput: (n) => set(port, {...d, cardFontScale: n/100}) })`;
`src/editors/form-kit.ts:470-489` — `rangeLine()` монтирует числовое поле
с `onInput: () => undefined` (черновик не коммитится) и `onChange` →
`committedRangeLineValue` → коммит. `150/100 = 1.5` — совпадает с
ассертом `cardFontScale === 1.5`. Это тот же контракт, что ломался в
#608, и теперь смок идёт через него, а не мимо.
3. Собрал бандл (`npm run bundle:sync`) — Validate этот прогон уже
подтвердил на `a3397329`, но локальной копии `demo/srv/assets` не было,
а без неё браузерные смоки не запускаются; пересборка нужна была для
пункта 4, не для повторной проверки `tsc`/`build`.
4. `node demo/smoke_space_settings_form.mjs` на HEAD — `OK`, включая новые
ассерты `fontDraftWaitsForChange`/`fontNumberCommitsThroughDom`,
зарегистрированные в `checkAll(out)` (проверил `demo/serve.mjs:75-77` —
`checkAll` требует `true` от каждого ключа объекта `out`, значит новые
поля действительно участвуют в вердикте смока, а не просто вычисляются).
5. **Тест умеет падать**: временно вернул ровно правленые строки к
варианту r1 (`c._spaceDialog = { ...c._spaceDialog, cardFontScale: 1.5 }`
без DOM-событий) — смок упал: `fontDraftWaitsForChange: expected true, got false`,
`FAILED (1)`. Восстановил файл из бэкапа, `git status --short` пуст.
6. `node scripts/smoke-select.mjs --base origin/dev --head HEAD` — «браузерные
смоки этим диффом не выбираются», диф не трогает `src/**` (как и в r1;
инструмент подтверждает то же самое на новом материале).
7. `node --test test/smoke-select.test.mjs` — 7/7, реестр `smoke-links.mjs`
структурно цел (символы/файлы существуют).
8. Сопутствующая регрессия дельты: прогнал `smoke_room_settings_form.mjs` и
`smoke_device_settings_form.mjs` на HEAD — оба `OK`. Дельта их не
касалась, но они входят в ту же запись реестра, что и правленый файл;
дешёвый прогон снял вопрос о побочном эффекте.
## Унаследовано из r1
Без повторной проверки в этом раунде — документ `docs/reviews/CODE-REVIEW-639-r1.md`,
SHA `0ac08434b5cd12848ce8b18aa17a6343b83b6653`:
- Причинно-следственная цепочка задачи (регресс #608 → красные ночные
гарды `smoke_room_settings_form`/`smoke_device_settings_form`) и её
устранение (`input`+`change` вместо только `input` на четырёх полях
`room-*-scale`, `marker-glow-brightness`, `marker-size`, `marker-angle`).
Дельта r2 эти файлы не трогает.
- Проверка, что соседние `unitInput`-поля без `rangeLine` (`#room-temp-min/max`,
`#marker-glow-radius`) не были задеты и не должны были быть.
- Структурная целостность `scripts/smoke-links.mjs` (символы/смоки
существуют) — механическая часть теста `smoke-select.test.mjs`, не
менялась.
- Классификация изменения (класс B, `User-Visible: no`, changelog не
требуется) — новый коммит несёт те же трейлеры (`Issue: #639`,
`User-Visible: no`), проверил их наличие в `a3397329`, но не пересматривал
саму классификацию.
- Полный перечень «чего не проверял и почему» (`tsc`/`npm test`/`npm build`
без пересборки — только на основании Validate; `check-docs`, `invariants`,
`golden:verify`, `pytest tests_backend`, перф-профили — диф вне их
условий). Дельта r2 не меняет ни одного из этих условий: всё ещё один
тестовый файл, не `src/**`, не геометрия, не Python, не рендер.
## Находки
Новых нет. Единственная находка r1 (M1) закрыта по существу — см. таблицу
выше. Дельта не вносит собственных дефектов: изменение состоит из тех же
DOM-событий (`input`+`change`), что уже использует эталонный код в этом же
файле для `#space-temp-max`, `#space-north-deg`, `.hpf-opacity input`, и тот
же коммит-контракт `rangeLine`, что уже подтверждён в r1 для room/device.
## Что проверено и корректно
- Новый DOM-путь `#space-card-font` соответствует продуктовому коммит-
контракту `rangeLine()`/`committedRangeLineValue` — подтверждено чтением
`form-kit.ts` и `space-form.ts`.
- Ассерты `fontDraftWaitsForChange`/`fontNumberCommitsThroughDom` включены
в `checkAll(out)` и реально влияют на код возврата смока (не отрисовка
без проверки).
- Тест умеет падать: воспроизвёл ровно на откате правленых строк.
- Соседние проверки того же смока (`resetDisabledAt100`, `resetRestores100`,
весь блок AC1/AC2/AC9/К1/К10, полосы экранов) не тронуты диффом и
остались зелёными при полном прогоне файла.
- Трейлеры коммита `a3397329`: `Issue: #639`, `User-Visible: no` — верно,
тестовая инфраструктура, изменений в user-facing changelog не требуется.
## Чего не проверял и почему
- `npx tsc --noEmit`, `npm test`, `npm run build` (сверка 3 копий бандла как
отдельный гейт) — не перегонял как отдельную проверку: Validate на `a3397329`
зелёный (https://github.com/Matysh/houseplan-card/actions/runs/35841321979,
указан в постановке задачи). `npm run bundle:sync` пересобрал тот же
бандл ради локальной копии для смока, но это не замена «сверки трёх
копий» как отдельного гейта, а побочный эффект пункта 3 выше.
- `node scripts/check-docs.mjs` — не запускал: дифф не трогает `src/**`
(файл в `demo/`), отпечаток скриншотов не устаревает.
- `npm run invariants` — не запускал: дифф не трогает геометрию/`layout`/
толщины/`marker.space`/`open_spans`.
- `npm run golden:verify` — не запускал: дифф — событийная семантика теста,
не код рендера; видимый результат карточки не меняется.
- `python -m pytest tests_backend` — не запускал: `custom_components/**/*.py`
не тронут.
- Остальные смоки `demo/smoke_*.mjs` вне записи `rangeLine`/`unitInput` —
не гонял: `smoke-select` их не выбирает, дифф темы не пересекает.
- Perf-профили — не запускал: не названы в задаче, дифф не задевает
чувствительные к перфу пути.
## Вывод
Дельта r2 — точечная правка ровно по единственной находке r1: смок
`smoke_space_settings_form.mjs` теперь действительно ведёт `#space-card-font`
через `input`+`change`, как заявляет запись `smoke-links.mjs`, и падает при
откате к прежнему прямому присваиванию. Причинно-следственная цепочка задачи
и фиксы room/device наследуются из r1 без повторной проверки — дельта их не
касается. Новых находок нет.
**Вердикт: зелёный.**
---
---
<!-- material-anchors: сгенерировано конвейером (#414) -->
## Материал раунда
- Ветка: `issue/639-range-line-smokes`, коммит `a3397329d534` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
- Дерево материала: `226a65401a6b48c9a19b8f450288905e5e7ec8e4`
```
git log --all --format='%H %T' | grep 226a65401a6b
```
- Тело issue: `7ad41f5686d99bfd44e274349b50adaec808bc8169c0e0ea2f31df52671bf0b3`
- Вердикт конвейера: `green` · High 0