settings.decor_default_style (all fields optional, validated) seeds
_decorStyle once from the first config that arrives; every UI change of
the session default flows through one runtime method with a 1s debounce
and the ordinary serialized expected_rev write path. The built-in default
is stored as the absence of the key; a partial or garbage key falls back
per-field. decorStyleFromSettings/decorStyleToSettings are the single
snake_case<->camelCase conversion point.
User-Visible: yes
Issue: #377
V6a: pass the stable devices array to resolvedLightSources — the WeakMap
cache is keyed by array identity, a spread guaranteed a miss on every
render in BOTH cards (full-card regression since beta.4).
V6b: the static wall geometry now carries the same non-enumerable
sourceFingerprint tag the full card attaches, so buildLightBarrierScene
takes the fast recutWallBodiesGeometry path on door state changes.
V6c: the static barrier-scene cache is an LRU of 8 per space (parity
with _lightBarrierPool) — a flipping door reuses both of its scenes.
V6d: enabledClip is cached by geometry fingerprint + disabled-room set,
with the full card's bbox prefilter for decor bodies.
User-Visible: yes
Issue: #375
The loadGerman-swap mutant tree-shook src/i18n/fr.ts, so the manifest
emit guard failed the mutant BUILD instead of the guard smoke. The
mutant now keeps import('./fr') alive and returns the English
dictionary, which only demo/smoke_french_locale.mjs can catch.
User-Visible: no
Issue: #371
The entry-removed variant died at build time (tree-shaking drops the fr
chunk and the manifest emit guard refuses the bundle) — an infrastructure
failure, not a red guard. The mutant now swaps the fr entry to the German
loader instead: everything builds, parity units stay green, and only the
French smoke catches the wrong dictionary.
Issue: #371
User-Visible: no
The complete French dictionary contributed in #371 (1026 keys, zero empty
values, zero placeholder mismatches) lands as the second lazy locale on the
fr.ts + one static entry. The contributor's snapshot predated this week's
keys, so the 121 additions (device inbox #29, backdrop guard #39, junction
limits #331, lazy-editor toasts #353/#354, furniture #159) are translated
in this commit and flagged in the issue for the author's review; 21 stale
pre-#62 keys are dropped; key order follows en.json. The HA integration
translations file ships as contributed (full parity).
Wiring: loadFrench + __HOUSEPLAN_FR_RETRY_ASSET__ with the same 1/1
replacement guarantee as German; locale roles and localeRoots generalise to
(de|fr); the stale-entry fallback panel (#353) gains its French branch —
the r1 reviewer caught that this second hardcoded language list would have
silently degraded French to English on a cached entry. French profiles
(fr, fr-FR, fr-CA, fr-BE, fr-CH) select automatically.
Proofs: the registry-driven parity suite covers fr by construction
(1128/1128 keys); French analogues of both German-personal tests (product
glossary + non-translation scan with a reviewed equal-to-English
allow-list of 22 legitimate homographs); smoke_french_locale — fr-CA
profile commits French from the real bundle, one lazy chunk per page,
initial graph free of fr; smoke_entry_stale gains the French run; a
registry mutant drops the fr entry and is killed by the smoke. Initial
view: +0.5 KB (registry entry + fallback branch); the 23 KB dictionary is
lazy.
Issue: #371
User-Visible: yes
Внешний пользователь завёл #370 как баг: в houseplan-space-card нет теней от
стен, хотя в houseplan-card они есть. Разбор показал, что кода это не касается —
ограничение намеренное и записано в src/space-render.ts:353 («the compact card
intentionally has no live radial pools»). visibilityPolygon из
src/light-visibility.ts импортируют ровно два файла, houseplan-card.ts и
houseplan-editor-runtime.ts; space-render.ts не импортирует его вовсе. Пулов нет,
а тень существует только как форма пула — затенять нечего.
Но претензия справедлива, просто адресована не туда. Единственная запись о
намеренности жила в комментарии исходника, которого пользователь видеть не может,
а руководство обещало обратное: «маркеры используют те же состояния, значения,
тревоги и эффекты, что полный план» — про свет ни слова. В LIGHT.md про
компактную карточку тоже не было ничего. Человек полез в код именно потому, что
документация молчала, и сам корректно предположил, что это может быть намеренно.
Теперь сказано в трёх местах: оба руководства и LIGHT.md, с причиной — пулы это
самая дорогая часть отрисовки, у неё свой перф-воркфлоу и бюджеты, и компактная
карточка платит за дешевизну именно ими.
Issue: #370
User-Visible: no