The shared-marker test used inspect.getsource(), which would pass while the
literal survived only in a comment and the classifier had stopped using it —
the exact break it exists to catch. Asserts through classify() now.
CHANGELOG: name AppLocker / Software Restriction Policy too (the taxonomy
covers WinError 1260), and don't imply the Smart App Control toggle is the
remedy on a managed PC.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two P1s, both correct:
- The enriched write failure lost its class. _describe_write_failure rewrites
the message, so the word "libsndfile" no longer appears — classify()
returned "" and the auto bug report and docs deeplink had nothing to name.
Worse, my own end-to-end test allowed "" as a pass, which is exactly why it
went unnoticed. audio_io now emits a stable AUDIO_WRITE_FAILED_MARKER,
failure.py matches that, and the assertion is exact.
- "error opening" was far too broad. It appears whenever a model, archive or
config file fails to open, so any such failure was handed the audio-file
remedy (check your disk, add an antivirus exclusion). Dropped in favour of
the marker; a regression test pins that a corrupt-model-archive error keeps
its own guidance.
A third test pins the marker across the two modules — core/ cannot import
services/, so the string is duplicated by necessity, and a reword on either
side would silently un-classify every enriched write failure.
CHANGELOG entries shortened with refs last (CodeRabbit).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`_oom_friendly_reraise` classifies every known way a generate can die; two real
reports fell through to its "an error OmniVoice doesn't recognize" catch-all.
#1227 — `OSError: [WinError 4551] An Application Control policy has blocked
this file`. Windows Smart App Control refused to load a file the engine needs.
Now named, with the setting to change (and the caveat that Windows only lets
you turn Smart App Control off once). WinError 1260 — the same class from
AppLocker / Software Restriction Policies — is matched too, on the numeric
codes, since Windows translates the message text.
#1221 — `LibsndfileError: System error.`, libsndfile's bare wording for an
OS-level audio read/write failure: no path, no errno, no next step. Two parts:
- `audio_io._safe_torchaudio_save` now re-raises write failures naming the
target, whether its folder exists and is writable, and the drive's free
space — the facts that identify a full disk, a removed drive, or an
antivirus/OneDrive lock. (It cannot re-use the original type:
`LibsndfileError.__init__` takes an integer libsndfile code, so
`type(e)(message)` builds an exception whose `str()` raises.)
- `_oom_friendly_reraise` covers every other libsndfile surface (reading a
reference clip, a decode) with the same causes.
Both get a `core.failure` class + hint (WINDOWS_APP_CONTROL_BLOCKED,
AUDIO_IO_FAILED) so the auto bug report and docs deeplink name them.
Regression test: tests/test_synth_error_classes.py — 11 of 12 fail before.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>