Files
houseplan-card/docs/reviews/CODE-REVIEW-173-r2.md
T
claude[bot] 63eea47ac6
Validate / docs (push) Failing after 20s
Validate / provenance (push) Successful in 33s
Validate / process-gate (push) Failing after 43s
Validate / changes (push) Successful in 41s
Validate / hacs (push) Skipped
Validate / hassfest (push) Skipped
Validate / frontend (push) Skipped
Validate / smoke (push) Skipped
Validate / golden (push) Skipped
Validate / performance_smoke (push) Skipped
Validate / backend (push) Skipped
docs: review document for #173
Issue: #173
User-Visible: no
2026-08-18 17:51:16 +00:00

19 KiB
Raw Blame History

CODE-REVIEW-173-r2

  • Issue: https://github.com/Matysh/houseplan-card/issues/173
  • Диапазон: origin/dev..HEAD, 5 коммитов: 8a25b52 (ТЗ), e206e87 (ревью ТЗ), fc1e795 feat: unify Plan wall drawing (единственный коммит класса A/B), aac2978 (документ CODE-REVIEW-173-r1.md), f54b9c0 (docs: refresh screenshot fingerprint for #173)
  • Роль: ревьюер кода (не автор), этап S7-code-review, сессия без контекста реализации
  • Цикл: r2/4 — не по находкам. r1 (docs/reviews/CODE-REVIEW-173-r1.md) дал зелёный вердикт с High:0, Medium:2 (обе вынесены отдельными issue, #176/#177, не блокировали); слияние в dev конфликтовало с параллельно влившимся #174, задача вернулась в S6-in-progress для ребейза, а не для правок по находкам ревью (комментарий владельца в issue). После ребейза на актуальный dev (1f11f8f, объединяющий #173 и #174) и docs-only коммита, чинящего screenshot-fingerprint, издана S7-code-review заново. Это другой код (переигранный поверх ушедшего вперёд dev), поэтому повторная проверка не формальность.

Скоуп ревью

fc1e795 — тот же продуктовый диф, что и в r1 (f931159 до ребейза): 28 файлов, +3304/-1926, идентичный набор файлов и идентичные суммы insertions/deletions. Это сильный признак того, что при ребейзе патч src/wall-face-graph.ts / src/houseplan-card.ts / тестов / smoke применился без текстового конфликта — конфликтовали только файлы, которые параллельно менял #174 (docs/specs/README.md, оба CHANGELOG*, три копии бандла). Отдельно проверено (см. ниже), что слияние в этих файлах корректно сохранило записи обоих issue.

Новое в r2 относительно r1:

  • fc1e795 перебазирован на dev, включающий #174 (S8-merged);
  • f54b9c0 — docs-only (docs/images/*.png, docs/images/screenshots.json), обновляет sourceFingerprint после объединения #173+#174 в общий src/.

Не в скоупе изменений (не тронуто ни в fc1e795, ни в f54b9c0): custom_components/houseplan/**/*.py, backend schema, demo/golden/**.

Что именно проверялось в r2 (сверх r1)

Поскольку продуктовый код (fc1e795) идентичен по diffstat уже провалидированному в r1, r2 сфокусирован на: (а) действительно ли текущее дерево green на гейтах, а не только по отчёту в issue; (б) не испортило ли слияние с #174 общие файлы; (в) легитимность нового docs-only коммита; (г) что Medium-находки r1 не потерялись и не были тихо «закрыты» вместо issue. Алгоритмический разбор wall-face-graph.ts, построчная сверка AC1–AC17 по существу и мутационная проверка «тест умеет падать» не повторялись заново пофайлово — они зафиксированы в docs/reviews/CODE-REVIEW-173-r1.md и не имеют оснований измениться, так как сам продуктовый диф не изменился.

Как проверялось — гейты

Гейт Команда Результат
typecheck npx tsc --noEmit pass, без ошибок
unit npm test 848/848 pass (после слияния с #174 набор больше r1-шного 843/843 на 5 тестов #174 — ожидаемо)
build + sync бандла npm run build && cmp dist/houseplan-card.js custom_components/houseplan/frontend/houseplan-card.js && cmp dist/houseplan-card.js demo/srv/assets/houseplan-card.js pass, три копии побайтно идентичны, SHA-256 00391dde7211db685c6c3c83c06b53808fb9a8a6a6c6c6b91b8346c5b27fc1ea — совпадает с числом, которое владелец привёл в хендоффе ребейза
целевой smoke (AC1–AC13) node demo/smoke_unified_wall_tool.mjs 19/19 pass
регрессия #138/AC7 node demo/smoke_room_autoclose.mjs 9/9 pass
регрессия толщины (AC1/AC12) node demo/smoke_draw_wall_thickness.mjs 11/11 pass
touch safety floor (AC3/AC16) node demo/smoke_editor_gestures.mjs 5/5 pass
performance (AC15) npm run benchmark:large-house-plan-snap pass, без брошенных contract-ошибок; wallFaceAcceptedClickMs ≈ 2.8–4.3 мс (порог 1000 мс); wallFaceGraph cache entries = 2, growth = 0 — совпадает с r1
process-gate (локально) node scripts/process-gate.mjs «гейт пройден, предупреждений 0», диапазон origin/dev..HEAD, 5 коммитов
docs freshness/links node scripts/check-docs.mjs --external «Documentation checks passed (7 files, 10 external links)» — совпадает с отчётом владельца; подтверждает, что sourceFingerprint в docs/images/screenshots.json после f54b9c0 реально соответствует текущему src/ (check-docs.mjs:132 сравнивает manifest.sourceFingerprint с живым sourceFingerprint(ROOT), а не просто наличие поля)
merge-корректность shared-файлов чтение docs/specs/README.md, docs/CHANGELOG.md, docs/CHANGELOG.ru.md обе записи (#173, #174) присутствуют, не дублированы, не потеряны; grep -rn '^<<<<<<<|^=======$|^>>>>>>>' по репозиторию — 0 совпадений, конфликтных маркеров не осталось

Не прогонялось и почему:

  • npm run golden:verify — diff (fc1e795, f54b9c0) не содержит изменений demo/golden/**; ни один baseline не принимался. AC12 остаётся проверенным чтением кода, как в r1 (переиспользование немодифицированных canonical хелперов рендера) — предрелизный гейт, не гейт код-ревью.
  • python -m pytest tests_backend -q — ни один файл custom_components/houseplan/**/*.py не тронут ни в fc1e795, ни в f54b9c0 (git diff --stat origin/dev...HEAD).
  • Полный набор из 138+ browser-smoke — как и в r1, тронута ровно одна поверхность (Plan editor); прогнаны целевой smoke плюс три соседних по diff-риску, совпадающих с r1. Продуктовый код не изменился с r1, поэтому расширять выборку в r2 нет причины, вытекающей из diff.
  • Алгоритмическая мутационная проверка «тест умеет падать» (снятие consumed.has(atom.key) и т.п.) — не повторялась: код wall-face-graph.ts и _applyWallFaceBatch в fc1e795 идентичен по diffstat уже промутированному в r1 коду; повторный прогон того же эксперимента на том же коде не добавляет доказательной силы, только тратит цикл.
  • npm run benchmark:compare против baseline SHA — как и в r1, сохранённого отчёта базового SHA нет в этой сессии; сырые цифры сверены вручную с budgets-large-house-plan-snap.json, ни один бюджет не ослаблен.

Проверка AC1–AC17

Все 17 AC остаются подтверждёнными по существу анализа r1 (docs/reviews/CODE-REVIEW-173-r1.md, раздел «Проверка AC1–AC17») — продуктовый код не изменился. В r2 дополнительно подтверждено исполнением:

  • AC1, AC2, AC3, AC7, AC10, AC11, AC16 — повторным зелёным прогоном целевого и трёх соседних smoke на актуальном дереве (см. таблицу гейтов);
  • AC15 — повторным прогоном benchmark:large-house-plan-snap на актуальном дереве, числа совпадают по порядку величины с r1;
  • AC14 — git diff --stat origin/dev...HEAD по новому диапазону подтверждает отсутствие Python/schema изменений и в fc1e795, и в f54b9c0;
  • AC17 — typecheck/unit/build зелёные на актуальном дереве, три копии бандла идентичны, check-docs.mjs подтверждает свежесть screenshot-fingerprint (то, чего не хватало непосредственно после ребейза и что чинит f54b9c0).

AC4–AC6, AC8, AC9, AC12, AC13 не переисполнялись отдельно в r2 (unit-suite wall-face-graph.test.mjs зелёный в общем прогоне 848/848, код не менялся) — проверено тем, что npm test покрывает их без регрессии, и явной пометкой, что построчный разбор не повторялся, так как нет предмета для повторного разбора (diff идентичен).

Находки

Находок уровня High нет. Новых находок уровня Medium нет.

Обе Medium-находки r1 остаются в силе, не блокируют и уже вынесены отдельными issue — проверено, что они не потерялись при ребейзе и не были закрыты задним числом:

  • #176 (S1-new, tech-debt, P3) — мёртвый код старого инструмента partition не удалён. Перепроверено: MARKUP_TOOLS (строка 532, было 533 — сдвиг на строку из-за не связанной с #173 правки, не регрессия), _partitionClick определён на 6943 и вызывается на 6644, 'partition' встречается 51 раз в src/houseplan-card.ts — состояние не изменилось между r1 и r2.
  • #177 (S1-new, tests, tech-debt, P3) — AC8 не имеет unit/smoke-доказательства именно для новой интеграции _offerWallFaces/_applyWallFaceBatch. Код, реализующий AC8, не изменился с r1, находка не переоткрывается заново.

Обе Low-находки r1 (if/else без скобок в _activateMarkupTool; wallFaceAcceptedClickMs не входит в отслеживаемые performance-бюджеты) остаются как записано в r1 — не блокируют, решение прежнего ревьюера в силе, код не изменился.

Проверка самого ребейза — отдельный предмет r2

Единственный содержательно новый риск этого цикла — не в продуктовом коде, а в слиянии с параллельной веткой #174. Проверено:

  1. Нет дублирования/потери записей. docs/specs/README.md содержит ровно по одной строке на #173 и #174; оба CHANGELOG.md/CHANGELOG.ru.md содержат ровно по одной записи Unreleased на каждый issue, без дублирующихся или осиротевших абзацев.
  2. Нет маркеров конфликта. grep по всему репозиторию на <<<<<<</=======/>>>>>>> — 0 совпадений.
  3. Бандл пересобран из объединённого дерева, а не унаследован от старой ветки. Собственная пересборка (npm run build) даёт три побайтно идентичные копии с тем же SHA-256, который владелец указал в хендоффе ребейза — то есть закоммиченные копии не устарели относительно текущего src/.
  4. docs/images/screenshots.json не рассинхронизирован. scripts/check-docs.mjs явно сравнивает закоммиченный sourceFingerprint с фингерпринтом живого src/ (check-docs.mjs:132) — прогон зелёный, то есть коммит f54b9c0 не просто «обновил какие-то числа», а актуален прямо сейчас, на этом дереве, а не только на дереве владельца в момент коммита.
  5. #174 действительно уже принят (S8-merged) — рероллы его кода этим ребейзом не создают повторного риска, требующего отдельной ревью-нагрузки в рамках #173.

Что проверено и корректно

  • Всё содержание раздела «Что проверено и корректно» CODE-REVIEW-173-r1.md остаётся в силе без изменений: алгоритм planar-graph, дисциплина «тест умеет падать» (мутационная проверка r1), finish-контракт на трёх точках выхода, cancel/escape restore terminal draft, лимиты до mutation, clean split reuse, provenance/толщина, совместимость (AC14), i18n RU/EN, трейлеры/changelog — всё это проверялось на идентичном продуктовом дифе.
  • Дополнительно к r1: ребейз на dev, включающий #174, произведён без потери/дублирования продуктовых записей в shared-файлах (docs/specs/ README.md, оба changelog), без оставленных маркеров конфликта, с пересобранным и сверенным бандлом.
  • f54b9c0 — легитимный docs-only коммит: трогает только docs/images/*.png и docs/images/screenshots.json (не demo/golden/baselines/**), поэтому не требует Release:/ Baseline-Reviewed: трейлеров; несёт Issue: #173, User-Visible: no корректно (сами скриншоты — не продуктовое поведение); check-docs.mjs подтверждает, что обновлённый fingerprint соответствует текущему src/.
  • process-gate.mjs зелёный на новом диапазоне origin/dev..HEAD (5 коммитов, было 3 в r1) — трейлеры на всех коммитах класса A/B/C корректны.

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

  • Не повторял построчный разбор алгоритма wall-face-graph.ts и AC4–AC6/AC8/ AC9/AC12/AC13 по существу — сделано в r1 на идентичном по diffstat коде; повторный построчный разбор того же самого кода не производит новой информации, только повторяет уже потраченный цикл. Подтверждено только косвенно: npm test зелёный (848/848) на актуальном дереве без изменений в затронутых файлах.
  • Не повторял мутационную проверку «тест умеет падать» — тот же аргумент, код wall-face-graph.ts/_applyWallFaceBatch не менялся с момента, когда она была выполнена в r1.
  • Не прогонял golden:verify и pytest tests_backend — как в r1, diff не задевает golden/backend поверхности; это предрелизный гейт.
  • Не прогонял полный набор 138+ browser-smoke — продуктовый код не изменился с r1, поверхность та же (Plan editor), расширять выборку без нового риска в diff не оправдано.
  • Не воспроизводил multi-client optimistic-lock conflict живым прогоном (AC13) — как в r1, проверено чтением, что batch не вводит новый conflict- путь; код batch не менялся.
  • Не запускал npm run benchmark:compare против сохранённого baseline SHA — такого отчёта нет в этой сессии; сверил абсолютные числа вручную с бюджетным файлом, как в r1.

Вердикт

Зелёный. High: 0, Medium: 0 новых (обе Medium-находки r1 остаются в силе, уже вынесены отдельными issue — #176, #177, — и не переоткрываются, так как код, к которому они относятся, не изменился). Low: 2, перенесены из r1 без изменений, не блокируют.

Причина цикла r2 не в качестве кода, а в необходимом по процессу повторном прогоне после ребейза на ушедший вперёд dev (слияние с #174). Продуктовый диф идентичен уже принятому в r1 по составу файлов и объёму изменений; новая проверочная нагрузка этого цикла была сосредоточена на самом слиянии и на корректности docs-only коммита f54b9c0 — обе проверки пройдены. Ни одна находка не свидетельствует, что изменение не решает заявленный сценарий или ухудшает смежное поведение.