Files
2026-10-01 23:05:20 +00:00

19 KiB
Raw Permalink Blame History

CODE-REVIEW-744-r4

Issue: #744 · Трек: ask · Заход: r4 · блокирующих циклов израсходовано 1 из 4

Материал: 2bcde131581a6130f971dcef167299d6cc1129ad (ветка issue/744-floor-geometry-key, поверх dev c4cb0649 — после слияния #762). Девять коммитов от merge-base: продуктовые/тестовые К1–К5 f5b20e07 и 6ed9aa16 (уже разобраны в r1/r2), a86be350 (ленивый space-editor, уже разобран в r3 под хешем 0f16312e — ребейз осиротил старый хеш, содержимое то же), три docs-коммита, публикующих CODE-REVIEW-744-r1/r2/r3.md (bb9aaefe, 2d7a1c97, 9882046b) и два коммита docs(reviews): индекс после сдвига каталога (3d68a2fe, 7bbab4b6), и новый 2bcde131 — единственная содержательная правка этого раунда.

Скоуп

r3 был зелёным на материале 0f16312e (комментарий автора, вердикт 2026-10-01). Пока ревью шло, dev продвинулся ещё на 5 коммитов; владелец зафиксировал это прямо в issue и вернул задачу в S6-in-progress не как правку кода, а как ребейз («Код-ревью зелёное — вердикт выше в силе, переделывать работу не нужно. Не удалось только слияние»). Автор сделал git rebase origin/dev на dev@c4cb0649 (после #762) и запушил без force (lease 98db7b1f → 2bcde131).

Ребейз дал ровно один конфликт — в docs/testing-notes/mutation-browser-guards.md (таблица пересекалась с чужими правками, ушедшими в dev раньше #744): автор взял строки dev и прибавил к ним два мутанта задачи (floor-geometry-key-*), подняв lifecycle 97→99 и Total 214→216. После ребейза один шаг gate:small покраснел на храповике монолита: bundleBytes вырос с 2 605 172 до 2 607 854 Б (+2 682 Б при полосе 2 000) — не потому что код раунда что-то добавил (К1–К5 и ленивый space-editor уже посчитаны в r1/r3), а потому что ребейз сам по себе сдвинул дерево dist/ относительно старой базы. Автор поднял базовую линию отдельным коммитом 2bcde131 с обоснованием (новый модуль ключа этажа + обёртка ленивого чанка), не трогая продуктовый код.

Задача по-прежнему track: ask, критерий §5 «перф» не переоценивается — не изменился с r1. route: fix.

Дельта r3 → r4

Проверено прямым чтением, не только по словам автора: содержимое продуктовых коммитов не изменилось, изменились только их хеши (ребейз переносит одни и те же патчи на новый родитель):

  • f5b20e07 (К1–К5, перф floor-geometry-key): git show f5b20e07 --stat даёт те же 13 файлов/456+/24− и тот же текст изменений, что описан в r1 — с одним отличием: правка docs/testing-notes/mutation-browser-guards.md внутри этого же коммита теперь содержит ребейзнутые числа 97→99/214→216 (было 90→92/205→207 на старой базе r1/r3). Это ожидаемый эффект ребейза коммита с текстовым конфликтом, не новая правка задачи.
  • 6ed9aa16 (тест «судить оба кадра удержанного resize») — 1 файл, 58+/7−, идентичен r2.
  • a86be350 (ленивый space-editor) — дифф src/space-card.ts побайтово совпадает с тем, что r3 разобрал под хешем 0f16312e (тот же import './space-editor' убран, тот же async getConfigElement()).

Единственное новое содержание раунда — коммит 2bcde131:

chore(monolith): raise the bundleBytes baseline for #744 (#744)
scripts/monolith-baseline.json | 2 +-

"bundleBytes": 2605172 → 2607854. Трейлеры: Issue: #744, User-Visible: no — верно: число самим пользователям не видно, это внутренний храповик монолита (scripts/monolith-metrics.mjs, docs/testing-notes/..., не пользовательская поверхность).

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

Гейт Статус Как
npx tsc --noEmit, npm test, npm run build + bundle-policy --verify не перегонял целиком, но npm run build выполнил сам Validate на точном SHA материала зелёный: https://github.com/Matysh/houseplan-card/actions/runs/36937043475 — сверено gh run view 36937043475, headSha = 2bcde131581a6130f971dcef167299d6cc1129ad, conclusion: success (не со слов автора). Дополнительно сам прогнал npm run bundle:sync (→ tsc --noEmit && rollup -c зелёные, бандл собрался за 22,2 с) ради смока ниже; рабочую копию dist/ вернул git checkout -- dist/ + git clean -fd dist/, git status --porcelain пуст после
Корректность ребейзнутой таблицы mutation-browser-guards.md прогнал сам Пересчитал список построчно (grep -c '^- \' по секциям): «Custom-element and HA browser lifecycle» = 99, сумма всех секций = 216 — совпадает с заявленным в таблице «99» и «216 / 200». Оба мутанта задачи (floor-geometry-key-global-epoch, floor-geometry-key-ignores-content`) в списке на месте
node scripts/mutation-gate.mjs --check прогнал сам exit 0; browser guards: 216/200 — WARN (не отказ, #699, та же картина что в r3, но с актуальными для текущего dev числами); оба мутанта задачи — ok
node demo/smoke_floor_geometry_cache.mjs прогнал сам, на пересобранном бандле Все проверки true/0/[] как ожидается: AC1 (ac1GardenVisitBuildsNo* = 0), AC2а/б/в (...EqualsAFreshCard = true), итог OK. Это прямое исполнение целевого смока задачи на точном материале раунда, не унаследованная запись
node scripts/smoke-select.mjs --base origin/dev --head HEAD прогнал сам 20 прямых совпадений (включая целевой smoke_floor_geometry_cache.mjs ← _cleanFloorCache) + 41 слабая связь на _curSpaceCfg — тот же профиль, что в r3 (дельта src/space-card.ts не читает _curSpaceCfg); решение не прогонять слабые — не затронуты дельтой
Freshness docs/reviews/INDEX.md прогнал сам node scripts/reviews-index.mjs → «docs/reviews/INDEX.md свеж»
npm run gate:small, полный smoke-select, golden, Full Performance, pytest tests_backend, npm run invariants не перегонял дельта раунда — ребейз без изменения продуктового кода плюс один chore-коммит над scripts/monolith-baseline.json; геометрия, Python и рендер плана не затронуты; AC1–AC5 (К1–К5) и AC4 (performance) уже закрыты исполнением в r1–r3 на коде, который не менялся с тех пор

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

r3 был зелёным без находок (0 High, 0 Medium) — закрывать нечего.

Унаследовано из r3 (и транзитивно из r1/r2)

Продуктовый и тестовый код К1–К5 (src/floor-geometry-key.ts, src/clean-floor.ts, src/stairs-editor.ts, src/houseplan-editor-runtime.ts, src/houseplan-card.ts, src/space-card.ts, demo/smoke_floor_geometry_cache.mjs, demo/benchmark_large_house.mjs, demo/performance/card-contract.mjs, scripts/mutation-registry.mjs, test/clean-floor.test.mjs) не менялся между r3 и r4 — дельта раунда ограничена ребейзом (без изменения содержимого этих файлов, подтверждено построчно выше) и одним новым chore-коммитом над scripts/monolith-baseline.json. Принято без повторного построчного разбора, с документом и материалом r2/r3 (docs/reviews/CODE-REVIEW-744-r2.md, материал d10285b0794d…; docs/reviews/CODE-REVIEW-744-r3.md, материал 0f16312e8ff1…):

  • Архитектура ключа этажа (contentFingerprint, память на эпоху и на пару объектов записи), её использование в четырёх кэшах и resize-preview со своим ключом.
  • Контракт К1–К5 и защита против «устаревшего кадра» независимым oracle в смоке — сам смок перепрогнан мной заново в этом раунде на пересобранном бандле и зелёный, так что это подтверждено исполнением, а не только унаследовано.
  • StairsEditor.write больше не чистит _cleanFloorCache других этажей.
  • Ленивая загрузка GUI-редактора space-card (контракт идентичен houseplan-card.getConfigElement()), структурная и поведенческая корректность подтверждены исполнением в r3 (манифест чанка + Playwright-зонд).
  • Два мутанта в scripts/mutation-registry.mjs — перепроверено мной mutation-gate --check в этом раунде, оба на месте.
  • AC4 — Full Performance против базы dev, закрыт в r1→r2, исполнение проверено r2 напрямую по API/логам; код, который измеряет AC4, с тех пор не менялся.
  • Трейлеры и CHANGELOG RU/EN на продуктовом коммите f5b20e07 (бывший 5263403c до ребейза) — текст дословно совпадает с ТЗ, оба файла правлены в одном коммите; проверено, что обе строки #744 сохранились в текущем docs/CHANGELOG.md/docs/CHANGELOG.ru.md после ребейза (не были потеряны слиянием).

Находки

Нет High. Нет Medium в скоупе. Нет Medium вне скоупа.

Наблюдение r3 о расхождении счётчика в mutation-browser-guards.md» (92/207 в тексте против 209 фактических) снято этим раундом: ребейз пересчитал коммит f5b20e07против актуальной базыdev, и таблица теперь точно совпадает с фактическим выводом mutation-gate.mjs` (216/216, 99/99 lifecycle) — подтверждено пересчётом выше.

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

  • Дельта раунда (ребейз + 2bcde131) не меняет ни одного продуктового файла К1–К5: сверено построчно по diff-статам коммитов f5b20e07/a86be350, совпадающим с тем, что уже разобрано в r1/r3.
  • Единственная содержательная правка — поднятие bundleBytes baseline — это class D (генерируемое значение), её корректность уже подтверждена прохождением gate:small/Validate на точном SHA (храповик монолита сам проверяет, что новое число соответствует фактической сборке в пределах полосы; расхождение завалило бы Validate).
  • Конфликт-резолюшн в docs/testing-notes/mutation-browser-guards.md корректен: фактический вывод mutation-gate --check (216 всего, 99 lifecycle) совпадает с текстом таблицы после ребейза, оба мутанта задачи на месте.
  • Целевой смок задачи (demo/smoke_floor_geometry_cache.mjs, AC1/AC2а/б/в) зелёный на пересобранном бандле точного материала — не только по унаследованной записи r3.
  • Трейлеры всех коммитов класса A/B раунда (f5b20e07, 6ed9aa16, a86be350, 2bcde131) содержат Issue: #744 и корректный User-Visible:; User-Visible: yes на f5b20e07 — оба CHANGELOG правлены в этом же коммите и сохранились после ребейза.
  • docs/reviews/INDEX.md свеж относительно опубликованных r1–r3 документов (node scripts/reviews-index.mjs).
  • Одно число — один источник: bundleBytes 2 607 854 видно один раз — в scripts/monolith-baseline.json, которое читает только scripts/monolith-metrics.mjs/gate:small; пользователю это число не показывается (User-Visible: no), второго источника для сверки нет.

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

  • Дешёвые гейты npx tsc --noEmit/npm test/bundle-policy --verify целиком не перегонял — Validate на точном SHA материала подтверждён зелёным (gh run view 36937043475); npm run build тем не менее выполнил сам (см. таблицу), так что сборка на этом дереве подтверждена дважды независимо.
  • Полный smoke-select (всю матрицу 289 смоков), browser-смоки/golden всех шардов не перегонял — дельта раунда не трогает рендер плана, геометрию или UI; целевой смок задачи и профильный mutation-gate --check прогнал сам.
  • Full Performance (AC4) не перезапускал — закрыт исполнением в r1/r2 на коде, который не менялся с тех пор; дельта этого раунда (ребейз + baseline-чиcло) не затрагивает горячий путь переключения этажа.
  • npm run invariants — не запускал, геометрия в этом раунде не менялась (К1–К5 не тронуты).
  • pytest tests_backend / HA harness — не запускал, Python не затронут ни в одном коммите материала.
  • Golden (ci:golden) — не перегонял; задача не рисует план иначе и дельта раунда (ребейз + chore) рендера не касается.
  • Английскую версию docs/USER-GUIDE.ru.md/EN — не проверял: видимое поведение задачи не изменилось с r1 (User-Visible: yes сверен с ТЗ ещё в r1), дельта этого раунда — User-Visible: no.

Вердикт

Зелёный. Дельта раунда — ребейз на dev@c4cb0649 (после #762), не менявший содержимое продуктового и тестового кода задачи (проверено построчно), плюс один chore-коммит, поднимающий bundleBytes baseline монолита на величину, которую сам раунд и внёс (ключ этажа + ленивый space-editor). Конфликт ребейза в docs/testing-notes/mutation-browser-guards.md разрешён верно — перепроверено пересчётом фактического вывода mutation-gate --check. Целевой смок задачи перепрогнан на пересобранном бандле точного материала и зелёный. Находок нет. Бюджет циклов остаётся израсходованным на 1 из 4 (унаследовано из r1) — зелёный вердикт цикла не образует.


Материал раунда

  • Ветка: issue/744-floor-geometry-key, коммит 2bcde131581a6130f971dcef167299d6cc1129ad.
  • git rev-parse HEAD на момент ревью: 2bcde131581a6130f971dcef167299d6cc1129ad.
  • Вердикт: green · High 0 · Medium 0 · маршрут fix.

Материал раунда

  • Ветка: issue/744-floor-geometry-key, коммит 2bcde131581a — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
  • Дерево материала: 0272ec42089ccc881841358169ad6e9105944e7c
    git log --all --format='%H %T' | grep 0272ec42089c
    
  • Тело issue: 9dec80eead95ea0cbc014364d7ed09eaef1f7f45b7e2c70f97f1a95c586ac465
  • Вердикт конвейера: green · High 0 · маршрут fix