fix: DEBUG-218 populate severity_bucket + assessment_type on crisis_detected emit#133
Merged
MP2EZ merged 1 commit intoJun 6, 2026
Conversation
…etected emit Both crisis-detection paths built the CrisisDetection object without severityLevel/assessmentType, so SupabaseService.trackCrisisDetection coerced the missing fields via String(undefined) → the literal "undefined" landed in analytics_events for the highest-acuity safety signal. Telemetry-only: the 988/intervention path, detection thresholds, and dedup ordering are unchanged. - assessmentStore: set severityLevel + assessmentType (+ secondaryTriggers) on the inline Q9 path AND CrisisDetectionService.detectCrisis. The score-based completed path was identically broken — the AC's claim it was already correct was wrong; non-Q9 crises (PHQ-9 >=15 no-Q9, GAD-7 >=15) also emitted "undefined". Severity derives from the existing total (>=20 critical, else high; GAD-7 high) via a shared helper — no threshold/trigger-taxonomy change. - SupabaseService.trackCrisisDetection: guard required categorical fields — a missing value degrades to an explicit 'unknown' sentinel + high-severity log and still emits (vital-interest event never dropped), never String(undefined). - Tests (test-first): regression suite drives the real inline + completed paths asserting no "undefined"; guard unit test pins the 'unknown' substitution; reconciled the emit fixture to the lowercase 'phq9' AssessmentType union. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes DEBUG-218
Problem
The vital-interest
crisis_detectedSupabase telemetry event landed the literal stringsseverity_bucket="undefined"/assessment_type="undefined"for the highest-acuity safety signal. Root cause: both crisis-detection paths built theCrisisDetectionobject withoutseverityLevel/assessmentType, andtrackCrisisDetectioncoerced the missing fields viaString(undefined). Telemetry-only — the 988/intervention path, detection thresholds, and dedup ordering are unchanged.AC correction (approved during planning)
The AC claimed the completed-assessment path "already sets both fields" — this was wrong.
CrisisDetectionService.detectCrisisbuilt the samePartial<CrisisDetection>cast and also omitted both, so non-Q9 crises (PHQ-9 ≥15 no-Q9, GAD-7 ≥15) also emitted"undefined". Scope was expanded to fix both detection sites (still additive — no threshold /trigger_typechange). The two intentionally-divergentdetectCrisisimplementations were NOT unified.Changes
assessmentStore.ts: setseverityLevel+assessmentType(+secondaryTriggers) on the inline Q9 path ANDCrisisDetectionService.detectCrisis, via shared helpers. PHQ-9 →criticalif total ≥20 elsehigh; GAD-7 →high; lowercasephq9/gad7(matches FEAT-129crisis_detection_dailygrouping). Inline severity derives from livecalculatePHQ9Score, try/catch'd with a safehighfloor so it can never throw into the crisis flow.SupabaseService.trackCrisisDetection: guard required fields — a missing value degrades to an explicit'unknown'sentinel + high-severitylogSecurityand still emits (vital-interest event never dropped), neverString(undefined).'phq9', droppedas anyso the type-checker enforcesAssessmentType.Tests (test-first)
crisisTelemetryFields.regression.test.ts(7) — drives the REAL inline + completed paths; boundaries Q9=0/Q9>0, low→high / ≥20→critical, PHQ 15–19→high, GAD≥15→high; asserts no"undefined".crisisTelemetryGuard.unit.test.ts(3) —'unknown'substitution + high-severity log + no false-positive.Maestro Phase 2.5 gate — deliberate override
The path-based gate triggered on the
src/features/assessment/edit and mapped to the q9/phq9/gad7 flows. This is a telemetry-only change: the user-visible contracts those flows pin (Q9 single-alert, PHQ-9 ≥20 completion banner, GAD-7 severe handoff) are provably unchanged — the jest regression confirms the only behavioral delta is the analytics payload on a fire-and-forget event that runs after the alert/intervention. Gate skipped by deliberate human decision (not--skip-e2e).🤖 Generated with Claude Code