# v2.50.0 — Settings that keep your changes, a first-run ready notice, and safer files and sockets

**Released 2026-11-06.** Upgrade:

```sh
sudo snap refresh yazses     # snap
pipx upgrade yazses          # or: uv tool upgrade yazses
scoop update yazses          # Windows
```

Restart the daemon afterwards (`yazses restart`). Three changes are visible; most of the rest corrects
something that did not do what it said.

## What you will notice

- **Settings asks before it drops your changes.** Closing the window with staged changes now offers Apply,
  Discard or Cancel (Cancel is the default and the Escape answer). While a package install or a language
  profile is being prepared, Apply is unavailable and only Discard or Cancel is offered.
- **A Refresh button beside the Microphone list.** A microphone plugged in after the Audio page opened is
  listed after one click, with your selection kept. If the device list cannot be read, the previous list is
  kept and the page says so.
- **The first run says when it is ready.** After YazSes downloads its speech model, a notice says
  "YazSes is ready — hold <key> to dictate". It appears only after a download in that run.
- **Troubleshooting says which launchers start the download.** `yazses start`, the macOS app and the Windows
  *YazSes* shortcut start it; the Linux app-grid entry and the Windows *YazSes Settings* shortcut open only
  Settings, so the answer there is `yazses start`.

## Security

- **The Meeting Mode recording is owner-only.** `audio.wav` is created `0600`, like the transcript and the
  other meeting files, and a symlink planted at that path is refused. Before, the raw meeting audio took the
  process umask and was usually readable by other local users.
- **The IPC socket is born owner-only.** It is bound under a `0o177` umask, closing the short window in which it
  existed with umask-derived permissions before the `chmod` that followed.
- **SLM model downloads are atomic and verified.** They go to a `.part` file with a timeout, are checked for
  length (and an optional SHA-256) before being renamed into place, and a truncated cached model is no longer
  trusted.

## Fixes

- **X11 erasing no longer deletes whole words.** Both the xdotool and the clipboard injectors now clear held
  modifiers when they send backspaces, so a hold-to-talk Ctrl still held at the start of a hold no longer turns
  each BackSpace into Ctrl+BackSpace. The clipboard injector also maps `meta` to Super.
- **Daemon lifecycle.** A stop requested while the daemon is still starting is honoured; a daemon being
  replaced no longer deletes its successor's socket and pid file; a dictation during a meeting no longer ends the
  meeting state; the daemon's own shutdown stops the push-to-talk recorder; and a failed typing is no longer
  recorded as typed — every lost dictation is announced.
- **Audio and streaming.** A failing consumer of audio chunks no longer aborts the microphone stream; on X11,
  releasing the hotkey while the microphone is opening no longer leaves it open; pressing the hotkey again during
  streaming no longer leaves two decode loops on one buffer.
- **IPC and MCP.** `ask_human` and `yazses send-to` no longer report a slow daemon as "not running"; the MCP
  server answers `ping`, negotiates the protocol version and rejects unknown tools and mistyped arguments; a
  malformed daemon reply is one typed error; a client that stalls mid-request no longer leaves a crash-like
  traceback in the daemon log.
- **Settings and tray.** Apply and restart no longer freezes the window; the General page says which key "auto"
  means; long microphone names no longer force a sideways scrollbar; the Linux tray menu shows what the other
  trays show.
- **Recovery.** Recovering from a missing speech model no longer dead-ends, and the phonetic corrector no longer
  scans every protected span for every token.
- **Microphones and meetings.** The OS default microphone is found by its index, so identical microphones (or
  one microphone listed under several host APIs) are no longer all marked as the default; a meeting that cannot
  open the microphone no longer leaks its recording file and a live-transcript thread on every retry.
- **Long and edited dictation.** Moonshine no longer loses a dictation that runs just past a multiple of 60
  seconds; "delete the last word" and "delete the last sentence" keep your line breaks; Persian normalisation
  gives the same result when run twice.
- **Overlay and tray.** A single non-finite audio level no longer leaves the overlay's sonar dark for the rest of
  the session.

Also in the repository, not in the product: a pure streaming-replay oracle and fake-screen tests that document
known streaming hazards as strict expected failures, a synthetic motor-imagery EEG stress study (hand-authored
waveforms, not human EEG), and research notes on prompt injection via transcripts, offline ASR runtimes and
model provenance, Android first use, and on-device ASR measurement. None of them changes what the software does.

What was checked: the full test suite, ruff, mypy and the documentation build on the release commit, and every
CI leg on `main` before this release was cut, including Windows, macOS, Linux arm64 and FreeBSD.

What was not checked: the Settings window and the tray on a real desktop session (the new close prompt and
Refresh button were tested offscreen with simulated dialogs and device lists), X11 erasing on a real X11 session,
Windows and macOS dictation on real machines, Wayland typing, Android, screen readers, real MCP clients, and any
biosignal device. Known gaps: the streaming preview's commit and cancel can act on a newly focused field or a
moved caret (documented by tests; the fix needs a design decision), and the Windows IPC client does not yet turn
a malformed reply into the typed error.

The complete list is in the [changelog](https://github.com/MSKazemi/yazses/blob/main/CHANGELOG.md).
