Files
houseplan-card/docs/reviews/CODE-REVIEW-330-r4.md
T
claude[bot] 2d1ca74a7d
Проверка (CI) / Классификация изменённых файлов (push) Successful in 1m30s
Проверка (CI) / Предполётные проверки: документация, провенанс, процесс (push) Failing after 1m50s
Проверка (CI) / Переиспользование: это дерево уже проверено (push) Successful in 1m50s
Проверка (CI) / HACS: валидация репозитория (push) Failing after 18s
Проверка (CI) / Hassfest: манифест интеграции (push) Failing after 28s
Проверка (CI) / Фронтенд: типы, юниты, мутанты, синхрон бандла (push) Failing after 5m56s
Проверка (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) Failing after 6m29s
docs: review document for #330
Issue: #330
User-Visible: no
2026-08-28 00:56:30 +00:00

15 KiB
Raw Blame History

CODE-REVIEW-330-r4

Issue: #330 — «Ограничения стыков (#329) блокируют event loop HA и дёргают ресайз на больших планах» Этап: code (PROCESS.md §2.7) Заход: r4 · блокирующих циклов израсходовано 3 из 4 (до этого раунда) Ветка: issue/330-junction-limits-performance, HEAD ревью — d33aa0a7

0. Разбор по дельте — почему и от какого SHA

Предыдущий вердикт (code-review r3, 2026-08-28T00:49:49Z — жёлтый, High: 1, Medium: 0) назван на HEAD 04bb54ae. Проверено, что этот SHA — прямой предок текущего HEAD и что ребейза не было:

