Волна 4 эпика #674. docs/testing-notes/: восемь ручных чек-листов по поверхностям и индекс удалены — ни одного отмеченного пункта, ручной фазы в PROCESS.md §2 нет. Правило #650 (пустое совпадение --test-name-pattern) перенесено в TESTING.md; пункты [manual] без автоматического свидетеля сведены в раздел «Чего не проверяет автоматика» (реальный HA, сенсорное устройство, ресурсы сервера, несколько клиентов, визуальная оценка, пользовательское содержимое). В TESTING.md снят блок чек-листов v1.43–1.44 и приложения по issue в разделе golden (#197/#249/#272/#275/#288/#261) — сцены объявлены в demo/golden/matrix.mjs. Остался реестр браузерных гвардов #659 (mutation-browser-guards.md). test/testing-notes-index.test.mjs → test/testing-doc.test.mjs: лимит 800 строк, правила #85, раздел ручных проверок и живые ссылки TESTING.md; каталог testing-notes содержит только реестр. Мутант testing-notes-index-drops-section (удалял строку индекса) → testing-doc-drops-manual-section. golden-matrix: копия 67 id сцен #242/#250 в чек-листе снята, список и способ его измерения — в demo/golden/matrix.mjs. docs/design/505-summary-panel удалён вместе с demo/capture_summary_panel_505.mjs и маршрутом /reference/ фикстуры диалога. docs/design/600-settings-dialogs: reference/, screenshots/, pairs/, ARCHIVE-README, ISSUE-FORM, OPEN-POINTS удалены; SPEC, IMPLEMENTATION-GUIDE, field-maps, ACCEPTANCE остаются; вывод capture_design_pairs_600.mjs и verify_ha_form_shell_609.mjs --capture — в artifacts/. docs/design: 68 файлов / 4,08 МБ → 13 / 0,70 МБ. README-ha-dialog-505.md → README-ha-dialog.md (путь в release-review.yml); demo/guard/README.md: запись гварда — в verify-guard.mjs, не в README. docs/design/649-25d-stage6 не тронут — пункт после стабильного v1.78.0. Issue: #681 User-Visible: no Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
17 KiB
#600 · приёмка против референса
Запись закрытой задачи. Кадры
pairs/,screenshots/и прототипreference/, на которые она ссылается, удалены из дерева в #681 и лежат в истории git (git checkout f989fbfe -- docs/design/600-settings-dialogs); новая съёмка пишет вartifacts/design-pairs-600/.
AC1 в #600 требует не «эталоны изменились», а парное сравнение с референсом:
для каждого диалога кадр продукта рядом с кадром референса, и каждое расхождение
названо со ссылкой на пункт SPEC.md или узел reference/.
Этот документ — место, где такое сравнение живёт. Он пополняется по мере реализации, по одной таблице на диалог, и предъявляется на код-ревью вместе с кадрами.
Как снимать парные кадры
Кадры продукта — одной командой из корня репозитория, на собранном бандле:
npm run build && npm run bundle:sync
node demo/capture_design_pairs_600.mjs # → artifacts/design-pairs-600/<диалог>-<тема>.png
Скрипт открывает четыре диалога в состояниях макетов (пространство с
температурной заливкой и своим севером, общие настройки со статическим фоном,
комната с эффективной температурной заливкой, привязанный светильник с ролью
Always и фиксированным свечением), раскрывает скроллер на всю высоту и снимает
поверхность 560 px в светлой и тёмной теме. Кадры референса — screenshots/
из архива дизайнера (светлая тема, 1120 px при devicePixelRatio 2).
Это диагностические кадры, а не golden-базы: они не принимаются
golden:accept и не участвуют в golden:verify. Эталоны живут отдельно и
закрываются AC10: принято 13 сцен (ed2af1b1) — одиннадцать из ТЗ (список
AC10 унаследован от #598, где диалог комнаты не менялся) плюс две
room-temperature-dialog-{desktop-en,mobile-ru}, потому что диалог комнаты в
скоупе #600. PNG пережаты в палитру 256 цветов — для сравнения
раскладки этого достаточно, а вес папки остаётся в полумегабайте.
#609: оболочка в настоящем Home Assistant
Парные кадры выше были сняты в нативной ветке hp-dialog. Для #609 отдельно
проверена ветка настоящего ha-dialog из закреплённого
home-assistant-frontend==20260729.7 (SHA-256
ba01782297e9506d3185f99a74d829f3811df322623848af21bcc0b8ea834c12):
npm run bundle:sync
node demo/verify_ha_form_shell_609.mjs --capture
Официальный компонент и его CSS не модифицируются; локальная фикстура не поднимает HA, не обращается к сети и падает при внешнем запросе, WebSocket или ошибке страницы. Измерения после завершения 200-миллисекундной анимации показа:
| Режим | Поверхность | Проверенный результат |
|---|---|---|
| desktop 1600×1000 | 560×940 | канва вокруг карточек, один скроллер .body HA, footer внутри |
| dark + text 200%, 1600×1000 | 560×940 | root font 32 px, один HA-скроллер, footer внутри, канва не сливается с карточками |
| граница 480×800 | 480×800 | fullscreen, радиус 0, горизонтального переполнения нет |
| mobile 390×844 | 390×844 | fullscreen, радиус 0, footer внутри |
| низкое окно 1280×480 | 1280×480 | штатный fullscreen HA сохранён |
Снимки приёмки: pairs/room-ha-light.png,
pairs/room-ha-dark-text-200.png и pairs/room-ha-mobile-light.png. Это
диагностические доказательства, а не
golden-базы; 13 нативных golden-сцен остаются неизменными. Быстрый обязательный
свидетель тех же публичных CSS-контрактов —
demo/smoke_ha_form_shell_parity.mjs, а перечень пяти потребителей оболочки
закреплён в test/form-shell-consumers.test.mjs.
Статус по диалогам
| Диалог | Серия | Референс | Продукт (светлая / тёмная) | Расхождения названы | Готово |
|---|---|---|---|---|---|
| Space settings | 1 | screenshots/space-settings-2026-09-18.png |
pairs/space-light.png / pairs/space-dark.png |
ниже | да |
| General settings | 2 | screenshots/general-settings-2026-09-18.png |
pairs/general-light.png / pairs/general-dark.png |
ниже | да |
| Room settings | 3 | screenshots/room-settings-2026-09-18.png |
pairs/room-light.png / pairs/room-dark.png |
ниже | да |
| Device on the plan | 4 | screenshots/device-on-the-plan-2026-09-18.png |
pairs/device-light.png / pairs/device-dark.png |
ниже | да |
Расхождения с референсом, по диалогам
Каждая строка — что видно на кадре продукта иначе, чем на кадре референса, со
ссылкой на пункт SPEC.md или узел reference/, и чем это закрыто.
Space settings (§4)
| Что | Референс | Продукт | Основание |
|---|---|---|---|
| Образец карточки комнаты | убран (§4.2) | внутри карточки Room cards на тинте | решение владельца Q2 |
| Поле цвета | input[type=color] (§3.2) |
плашка вокруг hp-color-opacity |
решение владельца Q5 |
| Тексты подписей | Space name, Floor plan, Appearance, Room cards, Sun & light… | те же (переименования Q6) | §4.1, решение владельца Q6 |
| Подписи сегмента заливки | Custom · Zigbee · Lights · Temperature | те же — короткие ключи fill.seg_* ленивого словаря, общие с комнатой (r1 M1: полные fill.* в RU переносились посреди слова) |
§4.2 reference/app.js fillOptions |
| Копия / удаление | Copy и Delete слева в футере | то же | §4.1 «Футер» |
General settings (§5)
| Что | Референс | Продукт | Основание |
|---|---|---|---|
| Zigbee links | один заголовок, тумблер, callout | то же: блок hp-zigbee-topology-settings в режиме embedded без своего заголовка |
§5.1, дефект 1 из #600 |
| Плитки цвета | 3 в ряд, hex, число прозрачности | то же; свотч — trigger прежнего пикера | Q5 |
| Компас | 44 px справа от поля севера | то же, с сохранённым перетаскиванием стрелки | §3.1 «Компас»; прежний ввод с свидетелем smoke_sun |
Room settings (§6)
| Что | Референс | Продукт | Основание |
|---|---|---|---|
| Образец карточки | убран (§6.1 «Font sizes») | под подсказкой размеров, на тинте | решение владельца Q2 |
| «?» у Basics | у поля Home Assistant area | у поля Home Assistant area (перенесён с заголовка карточки) | §6.1 |
| Подписи сегмента заливки | None · Zigbee · Lights · Temperature · Custom, по одной строке на пункт | те же — короткие ключи fill.seg_* (общие с пространством). Ревью r1 M1: «Temperature» рвалось посреди слова в пяти равных колонках — колонка сегмента больше не сжимается ниже самого длинного слова, слова переносятся только по пробелам, не поместившийся сегмент переносится на вторую строку целыми кнопками; свидетель — smoke_dialog_segments_i18n (четыре диалога × en/ru/de/fr) |
§6.1, §3.1 «Сегмент» |
| Подписи источников | Temperature / Humidity | Temperature source / Humidity source (прежние ключи) | текст, не раскладка |
| Поле цвета «Свой цвет» | input[type=color] |
плашка вокруг hp-color-opacity |
Q5 |
| Кнопка выбора датчика | в потоке, панель с поиском | то же (sourcePicker набора) |
§3.1 «Кнопка выбора источника» |
Device on the plan (§7)
| Что | Референс | Продукт | Основание |
|---|---|---|---|
| Подписи сегмента привязки | Virtual device · Pick from the HA list | Virtual device (no binding) · Pick from the HA list | прежний ключ marker.virtual_option; текст, не раскладка |
| «Show entities» | в панели выбора рядом с поиском | то же | решение владельца Q8 |
| Ask for confirmation | скрыта при Do nothing | показана только при toggle / run | Q8; прежнее условие |
| Display preview | упрощённый макет: сцена и таблица фактов | hp-device-preview целиком со своим заголовком «Display preview · Now» и переключателем деталей |
решение владельца Q3, §3.1 «Превью маркера» |
| Additional actions | строка-тумблер «This is a presence radar» | подзаголовок и кнопка «Объявить радаром» — прежнее действие радара; секции радара и пылесоса внутри диалога рисуются своими модулями без изменений | §7.2: ветки вне прототипа теми же примитивами; внутренняя разметка радара — вне скоупа #600 |
| Иконка | поле с превью, Clear, Pin в подсказке | то же; в HA — ha-icon-picker вместо текстового поля |
§7.1 |
| Value badge | тумблер, Value, Position сегментом | то же; предупреждения бейджа — заметки и callout'ы | §7.1 |
AC8: девять прямых дефектов выпущенного — свидетель на каждый
| № | Дефект (тело issue) | Чем закрыт | Свидетель |
|---|---|---|---|
| 1 | дублированный заголовок Zigbee links | карточка рисует заголовок и «?», hp-zigbee-topology-settings в режиме embedded своего не рисует |
smoke_general_settings_form → zigbeeHeadingOnce; мутант topology-embedded-draws-its-own-heading |
| 2 | «Fill color» дважды в строке заливки пространства | плашка цвета с одной подписью поля (colorRow + colorField, у пикера hide-label) |
smoke_space_settings_form → hexIsPrinted, noNativeColorInputs; noLegacyMarkup |
| 3 | семь rhint-абзацев в четырёх диалогах |
пояснения — под «?» (_help/shelp), сообщения о состоянии — callout'ы (К5) |
noLegacyMarkup в четырёх фокусных смоках (класс .rhint отсутствует); test/i18n-dead-keys; мутант state-callout-hidden-under-help |
| 4 | карточка внутри карточки (fieldset в Light and glow, Value badge) |
плоские блоки .hpf-block с подзаголовком |
smoke_device_settings_form → noLegacyMarkup (fieldset, .markerlightgroup), badgeBlock, neverDisablesGlowBlock |
| 5 | поповер «?» обрезается границей диалога комнаты | подсказка живёт в top layer (Popover API) либо в портале .overlay-portal вне поверхности диалога; тело формы без своего скроллера — резать нечем |
smoke_dialog_help_clipping: короткое окно, «?» нижней карточки комнаты, подсказка выходит за край скроллера и остаётся hit-test'ируемой во всех точках; четыре ветки — нативный <dialog> и ha-dialog × Popover и fallback. Ветка ha-dialog — заглушка с ловушками настоящей mwc-поверхности (transform + overflow: hidden + свой скроллер); настоящий ha-dialog (#505, загрузка колеса HA-frontend) — отдельная диагностическая приёмка владельца, demo/capture_summary_panel_505.mjs как образец |
| 6 | белый инпут на тёмной теме у Glow radius | поле набора .hpf-unit на токенах темы |
pairs/device-dark.png; smoke_device_settings_form |
| 7 | два скролла (тело формы и оболочка) | скроллер один — .content в hp-dialog; .body без max-height/overflow |
фокусные смоки → singleScroller / bodyHasNoOwnScroller |
| 8 | пустое пространство внизу | .body без max-height и лишнего padding-bottom |
те же; кадры pairs/ |
| 9 | «Загружаем редактор…» | editor.loading → «Загрузка…» / «Loading…» |
src/i18n/*.json |
Принятые адаптации
Расхождения, которые не являются дефектом, потому что продиктованы контрактами House Plan или решением владельца. Заполняется по ходу работы; каждая строка — с доводом, а не «так вышло».
| Место | Референс | Продукт | Почему |
|---|---|---|---|
| Образцы карточки комнаты | убраны (SPEC.md §4.2, §6.1) |
сохранены, встроены в карточку | решение владельца Q2: слайдер размера без образца — подбор вслепую |
| Поле цвета | нативный input[type=color] (SPEC.md §3.2) |
прежний hp-color-opacity, новая только раскладка |
решение владельца Q5; nativeColors() === 0 — контракт со свидетелем smoke_color_picker_consumers |
| Цвета | фиксированные hex (#4a9ec6, #f6f6f6, …) |
переменные темы HA | SPEC.md §2 «допустимые адаптации»; тёмная тема обязательна |
| Шапка | круглая кнопка × слева, заголовок, бейдж справа | прежняя шапка hp-dialog (× справа) с бейджем в слоте заголовка |
SPEC.md §3 «Шапка»: «существующая шапка hp-dialog; бейдж добавляется» |
| Тумблеры | input[type=checkbox][role=switch] с нарисованной дорожкой |
нативный чекбокс, нарисованный CSS набора; ha-switch не используется |
К7: один вид в HA, на стенде и в golden; smoke_ha_controls |
| Радар и пылесос внутри диалога устройства | нет в прототипе | прежняя разметка секций (radar-section.ts, _renderVacSection) |
SPEC.md §7.2: ветки вне прототипа; их внутренняя раскладка — отдельная задача |
| Высота строки подписи | 22 px, «?» 22 px | 32 px — по высоте кнопки hp-help |
подписи с «?» и без стоят на одной линии в сетке из двух полей |