Files
houseplan-card/docs/reviews/CODE-REVIEW-560-r1.md
T
claude[bot] 6706182a27
Проверка (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
docs: review document for #560
Issue: #560
User-Visible: no
2026-09-13 18:25:53 +00:00

155 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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