# SPEC-REVIEW-159-r2 - **Issue:** https://github.com/Matysh/houseplan-card/issues/159 - **ТЗ под ревью:** [`docs/specs/159-furniture-pack.md`](https://github.com/Matysh/houseplan-card/blob/issue/159-furniture-pack/docs/specs/159-furniture-pack.md), commit `d3d18b1b`, обычный трек (не `small`/`trivial`) - **Роль:** ревьюер ТЗ (не автор), этап `S4-spec-review` - **Лимит циклов:** обычный трек — 4 (PROCESS.md §4) - **Заход:** r2 · блокирующих циклов израсходовано 1/4 (r1 — жёлтый) **Примечание к номеру захода.** Метаданные задачи, переданные этому ревью, называли текущий прогон «заход r1 · 0/4». Это не совпадает с фактическим состоянием issue: в `docs/reviews/SPEC-REVIEW-159-r1.md` (ветка `issue/159-furniture-pack`) уже лежит завершённый жёлтый вердикт на commit `a9d4d9e6`, за ним следуют комментарии автора о его исправлении и явная фраза «Повторно передаю на ревью по дельте r2» (issue comment `#5454091450`). Согласно PROCESS.md §2.10 п.1, ненайденный/неверный SHA/номер раунда — находка сама по себе; здесь она отражает несогласованность метаданных конвейера с историей issue, а не дефект ТЗ. Ниже раунд посчитан по фактам issue: **r2**, бюджет **1/4**. ## Скоуп ревью Второй цикл ревью ТЗ #159. Предмет раунда — дельта `git diff a9d4d9e6..d3d18b1b -- docs/specs/159-furniture-pack.md`, то есть точечное исправление двух находок r1 (провенанс/лицензия 77 SVG и внутренняя нестыковка формулировки бюджета ≤18 KiB). Остальной текст ТЗ (сценарий, скоуп, каталог совместимости, UX-контракт, модель данных, i18n, AC2–AC7, AC9, план автотестов, риски, откат) дельту не затрагивает и наследуется из r1 без повторной проверки — см. раздел «Унаследовано из r1». Продуктовый код по-прежнему отсутствует на ветке — гейты (`typecheck`/`test`/ `build`) вне скоупа этапа ревью ТЗ (PROCESS.md §2.4/§8), как и в r1. ## Закрытие раунда r1 | Находка r1 | Чем закрыта | Где это видно | |---|---|---| | **High-1** — провенанс/лицензия 77 SVG опирались на комментарий `#issuecomment-5449707137` (`nikitaevfz-commits`, `authorAssociation: NONE`), который не содержал ни слова об авторстве или лицензии | Спец теперь цитирует **другой**, реальный комментарий владельца — `#issuecomment-5454085168` — и AC1/Scope переписаны под этот источник | Diff `docs/specs/159-furniture-pack.md` строки 42–46 и AC1 (см. ниже); сам комментарий получен напрямую через `gh api repos/Matysh/houseplan-card/issues/159/comments`: `author_association: OWNER`, `login: Matysh`, текст «Я являюсь автором всех 77 SVG из архива `houseplan-furniture-custom-0.3.0` и разрешаю House Plan использовать, изменять и распространять их на условиях MIT License репозитория без обязательной отдельной атрибуции в интерфейсе» — дословно то, что цитирует ТЗ | | **Medium-1** (в скоупе) — раздел «Производительность и bundle» описывал 18 KiB как *цель* с эскейп-хэтчем («пересогласовать продуктовую цену»), а AC8 — как обычный жёсткий критерий; противоречие оставляло код-ревью выбор из двух несовместимых трактовок | Раздел переписан: «Это блокирующий критерий задачи: при превышении реализация упрощает представление и повторяет замер. Поднять общий budget или принять превышение в #159 нельзя; иное решение требует отдельного изменения ТЗ и нового ревью до реализации» — эскейп-хэтч убран, формулировка теперь совпадает по смыслу с AC8 | Diff строки 247–253 (раздел «Производительность и bundle»); текст AC8 (строки 302–306 текущей редакции) не менялся и с новой формулировкой раздела больше не противоречит | | **Low-1** (снят с запиской в r1, без обязательства править) — непоследовательное форматирование метода доказательства в заголовке AC6 (`` `unit` ``, smoke без кавычек) | Не исправлено — и не требовалось: r1 явно снял находку без действия | Текущий текст: `### AC6 — локализации (`unit`, smoke)` — то же форматирование, что и в r1; расхождение с решением r1 отсутствует | Обе блокирующие/скоуп-находки закрыты по существу, а не заявлением автора: цитата теперь ведёт на комментарий, реально содержащий заявленный факт (и с верным `author_association`), а формулировка бюджета больше не допускает двух прочтений. ## Как проверялось (дельта r2) 1. Найден вердикт r1 и SHA, на котором он получен: `docs/reviews/SPEC-REVIEW-159-r1.md` на ветке `issue/159-furniture-pack`, зафиксированный на commit `a9d4d9e6` (сам документ называет SHA явно — в отличие от комментария-вердикта в issue, где SHA не назван; это отдельно отмечено выше). 2. Дельта объявлена и получена: `git diff a9d4d9e6..d3d18b1b -- docs/specs/159-furniture-pack.md` (полный diff воспроизведён выше построчно). 3. Прочитаны все комментарии issue между r1 и r2: реакция владельца на High-1 (запрос явного публичного заявления), собственно заявление владельца, финальный комментарий о закрытии обеих находок и передаче на ревью «по дельте r2». 4. Заявление-источник (`#issuecomment-5454085168`) получено напрямую через `gh api repos/Matysh/houseplan-card/issues/159/comments` (не через кэш `gh issue view`), проверены поля `author_association` (`OWNER`) и `login` (`Matysh`) — ссылка в ТЗ ведёт ровно на этот комментарий и текст совпадает дословно. 5. Перепроверен AC1 целиком (единственный AC, чья формулировка изменилась дельтой): текст остаётся однозначным и доказуемым — код-ревью сможет проверить (а) наличие публичного подтверждения по указанной ссылке, (б) что vendored source соответствует зафиксированному архиву, (в) что `--check` подтверждает свежесть двух generated каталогов. Три независимые, проверяемые части, ни одна не требует веры автору на слово. 6. Перепроверен раздел «Производительность и bundle» и его согласованность с AC8 (единственная другая точка, которую задело дельтой): новая формулировка убирает альтернативный путь «пересогласовать цену» и явно называет 18 KiB блокирующим критерием с единственным разрешённым выходом при превышении (упростить и переизмерить) — совпадает с буквальным прочтением AC8. Дополнительно проверено текущее состояние гейта: `dist/houseplan-assets.json` на `HEAD` (`78c60207`, до этой задачи) показывает `initialViewGzipBytes: 256828` против потолка `INITIAL_VIEW_GZIP_BUDGET = 282000` (`scripts/bundle-budget.mjs`) — то есть текущий запас ~25 KiB; бюджет задачи в 18 KiB для 44 SVG действительно тесен, но это риск реализации, явно описанный и обработанный самим ТЗ («реализация упрощает представление и повторяет замер»), а не дыра в тексте. 7. Проверена новая секция «Продуктово-правовое решение» — не вводит новых утверждений сверх уже проверенного пункта 4, корректно резюмирует закрытие правового вопроса и не оставляет открытых пунктов. 8. Проверено, что дельта не затронула ни один другой раздел ТЗ (сценарий, scope/не-scope, каталог совместимости, контракт UX, рендер/безопасность, модель данных, generation/source of truth, i18n, план автотестов, риски, откат, блок «принято предположительно») и, соответственно, ни один другой AC (AC2–AC7, AC9) — их доказательства дельта не задевает, они наследуются из r1 без повторной проверки. 9. Оценено, является ли дельта локальной по критериям §2.10: рёбейза на ушедший вперёд `dev` не было (ветка короткоживущая, `dev` за время цикла не продвигался в части, задевающей это ТЗ); контракт поведения не менялся (провенанс — не поведение, порог bundle — тот же порог, только однозначно сформулированный); новая подсистема не затронута; объём дельты (~20 строк из 375) несопоставим с объёмом задачи. Разбор по дельте — корректный объём для этого раунда. ## Унаследовано из r1 Все находки и разделы ниже приняты из `docs/reviews/SPEC-REVIEW-159-r1.md` (commit `a9d4d9e6`) без повторной проверки — дельта r2 их не касается: - Соответствие §7.1: все обязательные разделы присутствуют, включая оба продуктовых (сценарий/персона, «что увидит»). - Арифметика каталога (18 replace + 12 retained = 30 прежних; +26 add = 56) сверена построчно с `src/furniture.ts`/`FURNITURE_GROUPS` и `docs/FURNITURE.md` §3. - Технический план (generated TS вместо runtime SVG import, раздельные plan-art/menu-art графы, `--check` детерминированность) обоснован архитектурой `houseplan-editor-runtime.ts` и правилом «no user markup in config» из `docs/FURNITURE.md` §9. - Цитата про backend forward-compatibility (символ не проверяется по closed-list) дословно совпадает с `docs/FURNITURE.md` §8. - Модель данных: persisted schema не меняется, соответствует `docs/CONFIG-COMPATIBILITY.md`. - Не-скоуп корректно исключает то, что уже запрещено `docs/SCOPE.md`. - Двухуровневая палитра «категории → варианты» укладывается в принцип context tray из `docs/UX-MODES.md`, не изобретает новый паттерн навигации. - Решение «даже категория с одним вариантом проходит второй экран» помечено как предположение, подлежащее оспариванию ревьюером, — процесс соблюдён; в r2 это решение не переоценивалось повторно. - Трассируемость issue ↔ ТЗ двусторонняя (`docs/specs/README.md:126`). - AC2–AC7, AC9 однозначны, у каждого назван метод доказательства; текст этих разделов дельтой не менялся. ## Находки (r2) Ни одной новой находки High/Medium. Обе находки r1 закрыты по существу (см. таблицу выше). Low-1 из r1 остался в прежнем, сознательно принятом состоянии. ## Что проверено и корректно (дополнительно к унаследованному) - Источник провенанса — теперь настоящий комментарий владельца с верным `author_association: OWNER`, содержащий дословно то заявление, которое ТЗ ему приписывает. - Формулировка бюджета 18 KiB согласована между описательным разделом и AC8; оба места теперь читаются одинаково — как жёсткий блокирующий критерий без альтернативного «мягкого» пути. - Новая секция «Продуктово-правовое решение» не вводит противоречий и не оставляет открытых правовых/продуктовых вопросов. ## Чего не проверял - То же, что не проверялось в r1 (не в скоупе этапа ТЗ): содержимое архива `houseplan-furniture-custom-0.3.0.zip` и все 77 SVG построчно; фактическая величина gzip-прироста; golden/визуальные сцены; юнит/смоук-тесты — кода ещё нет. - Не проверялась подлинность личности `Matysh` как аккаунта владельца за пределами того, что гарантирует GitHub полем `author_association: OWNER` (это тот же уровень доверия, на котором стоит весь процесс — метки и роль ставит только тот, у кого есть право записи). - Не пересчитывался остаток бюджета `bundle:budget` для будущей реализации — указанные 256 828 / 282 000 B взяты из текущего `dist/houseplan-assets.json` на `HEAD` вне этой задачи и приведены только как контекст тесноты бюджета, а не как проверка AC8 (AC8 проверяется в код-ревью после реализации). ## Вердикт High: 0 · Medium: 0 (обе находки r1 закрыты; Low-1 остаётся снятым без правки, как решено в r1). **Зелёный.** ТЗ готово к разработке: провенанс/лицензия 77 SVG теперь опираются на реальное публичное подтверждение владельца с верной `author_association`, а формулировка bundle-бюджета в 18 KiB однозначна и совпадает с текстом AC8. Остальная часть ТЗ (наследуется из r1) остаётся технически выполнимой и проверяемой. `Вердикт: зелёный · заход r2 · блокирующих циклов 1/4 · High: 0 · Medium: 0`