The Phase 4 checkbox was stale: the behaviour is already implemented across
the services, but almost nothing tested it, so a refactor could have quietly
removed it. The failure mode being guarded against is silent — an un-caught
exception in any of these paths aborts a live phone call.
What was verified rather than assumed:
- The classifier is purely spectral. classify_chunk takes only audio_data;
there is no transcript parameter, so STT cannot be a hard dependency of hold
detection. The README's "classifier works without STT" parenthetical
described an aspiration, not a coupling.
- All three transcribe() callers catch, publish an ERROR event naming the
service, and return "". TranscriptionService.transcribe raises deliberately
so callers own the fallback — swallowing it made a down Speaches look like
"the AI is deciding badly".
- An LLM failure in the receptionist still returns a usable decision, and in
hold_slayer falls through to "press 0 for agent".
- _service_error is itself wrapped, so a dead event bus cannot turn
degradation into a second failure.
- A failed transcription sets available=False, which is what /health reads —
a failure that doesn't record itself makes the probe lie.
Each test was checked by mutation: removing the try/except in
HoldSlayerService._transcribe fails three of them. Without that check these
would assert behaviour they don't actually constrain.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>