Linux Docs Screenshots 35506234074 снял ветку после исправления скроллера.
Просмотрены space-create, device-editor и device-display-preview; кадр preview
отличается от обычного и показывает блок Display preview. Остальные восемь
сцен совпали побайтово.
Issue: #600
User-Visible: no
Завершение четырёх серий по референсу docs/design/600-settings-dialogs/:
- из eager-листов dialogs.styles.ts и chrome.styles.ts сняты стили прежней
разметки диалогов (.bindsel/.bindharow/.entcheck, .ctrlchip*, .markerhelp*,
.helpfieldlabel, .markerradios, .markerlightdisabled, .markerbadgetechnical,
.markerglowvalue, .fileupload, .descin, .pdfedit/.pdftag, .gsrow,
.ripple-*row, .radaradditional, .togglehint, футеры marker/room) — 5,8 КБ
исходника; с разметки сняты уже пустые классы;
- «Additional actions» карточки Details — подзаголовок и строка действий
набора, без раскрывашки (radar-section.ts, только additional-placement);
- Q3 уточнён по кадру: hp-device-preview стоит без обёртки — у него свой
заголовок «Display preview · Now», второй над ним удваивался; пустое
состояние — блок на тинте;
- §6.1: «?» у комнаты стоит у поля Home Assistant area, а не у заголовка
Basics; подписи сегмента заливки — None · Zigbee · Lights · Temperature ·
Custom (два коротких ключа room.fill_seg_*), источники — «Average of the
room’s sensors / Specific device or entity», режим свечения — «Colour and
brightness» (тексты прежних ключей укорочены под сегменты);
- подпись поля с «?» и без стоят на одной линии в сетке (min-height 32 по
кнопке hp-help); иконка внутри подсказки — inline;
- парные кадры: demo/capture_design_pairs_600.mjs снимает четыре диалога в
двух темах на 560 в состояниях макетов → docs/design/…/pairs/ (8 PNG,
палитра 256, ~0,5 МБ); ACCEPTANCE.md — статус по диалогам, расхождения с
референсом по каждому со ссылкой на пункт SPEC и принятые адаптации (шапка
hp-dialog по §3, тумблеры набора по К7, секции радара/пылесоса по §7.2);
- changelog EN/RU («Не выпущено»), USER-GUIDE ru/en: раздел «Как устроены
диалоги настроек», таблица настроек пространства по новым карточкам,
диалог комнаты, диалог устройства, ссылка «Как у пространства»;
- бюджет: стартовый граф 289 853 — потолок 291 600 → 290 900 (снятые стили);
ленивый редакторский 243 149 — итоговый потолок 243 900 с разбором по
сериям в bundle-budget.mjs.
Golden: 11 сцен диалогов (device-dialog-*, room-temperature-dialog-*,
toggle-entity-dialog-*, device-help-popover-light-ru,
general-color-popover-desktop-en, settings-help-zoom-200-*,
device-ripple-color-popover-mobile-ru, space-room-color-popover-desktop-ru)
прогнаны диагностически (capture, HP_ALLOW_FOREIGN_CAPTURE, только
artifacts/): харнесс проходит все пути без исключений, кадры «different» —
эталоны переснимаются на Linux CI / машине владельца по #455.
Скриншоты документации (06-device-editor, 06-device-display-preview и др.)
устарели по отпечатку — пересъёмка перед кандидатом беты (#479).
Гейты: typecheck, build, bundle:sync (три копии байт в байт), npm test
2793 pass по четырём частям, mutation-gate --check, check-inputs --coverage,
фокусные смоки четырёх форм и смоки диалога устройства.
Issue: #600
User-Visible: yes
AC0 задачи: пока референс лежит вложением в issue, ревью сравнивает продукт с
макетом «на глаз», и ровно это дало выпущенный в 1.77.0-beta.2 ложный паритет —
карточки снаружи, старая разметка внутри.
Содержимое архива `houseplan-settings-design-2026-09-18.zip`
(SHA-256 06f07fc212947ee9da1a39aaab2d14cbd41154cc9effe39bc48e1c2e1517255b,
сверен побайтово с вложением #591) разложено по образцу #505:
- `SPEC.md`, `IMPLEMENTATION-GUIDE.md`, `OPEN-POINTS.md`, карта полей Space —
с этого коммита часть ТЗ: расхождение называется ссылкой на пункт документа;
- `reference/` — свёрстанный прототип четырёх форм;
- `screenshots/` — четыре формы целиком, 560 px, 2x;
- `README.md` — происхождение, отпечаток, границы использования;
- `ACCEPTANCE.md` — место для парных кадров «референс / продукт» по AC1.
Автор — сотрудник владельца (подтверждено 20.09 в #600), внешний грант не нужен.
Windows-лаунчеры `START.cmd` и `START.ps1` не переносились: `node serve.mjs`
делает то же самое. `room-fill.test.mjs` перенесён как документ намерения, CI
его не запускает — под `docs/**` не попадает ни один тестовый glob.
В бандл отсюда не попадает ничего; `repo-hygiene` и полный набор зелёные
(2793 pass).
Issue: #600
User-Visible: no
Linux Docs Screenshots 35476276726 подтвердил отсутствие визуальных изменений во всех 11 сценах; обновлён только fingerprint исходников.
Issue: #585
User-Visible: no
Строгий docs-гейт #585 обнаружил отложенную визуальную дельту уже
смёрженного #598: карточки групп в диалогах пространства и устройства.
Все три кадра просмотрены; остальные восемь Linux-сцен совпали побайтно.
Съёмка и проверка воспроизводимости:
https://github.com/Matysh/houseplan-card/actions/runs/35465854646
Issue: #585
User-Visible: no
`scripts/check-docs.mjs` считает отпечаток от всего `src/**`, поэтому правка
трёх диалогов его состарила, хотя ни один из десяти сценариев `demo/docs`
диалоги настроек не открывает.
`npm run docs:accept -- --identical`: все 11 кадров совпали попиксельно,
принят только отпечаток исходников (81fa92d2). Переснятых кадров нет.
Issue: #598
User-Visible: no
Закрывает находки код-ревью r1 по #598.
M1 — неприкосновенный смок восстановлен. `demo/smoke_tap_run.mjs` вернулся
побайтово к версии `origin/dev`: он один из девяти `.srcrow`-смоков, которые
ТЗ объявило неизменяемыми, и правка в нём обесценивала собственное
доказательство AC2/AC3. Проверки карточек переехали в новый
`demo/smoke_settings_dialog_cards.mjs` — отдельного свидетеля ТЗ не запрещало.
M2 — сегментированный переключатель сделан там, где он обещан и уместен:
`space-bg-mode` и `space-zero-wall-style` переведены из `<select>` в
`segmented`. Остальные выборы в трёх диалогах остаются списками осознанно:
привязка маркера, роль света и режим свечения уже `role="radiogroup"`
(`.markerradios`), позиция значения закреплена смоком
`smoke_device_preview_parity`, списки сущностей и тем длинные. Сокращение
объявлено в ТЗ и в обоих changelog.
M3 — мутант `state-callout-hidden-under-help` патчит теперь оба состояния:
`marker.run_target_gone` и `gs.sun_missing`; гард — новый смок.
Заодно: `ensureFormKitStyles(this.host)` не вызывался ни в одном из трёх
диалогов — стили набора приезжали только из диалога комнаты, и без него
сегменты имели высоту 14 px вместо 44. Нашёл новый смок проверкой
`bgSegmentTargetIsBigEnough`.
Гейты: typecheck, test (2788 pass), build, bundle:sync, три смока,
mutation-gate --check, оба мутанта задачи.
Issue: #598
User-Visible: yes
«Общие настройки», «Пространство» и «Устройство на плане» были плоскими
столбцами. В «Общих» девять подписей-заголовков шли вперемешку с рядами и
абзацами; в «Устройстве» на 760 строк формы не было ни одного деления, и
«Название» лежало в одном списке с «Дополнительными действиями».
Теперь это карточки общего набора: семь в «Общих», четыре в «Пространстве»,
пять в «Устройстве». Набор взят как есть — он поднят в #594 и доказан на диалоге
комнаты и редакторе панели (#597).
Шесть пояснений переехали под «?» к своему заголовку, подзаголовку или строке;
текст не переписан. Два сообщения о СОСТОЯНИИ остались на виду — решение
владельца: `gs.sun_missing` и `marker.run_target_gone` говорят, что настройка
сломана прямо сейчас, а второе ещё и называет пропавшую цель подстановкой,
которой в статической подсказке взяться неоткуда.
`gs.hint` при этом переехал из ленивого support-словаря в основной: «?» читает
текст через `_t`, а не `supportT`. Тест мёртвых ключей сливает оба словаря, так
что копия в support удалена во всех четырёх локалях.
Классы-опоры сохранены намеренно: `.srcrow`, `.dispsection`, `.gsrow`,
`.colorrow`, `.namein`, `.areasel`, `.tempin` остались на своих элементах, а
карточки добавились вокруг. За эти имена держатся одиннадцать смоков, и потеря
любого превратила бы ревью в чтение переписанных свидетелей.
Изменён ровно один смок — `smoke_general_settings`, и изменён в сторону
строгости: вместо одного списка подписей он снимает теперь два (заголовки
карточек и подзаголовки внутри), требует непустоты каждой карточки, проверяет
что радиус свечения лежит ВНУТРИ карточки свечения (подпись такой границей не
была), что четыре переехавших пояснения доступны кнопкой и что их абзацев в
форме не осталось.
`src/houseplan-onboarding-runtime.ts` затронут двумя строками: он второй
потребитель переименованных ключей `space.hide_*_tip` → `space.hide_*.help`.
Один текст — один ключ; дублировать его ради неприкосновенности файла хуже.
Потолок стартового графа поднят 291 400 → 292 500. Выросли СТРОКИ, а не код:
12 новых ключей в четырёх локалях плюс переехавший `gs.hint`. Разметка диалогов
как была в ленивом редакторском графе, так там и осталась.
Свидетели: `state-callout-hidden-under-help` прячет сообщение о состоянии под
«?» и краснит новый блок `smoke_tap_run`; `dialog-card-loses-its-heading`
обнуляет заголовок карточки и краснит `smoke_general_settings` — карточка без
заголовка это снова плоский список, только с рамкой.
Issue: #598
User-Visible: yes
`node scripts/check-docs.mjs` краснел на материале ревью: диф трогает два файла
`src/**`, а отпечаток скриншотов считается от всего `src/**` и устарел. PROCESS.md
§8 называет этот гейт безусловным при любом диффе по `src/**`, и пропуск уже
стоил инцидента — #230, #234 оставили `dev` с красным job `docs` до #237.
Расхождения пиксельного нет и быть не могло: стили панели собираются побайтово
тем же текстом.
npm run docs:accept -- --identical
Все 11 кадров попиксельно совпали с закоммиченными:
принят только отпечаток исходников (f561ec99).
Issue: #597
User-Visible: no
Правка заголовочного комментария `src/furniture-art-runtime.ts` (коммит
`0565c7ad`) входит в корпус отпечатка исходников, поэтому предполёт кандидата
объявил индекс скриншотов устаревшим — строгий режим работает с #586.
Снято локально в каноническом Chromium 151.0.7922.34 через
`docs-accept --identical`: **все одиннадцать кадров совпали попиксельно**,
принят только отпечаток (047e917c). Ровно то, что предписывает ТЗ §9:
комментарий ничего не рисует, и кадры это подтверждают.
`check-docs --strict` зелёный.
Issue: #593
User-Visible: no
Medium 1 по делу: ТЗ §9 называло условие явно — «если там названо число 44 или
союз с примитивами», — условие сработало, а правки не было. Абзац про ленивый
граф арта (#474) до сих пор говорил «the 44 SVG drawings» и молчал о том, что
двенадцати примитивов больше нет.
Теперь там 60 и прямо сказано: библиотека состоит только из дизайнерского арта,
поэтому чанка ждут все предметы, а не 48 из 60. Это же снимает последнее место в
документации, где жило прежнее обещание «двенадцать рисуются всегда» (Q2).
Issue: #593
User-Visible: no
Встроенная библиотека мебели была смешанной: 44 предмета рисовал дизайнер, а
12 — код, прямоугольниками и эллипсами в unit box. Они выбивались из стиля, и
три категории меню (`computer`, `hood`, `oven`) вообще не открывались, потому
что вида сверху для них не было.
Пакет 0.4.0 перерисовывает все 56 существующих публичных ID и добавляет четыре
новых: `computer`, `hood`, `oven`, `cactus`. Каталог становится равен поставке:
60 символов, 32 непустые категории.
Совместимость. Ни один сохранённый план не мигрирует: положение, размер,
поворот, отражение, цвет, прозрачность и толщина линии не трогаются, а
default-размеры всех 56 прежних ID совпадают со старыми до числа — таблица
зашита в `test/furniture.test.mjs`, чтобы сдвиг было видно тестом, а не глазами.
Ловушка, ради которой примитивы удалены целиком. Библиотека собиралась союзом
каталога и `LEGACY_FURNITURE`, и обе половины несли ОДНИ И ТЕ ЖЕ публичные ID.
`BY_ID` — это `Map`, она оставляет последнюю запись, поэтому примитив молча
побеждал дизайнерский рисунок, который его заменял: задача выглядит выполненной,
12 предметов не обновились, ни один существующий тест этого не видит. Поэтому
`LEGACY_FURNITURE`, `RETAINED_IDS`, тип `Prim`, `box()` и `primitivePathD`
удалены, а на дубликаты в каталоге стоит тест и мутант.
Два продуктовых решения владельца (#593):
- `cactus` живёт в категории `plant`, а не `exercise`, как предлагал пакет:
плитка «Тренажёр» рисует тренажёр, и открывать её на кактус — врать о
содержимом палитры. `exercise` остаётся скрытой пустой категорией, непустых
становится 32, а не 33;
- при отказе ленивого чанка с рисунками не рисуется НИЧЕГО. Прежде 12
примитивов рисовались всегда, и `docs/FURNITURE.md` это обещал; обещание
снято. Это единственное место, где задача ухудшает наблюдаемое поведение, и
оно проверяется смоком, а не словом.
Бюджеты. Ревью ТЗ показало, что «бюджет ленивого графа защищён» было
заявлением без гейта: размеры печатались в отчёт и ни с чем не сравнивались.
Добавлены `lazyGraphCeilingViolation` и два настоящих потолка со своим мутантом.
Стартовый граф ушёл ниже полосы, поэтому `INITIAL_VIEW_GZIP_CEILING` опущен
292 400 → 291 400 — вторая половина храповика, без которой выигрыш отыграется.
Провенанс. Документ пакета воссоздан под 0.4.0: грант владельца, имя архива и
его SHA-256. Это единственная исполнимая защита от повторения истории #159, и
она не ослаблена — число проверок в тесте не уменьшилось, а мутант подменяет
хеш и обязан её покраснить.
Свидетели: пять новых мутантов, новая golden-сцена `furniture-new-symbols-light`
для четырёх новых ID, матрица 63 → 64. Шестой мутант правится, а не добавляется:
`furniture-placement-needs-art` ссылался на удалённое поле `g` и переставал
компилироваться — раннер честно отличал это от «пойман» и отчитывался
setup-failure. Ложь мутанта осталась прежней по смыслу, убрана только ветка про
примитив.
i18n: 7 ключей × 4 локали. `furn.cat_exercise` не добавлен — категория скрыта.
Issue: #593
User-Visible: yes
Две находки код-ревью r1 из трёх; третья — эталоны — снаружи песочницы, см.
комментарий в issue.
**Отпечаток скриншотов.** `check-docs` краснел ожидаемо: отпечаток считается от
всего `src/**`, а диф его трогает. Прогнал `npm run docs:accept -- --identical`
— все одиннадцать кадров совпали с закоммиченными **попиксельно**, поэтому
принят только отпечаток исходников (`b678af43`), ни один PNG не переснят. Это
и есть доказательство среды по правилу #334/#401: снимать можно где угодно,
принять получится лишь там, где кадры воспроизводятся.
**Свидетель полей.** Ревьюер прав: снимок черновика доказывал «пишет только
своё» для трёх полей из восьми, а перетипизированный `FILL_CHOICES` и выбор
зоны исполнимого oracle не имели вовсе. Добавлены две проверки по образцу
соседних: смена зоны меняет только `_areaSel`, смена режима заливки — только
`_roomFill`. Зона переключается на «Без зоны»: свободных зон в фикстуре может
не остаться, а этот вариант есть всегда, и имя уже заполнено, поэтому
автоподстановка имени по зоне в игру не вступает.
Issue: #594
User-Visible: no
Шаг 1 эпика #591. Набор поднят из редактора боковой панели — он сделан по
макетам дизайнера и уже живёт в продукте, — а не собран заново по прототипу.
Стили набора выдаёт генератор, параметризованный именами: контейнер формы,
префикс классов, карточки, футер и токены цвета. Это не украшение архитектуры,
а условие переезда панели на общий источник: тест с замороженной фикстурой
показывает, что с параметрами панели генератор отдаёт её нынешние правила
дословно — карточку, обводку фокуса, выключенное состояние и ряд-переключатель.
После этого переезд станет подстановкой, а не редизайном, и пиксели панели не
дрогнут. Сама панель в этом коммите не тронута.
Диалог комнаты собран в четыре карточки: «Основное», «Заливка», «Источники»,
«Размеры шрифтов». Порядок полей прежний, записи прежние — те же ключи
черновика, те же условия «Сохранить», тот же `hp-color-opacity` с атомарной
записью цвета и прозрачности. Пояснения уехали под «?» у заголовков групп
(решение владельца 18.09), выбор источника стал сегментированным
переключателем — под капотом это по-прежнему радиогруппа, поэтому стрелки и
скринридер работают как раньше.
Два измерения определили форму решения, и оба стоило сделать до кода.
Первое: лист набора в синхронном графе дал +1459 Б gzip и пробил потолок
initial View на 415 Б. Диалоги — инструмент администратора, во View их не
открывают, поэтому лист уехал в ленивый редакторский граф и вносится в теневой
корень при открытии диалога — тем же способом, которым это делает боковая
панель. Потолок не поднимался.
Второе: `css` с интерполяцией запрещён минификатором сборки (он намеренно
падает, чтобы не зависеть от рантайма), поэтому лист собирается `unsafeCSS`.
Цена — несжатые пробелы генератора, замерено 59 Б gzip; копия литералом стоила
бы расхождения с генератором, то есть единого источника.
Оставшийся рост initial View — 291 356 → 291 872 Б (+516) — это четыре текста
подсказок в двух встроенных локалях. Тексты сокращены до одного предложения:
подсказка под «?» и должна быть короткой.
`_renderRoomSource` переехал в модуль комнаты вместе со стабом карточки: у него
остался ровно один потребитель.
Issue: #594
User-Visible: yes