Files
houseplan-card/docs/reviews/SPEC-REVIEW-506-r1.md
T
2026-09-09 10:02:25 +00:00

14 KiB
Raw Blame History

SPEC-REVIEW-506-r1

Issue: #506 — «v1.73.0: лишние перерисовки при запуске плана блокируют Full Performance». Этап: spec (PROCESS.md §2.4). Заход: r1. Блокирующих циклов израсходовано 0 из 4. Материал: docs/specs/506-startup-performance.md, коммит e17cdb51628933aca12a5dab2923465f0e2c4278 (содержит только docs/specs/506-startup-performance.md + строку в docs/specs/README.md, код не тронут — корректно для S4-spec-review).

Скоуп

Трек — полный (не small, не trivial): аналитик обосновал это явно («критерий small «нет влияния на производительность» заведомо не выполнен») — это соответствует §2.2.8, вопрос закрыт. ТЗ существует файлом в docs/specs/, что верно для не-small issue (§2.3, §7.1).

Задача — узкий фикс: устранить лишний layout/re-render при старте карточки, вызванный ленивой (dynamic import) подгрузкой summary-runtime, без изменения видимого поведения, budgets, окон измерений или scope сводной панели (#500, #505 явно исключены). Продуктовая рамка по docs/SCOPE.md: J1/J2/J3 (отзывчивый корректный View/переключение режимов) — задача не расширяет функциональность, а устраняет деградацию отзывчивости, что попадает в мандат этих job напрямую.

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

Ревью технического содержания ТЗ, а не только формы — проверил, что заявленные факты не являются недоказанными догадками:

  1. Числа/SHA в ТЗ сверены с реальностью, а не переписаны с чужих слов.
    • d11f95bc — реальный коммит Release v1.73.0 candidate, прямой предок текущего HEAD.
    • fff171c7 заявлен как «продукт v1.72.0»: git merge-base --is-ancestor подтвердил, что тег v1.72.0 (bf69d768) — предок fff171c7, и git diff bf69d768 fff171c7 -- src/ пуст — разница только в ci/*.yml. Формулировка AC7 «база fff171c7 или эквивалентный продукт v1.72.0» точно отражает это несовпадение SHA с тегом — не голословное заявление.
  2. Техническая гипотеза дефекта сверена с текущим кодом, не измышлена:
    • src/houseplan-card.ts:2628 — connectedCallback действительно делает void import('./summary-panel-runtime-loaded').then(...) асинхронно и безусловно (кроме случая, когда this._summary уже создан), включая уже прогретый модуль браузера.
    • src/houseplan-card.ts:3247 (_warmAdopt) синхронно восстанавливает _hdrH и гасит _booting, не трогая _summary — подтверждает описанный в ТЗ разрыв «header settled, summary отсутствует» дословно.
    • Прочитан канонический docs/WARM-REMOUNT.md: модульная память (warmBoot, Map на уровне модуля, не экземпляра) — уже установленный в продукте паттерн; предложенный в ТЗ §4.1 «кеш фабрики кода на странице / runtime на экземпляр» — тот же архитектурный приём, применённый к другой подсистеме, а не изобретение с нуля.
  3. Артефакты доказательства (файлы тестов/смоков) существуют и не выдуманы: test/boot-soft-layout.test.mjs (фикстура ровно 780×669, совпадает с AC4), test/summary-panel-runtime.test.mjs, test/visual-continuity.test.mjs, demo/smoke_warm_remount.mjs, demo/smoke_preloader_lifecycle.mjs, demo/smoke_visual_continuity.mjs, demo/smoke_isometric_contract.mjs — все на месте. scripts/mutation-gate.mjs уже содержит мутанты по соседней подсистеме (#505, summary-panel-runtime-loaded.ts), значит требование AC8 «мутация в mutation-gate» технически выполнимо тем же механизмом.
  4. Сверил обязательные разделы ТЗ (PROCESS.md §7.1) построчно с текстом документа (см. ниже).
  5. Прочитал docs/SCOPE.md, PROCESS.md §2–§4, §7.1, AGENTS.md-эквивалент процесса, docs/UX-MODES.md, docs/USER-GUIDE.ru.md (термины kiosk/панель хоста совпадают). Не читал ревью-код-этап — задача туда ещё не дошла.

Ревью не запускал автотесты/гейты: этап — ревью ТЗ, а не код-ревью; кода в материале нет (см. diff выше), гейты §8 к этому SHA неприменимы.

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

Требование §7.1 Где в документе
Сценарий §1 «Пользователь и сценарий» — персоны J1/J2/J3, поверхности
Что человек увидит до/после §1, абзац «До: … После: …»
Проблема §2 «Доказательства и границы вывода»
Скоуп и не-скоуп §3 «Объём задачи» (включено/не включено раздельно)
Контракт поведения §4 (4.1–4.3), детально по владению/lifecycle/layout
UX §5 — явно «новых кнопок, настроек, решений нет»
Модель данных и миграция §5 — «хранение/config version/API неизменны»
i18n §5 — «не затрагивается» (обоснованно: нет UI-изменений)
AC1…ACn с доказательством §6, 8 AC, у каждого столбец «Доказательство»
План автотестов §3 (список поверхностей) + список файлов после таблицы §6 + §8
Риски §7
Откат §7 «Откат»
Release-артефакты §8, включая явное указание на переснятие docs-скриншотов при изменении fingerprint

Все разделы присутствуют по существу. Замечание к форме — см. Low ниже.

Находки

Блокирующих (High) и Medium в скоупе не найдено.

Low-1 (снято с записью). Соседние ТЗ той же подсистемы (docs/specs/505-...md, docs/specs/493-...md) выделяют технические допущения, оставленные на усмотрение реализации, отдельным финальным разделом «Принятые технические предположения». В 506-м это же содержание распределено внутри §7 («Предпочтительный дизайн… Точные имена и границы модуля допускается уточнить в реализации при сохранении контракта») — по существу требование §7.1 «явный блок принятых предположений» выполнено (формулировка именно такая: что можно менять свободно, что нет), только не вынесено отдельным заголовком. Содержательного риска нет — не блокирует, автору не возвращается.

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

  • Задача в скоупе docs/SCOPE.md (J1/J2/J3), не расширяет функциональность.
  • Трек выбран верно и обоснован (§2.2.8).
  • Числа, SHA и ссылки на прогон Full Performance в ТЗ соответствуют реальному git-состоянию репозитория (проверено merge-base/diff, не просто переписано из issue).
  • Техническое описание дефекта («header settled раньше summary») подтверждено чтением текущего src/houseplan-card.ts — это не догадка, а точное описание существующего кода.
  • Контракт §4 (владение кодом/состоянием, lifecycle, layout) не противоречит канону docs/WARM-REMOUNT.md и продолжает уже принятый в продукте паттерн модульного кеша.
  • Все 8 AC пронумерованы, однозначны, у каждого указан способ доказательства и он реалистичен относительно существующей тестовой инфраструктуры (файлы существуют).
  • Неопределённость (не доказано, что весь прирост isometric — summary-owned) не замаскирована: явно зафиксирована как открытый технический риск и закрыта через обязательный AC7 + условие «если гипотеза не закрывает isometric — stable остаётся заблокирован» — это не продуктовый вопрос владельцу (см. PROCESS.md §7.1: чисто технический риск решается вердиктом/AC, а не эскалацией), и он верно не эскалирован.
  • Продуктовых открытых вопросов, требующих ответа владельца, в ТЗ нет и не появилось при разборе — ни одного места, где решение выдано за факт без обоснования.
  • Не-скоуп прямо перечисляет то, что владелец запретил как «нерешение» (arbitrary sleep, ослабление budgets, исключение load из замера, сокращение samples) — совпадает с комментарием владельца в issue.
  • Release-артефакты учитывают правило docs fingerprint (node scripts/check-docs.mjs из инструкции этого ревью) — §8 уже требует переснять полный набор при изменении src-отпечатка, а не просто «обновить changelog».

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

  • Не проверял реализацию — её нет на этом SHA, этап spec.
  • Не запускал гейты (tsc, npm test, build, smoke, invariants) — неприменимо к ревью ТЗ без кода; будет обязательным на этапе код-ревью.
  • Не верифицировал экспериментально, что предложенный в §7 дизайн (typed loader + factory cache + per-host guard) действительно устранит регресс — ТЗ прямо не гарантирует это (гипотеза), и это корректно вынесено в риски с условным откатом через AC7, а не выдано за решённый факт.

Вердикт

Зелёный. ТЗ полно по §7.1, критерии приёмки однозначны и проверяемы, технические утверждения проверены по факту (код, git-история, существующие тестовые файлы), а не приняты на слово. High/Medium-находок нет. Единственное замечание (Low) — чисто формальное и снято без правки.


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

  • Ветка: issue/506-startup-performance, коммит e17cdb516289 — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
  • Дерево материала: e1d7dd1cf3e6655266aa0e76508a3f943f8fde9c
    git log --all --format='%H %T' | grep e1d7dd1cf3e6
    
  • ТЗ docs/specs/506-startup-performance.md, блоб d2517458924164f801f493ff8597ebdd2a8e4e35
    git log --all --find-object=d2517458924164f801f493ff8597ebdd2a8e4e35 -- docs/specs/506-startup-performance.md
    
  • Вердикт конвейера: green · High 0