Issue: #579 User-Visible: no
15 KiB
CODE-REVIEW-579-r2
Issue: #579 — «WebView pinch compositor churn»
Материал: 2c7abe7938ded08d63f277269d8b7e52c04e2d4d (диапазон origin/dev..HEAD: продуктовый коммит
216990e4 + служебные документы ревью + тестовый коммит 2c7abe79)
Заход: r2 (разбор по дельте от r1, PROCESS.md §2.9)
Блокирующих циклов израсходовано: 1 из 4 (потрачен r1; зелёный вердикт бюджет не тратит, #227)
Скоуп раунда
r1 (docs/reviews/CODE-REVIEW-579-r1.md, коммит 9bae4d28, вердикт жёлтый на материале
216990e4) закрыл всё, кроме одной находки: M1 — AC4 (матрица day cycle/Glow/room fills/
hatching/фон) не имела тестового доказательства. Между 216990e4 и HEAD лежит ровно один
новый коммит:
2c7abe79 test: cover live viewport effects matrix (#579)
git diff 216990e4..HEAD --stat:
demo/smoke_live_pan_coverage.mjs | 83 ++++++++++++++++-
docs/reviews/CODE-REVIEW-579-r1.md | 182 +++++++++++++++++++++++++++++++++++++
Второй файл — служебный документ самого r1 (класс C, публикация предыдущего раунда), не
материал для разбора. Единственный содержательный файл дельты — demo/smoke_live_pan_coverage.mjs
(класс B). Продуктовый код (src/live-viewport.ts, src/live-interaction-runtime.ts) не тронут:
автор прямо заявляет это в хендоффе, и git diff 216990e4..HEAD -- 'src/**' пуст — проверено.
Дельта локальна: правка только добавляет evidence к уже принятому продуктовому коду, не меняет контракт поведения, не трогает новую подсистему и по объёму (один тестовый файл) несопоставима с исходной задачей. Разбор этого раунда ограничен дельтой и AC4, которую она доказывает; остальные AC унаследованы из r1 (раздел ниже).
Закрытие раунда r1
| Находка r1 | Чем закрыта | Где это видно |
|---|---|---|
| M1 — AC4 (day cycle off/on × Glow off/on × room fills/hatching/фон) не имеет тестового доказательства | Добавлена исполняемая матрица 2×2 в demo/smoke_live_pan_coverage.mjs: configureEffectMatrix() (:161) включает/выключает bg_mode:'daynight'/glow_enabled на существующей fixture с добавленными стенами (space.walls, :406) и контрастным bg_color:'#123456'; effects (:64) снимает dayCycle/glowPools/roomFills/hatchedWalls/customBackground из живого DOM в immediateState и heldState; expected() (внутри runPan, вызывается для effectsDay{0,1}Glow{0,1}, :444-448) требует roomFills>0 && hatchedWalls>0 && customBackground && dayCycle===expected && glowPools соответствует glow в ОБОИХ кадрах |
Я прогнал node demo/smoke_live_pan_coverage.mjs на свежесобранном бандле: все 4 строки матрицы (effectsDay0Glow0…effectsDay1Glow1) дают EffectsVisible:true, и diagnostics показывают реальные значения (hatchedWalls:1, roomFills:1, customBackground:true, glowPools 0/1 согласно строке) — не заглушку |
Унаследовано из r1
Без повторной проверки принято всё, чего дельта не касается — документ
docs/reviews/CODE-REVIEW-579-r1.md (коммит 9bae4d28), выводы получены на дереве материала
09aab0675828 (SHA продуктового коммита 216990e4):
- AC1 (стабильная promotion-сессия), AC2 (бюджет сохранён), AC3 (сцена не пропадает в
представленных кадрах,
continuity:screencast), AC5 (паритет SVG/HTML ≤1px), AC6 (terminal cleanup), AC7 (существующее покрытие края) — доказаны в r1 unit-тестами, двумя мутационными свидетелями (live-pinch-compositor-demoted-on-budget-refresh,live-pinch-compositor-demoted-on-active-lit-commit) иcontinuity:screencast; продуктовый код, который они проверяют, в этом раунде не менялся — доказательства не протухли. - AC8 (нет регрессии управления) —
smoke_editor_gestures,smoke_smooth_zoom,smoke_tap_ctx,smoke_long_press_gesture, все зелёные в r1; ни один из этих смоков не в дельте. - AC9 (производительность) и AC10 (полевой Companion-контроль) — в r1 честно отмечены как предрелизные/beta-приёмка, не гейт ревью; дельта их не касается.
- Находка L1 r1 (AC2 без именованного мутанта, Low, снята с записью) — вне дельты, повторно не поднимаю.
- Трейлеры продуктового коммита
216990e4(Issue: #579,User-Visible: yes, оба changelog), документация (docs/ARCHITECTURE.md,docs/TESTING.md,docs/images/screenshots.json) — приняты в r1, дельта их не трогает.
Как проверялось в этом раунде
Дешёвые гейты уже подтверждены зелёным Validate на 2c7abe79
(https://github.com/Matysh/houseplan-card/actions/runs/34891309797) — typecheck/unit/build
со сверкой бандла перегонять не стал. Диф этого раунда не трогает src/**, поэтому
check-docs.mjs и npm run model-invariants не в скоупе (не требуются самим дифом) и не
перегонялись повторно — вывод r1 по ним не протухает, т.к. они завязаны на src/**, а он не менялся.
Дополнительно к зачёту CI лично прогнал:
| Гейт | Команда | Результат |
|---|---|---|
| Свежая сборка (нужна браузерным смокам — Validate на плейн-push heavy-джобы пропускает) | npm run bundle:sync |
зелёный, tsc --noEmit в составе build тоже прошёл |
smoke-select по дифу |
node scripts/smoke-select.mjs --base 216990e4 --head HEAD |
«Исполняемого frontend-диффа нет» — ожидаемо, дельта не трогает src/**; сам изменённый смок разбираю напрямую, это он и есть предмет дельты |
| Изменённый смок | node demo/smoke_live_pan_coverage.mjs |
OK, все 65 именованных проверок true, включая 20 новых (effectsDay0Glow0…effectsDay1Glow1 × ImmediateCoverage/HeldCoverage/UsesTemporaryOverflow/TargetStableWhileHeld/EffectsVisible) |
| Селекторы матрицы против реальной разметки | чтение src/houseplan-card.ts, src/glow-scene.ts, src/day-cycle-render.ts, src/space-render.ts |
.wallbody:not(.solid)[fill^="url("] (:9549-9551), .room.filled (:11666), .glowlayer .glow-pool (glow-scene.ts:606-615), .hp-day-cycle-env .hp-day-cycle-bg.active (day-cycle-render.ts:32-38) — все классы существуют в текущем рендере ровно с этими именами, не выдуманы под тест |
| Дисциплина «тест умеет падать» для изменённого файла | node scripts/mutation-gate.mjs --id=live-pinch-compositor-demoted-on-active-lit-commit |
«заявленный тест покраснел на мутанте», поймано 1/1 — подтверждает, что изменённый смок остался работоспособным guard'ом после правки, не просто не упал по случайности |
Не прогонял: полный demo/smoke_*.mjs (дельта не в src, smoke-select ничего не выбирает,
кроме самого изменённого файла, который прогнан напрямую); golden:verify (дельта не трогает
рендер-код, только тестовую fixture, и golden уже зелёный в r1 на продуктовом коммите);
python -m pytest tests_backend (диф не касается custom_components/**/*.py);
npm run model-invariants (диф не трогает геометрию/layout/marker.space); performance-профиль
(AC9 остаётся предрелизным гейтом, дельта его не касается); мутант
live-pinch-compositor-demoted-on-budget-refresh (его guard — test/live-viewport.test.mjs, не в
дельте, не перезапускал).
AC → доказательство в этом раунде
| AC | Доказано | Чем краснеет |
|---|---|---|
| AC4 эффекты не отключаются | demo/smoke_live_pan_coverage.mjs, матрица effectsDay{0,1}Glow{0,1} (:406-448), я прогнал — зелёный, значения реальные (не 0/false по умолчанию) |
expected() (внутри runPan) красит *EffectsVisible, если roomFills/hatchedWalls/customBackground пропадут или glowPools/dayCycle не совпадут с ожидаемым состоянием строки матрицы; отдельного MUTANT_DEFINITIONS-контрпримера на этот конкретный assert нет — это тот же класс пробела, что уже был снят как Low (L1, AC2) в r1 для соседнего assert'а того же файла, не новая находка |
Все остальные AC — см. «Унаследовано из r1».
Что проверено и корректно
- Матрица переиспользует уже существующую shared-fixture «coverage-room» (
space.rooms/space.settings, настраивается один раз перед всемиrunPan-сценариями файла), а не заводит отдельный конфиг —configureEffectMatrixклонируетcard._serverCfgи правит толькоsettings, не трогаяrooms/walls. Это единственная точка, где дельта расширяет уже используемый другими (не относящимися к #579) проверками в этом же файле объект: добавлениеspace.walls(:406) поначалу выглядит риском регрессии для более ранних проверок этого же файла (flatMouseRightEdgeи т.п., они используют ту же комнату) — прогон подтвердил, что все 45 pre-existing проверок остались зелёными; стены добавлены только для получения штриховки, сама fixture раньше стен не имела вовсе. _cfgEpoch++после подмены_serverCfg— не изобретённый в тесте API: то же поле и тот же паттерн инкремента уже используется продуктовым кодом (src/houseplan-card.ts:3294) для инвалидации кеша по конфигу.- Трейлеры нового коммита корректны:
Issue: #579,User-Visible: no— коммит меняет толькоdemo/**(класс B), продуктовое поведение не меняет, changelog не требуется. - «Одно число — один источник»: дельта не добавляет и не меняет пользовательски видимую величину (тестовые ассерты, не UI) — неприменимо.
Чего не проверял и почему
- Полный набор
demo/smoke_*.mjs— дельта не вsrc/**, единственный связанный с изменением смок прогнан напрямую. golden:verify,model-invariants,pytest tests_backend, performance-профиль — не в скоупе дельты (см. таблицу выше), их выводы из r1/из состоянияsrc/**не протухли.- Физический прогон HA Companion (AC10) — вне окружения ревью, остаётся beta-приёмкой (унаследовано из r1, дельта не меняет это решение).
Вердикт
Единственная находка r1 (M1, Medium в скоупе) закрыта исполняемым доказательством: селекторы матрицы проверены чтением реального рендера и совпадают, прогон смока даёт нетривиальные (не default-false/0) значения по всем 4 строкам, а изменённый файл остаётся рабочим mutation-guard'ом для уже принятых в r1 находок AC1/AC6. Новых High или Medium находок в дельте не найдено. Зелёный.
Материал раунда
- Ветка:
issue/579-webview-pinch-compositor, HEAD2c7abe7938ded08d63f277269d8b7e52c04e2d4d. - Продуктовый коммит остаётся
216990e469f2d123a81c03e99cdcb315ed756be0(не менялся с r1). - Предыдущий документ:
docs/reviews/CODE-REVIEW-579-r1.md, коммит9bae4d283a6156e39912e9c909c7afb7d59fa518, вердиктyellow, High 0, Medium 1.
Материал раунда
- Ветка:
issue/579-webview-pinch-compositor, коммит2c7abe7938de— ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. - Дерево материала:
723a78780b711457d23f95da0e1753e55361211agit log --all --format='%H %T' | grep 723a78780b71 - Тело issue:
4545e4010a0a0d13588d41c73912f543b83f5091653de15127390b77630498a0 - Вердикт конвейера:
green· High 0