Files
houseplan-card/docs/reviews/SPEC-REVIEW-448-r1.md
2026-09-04 16:20:34 +03:00

16 KiB
Raw Permalink Blame History

SPEC-REVIEW-448-r1

  • Issue: #448 — Labs: единый бессрочный переключатель hp_alpha для экспериментальных функций
  • ТЗ: docs/specs/448-alpha-switch.md (SHA aa72704a)
  • Трек: полный (лёгкий явно отклонён аналитикой: «меняются долговременный compatibility-контракт и несколько runtime/test/documentation поверхностей»)
  • Этап: S4-spec-review · заход r1 · блокирующих циклов израсходовано 0 из 4 (до этого вердикта)
  • Ревьюер ≠ автор ТЗ (Codex); эта сессия не участвовала в написании ТЗ.

Скоуп

Диапазон, вынесенный на ревью, — только документация: git diff origin/dev...HEAD даёт два файла, docs/specs/448-alpha-switch.md (новый, 260 строк) и одну строку в docs/specs/README.md (реестр ссылок issue↔ТЗ). Продуктовый код не менялся — верно для стадии S4-spec-review, где менять src/**/ custom_components/** запрещено правилом №1 до S5-ready. Коммит aa72704a несёт трейлеры Issue: #448 и User-Visible: no — корректно, поведение ещё не изменилось.

Задача продолжает прямо одобренное узкое 2.5D-исключение из docs/SCOPE.md (единственный прецедент #89) и служит J1: она не строит новую функцию, а чинит контракт включения уже принятого Stage 1/2 изометрического View, испорченный version-expiry в src/labs.ts. Из «не-скоуп» разделов SCOPE.md задача не задевает ничего — доступ к experimental-переключателю остаётся скрытым, публичного 3-D запуска и новых редакторов ТЗ не вводит.

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

  1. Прочитаны docs/SCOPE.md, AGENTS.md, PROCESS.md (§1–§10.4 включительно).
  2. Прочитаны тело issue #448 и все три комментария (аналитика, вопросы владельцу, решения владельца со ссылкой на ТЗ).
  3. Прочитан канонический docs/ISOMETRIC.md (текущий контракт iso/Labs, which hp_alpha заменяет) и docs/UX-MODES.md (раздел Kiosk mode) — подсистема, которую задевает пункт «full-card View и kiosk gate».
  4. Прочитан действующий src/labs.ts целиком и потребители Labs в src/houseplan-card.ts (grep по iso|Labs|labs, ~40 точек использования: _labsIso, _desiredProjection, _setProjection, _effectiveProjection, projection-toggle кнопка, noteLabsRender) — чтобы отличить утверждения ТЗ о текущем поведении от догадок.
  5. Сверены i18n-ключи view.flat/view.volumetric в src/i18n/{ru,en}.json с прозой ТЗ («Плоский / 3-D»).
  6. Проверено docs/CONFIG-COMPATIBILITY.md (сфера действия — persisted-поля схемы плана, не browser-local Labs storage) — подтверждено, что раздел «Модель данных и миграция» ТЗ корректно объявляет её вне применимости этого реестра.
  7. Проверено docs/TOUCH-SUPPORT.md (product contract: View — touch-first, kiosk — primary supported environment) на предмет обязательного пункта DoR §2.5 «влияние на touch… View и киоск — блокирующие».
  8. Проверены обязательные разделы §7.1 построчно по тексту ТЗ.
  9. git show aa72704a --stat и -s --format=full — трейлеры и состав коммита.

Гейты кода (typecheck/test/build/check-docs) не прогонялись: диапазон не касается src/** и custom_components/**, только docs/**; на этой стадии они не гейт ревью ТЗ. check-docs.mjs, о котором автор отчитался в issue, тоже не относится к «правкам src» — но и не вредит, лишний прогон.

Находки

Medium (в скоупе задачи — правится в текущем ТЗ)

M1. ТЗ не закрывает обязательный пункт DoR «влияние на touch» (docs/TOUCH-SUPPORT.md).

  • Файл: docs/specs/448-alpha-switch.md
  • PROCESS.md §2.5 требует для перехода в «Готово к разработке»: «влияние на touch по docs/TOUCH-SUPPORT.md (View и киоск — блокирующие)», названо явно или явным «нет». docs/TOUCH-SUPPORT.md фиксирует View как touch-first, обязательный к полной поддержке, а kiosk — как «primary supported environment»: любой тач-дефект в этих поверхностях — не допустимая деградация, а дефект продукта.
  • В тексте ТЗ (проверено построчным поиском touch|Touch|сенсор — ноль совпадений) нет ни одной строки о touch. Задача прямо называет затронутой поверхностью «full-card View и kiosk gate» (аналитика) и пункт 13 контракта возвращает в View именно интерактивный контрол — существующую кнопку projection-toggle (src/houseplan-card.ts:11501-11507), которая сейчас недостижима из-за expires: 1.65.0 и станет достижимой снова.
  • Это не открытый продуктовый вопрос владельцу: сама кнопка и её touch-поведение уже прошли ревью в #89/#122 и код не меняется — задача лишь восстанавливает достижимость уже принятого контрола через новый резолвер. Достаточно одной явной строки в ТЗ (например, в «UX и диагностика» или отдельным подпунктом «Touch»), фиксирующей это рассуждение как решение ревью, а не оставляющей пункт чек-листа непроверенным. Без такой строки раздел DoR формально не закрыт, и это факт, а не стилистика: чек-лист §2.5 зовёт этот пункт поимённо и отмечает его блокирующим для View/kiosk.
  • Воспроизведение: grep -inE "touch|Touch|сенсор" docs/specs/448-alpha-switch.md → нет совпадений.
  • Не блокирует переход High-порогом, чинится добавлением строки в этом же ТЗ, отдельный цикл не обязателен по существу (это не смена контракта), но по процессу возврат один — правка ТЗ и повторный (лёгкий) заход.

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

  • Обязательные разделы §7.1 все присутствуют и в правильном порядке: сценарий, что человек увидит до/после, проблема, скоуп/не-скоуп, контракт поведения, UX и диагностика, модель данных и миграция, i18n и accessibility, критерии приёмки AC1–AC13 с доказательством, план автотестов, риски, откат, release-артефакты, плюс необязательный, но полезный блок «Принятые предположения».
  • AC1–AC13 пронумерованы, взаимно не пересекаются и у каждого указан явный способ доказательства (unit / unit+smoke / source-contract / targeted smoke + golden / performance profile / static contract). Ни один AC не сформулирован как «работает корректно» без проверяемого критерия.
  • Ни одной непомеченной догадки о существующем поведении не найдено. Каждое фактическое утверждение о текущей системе сверено с кодом/каноном и подтвердилось: version-expiry 1.65.0 действительно отфильтровывает iso на линии 1.71 (liveLabsFlags + LABS_FLAGS[0].expires); переключатель Flat↔3-D уже существует в full-card View и уже скрыт в kiosk (!this._kiosk) — src/houseplan-card.ts:11501; per-space preference houseplan_card_view_v1 используется как заявлено (LS_VIEW в houseplan-card.ts:489); редакторы и houseplan-space-card не проецируют iso — подтверждено docs/ISOMETRIC.md («Editors and houseplan-space-card are always flat»). Единственная content-догадка о будущем поведении («явное неизвестное URL-значение не портит сохранённое значение») корректно вынесена в блок «Принятые предположения», как и требует PROCESS.md §7.1.
  • Продуктовые вопросы владельцу заданы по существу, каждый с предложенным default (способ включения/выключения hp_alpha; судьба legacy iso), ответ получен и зафиксирован явным решением в третьем комментарии issue — процессуально верно (§3.7.1: только «что видит/делает человек» и «объём видимых изменений», без технических вопросов владельцу).
  • Скоуп/не-скоуп точно очерчивают границу: явно исключены публичный запуск 3-D, Stage 3 (#160), серверное хранение/синхронизация, миграция старого iso. Соответствует ответу владельца на Q2 (без миграции).
  • Откат описан содержательно — включает явный запрет «плохого» отката (продление iso-expiry, возврат нескольких внешних ключей), что и было первоисточником проблемы.
  • Компат-модель: раздел корректно утверждает, что схема плана/backend/HA- запросы не меняются — проверено по docs/CONFIG-COMPATIBILITY.md, чья область действия — persisted-поля конфигурации плана, а не browser-local Labs-хранилище; обращение к этому реестру здесь действительно не требуется.
  • i18n: заявлено «новых публичных строк нет» — проверено, view.flat / view.volumetric уже существуют в ru.json/en.json; прозаические «Плоский / 3-D» в тексте ТЗ — не заявка на новую строку, а неформальный пересказ существующих меток, реальный текст меток задачей не меняется.
  • Класс изменений и трейлеры коммита верны: только docs/** (класс C), Issue: #448, User-Visible: no — корректно для стадии, где поведение ещё не менялось; продуктовый код не тронут ни одним файлом (правило №1 не нарушено).
  • Персона/повод: аналитика прямо связывает задачу с J1 SCOPE.md и с уже одобренным исключением #89; формулировка «продвинутый пользователь/тестировщик» в разделе «Сценарий» не совпадает дословно ни с одной строкой таблицы персон SCOPE.md (Home admin/Household members/Guests), но по контексту (URL-флаг, desktop) однозначно про Home admin — рассмотрено, не поднято до отдельной находки: не создаёт двусмысленности для реализации или проверки AC, чисто формальная формулировка. Low, не фиксирую отдельно.

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

  • Не прогонял npx tsc --noEmit / npm test / npm run build — диапазон не содержит кода класса A/B, эти гейты не гейтуют ревью ТЗ.
  • Не прогонял node scripts/check-docs.mjs — диапазон не касается src/** (отпечаток скриншотов документации), автор уже привёл passed в issue, но это не обязательный гейт для docs-only диффа.
  • Не проверял golden/smoke/performance-фикстуры буквально (их ещё нет — они появятся в реализации, план автотестов на этой стадии оценивается как план, а не как прогон).
  • Не оценивал техническую реализуемость внутреннего резолвера построчно (не моя роль на этой стадии и не предмет спор ТЗ↔код) — только соответствие контракта существующему коду и канону.

Вердикт

hp_alpha заменяет version-expiry контракт корректно очерченным, непротиворечивым и полностью доказуемым ТЗ; единственная находка — реальный, но локально устранимый пробел DoR по touch-влиянию, входящий в скоуп этой же задачи.

Вердикт: жёлтый · заход r1 · блокирующих циклов 1/4 · High: 0 · Medium: 1 → в задаче


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

  • Ветка: issue/448-alpha-switch, коммит aa72704aacce — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
  • Дерево материала: 4bea42cb1c9dc9c0fc49c8de4005942035e965d1
    git log --all --format='%H %T' | grep 4bea42cb1c9d
    
  • ТЗ docs/specs/448-alpha-switch.md, блоб ba9b8e5f621f5ad8ecb881e1cbf40d3cc24573ef
    git log --all --find-object=ba9b8e5f621f5ad8ecb881e1cbf40d3cc24573ef -- docs/specs/448-alpha-switch.md