docs: review document for #615
Проверка (CI) / Классификация изменённых файлов (push) Failing after 7m4s
Проверка (CI) / Предполёт: документация, провенанс, процесс (push) Failing after 9m4s
Проверка (CI) / Переиспользование: это дерево уже проверено (push) Skipped
Проверка (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) / Смоки в браузере (шард 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 7m29s

Issue: #615
User-Visible: no
This commit is contained in:
claude[bot]
2026-09-25 00:38:11 +00:00
parent 2bf929e34e
commit 524908b23b
2 changed files with 80 additions and 1 deletions
+78
View File
@@ -0,0 +1,78 @@
# CODE-REVIEW-615-r1
Issue: #615 · трек `small` · заход r1 · блокирующих циклов 0/2 (это первый заход, в котором код действительно читался — два предыдущих возврата в `S6` были доконвейерными: неудачный `workflow_sync` и конфликт ребейза на `tsconfig.test.json`, циклы ревью на них не тратились).
Материал: `git log --oneline origin/dev..HEAD` = один коммит `2bf929e3` (`fix(settings): colour tiles show alpha as a checkerboard (#615)`), `git diff origin/dev...HEAD`. Рабочая копия — на этом SHA (`git rev-parse HEAD` = `2bf929e34ed51a37b1fe0745e94863e8a2e37803`), все блобы из хендоффа (`src/hp-color-opacity.ts`, `src/editors/color-tile-ink.ts`, `src/editors/form-kit.ts`, `test/form-kit.test.mjs`, `demo/smoke_dialog_polish_605.mjs`, `scripts/mutation-registry.mjs`, `tsconfig.test.json`) сверены `git hash-object` и совпадают побайтово с якорями последнего хендоффа (2026-09-25T00:16:19Z).
## Скоуп
ТЗ (редакция r2, зелёное спек-ревью SPEC-REVIEW-615-r1/r2) закрывает регресс #605: плитки цвета General settings (10 штук: Lights/Temperature/Zigbee/Glow) снова показывают α шахматкой, плашки цвета остаются сплошными. Это правка визуального регресса редактора (администратор дома, десктоп, `docs/SCOPE.md` — обслуживает J4/J6, «плата за верность плана» и GUI-онбординг остаются читаемыми); View не затронут, персона «домочадцы/киоск» не видит изменения.
## Как проверялось
Дешёвые гейты (`typecheck`, `npm test`, `npm run build` со сверкой копий бандла, `check-docs`) подтверждены зелёным Validate на этом SHA (run 36076829827) — не перегонялись. Сам код прочитан построчно (диффы `src/hp-color-opacity.ts`, `src/editors/color-tile-ink.ts`, `src/editors/form-kit.ts`, `demo/smoke_dialog_polish_605.mjs`, `test/form-kit.test.mjs`, `scripts/mutation-registry.mjs`, changelogs, USER-GUIDE); проверены все места использования `flat-swatch`/`cover-swatch` (`general-settings-dialog.ts`, `space-form.ts`, `room-settings-dialog.ts`, `marker-dialog.ts`) — только один потребитель (плитки General) задаёт оба атрибута разом, все плашки задают только `flat-swatch`, так что `_solidSwatch = flatSwatch && !coverSwatch` не меняет поведение плашек и включает шахматку только у плиток.
Гейты, прогнанные лично в этом заходе (сверх подтверждённого Validate):
| Гейт | Результат |
|---|---|
| `node scripts/smoke-select.mjs --base origin/dev --head HEAD` | 5 «прямых совпадений»: `smoke_dialog_polish_605`, `smoke_bg_color`, `smoke_color_picker_consumers`, `smoke_color_picker`, `smoke_ha_controls` — совпадает с выбором автора |
| `npm run build` + `node scripts/bundle-sync.mjs` | ok, бандл пересобран для смоков |
| `node demo/smoke_dialog_polish_605.mjs` | OK, включая новые проверки `tileAlpha`, `defaultsDiffer`, `noneInkDark`, `liveAlpha`, `platesFlat`, `plateSolid` (12 комбинаций тема×ширина) |
| `node demo/smoke_bg_color.mjs`, `smoke_color_picker_consumers.mjs`, `smoke_color_picker.mjs`, `smoke_ha_controls.mjs` | OK (регресс, названы в AC3(в)) |
| `node demo/smoke_general_settings_form.mjs`, `smoke_dialog_config_parity.mjs` | OK (доп. регресс из плана автотестов) |
| `node scripts/mutation-gate.mjs --id=M-615-tile` | «поймано 1 из 1» — лично прогнан, не только со слов автора |
| `node scripts/mutation-gate.mjs --id=M-615-plate` | «поймано 1 из 1» — лично прогнан |
| `node scripts/mutation-gate.mjs --id=M-615-label` | «поймано 1 из 1» — лично прогнан |
| `node scripts/bundle-budget.mjs` | initial View 289870 B (потолок 290400±2000, запас 11196 Б) — совпадает с числом автора, предупреждение о запасе — унаследованный долг, не от этой задачи |
| `node scripts/check-docs.mjs --screenshots=warn` | passed, 1 WARN об устаревшем отпечатке скриншотов (ожидаемо на push, не на кандидате беты, §8/AGENTS.md) |
Не прогонялось (совпадает с «чего не проверял» автора, обоснованно):
- `golden:verify`/`docs:capture` — только Linux CI/WSL (#455); AC4 сам это фиксирует как предрелизный гейт, ожидаемый список кадров (`general-color-popover-desktop-en` + возможные `settings-help-zoom-*`) назван явно.
- Полная матрица смоков (266 шт.) — выборка `smoke-select.mjs` даёт только «прямые совпадения», широких/неопределённых связей нет, расширять нет оснований.
- HA backend, Windows-гейт, perf-профили — диф не трогает Python/geometry/perf-контракты, в AC не названы.
- Инварианты модели (`npm run invariants`) — геометрия/конфиг не меняются (только CSS и цвет подписи), точка данных `{c,a}` не тронута.
## AC — доказательства
| AC | Проверено | Вывод |
|---|---|---|
| AC1 (шахматка/цвет по α, живой ввод 0/100) | Прочитано (`_solidSwatch`, рендер `hp-color-opacity.ts:850-867`) + лично прогнан смок `tileAlpha`/`defaultsDiffer`/`liveAlpha` | Доказано исполнением, тест умеет падать — подтверждено мутантом M-615-tile лично |
| AC2 (подпись по видимому цвету) | Юнит `test/form-kit.test.mjs` (`#615`) прочитан, формула `colorTileInk` сверена вручную (0.299/0.587/0.114, порог 0.6, `CHECKER_MEAN=211=(184+238)/2`) | Доказано юнитом, мутант M-615-label лично краснеет |
| AC3(а) (одна поверхность, hex, клавиатура) | Прежние `oneSurface`/`opensPicker`/`upperHex`/`tileWholeSurfaceOpens`/`tileKeyboardOpens` — зелёные в моём прогоне | Разобрано чтением + исполнением (не менялось по существу, кроме снятия условия `opacity==='1'`, что и есть предмет задачи) |
| AC3(б) — защитный AC (плашки остаются сплошными) | Новые `platesFlat`/`plateSolid` прочитаны и прогнаны лично; таблица «чем краснеет» в ТЗ и хендоффе называет мутант M-615-plate — прогнан лично, «поймано 1 из 1» | Защитный AC полностью доказан: тест + названная мутация + результат прогона, столбец не пуст |
| AC4 (golden) | Кадр `general-color-popover-desktop-en` существует в `demo/golden/matrix.mjs`/`baselines-index.json` — сверено чтением. Съёмка отложена на предрелизный гейт, как и предписывает ТЗ | Проверено чтением, не исполнением — исполнение вне скоупа этого гейта (только Linux CI) |
Трейлеры коммита: `Issue: #615`, `User-Visible: yes`; `docs/CHANGELOG.md` и `docs/CHANGELOG.ru.md` правлены в том же коммите — сверено `git show --stat` и текстом записи.
## Находки
**L1 (Low).** «Одно число — один источник» (§8): `CHECKER_MEAN = 211` в `src/editors/color-tile-ink.ts:22` — вручную посчитанное среднее шахматки `hp-color-opacity` (`#b8b8b8`/`#eee`, CSS в `src/hp-color-opacity.ts:113-116`). Это два независимых литерала без общей константы и без теста, который бы их связывал (`grep` по `b8b8b8`/`CHECKER_MEAN` не находит перекрёстной проверки). Если шахматку в CSS перекрасят, `colorTileInk` продолжит смешивать с прежним 211 и подпись на средних α станет слегка менее контрастной, чем видимый цвет — не крах и не потеря функциональности, только постепенно расходящаяся аппроксимация контраста. Снимаю без правки: риск узкий (шахматка — общий паттерн продукта, встроен во множестве мест, менять только эти два хардкода без ревью остальных потребителей `hp-color-opacity` маловероятно), связь задокументирована комментарием в коде, а сам приём (смешивание со средним тоном для эвристики контраста) уже сознательно принят как приближение в разделе ТЗ «Риски». Если владелец сочтёт нужным — можно вынести числа в общий модуль, отдельного issue не требуется.
Других находок нет. High: 0, Medium: 0.
## Что проверено и корректно
- Изоляция режима `cover-swatch` от остальных потребителей `hp-color-opacity` подтверждена чтением всех вызовов (`general-settings-dialog.ts`, `space-form.ts`, `room-settings-dialog.ts`, `marker-dialog.ts`) — только плитки задают `cover-swatch`, плашки — нет.
- Значения по умолчанию `light_none.a=0`, `light_on.a=0.18` (`src/logic.ts:1436,1438`) совпадают с тем, что проверяет `defaultsDiffer`.
- `dist/houseplan-card.js` и `custom_components/houseplan/frontend/houseplan-card.js` побайтово совпадают (`cmp`) после локальной пересборки — комплект бандла синхронен.
- Ни новых i18n-ключей, ни изменений модели данных/`{c,a}`/миграции — сверено чтением диффа (нет правок в `src/i18n*`, конфиг не тронут).
- Мутанты `M-615-tile`/`M-615-plate`/`M-615-label` не только заявлены, но и лично прогнаны через `mutation-gate.mjs --id=…`, каждый даёт «поймано 1 из 1» — дисциплина «тест умеет падать» выполнена по прогнанным тестам.
## Вердикт
Зелёный. AC1–AC4 доказаны (AC4 — в объёме, доступном на этом гейте), защитный AC3(б) закрыт тестом с названной мутацией и результатом прогона, регрессий по смокам нет, трейлеры и changelog на месте. Единственная находка (L1) — Low, снята без правки с запиской выше.
---
<!-- material-anchors: сгенерировано конвейером (#414) -->
## Материал раунда
- Ветка: `issue/615-swatch-checkerboard`, коммит `2bf929e34ed5` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
- Дерево материала: `0810efbc7b22e071c9911b6fa529ab677d3b65f0`
```
git log --all --format='%H %T' | grep 0810efbc7b22
```
- Тело issue: `c97b73a26ff6fd7f6f98066a8188d815fbfac1ad9db4ed0085317efe13f01a30`
- Вердикт конвейера: `green` · High 0
+2 -1
View File
@@ -1,6 +1,6 @@
# Индекс ревью
Генерируется `node scripts/reviews-index.mjs` (#635) — не редактировать руками. Документов: 1037, issue: 365. Вердикт: 🟢 зелёный · 🟡 жёлтый · 🔴 красный · ⚪ не распознан (свободная форма старых документов). H/M — число High/Medium по строке вердикта или заголовкам находок. Файлы — пути, названные в находках; ищите по имени файла: `grep form-kit INDEX.md`.
Генерируется `node scripts/reviews-index.mjs` (#635) — не редактировать руками. Документов: 1038, issue: 365. Вердикт: 🟢 зелёный · 🟡 жёлтый · 🔴 красный · ⚪ не распознан (свободная форма старых документов). H/M — число High/Medium по строке вердикта или заголовкам находок. Файлы — пути, названные в находках; ищите по имени файла: `grep form-kit INDEX.md`.
| Issue | Документ | Этап · раунд | Вердикт | H | M | Находки | Файлы |
|---|---|---|---|---:|---:|---|---|
@@ -54,6 +54,7 @@
| #617 | [CODE-REVIEW-617-r2.md](CODE-REVIEW-617-r2.md) | code · r2 | 🟢 зелёный | 0 | 0 | — | — |
| #615 | [SPEC-REVIEW-615-r1.md](SPEC-REVIEW-615-r1.md) | spec · r1 | 🟡 жёлтый | 0 | 1 | AC3 называет несуществующую защиту от расползания на плашки цвета | `smoke_room_settings_form.mjs` `smoke_space_settings_form.mjs` `smoke_device_settings_form.mjs` `smoke_dialog_polish_605.mjs` `smoke_general_settings_form.mjs` |
| #615 | [SPEC-REVIEW-615-r2.md](SPEC-REVIEW-615-r2.md) | spec · r2 | 🟢 зелёный | 0 | 0 | — | — |
| #615 | [CODE-REVIEW-615-r1.md](CODE-REVIEW-615-r1.md) | code · r1 | 🟢 зелёный | 0 | 0 | — | — |
| #614 | [SPEC-REVIEW-614-r1.md](SPEC-REVIEW-614-r1.md) | spec · r1 | 🟢 зелёный | 0 | 0 | — | — |
| #614 | [CODE-REVIEW-614-r1.md](CODE-REVIEW-614-r1.md) | code · r1 | 🟡 жёлтый | 0 | 1 | AC1/AC2/AC3 требуют unit-тест, а он не написан | `test/dialog-baseline.test.mjs` `test/space-dialog.test.mjs` `general-form-state.ts` `space-form-state.ts` `marker-form-state.ts` `tsconfig.test.json` `dialog-baseline.ts` `scripts/mutation-registry.mjs` |
| #614 | [CODE-REVIEW-614-r2.md](CODE-REVIEW-614-r2.md) | code · r2 | 🟢 зелёный | 0 | 0 | — | — |