v3.8.2 — Mobile UX, Customizer, Performance
(Draft for operator review. ~3 weeks of work since v3.8.1, ~25 substantive commits.)
Headliners
- Mobile UX overhaul — packets surface redesigned mobile-first with single-row navbar, semantic-first detail panel, hidden chrome rail; nav controls (Favorites/Search/Customize) finally reachable on phones (#1471 — closes #1415/#1458/#1461/#1467/#1468/#1470).
- Customizer reframe — CB preset is now an end-user OPT-IN, not a force-override. Operator's
config.json nodeColorsare honored by default; per-user customizer override beats the preset (#1446/#1447/#1448/#1449 — fixes longstanding "config not honored" reports). - Dark-tile provider picker — 4 dark map variants pickable in customizer: Carto Dark, Esri Dark Gray, Voyager Inverted, Positron Inverted (#1420/#1430). Honored across all map surfaces including node-detail inset (#1470).
- Observer timestamps fixed — California (UTC-7) observers were perpetually 7h stale because naive timestamps were treated as UTC. Now:
observer.last_seenalways uses ingest time, per-packet rxTime keeps envelope time with symmetric clamp (#1463/#1464/#1465/#1466). - Cold-path cache —
/api/nodesno longer blocks on stale-cache rebuild; serves stale-while-revalidate (#1272/#1436).
Operator-facing changes
UI / UX
- New customizer toggle: Show encrypted channels (default OFF — finally a way to control the encrypted-channel flood without DevTools) (#1454/#1455)
- Traffic share label replaces the misleading "Usefulness" score (renamed everywhere; new
traffic_share_scoreJSON field added alongside the legacyusefulness_scorefor API compat). Tooltips explain both Traffic share and Bridge score with tap-to-toast on mobile (#1456/#1457) - Custom navbar logos no longer squished to 125×36 — proportional aspect preserved for square, tall, wide variants (#1450/#1451)
- Per-role color overrides now actually propagate to marker SVGs (was silently dropped before — #1438/#1439/#1441/#1443)
- "unknown" fake channel no longer accumulates in the channel list (live router was synthesizing it from undecryptable CHAN messages — #1468)
- Hash matrix marks 0x00 and 0xFF as reserved prefixes per MeshCore firmware keygen convention (@halo779 report — #1473/#1474)
- Mobile gesture hints — touch-only gate added (no longer show on desktop), width:fit-content fix for off-screen pills (#1065 chain)
Server / Performance
repeaterEnrichTTLcache cold-path now stale-while-revalidate; first request after expiry no longer blocks (#1272/#1436)- Hourly SQLite WAL checkpoint prevents unbounded WAL growth (#1435)
- Startup warning when
GOMEMLIMIT < 50% of container memory limit— prevents future OOMs (#1264/#1429) - WebSocket MQTT broker support (
ws:///wss://) documented + tested (#902) - Paths-through-node now sorted by recency (LastSeen DESC) with count as tiebreaker — was non-deterministic map iteration order (#1145/#1431)
Bug fixes
- Naive (zone-less) ISO timestamps in MQTT envelopes now symmetrically clamped (was: only future-skew rejected, past-skew passed through verbatim — California observers perpetually stale) (#1463/#1464)
- Observer.last_seen always uses ingest time, never envelope time (architectural cleanup, eliminates whole class of TZ bugs) (#1465/#1466)
- Hop-name mis-resolution on prefix collision — regression test added for #1144 (the production fix shipped earlier; this guards against re-introduction) (#1433)
- Channel-color-picker outside-click E2E flake fixed for real this time (race with
setTimeout(0)listener install — proper fix using rAF×2 + retry) (#1462) - CI: master runs no longer cancelled by subsequent commits (was dropping Deploy Staging silently — #1395/#1426)
- CSS parse-error: stray non-comment text after
#1062block was eating the next CSS rule from CSSOM (gesture-hint .width:fit-content wasn't taking effect for weeks) (#1065/#1453)
Community contributions this cycle
- @efiten — #1145 paths sort, #1264 GOMEMLIMIT warning, #1272 cold-path cache, #902 WS MQTT docs, #1395 CI concurrency fix, WAL checkpoint
- @halo779 — #1473 reserved-prefix report (your in-game testing flagged the firmware convention CoreScope was ignoring)
Thanks 🙏
Known issues / follow-ups
Resolved from v3.8.1's known-issues list:
- ✅ CB preset switching now applies everywhere without reload (#1446 reframe + cascade fix)
- ✅ Customizer (🎨) reachable on mobile portrait via bottom-nav More sheet (#1467, no more rotate-to-landscape workaround)
Still pending from v3.8.1 (carried forward):
- Mobile route view auto-fit can briefly overshoot on iOS Safari URL bar collapse
- Sidebar drag-resize doesn't persist when localStorage is blocked
- "Scan QR" for PSK channel not yet functional
- Analytics → Distance tab still launches the route map via legacy sessionStorage flow (not deep-link)
New in v3.8.2:
- Node-detail card backgrounds are technically dark but visually close to page bg (#1470 deferred — operator's call: ship or revisit)
- Group-header rows in /packets render 200-700px tall in some cases (existing grouping behavior, not new this cycle)
Upgrade notes
- Frontend cache-bust automatic via
__BUST__token - Backend image:
ghcr.io/kpa-clawbot/corescope:v3.8.2(will tag on release) - No config migration required
- New
traffic_share_scorefield appears in/api/nodesand/api/nodes/{pk}responses alongside existingusefulness_score— no breaking change