Skip to content

v2.25.1 — surfaces that stated things that were not true

Released 2026-08-17. Upgrade:

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

Every fix here is the same shape: a command printed something confident and wrong. None of them crashed, none failed a test, and every one was found by running YazSes on a real machine and reading what it said — several of them within minutes of each other, because once you start comparing what two commands say about the same thing the disagreements are not subtle.

Three of these describe the same underlying fact, arrived at from three directions: speech models answer near-silence with a confident invented word rather than with nothing. Nothing in YazSes accounted for that.

Your microphone gate may be below your room

yazses doctor --mic exists to warn when the room's resting noise level already reaches vad_threshold — because then ordinary silence passes the gate, reaches the model, and is transcribed. On a real machine it printed:

[OK] Mic level: ambient 0.0010 under vad_threshold 0.0005

0.0010 is not under 0.0005. The warning was conditioned on not stats.is_silent, and is_silent is measured against a fixed floor (0.002) that has nothing to do with your gate — so for any vad_threshold below that floor, the warning was suppressed across exactly the band where the gate sits under the room, and the OK branch then asserted "under" for a value that was over.

The guard was disabled precisely when it was needed. It now compares against your gate and nothing else, and says what the consequence is: silence passes and is typed as invented words. The fix is yazses mic-level --set.

Silence transcribed to a confident word

Two seconds of digital silence through yazses transcribe:

Wrote out.txt
$ cat out.txt
You

A word, with a start and an end time, present in the JSON as an utterance. The empty-transcript note added in v2.25.0 cannot see it — the transcript is not empty.

No property of the output separates an invented word from a real one, so the check is on the input, where it is unambiguous: audio with no signal in it cannot contain speech. A muted microphone, an input device held by another application, and capture pointed at the wrong device all produce exactly this, and all three are ordinary.

Measured on the peak, not the mean — an hour of interview with sparse talking averages to almost nothing, so a mean-based gate would call a real recording silent.

yazses verify reported a count instead of the word

Run in a quiet room with nobody speaking:

[OK] Signal: level 0.0013 clears the gate (0.0005)
[OK] Transcription: produced 1 word(s)
✓ Dictation works end to end on this machine.

The one word was the same hallucination. A count cannot be checked against what you said, so it cannot contradict anything. The line now reads heard "You" — the person running this is the only one who knows what they said, so the evidence belongs in front of them.

yazses report understated the learning corpus 430x

Two surfaces, one corpus:

yazses report          corpus: 3.0 MB
yazses corpus status   size:   1294.9 MB

report sized corpus.db and nothing else; the encrypted audio clips beside it are almost all of a real corpus. That number is what gets attached to bug reports, so a maintainer reading 3 MB rules the corpus out of a disk problem it is causing — and it is what you check against [learning] max_corpus_mb, so someone 2.5× over the cap reads it as comfortably under.

The release gate certified a platform on one architecture of a pair

release-complete.yml counts two bundles per platform and explains why: "at least one .dmg" is what let v2.20.0 and v2.21.0 print All platforms published while carrying no Intel bundle. The wait was hardened at the time; the check it delegates the verdict to was not, and that check also decides whether an incomplete release keeps the "Latest" label. A release carrying only an arm64 .dmg passed it, was never demoted, and went on pointing Intel users at a download that did not exist.

Run against the real releases after the fix — v2.20.0 and v2.21.0 now report exactly the halves they shipped without, and v2.25.0 passes with both.

A second gate fix: the wait covered four of the five channels the tag push publishes and omitted the container image, so the report named Docker missing while it was still building. Both the wait and the verdict now go through one implementation, which is what let them drift apart in the first place.

Also

  • yazses tune looked like a hang. Against a real corpus it printed one line and nothing more for over eight minutes — the re-transcription of 3280 clips, silently, on a run that would take about two hours. The count is a metadata query known before any audio is touched, so it now announces the total and counts up.
  • A missing file was reported as a format problem. Asking the MCP server for a path that does not exist answered "probably not an audio or video file, or it is truncated" when the real error was No such file or directory — sending the reader to inspect the file's contents instead of its name. load_audio had promised FileNotFoundError in its docstring and never raised it.
  • Two status lines that read as faults. meeting list described an undiarized 8081-second meeting as 0 speaker(s), which reads as a failed recording rather than as speaker labelling never having been attempted; it now says not diarized. And yazses status printed uptime: 48176.17s — thirteen hours, in seconds, to two decimals never measured.
  • A privacy guard answered differently per Python. Carried over from v2.25.0's cycle: is_loopback_endpoint trusted a stdlib predicate that changed behaviour in 3.13, so an IPv4-mapped loopback endpoint was refused on 3.11 and 3.12.