From 41ae5e99868db27e3bfde9a40426c0a636c374bd Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Fri, 11 Sep 2026 17:12:06 +0000 Subject: [PATCH] docs: review document for #532 Issue: #532 User-Visible: no --- docs/reviews/CODE-REVIEW-532-r2.md | 181 +++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 docs/reviews/CODE-REVIEW-532-r2.md diff --git a/docs/reviews/CODE-REVIEW-532-r2.md b/docs/reviews/CODE-REVIEW-532-r2.md new file mode 100644 index 00000000..5f0efe66 --- /dev/null +++ b/docs/reviews/CODE-REVIEW-532-r2.md @@ -0,0 +1,181 @@ +# CODE-REVIEW-532-r2 + +Вердикт: **зелёный** · заход r2 · блокирующих циклов израсходовано 1 из 4 · High: 0 · Medium: 0 + +Материал: `1cfe7fa53c71b2ba595c92d1bdfc560f90242f40`. Ветка приведена к `dev` +конвейером: поверх головы задачи (`a89bd1b8`, тот же коммит, что автор назвал +хендоффом r2) легло 7 коммитов `dev` (релиз v1.74.0 и посторонняя задача +#533), ветка перемотана на `a89bd1b8 → 1cfe7fa5`. Это другой код по §7.2 — +разбор ниже полный, а не только по дельте, хотя `origin/dev..HEAD` содержит +всего 3 коммита самой задачи. + +## Скоуп + +Issue #532 (не изменился с r1): тройной `drop-shadow` внешнего контура плана +(`.hp-paperg`) жил в общем композиционном слое с планом, поэтому любая +перерисовка плана (ховер, панорама) заново прогоняла три прохода размытия по +габариту всего листа — в Firefox владельца ~9 к/с, 23 МБ текстур/кадр. Правка: +`will-change: filter` на `.stage.daycycle .hp-paperg, .hp-static-stage.daycycle +.hp-paperg`, уводящее отфильтрованную бумагу в свой слой. Побочный эффект +контракта (К2, принят спек-ревью r2): промоушен делит SVG на два слоя, отчего +диагональная штриховка стен антиалиасится иначе — 4 golden-кадра +`day-cycle-{dawn,day,dusk,night}-dark` расходятся и пересматриваются отдельным +коммитом на кандидате беты. Продуктовая рамка (View-режим как продукт для двух +персон, `docs/SCOPE.md`) не тронута этим раундом — перечитал `SCOPE.md`, +вывод не изменился. + +Раунд r2 — это ровно исправление двух Medium-находок r1: оба чейнджлога и +`docs/SUN.md`. Продуктовый код (`src/styles/plan.styles.ts`), смок +(`demo/smoke_daycycle_raster.mjs`) и мутант (`scripts/mutation-gate.mjs`) +байт-в-байт не изменились с r1 — доказано ниже, не заявлено. + +## Что изменилось между r1 и HEAD (доказательство байт-в-байт для остального) + +``` +git diff bb04f8605f9003c0ec6643359fa47af9319247bc ced9b416 -- \ + src/styles/plan.styles.ts demo/smoke_daycycle_raster.mjs \ + scripts/mutation-gate.mjs docs/images/screenshots.json +``` +→ пустой вывод: коммит `ced9b416` (содержимое головы задачи после ребейза) +идентичен коммиту `bb04f8605f90`, который разобрало r1, по всем файлам кроме +самих чейнджлогов/`SUN.md`. Единственный новый коммит раунда — +`1cfe7fa53c71b2ba595c92d1bdfc560f90242f40` («Say what the day-cycle layer +change does to the picture...»), и он трогает только `docs/CHANGELOG.md`, +`docs/CHANGELOG.ru.md`, `docs/SUN.md` (14 строк, `User-Visible: no`). + +Это не молчаливое доверие: равенство деревьев проверено мной командой выше, а +не взято со слов автора. + +## Как проверялось + +Validate на `1cfe7fa5` зелёный +(https://github.com/Matysh/houseplan-card/actions/runs/34625301309) — +`tsc`, `npm test`, `npm run build`+сверка бандла, `check-docs.mjs` не +перегонял отдельно, кроме случаев ниже. + +Прогнал сам (диф трогает рендер CSS через `ced9b416`, хоть и унаследованный +от r1 — golden/смок/мутант не покрыты Validate): + +| Гейт | Команда | Результат | +|---|---|---| +| Сборка + синхронизация 3 копий бандла | `npm run build && npm run bundle:sync` | чисто, `git status` пуст после — рабочее дерево воспроизводит закоммиченный `dist`/`custom_components/houseplan/frontend`/`demo/srv/assets` побайтово | +| Смок-свидетель | `node demo/smoke_daycycle_raster.mjs` | OK, 8/8 (`ratio: 0.78`, другая машина, тот же порядок, что у автора 0.73–0.82) | +| Мутант | `node scripts/mutation-gate.mjs --id=daycycle-outline-not-promoted` | «тест покраснел, как обязан» — поймано 1 из 1, рабочее дерево осталось чистым после | +| Три копии бандла | `diff -q dist/houseplan-card.js custom_components/houseplan/frontend/houseplan-card.js` + `houseplan-assets.json` | идентичны | +| `check-docs.mjs` | `node scripts/check-docs.mjs` | passed (7 files, 12 external links) | + +Golden-матрицу (169 сценариев) и построчный анализ 4 кадров дневного цикла +**не перегонял** — код, который её результат определяет +(`plan.styles.ts`), байт-в-байт тот же, что r1 уже прогнало полностью (ровно +4 `different`, bbox и средний цвет посчитаны для всех четырёх кадров +самостоятельно, см. `docs/reviews/CODE-REVIEW-532-r1.md`). Замена входа +исключена диффом деревьев выше — прогон на неизменных байтах дал бы тот же +результат, а сама матрица не из дешёвых. + +Не прогонял: `pytest tests_backend` (бэкенд не задет), `npm run invariants` +(диффа геометрии/модели/`layout`/`marker.space`/`open_spans` нет — раунд +чисто документационный, а унаследованный код — чистый CSS), performance- +профили Validate (не названы в AC), `smoke-select` заново (диф раунда — доки, +не `src/**`; для унаследованного CSS-диффа r1 уже получило и задокументировало +«НЕОПРЕДЕЛЁННОСТЬ» и обосновало решение не гонять смежные `smoke_glow*`/ +`smoke_discovery_filters` кодом К3/К4 — не переоткрываю). + +## Закрытие раунда r1 + +| Находка r1 | Чем закрыта | Где это видно | +|---|---|---| +| Medium-1: чейнджлоги утверждали «picture is unchanged, to the pixel» / «не изменилась ни на пиксель», что противоречит К2/AC3 (3.3–3.5 % пикселей расходятся) | Коммит `1cfe7fa5` переписал обе записи: «The view is the same: the outline around the plan matches pixel for pixel, and the hatch inside the walls is anti-aliased a shade differently — splitting the layer moves it by a sub-pixel» (и симметрично по-русски) | `docs/CHANGELOG.md:9-12`, `docs/CHANGELOG.ru.md:15-17` | +| Medium-2: `docs/SUN.md` приписывал коэффициент «×15» профилю Firefox, хотя измерен в headless Chromium через CDP | Коммит `1cfe7fa5` разделил источники: «Measured in headless Chromium (CDP tracing, summed `RasterTask`) on a demo-stand pan, that cost about fifteen times…; the owner's Firefox profile that opened #532 showed the same cause as 23 MB of texture uploads per frame and about nine frames per second, without a comparable ratio of its own» | `docs/SUN.md:82-88` | + +Проверил не по заявлению автора, а построчным чтением обоих файлов после +правки (см. выше) — формулировки соответствуют находкам r1 дословно, включая +рекомендованную ревьюером r1 замену «a Firefox window» → «our +Chromium/CI measurement». + +## Унаследовано из r1 + +Без повторного прогона (дорогие гейты), на основании доказанного выше +байт-в-байт равенства `src/styles/plan.styles.ts`, `demo/smoke_daycycle_raster.mjs`, +`scripts/mutation-gate.mjs` между `ced9b416` (голова этого раунда) и +`bb04f8605f9003c0ec6643359fa47af9319247bc` (материал r1): + +- AC1/AC2/AC4 (подсказка стоит только под `.daycycle`, отношение растеризации + ≤ 2.0, статичный фон не платит) — доказаны в r1 смоком + мутантом; я + независимо перепрогнал оба на текущем SHA (таблица выше) вместо чистого + наследования. +- AC3 количественно (полная golden-матрица 169 сценариев: ровно 4 + `different`; средний цвет и bbox расхождения посчитаны r1 лично для всех + четырёх кадров `day-cycle-*-dark`, не только `night-dark`; семь «шумных» + кадров подтверждены контролем на базе `origin/dev` тем же Chromium) — + наследую без повторного прогона матрицы, см. документ + `docs/reviews/CODE-REVIEW-532-r1.md`, SHA `bb04f8605f9003c0ec6643359fa47af9319247bc`. +- Структурные факты кодом: `demo/golden/matrix.mjs` содержит ровно 4 сценария + с `bgMode: 'daynight'`; `svgScreenBlendSupported` (`src/glow-blend.ts`) не + читает `bg_mode` (К4 вне скоупа подтверждено кодом); `.hp-paperg` — только + бумажные силуэты (`src/houseplan-card.ts`), не меняется на ховере/панораме. + Файлы не изменились с r1 — наследую вывод. +- Риск 5 ТЗ (`smoke-select` не находит связь для чисто-CSS диффа) — + подтверждён независимо в r1, код не изменился — наследую. +- Трейлеры и три копии бандла коммита `ced9b416` (`Issue: #532`, + `User-Visible: yes`, оба чейнджлога в одном коммите с поведением) — уже + проверены в r1 и не менялись; коммит `1cfe7fa5` несёт свои корректные + трейлеры (`Issue: #532`, `User-Visible: no` — меняется только формулировка, + не поведение), проверено мной заново. + +## Что проверено и корректно (этот раунд) + +- Оба чейнджлога и `docs/SUN.md` больше не содержат ни одного из двух + утверждений, отмеченных r1 как противоречащих контракту задачи; новые + формулировки проверяемы читателем и не смешивают источники чисел. +- `1cfe7fa5` несёт `Issue: #532` и `User-Visible: no` — корректно: меняется + только текст о поведении, не само поведение. +- Рабочее дерево после `npm run build && npm run bundle:sync` совпадает с + закоммиченными `dist/**`, `custom_components/houseplan/frontend/**`, + `demo/srv/assets/**` побайтово (`git status` пуст) — сборка воспроизводима + на этом SHA. +- `docs/images/screenshots.json` не менялся в этом раунде (проверено диффом + дерева) — отпечаток документации не поехал. +- Продуктовый вопрос автора из хендоффа r1 («приемлема ли цена пересъёмки 4 + эталонов») закрыт зелёным спек-ревью r2 и не переоткрывается: этот раунд не + трогает К2/AC3 по существу, только их описание в публичных доках. + +## Чего не проверял + +- `pytest tests_backend` — `custom_components/**/*.py` не задет. +- `npm run invariants` — геометрия/модель/`layout`/`marker.space`/ + `open_spans` не задеты; унаследованный код — чистый CSS без геометрии. +- Полная golden-матрица заново — код, который её результат определяет, не + изменился (доказано диффом деревьев); повторный прогон на тех же байтах не + добавляет информации, а гейт дорогой. +- Performance-профили Validate — не названы в AC. +- `smoke-select` заново — диф раунда лежит только в `docs/**`, инструмент по + документации не разрешает связей; для унаследованного CSS-диффа ответ r1 + («НЕОПРЕДЕЛЁННОСТЬ») не переоткрываю. +- Приговор по настоящему Firefox (профиль владельца до/после этой конкретной + правки текста) — вне возможностей код-ревью и не AC этой задачи. + +--- + +**Материал раунда:** SHA `1cfe7fa53c71b2ba595c92d1bdfc560f90242f40`, +`origin/dev..HEAD` = 3 коммита (`ced9b416` — голова задачи после ребейза, +байт-в-байт равна материалу r1; `3322c20c` — публикация документа r1; +`1cfe7fa5` — исправление по r1, единственный содержательный коммит раунда). +Полный разбор по указанию конвейера (ребейз через 7 чужих коммитов, §7.2), с +опорой на доказанное byte-for-byte наследование дорогих гейтов из r1. + +**Предыдущий раунд:** `docs/reviews/CODE-REVIEW-532-r1.md`, вердикт жёлтый, +материал `bb04f8605f9003c0ec6643359fa47af9319247bc`. + +--- + + + +## Материал раунда + +- Ветка: `issue/532-daycycle-raster`, коммит `1cfe7fa53c71` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. +- Дерево материала: `0da2d90f30f9e607782d065fe23fc1e770c7e676` + ``` + git log --all --format='%H %T' | grep 0da2d90f30f9 + ``` +- Тело issue: `12e66588332b94c78100156f01e4832881b8163fb6f8fdca83acfcb8e90f4545` +- Вердикт конвейера: `green` · High 0