Files
houseplan-card/docs/reviews/CODE-REVIEW-304-r2.md
2026-08-25 14:30:36 +00:00

17 KiB

CODE-REVIEW-304-r2

Issue: #304 — паритет базовых осей и узлов между инструментами Plan editor Ветка: issue/304-plan-axis-parity, HEAD e603c5496fcbbd674c48a0314ca4f2e6f22a4c71 Диапазон: origin/dev...HEAD (4 коммита: a2b4d32b код, 7310ce01 скриншоты докс, 33dcd1ce документ ревью r1, e603c549 приёмка golden-эталонов) Трек: small Заход: r2 · блокирующих циклов израсходовано 1 из 2 (расход только на жёлтый/красный вердикт r1; зелёный вердикт этого раунда цикл не образует) Вердикт: зелёный · High: 0 · Medium: 0

Скоуп этого раунда (дельта)

Предыдущий раунд (r1) закончился жёлтым вердиктом на SHA 7310ce0134ca8e5b1c32e6816a2e70625ea158e2 (документ docs/reviews/CODE-REVIEW-304-r1.md, коммит 33dcd1ce). Единственная находка — H1: golden-доказательство неполно, канонический Linux Validate для этой ветки (run 32854408646, commit a2b4d32b) дал golden: failure на 5 сценах (safe-resize-handles-clamp-{light,dark}, opening-placement-{door,passage}-thick-wall-{dark,light}), новый эталон не был снят/принят.

Дельта r2 = git diff 7310ce01..HEAD:

demo/golden/baselines/baselines-index.json         |  28 +--
demo/golden/baselines/decor-color-popover-mobile-ru.png       | Bin
demo/golden/baselines/opening-placement-door-thick-wall-dark.png | Bin
demo/golden/baselines/opening-placement-passage-thick-wall-dark.png | Bin
demo/golden/baselines/opening-placement-passage-thick-wall-light.png | Bin
demo/golden/baselines/room-label-parity-plan-dark.png | Bin
demo/golden/baselines/room-label-parity-plan-light.png | Bin
demo/golden/baselines/safe-resize-handles-clamp-dark.png | Bin
demo/golden/baselines/safe-resize-handles-clamp-light.png | Bin
demo/golden/baselines/space-tab-drop-after-dark.png | Bin
demo/golden/baselines/split-corner-wall-thick-dark.png | Bin
demo/golden/baselines/wall-junctions-plan-preview-light.png | Bin
demo/golden/baselines/wall-junctions-plan-t-dark.png | Bin
docs/reviews/CODE-REVIEW-304-r1.md                  | 272 +++ (публикация r1, не код)

