feat(voice): Add VOICE_STRICT_MODE for conditional voice notifications
Summary
Adds VOICE_STRICT_MODE environment variable to control voice notification behavior in the stop-hook-voice system. When enabled, voice notifications only trigger when an explicit COMPLETED message is detected in the assistant's response—eliminating unwanted "Completed task" fallback notifications.
Problem
The current implementation falls back to speaking "Completed task" whenever no COMPLETED pattern is found in the response. This creates unwanted voice notifications for:
- Intermediate responses during multi-step workflows
- Conversational exchanges that don't represent task completions
- Error messages or clarification requests
Solution
Introduce VOICE_STRICT_MODE environment variable with the following behavior:
| VOICE_STRICT_MODE | COMPLETED Found | Result |
|---|---|---|
| unset / false | Yes | ✅ Speak completion message |
| unset / false | No | ✅ Speak "Completed task" (fallback) |
| true / 1 | Yes | ✅ Speak completion message |
| true / 1 | No | 🔇 Skip silently |
Changes
Code (Packs/kai-voice-system/src/hooks/stop-hook-voice.ts)
- Add
isStrictModeconstant readingVOICE_STRICT_MODEenv var (supportstrueand1) - Change
extractCompletion()return type fromstringtostring | null - Return
nullinstead of fallback when strict mode enabled and no COMPLETED found - Add
if (completion)guard inmain()to skip notification when null
Documentation (Packs/kai-hook-system/README.md)
- Add
VOICE_STRICT_MODEto environment variables table - Bump version to 1.1.0
- Add changelog entry
Configuration
Enable in your environment or $PAI_DIR/.env:
VOICE_STRICT_MODE=true
Test Plan
- Default behavior preserved: Without VOICE_STRICT_MODE, fallback to "Completed task" still works
- Strict mode + COMPLETED present: Voice notification fires with extracted message
- Strict mode + no COMPLETED: Silent skip (no notification sent)
- Build verification: TypeScript compiles without errors
Backward Compatibility
✅ Fully backward compatible - Existing behavior unchanged when VOICE_STRICT_MODE is unset or false.
🤖 Generated with https://claude.com/claude-code