c15f9b71a5
Premise check on live main: barge-in machinery EXISTS for the per-turn STREAMING pipeline only — cli.py chat() arms _voice_barge_in_monitor and tui_gateway _tts_stream_begin arms _tts_stream_barge_in_monitor. What was actually broken for spoken interruptions: 1. CLI whole-file fallback (_voice_speak_response_async — used whenever streaming TTS cannot start: sounddevice missing, requirement probe fails): NO monitor was ever armed, so talking over the reply did nothing. Now arms _voice_barge_in_monitor in continuous voice mode. 2. Gateway fallback speak (tts_queue None → speak_text thread) and the voice.tts RPC (desktop-triggered speech): speak_text ran bare, and its internal streaming dispatch created a PRIVATE stop event nothing could reach — uninterruptible even by stop_playback(). New _speak_text_with_barge() runs the same barge monitor beside the speak thread; hermes_cli.voice.speak_text/_speak_text_streaming accept an external stop_event so a barge cuts the streaming pipeline too. Stop-phrase handling and voice.transcript submission are inherited from the shared monitor (merged #73933 behavior preserved). 3. False barge during TTS (the reason interruption "worked" then self-cancelled or fired randomly): salvaged PR #71083 by @beardedeagle (previous commit, kept authorship) — rolling-window VAD floor, 8x multiplier, 4000-RMS trigger ceiling, barge_in_grace_seconds (2s) before the mic opens, min-floor clamp. barge_in_grace_seconds is now documented in DEFAULT_CONFIG. Desktop spoken barge (renderer mic via voice-barge-in.ts) already covers both its live-stream and fallback speech paths — verified, no change.