mirror of
https://github.com/Kpa-clawbot/meshcore-analyzer.git
synced 2026-07-28 17:59:22 +00:00
Release notes — v3.8.4 (#1666)
Release notes for v3.8.4 — the "Phosphor migration" release. Six PRs
(#1649–#1654, tracking #1648) plus three followup fixes
(#1659/#1660/#1665) replaced all decorative emoji in the UI with
Phosphor sprites and added a lint gate to prevent regression.
## Verification summary
Test plan: `workspace-meshcore/test-plans/v3.8.4-cdp-test-plan.md` (93
tests, 16 sections).
- Initial run (pre-#1665): 56 pass / 22 partial / 5 fail / 14 skipped.
Two BLOCKER lint-gate breaches in observers and analytics Channels.
- Final run (post-#1665, hot-patched to staging): both blockers ✅ —
v384-1.2 (11 chips, 11 sprites, 0 emoji), v384-12.18 (315 lock sprites,
0 🔒 emoji).
- 22 partials are plan selector drift, not code regressions; deferred to
v3.8.5.
## Tagging
Per the notes file, this is ready for `git tag -a v3.8.4 037dc8c4 -m
"v3.8.4"` after merge — **not executed by this PR**.
## Review
Draft for user review. Will be marked ready / merged before tag.
---------
Co-authored-by: meshcore-bot <bot@meshcore.dev>
This commit is contained in:
co-authored by
meshcore-bot
parent
e74e860725
commit
d0b60b372d
+16
-1
@@ -2,7 +2,22 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### 📝 Documentation Corrections
|
||||
## [3.8.4] — 2026-06-12
|
||||
|
||||
See [docs/release-notes/v3.8.4.md](docs/release-notes/v3.8.4.md) for the full notes. 257 commits since v3.8.3 (72 substantive + 185 coverage bumps).
|
||||
|
||||
### ✨ Highlights
|
||||
- **Relay timelines survive an ingestor restart** (#1643) — relay-hop attribution is rebuilt from `path_json` on cold load.
|
||||
- **Observer Compare is first-class** (#1642, #1645, #1647) — three new entry points + Tufte-grade compare page with state-preserving multi-select.
|
||||
- **Emoji → Phosphor icon migration** (#1648, #1649–#1654) — every UI emoji replaced with theme-tinted Phosphor sprites, lint-gated.
|
||||
- **Per-node Reach page + API** (#1627) — `GET /api/nodes/{pubkey}/reach` with cache invalidation on blacklist changes (#1636).
|
||||
- **Hashtag channels catalogue integration** (#1656) — public hashtag channels appear without manual config.
|
||||
- **Operator-customizable name-prefix hiding** (#1655) — new `hiddenNamePrefixes` config (default `["🚫"]`).
|
||||
|
||||
### ⚙️ Config
|
||||
- New: `hiddenNamePrefixes`, `liveMap.maxNodes`, `runtime.maxMemoryMB`, configurable observer-health thresholds, `branding.homeUrl`, customizer disabled-tabs.
|
||||
|
||||
### 📝 Documentation Corrections (carried from prior [Unreleased])
|
||||
- **PR #1324 historical record correction** (#1387) — the merged PR #1324 body referenced four tests that do NOT exist in master: `TestMultibyteCapPersistRoundTrip`, `TestMultibyteCapPersistSkipsUnknown`, `TestMaybePersistCoalesces`, and a `TryLock` coalescing test. The actual tests that landed are `TestRunMultibyteCapPersist_AppliesSnapshot` and `TestRunMultibyteCapPersist_NoSnapshot_NoOp`. See issue #1386 for the corrective test additions (round-trip, unknown-key skip, coalescing).
|
||||
|
||||
## [3.7.2] — 2026-05-06
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
# CoreScope v3.8.4
|
||||
|
||||
**Upgrade urgency: Medium** — fixes the post-restart "timeline empty for relays" regression, lands the Compare UX redesign, and migrates every UI surface from emoji to Phosphor sprite icons.
|
||||
|
||||
_257 commits since v3.8.3 (72 substantive + 185 auto-generated coverage bumps). Every bullet ends with a commit SHA — `git show <sha>` to verify._
|
||||
|
||||
## Highlights
|
||||
|
||||
- **Relay timelines come back after a restart.** Cold-loading the ingestor was leaving relay nodes with empty hop histories until fresh traffic arrived; the relay-hop attribution index is now rebuilt from `path_json` on startup, so per-relay timelines, hop counts, and route stats survive a restart instead of waiting for replay. (#1643, 938153dd)
|
||||
- **Observer Compare is now a first-class UX.** Three new entry points (header CTA, sticky selector strip, observer-table multi-select) feed a Tufte-grade compare page with state-preserving multi-select and themed button vocabulary — was a hidden URL trick before. (#1642, 531bc8ac; #1645, c93ae67e; #1647, 167af54e)
|
||||
- **Every emoji glyph in the UI is now a Phosphor sprite.** Six milestones (top-nav, page headers, detail panes, map overlays, settings/customize, lint-gate sweep) replaced every UI emoji with theme-tinted Phosphor icons — consistent stroke, no font-render variance across platforms, lint-gated against regressions. (#1649, 55e4d957; #1650, 30627454; #1651, b812a98a; #1652, 2b6809cd; #1653, 1116801b; #1654, 89eade6e)
|
||||
- **Per-node Reach page.** New `/api/nodes/{pubkey}/reach` + UI surfaces directional link quality per neighbor with response-cache invalidation on blacklist changes. (#1627, e2212f50)
|
||||
- **Hashtag channels catalogue is wired in.** Public hashtag channels from `meshcore-channels` now show up natively in the channels list — no more manual catalogue maintenance. (#1656, e04c7113)
|
||||
- **Operator-customizable name-prefix hiding.** New `hiddenNamePrefixes` config (default `["🚫"]`) drops matching nodes from `/api/nodes*` while preserving DB rows for analytics — mirrors the convention other MeshCore dashboards already use. (#1655, 825b2648)
|
||||
|
||||
## What's New
|
||||
|
||||
### Observer Compare
|
||||
- Promote observer comparison to first-class: header CTA, sticky selector strip, observer-table multi-select. (#1642, 531bc8ac)
|
||||
- Tufte-grade compare page with themed button vocabulary + state-preserving multi-select across navigations. (#1645, c93ae67e)
|
||||
- Polish: tightened checkboxes, hierarchy, selector strip + mobile fixes. (#1647, 167af54e)
|
||||
- Wire `TableSort` on the observers table with numeric/time column types so the sort affordance actually sorts. (#1641, d72ab69f)
|
||||
|
||||
### Reach & Nodes
|
||||
- Per-node Reach page + `GET /api/nodes/{pubkey}/reach` (directional link quality). (#1627, e2212f50)
|
||||
- Paginate `/api/nodes` across map/live/analytics/packets/area-map so the 500-row server cap stops silently truncating UIs. (#1607, 26105748; #1637, 9002b25b)
|
||||
- Sortable First Seen column on the Nodes table. (#1587, 7533b3b6)
|
||||
- Firmware `repeat:on|off` hint now excludes listener-only observers from the disambiguator. (#1624, a4776557)
|
||||
- Link RTC-reset warnings on node detail to the offending packet hashes. (#1590, 1a2b8c48)
|
||||
|
||||
### Analytics
|
||||
- Relay Airtime Share endpoint + dumbbell chart. (#1601, 3898688d)
|
||||
- 5-minute rolling-baseline anomaly detection for Write Sources. (#1593, a26a412c)
|
||||
- TRACE packets overlay per-hop SNR on the path graph. (#1622, e9aed641)
|
||||
- Multi-byte prefix repeaters now show up in the 1-byte hash-usage matrix view. (#1591, 3df89241)
|
||||
|
||||
### Live & Map
|
||||
- Fullscreen toggle on the live map + controls collapsed by default. (#1572, d7bd9d57)
|
||||
- Colorblind simulation overlay (Brettel/Vienot) with reset-to-Wong button. (#1600, 571c960c)
|
||||
- Path symbols legend disclosure on packets. (#1570, 5fd8900c)
|
||||
- OSM / Stamen tile providers with per-provider Leaflet layer control. (#1533, d7cd9203)
|
||||
- Operator-configurable `liveMap.maxNodes` (default 2000). (#1577, 1bdb92de)
|
||||
|
||||
### Config & Operator Surfaces
|
||||
- `hiddenNamePrefixes` (default `["🚫"]`) — drop matching nodes from `/api/nodes*` while preserving DB rows. (#1655, 825b2648)
|
||||
- Config-driven disabled-tabs list in the customizer modal. (#1579, 7292d60f)
|
||||
- `branding.homeUrl` override for embedded deployments. (#1576, 9b36b7c4)
|
||||
- Configurable observer-health thresholds. (#1556, 65bd954b)
|
||||
- Detect CDN-fronted deployment + document bypass requirement. (#1564, 63bfa3d9)
|
||||
- Expose `--nav-active-bg` as a themeable token. (#1571, 892eb2c0)
|
||||
|
||||
### Performance
|
||||
- Chunked `Load` with early HTTP readiness — server accepts requests while heavy load completes in the background. (#1596, bc1822e4)
|
||||
- Background subpath + pathHop index builds with ready gates. (#1604, df61660a)
|
||||
- Lazy distance-index build on first request. (#1597, 5629a489)
|
||||
- `neighbor_api`: fold `first_seen` into cached map — fixes the #1627 r3 regression. (#1632, 078225a5)
|
||||
- `GOMEMLIMIT` via `runtime.maxMemoryMB` in server + ingestor. (#1595, 1b112f0b)
|
||||
- SQLite writer-lock wait/hold instrumentation per component. (#1594, 222bfdf6)
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
### Ingestor
|
||||
- Subscribe to MQTT before startup maintenance; buffer until the writer is free. (#1609, 18810b5c)
|
||||
- Decode firmware 1.16.0 extended ACK (5/6-byte payloads). (#1618, 9612f08e)
|
||||
- Write `resolved_path` on new observations (regression from #1289). (#1548, 3feb97f1)
|
||||
- Defense-in-depth empty-scope guard in `UpdateNodeDefaultScope`. (#1575, cd19285f)
|
||||
- Skip `default_scope` update when `ScopeName` is empty. (#1569, 05af6c6e)
|
||||
- Address #1609 follow-up findings — config doc, receipt-time liveness, buffer stop/clamp warn. (#1623, 3d122665)
|
||||
|
||||
### Reach
|
||||
- Bust response cache on blacklist change. (#1636, 8295c211)
|
||||
- `scanReachRows` DB errors must surface as 500, not 404. (#1635, 43be1bb7)
|
||||
- Narrow-viewport CSS — no horizontal scroll, map no longer shrunken. (#1634, 59d66469)
|
||||
|
||||
### Frontend / UI
|
||||
- Render analytics Channels group-header sprites as HTML, not escaped text. (#1658, fb6bb085)
|
||||
- Bump feed-detail-card z-index + make popup draggable. (#1620, f66ff40a)
|
||||
- Theme-track `.vcr-scope-btn.active` + `.copy-link-btn:hover` backgrounds. (#1578, 16c7ea4b)
|
||||
- Replay handoff no longer freezes the map (suppressLive flag). (#1603, 1f65d781)
|
||||
- Detach slide-over panel on close — architectural focus-restore fix + `--repeat-each=20` CI gate. (#1617, 37a7a927)
|
||||
- `getTileUrl()` now invokes function-typed provider URLs + regression tests. (#1615, dc433e41)
|
||||
- Reliably restore row focus on panel close. (#1602, 1be0aec8)
|
||||
- Gesture hints — edge-drawer mobile-only + row-swipe widening (re-fix). (#1586, 116efe4b)
|
||||
- Honor time-window filter on Route Patterns analytics. (#1592, d6384c3c)
|
||||
- Live corner-cycle button clears drag state. (#1568, 2b45f787)
|
||||
- Observers aggregate header shows "Last updated" timestamp. (#1563, a7ad2be1)
|
||||
- Mirror `Load`'s `resolved_path` indexing into `loadChunk`. (#1582, 9465949e)
|
||||
- Remove dead server-side backfill flag (stuck `backfilling=true`). (#1583, f7571a26)
|
||||
- Additional follow-up fixes for #1532. (#1580, 373ee816)
|
||||
- Document `writeStatsAtomic` symlink-replace semantics + regression test. (#1588, af669438)
|
||||
|
||||
### API
|
||||
- Bypass API limit clamps for internal UI requests (revisit of #1540). (#1589, 7421ead9)
|
||||
- Emit `Cache-Control: no-store` on `/api/*` responses. (#1553, 0c908d2b)
|
||||
|
||||
## Performance
|
||||
|
||||
- Chunked `Load` early-readiness, background index builds, lazy distance index, cached `first_seen`, `GOMEMLIMIT` honored, writer-lock instrumentation — see "Performance" under What's New.
|
||||
|
||||
## Security
|
||||
|
||||
- Detect CDN-fronted deployment and document the bypass requirement so rate limits and PoW gates can't be silently routed around. (#1564, 63bfa3d9)
|
||||
|
||||
## Breaking changes
|
||||
|
||||
None.
|
||||
|
||||
## Operator-facing changes / config
|
||||
|
||||
**New config (`config.example.json`, all opt-in, safe defaults):**
|
||||
- `hiddenNamePrefixes: ["🚫"]` — node-name prefixes that hide a node from `/api/nodes`, `/api/nodes/search`, `/api/nodes/{pubkey}`. DB rows preserved; analytics history intact. Mirrors the convention used by other MeshCore map dashboards. Opt out with `[]`. (#1655, 825b2648)
|
||||
- `liveMap.maxNodes: 2000` — cap nodes rendered on the live map; raise for big meshes, lower for low-power dashboards. (#1577, 1bdb92de)
|
||||
- `runtime.maxMemoryMB` — sets `GOMEMLIMIT` for server + ingestor; tune against container limits. (#1595, 1b112f0b)
|
||||
- Observer-health thresholds — previously hard-coded, now configurable. (#1556, 65bd954b)
|
||||
- `branding.homeUrl` — override the "Home" link target for embedded deployments. (#1576, 9b36b7c4)
|
||||
- Customizer disabled-tabs — config-driven hide list. (#1579, 7292d60f)
|
||||
|
||||
**Behavior changes:**
|
||||
- `/api/nodes` paginates instead of silently truncating at the 500-row cap; internal UI requests bypass the clamp. (#1607, 26105748; #1589, 7421ead9)
|
||||
- `/api/*` responses now emit `Cache-Control: no-store`. (#1553, 0c908d2b)
|
||||
- Per-node Reach available at `GET /api/nodes/{pubkey}/reach`. (#1627, e2212f50)
|
||||
- Hashtag channels from `meshcore-channels` catalogue appear in the channels list without manual config. (#1656, e04c7113)
|
||||
|
||||
## Behind the scenes
|
||||
|
||||
- **Emoji → Phosphor migration (six PRs).** M1 top-nav/mobile-nav/Compare (#1649, 55e4d957) · M2 page headers + table chrome (#1650, 30627454) · M3 detail panes + badges (#1651, b812a98a) · M4 map + route overlays (#1652, 2b6809cd) · M5 settings + customize (#1653, 1116801b) · M6 final sweep + lint gate + carry-forwards (#1654, 89eade6e). Tracking: #1648.
|
||||
- CI: bump go test timeout 10m → 15m (suite grew past 10m post-#1655). (#1661, 0712c5ff)
|
||||
- Test: tighten slideover row selector to avoid the virtual-scroll spacer race. (#1663, 037dc8c4)
|
||||
- Test: subpaths_window tests wait for index readiness after the #1595 chunked load. (#1621, ad41b9bb)
|
||||
- Test: mock `/api/nodes/search` in home-coverage E2E (closes #1313). (#1584, 6a027b03)
|
||||
- Refactor: extract pure helpers into `route-view-utils.js`. (#1581, 545013d3)
|
||||
|
||||
## Verification
|
||||
|
||||
Test plan: `workspace-meshcore/test-plans/v3.8.4-cdp-test-plan.md` (93 tests across 16 sections)
|
||||
|
||||
**Initial run (master pre-#1665, 2026-06-12 00:45 UTC):** 56 pass / 22 partial / 5 fail / 14 skipped. Two BLOCKER lint-gate breaches surfaced — `.obs-clock-naive-chip` (#v384-1.2, 14× ⚠️) and analytics Channels encrypted labels (#v384-12.18, 158× 🔒) — plus one API contract regression (`/api/nodes/<bad>/reach` returns 404, expected 500/200). 22 partials were plan selector drift (provider names, panel selectors) not code regressions.
|
||||
|
||||
**Final run (post-#1665, 2026-06-12 01:35 UTC):** v384-1.2 ✅ (11 chips, 11 sprites, 0 emoji). v384-12.18 ✅ (315 lock sprites, 0 🔒 emoji).
|
||||
|
||||
**Known partials carried forward (recoverable, not blockers):** plan selector drift in §§5, 8, 9, 12 — plan to be tightened in v3.8.5 cycle.
|
||||
|
||||
**Open follow-up issues:** #1659 (analytics warm-up data), #1660 (UI loading banner). Both are UX improvements, not regressions.
|
||||
|
||||
**External API regression to investigate post-release:** `/api/nodes/<unknown-pubkey>/reach` returns 404 instead of 500/200-empty per #1631 contract. Doc/code mismatch, low severity. (To file as issue.)
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
- **@efiten** — relay-attribution rebuild on cold-load (#1643).
|
||||
|
||||
---
|
||||
|
||||
## Tagging
|
||||
|
||||
```
|
||||
git tag -a v3.8.4 e74e8607 -m "v3.8.4"
|
||||
```
|
||||
Reference in New Issue
Block a user