(iconDevs.map) and opening symbols (resolvedHosted.map) were still bare
map() calls. The card takes the full cardStyles, so `.device-core`
(background/color 0.15 s), `.device-shell-frame` (border-color) and the
door `.op-leaf`/`.op-arc` (0.6 s) transition, and Lit's positional reuse
turned a list change into an animation of something that never happened.
Measured on dev with a browser witness (one card element, doors on a
partition in both spaces, neighbours in different states):
- setConfig f1 -> garden: 4 nodes outlive the switch (closed door
hp764-g-shut drawn in frame 0 at f1's open angle, matrix(0,-1,1,0); the
same-id door hp764-shared in f1's closed state; mower and gate start in
the ceiling light's orange), 16 transitionrun, 39/65 frames off-final.
- config push (a door inserted first, the first marker hidden): 11 nodes
handed to a neighbour, 35 transitionrun, 38/68 frames off-final.
Both lists are now keyed(space.id, repeat(..., id, ...)), the shape of the
full card (#525/#534) and of the rooms (#745). The outer key makes a door
with the same id on another floor a new object; an id-less opening keys by
its index. The transitions stay: a real contact or light change on the same
object still animates on the same node, and the witness asserts it (catches
a `transition: none` fix). The #742/#745 note in plan.styles.ts now names
these lists too.
Witness: demo/smoke_space_card_identity.mjs (new, linked in smoke-links to
src/space-render.ts). It samples computed styles per frame and compares
each object to its settled look, not just DOM ids (#528). Red on dev as
above, green after: 0 transitions, 0 frames off-final, 0 reused nodes.
Mutants (checked by hand, each red on its own case): markers by map() and
openings by map() (config push), openings without the space key (same-id
door on setConfig). The marker space key has no observable case here, as
device ids are global; it is kept for parity with #534.
Issue: #764
User-Visible: yes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
The on-plan radar setup multiplied SpaceModel room contours by 1000 a
second time. They are render units already, so the outline was drawn at
40000… far outside the fixed "0 0 1000 1000" viewBox, and the
administrator placed mount, heading and references on an empty field.
Dropping the multiplier alone is not enough: the fixed board also cut
every room drawn outside the historical square, and the pointer mapping
ignored the letterbox and clamped presses to [0,1].
The setup now frames the plan with the main card's content frame
(docs/CANVAS.md §4, the same items through the editor host port). It
opens on core and switches to all when core would cut the configured
room; the stored view_box remains the empty-content fallback. The frame
is computed once per session. One pure projection serves every layer:
the contour is drawn as is, mount, heading, pending/reference marks and
the live trail go through plan units x NORM_W, and a press maps back
through xMidYMid meet to unclamped plan units, a press in the letterbox
placing nothing. Stored radar data, the calibration solve, Apply/Save
and View are unchanged.
Tests: a unit table for the projection and the frame (offset frame,
letterbox, negative and >1 plan units, outlier core -> all, empty-content
fallback) and an extended smoke_radar_setup (a room outside [0,1] with
view_box [0,0,1,1], vertices and bbox, known presses -> draft and DOM,
frame stability across presses, live trail and resize, Apply, Cancel,
Escape and reopen, a room without contour, an unknown room). Five
unit-guarded mutants are registered.
Issue: #774
User-Visible: yes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
A 3 s hold in kiosk mode opens the per-screen size dialog. The core card
draws it (`_renderKioskDialog`, `hp-dialog` from the core bundle, core
i18n keys) and the summary-panel runtime, which every card connects on
mount, saves it. Yet `_kioskDialog` was listed in `editorRuntimeRequested`,
so every hold on a wall tablet downloaded the whole editor chunk; with the
chunk unreachable the kiosk also showed "Could not load the editor" (#757
only capped the retries). Dropping it from the condition is the whole fix;
the loader and the gesture are untouched.
Proof: new smoke_kiosk_scale_no_editor runs a cold page, a real 3.4 s touch
hold (CDP synthesizeTapGesture: a long press, not a tap on the new backdrop),
sliders by keyboard, Reset/Close taps, a second hold to reopen, the chunk
refused by the network, and the ordinary editor entry as control. On dev it
is red in 3 network checks (chunk fetched; refused chunk = 2 requests and a
toast); with the fix all 20 checks pass. smoke_lazy_editor_chunk case (a)
pinned the old cycle and now asserts zero requests and zero notices; the
(checked by hand). New mutant kiosk-scale-dialog-loads-editor-runtime
(caught by hand), listed under browser lifecycle guards; the smoke is
linked in smoke-links because it names none of the touched members.
Issue: #763
User-Visible: yes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
A topology snapshot is labelled stale after one hour instead of five
minutes. Nothing refreshes the map on its own and a Zigbee2MQTT scan alone
can take more than ten minutes, so the old age marked almost every map. A
failed refresh still marks the retained snapshot stale at once.
Route lines and arrows now paint over battery indicators. Endpoint markers
rise above the route layer as a whole (#464), battery included, so the
overlay renders a copy of the routes one level higher (z 9, before the
captions in DOM order) clipped to the endpoint battery frames. The frames
are measured in the existing layout frame of the overlay; outside them the
picture is unchanged: endpoint cores stay above routes, captions above
routes and batteries (#792 AC7). The copy carries no data-hp, so route
counts and selectors stay as they were; parent-caption arrows update in both
layers.
Tests: smoke_device_battery_zigbee gains a local link whose route crosses a
whole battery frame — the hovered endpoint's and the neighbour endpoint's,
Flat and 2.5D, sampled along the drawn line. On dev three of the four probes
are red (2.5D neighbours are not raised today). New mutant
zigbee-route-copy-under-battery (manually red); the parent-LQI mutant anchor
follows the refactored route list. smoke_zigbee_topology_hover age fixtures
move to the one-hour boundary. The golden routes control hides both layers;
device-battery-zigbee-overlap-dark changes (arrowhead now over the battery)
and needs acceptance via ci:golden.
Issue: #808
User-Visible: yes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
The volumetric settings smoke still expected the retired battery checkbox.
Assert the three radio segments in their real DOM order after the established
Display toggles.
Issue: #807
User-Visible: no
smoke_settings_dialog_cards took the first radiogroup of General settings as
the background segment. The battery choice of #807 is a segmented control in
the Display card above it, so the smoke now selects the group that owns the
gs-bg-mode radios.
Issue: #807
User-Visible: no
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
General settings offer All / Low only / None for battery indicators as a
three-button segmented control, the same visual as the light-source choice
in the device dialog. Low only keeps just the red low state (below 20 %, or
a binary battery sensor that is on); normal, warning and unknown are hidden.
Storage keeps #792 compatibility: absent = All, false = None, the exact
string "low" = Low only. The backend accepts bool or "low" and refuses any
other value; old frontends read "low" as All, old backends refuse to save it
(documented in CONFIG-COMPATIBILITY). One presentation option
(batteryLowOnly) filters the resolved indicator, so View, kiosk, 2.5D,
space-card and the device dialog preview share the same rule.
Track raised ship -> show: new i18n keys, a new config value and Python.
Tests: unit (mode resolver, write, dirty, low-only presentation), backend
validator and support package, smoke_device_battery (low-only keeps only
red), smoke_general_settings_form (radios, save/reopen/clean, All removes
the key). New mutant battery-low-only-shows-every-state; the backend mutant
anchor moves to the new validator.
Issue: #807
User-Visible: yes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
Эталон подтверждает увеличенную тень четырёх состояний и трёх размеров
непосредственно на нейтральной серой плоскости. Полная матрица: 205 сцен.
Issue: #806
User-Visible: no
Release: v1.80.0-beta.6
Baseline-Reviewed-Local: sha256:d5e785e772731545943419b719df10f952592b82bbfb65db61a6727892d8b61c
Проверены светлый, тёмный и мобильный масштабы, перекрытие Zigbee и
сцена диалога с новой локальной настройкой. Остальные 199 сцен совпали.
Issue: #806
User-Visible: no
Release: v1.80.0-beta.6
Baseline-Reviewed-Local: sha256:453d95ec28670c0e2b0d962acaf1fb2aa715178944b3796402cc7a4e50808d8a
Count delivered page errors after awaited browser close. Exercise the public
harness lifecycle with deterministic negative subprocess cases and retain the
unchanged Chromium probes for the real transport. Move the premature-snapshot
mutation witness to the deterministic Node suite.
Issue: #776
User-Visible: no
Review the actual 420x140 frame from the complete attested WSL capture of
published 88bdd513e. The caption covers 70/70 sampled battery pixels;
coreChanged=0 and exposedRoute=49. All 203 existing scenes passed and their
PNG bytes remain untouched. Accept exactly the single declared new scene.
Issue: #792
User-Visible: no
Release: v1.80.0-beta.4
Baseline-Reviewed-Local: sha256:4918901746d50a9b8876c6683f9d4e71ce6782c2c02c680c836d0cd1af1b0765
Address the in-scope Medium from CODE-REVIEW-792-r1 with a deterministic
golden scenario that uses actual topology rendering and overlapping battery
ink. Keep the existing battery boards and their reviewed images unchanged.
Align the English guide's setting name with the shipped locale (Low).
Issue: #792
User-Visible: no
Append battery visibility after the existing tooltip, radar and volumetric
controls. The established 2.5D setting remains third. Extend the existing
browser oracle to allow exactly the new fourth option while preserving
its original first-three ordering requirement.
Full Validate 37461167422 exposed the ordering regression. It was reproduced
locally before the change; volumetric_setting, general_settings_form and
settings_dialog_cards all pass after it. Record the final gzip measurement.
Issue: #792
User-Visible: yes
Full 203-scene capture from published d4d48bb040
on pinned WSL/ext4 toolchain: 200 unchanged scenes and three new scenes;
105 environment witnesses passed (required floor: 10).
Reviewed light/dark boards and mobile framing against owner-approved MDI
glyphs and the designer's sizes, gaps and colors. Correct measured gzip
documentation by three bytes after the final source fingerprint settled.
Issue: #792
User-Visible: no
Release: v1.80.0-beta.4
Baseline-Reviewed-Local: sha256:7e238b1840401f791e00e53f5c77388006a0b04cc8d4e535775b3a5dc9f9db03
Resolve one stable battery source independently of the functional device face,
include battery-only ticks in immutable render snapshots, and add a default-on
shared preference. Keep LED strips excluded and Zigbee captions above the
passive, out-of-flow indicator. Use the owner's accepted four MDI icons in the
designer's frame geometry and colours.
Include resolver/backend/browser/pixel contracts and three new golden scenes.
Recalibrate the owner-approved absolute/raw size budgets; preserve the existing
initial View rolling ceiling and band. Lazy extraction remains separate #805.
Issue: #792
User-Visible: yes
Use bounded Playwright polling for the RAF-backed facade operation, following
the existing preloader smoke precedent. No config retries or relaxed assertions.
Issue: #802
User-Visible: no
Full release CI caught room becoming undefined instead of false after the
pointer-tooltip path stopped calling _showTip. Preserve the existing shape;
keep and strengthen the room-tooltip-toggle regression assertion.
Issue: #802
User-Visible: no
Keep diagnostic captions and the matching pointer tooltip readable, including
late overlay paint, camera/resize changes and narrow-card fallback. Preserve
focus, touch and device actions. Add pure placement and real-mouse witnesses.
Issue: #802
User-Visible: yes
Reviewed the complete attested WSL capture on published 22828495b.
Only general-color-popover-desktop-en changes: the Zigbee hint describes
provider-confirmed routes rather than observed neighbors. Preserve the other
199 PNGs; 107 byte-identical witnesses, floor 10. No threshold/matrix changes.
Author self-review and dev merge are explicitly authorized by the owner.
Issue: #798
User-Visible: no
Release: v1.79.0
Baseline-Reviewed-Local: sha256:c0d5ed83d3bf2591a21fff465403ce4ab71c10df781a78736cf690a578a5df52
Replace inferred BFS topology with confirmed end-device parents and active
router routes from ZHA and Zigbee2MQTT. Fail closed on ambiguous evidence,
preserve stale snapshots, and request routing tables without hover traffic.
Use solid LQI-coloured arrows, plan-scaled unknown-LQI outlines, and named
unplaced targets. Add provider/runtime/visual regression coverage.
Owner authorized author self-review and merge to dev while the review model
is unavailable; no release or issue closure is included.
Issue: #798
User-Visible: yes
Retain the 48-band DOM and exact idle raster, paint 24 midpoint bands during actual zoom, and restore after 160 ms. Keep input, HA and lifecycle guards observable; measure the full camera/restore/restart cycle without relaxing historical budgets.
Issue: #789
User-Visible: yes
Coalesce source-entry updates without changing the 500 ms transition or
field geometry. Resolve shared barrier revisions once within a synchronous
render and always recheck content on the next pass. Release main/static
LED owners on no-strip exits and static owner/config teardown.
Protect scheduling, real browser fades, cold imports and the bundled
render-pass wiring. Performance acceptance remains a separate exact-SHA
full Linux run; this commit alone does not assert that AC3 has passed.
Issue: #789
User-Visible: yes
Accept only the six reviewed active-LED frames from the complete canonical
WSL capture. All other baseline PNG bytes are preserved. Both off-LED
captures are byte-identical to their reviewed baselines.
Root and an independent reviewer inspected the candidates and diffs.
Separate DOM-white controls localize the intended core colour change;
residual old-baseline differences remain at Glow rims (48/74/212 pixels
above delta 10, all below the unchanged .0005 ratio threshold). Rectangle
control also records 10 baseline-to-white residual pixels and five
white-to-colour raster/repaint pixels outside the core near the door.
No claim is made that the old-baseline RGBA diff is exclusively the core,
or that the residual's historical cause has been established. No golden
threshold, product geometry, field alpha or field algorithm is changed.
Issue: #790
User-Visible: no
Release: v1.79.0
Baseline-Reviewed-Local: sha256:aaf9ebcb3613071dc8048506f68a889dab6bdea8e62ba5ce677b12d611e9eae7
Keep off and unavailable presentation unchanged. Extend the rendered colour
and surface matrix and retain the independent white-source geometry oracle.
Issue: #790
User-Visible: yes
Reviewed Linux Validate 37134548622 on c142e4f7. The right free cap now
fades through the valid wall-circle crescent instead of cutting it away.
One declared frame changed; 199 baselines retained, 101 exact witnesses.
Private household screenshots were not uploaded or committed.
Issue: #788
User-Visible: no
Release: v1.79.0-beta.7
Baseline-Reviewed: https://github.com/Matysh/houseplan-card/actions/runs/37134548622
Keep real end and corner emitters, robust decimal joins and wall-circle
sweep events. Render one positive-winding compound visibility clip so
Chromium cannot cancel or cut away overlapping light regions.
Add independent pixel oracles for glow falloff and wall-following tubes.
Replace the lossy fan-count limit with explicit cached-path bounds while
retaining the original timing and warm-cycle heap-growth limits.
Issue: #788
User-Visible: yes
The state and room-setting updates are separate renders. Assert the stable no-Glow contract after the legitimate 500 ms leaving phase instead of racing it on fast CI runners.
Release: v1.79.0-beta.4
Issue: #784
User-Visible: no
Reviewed all three changed WSL frames: the 30 cm field is continuous at
straight cuts and corners in 2D light/dark and 2.5D scenes.
Issue: #784
User-Visible: no
Release: v1.79.0-beta.4
Baseline-Reviewed-Local: sha256:cf474aa1ff676d2262f1c9e442114e7df0e91867c69c78bdc82c923a48355650
r1 M5: the runtime and field chunks release a card's frame and field cache
on disconnect (ledRelease from disconnectedCallback), never cache for a
disconnected card, and a chunk that lands after disconnect renders nothing
(the card's LED hook is connected-only). The profile now reports the three
caches of the shown space separately (shapes ≤ 50, visibility ≤ 50, retained
per-emitter fans ≤ 2500) through the runtime's ledStats, asserts 0 retained
entries and 0 live LED timers/frames/observers after every disconnect,
judges the Long Tasks of a 100-step camera series as well as the interaction
profile's camera scenario, runs one extra cold mount whose runtime response
is held while the card is removed, and enforces ≥ 7 samples after ≥ 1
warm-up — also on reports merged from parts (--warmup-only, --merge).
Issue: #780
User-Visible: no