Files
houseplan-card/docs/reviews/SPEC-REVIEW-640-r1.md
T
2026-09-23 15:49:45 +00:00

16 KiB
Raw Blame History

SPEC-REVIEW-640-r1

Скоуп ревью

Этап: ревью ТЗ (PROCESS.md §2.4), трек small. Заход r1, блокирующих циклов израсходовано 0 из 2 (лимит цикла ревью ТЗ на лёгком треке — 2, §5).

Предмет: раздел ## ТЗ в теле issue #640 — точечная замена menu-иконки категории dishwasher («Посудомоечная машина», группа «Техника») в палитре мебели на рисунок из приложенного архива dishwasher.zip, без изменения планового символа, публичного ID, размеров (60×60 см) и любых сохранённых данных.

Материал ревью: тело issue #640 (раздел ## ТЗ) и оба комментария (Оценка: ..., ТЗ добавлено ...) на момент чтения, working tree на f234855e (HEAD detached), продуктовый код не менялся — подтверждено git status (clean) и текстом комментария автора.

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

Продуктового диффа нет (только текст ТЗ в issue), поэтому дешёвые гейты (typecheck/test/build) не запускались — репозиторий не тронут этой задачей на этапе спецификации. Вместо гонки гейтов каждое фактическое утверждение ТЗ сверено с текущим состоянием репозитория:

