mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-30 11:49:16 +00:00
@@ -0,0 +1,166 @@
|
||||
# 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`) явно признана риском с планом на случай провала, а не выдана
|
||||
за решённую. Готово к разработке.
|
||||
|
||||
---
|
||||
|
||||
<!-- material-anchors: сгенерировано конвейером (#414) -->
|
||||
|
||||
## Материал раунда
|
||||
|
||||
- Ветка: `dev`, коммит `116cfd5fefc4` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
|
||||
- Дерево материала: `45453f44ff5e3243d824ab00132e42c14c9f7c33`
|
||||
```
|
||||
git log --all --format='%H %T' | grep 45453f44ff5e
|
||||
```
|
||||
- Тело issue: `b15dfcb6b8488979f9d1b9d85cad33d752f45ce246f228439ebf47e35f7e048a`
|
||||
- Вердикт конвейера: `green` · High 0
|
||||
Reference in New Issue
Block a user