Files
houseplan-card/docs/reviews/SPEC-REVIEW-592-r2.md
T
2026-09-18 16:15:53 +00:00

14 KiB
Raw Blame History

SPEC-REVIEW-592-r2 — «Вынести четыре диалога настроек из houseplan-editor-runtime.ts в модули (шаг 0 эпика #591)»

Issue: #592 Этап: spec Заход: r2 (блокирующих циклов израсходовано 1 из 4 — израсходован жёлтым вердиктом r1; зелёный вердикт цикла не образует, §4)

Вердикт

Зелёный. High: 0. Medium: 0.

Скоуп разбора — по дельте (§2.10)

Предыдущий раунд (r1) — жёлтый, две находки: M1 (в скоупе) и L1 (снята с записью). Документ: docs/reviews/SPEC-REVIEW-592-r1.md. Материал r1 объявлен его блоком «Материал раунда»: ветка dev, коммит 01fe7350791e, дерево материала 0054c6622b79256b64b455ed786b46270fec9208. SHA живой (это предок текущего HEAD — 01fe7350 виден в истории репозитория), ре-резолвить по якорям не потребовалось.

Дельта этапа spec — не код, а тело issue #592 (ревизия r2 против r1). По правке автора в комментарии видно, что изменения локальны: заголовочная строка «Редакция r2: правки по ревью ТЗ r1», таблица «Мера храповика/Запас» (4→3), формулировка «трёх строках» вместо «нескольких», список эталонов AC2 (добавлен device-ripple-color-popover-mobile-ru), новый абзац «Почему именно этот список эталонов (правка по M1)» с таблицей покрытия по диалогам, и список смоков AC1 (добавлены smoke_gear_tabs, smoke_esc_dialogs, smoke_dialog_footer_width). Остальные разделы ТЗ (Проблема кроме числа, Контракт К1–К5, Скоуп/не-скоуп, AC3–AC7, Риски, Откат, Release-артефакты, «Принято предположительно») дельту не задевают — это подтверждают обе реплики автора («обе находки закрыты», список правок исчерпывающий) и сверка структуры документа r2 с r1: разделы совпадают дословно за пределами перечисленных мест.

Дельта локальна: новый субъект не появился (та же подсистема — редакторский граф диалогов), контракт поведения (К1–К5) не менялся, объём правки (несколько строк и одна таблица) несопоставим с объёмом исходной задачи. Условия «разбор остаётся полным» (ребейз, смена контракта, новая подсистема, сопоставимый объём) не выполнены — сокращённый разбор оправдан.

Поскольку код ещё не менялся (шаг не начат, User-Visible: no, задача готовит почву), дешёвые гейты (typecheck/test/build) в этом раунде не гоняю — они относятся к материалу code-review, а не к телу issue на этапе spec; это не пропуск, а неприменимость предмета.

Закрытие раунда r1

Находка r1 Чем закрыта Где это видно
M1 (Medium, в скоупе) — AC2 не называет эталон device-ripple-color-popover-mobile-ru, хотя он единственный доказывает ветку display === 'icon_ripple' в переносимом _renderMarkerDialog Эталон добавлен в список AC2 (выделен жирным в теле issue) Тело issue, строка AC2: «…device-ripple-color-popover-mobile-ru…»; проверено независимо: demo/golden/matrix.mjs:1084 регистрирует сценарий, demo/golden/harness.mjs:1994-2013 (ветка dialog === 'device-ripple-color') открывает _openMarkerDialog, ставит display: 'icon_ripple' и раскрывает hp-color-opacity с ярлыком marker.activity_color; baseline demo/golden/baselines/device-ripple-color-popover-mobile-ru.png существует
L1 (Low, снята с записью) — шапка называла запас ядер «4», фактически 3 (split('\n').length, не wc -l) Число исправлено на «3» в таблице «Мера храповика/Запас» и в тексте «Проблема» Тело issue: таблица показывает Запас: 3 / 3; текст «Оба ядра стоят в трёх строках от жёсткого потолка»; проверено пересчётом: src/houseplan-editor-runtime.ts — 14096 строк по wc -l/awk 'END{print NR}', split('\n').length даёт 14097 против потолка 14100 в test/core-file-budget.test.mjs:36 → запас 3; src/houseplan-card.ts — 13728 строк, split.length = 13729 против потолка 13732 (:32) → запас 3

Обе находки закрыты фактом текста/кода, а не заявлением автора — проверено независимо, не только пересказано.

Что проверено в этом раунде (дельта)

  1. Новый абзац «Почему именно этот список эталонов» — таблица покрытия по диалогам (Устройство 7 / Комната 2 / Общие настройки 3 / Пространство 1) пересчитана и совпадает с фактическим списком AC2: 3 device-dialog-* + 1 device-help-popover-* + 1 device-ripple-color-* + 2 toggle-entity-dialog-* = 7 для устройства; 2 room-temperature-dialog-* для комнаты; general-color-*

    • 2 settings-help-zoom-200-* = 3 для общих настроек; 1 space-room-color-popover-desktop-ru для пространства. Итого 13 эталонов в AC2 (12 из r1 + добавленный ripple) — сходится с телом issue.
  2. Три новых смока в AC1, заявленные как компенсация единственного golden-кадра пространства. Проверено чтением каждого файла:

    • demo/smoke_gear_tabs.mjs — открывает _spaceDialog (строки 23-49), проверяет режим create (_spaceDialog.mode === 'create') — реально задействует диалог пространства;
    • demo/smoke_esc_dialogs.mjs:67-68 — вызывает c._openSpaceDialog('edit', c._space) и проверяет закрытие по Esc;
    • demo/smoke_dialog_footer_width.mjs — вызывает _openSpaceDialog('edit', …) дважды (desktop и narrow), измеряет buttons, oneRow, noHorizontalOverflow, insideViewport (строки 87, 139, 201-217) — реально проверяет структуру диалога пространства (число кнопок, отсутствие переполнения), а не просто факт открытия.

    Все три файла существуют, все три действительно открывают/используют _spaceDialog/_openSpaceDialog, заявление автора подтверждено чтением кода, а не принято на слово. Важная оговорка (не находка, а точность формулировки): эти три смока — функциональные/структурные проверки (число кнопок, переполнение, режим), не побайтовые сравнения кадра. Автор сам явно не относит их к AC2 (побайтовое совпадение), а держит в AC1 — формулировка в issue корректна и не выдаёт смок за замену golden-сравнения.

Унаследовано из r1

Без повторной проверки в этом раунде, со ссылкой на docs/reviews/SPEC-REVIEW-592-r1.md (материал: ветка dev, коммит 01fe7350791e, дерево 0054c6622b79256b64b455ed786b46270fec9208):

  • Границы всех четырёх методов (_renderMarkerDialog 12884–13610, _renderSpaceDialog 13611–13907, _renderSettingsDialog 10337–10502, _renderRoomDialog 13984–14097) — дельта их не меняет, номера строк в теле issue r2 идентичны r1.
  • Прецедент radar-section.ts/vacuum-maps-section.ts (форма экспорта, отсутствие @state(), кто импортирует) — К2 в r2 не менялся.
  • Число мутационных патчей (33) с file: 'src/houseplan-editor-runtime.ts' и направление relocateEditorPatch — К5 в r2 не менялся.
  • Реальность доказательств AC5 (bundle:budget, bundle-assets.test.mjs разбирают фактический вывод сборки) и AC6 (mutation-gate.test.mjs — уникальность якоря) — тексты AC3–AC7 в r2 не менялись.
  • Полнота обязательных разделов §7.1, отсутствие незаявленных допущений (раздел «Принято предположительно» ограничен техническими решениями) — структура документа вне перечисленных мест дельты идентична r1.
  • Продуктовая рамка: задача — шаг 0 эпика #591, видимых изменений нет (К1), сценарий и «что человек увидит» корректно формулируют нулевой видимый эффект как факт, а не как отсутствие анализа.
  • Trailers: User-Visible: no корректно, changelog не требуется — задача не меняет ничего наблюдаемого пользователем.

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

  • Не повторял построчный аудит всех ≈1300 строк четырёх методов на предмет других скрытых веток по образцу ripple, кроме уже закрытой M1 — дельта r2 не расширяла зону риска (не добавляла новых диалоговых веток), только меняла список эталонов/смоков; повторный полный аудит не относится к предмету раунда.
  • Не проходил построчно содержимое smoke_general_settings.mjs/ smoke_room_settings.mjs/smoke_color_picker_consumers.mjs/ smoke_static_icon.mjs/smoke_device_inbox.mjs/smoke_room_temperature_thresholds.mjs/ smoke_device_preview_parity.mjs — эти семь смоков дельту не задели, их разбор унаследован из r1 неявно (r1 их не проверял построчно и сам отметил это в «Чего не проверял»; предмет этого раунда — не они).
  • Не гонял npx tsc --noEmit, npm test, npm run build, golden:verify, bundle:budget — этап spec, продуктовый код ещё не менялся под эту задачу; единственная числовая проверка (split('\n').length против потолков test/core-file-budget.test.mjs) сделана вручную пересчётом, сам тестовый файл не запускался (не нужен: код диалогов ещё на месте, ratchet не может измениться).
  • Не читал повторно эпик #591 целиком — К1 подготовки к нему в r1 уже подтверждён, дельта эпика не касается.

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

  • Issue #592, тело на момент разбора (gh issue view 592 --json body), ревизия r2 (после комментария автора от 2026-09-18T16:11:07Z).
  • Заход r2, циклов ревью ТЗ израсходовано 1 из 4 (израсходован жёлтым вердиктом r1; текущий зелёный вердикт цикла не расходует, §4).
  • Предыдущий раунд: docs/reviews/SPEC-REVIEW-592-r1.md, материал — коммит 01fe7350791e, дерево 0054c6622b79256b64b455ed786b46270fec9208.
  • Код на момент разбора — рабочая копия на HEAD = 8ec85ac0f6f62e72f8ac43c95786080e02b3a8bf (продуктовый код задачи ещё не менялся; ссылки на строки/потолки относятся к этому состоянию репозитория).

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

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