@@ -99,13 +99,54 @@ const baseUrl =
9999const audioUrl = ` ${baseUrl }/audio/dreams/${dreamId }_combined.opus ` ;
100100```
101101
102- ### Sleep Detection Flow
102+ ### Sleep Detection Flow (Hybrid Classifier)
103103
104- 1 . ` services/sleep.ts ` captures microphone via Web Audio API
105- 2 . Meyda extracts RMS, spectral features for breathing analysis
106- 3 . Breathing regularity + RRV (respiratory rate variability) → sleep stage
107- 4 . ` onRemStart ` /` onRemEnd ` callbacks fire when REM detected
108- 5 . ` SleepModePlayer ` plays queued dreams during REM windows
104+ The app uses a hybrid classifier that fuses audio-based breathing analysis with wearable vitals (via HealthConnect/HealthKit):
105+
106+ ```
107+ ┌─────────────────────────────────────────────────────────────────┐
108+ │ SLEEP SESSION START │
109+ ├─────────────────────────────────────────────────────────────────┤
110+ │ 1. Load existing model (or create empty) │
111+ │ 2. Start hybrid session │
112+ │ 3. [Background] Auto-retrain if model >24h old │
113+ └─────────────────────────────────────────────────────────────────┘
114+ │
115+ ┌───────────────────┴───────────────────┐
116+ ▼ ▼
117+ ┌─────────────────────┐ ┌─────────────────────┐
118+ │ AUDIO SOURCE │ │ VITALS SOURCE │
119+ │ (Microphone) │ │ (HealthConnect) │
120+ ├─────────────────────┤ ├─────────────────────┤
121+ │ Web Audio API │ │ HR, HRV, RR │
122+ │ → Meyda features │ │ → 30s polling │
123+ │ → Breathing analysis│ │ → RMSSD/CV analysis │
124+ └─────────────────────┘ └─────────────────────┘
125+ │ │
126+ └───────────────────┬───────────────────┘
127+ ▼
128+ ┌─────────────────────────────────────────────────────────────────┐
129+ │ HYBRID CLASSIFIER │
130+ │ • Fuses audio + vitals with weighted probabilities │
131+ │ • Applies temporal priors (awake more likely at start/end) │
132+ │ • Two-stage: Awake detection → REM vs NREM │
133+ │ • Computes remConfidence for playback gating │
134+ └─────────────────────────────────────────────────────────────────┘
135+ │
136+ ▼
137+ ┌─────────────────────────────────────────────────────────────────┐
138+ │ REM PLAYBACK GATE │
139+ │ if (stage === 'rem' && remConfidence >= 0.5) → play dream │
140+ │ else → log and skip │
141+ └─────────────────────────────────────────────────────────────────┘
142+ ```
143+
144+ ** Key Components:**
145+
146+ - ` services/sleep.ts ` - Session management, audio capture, stage transitions
147+ - ` services/hybridClassifier.ts ` - Fuses audio + vitals sources
148+ - ` services/remOptimizedClassifier.ts ` - REM-focused classification with learned parameters
149+ - ` services/healthConnect.ts ` - Android Health Connect integration
109150
110151### State Sharing (Launch Queue)
111152
@@ -217,21 +258,24 @@ export function useLaunchQueue() {
217258- Browse/Search with transcript content matching
218259- Audio playback with progress persistence
219260- Favorites system (local storage)
220- - Sleep tracking UI with audio-based detection
221261- Queue management with shared state
222262- CI audio generation (Edge TTS + procedural music)
263+ - ** Health Connect integration** (Android) - HR, HRV, respiratory rate, sleep stages
264+ - ** Hybrid sleep classifier** - fuses audio + vitals for stage detection
265+ - ** Auto-training classifier** - learns from user's HealthConnect history
266+ - ** REM confidence gating** - prevents false positive dream playback
223267
224268### Partial
225269
226270- Auth (UI complete, uses mock data)
227271- Offline indicator (component exists, not integrated)
228- - HealthKit/Health Connect ( stub only)
272+ - HealthKit (iOS) - stub only, Health Connect (Android) is complete
229273
230274### Not Started
231275
232276- Supabase backend integration
233277- Deep link handling
234- - Wearable device sync
278+ - watchOS/WearOS companion apps
235279
236280## Audio Generation
237281
@@ -250,18 +294,53 @@ See `scripts/AGENTS.md` for detailed audio pipeline documentation.
2502944 . Generate audio: ` python scripts/generate_audio.py --dream dream-N `
2512955 . Commit only ` *_combined.opus ` files
252296
253- ## Sleep Detection Thresholds
297+ ## Sleep Classifier Configuration
298+
299+ ### Two-Stage Classification (Option A+C)
300+
301+ ``` typescript
302+ // services/remOptimizedClassifier.ts
303+
304+ // Stage 1: Awake Detection
305+ const AWAKE_MEAN_DIFF_BASE_THRESHOLD = 3.0 ; // HR beat-to-beat variability
306+ const AWAKE_CONSECUTIVE_REQUIRED = 1 ; // Signals before awake confirmed
307+
308+ // Learned awake priors by 30-min time bins (from Fitbit analysis)
309+ // 0-30min: 38.1%, 30-60min: 4.8%, 60-90min: 1.6%, ...330-360min: 30.9%
310+
311+ // Dynamic threshold adjustment based on time prior:
312+ // prior > 25% → threshold * 0.85 (more sensitive at sleep onset/wake)
313+ // prior < 5% → threshold * 1.3 (less sensitive mid-sleep)
314+
315+ // Stage 2: REM vs NREM
316+ const CV_THRESHOLD = 0.2 ; // RMSSD coefficient of variation
317+ const REM_CONSECUTIVE_REQUIRED = 2 ; // Consecutive signals for REM
318+
319+ // Blended awake score: 0.7 * hr_signal + 0.3 * time_prior > 0.4
320+ ```
321+
322+ ### REM Playback Gating
254323
255324``` typescript
256325// services/sleep.ts
257- const BREATHING_RATE_MIN = 8 ; // BPM
258- const BREATHING_RATE_MAX = 25 ; // BPM
259- const REM_RRV_THRESHOLD = 0.25 ; // High variability = REM
260- const DEEP_SLEEP_RRV_THRESHOLD = 0.1 ; // Low variability = deep
261- const DROWSY_BREATHING_REGULARITY = 0.7 ;
262- const SLEEP_BREATHING_REGULARITY = 0.85 ;
326+ const MIN_REM_CONFIDENCE_FOR_PLAYBACK = 0.5 ;
327+
328+ // remConfidence computed from:
329+ // - REM probability from classifier
330+ // - Time bonus (>70 min since sleep start)
331+ // - REM window bonus (in expected REM portion of cycle)
332+ // - Consecutive REM signals
333+ // - REM propensity (increases through night)
263334```
264335
336+ ### Expected Performance (Best Balanced)
337+
338+ | Metric | Value |
339+ | ----------------- | ----- |
340+ | REM Sensitivity | 79.8% |
341+ | Awake Sensitivity | 31.0% |
342+ | Awake Precision | 30.8% |
343+
265344## Deployment
266345
267346- ** Web** : GitHub Pages at https://context-lab.com/dream-stream/
@@ -333,4 +412,4 @@ Health Connect is integrated and working:
333412
334413---
335414
336- _ Last updated: 2026-01-13 _
415+ _ Last updated: 2026-01-15 _
0 commit comments