$ git merge-base --is-ancestor 04bb54ae HEAD && echo ancestor
ancestor
$ git log --oneline 04bb54ae..HEAD
d33aa0a7 docs: refresh the screenshot pair after the cache-key fix (#330 r3-H1)
90a3313d docs: review document for #330

Также проверено, что dev не ушёл вперёд за это время:

$ git fetch origin dev --quiet
$ git log --oneline -1 origin/dev
eff786fa docs: review document for #62
$ git merge-base --is-ancestor origin/dev HEAD && echo "dev is ancestor of HEAD"
dev is ancestor of HEAD

Дельта — два коммита: 90a3313d — публикация документа r3 (класс C, не код), d33aa0a7 — точечный фикс единственной находки r3 (H1). Контракт поведения не менялся, новая подсистема не задета, объём дельты меньше даже r2→r3. Условия §2.10/§7.2 для полного разбора не выполнены — разбираю по дельте git diff 04bb54ae..HEAD.

1. Скоуп дельты

git diff 04bb54ae..HEAD --stat:

 docs/images/screenshots.json       |  22 ++--
 docs/reviews/CODE-REVIEW-330-r3.md | 226 +++++++++++++++++++++++++++++++++++++
 2 files changed, 237 insertions(+), 11 deletions(-)

Только r3-H1 (докс-гейт красный на HEAD предыдущего раунда):

  • docs/images/screenshots.json — sourceFingerprint и все десять sourceSha256 заменены с устаревшего 2a5ae6c1… на актуальный dbac4a84d0eb558e66066f5072363977ff4a78c0a032e6f2b9a5d0848cd20f0f — ровно то значение, которое r3 уже вычислил независимо (visualFingerprint() на дереве r3, см. документ r3 §3) как «реальное». Ни один imageSha256 не изменился ни в одной из десяти сцен — предсказание r3 («UI не менялся, PNG, вероятно, останутся байт-в-байт те же») подтвердилось буквально.
  • src/**, test/**, demo/**, scripts/**, custom_components/**, dist/** — не тронуты вовсе. Никакого продуктового или тестового кода в дельте нет.
  • docs/reviews/CODE-REVIEW-330-r3.md — публикация документа предыдущего раунда (класс C, инфраструктурный шаг, не предмет код-ревью).

2. Закрытие раунда r3

Находка r3 Чем закрыта Где это видно
H1 (в скоупе) — node scripts/check-docs.mjs завершался exit 1: записанный sourceFingerprint (2a5ae6c1…) разошёлся с реальным visualFingerprint() дерева (dbac4a84…) после того, как 04bb54ae поменял src/houseplan-card.ts без пересчёта скриншот-манифеста Манифест пересчитан прогоном npm run build && node demo/docs/capture.mjs и принят: новый sourceFingerprint/все sourceSha256 равны dbac4a84… — ровно значению, которое r3 назвал ожидаемым. imageSha256 не изменился ни в одной сцене, то есть пересчитан именно отпечаток источника, а не подменены сами PNG docs/images/screenshots.json (диф выше); я прогнал node scripts/check-docs.mjs на текущем HEAD лично (не со слов автора)

Находка закрыта по существу и подтверждена исполнением, не только чтением коммита.

3. Как проверялось (дельта, r4)

Validate на этом SHA (d33aa0a7) уже зелёный (см. вводную задачи, ссылка на прогон), поэтому tsc/npm test/npm run build + сверка бандла не перегоняю — они не относятся к предмету этой дельты (дельта не трогает src/**/test/**) и уже подтверждены на этом самом SHA.

Единственный релевантный дельте гейт — сам докс-гейт, ради которого сделан коммит:

Гейт Команда Результат
Докс-гейт node scripts/check-docs.mjs Documentation checks passed (7 files, 10 external links)., exit 0
Ручная сверка значения фингерпринта git diff 04bb54ae..HEAD -- docs/images/screenshots.json все 11 вхождений sourceFingerprint/sourceSha256 заменены на один и тот же новый хеш; все 10 imageSha256 не изменились
Trailers коммитов дельты git show 90a3313d -s --format=%B, git show d33aa0a7 -s --format=%B оба несут Issue: #330, User-Visible: no — корректно: 90a3313d публикует документ ревью (класс C, не продукт), d33aa0a7 пересчитывает служебный отпечаток без изменения видимого результата (PNG идентичны)
Рёбейз/уход dev git merge-base --is-ancestor 04bb54ae HEAD, git fetch origin dev && git merge-base --is-ancestor origin/dev HEAD оба — да; условие полного разбора (§2.10, ребейз на ушедший вперёд dev) не выполнено

Дельта не трогает геометрию, рендер, стили, слои, публичный контракт, custom_components/** и ни один файл, упомянутый в §5 текста ревью (инварианты модели, смоки, golden, perf-профили, бэкенд-тесты) — поэтому эти гейты не перегоняю, наследую решениеr3 не гонять их (см. §5 ниже).

4. Находки

Находок нет. Единственная находка предыдущего раунда (r3-H1) закрыта точным, минимальным коммитом, который меняет ровно то, что было названо дефектным (отпечаток источника), и ничего больше.

5. Унаследовано из r3 (без повторной проверки)

Дельта r4 не касается ни одной строки продукта, теста или конфигурации — наследую весь корпус r3 целиком, включая то, что сам r3 унаследовал из r2:

  • Архитектура срезов §4.1–§4.7 (executor-цепочка, rev-кэш previous, byNode-индекс П3, bucket-решётка П4, §4.6 «v9 как есть», общий проход §4.7) — признана верной в code-review r2 (docs/reviews/CODE-REVIEW-330-r2.md, HEAD 85636a65) и подтверждена неизменной в r3 (docs/reviews/CODE-REVIEW-330-r3.md, HEAD 04bb54ae, §5). Ни r3, ни r4 её не трогают.
  • AC1 (event loop/executor) — pytest -k 330 → 1 passed, исполнено в r2, не затронуто с тех пор (custom_components/** не в дельте ни r3, ни r4).
  • AC2/AC3/AC5 (линейный П3/П4, rev-кэш бэкенда, эквивалентность §4.6) — паритет-тесты TS↔Python, pytest tests_backend -q (423 passed), исполнены в r2, не затронуты в r3/r4.
  • AC4 (баланс кэша фронта) — закрыто по существу в r3 (см. таблицу закрытия r2→r3 в docs/reviews/CODE-REVIEW-330-r3.md §2): ключ кэша заменён на identity документа + spacePhysicalGeometryFingerprint, мутант junction-limit-baseline-cache-stale ловится смоком, mutation-gate.mjs --id=junction-limit-baseline-cache-stale зелёный. Дельта r4 не трогает src/houseplan-card.ts, demo/smoke_junction_limits.mjs, test/junction-limits.test.mjs, scripts/mutation-gate.mjs — код кэша байт-в-байт тот же, что был подтверждён исполнением в r3.
  • AC7/перф-контракт §5, включение в validate.yml — подтверждено исполнением в r2 и r3 (benchmark:junction-limits → pass: true, запас ≥2.6×). Не в дельте r4.
  • golden:verify — не гонял, как и в r2/r3: ни один раунд с r1 не касался рендера/геометрии/стилей/слоёв, r4 тем более (дельта — только screenshots.json, а он не входит в golden-контур).
  • Полная матрица demo/smoke_*.mjs и полный mutation-gate.mjs — не гонял целиком: предрелизные гейты (PROCESS.md §8), не гейт ревью. По дельте r4 гонять нечего — она не содержит кода, который могла бы затронуть какая-либо смок-проверка.
  • pytest tests_backend — не гонял; дельта r4 не содержит ни одного файла .py.
  • npm run invariants -- --config <...> — не гонял; дельта не вводит и не меняет геометрию, layout, marker.space, open_spans или записи толщины ни в r3, ни в r4.
  • Одно число — один источник — неприменимо: дельта r4 не вводит и не меняет ни одной пользователю видимой величины. Более того, она подтверждает обратное намеренно: imageSha256 (то, что реально видит пользователь на скриншотах) не изменился ни на бит — изменился только служебный sourceFingerprint/sourceSha256, внутренний отпечаток дерева исходников для докс-гейта, невидимый конечному пользователю карточки.
  • CHANGELOG — не требуется ни для 90a3313d (публикация документа ревью, класс C, не входит в DoD задачи по видимому поведению), ни для d33aa0a7 (User-Visible: no, подтверждено фактом: PNG идентичны, меняется только служебный манифест).

6. Что проверено и корректно (эта дельта)

  • Значение нового sourceFingerprint в docs/images/screenshots.json совпадает с тем, которое r3 независимо вычислил как «реальное» (dbac4a84…) на том же дереве до этого коммита — не просто «файл изменился», а изменился на правильное значение.
  • Ни один imageSha256 не менялся — фикс не подменяет и не портит сами скриншоты, трогает только служебное поле идентификации источника.
  • node scripts/check-docs.mjs зелёный на текущем HEAD, прогнан лично.
  • Trailers обоих коммитов дельты корректны для их класса изменений.
  • Дельта не расширяет и не сужает скоуп задачи: единственная цель коммита — закрыть ровно ту находку, которая была названа, ничего лишнего не задето.

7. Чего не проверял и почему

  • npx tsc --noEmit, npm test, npm run build + сверка бандла — Validate зелёный на этом самом SHA (d33aa0a7, ссылка в вводной задачи), а дельта не трогает ни src/**, ни test/** — перегонять нечего нового.
  • pytest tests_backend, golden:verify, инварианты модели, смоки помимо докс-гейта, perf-бенчи — дельта r4 не содержит ни одного файла, который могли бы затронуть эти гейты (только docs/images/screenshots.json и публикация документа ревью); все они наследуются из r2/r3 без повторного прогона (см. §5).
  • Ручное тестирование в браузере — вне цикла ревью по регламенту; предмет этого раунда — сугубо служебный докс-манифест, для него замена (докс-гейт) прогнана.

8. Итог

High: 0. Medium: 0. Единственная находка r3 (H1) закрыта точным, минимальным, верифицированным коммитом — значение фингерпринта совпало с независимо вычисленным ожиданием, PNG не изменились, докс-гейт зелёный на исполнении, не со слов автора. Весь остальной корпус задачи (§4.1–§4.7, AC1–AC7, AC4-фикс r2→r3) наследуется без повторной проверки — дельта r4 его не касается ни одной строкой. Зелёный вердикт, бюджет циклов не тратится.