feat: voice message distress analysis — paralinguistic features (#131) #173
Open
bezalel
wants to merge 1 commits from
fix/131-voice-analysis into main
pull from: fix/131-voice-analysis
merge into: Timmy_Foundation:main
Timmy_Foundation:main
Timmy_Foundation:fix/200
Timmy_Foundation:step35/201-intake-submission-from-image
Timmy_Foundation:step35/203-intake-submission-from-image
Timmy_Foundation:step35/200-intake-submission-from-test
Timmy_Foundation:step35/197-door-1-build-anonymous-intake
Timmy_Foundation:fix/121
Timmy_Foundation:fix/99
Timmy_Foundation:fix/130
Timmy_Foundation:fix/141-crisis-contract
Timmy_Foundation:burn/20260421-0040-fix
Timmy_Foundation:fix/101
Timmy_Foundation:fix/134
Timmy_Foundation:fix/135
Timmy_Foundation:fix/100
Timmy_Foundation:fix/123
Timmy_Foundation:fix/133
Timmy_Foundation:fix/36
Timmy_Foundation:fix/37
Timmy_Foundation:fix/96
Timmy_Foundation:fix/41
Timmy_Foundation:fix/673-genome-door
Timmy_Foundation:fix/95
Timmy_Foundation:fix/97
Timmy_Foundation:fix/73-toast-alerts
Timmy_Foundation:fix/59-about-footer-link
Timmy_Foundation:fix/59-1776403637
Timmy_Foundation:burn/59-1776304777
Timmy_Foundation:fix/59-about-link
Timmy_Foundation:fix/136-crisis-metrics-cli
Timmy_Foundation:feat/136-cli-metrics
Timmy_Foundation:fix/38
Timmy_Foundation:fix/75
Timmy_Foundation:fix/673
Timmy_Foundation:door/issue-38
Timmy_Foundation:fix/141
Timmy_Foundation:fix/59
Timmy_Foundation:burn/73-inline-toast
Timmy_Foundation:burn/1601-crisis-logic-alignment
Timmy_Foundation:burn/123-1776303473
Timmy_Foundation:burn/73-1776303595
Timmy_Foundation:burn/123-1776303595
Timmy_Foundation:fix/130-behavioral
Timmy_Foundation:feat/136-crisis-metrics-cli
Timmy_Foundation:feat/134-unified-crisis-scorer
Timmy_Foundation:feat/133-behavioral-detection
Timmy_Foundation:feat/131-voice-analysis
Timmy_Foundation:burn/35-1776218265
Timmy_Foundation:fix/132
Timmy_Foundation:burn/99-1776264183
Timmy_Foundation:burn/99-1776264262
Timmy_Foundation:fix/136
Timmy_Foundation:fix/123-duplicate-patterns-6213
Timmy_Foundation:fix/burn-crisis-logic-alignment
Timmy_Foundation:burn/37-1776264184
Timmy_Foundation:burn/101-1776264183
Timmy_Foundation:burn/69-1776264183
Timmy_Foundation:burn/101-1776264262
Timmy_Foundation:burn/38-1776264184
Timmy_Foundation:burn/41-1776264184
Timmy_Foundation:burn/36-1776264184
Timmy_Foundation:burn/101-1776263878
Timmy_Foundation:door/issue-35
Timmy_Foundation:door/issue-69
Timmy_Foundation:fix/101-crisis-ab-testing
Timmy_Foundation:fix/94-safety-plan-inline-feedback
Timmy_Foundation:feat/safety-plan-history
Timmy_Foundation:fix/96-safety-plan-version-history
Timmy_Foundation:fix/97-crisis-metrics-endpoint
Timmy_Foundation:fix/98-offline-crisis-resources
Timmy_Foundation:fix/crisis-overlay-debounce
Timmy_Foundation:fix/90-overlay-focus-enabled-element
Timmy_Foundation:fix/95-overlay-keyboard-nav
Timmy_Foundation:fix/59-footer-about-link
Timmy_Foundation:fix/95-crisis-overlay-keyboard-nav
Timmy_Foundation:fix/overlay-escape-key
Timmy_Foundation:burn/73-1776218082
Timmy_Foundation:burn/73-1776218180
Timmy_Foundation:burn/36-1776218258
Timmy_Foundation:fix/38-safety-plan-in-chat
Timmy_Foundation:burn/69-1776218206
Timmy_Foundation:burn/69-1776217968
Timmy_Foundation:burn/37-1776217996
Timmy_Foundation:burn/73-1776217949
Timmy_Foundation:door/issue-73
Timmy_Foundation:burn/41-1776217979
Timmy_Foundation:fix/issue-75-1
Timmy_Foundation:fix/issue-73-2
Timmy_Foundation:fix/67-focus-trap
Timmy_Foundation:fix/65-modal-focus-trap
Timmy_Foundation:fix/69-initial-focus
Timmy_Foundation:fix/59-about-route
Timmy_Foundation:fix/59-footer-about
Timmy_Foundation:dispatch/38-1776180746
Timmy_Foundation:dispatch/40-1776180746
Timmy_Foundation:am/38-1776166469
Timmy_Foundation:am/40-1776166469
Timmy_Foundation:am/41-1776166469
Timmy_Foundation:dispatch/41-1776180746
Timmy_Foundation:dawn/38-1776130053
Timmy_Foundation:triage/38-1776129677
Timmy_Foundation:q/38-1776129480
Timmy_Foundation:queue/38-1776129201
Timmy_Foundation:burn/59-1776131200
Timmy_Foundation:burn/37-1776131000
Timmy_Foundation:dawn/40-1776130053
Timmy_Foundation:dawn/41-1776130053
Timmy_Foundation:triage/40-1776129677
Timmy_Foundation:triage/41-1776129677
Timmy_Foundation:q/41-1776129480
Timmy_Foundation:q/40-1776129480
Timmy_Foundation:queue/41-1776129201
Timmy_Foundation:queue/40-1776129201
Timmy_Foundation:whip/38-1776128804
Timmy_Foundation:whip/40-1776128804
Timmy_Foundation:whip/41-1776128804
Timmy_Foundation:feat/session-crisis-tracking
Timmy_Foundation:burn/20260413-1620-dying-detection-dedup
Timmy_Foundation:feat/crisis-synthesizer
Timmy_Foundation:feat/compassion-router-wiring
Timmy_Foundation:fix/deduplicate-crisis-detectors
Timmy_Foundation:feat/compassion-router-gateway
Timmy_Foundation:fix/dedup-crisis-detector
Timmy_Foundation:fix/remove-bridge-false-positive
Timmy_Foundation:burn/20260413-0406-fix
Timmy_Foundation:burn/rescue-crisis
Timmy_Foundation:burn/20260413-0213-vps-deploy
Timmy_Foundation:fix/test-none-input
Timmy_Foundation:burn/20260412-0812-vps-prep
Timmy_Foundation:burn/20260412-1851-crisis-system
Timmy_Foundation:burn/20260409-1931-crisis-prompt
Timmy_Foundation:burn/20260410-2030-crisis-active-listening
Timmy_Foundation:fix/add-smoke-test
Timmy_Foundation:feat/ci-sanity-checks
Timmy_Foundation:feat/detailed-crisis-guidelines
Timmy_Foundation:burn/20260409-1230-issue4-crisis-backend
Timmy_Foundation:feat/sovereign-heart-router
Timmy_Foundation:feature/resilience
Timmy_Foundation:feature/content-pages
Timmy_Foundation:feature/dying-detection
Timmy_Foundation:feature/crisis-system-prompt
Dismiss Review
Are you sure you want to dismiss this review?
Labels
Clear labels
backend
batch-pipeline
content
deploy
epic
frontend
hardening
infra
priority:critical
priority:high
priority:medium
protocol
throughput-10x
token-masterplan
velocity-engine
Backend / API
batch-pipeline label
Content, copy, testimony
Deployment / go-live
Epic / parent issue
Frontend / UI
Resilience, fallback, security
Infrastructure, DevOps, deployment
Must have for launch
Important for launch
Nice to have at launch
Crisis detection protocol
throughput-10x label
token-masterplan label
Auto-generated by velocity engine
No Label
Milestone
No items
No Milestone
Projects
Clear projects
No project
Assignees
Rockachopa
Timmy
allegro
antigravity
bezalel
claude
codex-agent
ezra
gemini
google
grok
hermes
kimi
manus
perplexity
sonnet
Clear assignees
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: Timmy_Foundation/the-door#173
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "fix/131-voice-analysis"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #131\nEpic: #102 (Multimodal Crisis Detection)\n\n## What\nParalinguistic feature extraction for voice message distress analysis.\n\n## File\n-
voice_analysis.py— full analysis pipeline\n\n## Signals Detected\n1. Speech rate (very slow <80 WPM or very fast >200 WPM)\n2. Pitch variability (monotone <15 Hz std dev = depression indicator)\n3. Silence ratio (excessive pauses >40%)\n4. Vocal tremor (amplitude modulation in 3-12 Hz band)\n5. Volume drops (sudden >50% decreases)\n\n## API\npython\nresult = analyze_voice_message("voice.ogg")\n# Returns: transcript, speech_rate, pitch_mean, pitch_variability,\n# silence_ratio, tremor_score, volume_drop_score,\n# distress_score (0-1), distress_level (none/low/medium/high)\n\n\n## Dependencies\n- whisper (optional — transcription)\n- librosa (optional — audio feature extraction)\n- numpy (optional — numerical analysis)\n- Falls back gracefully if any are missing\n\n## Acceptance\n- [x] Voice analysis module exists\n- [x] All 5 paralinguistic signals detected\n- [x] Distress score thresholds: low (<0.3), medium (0.3-0.7), high (>0.7)\n- [x] Integrates with crisis_detector.py🚫 Cannot merge PR #173 - Merge failed. Reason:
🔎 Merge sweep 2026-04-21: not merging this PR in the current sweep. Blocked: large voice-analysis module lands without tests/integration and uses risky temp-file / optional-dependency assumptions.
Perplexity Review — PR #173
Status: Approve with reservation
Adds voice message distress analysis via paralinguistic features (issue #131, epic #102). Analyzes speech rate, pitch variability, silence ratio, vocal tremor, and volume drops to compute a composite distress score.
Strengths:
Concerns:
Verdict: Solid foundation for multimodal crisis detection. Must add tests and fix the tempfile.mktemp() security issue before merging. Input validation on audio_path is also recommended.
Approved — 1 file(s) changed, +350/-0 lines.
Minor observations (non-blocking):
Review: APPROVE
Voice message distress analysis via paralinguistic features. Well-structured with clear thresholds and graceful degradation when libraries are unavailable.
Good: Graceful fallback when whisper/librosa/soundfile are not installed. Each analysis function returns 0.0 on ImportError. Composite scoring with weighted modalities.
tempfile.mktempis insecure:_convert_to_wavusestempfile.mktemp()which is deprecated due to race conditions. Usetempfile.NamedTemporaryFile(suffix=.wav, delete=False)instead.subprocess.runwithoutcheck=True: The ffmpeg call does not check the return code. If ffmpeg fails (bad input, unsupported codec), the function silently returns the original audio path, which may not be in a format the analysis functions expect.Whisper model loaded on every call:
_transcribecallswhisper.load_model("base")every time. This loads the model from disk/network on each voice message. Cache the model at module level or use a singleton.No tests in this PR: The voice analysis module has zero test coverage. At minimum, add tests for
_compute_distress_scorewith known inputs, and for the graceful degradation paths.Temp file cleanup: If an exception occurs between
_convert_to_wavand the cleanup at the end ofanalyze_voice_message, the temp file leaks. Use a try/finally block.Approve with the recommendation to address the tempfile security issue and add tests.
This PR adds voice message distress analysis via paralinguistic features (voice_analysis.py). Review findings:
The paralinguistic feature set (speech rate, pitch variability, silence ratio, tremor, volume drops) is clinically appropriate for distress detection. Fix the mktemp deprecation.
Need to check this PR.
Well-structured voice analysis module. The paralinguistic feature extraction (speech rate, pitch variability, silence ratio, tremor, volume drops) covers the key distress indicators. Good fallback behavior when ffmpeg or whisper are unavailable. The composite distress score calculation with weighted signals is reasonable. Clean dataclass for results. Approve.
🛡️ Goblin Patrol Alert 🛡️
Hey brother — this PR has been idle for 10 days and is unassigned.
The goblin fleet has been notified. A goblin may claim this if it remains stale.
— Timmy Goblin Wizard King
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.