25 KiB
SPEC-REVIEW-600-r1 — #600: диалоги настроек разошлись с макетами #591
- Issue: #600
- Этап:
spec(PROCESS.md §2.4) - ТЗ под ревью: тело issue #600, раздел
## ТЗ(коммит94c9d8ad, веткаissue/600-settings-dialogs,HEADдетач на этом SHA) - Трек: полный (аналитика #600 явно отказалась от лёгкого — сложность 8/10 > 3, четыре поверхности, новый UX-контракт Save/dirty, влияние на perf-потолок)
- Заход: r1, блокирующих циклов израсходовано 0/4
- Вердикт: зелёный
Скоуп ревью
Материал этапа — тело issue #600 (## ТЗ) и все 9 комментариев: разбор архива,
две записи аналитики (S2), пакет из одиннадцати развилок с умолчаниями автора,
решения владельца по Q1–Q11, подтверждение выполнения AC0. Плюс коммит
94c9d8ad (docs: положить дизайн-референс диалогов настроек в репозиторий),
который уже лежит в дереве на момент ревью и добавляет
docs/design/600-settings-dialogs/ (SPEC.md, IMPLEMENTATION-GUIDE.md,
OPEN-POINTS.md, field-maps/FIELD-MAP-space.md, reference/,
screenshots/, README.md, ACCEPTANCE.md) — по решению владельца эти
документы являются частью ТЗ, а не приложением к нему, поэтому проверены
как нормативный материал, а не как справка.
Референсный контекст, прочитанный до вердикта: docs/SCOPE.md, AGENTS.md,
PROCESS.md §1–§9 (в частности §2.2–§2.4, §2.6, §7.1, §7.2), тело и все
комментарии #600, docs/USER-GUIDE.ru.md (для проверки терминологии
переименований Q6 — сверка не потребовалась предметно, переименования не
затрагивают уже описанные в гайде формулировки настроек, кроме текстов,
которые сама задача обязана обновить как release-артефакт).
Как проверялось
Ревью ТЗ, не ревью кода: рабочая копия уже на 94c9d8ad, продуктовый код
(src/**) в диапазоне не менялся — только docs/design/**. Прогон
npm test/npm run build не требовался: класс изменения C (документация),
это подтверждено самим коммитом и git show --stat 94c9d8ad.
| Проверка | Результат |
|---|---|
| Обязательные разделы ТЗ по PROCESS.md §7.1 | все присутствуют, см. таблицу ниже |
| Каждый AC0–AC13 — однозначность + способ доказательства | см. «AC» ниже |
| Технические утверждения ТЗ против реального кода | см. «Верификация фактов» |
| Прослеживаемость Q1–Q11 → решения владельца → правки ТЗ | сверено построчно |
docs/design/600-settings-dialogs/ реально существует и соответствует заявленному в AC0 |
ls, сверка секций SPEC.md |
| Признаки «догадка выдана за решение» без пометки предположения | целевой поиск |
| Продуктовые вопросы владельцу вместо технических | сверено — все 11 вопросов продуктовые или лицензионные |
Обязательные разделы ТЗ (PROCESS.md §7.1)
| Раздел | Есть | Где |
|---|---|---|
| Сценарий | да | «Сценарий» |
| Что человек увидит до/после | да | «Что человек увидит до и после» |
| Проблема | да | «Проблема» |
| Скоуп и не-скоуп | да, с явным перечнем файлов | «Скоуп / не-скоуп» |
| Контракт поведения | да, десять пунктов К1–К10 | «Контракт поведения» |
| UX | да — распределён по «Набору контролов», «Поведению на разных экранах», «Составу диалогов», а не под одним заголовком | см. ниже |
| Модель данных и миграция | да | «Нет» |
| i18n | да | «i18n» |
| AC1…ACn с доказательством | да, AC0–AC13, у каждого «чем доказывается» и «чем краснеет» | «Критерии приёмки» |
| План автотестов | да | «План автотестов» |
| Риски | да, семь пунктов | «Риски» |
| Откат | да | «Откат» |
| Release-артефакты | да | «Release-артефакты» |
UX-раздел не собран под одним заголовком «UX», но материально присутствует:
«Набор контролов» (таблица примитивов с числами из §3.1 источника),
«Поведение на разных экранах (Q7)» (три полосы, семь контрольных ширин) и
«Состав диалогов» (ссылка на §4–§7 SPEC.md) вместе покрывают то же
содержание, что требует §7.1. Как и в прецеденте SPEC-REVIEW-89-r1 (находка
L1, риски без отдельного заголовка), рассеянность по разделам не делает текст
неисполнимым или непроверяемым — единственный критерий блокировки на этом
этапе. Отмечаю как Low-наблюдение, не как находку, требующую действия.
Верификация фактов
Основная часть работы — задача сама объясняет, что предыдущие три захода
(#594, #598, #599) провалились именно из-за непроверенных утверждений
(«К7 выполнен, значит референс не нужен» и т.п.), поэтому каждое конкретное
техническое утверждение ТЗ сверено с текущим деревом на 94c9d8ad, а не
принято на слово:
- Дефолтная ширина диалогов 500 px, а не 560. Подтверждено:
src/hp-dialog.ts:169—width: min(var(--hp-dialog-wide-width, 500px), 94vw). data-kindуже проставлен на всех четырёх диалогах. Подтверждено:grep -l data-kind src/editors/*.tsвозвращает все четыре файла (space-settings-dialog.ts,general-settings-dialog.ts,room-settings-dialog.ts,marker-dialog.ts).- Три сегмента уже стоят (
gs-bg-mode,space-bg-mode,space-zero-wall-style). Подтверждено по исходникам этих трёх диалогов. - Двенадцать смоков держатся за
.srcrow/.dispsection. Подтверждено ровно:grep -rln "srcrow|dispsection" demo/smoke_*.mjsдаёт 12 файлов — число из аналитики S2 не устарело на момент ревью. - Потолок ленивого графа:
LAZY_EDITOR_GZIP_CEILING = 222 900,LAZY_GRAPH_CEILING_BAND = 2 000. Подтверждено дословно вscripts/bundle-budget.mjs:393-394. editor.loading= «Загружаем редактор…» вru.json. Подтверждено — прямой дефект #9 описан точно, ключ существует и требует правки текста, не переименования ключа;editor.loading_ariaрядом и намеренно не трогается.- Замороженные фикстуры панели существуют (
test/fixtures/summary-panel-editor.css, К9/AC11) — файл на месте. - Мутанты, названные существующими (
state-callout-hidden-under-help,dialog-card-loses-its-heading) действительно есть вscripts/mutation-registry.mjs; два новых (dialog-control-writes-to-a-neighbour-key,dialog-segment-drops-radio-semantics) корректно не найдены — план автотестов честно относит их к работе задачи, а не выдаёт за готовые. Мутант «на инверсию слоёв» и «на Save активен без изменений» из плана автотестов также ещё не существуют — ожидаемо, план их и не называет существующими. - Смоки, названные по имени в AC6/AC7/AC5 (
smoke_esc_dialogs,smoke_help_affordance,smoke_color_picker_consumers) — все три файла существуют вdemo/. docs/design/600-settings-dialogs/реально содержит заявленное в AC0:README.md,ACCEPTANCE.md,SPEC.md(273 строки, секции §1–§12 + «Принятые технические предположения» — совпадает с описанием),field-maps/FIELD-MAP-space.md,reference/,screenshots/— на месте. AC0 на дату ревью уже выполнен, что и заявлено последним комментарием.- §4.2/§5.2/§6.2/§7.2 архивного
SPEC.md(полные карты «контрол → ключ состояния», на которые ссылается К1) действительно существуют как подразделы «Состав карточек» / «Состав и правила» внутри §4–§7 — ссылка ТЗ не бьёт в пустоту. - Q1–Q11 → решения владельца → правки ТЗ сверены построчно: Q2 (образцы
карточки остаются) и Q5 (только раскладка, без нативного пикера) — оба
места, где решение владельца разошлось с умолчанием автора и с
SPEC.mdоригинала, — оба явно и без потери смысла отражены в разделе «Решения владельца 20.09» и продублированы в контракте (К... нет отдельного пункта, но упомянуты в «Набор контролов» и AC5/AC1). Ни одно решение владельца не потеряно и не переврано при переносе в нормативный текст. - Вопросы владельцу все продуктовые или лицензионные, ни один не является
техническим, замаскированным под продуктовый (Q11 — лицензия на перенос
материалов, тоже не техническая деталь реализации, а вопрос прав на
контент). Технические развилки (модуль
form-kitvs новыйsettings-form-view.ts, имена классов/ключей) автор решил сам и вынес в «Принято предположительно», как и предписывает §7.1.
Ни одного утверждения о текущем состоянии кода, не подтверждённого чтением
дерева на 94c9d8ad, не найдено.
Находки
Ни одной High. Ни одной Medium. Одна Low — разобрана и снята здесь же с записью.
L1 — регресс-гарантия для существующих кнопок действий не названа отдельным AC
Архивный SPEC.md (§11, AC8: «Copy, Delete, Hide, Skip, Keep as walls,
Export/Import, Optimize, Read ZHA / Update map, Attach, Pin, Open in HA
работают как до задачи») содержал отдельный критерий приёмки на то, что
существующие кнопки-действия внутри четырёх диалогов не сломаются при
перестройке карточек и футера вокруг них. При переносе в тело issue этот AC
не появился ни как отдельный пункт, ни как явно объявленное отступление (в
отличие от Q2/Q5, которые в тексте прямо помечены «против умолчания автора»).
Формально это расхождение с материалом, который сама задача называет частью
ТЗ, без объявленной причины — ровно то, чего требует избегать формулировка
«расхождение оформляется ссылкой на пункт документа, а не „на глаз“».
Проверка по коду показала, что фактический риск невысок: клик-обработчики
этих кнопок (_readZha, openSpaceCopyDialog/_deleteSpace,
_saveRoom/canSaveNew, обработчик Pin в marker-dialog.ts:546-549)
находятся в стороне от заменяемых примитивов (радиосписок → сегмент, чекбокс
→ строка-тумблер и т.д.) — редизайн трогает только обёртку разметки, а не
привязку событий. Часть функций уже защищена независимыми тестами вне
двенадцати смоков-опор, которые будут сознательно переписаны
(test/space-copy-runtime.test.mjs, test/space-dialog.test.mjs,
demo/smoke_danger_confirmation.mjs, test/zigbee-topology.test.mjs,
demo/smoke_zigbee_topology_hover.mjs, demo/smoke_space_copy.mjs и другие
smoke_optimize_*/smoke_*_reconciliation). Явного smoke-свидетеля для
«Pin» (marker.icon_pin_auto) и «Attach»/«Keep as walls» в create-режиме не
нашлось, но это уже существующий пробел покрытия, не новый, и он не входит в
скоуп задачи (задача не трогает эту логику, только оборачивающую разметку).
Вердикт по находке: снимается с записью. Отсутствие своего номера AC не
делает ТЗ неисполнимым — блокирующий критерий этапа ТЗ; AC13 («Полный набор
зелёный: npm test, npm run gate:small») и явное требование плана
автотестов «в хендоффе перечисляется, какой смок и почему» правкуется под
каждый из двенадцати переписываемых смоков — при выполнении этого требования
регресс в перечисленных кнопках будет пойман тем же механизмом, каким ловится
любой другой регресс со смены разметки. Рекомендация автору (не обязательна
для этой редакции, годится на код-ревью или в хендофф): явно перечислить эти
кнопки как часть AC4 или как отдельную строку плана автотестов — «действия
Copy/Delete/Skip/Keep as walls/Export/Import/Optimize/Read ZHA/Update
map/Attach/Pin/Open in HA не меняют поведение, только окружение» — так
код-ревью получит именованный критерий вместо необходимости реконструировать
его из архивного документа.
Что проверено и корректно
- Все обязательные разделы §7.1 присутствуют по содержанию (см. таблицу выше); UX рассредоточен, но не потерян.
- AC0–AC13 пронумерованы без пропусков, у каждого явно указано и «чем доказывается», и «чем краснеет» — сильнее минимального требования §2.5 («указано, чем доказывается»).
- AC0 на дату ревью уже фактически выполнен и проверен:
docs/design/600-settings-dialogs/на месте, содержит заявленные документы, референс не участвует в бандле (утверждение коммита94c9d8ad, не перепроверялось повторным запускомbundle-tree— см. «Чего не проверял»). - Одиннадцать открытых точек (
OPEN-POINTS.md) корректно доведены до владельца одним пакетным комментарием, каждая с предложенным умолчанием и рекомендацией автора — по форме и духу PROCESS.md §7.1 («вопросы задаются одним комментарием, пачкой, каждый — что неясно / что изменится / вариант по умолчанию»). Отклонения автора от умолчаний оригинальногоSPEC.md(Q1 fallback, Q4, Q7 — «решено молча и неправильно» на прошлом заходе) честно возвращены владельцу как открытые вопросы, а не оставлены свершившимся фактом — именно то, что было нарушено в #598/#599. - Два места, где решение владельца разошлось с рекомендацией/умолчанием
автора (Q2 — образцы карточки остаются; Q5 — только раскладка без
системного пикера), в тексте ТЗ прямо помечены как расхождение с
SPEC.mdавтора — выполнено требование «расхождение оформляется ссылкой на пункт документа». - Контракт поведения (К1–К10) покрывает данные (К1), инверсию только в UI
(К2), наследование (К3), скрытые прототипом ветки (К4), видимость
сообщений о состоянии (К5), единственный скролл (К6), доступность (К7),
граф загрузки (К8), заморозку панели (К9) и Save/закрытие (К10) — то есть
ровно те риски, которые аналитика #591/#598/#600 определила как причину
прошлого провала (ложный паритет, потеря
rhint-текстов, скрытие callout'ов под «?», заморозка смоков вместо честной проверки). - Классы риска §2.6 явно пройдены в самом ТЗ (async — н/п, данные и права — К1/AC3, геометрия — н/п, визуал — главный риск с AC10/AC1, объём/perf — AC12, host/input — К7/AC2/AC9) — облегчает будущий DoR и код-ревью.
- Технические решения (структура
form-kitвместо нового модуля, имена классов/ключей, механика dirty-состояния) корректно отнесены в «Принято предположительно, поменять свободно» и не заданы владельцу как вопросы — ни одного технического вопроса в пакете Q1–Q11 не найдено. - Провенанс архива-источника (
SHA-256 06f07fc2…) сверен дважды (аналитик → автор архива в #591, затем владелец лично передал архив 20.09) и зафиксирован вdocs/design/600-settings-dialogs/README.md; вопрос лицензии (Q11) закрыт владельцем явно («сотрудник, внешний грант не нужен»), а не предположен. - Порядок работ (Space → General → Room → Device, один issue, парные отчёты по каждой серии) прослеживается до решения владельца по Q9 без искажения.
Чего не проверял
- Гейты
npm test/npm run build/npm run bundle:budgetне запускались — на диапазоне этого ревью нет изменений класса A/B/D (толькоdocs/design/**), запуск проверял бы пустое множество; численные значения потолка (222 199/222 900/2 000) сверены чтением исходника, а не пересчётом бандла. - Не перезапускал
bundle-tree/npm run bundle:syncдля повторной проверки утверждения «в бандл из референса не попадает ничего» (заявлено в предыдущем комментарии «AC0 выполнен») — доверился заявленному результату зелёногоrepo-hygieneи полного набора «2793 pass, 0 fail», это будет ре-проверено гейтами код-ревью на реализации. - Не читал
reference/(9 модулей, 388 строк CSS) построчно как код — по решению владельца от 18.09 он не исполняется и используется только как текст-источник чисел; численные значения из §3.1SPEC.md, которые ТЗ переиспользует, сверены с таблицейSPEC.md, а не с самим CSS референса. - Не оценивал реализуемость конкретных CSS-чисел (радиус 11, gap 16 и т.п.) на реальных темах HA — это предмет код-ревью и golden-эталонов, а не текста спецификации.
- Не проверял, действительно ли
smoke_settings_dialog_cards.mjsи другие файлы, упомянутые в §10SPEC.mdкак подлежащие правке, содержат ровно те сценарии, которые там описаны — это будет предметом код-ревью, когда правки появятся, а не ревью текста ТЗ.
Вердикт
Зелёный · заход r1/4 · High: 0 · Medium: 0 → нет новых issue.
ТЗ проверяемо, каждый AC0–AC13 имеет однозначный способ доказательства,
десять продуктовых развилок закрыты явными решениями владельца без потери
смысла при переносе в нормативный текст, а технические утверждения о
текущем состоянии кода выдержали построчную сверку с деревом на 94c9d8ad.
Единственная находка (L1) снята с записью и рекомендацией на будущее.
Следующий статус — «Готово к разработке» (S5-ready).
Материал раунда
- Ветка:
issue/600-settings-dialogs, коммит94c9d8addf3f— ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. - Дерево материала:
84be0429b2b9a13a50086986b601bdd88bac4317git log --all --format='%H %T' | grep 84be0429b2b9 - Тело issue:
2871bca5cd192e74cd862e2a4db109f96d559aecf77c8c2032369475e76aa1c6 - Вердикт конвейера:
green· High 0