Issue: #437 User-Visible: no
14 KiB
CODE-REVIEW-437-r4
Issue: #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.
Материал раунда
- Ветка:
issue/437-summary-panel, коммит63ceef6618ba— ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. - Дерево материала:
0cfa507586e643c0cd13d289f017c6939cceb607git log --all --format='%H %T' | grep 0cfa507586e6 - ТЗ
docs/specs/437-summary-panel.md, блоб58a2db80c2161079bc9044c107063e54bfcf0be6git log --all --find-object=58a2db80c2161079bc9044c107063e54bfcf0be6 -- docs/specs/437-summary-panel.md