v2.15.0 — the honesty release¶
Released 2026-08-07. Install or upgrade:
Every headline item in this release is the same shape of defect: the software was telling somebody something that was not true. None of it crashed, which is exactly why none of it had been noticed.
Dictation stopped eating real words¶
Filler removal always claimed to be case-insensitive, and the regex was. But a guard refused to touch any capitalised token — which is how "the Like button" survives. The side effect went unnoticed for a year: Whisper capitalises the first word of a sentence, so a filler in the single most common position it occurs — a leading "Um…" — was capitalised, protected, and therefore never removed.
Fixing that naively then went too far and started deleting ordinary words. Three rounds of argument later, the rule is: a filler is stripped at the start of an utterance only when it contains a sound that is never a word (um, uh, er, ah, hmm).
"Um the meeting is at noon" → "the meeting is at noon" ✅
"So um the meeting is at noon" → "the meeting is at noon" ✅
"Uh... so I think" → "so I think" ✅
"Right turn at the corner" → unchanged ✅ a direction
"Like button is broken" → unchanged ✅ a UI element
"Okay so what do you think?" → unchanged ✅ a real message
"You know the meeting is at noon" → unchanged ✅ addressed to someone
Code and paths are still protected throughout: main.py, basically_fn and Actually.py come through untouched.
Known issue
err is in the default filler list and is also a real English verb, so "To err is human" currently becomes "To is human". Tracked in #125; remove err from [filters.disfluency] filler_words to avoid it in the meantime.
The snap stopped giving advice that could never work¶
yazses doctor reported Keyboard capture: denied inside a snap and told users to join the input group and log back in. Snapd blocks raw keyboard reads whatever groups you are in — so people followed that advice in circles and concluded the app was broken.
doctor now recognises confinement and names the only two things that can change the outcome:
The snap also declares the raw-input interface for the first time — previously there was no interface a user could connect even if they knew to. It is not auto-connected, and Wayland keystroke injection remains unavailable under confinement, so the APT and pipx installs are still the recommended path on Linux.
The installer stopped trusting an unpinned script¶
install.sh piped astral.sh/uv/install.sh straight into sh — and that is the script the README's curl | bash one-liner reaches. It now pins a specific uv release, downloads it to a temp file, and verifies its SHA-256 before executing. A mismatch aborts.
Verification is portable (macOS has no sha256sum, so it falls back to shasum), and if no checksum tool exists at all the install aborts rather than skipping the check — an unverifiable download is a failure, not a pass.
The contract went 1.1.0 → 4.0.0¶
Three deliberate changes to shared text behaviour, each raised as an issue, argued in public, and pinned as golden vectors that the Android port (#81) inherits automatically. The contract is now 6 units, 131 cases.
Also new: property-based fuzz tests over the whole text pipeline — control characters, Persian RTL, zero-width characters, astral-plane emoji, and 5000-character transcripts. The strongest property asserts that classify can never flip a dictation into a command without a real rule sanctioning it: a crash is loud, but a burst that silently executes instead of being typed is the failure that actually hurts.
Thanks¶
This release is mostly other people's work. @AshSgDe29071999, @slegarraga, @waterlemonnn, @Maqbool61, @Parinitha-26, @jackie-cqz, @HeaTTap and @lntutor have all shipped code — see the contributor wall.
Want to join them? The good first issues are real, reserved, and reviewed fast.