mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-06 14:39:22 +00:00
182 lines
16 KiB
Markdown
182 lines
16 KiB
Markdown
# SPEC-REVIEW-448-r1
|
||
|
||
- Issue: [#448](https://github.com/Matysh/houseplan-card/issues/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 → в задаче
|
||
|
||
---
|
||
|
||
<!-- material-anchors: сгенерировано конвейером (#414) -->
|
||
|
||
## Материал раунда
|
||
|
||
- Ветка: `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
|
||
```
|