Решения владельца: 1б — индекс ревью не пересобирается в ветке задачи,
только коммитами, идущими в dev; 2б — бандл меняет только кандидат
беты/релиза, стенд dev берёт его из артефакта Validate.
- scripts/bundle-policy.mjs: коммит, трогающий dist/** или
custom_components/houseplan/frontend/**, обязан нести Release:
(хук commit-msg и история в CI через validate-commit-provenance;
коммиты с датой автора до 2026-09-27 не судятся); --verify судит
целостность свежей сборки всегда, побайтовую сверку с закоммиченной
копией — только на коммите, меняющем бандл, или кандидате; --clean.
- release-prerelease: публикация отказывает, если отпечаток исходников
в закоммиченном манифесте не равен отпечатку дерева (хотфикс поверх
кандидата без пересборки).
- bundle-sync: по умолчанию только demo/srv/assets; --release
(npm run bundle:release) — ещё и custom_components.
- rebase-on-dev: конфликт в бандле берёт копию dev, без пересборки
и amend.
- validate.yml: job dev_build публикует card-bundle головы dev в
сиротскую ветку dev-build (scripts/dev-build.mjs); стенд накладывает
её demo/stand/update-dev-bundle.sh.
- _process.yml: индекс ревью больше не пересобирается при приведении
к dev и при публикации документа в ветку задачи.
- golden-wsl-artifact/golden-container: сборка перед съёмкой не
считается правкой источника, после — bundle:clean.
- test/bundle-tree-committed: судит закоммиченный снимок, не диск.
- 11 мутантов в реестре; PROCESS/AGENTS/DEVELOPMENT/AUTHOR/REVIEWER.
Issue: #657
User-Visible: no
Render only the core and value-badge geometry needed by the common floor-shadow layer. Avoid mounting hidden icons, activity indicators and satellites for every 2.5D marker.
Issue: #649
User-Visible: no
CODE-REVIEW-649-r1 M1: the 2.5D beam's cut by physical bodies (AC7) had no
witness. Unit: a column in the beam leaves the floor between window and
column lit and shades it behind the column; smoke: a Solid partition across
the south beam removes floor from the rendered wash. Mutants: occluders
extruded toward the sun, occluders ignored, card drops occluders.
Lows: L1 stale alpha wording (DEVELOPMENT, ARCHITECTURE, card comment,
benchmark); L3 dark-theme state edges computed per theme; L4 Alert beats a
plain Hover and a plain Selected; L5 a virtual marker has no dashed ring;
L6 tiles and shadows stay without walls (show_borders off).
Issue: #649
User-Visible: no
- settings.volumetric_view (General settings › Display, third switch) replaces
the alpha entry, the header projection toggle and the phone-menu item; one
rule for card, sidebar page and kiosk; editors stay Flat; backend accepts
only a boolean, support package copies it.
- Raised tiles in 2.5D View: no ring, rounded body min(0.275 D, 0.3 h), edge
0.1 D with the lab filters, ×1.12 size also in layout/collision, lift
0.075 D, one floor-shadow layer under all markers (theme × floor table),
frames hugging tile and edge (Alert > Focus > Selected > Hover), forced
colours without edge and shadow (src/iso-tiles.ts, styles/iso-tiles).
- Soft sun wash instead of projected Flat wedges (src/iso-sun.ts): same gates
and windows as sun_rays, length from elevation, parallelogram along the sun,
tone and streaks by floor lightness, sill line.
- Walls take the user's wall colour (top opaque, sides × .77/.68/.60); theme
rules for walls/openings/labels removed; furniture uses the Flat stroke rule.
- Smokes smoke_iso_tiles/iso_sun/iso_theme_walls/volumetric_setting, 16 new
mutants, acceptance scenes STAGE6_ACCEPTANCE_SCENARIOS (golden with their
Linux CI baselines), ACCEPTANCE.md side by side.
Issue: #649
User-Visible: yes
На окне не шире 480 px шапка карточки и страницы бокового меню занимает одну
строку ≤ 56 px: вкладки пространств (без шестерёнок и «+», прокрутка вбок,
текущая вкладка докручивается в видимую область), масштаб, одна шестерёнка
«Действия и настройки» и у админа слот крестика #647. Заголовок скрыт.
Меню шестерёнки (src/header-menu.ts): редакторы, настройки и добавление
пространства, общие настройки, PDF, помощь, сводная панель и объёмный вид
(alpha) — в фиксированном порядке и с теми же условиями и действиями, что у
прежних кнопок. Пункт закрывает меню; Escape возвращает фокус на шестерёнку;
касание вне меню поглощается прозрачной подложкой. На > 480 px шапка прежняя,
в киоске меню нет.
- три кнопки шапки вынесены в renderHeaderActions — шапка карточки не растёт;
- сводная панель отдаёт свои пункты методом menuItems();
- i18n: title.header_menu (en/ru/de/fr);
- потолок initial View 291 000 → 292 600 (замер 291 635), база bundleBytes;
- смок smoke_mobile_view_header, юнит header-menu, 10 мутантов; смоки
support_feedback, gear_tabs, modes, toolbar_stable_width переведены на
меню на ≤ 480 px; подпись вкладки в span.tabtitle без pointer-events;
- USER-GUIDE.ru, UX-MODES, TOUCH-SUPPORT, STYLING-HOOKS, data-hp-contract,
оба changelog.
Issue: #616
User-Visible: yes
Счётчик «N устр.» и ключ count.devices удалены вместе с правилом
`.head .count` (скрывало счётчик на ≤1100 px). Крестик закрытия редактора
вынесен из активной кнопки режима в отдельный слот `.editor-close-slot`
сразу после группы кнопок режимов: 24 × 24 px (--hp-editor-close-size),
одинаковый в редакторе и вне его; вне редактора слот пуст, aria-hidden,
без фокуса и pointer-events. Кликабельная зона × — весь слот (≥24×24, #195),
глиф 13 px; × виден на любой ширине, где видны кнопки режимов.
Смок smoke_toolbar_stable_width (1400/1000/768/390 px, en/ru): ширина
шапки и отступы кнопок стабильны во всех переходах, × виден, попадание
в край зоны закрывает редактор, нет нового overflow. smoke_editor_tabs,
smoke_edge_cases, smoke_hidden_flag переведены на слот/список устройств.
6 мутантов. docs: UX-MODES.md, STYLING-HOOKS.md, data-hp-contract.json.
Issue: #647
User-Visible: yes
Транзитная геометрия Resize теперь только вычисляет центр для текущего кадра и не удаляет сессионную позицию. Окончательная геометрия по-прежнему очищает точку, если она действительно вышла за комнату.
Issue: #645
User-Visible: yes
Кнопка сохраняет положение в пределах комнаты только на время сессии редактора,
корректно отменяется при pinch/cancel и учитывается подписями Resize.
Issue: #645
User-Visible: yes
- scripts/no-new-private-writes.mjs: смоки и demo/helpers/** не добавляют
записей в приватное состояние карточки (присваивание, ++/--, delete по
цепочке с сегментом _x; от this — нет) и вызовов _setMode/_openRoomEdit/
_openMarkerDialog/_openSpaceDialog. Зачёт правки по полю, перенос блока —
movedLinesByFile из no-new-any; исключение // private-ok: <причина>.
--count — остаток на HEAD. Подключён в gate:small и в шаг frontend рядом с
no-new-any, с той же базой.
- demo/helpers/hp-test.mjs: 10 операций через контрактные хуки и события
фикстуры (setMode, setTool, switchSpace, openRoomEdit, openMarkerDialog,
openSpaceDialog, setServerConfig, setLayout, input, close); ставится
launch*() из demo/serve.mjs. В бандле фасада нет.
- demo/srv/demo.html: доставка houseplan_config_updated/_layout_updated,
__pushServerConfig/__pushServerLayout; после доставки запись со старым
expected_rev — conflict, как у настоящего сервера.
- HP_SMOKE_CHECKS=1 печатает имена проверок в finish().
- smoke_area_relocation, smoke_glow, smoke_grid_snap переведены на фасад без
потери утверждений; новый smoke_test_facade доказывает каждую операцию.
- 7 мутантов, docs/TESTING.md (раздел + правило №6), PROCESS.md §2.7, AGENTS.md.
Issue: #629
User-Visible: no
General settings colour tiles (room fills and glow) paint their colour at
its opacity over the checkerboard again, so "No light sources" at 0 % no
longer looks like solid grey. The label ink is chosen from the visible
colour (hex mixed with the checkerboard by alpha). Colour plates
(flat-swatch without cover-swatch) stay solid — now witnessed by the
- hp-color-opacity: one `_solidSwatch` condition drives background and
opacity; cover-swatch keeps the checkerboard
- editors/color-tile-ink.ts: pure isLightHex/colorTileInk, unit-tested
- smoke_dialog_polish_605: tileAlpha, defaultsDiffer, noneInkDark,
liveAlpha, platesFlat, plateSolid; oneSurface drops the opaque check
- mutants M-615-tile, M-615-plate, M-615-label
- USER-GUIDE (ru/en): "Colour tile" row; both changelogs
Issue: #615
User-Visible: yes
На вкладках «На плане» и «Скрытые» — флажки строк, «Выбрать все (N)» по
всему отфильтрованному набору (включая строки за «Показать ещё»), панель
«Выбрано: K · Скрыть/Показать выбранные (K) · Снять выбор» в отдельном
контейнере .device-inbox-batch вне .device-inbox-filters.
- src/device-inbox.ts: чистые inboxVisibilityAllowed (один источник для
canHide/canShow и выбора), selectableInboxRows, effectiveInboxSelection,
applyInboxVisibility — свёртка одиночных действий; одиночное = пакет из
одной строки.
- src/device-inbox-batch.ts (новый, lazy editor): выбор, панель, строка-
флажок и writeInboxVisibility — одна запись houseplan/config/set с
expected_rev на пакет, busy='__batch__' (inert), откат маркеров при отказе,
выбор сохраняется и сужается. Одиночный _setInboxHidden рантайма — тонкая
обёртка над той же записью; рантайм стал короче базы на 14 строк.
- сброс выбора при смене вкладки (клик и стрелка), поиска и «Только новые».
- i18n en/ru/de/fr: 9 ключей по ТЗ §8.
- смок demo/smoke_device_inbox_batch.mjs (AC1–AC8, AC10), юниты
test/device-inbox.test.mjs (AC2, AC4), 4 мутанта в реестре.
- docs: USER-GUIDE ru/en, FILTERING.md, оба changelog.
- monolith-baseline: hostRefs 4948→4959, bundleBytes 2500387→2505569 —
новая фича (состояние выбора и запись идут через порт хоста).
- bundle-budget: LAZY_EDITOR_GZIP_CEILING 245 400 → 246 600 (замер 245 610,
+1 190 Б gzip от базы 244 420); initial View 289 449 → 289 765 (+316 Б,
строки en-словаря), в пределах потолка.
Golden device-inbox-* изменятся ожидаемо — пересъёмка предрелизным гейтом
на Linux CI (§11.4).
Issue: #618
User-Visible: yes
План уходил base64 в WebSocket-кадре: файл больше ~3 МиБ давал кадр больше
4 МиБ, HA закрывал сокет до обработчика, и обещанные 8 МБ были недостижимы.
- бэкенд: HouseplanPlanUploadView (POST /api/houseplan/plans/upload), потоковый
предел MAX_PLAN_BYTES (read_bounded), общий writer store_plan_upload для view
и ws_plan_set (контракт WS без изменений);
- карточка: stagePlanFile/uploadPlanFile/renderPlanBackdropGuard в
backdrop-pick.ts для обоих рантаймов; PlanFilePayload хранит Blob вместо b64;
SVG больше предела — тост при выборе, растр — диалог #39 только с уменьшенной
копией, копия больше предела не попадает в staging, 413 называет предел;
- i18n toast.plan_too_large, backdrop.over_limit_body (en/ru/de/fr);
USER-GUIDE ru/en, CHANGELOG ru/en, docs/testing-notes (#617);
- тесты: test/plan-upload-limit.test.mjs, tests_backend/test_plan_upload.py,
test_ha_upload.py (#617), smoke_plan_upload_limit.mjs; три смока переведены
с b64/plan/set на blob/fetchWithAuth; мутанты plan-upload-*;
- база монолита: hostRefs +3 (общий хелпер плана вместо двух копий в рантаймах,
новый тост уменьшенной копии).
Issue: #617
User-Visible: yes
smoke_danger_confirmation asked for a confirmation as soon as btn.cancel was
translated. With #627 the settings namespace of de/fr settles after the main
catalog; while it is pending the host gate is warm and #417 refuses the
request — the dialog never painted and the smoke crashed intermittently.
The switch now waits until the host drops aria-busy (the gate settled), and
the settings-de/fr chunks are delayed by 300 ms so the slower-namespace order
is deterministic instead of a CI-speed coincidence. New checks name the lost
dialog directly instead of a TypeError.
Issue: #627
User-Visible: no
- ru/de/fr трёх словарей пространств — девять ленивых чанков (по одному на
пару «пространство × язык»), английский статически как слой отката;
рантайм — тот же LanguageRuntime (две попытки, отпечаток сборки, fallback,
общий тост отказа), src/i18n/namespace-language.ts.
- Загрузчики рантаймов онбординга и редактора отдают поверхность в рендер
только после того, как словарь текущего языка осел; гейт хоста учитывает
словари загруженной на нём поверхности (смена языка на лету — ветка warm).
Оверлей Zigbee ждёт topology до первой отрисовки.
- bundle-manifest: граф lazyNamespaceLocaleFiles, девять retry-токенов со
строгим счётом «ровно один». bundle-budget: потолок онбординга 28 500
(замер 27 470), редактор 245 400 → 228 900 (замер 227 869), проверки
ленивости и владения по содержимому.
- Смок smoke_lazy_admin_locale (AC4–AC7); регресс-смоки, переключавшие язык
синхронно, ждут гейт вместо ослабления проверок; пять мутантов.
- monolith-baseline bundleBytes 2 500 387 → 2 508 676: +10 чанков (rollup intro
и export на каждый) и записи манифеста; gzip каждой поверхности при этом
уменьшился.
Issue: #627
User-Visible: no
Первый вынос из монолита по образцу live-*/RadarSetupController.
src/optimize-plans-dialog.ts: OptimizePlansDialogState, чистые
preflightDiagnostics/preflightVersionsDiffer и класс OptimizePlansDialog
(open/preview/toggleLivePositions/run/copyDiagnostics/
reportPreflightFailure/render, clipboardFallback) за портом из 18 членов.
Модуль не знает HouseplanEditorHostPort; импортирует его только рантайм,
карточка берёт тип.
Инлайн-фолбэк буфера обмена — WeakMap по объекту диалога
(CODE-REVIEW-295-r1 M2), дедуп dev-лога — поле класса: из карточки и порта
ушли _preflightClipboardFallback и _reportedPreflightFingerprint, пять
делегатов и две стрелки-заглушки. Харнесс (13 смоков, wall-draw-click,
golden) зовёт card._editorRuntime.optimizePlans.* — меняется только адрес.
11 текстовых утверждений i18n.test.mjs о разметке и тосте диалога и гварды
8 мутантов переехали в юнит test/optimize-plans-dialog.test.mjs
(test-build); новый мутант optimize-dialog-imports-host-port.
monolith-baseline: delegates 159→154, portMembers 350→348,
hostRefs 4948→4869, portPrivates 96→94, harnessPrivates 107→101,
bundleBytes 2499647→2499182. Потолки ядер опущены на выигрыш;
потолок lazy editor gzip пересчитан (+555 Б gzip при −465 Б сырых).
Issue: #642
User-Visible: no
Полный прогон для #640 выявил устаревший parity-свидетель после уже слитого #614: прямой путь теперь обязан задавать и сырой текст числовых полей.
Issue: #640
User-Visible: no
Extend the authentic pinned-HA diagnostic with explicit light and dark palettes, a 32 px root-font case, one-scroller geometry assertions, and reviewed evidence images. Correct stale AC references in the mutation descriptions.
Issue: #609
User-Visible: no
Use Home Assistant's public dialog tokens for the reviewed 560 px canvas, height cap, single scroller and mobile fullscreen layout. Keep generic dialogs and the native fallback unchanged, with authentic-HA evidence and mutation witnesses.
Issue: #609
User-Visible: yes
Reviewed the complete Linux Validate artifact 35606718247: one new furniture scene and eight expected dialog-polish changes; 166 other scenes remain unchanged.
Release: v1.77.0-beta.5
Baseline-Reviewed: https://github.com/Matysh/houseplan-card/actions/runs/35606718247
Issue: #603
Issue: #605
Issue: #606
User-Visible: no
Publish corrected 0.4.1 pack, preserve old cactus objects as a read-only alias, and cover the catalog, renderers, editor, PDF and visual scene.
Issue: #606
User-Visible: yes
Count the Optimize action by its label instead of the removed alignall layout class, so the clean mutation guard still protects the action after the polish.
Issue: #605
User-Visible: no
Make colour tiles solid, readable and fully clickable; align Data actions and device icon field with the form kit. Cover narrow Windows layouts and both icon-picker branches with a focused browser smoke.
Issue: #605
User-Visible: yes
Reviewed room settings desktop/mobile and the new 320px discard confirmation from Linux Validate 35566453055; 171 scenes unchanged and 106 environment witnesses.
Issue: #603
User-Visible: no
Release: v1.77.0-beta.4
Baseline-Reviewed: https://github.com/Matysh/houseplan-card/actions/runs/35566453055
С Linux CI Validate 35538133817 приняты ровно восемь визуально проверенных сцен: три базовых диалога устройства, три help/popover-сцены и два цветовых поповера. Остальные 165 сцен сохранены без изменений; строгий allowlist accept.mjs исключил необъявленные расхождения.
Issue: #602
User-Visible: no
Release: v1.77.0-beta.3
Baseline-Reviewed: https://github.com/Matysh/houseplan-card/actions/runs/35538133817
Съёмка — Linux CI, Validate 35515236776 на ec97fd95; приёмка — Windows
владельца с HP_ALLOW_FOREIGN_CAPTURE (#455).
Просмотрены toggle-entity-dialog-desktop-en и
space-room-color-popover-desktop-ru. Остальные 171 сцена совпали; accept.mjs
отказал бы при любом необъявленном расхождении.
Issue: #600
User-Visible: no
Release: v1.77.0-beta.3
Baseline-Reviewed: https://github.com/Matysh/houseplan-card/actions/runs/35515236776