Files
houseplan-card/docs/reviews/SPEC-REVIEW-532-r1.md
2026-09-11 15:31:27 +00:00

15 KiB
Raw Permalink Blame History

SPEC-REVIEW — issue #532 · заход r1

Скоуп ревью

Issue #532, полный трек (владелец назвал нарушенный критерий §5: «нет влияния на производительность» — задача целиком о нём). ТЗ живёт в теле issue под заголовком ## ТЗ (решение #517); ревью — этот документ, не комментарий, как и положено полному треку. Раунд первый: git log --oneline origin/dev..HEAD для #532 пуст, кода ещё нет — предмет ревью строго текст ТЗ и его согласованность с текущим состоянием репозитория (dev@116cfd5f).

Материал: тело issue #532 (разделы до ## ТЗ — симптом и замер S1; раздел ## ТЗ — собственно спецификация; ## Состояние при заведении — метаданные заведения) и два комментария («Аналитика (S2)», «ТЗ готово — на ревью (S3→S4)»). Устных пояснений автора не запрашивалось.

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

  1. Прочитаны docs/SCOPE.md, AGENTS.md, PROCESS.md §2.3/2.4/7.1/7.2/§4, docs/SUN.md (раздел «Current four-phase background»).
  2. Каждое техническое утверждение ТЗ сверено с текущим кодом, а не принято на слово:
    • grep по src/styles/plan.styles.ts подтвердил дословно селектор К1 — .stage.daycycle .hp-paperg, .hp-static-stage.daycycle .hp-paperg со стопкой из трёх drop-shadow и transition: filter 1100ms … (строки 89–96), плюс дубль в @media (prefers-reduced-motion: reduce) (100–101). Ровно то место, куда К1 просит добавить will-change: filter.
    • grep по src/space-render.ts/houseplan-card.ts подтвердил, что класс daycycle навешивается только когда dayCycle вычислен (т.е. только при bg_mode: 'daynight') — это подтверждает АC1/AC4 («при статичном фоне — не несёт, и filter тоже отсутствует»): без класса .daycycle селектор К1 не совпадает вовсе, значит ни filter, ни будущий will-change не применятся.
    • demo/golden/matrix.mjs подтвердил дословно цифры К2: сценарии day-cycle-{dawn,day,dusk,night}-dark используют пресет stage — { maxChannelDelta: 10, maxDiffRatio: 0.0005 } (строка 6) — именно то, что ТЗ называет действующим порогом.
    • src/glow-blend.ts подтвердил утверждение К4: svgScreenBlendSupported — рантайм-проба, не читающая bg_mode; довод «свет не зависит от фона» обоснован кодом, а не только измерением.
  3. Проверены на однозначность и способ доказательства все AC1–AC5 (таблица ниже), включая то, умеет ли названный мутант/проверка отличить сломанную защиту от рабочей — насколько это можно оценить до появления теста.
  4. Сверены обязательные разделы §7.1 с текстом ТЗ (таблица ниже).
  5. Проверено разделение «продуктовый вопрос / техническое решение» (§7.1, владельцу — только о том, что видит и делает человек).

Гейты (typecheck/test/build) не запускались: на этой стадии нет кода #532 — git log --oneline origin/dev..HEAD для ветки задачи пуст, дерево ровно на 116cfd5f. Прогонять их нечего — это забота код-ревью следующего этапа.

Проверка обязательных разделов ТЗ (PROCESS.md §7.1)

Раздел §7.1 Есть в ТЗ Где
Сценарий (персона/поверхность/момент) да «Продуктовая рамка»: домочадцы и админ в View, настенный планшет/телефон/десктоп, сам план
Что человек увидит до/после да «До.»/«После.»
Проблема да (фактически) абзац «До.» плюс разделы до ## ТЗ (Симптом, замер аналитики) — единый контекст issue, а не выдумка
Скоуп и не-скоуп да К1 задаёт единственную правку; «Чего задача не трогает» — явный не-скоуп
Контракт поведения да К1–К4
UX да (в виде «нет») «Ни одной новой настройки, ни одного нового элемента интерфейса»
Модель данных и миграция да (в виде «нет») «не трогает: … bg_mode и его миграции»
i18n да (в виде «нет») «не трогает: … i18n»
AC1…ACn с доказательством да таблица «AC и доказательства», у каждого — «чем доказан»/«чем краснеет»
План автотестов да новый смок demo/smoke_daycycle_raster.mjs, его регистрация в smoke-links.mjs/check-inputs.mjs, мутант в mutation-gate.mjs — раздел «Затронутые файлы»
Риски да 4 риска, включая главный технический (бюджет will-change в Gecko) с планом на случай провала
Откат да одна строка — ревёрт декларации
Release-артефакты да оба changelog, docs/SUN.md, golden:verify (AC3)

Все обязательные разделы присутствуют по содержанию. Формально «Продуктовая рамка» идёт не первым текстом под ## ТЗ (перед ней — строка автора, раздел «Документация» и «Чего задача не трогает») — §7.1 хочет продуктовые разделы первыми. Содержательно это ни на что не влияет: у issue нет предыстории, которую скрывают, здесь просто иной порядок изложения. Low, не блокирует, не записываю отдельной находкой.

