v1.54.2: HP-1541-01 — vacuum selected_map fallback obeys the not-nullish map-id contract

The v1.54.1 contract (first not-None value wins, zero is a value) covered
the source entity but not the card's fallback on the vacuum's own
selected_map: _vacMapId still used truthiness, so selected_map: 0 became
'default' on the frontend while trails.py resolve_map_id stored the run
under '0'. Calibration and server trails split across two keys and the
recorded run never rendered after reload.

The fallback is now the shared pure helper vacMapIdWithFallback (nullish
check), mirroring resolve_map_id. Cross-runtime regressions added for
selected_map = 0, '0' and '' on both sides; the frontend cases fail on the
old truthiness code.
This commit is contained in:
Matysh
2026-07-31 13:44:10 +03:00
parent 909bb6fbc7
commit fad2e87ab5
14 changed files with 109 additions and 17 deletions
+17
View File
@@ -1,5 +1,22 @@
# Changelog
## v1.54.2 — 2026-07-31
Patch release: the one remaining finding of the v1.54.1 re-audit
(HP-1541-01), pinned by regression tests on both sides of the contract.
- **Fix: a vacuum whose own `selected_map` is `0` split calibration and
trail between two map ids.** The v1.54.1 map-id contract («the first value
that exists wins, and zero is a value») was applied to the source entity
but not to the card's fallback on the vacuum's `selected_map`: the
frontend still judged it by truthiness and turned `0` into `default`,
while the server recorder stored the run under `0`. Calibration was saved
under a key the recorder never used, and the recorded trail never rendered
after a reload. The fallback now follows the same not-nullish rule on both
sides (`vacMapIdWithFallback` in the card, `resolve_map_id` on the
server), with cross-runtime regressions for `selected_map` = `0`, `"0"`
and `""`.
## v1.54.1 — 2026-07-31
Patch release: everything the adversarial audit of v1.54.0 found