feat: Unified multimodal crisis scorer (#134) #145
Closed
Rockachopa
wants to merge 2 commits from
feat/134-unified-crisis-scorer into main
pull from: feat/134-unified-crisis-scorer
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/131-voice-analysis
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/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
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#145
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 "feat/134-unified-crisis-scorer"
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 #134
Epic: #102
What
Unified crisis scorer combining text, voice, image, and behavioral scores into a single risk assessment.
Implementation
crisis/unified_scorer.pyUnifiedCrisisScorer class:
add_text_score(score, indicators)— Text analysisadd_voice_score(score, indicators)— Voice analysisadd_image_score(score, indicators)— Image screeningadd_behavioral_score(score, indicators)— Behavioral trackingassess()→UnifiedCrisisScore— Combined assessmentget_988_resources()— Crisis responseScoring Model:
Crisis Levels:
Features:
tests/test_unified_scorer.py20+ tests covering:
Usage
Files
crisis/unified_scorer.py: Scorer module (300 lines)tests/test_unified_scorer.py: Tests (150 lines)Critical component — the unified scorer is the heart of multimodal crisis detection. Architecture is sound: weighted combination of text/voice/image/behavioral scores with level thresholds.
Critical findings:
SAFETY: requires_988 flag logic needs review: The PR sets requires_988=True at CRITICAL level. Verify this triggers the 988 Suicide & Crisis Lifeline resources reliably. A missed 988 delivery is a life-safety failure. Ensure the flag cannot be silently ignored downstream.
SAFETY: max-based vs weighted scoring: The assess() method uses weighted average. However, a single CRITICAL text score (0.95) could be diluted by low behavioral/image scores pulling the weighted average below CRITICAL threshold. Consider using max(individual_scores) as an override — if ANY modality hits CRITICAL, the unified score should be CRITICAL regardless of the weighted average.
Good: audit logging to JSONL for accountability. Verify the audit log cannot be tampered with in production.
Good: 988 resources include multiple contact methods (call, text, chat). The test checks for '988' and 'Jesus' in resources — the 'Jesus' check seems like a test artifact or project-specific; verify this is intentional.
Weight normalization: If only some modalities have scores, the weights should be renormalized to sum to 1.0 across available modalities. Verify this is handled.
Threshold review: CRITICAL at 0.80 combined score seems appropriate. The gap between HIGH (0.60) and CRITICAL (0.80) gives room for the weighted average concern in point #2.
Requesting changes due to the max-override concern (#2) — a single high-confidence CRITICAL signal from any modality must not be averaged away.
Closing: Superseded by #149 (behavioral detection subsumes multimodal scorer).
Pull request closed