Продуктовый код (src/houseplan-card.ts), тесты/смоки и документация пользователя не менялись с r1 — только один коммит класса D (e603c549, demo/golden/baselines/**) плюс публикация предыдущего документа ревью (не относится к предмету оценки). Это ровно та дельта, которую и требовала находка H1: разбор по существу ограничен ею, AC не переоткрываются заново — они не задеты этим коммитом.

Закрытие раунда r1

Находка r1 Чем закрыта Где это видно
H1 (High) — golden-доказательство AC6/«Release-артефакты» неполно: 5 сцен different на каноническом Linux Validate, эталон не принят Коммит e603c549 test: accept reviewed plan-axis baselines — принят полный 110-сценовый Linux-артефакт из того же run 32854408646 через npm run golden:accept -- --reviewed --from=<артефакт>; новый эталон закрывает все 5 названных сцен git show -s --format=%B e603c549 содержит Release: v1.67.0-rc.3 и Baseline-Reviewed: https://github.com/Matysh/houseplan-card/actions/runs/32854408646; git diff 7310ce01..e603c549 --stat показывает ровно эти 5 файлов среди 12 изменённых PNG; свежий Validate на точном HEAD e603c549 — run 32858067234, job golden → success (проверил сам, gh run view 32858067234 --json jobs)
Low (снята без правки в r1) — AC1 использует смежную, не буквально идентичную unit/smoke fixture golden-топологию Не менялась, не требовала правки; остаётся снятой документ r1, раздел «Low»

Как проверялось (r2)

Материал: git log --oneline origin/dev..HEAD, git diff 7310ce01..HEAD (дельта раунда) и git diff origin/dev...HEAD (полная картина, для сверки, что делта не задевает продукт).

Прогнано лично в этом раунде

Проверка Команда Результат
Typecheck npx tsc --noEmit зелёный, без ошибок
Unit npm test 1299 тестов, 1298 passed, 0 failed, 1 skipped (тот же pre-existing #281-скип, что и в r1; не связан с #304 и с этой дельтой)
Bundle-копии cmp dist/houseplan-card.js custom_components/houseplan/frontend/houseplan-card.js идентичны (код не менялся с r1, пересборка не требовалась)
Docs fingerprint node scripts/check-docs.mjs «Documentation checks passed (7 files, 10 external links)»
Provenance/process gate node scripts/process-gate.mjs --range=origin/dev..HEAD «гейт пройден, предупреждений 1» — единственный WARN («ТЗ docs/specs/304-*.md не найдено») ожидаем для small
Канонический golden (Linux CI, не локально) gh run view 32858067234 --repo Matysh/houseplan-card --json jobs на точном HEAD e603c549 все джобы success: golden, docs, frontend, provenance, все 3 smoke-шарда, performance_smoke; backend/hacs/hassfest — skipped (файлы этих поверхностей не тронуты, ожидаемо)
Число принятых сцен `ls demo/golden/baselines/*.png wc -l= 110;node -e "import('./demo/golden/matrix.mjs').then(m=>console.log(m.GOLDEN_SCENARIOS.length))"` = 110

Дешёвый набор (tsc/unit/build/check-docs) прогнан заново, потому что это правило раунда без исключений — они стоят минуты независимо от размера дельты. npm run build целиком не перезапускал: код не менялся с r1, байтовое сравнение уже показывает три копии идентичными.

Что не прогонял и почему

  • npm run golden:verify локально — не запускал. Дельта — это уже принятые эталоны из канонического Linux-прогона; локальный verify на этой машине (не подтверждённый как каноническое Linux-окружение) не добавил бы доказательности сверх реального Linux CI-прогона на точном HEAD, который зелёный (см. таблицу выше).
  • smoke-select.mjs / прицельные смоки — не перезапускал. Дельта не трогает src/**, demo/smoke_*.mjs, test/** — выбор смоков и их результат наследуются из r1 без изменений (см. «Унаследовано из r1»).
  • node scripts/model-invariants.mjs — не запускал. Дельта не касается рёбер комнат, layout, marker.space, open_spans, записей толщины — только растровые PNG-эталоны и индекс манифеста.
  • python -m pytest tests_backend — не запускал, custom_components/**/*.py не тронут ни в этой дельте, ни во всём диапазоне.
  • Полный demo/smoke_*.mjs — не прогонял; наследуется из r1 (не задет дельтой).

Визуальная сверка новых эталонов (не только доверие к commit message)

Открыл несколько принятых PNG, чтобы не принимать формулировку коммита («below-threshold raster refresh» для 7 сцен, «intended new layer» для 5) на слово:

  • opening-placement-door-thick-wall-dark.png и safe-resize-handles-clamp-light.png (2 из 5 «смысловых» сцен из H1) — на обеих виден новый статический слой осевых линий/узлов (пунктирные линии через тела стен) в инструментах Opening и Resize, чего не было до фикса #304 — соответствует контракту п.1 issue, ожидаемое изменение;
  • decor-color-popover-mobile-ru.png (одна из 7 «уже проходивших» сцен) — Background editor, цветовой попап, никакой связи с Plan editor/осями нет; сцена не может быть затронута кодом #304 по существу — расхождение байтов до принятия объясняется только суб-пиксельным дрейфом рендера того же Chromium-прогона, ровно как заявлено в commit message, не скрытой регрессией.

Механика приёмки — прочитан сам скрипт, не только описание

demo/golden/accept.mjs копирует все сценарии текущей матрицы (GOLDEN_SCENARIOS, 110 штук) из одного переданного артефакта и атомарно перезаписывает единый манифест (sourceFingerprint/chromium/acceptedAt — общие для всего набора, не по сцене) — значит «приняты все 110, из них у 12 изменились байты» — ожидаемое поведение инструмента, не частичная/избирательная перезапись и не расширение скоупа: манифест домена смоделирован как один атомарный набор от одного канонического прогона, а не патчворк разных прогонов во времени.

Унаследовано из r1

Документ docs/reviews/CODE-REVIEW-304-r1.md (заход r1, SHA 7310ce0134ca8e5b1c32e6816a2e70625ea158e2, опубликован коммитом 33dcd1ce). Дельта r2 не трогает src/**, тесты/смоки, i18n, документацию пользователя — принято без повторной проверки:

  • разбор самой продуктовой правки (src/houseplan-card.ts, гейтинг снят в двух местах, transient state остаётся эксклюзивным «Стенам») — код не менялся с r1;
  • AC1–AC5, AC7 — доказательства (unit/smoke, включая проверенную способность нового смока и нового golden-инварианта падать) не переоткрывались: ни один из задетых файлов не входит в дельту r2;
  • границы режимов (View/Device editor/Background editor), transient-контракт п.4, отсутствие промежуточного кадра (п.7) — код-основа не менялась;
  • трейлеры коммита a2b4d32b (Issue: #304, User-Visible: yes, оба changelog в том же коммите) — проверены в r1, повторно не смотрел;
  • i18n/compatibility/performance разбор из r1 — не задет дельтой, наследуется целиком;
  • Low-находка r1 (AC1 golden-топология смежная, не идентичная) — остаётся снятой, дельта её не касается.

Что проверено и корректно (r2, по существу дельты)

  • Ровно 5 сцен из H1 обновлены и визуально показывают ожидаемое новое поведение (#304), а не случайное изменение;
  • ровно 7 дополнительных сцен обновлены синхронно тем же атомарным прогоном приёмки — не выборочная правка, механика инструмента подтверждена чтением accept.mjs; выборочно открытая «decor»-сцена подтверждает отсутствие скрытой регрессии в этой группе;
  • трейлеры коммита e603c549 полны: Issue: #304, User-Visible: no (генерируемые артефакты, продукт не меняется), Release: v1.67.0-rc.3, Baseline-Reviewed: со ссылкой на реальный прогон — процесс provenance для класса D соблюдён;
  • канонический Linux Validate на точном итоговом HEAD зелёный целиком, включая golden и все 3 смок-шарда — это сильнее локального прогона и снимает саму находку H1 по факту, а не по утверждению автора;
  • полный набор эталонов (110/110) внутренне согласован (единый sourceFingerprint/chromium в манифесте) — не оставляет часть эталонов от старого несовместимого Chromium-прогона.

Чего не проверял

  • Полный demo/smoke_*.mjs и полный npm run golden:verify локально — дельта не требует, см. «Как проверялось»;
  • python -m pytest tests_backend, node scripts/model-invariants.mjs — не запускал, дельта их не касается;
  • Побайтовую/пиксельную сверку всех 12 изменённых PNG — открыл 2 из «смысловых» пяти и 1 из «шумовых» семи как выборочную проверку заявления автора; оставшиеся 9 не смотрел глазами, доверился единому механизму приёмки (accept.mjs, прочитан целиком) и совпадению количества принятых сцен с полной матрицей.
  • Точная арифметика «110 passed / 5 different» из текста r1-документа (там написано «110 сцен passed, 5 different» при общей матрице 110 сцен, что даёт 115 — арифметически не сходится: видимо, опечатка прежнего раунда, верное соотношение 105/5). Не влияет на существо закрытия H1 и не относится к дельте r2, поэтому не переоткрывал.

Итог

Единственная блокирующая находка предыдущего раунда (H1, неполное golden-доказательство) закрыта по существу: канонический Linux-прогон полного матрикса принят как эталон через штатный golden:accept --reviewed, снабжён обязательными Release:/Baseline-Reviewed: трейлерами, и свежий Validate на итоговом HEAD зелёный целиком — включая job golden. Продуктовый код и его доказательная база не менялись с r1 и наследуются без повторной проверки. Новых находок в дельте r2 нет.