Проверка AC на однозначность и доказуемость

AC Однозначен? Доказательство названо? Комментарий
AC1 да — getComputedStyle даёт will-change: filter да/нет, filter присутствует/отсутствует, по двум значениям bg_mode да, demo/smoke_daycycle_raster.mjs, часть 1 падает от мутанта daycycle-outline-not-promoted» — правдоподобно: он снимает декларацию, getComputedStyleперестаёт видетьwill-change`
AC2 да — числовой порог «не больше чем вдвое», отношение, а не абсолютные мс да, тот же смок, часть 2, CDP-трасса RasterTask заявленный запас (0.26 против порога 2.0, и 7.9 без правки) восьмикратный в обе стороны — порог не хрупкий
AC3 да — 4 конкретных golden id да, npm run golden:verify пороги сверены с matrix.mjs, совпадают
AC4 да, но по факту вторая половина AC1 да не дефект, просто разнесено на два номера ради «краснеет» на другой мутации (декларация без .daycycle)
AC5 да — два конкретных факта (текст в SUN.md, обе строки changelog) да, «ревью кода построчно» — допустимый способ доказательства для документных AC —

Ни один AC не сформулирован как решение-без-обоснования: пороги (2.0; 7/255 канала; 2% шум между прогонами) — измеренные величины из комментария S2, а не придуманные числа, и это видно по совпадению цифр между комментарием и ТЗ.

Проверка «догадка вместо решения»

Отдельный технический раздел «Принято предположительно» правильно отделяет то, что не наблюдает пользователь и что решает автор (will-change: filter vs transform, порог 2.0, движок свидетеля — Chromium, метод замера — CDP RasterTask), от продуктовых утверждений. Ни одно продуктовое утверждение (вид не меняется, новых настроек нет) не подано как факт без основания — оба подтверждены измерением (максимальное отклонение канала 7 при пороге 10) либо тривиальны (правка — одна декларация, интерфейс не трогается).

Главная техническая неопределённость — бюджет памяти will-change в Gecko может молча отклонить подсказку — не скрыта и не выдана за решённый вопрос: она вынесена в Риск №1 с явным планом «если так — задача не закрыта, переходит в К3». Это не относится к продуктовым вопросам владельца (§7.1: только «что видит/делает человек» и «объём видимых изменений») — это инженерная неопределённость стороннего движка, которую нельзя разрешить вопросом, только измерением после реализации. Правильно, что автор сам назвал её ревьюеру третьим пунктом «где спорить», а не спрятал.

Находки

Нет ни одной находки High или Medium. Формальная асимметрия в порядке разделов (см. выше) — Low, не блокирует и не создаёт риска для приёмки; в исправлении не нуждается.

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

  • Все селекторы, свойства и значения, на которые ссылается ТЗ (.hp-paperg, класс daycycle, стопка drop-shadow, transition, golden id и их пороги, источник screenBlend), дословно совпадают с текущим кодом на 116cfd5f — ТЗ не описывает воображаемую версию файла.
  • К3/К4 (слои окружения и блендинг света вне скоупа) обоснованы цифрами из S2-аналитики (13% и «в пределах шума» соответственно), а не решением «на глаз».
  • AC2 использует отношение, а не абсолютные миллисекунды — устойчиво к шуму раннера, восьмикратный запас в обе стороны от порога.
  • Откат — одна строка, соответствует размеру правки.
  • Не-скоуп корректно исключает миграции, i18n, touch-контракт, PDF-сцену — все верно, ни один из них декларация will-change: filter не затрагивает.

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

  • Гейты typecheck/test/build/golden/смоки — нет кода для проверки на этой стадии, дерево #532 пусто относительно dev.
  • Реальное поведение в Gecko/Firefox — по постановке самой задачи, это не предмет автоматических AC, а предмет профиля владельца после реализации («Приёмка по скорости — отдельно»); дать вердикт по нему на этапе спецификации нельзя и не нужно.
  • Существование/содержимое ещё не написанных файлов (demo/smoke_daycycle_raster.mjs, правки mutation-gate.mjs, smoke-links.mjs, check-inputs.mjs) — это работа код-ревью следующего этапа, когда файлы появятся.

Вердикт

Зелёный. ТЗ полное по §7.1, каждый AC однозначен и снабжён способом доказательства и способом падения, технические утверждения проверены по текущему коду и не разошлись с ним, продуктовая рамка и не-скоуп на месте, единственная значимая техническая неопределённость (реакция Gecko на will-change) явно признана риском с планом на случай провала, а не выдана за решённую. Готово к разработке.


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

  • Ветка: dev, коммит 116cfd5fefc4 — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
  • Дерево материала: 45453f44ff5e3243d824ab00132e42c14c9f7c33
    git log --all --format='%H %T' | grep 45453f44ff5e
    
  • Тело issue: b15dfcb6b8488979f9d1b9d85cad33d752f45ce246f228439ebf47e35f7e048a
  • Вердикт конвейера: green · High 0