# SPEC-REVIEW-437-r2 Issue: [#437](https://github.com/Matysh/houseplan-card/issues/437) — конфигурируемая сводная панель поверх плана. Ветка: `issue/437-summary-panel`. Заход: **r2**, блокирующих циклов израсходовано 1/4. Материал раунда: `git diff 4a1aac16..14597ccd` (r1 SHA → текущий HEAD). Трек: полный (без изменений с r1). ## Скоуп проверки r2 r1 закончился жёлтым вердиктом с одной находкой Medium (M1, в скоупе) и двумя Low (L1, L2). Это не первый цикл, поэтому объём разбора — по дельте (PROCESS.md §2.9), а не заново. ``` docs/reviews/SPEC-REVIEW-437-r1.md | 246 +++++++++++++++++++++++++++++++++++++ docs/specs/437-summary-panel.md | 125 ++++++++++--------- ``` Второй файл в diff — публикация r1-документа шагом конвейера (не автор, содержимое совпадает с найденным на GitHub комментарием, не редактировалось). Единственный файл, изменённый автором по существу, — `docs/specs/437-summary-panel.md`. Дельта локальна и не требует полного разбора: правки не меняют ни одного AC, ни модель хранения, ни контракты поведения — только (а) добавление раздела French в §10 (i18n) с производными правками AC11, матрицы макетов и §12, и (б) явное определение `viewAllowed` в §5.3, плюс (в) точечные пробельные правки чисел по всему документу (не меняющие арифметику). Продуктовый код не тронут ни в r1, ни в r2. ## Как проверялось 1. Прочитано тело issue #437 (текущая версия) и все 8 комментариев целиком, включая раунды r1/r2 и команду владельца «S5-ready, затем остановка, реализацию не начинать». 2. Получен полный текст `git diff 4a1aac16..14597ccd -- docs/specs/437-summary-panel.md` и построчно сверен с таблицей находок r1 (раздел «Закрытие раунда r1» ниже). 3. Прочитан весь изменённый раздел §10 «i18n и визуальное соответствие» после правки, а также затронутые AC11/§12 численные fixtures — целиком, не по диффу, поскольку это содержательная правка, а не только пробелы. 4. Проверено определение `viewAllowed` (новая строка §5.3) на согласованность с §4.1 (единственное место, где до этого описывался View/kiosk/редакторы) — термины совпадают дословно. 5. Факт-чек M1 переисполнен независимо от r1, а не принят на слово: - `src/i18n/registry.ts` — French зарегистрирован как полноценная locale с ленивой загрузкой (`loadFrench`), тем же паттерном, что немецкая. - Подсчитаны ключи всех четырёх словарей: `en.json`, `ru.json`, `de.json`, `fr.json` — по 1257 ключей в каждом (python3 `json.load` + `len`). - `CONTRIBUTING.md:14–28` подтверждает автоматический parity-тест реестра локалей; `test/i18n.test.mjs` присутствует в дереве. 6. Проверена структурная целостность документа после правок: `## `-разделов — 14 (без изменений), строк `| AC` — ровно по одной на каждый номер AC1…AC26 без пропусков и дублей (`grep -oP '^\| AC\d+'` + сортировка), `wc -l` = 725. 7. Проверено, что вне изменённых разделов дельта не задела семантику: полный `git diff` построчно проверен на предмет отсутствия смысловых правок — единственные изменения не в §10/§5.3 — вставка пробела перед/после числа (`336`→`336 `, `72`→` 72`, `1`→`версия 1` и т.п.); отдельный `grep -noP` по всему файлу на оставшиеся «слово+число без пробела» не нашёл ни одного пропущенного случая вне легитимных идентификаторов (`AC1`, `P2`, `i18n`, `p95`, номера коммитов/hash). 8. `docs/SCOPE.md` и `docs/specs/README.md` — не тронуты в дельте r1→r2 (`git diff --stat` подтверждает отсутствие изменений), их корректность наследуется из r1 без повторной проверки. ## Закрытие раунда r1 | Находка r1 | Чем закрыта | Где это видно | |---|---|---| | **M1** — §10 ограничивал новые строки RU/EN/DE, пропуская полноценную поддерживаемую локаль FR; риск красного `npm test` (parity-тест реестра локалей) при буквальной реализации. | Раздел переписан на «RU, EN, DE и FR — всех четырёх существующих поддерживаемых локалях»; таблица терминов расширена столбцом FR (все 15 строк переведены); AC11 обновлён на «RU/EN/DE/FR»; матрица визуальных проверок — на «длинные RU/DE/FR подписи»; §12 численные fixtures не требовали правки по существу (не завязаны на список локалей). Добавлена явная ссылка на штатный parity-тест `npm test` по `src/i18n/registry.ts` из `CONTRIBUTING.md`. | `docs/specs/437-summary-panel.md` §10 (строки ~544–575), таблица терминов, строка AC11 в §11, матрица макетов §10. Независимо перепроверено: `src/i18n/fr.json` — 1257 ключей, совпадает с en/ru/de; `registry.ts` регистрирует French наравне с German. | | **L1** — термин `viewAllowed` в формуле `effectiveVisible` не был определён явно. | Добавлено предложение: «`viewAllowed` — full card находится в режиме View (обычном или kiosk), не в редакторе плана, устройств или подложки (§4.1)». | `docs/specs/437-summary-panel.md` §5.3, сразу перед формулой `effectiveVisible`. Согласовано с §4.1, где то же условие («В редакторах плана, устройств и подложки overlay… скрыты») описано без термина. | | **L2** — пропущенные пробелы перед числами по тексту («шаг5%», «ширина336» и т.п.), снижающие читаемость. | Пробелы расставлены по всему документу: `диапазон 50…300%`, `шаг 5%`, `Reset 100%`, `ширина 336`, `высота 161`, `версия 1`, `4 m²`, `200 rows/10 blocks` и т.д. — весь diff вне §10/§5.3 состоит только из таких правок. | `git diff 4a1aac16..14597ccd` — построчно; независимая проверка `grep`-ом по финальному файлу не нашла оставшихся случаев «слово прилипло к числу» вне легитимных идентификаторов (AC-номера, версии стандартов, хеши коммитов). | Все три находки r1 закрыты по существу, без побочных изменений AC, модели или контрактов. Новых расхождений правка не внесла (арифметика чисел в §5.2 и §12 не менялась, только пробелы вокруг них). ## Унаследовано из r1 Без повторной проверки в r2 принято на основании `docs/reviews/SPEC-REVIEW-437-r1.md` (документ ревью r1, доступен в дереве по коммиту `2a7d1dd2`), на SHA `4a1aac16`, поскольку дельта r1→r2 их не затрагивает: - Соответствие структуры ТЗ обязательным разделам PROCESS.md §7.1. - Соблюдение границ `docs/SCOPE.md` (узкое исключение от 2026-09-03 для #437, строки 115–122) — файл не менялся в дельте. - Закрытие продуктовых вопросов Q1–Q5 до начала написания ТЗ и их точное отражение в тексте (раздел §3 «Принятые Q1–Q5», разделы 3–9 общего ТЗ и соответствующие пункты номерного ТЗ). - Верификация технических утверждений ТЗ против фактического кода на `dev@ed9ee026` (`houseplan-panel.ts`, `_kioskScale`, `ha-binding-status.ts`, `websocket_api.py`, соответствие `CONFIG-COMPATIBILITY.md`, `TOUCH-SUPPORT.md`, `UX-MODES.md`) — код с r1 не менялся (диапазон r1→r2 это только два файла в `docs/`), переверификация не требуется. - Отсутствие пропусков/дублей в AC1…AC26 по номерам и наличие плана доказательства и отрицательного свидетеля у защитных AC — структура таблицы AC не пострадала от точечных правок r2 (перепроверено заново в этом раунде п.6 выше, а не только унаследовано, поскольку дельта формально касалась строк таблицы AC11). - Отсутствие догадок, выданных за решения: технические допущения ТЗ по-прежнему вынесены в §14 «Принято предположительно» — раздел не затронут дельтой. ## Находки r2 Новых находок нет. High: 0. Medium (в скоупе): 0. Medium (вне скоупа): 0. Low: 0. ## Что проверено и корректно (сверх закрытия r1) - `docs/specs/README.md` по-прежнему содержит ссылку на #437 → `437-summary-panel.md`. - Документ синтаксически цел: 14 `##`-разделов, 725 строк, парные code fences (проверено ранее автором `git diff --cached --check`, независимо перепроверено отсутствием незакрытых ``` в файле). - `node scripts/check-docs.mjs` — pass (7 файлов, 12 внешних ссылок). ## Гейты Диапазон r1→r2 не трогает `src/**` и `custom_components/**/*.py` — это чисто документационная правка (кроме публикации r1-отчёта). Тем не менее прогнаны дешёвые гейты на HEAD `14597ccd`, поскольку зелёного Validate на этом SHA не найдено: | Гейт | Результат | |---|---| | `npx tsc --noEmit` | pass, без вывода | | `npm test` | pass — 2253 теста, 2252 pass / 0 fail / 1 skipped / 0 cancelled | | `npm run build` | pass — `tsc --noEmit && rollup -c`, бандл собран за 18.1s | | `node scripts/check-docs.mjs` | pass — 7 файлов, 12 внешних ссылок | ## Чего не проверял и почему - **`npm run golden:verify`, браузерные smoke (`demo/smoke_*.mjs`), инварианты модели (`npm run invariants`), performance-профили** — не прогонялись. Diff не меняет продуктовый код, геометрию, `layout`, `marker.space`, `open_spans`, рендер или видимое поведение приложения: правка ограничена текстом ТЗ (i18n-раздел ещё не реализованной фичи + определение термина + пробелы). Эти AC (продуктовая реализация) физически не существуют в коде на этом SHA — гонять их не по чему. - **Три копии бандла на совпадение** в рамках `npm run build` — не сверялись, поскольку сборка вообще не является предметом этого diff (продуктовый код не менялся ни в r1, ни в r2); `npm run build` прогнан только как дешёвый sanity-гейт, а не потому что диф мог сломать сборку. - **Перевод FR построчно носителем языка** — не проверялся; это вне компетенции автоматизированного ревью. Механически подтверждено, что таблица заполнена по всем 15 строкам и не содержит явных артефактов (пустых ячеек, скопированного текста другого языка). - **`docs/reviews/SPEC-REVIEW-437-r1.md` как публикуемый артефакт** — не ревьюировался повторно по существу: это готовый отчёт предыдущего раунда, зафиксированный шагом публикации конвейера, а не предмет ТЗ-ревью r2. ## Вывод Обе Medium/Low находки r1 закрыты точно и без побочных эффектов; дельта r1→r2 содержательно ограничена FR-локалью и определением `viewAllowed`, обе правки корректны и перепроверены независимо от заявлений автора. Новых находок нет. High: 0, Medium (в скоупе): 0, Medium (вне скоупа): 0. **Вердикт: зелёный.** --- ## Материал раунда - Ветка: `issue/437-summary-panel`, коммит `14597ccdf98b` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. - Дерево материала: `b2833da6cc9238d0be6602a5e4042017a04abe1a` ``` git log --all --format='%H %T' | grep b2833da6cc92 ``` - ТЗ `docs/specs/437-summary-panel.md`, блоб `58a2db80c2161079bc9044c107063e54bfcf0be6` ``` git log --all --find-object=58a2db80c2161079bc9044c107063e54bfcf0be6 -- docs/specs/437-summary-panel.md ```