Утверждение ТЗ Проверка Результат
«остальные 32 menu-иконки» ls assets/furniture/houseplan-0.4.1/svg/menu 33 файла всего, 33−1=32 — совпадает
viewBox 110×110, безопасный menu-контракт (только svg/g/path, svg только viewBox,xmlns, path только d/fill/stroke/stroke-width/stroke-linecap/stroke-linejoin, fill=none, stroke=currentColor, круглые linecap/linejoin) прочитан scripts/generate-furniture-assets.mjs (svgArt(), парсер атрибутов) и текущий dishwasher.svg контракт существует буквально в описанном виде и уже применён к текущему файлу — ТЗ не изобретает требование
группа «Техника», названия ru/en, размеры 60×60, menu_icon: dishwasher прочитан assets/furniture/houseplan-0.4.1/pack.json group: "appliance", name_ru: "Посудомоечная машина", width_cm/depth_cm: 60 — совпадает
«иконки редактора остаются в ленивом editor-графе» прослежен путь decor-image-editor.ts → houseplan-editor-runtime.ts → houseplan-card.ts:720 await import(...) подтверждено: путь до GENERATED_FURNITURE_MENU целиком за динамическим import(), в стартовый граф не входит
golden-сцена furniture-categories-light существует и показывает категории (не единственную) demo/golden/matrix.mjs:619 сцена есть, furniturePalette: 'categories' — показывает плитки категорий, а не один вариант
«новые скриншоты документации не нужны» grep furniture demo/docs/screenshots.mjs — 0 совпадений; единственный сценарий с decor (07-background-editor.png) использует editorTray: 'decor-selection', а это трей выбора объекта декора (_decorSel), не палитра мебели подтверждено — палитра мебели ни в одном сценарии документации не фигурирует
npm run furniture:generate / npm run furniture:check существуют package.json:46-47 оба скрипта определены как заявлено
существующий unit ленивой загрузки для AC3 demo/smoke_furniture_lazy_art.mjs найден подтверждает наличие свидетеля, хотя ТЗ называет его «unit», а по факту это browser-smoke; см. находку Low ниже
нет других мест в src/**, где рисуется/дублируется menu-иконка dishwasher (проверка «одно число — один источник» применительно к арту) grep -r dishwasher src/ только генерированные файлы и i18n-строки (названия, не геометрия); единственный потребитель generated menu-art — decor-image-editor.ts

Дешёвые гейты typecheck/test/build не гонялись — на этапе ТЗ нет продуктового диффа, гонять их не по чему. Ссылка на зелёный Validate из контекста задачи (f234855e) относится к предыдущей задаче (#614) и здесь не переиспользуется как доказательство: доказывать было нечего.

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

Все обязательные разделы присутствуют и в правильном порядке (сценарий и «что человек увидит» — первыми):

  • Сценарий — есть, называет персону (администратор, docs/SCOPE.md), поверхность (редактор подложки, палитра мебели) и момент (перед добавлением предмета);
  • Что человек увидит до/после — есть, без терминов реализации;
  • Проблема/скоуп/не-скоуп — есть, скоуп точен (один файл), не-скоуп явно перечисляет плановый SVG, ID, названия, размеры, сохранённые данные, остальные иконки, backend, i18n;
  • Контракт и UX — есть, технически точен (сверено с кодом, см. таблицу выше);
  • Данные/миграция/i18n/perf/touch — есть, единым абзацем, все пункты закрыты явным «не меняется»/«не нужна»;
  • AC1…AC3 с указанием доказательства — есть, см. разбор ниже;
  • План автотестов — есть;
  • Риски и откат — есть;
  • Release-артефакты — есть, требует правки обоих changelog;
  • Блок принятых предположений — есть, оба пункта в границах технических решений автора, не продуктовых.

Дополнительно ТЗ содержит незаявленный процессом, но уместный раздел «Происхождение и право использования» — фиксирует provenance приложенного архива (сотрудник JustBusiness, право MIT-использования, ранее подтверждено владельцем). Это не догадка: аналитический комментарий тем же автором детализирует содержимое архива (SHA-256, viewBox, отсутствие активного XML) — похоже на результат реального осмотра вложения владельцем, а не предположение, выданное за факт.

Разбор критериев приёмки

  • AC1 («новая menu-иконка», доказательство: unit + golden furniture-categories-light + ревью diff) — однозначен и проверяем: число «32» подтверждено подсчётом файлов, golden-сцена существует и показывает категории. Байтовое сравнение прочих 32 файлов — за автором на этапе кода, тестируемо unit-тестом (сравнение содержимого файлов).
  • AC2 («плановый контракт неизменен») — однозначен, перечисляет конкретные инварианты (файл, ID, группа/категория, ru/en названия, 60×60 см, рендер размещённых объектов), доказательство unit + diff — проверяемо чтением изменённых файлов на код-ревью.
  • AC3 («генерация и загрузка корректны») — перечисляет команды гейтов, существующие в package.json (проверено), и «существующий unit ленивой загрузки» — по факту это browser-smoke demo/smoke_furniture_lazy_art.mjs, не unit-тест. Терминологическая неточность (см. находку Low), не блокирует проверяемость критерия.

Ни один AC не описывает поведение, зафиксированное только предположением автора: каждое числовое или структурное утверждение сверяется с реальным файлом кода или манифеста (см. таблицу выше), а не изобретается.

Находки

Low — AC3 называет browser-smoke «unit»-тестом

Файл: тело issue #640, раздел «Критерии приёмки», AC3. Суть: «Доказательство: команды гейтов + существующий unit ленивой загрузки» — свидетель, на который ссылается формулировка (demo/smoke_furniture_lazy_art.mjs), является browser-smoke из demo/smoke_*.mjs, а не test/*.test.mjs unit-тестом. Не искажает проверяемость критерия (свидетель существует и годен), но при код-ревью формулировка может увести к поиску несуществующего unit-теста. Решение ревьюера: не блокирует, оставляю без правки автору — на код-ревью проверяющий сверится с фактическим файлом, а не с текстом ТЗ; исправление слова стоит дешевле, чем цикл ревью ради него.

Других находок нет. High- и Medium-находок в скоупе задачи — 0. Medium вне скоупа — 0, отдельный issue не заводится.

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

  • Число прочих menu-иконок (32) и точный viewBox/безопасный контракт SVG, включая цвет и толщину линии, — сверены с реальным генератором и текущим файлом, а не приняты на слово;
  • Соответствие группы/названий/размеров манифесту pack.json;
  • Утверждение о ленивой загрузке menu-арта — прослежено по цепочке импортов до динамического import() в houseplan-card.ts;
  • Существование golden-сцены и её охват (все категории, не одна плитка);
  • Отсутствие влияния на скриншоты документации — палитра мебели не фигурирует ни в одном сценарии demo/docs/screenshots.mjs;
  • Отсутствие второго источника рисунка иконки в src/** (единственный потребитель — decor-image-editor.ts через GENERATED_FURNITURE_MENU);
  • Существование обоих npm-скриптов (furniture:generate, furniture:check), на которые ссылается AC3;
  • Полнота обязательных разделов ТЗ по §7.1 и корректность их порядка;
  • Согласованность аналитического комментария (Оценка: ...) с выбранным треком small — все критерии §5 выполнены одновременно (сложность 2/10, одна поверхность, нет миграции/нового UX-контракта/ влияния на perf или touch), отказ от trivial обоснован верно (тип — enhancement, не bug).

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

  • Подлинность SVG-геометрии внутри приложенного dishwasher.zip (не скачивал архив по внешней ссылке — это дело код-ревью: сверить итоговый path в svg/menu/dishwasher.svg с содержимым архива по заявленному SHA-256, а не задача спек-ревью проверять содержимое ещё не реализованного изменения);
  • Юридический статус provenance (принадлежность аккаунта nikitaevfz-commits компании JustBusiness) — зафиксировано как решение владельца вне этого ревью, продуктовым вопросом не является;
  • Дешёвые гейты (typecheck/test/build) — не гонялись, продуктового диффа для них нет на этапе ТЗ.

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

  • Issue: #640, заход r1.
  • Тело issue (раздел ## ТЗ) прочитано целиком через gh issue view 640 --json body.
  • Working tree: HEAD detached на f234855e66ee7baba528b7c856c5ab79e9491156, git status — чисто, продуктовый код этой задачей не менялся.

Вердикт

Зелёный. ТЗ полно, каждый AC проверяем и подкреплён проверкой по реальному коду/манифесту/скриптам, продуктовых вопросов владельцу нет, единственная находка — Low (терминологическая неточность в AC3), не требует правки для перехода в «Готово к разработке».


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

  • Ветка: issue/640-dishwasher-menu-icon, коммит f234855e66ee — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
  • Дерево материала: 703233aee85cb3c3cbf101b84e288ec9dba3ce34
    git log --all --format='%H %T' | grep 703233aee85c
    
  • Тело issue: 1336c4649192ea657779f92aeaf1daff7c7f23c2b85316d89d401bcd9f06101f
  • Вердикт конвейера: green · High 0