Files
houseplan-card/docs/reviews/SPEC-REVIEW-406-r4.md
T
2026-09-01 16:32:25 +00:00

209 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SPEC-REVIEW-406-r4
- Issue: #406
- ТЗ: `docs/specs/406-beta2-polish.md`, ветка `issue/406-beta2-polish`,
ревизия 4, SHA `7a3dcfd7` (тот же коммит, что назвал автор в передаче на
ревью: «Head: `7a3dcfd7`»; `git rev-parse HEAD` подтверждает)
- Этап: spec (PROCESS.md §2.4)
- Заход: r4 · блокирующих циклов израсходовано 3 из 4
- Вердикт: **зелёный**
## Почему разбор по дельте, а не заново
Предыдущий вердикт (SPEC-REVIEW-406-r3) получен на SHA `c43051ac`.
`origin/dev` = `b04387ce` — тот же коммит, что был актуален и на момент r2/r3
(`git merge-base c43051ac origin/dev` = `b04387ce` = сам `origin/dev`,
`git merge-base --is-ancestor c43051ac origin/dev` → false, т.е. ветка задачи
не сливалась и не ребейзилась поверх ушедшего вперёд `dev`). Не §2.10-случай
«ребейз на ушедший вперёд dev».
Дельта объявлена как `git diff c43051ac..7a3dcfd7`:
```
docs/reviews/SPEC-REVIEW-406-r3.md | 235 +++++++++++++ (новый файл — документ прошлого раунда)
docs/specs/406-beta2-polish.md | 26 +++++++------
```
В самом ТЗ дельта — три места: (1) ревизия 3→4 в шапке, (2) одно предложение
в разделе «Что человек увидит… После», (3) полностью переписанные разделы
«UX» и «Release-артефакты». Контракты (а), (б), (в), (г), AC1–AC12, план
автотестов, риски, откат, скоуп/не-скоуп дельтой не задеты ни строкой —
инвариант проверен `git diff c43051ac..7a3dcfd7 -- docs/specs/406-beta2-polish.md`
построчно. Диапазон `origin/dev...HEAD` по-прежнему состоит только из
doc-файлов (три ревью-документа + сам ТЗ) — продуктового кода нет, гейты
`tsc`/`test`/`build` неприменимы, тот же факт, что в r1–r3.
Дельта локальна и закрывает единственную Medium-находку r3 — это ровно
случай, для которого §2.10 предписывает разбор по дельте, а не заново.
## Скоуп
Без изменений: пять пунктов из тела issue → четыре после того, как (д)
выведен из скоупа в r3 (дефект уже исправлен в #409 коммитом `8119c523`).
Четыре пункта на трёх поверхностях: словари i18n (а), роль/описание диалога
подтверждения (б) вместе со смок-покрытием HA-ветки (в), уборка снапшотов
area (г). Полный трек обоснован (три несвязанные поверхности, критерий
«одна поверхность» для `small` не выполняется) — не пересматривался, дельта
трек не касается.
## Как проверялось
Прочитаны заново `docs/SCOPE.md`, `PROCESS.md` целиком (включая §2.10, §4,
§7.1, §7.2), `AGENTS.md`. Прочитано тело issue #406 и все восемь
комментариев (два S2-разбора, четыре передачи на ревью автором, два
предыдущих вердикта). Прочитаны целиком `docs/reviews/SPEC-REVIEW-406-r1.md`
(входит в SHA дерева как исторический контекст), `-r2.md` и `-r3.md`.
Само ТЗ (`docs/specs/406-beta2-polish.md`, 344 строки) прочитано целиком
построчно на SHA `7a3dcfd7`, не только дельта — чтобы убедиться, что
переписанные разделы UX/Release-артефакты не противоречат ничему из
разделов, которые дельта не тронула (сценарий, контракт (б), AC6–AC8).
Точечно перепроверена по коду цифра, впервые появившаяся в этой ревизии текста
(раздел UX, строка 197: «восемь точек входа: семь `destructive` и одна
`warning`») — это не пересказ старой находки r1, а новое количественное
утверждение в новом месте документа, поэтому дельта его касается:
```
grep -n "kind: *'destructive'" src/*.ts → 7 вхождений
houseplan-onboarding-runtime.ts:224, 437
houseplan-editor-runtime.ts:3127, 3153, 8418, 8658, 8884
grep -n "kind: *'warning'" src/*.ts → 1 вхождение
houseplan-card.ts:13044
```
7 + 1 = 8, число в тексте точное.
Проверена терминология «нативная оболочка House Plan» против
`docs/USER-GUIDE.ru.md`: строки 730 и 1904 этого документа уже используют
оборот «общий диалог House Plan» / «единый диалог House Plan» для того же
подтверждения — новая формулировка ТЗ не изобретает термин, а совпадает с
уже принятым в проекте словарём интерфейса.
Продуктового кода в диапазоне `origin/dev...HEAD` нет (`git diff
origin/dev...HEAD --stat` — только четыре `.md`-файла), поэтому `tsc`/`test`/
`build` не гонялись — неприменимы, тот же факт, что в r1–r3.
## Закрытие раунда r3
| Находка r3 | Чем закрыта | Где это видно |
|---|---|---|
| №1 (Medium, в скоупе) — раздел «UX» и «Release-артефакты» утверждали «оформление не меняется», хотя раздел (б) в r3 впервые ввёл видимый переход confirm-диалогов с HA-хрома на нативную оболочку `hp-dialog` | Раздел «UX» переписан: явно назван видимый переход для всех восьми точек входа («…в реальном Home Assistant переходят с оболочки `ha-dialog` на уже поддерживаемую нативную оболочку `hp-dialog`: возможны небольшие отличия заголовка и анимации»), явно перечислено, что не меняется (кнопки, цвет, защита от случайного закрытия, начальный фокус, Esc), явно названо, что это «осознанный видимый компромисс… а не обещание pixel parity». Раздел «Release-артефакты» требует пункт CHANGELOG именно про нативную оболочку **и** про `alertdialog`, `User-Visible: yes` | `docs/specs/406-beta2-polish.md:193-206` (UX), `:339-343` (Release-артефакты); в дифф `c43051ac..7a3dcfd7` эти два раздела — единственные содержательно переписанные блоки |
Находка закрыта по существу: числовое утверждение, добавленное в закрывающем
тексте («восемь точек входа: семь + одна»), перепроверено независимо по
коду (см. «Как проверялось») и совпадает; формулировка не противоречит ни
одному месту ТЗ, которое дельта не трогала (AC6–AC8, контракт (б), раздел
«Проверена ровно закреплённая проектом версия…»); терминология не
изобретена, а совпадает с `docs/USER-GUIDE.ru.md`.
## Унаследовано из r3
Разделы, дельтой `c43051ac..7a3dcfd7` не задетые ни строкой, приняты без
повторной построчной проверки контракта — из `docs/reviews/SPEC-REVIEW-406-r3.md`
(и через него — из r2/r1), на SHA `c43051ac`:
- **(а) Мёртвые строки в словарях** — инвентарь 13 мёртвых ключей (7
`confirm.*` + 6 прочих семейств), правило извлечения производных
`*.help.aria` из литеральных `_help('*.help')` для всех 19 пар, коллизия с
`test/unified-wall-tool-source.test.mjs` и её разрешение как открытого
вопроса реализации — вся фактура из r1/r2, подтверждена в r2 и не
пересчитывалась в r3 и в этом раунде.
- **(б) контракт роли/описания** (без изменённого в этом раунде текста UX) —
дихотомия `destructive`/`warning` → `alertdialog`, механизм
`.ariaDescribedBy`/`type` в закреплённой версии `home-assistant-frontend
==20260729.7`, независимо подтверждённый в r3 построчным чтением реального
`ha-dialog.ts` (560 строк). Эта часть контракта дельтой r3→r4 не менялась.
- **(в) смок-покрытие HA-ветки** — контракт «смок с зарегистрированным
`ha-dialog` проверяет обе развилки», прецедент стаба `smoke_free_walls.mjs`,
требование к стабу моделировать публичные свойства, а не внутренний shadow
DOM — переписано и подтверждено в r3, дельтой r4 не тронуто.
- **(г) снапшоты area** — условие «уборка только при авторитетном реестре»,
связь с #403, порядок обрезки `markerAreaSnapshotOf` (сохранять последние,
а не первые) — фактура из r1/r2, не пересчитывалась в r3 и в этом раунде.
- **AC1–AC12, план автотестов, мутанты, риски, откат, модель данных/миграция,
i18n** — текст этих разделов не изменился ни на строку между `c43051ac` и
`7a3dcfd7`; их разбор в r3 («AC6-AC8 и обновлённый план автотестов
внутренне непротиворечивы», «нет висячих ссылок на AC13/AC14», «§7.1 —
все разделы присутствуют») принят как есть.
- **Отсутствие продуктовых вопросов владельцу** — подтверждено в r1/r2/r3, в
этом раунде тоже не появилось: единственная правка (UX/Release-артефакты)
технический вопрос не поднимает, она документирует уже принятое
техническое решение (б).
## Находки
Блокирующих (High) и находок Medium в скоупе, не закрытых этой ревизией, нет.
**[Low, снято с записью]** DoR-пункты «влияние на touch по
`docs/TOUCH-SUPPORT.md`» и «влияние на производительность названо явно» не
выделены в ТЗ отдельной строкой (ни в этой, ни в предыдущих трёх ревизиях —
проверено по `docs/reviews/SPEC-REVIEW-406-r{1,2,3}.md`, ни один не поднимал
этот пункт). Разбираю по существу, не откладываю: производительность
покрыта явно — AC12 фиксирует бюджет initial (удаление ключей уменьшает его,
роль/`aria-describedby` добавляют единицы байт), доказательство —
`bundle:budget` до/после. Touch не упомянут вовсе, но по факту неприменим:
все четыре пункта задачи — словари, диалог `hp-confirm` (используется
исключительно в двух редакторах, `SCOPE.md`: View никогда не показывает
destructive/warning-действий), снапшоты area (внутренняя уборка данных, не
интерфейс) — не меняют ни один жест, ни один drag/resize/tap-путь
`TOUCH-SUPPORT.md`; смена HA-хрома на нативный `<dialog>` — рендер-путь,
одинаковый независимо от способа ввода. Снимаю без возврата автору: правка
тривиальна (одна фраза «влияние на touch: нет, диалог не входит в
touch-специфичные пути редакторов»), но её отсутствие не меняет ни одного
AC и не создаёт риска — решение реализации от неё не зависит.
## Что проверено и корректно
- **Единственная Medium-находка r3 закрыта по существу**, не косметически:
новый текст UX/Release-артефактов называет ровно то видимое изменение,
которое раздел (б) вводит, ничего не занижая и не расширяя сверх
доказанного в r3.
- **Новое количественное утверждение в закрывающем тексте («8 точек входа:
7 + 1») точное** — перепроверено независимым `grep` по `src/*.ts`, не
принято на слово автора.
- **Терминология не изобретена** — «нативная оболочка House Plan» совпадает
с уже используемым в `docs/USER-GUIDE.ru.md` оборотом («общий диалог
House Plan», «единый диалог House Plan»).
- **Внутренняя согласованность документа после правки** — раздел UX не
противоречит AC6–AC8, контракту (б) и разделу «Практически» (строки
120-130); раздел Release-артефакты корректно относит к User-Visible ровно
один пункт (б) и оставляет три остальных (а, в, г) внутренними.
- **§7.1, обязательные разделы** — все присутствуют и после правки: сценарий,
что человек увидит до/после, проблема+контракт по каждому из четырёх
пунктов, скоуп/не-скоуп, UX, модель данных и миграция, i18n, AC1-AC12 с
доказательством, план автотестов, риски, откат, release-артефакты.
- **Дельта c43051ac..7a3dcfd7 не задевает ни один AC** — контракты и план
автотестов текстуально не изменились, поэтому доказательства AC1-AC12
наследуются из r3 без пересчёта.
- **origin/dev не продвинулся** с r2/r3 (`b04387ce`) — основание для разбора
по дельте, а не заново, сохраняется.
- **Продуктовых технических вопросов владельцу не вынесено** — как и в
r1/r2/r3.
- **Три проверки автора** (`check-docs.mjs`, `process-gate.mjs --issues`,
`git diff --check`), названные в передаче revision 4 неявно (те же, что
называл автор в revision 3) — doc-only дерево, не относятся к предмету
находок этого раунда.
## Чего не проверял
- Гейты `tsc`/`test`/`build` — не гонял: `git diff origin/dev...HEAD --stat`
показывает только четыре `.md`-файла, продуктового кода нет. То же
основание, что в r1-r3.
- Не пересчитывал заново инвентарь мёртвых ключей (а), механику снапшотов
(г), контракт (б)/(в) по существу — унаследовано из r3 (SHA `c43051ac`),
дельта r3→r4 их не касается (см. раздел «Унаследовано из r3»).
- Не проверял поведение реального `wa-dialog` глубже, чем сделал r3 (та же
граница: `ha-dialog.ts` не передаёт `type`/`role` внутрь — этого достаточно
для контракта (б), глубже в сторонний пакет ТЗ сознательно не заходит).
- Не проверял `scripts/mutation-gate.mjs` на техническую реализуемость трёх
заявленных мутантов — на этапе ТЗ это описание намерения, не код.
- Не запрашивал у владельца touch/perf-строку DoR — разобрал сам как Low и
снял с записью (см. «Находки»); оба ответа выводятся из уже
зафиксированного в `SCOPE.md`/`TOUCH-SUPPORT.md` факта («View никогда не
показывает destructive-действий»), продуктовым вопросом не является.
## Вердикт
Вердикт: зелёный · заход r4 · блокирующих циклов 3/4 · High: 0 · Medium: 0