Files
houseplan-card/docs/reviews/CODE-REVIEW-437-r4.md
T
claude[bot] 586494b726
Проверка (CI) / Предполётные проверки: документация, провенанс, процесс (push) Failing after 50s
Проверка (CI) / Классификация изменённых файлов (push) Successful in 29s
Проверка (CI) / HACS: валидация репозитория (push) Skipped
Проверка (CI) / Hassfest: манифест интеграции (push) Skipped
Проверка (CI) / Мутанты по диффу (1/3): затронутые свидетели краснеют (push) Skipped
Проверка (CI) / Мутанты по диффу (2/3): затронутые свидетели краснеют (push) Skipped
Проверка (CI) / Мутанты по диффу (3/3): затронутые свидетели краснеют (push) Skipped
Проверка (CI) / Фронтенд: типы, юниты, мутанты, синхрон бандла (push) Skipped
Проверка (CI) / Переиспользование: это дерево уже проверено (push) Successful in 55s
Проверка (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) / Бэкенд: pytest в Home Assistant (push) Skipped
docs: review document for #437
Issue: #437
User-Visible: no
2026-09-08 17:44:24 +00:00

94 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-437-r4
Issue: [#437](https://github.com/Matysh/houseplan-card/issues/437) — конфигурируемая read-only сводная панель поверх плана.
Этап: код-ревью, заход **r4**, блокирующих циклов израсходовано **2/4** до этого раунда (полный трек, лимит 4).
## Материал раунда и объявление дельты (PROCESS §2.9/§2.10)
- Вердикт r3: **зелёный**, High 0 / Medium 0 (только 2 Low, сняты с записью), документ `docs/reviews/CODE-REVIEW-437-r3.md`, материал `HEAD = f87d3dc5457834cddc3b447cb1390d2f5921c24d`.
- Зелёный вердикт цикл не образует и бюджет §4 не тратит (решение владельца 2026-08-20, #227) — поэтому «блокирующих циклов 2/4» перед этим раундом совпадает со значением, названным в самом r3.
- Слияние r3 отменено серверным стопором (issue-комментарий `2026-09-08T17:37:30Z`, шаблон PROCESS §2.7/#312): «вершина ветки изменилась после проверенного материала». Задача вернулась в `S6-in-progress`, затем снова в `S7-code-review` — отсюда r4, без изменения бюджета циклов.
- **Дельта r3→r4 объявляется явно**: `git diff f87d3dc5..HEAD` — единственный файл, `docs/reviews/CODE-REVIEW-437-r3.md` (106 строк, добавление), коммит `63ceef66` — собственный doc-коммит публикации итога r3 (`Issue: #437 · User-Visible: no`). Продуктового, тестового, backend- или scripts-кода дельта не содержит: `git diff --stat f87d3dc5..HEAD -- 'src/**' 'custom_components/**/*.py' 'demo/**' 'test/**' 'tests_backend/**' 'scripts/**'` — пусто.
- Родитель от `dev` не сместился: `git merge-base HEAD origin/dev` = `git merge-base f87d3dc5 origin/dev` = `ed9ee026dc08054e12038b7dbd1b8525e7706d04` — ребейза не было, `dev` не ушёл вперёд.
- **Разбор полным не признан необходимым**: дельта — ровно тот «допустимый doc-коммит публикации поверх» материала, который PROCESS §2.7 прямо разрешает не считать расхождением; она не трогает ни один файл источника, теста, бэкенда или инструментов, не меняет контракт AC1–AC26, не задевает новую подсистему, объём (1 файл, только markdown) на порядки меньше исходной задачи (93 файла в общем диффе с `dev`). Это самый узкий возможный случай «зелёное ревью, слияние которого не удалось» — сам код с момента r3 не менялся ни на строку.
## Закрытие раунда r3
Новых находок в r3 не было (High 0, Medium 0); блокирующих пунктов для закрытия в r4 нет. Единственное, что «закрывается» этим раундом, — не находка, а причина возврата: слияние отменено не из-за дефекта в коде, а из-за расхождения вершины ветки с зафиксированным материалом ревью. Дельта выше показывает, что расхождение исчерпывается собственным doc-коммитом публикации r3, который PROCESS §2.7 разрешает не считать таким расхождением.
| Причина возврата в r3→r4 | Чем закрыта | Где это видно |
|---|---|---|
| «Вершина ветки изменилась после проверенного материала» (комментарий `2026-09-08T17:37:30Z`) | Проверено, что единственное изменение вершины — doc-коммит публикации самого r3 | `git diff --stat f87d3dc5..HEAD` = 1 файл (`docs/reviews/CODE-REVIEW-437-r3.md`), `git diff --stat f87d3dc5..HEAD -- 'src/**' 'custom_components/**/*.py' 'demo/**' 'test/**' 'tests_backend/**' 'scripts/**'` = пусто |
## Унаследовано из r1/r2/r3 (без повторной проверки)
Дельта `f87d3dc5..HEAD` не касается ни одного файла источника, поэтому все выводы предыдущих раундов наследуются без повторной проверки:
- **M1–M5 (r1–r3, все закрыты)** — детали и точное закрытие описаны в `docs/reviews/CODE-REVIEW-437-r1.md` (материал `96e07b9a`), `-r2.md` (материал `89976c85`), `-r3.md` (материал `f87d3dc5`); ни один из доказывающих файлов (`src/summary-panel-style.ts`, `src/summary-panel-identity.ts`, `src/houseplan-card.ts`, `src/boot-soft-layout.ts`, `test/summary-panel.test.mjs`, `demo/smoke_kiosk.mjs`, `demo/smoke_zoom_out.mjs`) не тронут дельтой r3→r4;
- **AC1–AC26** — доказательства лежат в файлах источника и backend, ни один не тронут в r4 (см. предыдущий пункт плюс `custom_components/houseplan/**/*.py`, i18n-словари, `src/summary-panel-editor.ts`, `summary-panel-host.ts`);
- `pytest tests_backend/test_summary_panel.py` — 396 passed / 3 skipped на `96e07b9a` (r1); backend не тронут ни в одном раунде r2–r4;
- Low L4 (non-null assertion в `measuredCardHeaderHeight(...)!`) и L5 (changelog не упоминает восстановление камеры отдельной строкой) — обе сняты решением ревьюера в r3 с записью, файлы, к которым они относятся, не тронуты;
- L3 (`summary-panel-identity.ts`, архитектурное сомнение по Masonry-индексу) — остаточное наблюдение, файл не тронут;
- Три копии бандла и их байтовое совпадение, границы SCOPE, версионирование backend — не тронуты.
## Как проверялось — гейты
Зелёного Validate на `63ceef66` не найдено (`gh api repos/Matysh/houseplan-card/commits/63ceef66/check-runs` — пусто, `.../status` → `pending`) — прогнал дешёвые гейты сам, на актуальном `HEAD`.
| Гейт | Команда | Результат |
|---|---|---|
| Типы | `npx tsc --noEmit` | pass, 0 ошибок |
| Юниты (полный набор) | `npm test` | 2269 tests, 2268 passed, 0 failed, 1 skipped (32.7s) — те же числа, что на `f87d3dc5` в r3 |
| Сборка + бандл (3 копии) | `npm run build && npm run bundle:sync` | pass; `sha256sum` — `dist/houseplan-card.js`, `custom_components/houseplan/frontend/houseplan-card.js`, `demo/srv/assets/houseplan-card.js` все `c03169ee55…` — тот же хеш, что зафиксирован в r3 (подтверждает, что бандл-код не менялся); `git status --porcelain` после сборки пуст |
| Процесс-гейт | `node scripts/process-gate.mjs` | «гейт пройден, предупреждений 0» (13 коммитов в диапазоне `origin/dev..HEAD`, на один больше, чем в r3 — сам doc-коммит `63ceef66`) |
| Выбор смоков/гейтов по дельте r3→r4 | `node scripts/smoke-select.mjs --base f87d3dc5 --head HEAD` | «Исполняемого frontend-диффа нет (src/**/*.ts не тронут)… тронуто файлов: 1» — инструмент подтверждает, что выбирать нечего |
Остальные гейты (`no-new-any`, `check-docs`, `bundle-budget`, `single-source-numbers`, целевые смоки, backend pytest, golden/invariants/perf) **не перезапускались** — дельта не трогает ни одного файла, от которого зависит их результат; их выводы наследуются из r3 без изменений (см. раздел выше и «Чего не проверял»).
## Находки
Новых находок нет. High: 0, Medium: 0, Low: 0 (новых; ранее снятые L3–L5 остаются как в r3, не переоткрывались).
## Что проверено и корректно
- Дельта r3→r4 действительно ограничена собственным doc-коммитом публикации r3 (`63ceef66`) — подтверждено `git diff --stat` по всем классам путей (источник, тесты, backend, demo, scripts) отдельно.
- Код на `HEAD` побайтово идентичен коду на материале r3 (`f87d3dc5`): совпадение SHA-256 собранного бандла `c03169ee55…` с зафиксированным в `CODE-REVIEW-437-r3.md`.
- `npm test` даёт те же числа (2268 passed / 0 failed / 1 skipped), что и в r3 — регрессии от самого факта нового раунда не возникло.
- `merge-base` с `origin/dev` не сместился — правило «разбор полным, если ребейз на ушедший вперёд dev» не применяется, `dev` не двигался.
- Причина возврата (расхождение вершины ветки с материалом ревью) закрыта: расхождение исчерпывается допустимым doc-коммитом публикации, который PROCESS §2.7 прямо не считает нарушением.
## Чего не проверял
- `python -m pytest tests_backend -q` — не прогонялся в этом раунде; дельта не трогает `custom_components/**/*.py` вообще, полный прогон наследуется из r1 (396 passed, 3 skipped на `96e07b9a`), backend не менялся ни в одном последующем раунде.
- `node scripts/no-new-any.mjs`, `node scripts/check-docs.mjs`, `node scripts/bundle-budget.mjs`, `node --test test/single-source-numbers.test.mjs` — не перезапускались; дельта r3→r4 не добавляет строк кода и не трогает `src/**`, поэтому результаты этих гейтов не могут измениться относительно зафиксированных в r3 (check-docs там был ожидаемо красным — предрелизный гейт, некритично на обычном push).
- Целевые/прямые смоки (`smoke_zoom_out`, `smoke_summary_panel`, `smoke_kiosk`, `smoke_german_locale`, `smoke_room_link` и остальные 19 прямых совпадений из r3) — не перезапускались; `smoke-select --base f87d3dc5 --head HEAD` сам подтвердил, что исполняемого frontend-диффа нет и выбирать нечего.
- `npm run golden:verify`, `node scripts/model-invariants.mjs`, performance-профили — не по чему прогонять: дельта не меняет геометрию, `layout`, `marker.space`, рендер или чувствительные к перфу пути.
## Вердикт
Зелёный. Дельта раунда — единственный doc-коммит публикации предыдущего зелёного вердикта; продуктовый код с материала r3 (`f87d3dc5`) не изменился ни на строку (подтверждено байтовым совпадением собранного бандла). Причина отмены слияния r3 закрыта: расхождение вершины ветки исчерпывается допустимым по PROCESS §2.7 doc-коммитом. Новых находок нет. Задача готова к `S8-merged`.
---
## Материал раунда
- Ветка: `issue/437-summary-panel`, коммит `63ceef6618ba39aeb206781db290b728d53dd887`.
- Дерево материала: см. `git rev-parse HEAD^{tree}` на момент публикации.
- Родитель от `dev`: `ed9ee026dc08054e12038b7dbd1b8525e7706d04` (`git merge-base HEAD origin/dev`), не сместился относительно r3.
---
<!-- material-anchors: сгенерировано конвейером (#414) -->
## Материал раунда
- Ветка: `issue/437-summary-panel`, коммит `63ceef6618ba` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
- Дерево материала: `0cfa507586e643c0cd13d289f017c6939cceb607`
```
git log --all --format='%H %T' | grep 0cfa507586e6
```
- ТЗ `docs/specs/437-summary-panel.md`, блоб `58a2db80c2161079bc9044c107063e54bfcf0be6`
```
git log --all --find-object=58a2db80c2161079bc9044c107063e54bfcf0be6 -- docs/specs/437-summary-panel.md
```