15 KiB
SPEC-REVIEW-526-r1
Issue: #526 — CSS-комментарии едут пользователю: минификатор шаблонов не снял ~23 КБ пояснений
Этап: ТЗ на ревью (PROCESS.md §2.4), трек — полный (критерий §5, который задача не проходит: «нет влияния на производительность» — подтверждено аналитиком)
Заход: r1 · блокирующих циклов израсходовано 0 из 4 (лимит для полного трека — 4)
Материал: тело issue #526, раздел ## ТЗ, состояние на момент ревью (issue также несёт метки P2, S4-spec-review, tech-debt; ветка задачи ещё не заведена — ожидаемо на этой стадии)
Скоуп ревью
Читается ровно ТЗ из тела issue #526 (не файл — с 2026-09-10 архив docs/specs/ не принимает новых записей, #517). Проверено:
- соответствие
docs/SCOPE.md— задача не создаёт нового продуктового поведения, а сокращает вес initial-чанка, который качает каждый пользователь при первой загрузке карточки. Это прямое улучшение J1 («покажи весь дом сейчас») на всех трёх персонах и особенно ощутимо на планшете-киоске при слабом канале — в скоупе; - обязательные разделы §7.1 — присутствие и полнота;
- однозначность и проверяемость каждого AC (AC1–AC8), включая указанный способ доказательства;
- отсутствие догадки, выданной за факт, вне промаркированного блока предположений;
- корректность выбора трека и согласованность цифр между аналитикой (комментарий S2) и текстом ТЗ.
Как проверялось
- Построчное чтение issue body +
## ТЗцеликом. - Сверка §7.1 PROCESS.md (список обязательных разделов) с фактическими заголовками/абзацами ТЗ.
- Сверка чисел бюджета (300 111 → 287 284 Б gzip; запас 955 → 13 782 Б) между аналитикой автора (комментарий S2, 2026-09-11) и разделом «Производительность и бюджеты» — совпадают, расхождений нет.
- Проверка каждого AC на «может ли тест, названный доказательством, реально упасть» — не запуская код (стадия спецификации, кода ещё нет): для AC1/AC2/AC4/AC6 логика мутации описана и правдоподобна (AC7 явно называет мутант — возврат
code.includes('css\')` — и AC, которое он красит); для AC3/AC5 доказательство — сравнение CSSOM / golden, стандартный и проверяемый метод. - Проверка раздела «Принятые технические предположения» — все три пункта технические (расположение guard, порядок плагинов, отсутствие интерполированных шаблонов сегодня), ни один не подменяет продуктовое решение.
Находки
Medium (в скоупе задачи, чинится в этом же issue)
Отсутствуют оба обязательных продуктовых раздела ТЗ: «сценарий» и «что человек увидит до и после».
PROCESS.md §7.1 называет эти два раздела первыми не случайно: «ТЗ, которое не может ответить на эти два вопроса, описывает работу, а не изменение продукта». В ## ТЗ issue #526 таких разделов нет вовсе — текст сразу переходит к треку, причине бага (эхо аналитики) и контракту К1–К5. Ближайшее по смыслу — раздел «Производительность и бюджеты» («Ожидаемо −12,8 КБ gzip в начальном чанке») — но это описание в терминах реализации (gzip, чанк), а не персона/поверхность/момент и не фраза «что человек увидит» без терминов реализации, как того требует §7.1.
Из остального текста ответ восстановим (это и удерживает находку на Medium, а не на High): персона — любая из трёх (docs/SCOPE.md), поверхность — любая, где грузится карточка, момент — первая (холодная) загрузка бандла, особенно заметно на медленном канале и на планшете-киоске, где заходит второй и третий персонажи из таблицы docs/SCOPE.md. Видимый эффект — новых элементов интерфейса не появляется, план начинает отрисовываться немного быстрее при первой загрузке; на быстром канале эффект неразличим на глаз. Но это восстановление сделал ревьюер, а не автор — ТЗ обязано отвечать на эти два вопроса само.
Воспроизведение: ## ТЗ в теле issue #526, весь раздел от строки «Полный трек. Критерий §5…» до «### Контракт» — ни разу не появляются персона, поверхность или фраза о видимом эффекте без терминов реализации.
Чем чинится: один короткий абзац в начале ## ТЗ в духе — «Сценарий: любая персона (docs/SCOPE.md) на любой поверхности, при первой (холодной) загрузке карточки — особенно заметно на планшете-киоске и медленном канале. Что человек увидит: интерфейс не меняется; план на экране появляется немного быстрее при первой загрузке, на быстром канале разница не будет заметна на глаз.» — без привязки к формулировке, смысл важнее буквы.
Low (снимается с записью)
Раздел «UX» не выделен явно. §7.1 перечисляет UX отдельным обязательным разделом. По содержанию задачи (правка только конвейера сборки, ни одно поведение интерфейса не меняется) ответ тривиален — «нет», и он логически следует из К1–К5 и раздела Touch («Не затрагивается»). Снимаю без возврата автору: добавлять пустую строку «UX: нет» ради формы не даёт нового знания, а содержательного вопроса здесь не остаётся.
Что проверено и корректно
- Причина бага локализована предметно и без гипотез. Отсев в
transformи внутренний сканерminifyStaticCssTemplatesищутcss`(без пробела), а TypeScript-компилятор печатает тег и шаблон через пробел —css `— поэтому минификация не срабатывала ни разу ни для одного файла стилей. Автор подтверждает это инструментированной сборкой (аналитика), а не догадкой. - К1–К5 однозначны и не пересекаются. К1 (распознавание тега с произвольным пробельным разделителем, включая отказ на присоединённых идентификаторах вроде
mycss\``/something.css``) — точная граница словом; К2 (поведение самого минификатора не меняется) правильно замораживает риск только на «какие файлы обрабатываются», а не «как»; К3 (эквивалентность через сравнение CSSOM) — измеримый и не зависящий от реализации критерий; К4 (потолок опускается под факт) числом; К5 явно исключает ленивый граф, перенос чанков и правки самих стилей. - AC1–AC8 проверяемы и у каждого назван способ доказательства (
unit/smoke/golden/мутант/ревью кода), как того требует DoR (§2.5) и сам §7.1. AC4 — явный защитный AC («в бандле нет строк комментариев исходников») со своим мутантом AC7, что на шаг опережает требование §2.7 к код-ревью (таблица «чем краснеет»), а не просто декларирует защиту без свидетеля. - Блок «Принятые технические предположения» промаркирован явно и не содержит продуктовых решений, выданных за факт: все три пункта — расположение guard/порядок плагинов/отсутствие интерполированных
css-шаблонов сегодня — технические и агенты вправе решать их сами (§7.1 «Всё, чего пользователь не наблюдает…»). - Числа согласованы. Значения в разделе «Производительность и бюджеты» ТЗ (287 284 Б, запас 13 782 Б) совпадают с измерениями в комментарии аналитики S2 — одно число, один источник, расхождений нет.
- Откат конкретен и исполним: ревёрт коммита возвращает строгое распознавание тега, минификацию и потолок бюджета к исходному состоянию — без флагов и миграций, что уместно для такой правки.
- Выбор полного трека обоснован явно названным критерием («нет влияния на производительность»), как того требует §5 после инверсии умолчания (#338) — не «обычный трек» без причины.
- i18n/миграция/бэкенд корректно закрыты записью «Ничего» — задача не трогает пользовательский конфиг и данные.
- Release-артефакты названы (AC8: оба changelog +
docs/DEVELOPMENT.md), с трейлеромUser-Visible: yes, что верно для видимого пользователю (хоть и малозаметного) эффекта на размер загрузки.
Чего не проверял
- Не запускал никакой код и не собирал бандл — стадия ТЗ, продуктового кода ещё нет, проверять нечего.
- Не оценивал корректность самого регулярного выражения/парсера для К1 построчно — на этой стадии это техническая реализация, а не продуктовый вопрос; будущий код-ревью обязан убедиться, что AC1 «умеет падать» на реальном мутанте.
- Не проверял
scripts/mutation-gate.mjsи текущий формат его реестра — вне ТЗ, дело код-ревью. - Не запрашивал у владельца ничего: все размытые места (кроме находки выше) — технические, решаемые автором/ревьюером кода без владельца.
Вердикт
Полностью выполненных AC недостаточно, чтобы закрыть ТЗ зелёным: не хватает обязательного продуктового обрамления (§7.1, разделы «сценарий» и «что человек увидит»), которое ревьюер восстановил по контексту, а не нашёл в тексте. Остальное — контракт, AC, риски, откат, треки — сделано аккуратно и без догадок, выданных за решения.
Вердикт: жёлтый · заход r1 · блокирующих циклов 0/4 · High: 0 · Medium: 1 → в задаче
Возврат автору: добавить в начало ## ТЗ абзац сценария и абзац «что человек увидит до/после» (см. находку выше), без изменения контракта, AC или чисел — остальной текст ревью не затрагивает.
Материал раунда
- Ветка:
dev, коммит9609040d312c— ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. - Дерево материала:
6c56dcbd7a046cf3ab745dbe08582ea0b8eb0cfegit log --all --format='%H %T' | grep 6c56dcbd7a04 - Тело issue:
98e0c738d317362cf2f3d9df66835e0d4273addeec1973eb776efff8866a3d10 - Вердикт конвейера:
yellow· High 0