docs: review document for #560
Проверка (CI) / Классификация изменённых файлов (push) Successful in 39s
Проверка (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) Failing after 2m28s
Проверка (CI) / HACS: валидация репозитория (push) Failing after 4m0s
Проверка (CI) / Hassfest: манифест интеграции (push) Failing after 26s
Проверка (CI) / Переиспользование: это дерево уже проверено (push) Successful in 5m1s
Проверка (CI) / Фронтенд: типы, юниты, мутанты, синхрон бандла (push) Failing after 1m44s
Проверка (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) Successful in 6m29s
Проверка (CI) / Бэкенд: pytest в Home Assistant (push) Failing after 10m20s
Проверка (CI) / Доказательство выполненных проверок (push) Failing after 15s

Issue: #560
User-Visible: no
This commit is contained in:
claude[bot]
2026-09-13 18:25:53 +00:00
parent db7eef5306
commit 6706182a27
+154
View File
@@ -0,0 +1,154 @@
# CODE-REVIEW-560-r1
Issue: #560 «Корпус геометрий, household-сценарии и аудит доступности View»
Материал: `db7eef530635b699a72c3cf978a7df79db99fcbd`, ветка `issue/560-quality-field-corpus`
на `dev` (`a03ccd65`), один коммит.
Заход: r1 · блокирующих циклов ревью 0 из 4 (лимит для инфраструктурного/полного трека — 4)
## Скоуп
Задача — прямое поручение владельца по оставшемуся пункту независимого аудита
(12.09.2026): усилить доказательства View household-сценариями и корпусом
пользовательских геометрий. Инфраструктурная постановка (`infra`, без
продуктовых `S*`-статусов до `S7-code-review`), явно **research/tests-only**:
диффу запрещено трогать `src/**` и `custom_components/**`, а находки —
заводиться отдельными issue, а не чиниться здесь.
`git diff origin/dev...HEAD --stat` подтверждает границу: только
`demo/**`, `test/**`, `scripts/mutation-registry.mjs`, `docs/QUALITY-560.md` —
класс B/C, ни одного файла класса A. Трейлеры коммита: `Issue: #560`,
`User-Visible: no` — корректны, продуктового поведения нет.
Три направления приёмки (SCOPE J1/J2/J3/J6):
1. household-сценарии View на двух ширинах карточки;
2. аудит доступности текущего View;
3. обезличенный geometry corpus (import → Optimize → Optimize → Resize →
save/reload → export) с численными оракулами.
## Как проверялось
Ревью независимое: сессия без контекста реализации, материал не редактировался.
Дешёвые гейты (`tsc`, `npm test`, `npm run build`) уже подтверждены зелёным
прогоном Validate на этом самом SHA — перепрогонять не стал, а сверил сам факт:
| гейт | результат |
|---|---|
| Validate (CI) на `db7eef53` | `gh run view 34773796018` → `conclusion: success`, `headSha: db7eef53...` — совпадает |
Что прогнал сам (соразмерно диффу и AC, не входит в «дешёвый» набор, зафиксированный Validate):
| гейт | команда | результат |
|---|---|---|
| build (нужен как база для смоков) | `npm run build && npm run bundle:sync` | зелёный, дерево бандла не изменилось (`git status` чист после) |
| unit-тесты | `npm test` | `2679` тестов, `2678` pass, `0` fail, `1` skip — совпадает с заявленным «2678 / 0 / 1 skip (+35)» |
| новый браузерный смок 1 | `node demo/smoke_household_journeys.mjs` | `OK`, все числа (J4 15 остановок Tab, F1 390px владельцы `dense2,dense3,dense4,dense5,dense5`, J7 780px владельцы `dense1..dense5`) совпадают с `docs/QUALITY-560.md` |
| новый браузерный смок 2 | `node demo/smoke_geometry_corpus.mjs` | `OK`, числа (3 комнаты, толщины `20,20,20,20,20,20,20,22,33,33` до/после ресайза, 2 комнаты+1 проём для c4) совпадают с отчётом |
| mutation-gate — 4 новых мутанта, по одному | `node scripts/mutation-gate.mjs --id=<id>` × 4 | все 4: «поймано 1 из 1» (см. таблицу ниже) |
| mutation-gate anchors | `node scripts/mutation-gate.mjs --check` | без нарушений |
| process-gate | `node scripts/process-gate.mjs --issues` | «гейт пройден», 1 WARN (см. находку Low ниже) |
| check-docs | `node scripts/check-docs.mjs` | passed (диффу не требовался — `src/**` не тронут) |
| smoke-select | `node scripts/smoke-select.mjs --base origin/dev --head HEAD` | «исполняемого frontend-диффа нет, browser-smoke этим диффом не выбираются» — ожидаемо для инфра-трека без `src/**` |
| model-invariants CLI (сверка численных оракулов вручную) | `node scripts/model-invariants.mjs --config ... --layout ...` на `c6-stale-layout` | «Нарушений: 2» — `references/layout_space` × 2, совпадает с `expectedViolations` теста и находкой #566 |
| приватность фикстур | `grep` по `test/fixtures/560-corpus/*.json` на `sensor.\|light.\|binary_sensor.\|climate.\|lock.` | ничего не найдено; маркеры в геометрических фикстурах — пустые массивы |
Не прогонял и почему:
- `golden:verify`, `performance_smoke`, `python -m pytest tests_backend` — diff не
трогает `src/**` (рендер и стили не менялись) и не трогает `custom_components/**/*.py`;
ни один AC не требует визуального или бэкенд-гейта.
- Полный набор `demo/smoke_*.mjs` — `smoke-select` прямо сообщил, что выбирать
нечего (frontend не менялся); два новых смока прогнаны напрямую целиком.
## Находки
### Low — `process-gate` даёт 1 предупреждение, а хендофф заявляет «предупреждений 0»
`node scripts/process-gate.mjs --issues` на этом дереве печатает:
```
WARN п.8 статус issue - инфраструктурный диапазон (#562): файлов класса A нет,
статусная метка не требуется до S7-code-review
гейт пройден, предупреждений 1
```
Это ожидаемое, безопасное предупреждение — оно печатается всегда для
инфраструктурного диапазона по дизайну (`scripts/process-gate.mjs:806-813`,
комментарий «пропуск обязан быть виден»), гейт всё равно зелёный. Расхождение
чисто в тексте хендоффа («предупреждений 0» вместо факта «1»), не в существе
проверки. Не блокирует; правится или снимается автором с примечанием.
Третий столбец («чем краснеет») для этой находки не нужен — она не о защите, а
о точности отчётной цифры.
## Что проверено и корректно
- **Границы задачи соблюдены.** Ни одного файла класса A в диффе; все три
находки уровня High/Medium (F1 «390px — соседний маркер», F2 «контраст
подписей 2,01:1», F3 «активная вкладка без ARIA-состояния») и Low (F4, F5,
F6) заведены отдельными issue со ссылкой на #560 — проверил напрямую:
`#564` (High, bug, P1, S1-new), `#565` (Medium+Low, bug, P2, S1-new), `#566`
(Low, tech-debt, P3, S1-new) существуют, открыты, корректно размечены.
Ничего не оставлено как TODO внутри документа ревью/отчёта.
- **Приватность данных.** Реальный план владельца (5 пространств/37 комнат/121
запись толщины и т.д.) в репозиторий не попал — фикстуры `test/fixtures/560-corpus/*.json`
синтетические, воспроизводят условия числами; маркеры пустые, ссылок на
реальные HA-сущности нет (проверено grep).
- **Каждый AC приёмки закрыт и доказан исполнением, не чтением:**
- «персона/вход/действие/независимый oracle» — семь J-путей в
`demo/smoke_household_journeys.mjs` прогнаны, оракулы независимые
(вызов `light.turn_off`, `aria-label`, `data-state`, а не факт наличия
класса) — подтверждено запуском, числа совпали.
- «geometry corpus не принимает рендер как эталон» — оракулы в
`test/geometry-corpus.test.mjs` численные (инварианты, immutability
Optimize, фикс-пойнт #477, сохранность записей толщины, независимый
пересчёт `wallKey`); браузерная половина проверяет только присутствие
узлов и попадание в `viewBox`, не пиксели — прочитано и прогнано.
- **Тест умеет падать.** Для двух product-facing защит (клавиатурная
доступность маркера, вызов действия по Enter/Space) и двух свойств самого
корпуса (фикстура несёт условие, `changed` не врёт) прогнаны названные
мутанты — все 4 «поймано 1 из 1» (перепроверено мной лично, не с чужих слов).
- «bounded corpus, без бесконтрольного роста» — 6 фикстур × (свой тест
условия + 3 теста цепочки) + 2 сквозных теста = 26, как заявлено; синтетика
(`c3-x-junction`) прямо помечена как таковая и в тесте, и в отчёте.
- «итог отделяет bugs от гипотез» — раздел 6 `docs/QUALITY-560.md` называет
U1–U3 гипотезами именно потому, что без людей (screen reader,
color-blindness sim, доброволец) не проверяются; это не притворство
решением, а честно обозначенная граница.
- **Числа отчёта воспроизводимы**, а не переписаны на веру: гоняя оба новых
смока и `npm test` заново, получил те же цифры, что в `docs/QUALITY-560.md`
(включая тонкие — 1,6 px запас на 780px, 15 остановок Tab, `rev`-независимые
толщины). Ни одного «verified» без названной команды в материале нет.
- **Единый источник числа.** Диф не вводит ни одной новой пользовательской
величины (не продуктовый код); дублирования вида «превью против записи»
не создаётся.
## Чего не проверял и почему (сверх раздела «как проверялось»)
- Не проверял вручную полевую установку владельца — по постановке задачи это
read-only полевая часть текущего захода, она не воспроизводима вне сессии
автора и с чужой машины не перепроверяется; профиль (числа) сверен на
внутреннюю согласованность с корпусом, а не с самим домом.
- Не гонял скринридер/цветовую симуляцию — U1–U3 прямо помечены как гипотезы,
не как заявленные доказанные AC; требовать здесь исполнимый oracle было бы
спором с самой постановкой задачи (research/tests-only, без людей в этом заходе).
## Вердикт
Единственная находка — Low, редакционная неточность в тексте хендоффа
(«0» вместо фактических «1» предупреждения `process-gate`, само предупреждение
ожидаемо и не является нарушением). High/Medium в материале нет. Задача решает
заявленный сценарий (усиление evidence по трём направлениям аудита) без
деградации соседнего поведения — продуктовый код не тронут вовсе.
**Зелёный.**
---
<!-- material-anchors: сгенерировано конвейером (#414) -->
## Материал раунда
- Ветка: `issue/560-quality-field-corpus`, коммит `db7eef530635` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
- Дерево материала: `eea41e91476fced5276e10601e5d29ad1bd6642b`
```
git log --all --format='%H %T' | grep eea41e91476f
```
- Тело issue: `0ab01902457f91e2bbe866f790b19fb58567ef790403214e6886dc7df209ac70`
- Вердикт конвейера: `green` · High 0