docs(release): write the v0.9.0 changelog and refresh artifact names

release:notes is not usable for this batch: it maps changed files to their
TRACES, and the logging sweep touched 63 files spanning most of the codebase, so
it reports nearly every user requirement as changed — including ones explicitly
not implemented. Written by hand instead.

Also updates the checklist's artifact names for the rename and adds the rpm,
which the checklist never listed because it was never published.
This commit is contained in:
2026-08-20 21:07:13 +02:00
parent 28b600304f
commit bb140a8734
2 changed files with 98 additions and 2 deletions
+95
View File
@@ -9,6 +9,101 @@ generated trace matrix lives in [docs/traceability.md](docs/traceability.md).
For how long each fixed defect had been shipping before it was found, see
[docs/defect-windows.md](docs/defect-windows.md).
## v0.9.0
An audit release. One new setting you asked for, two naming bugs that only ever
showed in builds a developer never looks at, and a large amount of tidying that
should be invisible in use.
Note for anyone upgrading a Linux package: the Debian/RPM package is now called
`jelly-tau` rather than `jellytau` (the packager derives it from the app name).
It declares the rename, so `apt`/`dnf` will replace the old package rather than
install a second copy. The command is still `jellytau`.
### ✨ Changes
- **You can now hide library folders from music browsing.** Pick the folders to
exclude in Settings; they disappear from albums, artists, genres, search and
the home rows alike. This replaces a filter that dropped anything *named*
"Podcasts" — one person's library layout compiled into the app, which meant an
album genuinely called "Podcasts" vanished while a podcast folder named
anything else stayed. Exclusion now matches on the folder itself, is decided
in one place rather than at the six screens someone remembered to filter, and
defaults to excluding nothing. (UR-076 → DR-209)
- **The app is called JellyTau again.** The Android release build showed
`jellytau` under its icon, and the Linux and Windows packages carried the same
lowercase name. The debug build has always overridden the label to "JellyTau
Debug", so the install a developer looks at every day was the only correctly
cased one and nobody saw it. (DR-214)
- **The RPM package is published.** It has been built by every release since
Linux packaging was added, and never copied out of the build — so it existed,
cost build time, and reached nobody. (DR-214)
- **Linux and Windows packages carry their own metadata.** Publisher, copyright,
category, description and licence were all absent, so the packages installed
with no maintainer and no description. The hand-written Arch package had all
of it; only the generated packaging was missing it. (DR-214)
### 🔒 Hardening
None of these were reachable in normal use — the app refuses plain-`http`
servers, Android blocks cleartext, and the webview runs under a CSP that bars
inline script — so they are consistency fixes rather than incidents. Each one
had the correct pattern already in the same file, a few lines away.
- **Thumbnail cache writes stay inside the cache directory.** The filename was
built from three values but only one was sanitised, and joining a path does not
fold `..` or keep the base when handed an absolute path. (DR-210)
- **Download paths stay inside the download directory.** A correct sanitiser
already existed, but the command that queues a download accepted a raw path,
so the guard could be routed around rather than being absent. (DR-211)
- **Query and URL values are bound and encoded, not pasted in.** The offline
item-type filter built SQL by string formatting while its sibling query used
placeholders, and browse URLs left values unencoded while the genre parameter
next to them was encoded properly. Volume is also range-checked at the command
boundary instead of relying on each player backend. (DR-212)
### 🛠 Development
Nothing here changes the app, but the previous release's audit found the tooling
claiming more than it delivered, and this is the repair.
- **The frontend has a real logger.** 484 `console` calls shipped to users and
ran on every device; the Rust half has had levelled logging with a runtime
override since the beginning. There is now a matching facade — quiet in
release builds, verbose in debug ones, with warnings and errors never
suppressed and `localStorage` able to turn the volume up in a shipped build to
diagnose a problem. (DR-204)
- **The traceability matrix is navigable.** Every one of its ~2,800 file links
was broken: the generator wrote repo-root paths into a file that lives in
`docs/`. The document the whole traceability system exists to produce could not
be clicked through, and had no test. Both are fixed, and a link checker now
fails the build on a dead documentation link. (DR-093, DR-208)
- **The Rust toolchain is pinned.** Developer machines and CI were five releases
apart, which meant a clean `cargo clippy` locally proved nothing about CI — the
same tree measured zero warnings on one and three on the other. With both sides
on the same compiler, clippy is now a hard gate instead of advisory. (DR-206)
- **The frontend has a linter and formatter**, its first — the Rust half has had
`cargo fmt --check` and clippy in CI for a while. A pre-commit hook runs the
fast checks, so the "before committing" list is enforced rather than
remembered. (DR-205, DR-207)
- **Containerised builds no longer leave root-owned files** in the working tree,
which had accumulated to the point of breaking `cargo clean` and, eventually,
`cargo build` itself. (DR-213)
- Removed: a webdriverio end-to-end suite that had not run in seven months and
was wired into nothing, and a frontend validation module whose six exported
functions had no caller outside their own tests — which made it read as
covered input validation while guarding nothing.
## v0.8.2
A single fix, for Android background audio.