18 KiB
SPEC-REVIEW-532-r2
Issue: #532 · Этап: ТЗ на ревью (S4-spec-review) · Заход r2 · блокирующих циклов израсходовано 0/4 (r1 — зелёный, бюджет не тратит, #227)
Скоуп ревью
Материал — тело issue #532, раздел ## ТЗ, редакция r2 (комментарий автора
«ТЗ r2 — на ревью», 2026-09-11T15:56:10Z). Это не первый заход, но контракт
изменился по существу (К2 переписан, AC3 переписан), поэтому по PROCESS.md
§2.10 разбор веду полным, а не только по находкам r1 — причина: «смена
контракта поведения», один из явных критериев, требующих полного разбора.
Основание: r1 получил зелёный вердикт на К2 «golden останется зелёным»
(комментарий ревьюера от 2026-09-11T15:31:18Z), затем автор сам вернул задачу
в S3-spec, потому что реализация это обещание опровергла (комментарий
«Возврат в S3-spec: К2 опровергнут замером», 15:54:23Z). Это не находка
ревью — обещание опровергла сама реализация, автор зафиксировал это честно и
переписал контракт, не подгоняя факт под старый текст.
Точную дельту r1→r2 получил не из пересказа, а из истории редактирования тела
issue (gh api graphql → Issue.userContentEdits, три снимка: до появления
## ТЗ, редакция r1, редакция r2) и построил diff -u между снимками r1 и r2.
Как проверялось
Читал в порядке из инструкции: docs/SCOPE.md, PROCESS.md (§1–§10.3),
AGENTS.md, тело issue #532 целиком (симптом → замер → аналитика → ТЗ) и все
5 комментариев, docs/SUN.md (канонический документ фона, раздел «Current
four-phase background»). Технические утверждения ТЗ сверял с кодом на дереве
dev@8afba7e6 (рабочая копия):
src/styles/plan.styles.ts:89-96— селектор и стопкаdrop-shadowдословно совпадают с К1/К2 (.stage.daycycle .hp-paperg,.hp-static-stage.daycycle .hp-paperg); правки ещё нет, дерево в состоянии «до» задачи — ожидаемо для стадии ТЗ;demo/golden/matrix.mjs:6— пороги сценыstage:maxChannelDelta: 10,maxDiffRatio: 0.0005, ровно те, о которые разбивается К2 (3.43 % наday-cycle-night-dark— превышение в ~68 раз, как и пишет автор);demo/golden/matrix.mjs:458-472— ровно 4 сцены сbgMode: 'daynight'во всей матрице (day-cycle-{dawn,day,dusk,night}-dark), других нет; отсюда утверждение К2 «никакой другой кадр матрицы измениться не имеет права» проверяемо и заявление АС3 «ровно четыре» структурно верно — играть могут только эти четыре записи;src/glow-blend.ts:61—svgScreenBlendSupportedдействительно рантайм- проба, не читаетbg_mode— подтверждает К4 кодом, а не только измерением (унаследовано из r1, но перепроверил сам, это дёшево);docs/SUN.md:59-86— раздел «Current four-phase background» пока не содержит упоминания композиционного слоя контура: правка AC5 добавляет новую строку, а не противоречит существующей; стиль совпадает с уже имеющимися архитектурными утверждениями раздела (например, про группировку контура «outside the grouped plan-paper footprint»), так что место для этого факта в каноне — правильное;scripts/smoke-select.mjs:1-45—isExecutableFrontendсчитает.ts-файл исполняемым, значитplan.styles.tsинструмент разберёт; но извлекает он символы, а изменённая строка — чистая CSS-декларация (will-change: filter;) без идентификаторов проекта. Заявление риска 5 «селектор честно отвечает «неопределённость»» правдоподобно по механике инструмента (нет символа для точного совпадения, а «filter» как слово слишком частый, чтобы пройтиBROAD_SHARE); автор не выдаёт это за факт, а обещает прогнать и назвать результат в хендоффе — это ровно то, что требует процесс;- проверил, что
demo/smoke_daycycle_raster.mjsиdemo/benchmark_daycycle_raster.mjsв дереве действительно отсутствуют — ТЗ корректно называет свидетеля «создаётся», а не существующим.
Не гонял ни одного гейта: на этапе ТЗ материал — текст, а не код; гейты
исполнимого кода к этому раунду не относятся (кода ещё нет — реализация,
проваленная в предыдущей попытке, не смержена, git log подтверждает: на
dev нет коммита #532).
Находки
Нет. Ни одной блокирующей или требующей правки в скоупе задачи.
Рассмотренные и снятые как небеспроблемные кандидаты (перечисляю, потому что процесс требует не прятать сомнение, а не потому что они стали находками):
- Порог бюджета 2.0 против переизмеренного «здорового» отношения 0.82 — запас всего ~2.44×, у′же, чем на «около восьмикратный» из r1 (там был 0.26). Автор сам скорректировал формулировку риска 4 (убрал «восьмикратный запас», оставил «большой запас») — то есть не скрыл сужение. Порог отмечен как «принято предположительно, менять свободно» — ревьюер вправе спорить, и я не вижу оснований спорить: 2.0 всё ещё далеко и от здорового (0.82), и от больного (15.06) значения, а фактический шум CI будет виден на реальном прогоне свидетеля в код-ревью.
- AC3 экстраполирует порог «сдвиг среднего цвета ≤0.1/255» на все четыре
кадра, хотя пиксельно автор разобрал только
day-cycle-night-dark(сдвиг 0.07) — для остальных трёх есть только «все четыре разошлись» без разбора. Это не догадка, выданная за факт: у AC3 явный красный триггер («пятый разошедшийся кадр либо сдвиг среднего цвета — находка ревью»), значит фактическую проверку для всех четырёх кадров сделает код-ревью на реальном артефакте golden, а не эта редакция ТЗ. Контракт проверяем, а не голословен. .hp-static-stage.daycycle .hp-paperg(houseplan-space-card) получает ту же подсказку, но ни одна сцена матрицы её не использует сbgMode: daynight— по коду это существующий пробел покрытия golden, не появившийся из-за этой задачи и не расширяемый ею;К1 намеренно трогает оба селектора одним правилом, а не только.stage. Не блокирует.- Отложенная пересъёмка эталонов оставляет
dev/nightlygoldenкрасным до коммита на кандидате беты. Это не самодеятельность автора: тот же механизм (Release:+Baseline-Reviewed:,golden:accept --reviewed) уже используется в проекте буквально соседним коммитом (f65d07e3 Принять три PDF-эталона, которые изменил #530). Риск назван в ТЗ явно (риск 2), цена не спрятана.
Закрытие раунда r1
r1 (docs/reviews/SPEC-REVIEW-532-r1.md, зелёный, материал — тело issue до
правки 2026-09-11T15:55:49Z) не вернул находок — цикл не был потрачен.
Возврат в S3-spec произошёл не по вердикту ревью, а по решению автора после
того, как собственная реализация опровергла обещание К2. Формально закрывать
нечего, но фиксирую, чем именно старое К2 расходится с новым и почему это не
недоработка автора, а корректная реакция на новый факт:
| Что было в r1 | Что показала реализация | Чем закрыто в r2 |
|---|---|---|
К2: «вид не меняется ни на пиксель сверх порога»; golden обязан остаться зелёным при maxChannelDelta: 10 |
4 кадра day-cycle-*-dark разошлись, day-cycle-night-dark — 3.43 % пикселей, превышение maxDiffRatio в ~68 раз |
К2 переписан: вид не меняется содержательно (ореол снаружи плана байт-в-байт, средний цвет кадра 176.59→176.66), но 4 эталона пересматриваются на кандидате беты |
AC3: «четыре golden-кадра не изменились», проверка — golden:verify на полной матрице |
Тот же прогон красный | AC3 переписан: «изменились ровно четыре, и вот чем» — список кадров + срез ореола + средний цвет; пятый кадр или больший сдвиг — красный |
| Риск 3 (r1): «Golden. Порог сцены 10, кадры обязаны остаться зелёными» | Не подтвердилось | Риск заменён на «Пересъёмка эталонов стоит руки владельца» — цена, а не гарантия |
| Порог бюджета 2.0 на числах 7.9/0.26 (демо-стенд, ховер) | Реальный смок на панораме дал другие абсолютные числа (15.06/0.82) | Числа в «Принято предположительно» обновлены на измеренные смоком, порог 2.0 оставлен — по-прежнему с запасом в обе стороны |
Унаследовано из r1
Без повторной проверки принято на слово из r1 то, чего дельта не касается, но
я всё же перепроверил дешёвые из этих утверждений сам (см. «Как проверялось»)
вместо слепого наследования, так как они стоили пары grep:
- К1 (правило
will-change: filterна связке двух селекторов, ограничено классомdaycycle) — не менялось между r1 и r2 текстуально; перепроверил код (plan.styles.ts:89-96) сам, а не унаследовал. - К3 (четыре слоя окружения вне скоупа) и К4 (экранный блендинг вне
скоупа,
svgScreenBlendSupported— рантайм-проба) — не менялись; К4 перепроверил кодом сам. - К5 (бюджет — отношение, а не абсолютные мс) — не менялся текстуально.
- AC1, AC4 (вычисленный стиль
.hp-papergс/безwill-changeв двух режимах фона) — не менялись по существу (только словесная правка «новый смок» → «смок» и точное число в столбце AC2 вместо оценки «около 8»). - AC5 (документация
docs/SUN.md+ оба changelog) — не менялся. - Продуктовая рамка, скоуп/не-скоуп, откат (кроме добавленной фразы про эталоны) — не менялись.
- Источник:
docs/reviews/SPEC-REVIEW-532-r1.md, материал — тело issue на снимке до 2026-09-11T15:55:49Z (см.userContentEdits, узел 0, деревоdev@116cfd5fна момент r1).
Что проверено и корректно
- Полнота разделов по PROCESS.md §7.1: сценарий и «до/после» — первые в блоке
ТЗ; проблема разобрана выше
## ТЗ(симптом, решающий опыт, замер) и ТЗ на неё явно ссылается; скоуп/не-скоуп — «Чего задача не трогает»; контракт — К1–К5; i18n, миграция, touch — закрыты одним перечислением «не трогает» (bg_modeи его миграции, i18n, touch-контракт); план автотестов и AC — таблица AC1–AC5 с «чем краснеет» у каждого; риски — 5 штук, включая новый; откат — есть; release-артефакты — changelog RU+EN,docs/SUN.md, отдельный коммит эталонов на кандидате беты. - Трек: полный, критерий §5, который задача не проходит, назван явно («нет влияния на производительность»).
- Ни одного продуктового вопроса владельцу не поднято и не нужно: все
открытые места (порог 2.0,
will-change: filtervstransform, permanent vs on-gesture, движок свидетеля) — технические, помечены «принято предположительно, менять свободно», и я как ревьюер с ними согласен по существу (см. «Как проверялось»). - Не найдено ни одной догадки, выданной за факт: там, где вывод не доказан
на 100 % (антиалиасинг штриховки как причина, а не что-то ещё), автор дал
контрольный эксперимент (тот же эффект с
transformвместоfilter) и явный красный триггер в AC3, а не декларацию «это точно так».
Чего не проверял
- Не выполнял ни одного гейта (
typecheck/test/build/golden) — на этой стадии кода нет, гонять нечего; деревоdev@8afba7e6не содержит правки #532 (реализация из провалившейся попытки не смержена). - Не перепроверял сам сырые числа профиля Firefox с машины владельца (объективно недоступны) — принимаю их как входные данные симптома, не как предмет этого ревью.
- Не проверял, действительно ли
will-changeв реальном Gecko владельца будет принят движком (риск 1) — это заявлено и ТЗ, и мной как непроверяемая до реализации/профиля неопределённость, а не блокирующий пробел контракта.
Вердикт
Вердикт: зелёный · заход r2 · блокирующих циклов 0/4 · High: 0 · Medium: 0 → в задаче
Материал раунда
- Ветка:
dev, коммит8afba7e6edb5— ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. - Дерево материала:
2acfb9ec47f68cd0c479f34c772597bb4569e96agit log --all --format='%H %T' | grep 2acfb9ec47f6 - Тело issue:
12e66588332b94c78100156f01e4832881b8163fb6f8fdca83acfcb8e90f4545 - Вердикт конвейера:
green· High 0