Skip to content

v2.24.0 — the settings that were documented and read by nothing

Released 2026-08-17. Upgrade:

sudo snap refresh yazses     # snap
pipx upgrade yazses          # or: uv tool upgrade yazses

Everything in this release was found by running YazSes and reading what it printed, not by reading its code. That distinction is the release: each of these had a passing test suite, honest-looking source, and a false answer on a real machine.

Read this before you restart

If your learning corpus is over its configured limits, the first daemon restart after upgrading will evict the excess — that is the documented behaviour finally happening. Check with yazses corpus status; raise [learning] max_corpus_mb or retention_days first if you want to keep what is there. If you never enabled [learning], nothing changes.

Two privacy controls that never ran

The learning corpus ignored its own limits. [learning] retention_days (default 30) and max_corpus_mb (default 500) are documented as "auto-evict events older than this" and "cap corpus size; oldest events trimmed first". CorpusStore.prune() has existed since the corpus shipped, with its own tests — and nothing ever called it.

Measured on a real machine with both settings at their defaults: 1292 MB across 38 days. Two and a half times the cap, eight days past the retention window.

The disk cost is the lesser half. Retention is a privacy control: the promise is that captured audio and transcripts age out. A privacy limit that silently does not apply is worse than one never offered, because you have already decided you are protected by it. Pruning now runs on the writer's background thread — once at start, then periodically — so neither a restarted daemon nor one left running for weeks grows unbounded, and no disk work lands on the dictation path.

yazses report leaked your account name. The bundle exists to be pasted into a public issue and promises "settings with paths and identifiers removed". It replaced your home directory correctly and missed the account name everywhere else:

/media/<you>/USB-STICK/note.wav      a file transcribed off a drive
/run/media/<you>/…                   the same, other distributions

The first is ordinary use of this program. Now redacted on word boundaries — with short and generic names (root, ubuntu, ci) deliberately left alone, because such an account identifies nobody and blanking a common word would shred the log into unreadable diagnostics.

The privacy statement described something that never happened

It said that with [commands] lsp_enabled = true, YazSes reads your active file path, language and cursor line into every transcription prompt, and listed turning it off as a mitigation.

None of that happened. The daemon never constructs the editor bridge, and lsp_enabled is read by nothing. The statement overstated what is collected and offered protection against nothing — the harmless direction to be wrong in, but a privacy statement has to be accurate in both. It is corrected in place and marked as a correction, because anyone who read it made a decision on it.

The same sweep found that docs/architecture.md described a Tier 2 language-model router resolving ambiguous commands. Nothing constructs one; Tier 1 decides every utterance. The repo's own orphan ledger already recorded this — the ledger and the architecture page were both checked in, disagreeing.

doctor called a stale daemon healthy

Upgrading replaces files on disk. It does not touch a process that is already running, so the daemon keeps executing the build it started with until yazses restart. doctor printed the CLI's version on one line and the daemon's liveness on the next, and never compared them — so the page you open to ask is everything fine answered yes while dictation ran an older build.

The daemon now reports its version over IPC and doctor compares. A daemon that reports no version is treated as evidence rather than as an unknown: the field is new, so its absence means the process predates it.

[injection] fallback_to_clipboard did nothing

The clipboard fallback was built unconditionally. The setting appears in seventeen places across the docs and the example configs people copy, defaults to true, and no code read it — so anyone who turned it off was silently overruled.

Turning it off is a remedy, not a preference, and the codebase already knew why: a typing timeout can fire after part of the text is typed, the fallback then types it a second time, and the streaming commit deletes a span computed from the first copy.

Also

  • The overlay's reduced-motion probe asked the wrong things on two platforms. macOS read an undocumented preference key instead of NSWorkspace; Linux asked GNOME only, and now asks the XDG desktop portal first — which matters most inside the snap, where a confined gsettings read may answer about the sandbox rather than your session.
  • “never mind” meant three different things. It dismissed the microphone toast, and it was already a command-safety cancel word and a disfluency self-correction trigger. Removed from the mic answers; “ignore”, “ignore that” and “dismiss” remain.
  • The test suite was writing into your real diagnostic log — 44 KB per run of fake recorders and injected errors, into the file yazses logs prints and yazses report bundles into bug reports.
  • yazses features had gone ragged, with 10 of 147 rows misaligned as names grew. The toggle-name column now grows to fit and is never truncated, because it is the one you copy into a command.