From c2a9500060d6e36764bd42c65c772d160aa47ca0 Mon Sep 17 00:00:00 2001 From: efiten Date: Sun, 4 Oct 2026 13:23:25 +0200 Subject: [PATCH] docs(release): notes and changelog for v3.13.0 (#2110) Release notes and CHANGELOG entry for v3.13.0, in the shape used for v3.12.0. Once merged, the tag goes on the merge commit so `deploy.yml` picks up `docs/release-notes/v3.13.0.md` as the release body (#2076). - 16 commits since v3.12.0: 10 fix, 4 test, 2 feat, so a minor bump. - "Read this before upgrading" covers the one-off advert route evidence backfill from #2088. Durations are measured on two instances (live 24m 1s on 16.8M observations, staging 36m 23s on 16.5M), and ingest during the backfill window is measured as unaffected on live. - Issues closed come from each PR's closing references: 14 from 16 PRs. Docs only. #2089 is deliberately not in this release. Co-authored-by: Claude Opus 5.5 --- CHANGELOG.md | 13 ++++ docs/release-notes/v3.13.0.md | 131 ++++++++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 docs/release-notes/v3.13.0.md diff --git a/CHANGELOG.md b/CHANGELOG.md index bc970c3f..9e5b1d34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,19 @@ ## [Unreleased] +## [3.13.0] - 2026-10-04 + +See [docs/release-notes/v3.13.0.md](docs/release-notes/v3.13.0.md) for the full notes. 16 commits since v3.12.0: 10 fix, 4 test, 2 feat. + +### Highlights +- **The first start backfills advert route evidence in the background, and flood counts read low until it finishes** (#2088) - measured at 24m 1s on 16.8M observations and 36m 23s on 16.5M on a busier host. Startup and ingest do not wait for it. Runs once per database and resumes after a restart. **Operator awareness required.** +- **Adverts are split by the route they arrived on** (#2088, #2085) - flood, direct with an empty path, or mixed, in Analytics and on node detail. +- **Path hops are resolved with the observer that heard them** (#2099) - with one per-path warning in the packets list when hops stay ambiguous. +- **A compact packets table with a Full Names toggle** (#2090). +- **Channel unread counts and key-only channels survive a list refresh** (#2096). + +No manual migration step: `advert_route_evidence` is created at boot. + ## [3.12.0] - 2026-09-26 See [docs/release-notes/v3.12.0.md](docs/release-notes/v3.12.0.md) for the full notes. 29 commits since v3.11.0: 15 fix, 5 test, 3 perf, 3 feat, 2 ci, 1 chore. diff --git a/docs/release-notes/v3.13.0.md b/docs/release-notes/v3.13.0.md new file mode 100644 index 00000000..4a82dd8a --- /dev/null +++ b/docs/release-notes/v3.13.0.md @@ -0,0 +1,131 @@ +# v3.13.0 + +16 commits since v3.12.0: 10 fix, 4 test, 2 feat. Two feats, so minor not patch. + +## Read this before upgrading + +**The first start after this release backfills advert route evidence in the +background, and flood counts read low until it finishes.** + +#2088 records, per advert, whether it was seen arriving by flood, by direct with +an empty path, or both. New adverts get this at ingest. For the adverts already +in your database, the ingestor runs a one-off background job +(`advert_route_evidence_v1`) that reads their stored observations. Until it +completes, the Analytics advert split and each node's flood-advert count only +know the adverts it has reached so far, so they undercount. + +Measured on two instances of the same deployment, both on a 4-core ARM64 host: + +| | observations | database | duration | +|---|---|---|---| +| live | 16.8M | 10.6 GB | 24m 1s | +| staging, sharing the host with live | 16.5M | 10.3 GB | 36m 23s | + +The author measured 5m43s on 11M observations on other hardware, so expect a +wide spread. + +Startup does not wait for it, and ingest carries on alongside it: on the live +instance the 15 minutes from 13:00, inside the backfill window, stored 2,803 +observations against 2,605 to 3,194 in the quarter hours before the deploy. + +It runs once per database. Its progress is kept in the database +(`advert_evidence_backfill` holds the cursors, `_async_migrations` the status), +so a restart resumes rather than repeats it. There is no setting to skip it. + +What it cannot recover: an observation that was overwritten before this release +keeps only its last frame, so some old adverts stay unclassified. The Analytics +page says so under the chart. + +## Features + +- **Adverts are split by the route they arrived on** (#2088, closes #2041) - + Analytics separates flood adverts from direct adverts with an empty path, and + shows adverts seen both ways as mixed. Node flood-advert counts use the same + evidence. An empty remaining path is labelled as exactly that: the firmware + can forward a direct advert down to an empty path, so it does not prove the + advert was sent zero-hop or from nearby. If writing the evidence fails, the + error is logged and counted and the observation is still stored. +- **Node detail groups recent adverts the same way** (#2085, closes #2073) - + both the side pane and the full page group by the server's classification. + An advert without evidence goes to "other" rather than being guessed from the + first stored frame, which could belong to a different route than later + observations of the same advert. + +## Paths and packets + +- **Path hops are resolved with the observer that heard them** (#2099, closes + #2097) - a 1-byte hop prefix matches several repeaters. Resolution now uses the + receiving observer's position, and the packets list shows one warning at the + start of a path saying how many of its hops have more than one candidate. The + detail pane keeps a badge on each such hop, tied to its name. +- **The packets table is compact** (#2090) - short columns such as time, size + and hop count are sized to their content instead of a share of the screen, a + grouped row draws one expand arrow, and a **Full Names** toggle shows observer + and hop names unabbreviated. +- **Packet links keep the selected observation** (#2093, closes #2091) - + changing the type or observer filter no longer drops `?obs=` from the URL. + +## Interface + +- **Channel state survives a channel-list refresh** (#2096, closes #2095) - + unread counts, last-message previews and the channels you added with a key + are kept when the region filter or the show-encrypted toggle reloads the list. + Before, every unread count reset and an open key-only channel was closed. +- **Live accepts node-filter input only once it can process it** (#2103, closes + #2094) - typing while the initial node list loaded was silently lost. +- **Heard By drops a Region column that was always empty** (#2077, closes + #2062) - the endpoint never sent that field. +- **Navigation and channel buttons are one size, 48px** (#2078, closes #2052). +- **The route sidebar no longer covers Path Inspector candidates** (#2082, + closes #2060 and #2081). + +## Tests, CI and release tooling + +- **The GitHub release body is these notes** (#2076) - v3.10.1, v3.11.0 and + v3.12.0 were published with an empty body. +- **Four intermittent E2E and server-test failures fixed** (#2084, #2087, #2105, + #2109) - #2109 is the Path Inspector failure that turned master red twice on + 2026-10-03. +- **Packets fixture tests are stable, mobile empty states kept** (#2080, closes + #2054). + +## Issues closed + +14 issues, from the 16 pull requests in this range. Collected from each pull +request's closing references rather than from commit text. + +- #2041 [feat] #/analytics split advert into flood-advert and zero-hop-advert +- #2052 style.css declares .nav-btn and .ch-icon-btn at both 48px and 44px +- #2054 26 wired E2E suites depend on the packets page's 15-minute window surviving the length of the job +- #2060 The E2E fixture's neighbour graph yields no path-inspector candidates, so two assertions cannot run +- #2062 Node detail "Heard By": the Regions line and Region column read a field the endpoint does not emit +- #2073 [feat] node detail, separate flood-adv from zero-hop adv +- #2081 bug(map): route sidebar shifts Leaflet over Path Inspector candidates +- #2083 test(server): node-path regressions race asynchronous index readiness +- #2086 test(e2e): channel WS assertions race initial channel loading +- #2091 Packets: changing the type or observer filter drops ?obs= from a packet detail URL +- #2094 bug(live): node filter accepts input before its handler is ready +- #2095 channels: loadChannels() replaces the channel array and discards all client-only state +- #2097 packets: an ambiguous path hop is shown as a single certain name, resolved without the geographic filter +- #2104 test(packets): observation hex test clicks stale DOM handles + +## Contributors + +Pull request authors: @n30nex (11), @efiten (4), @sylr (1). + +No co-authors other than tooling are credited in the commits. + +Issues in this release were reported by @efiten (6), @n30nex (5), +@damn-simple-scripts (2), @dborup (1). + +@n30nex wrote 11 of the 16 pull requests, including both features. @efiten, the +interim maintainer, wrote 4 and reviewed and merged the rest. + +## Upgrade notes + +No manual migration step. #2088 adds the `advert_route_evidence` table, created +at boot, and the background backfill described at the top fills it for existing +adverts. It needs no action, only the awareness that flood counts are low until +it finishes. + +Nothing is opt-in and no configuration key was added or changed.