GAP Score (General Adaptation Profile) — Technical Blueprint¶
Extracted from Jeff's brainstorm session. Core proprietary capability for BioThread.
The Problem¶
Standard fitness apps (Apple Health, Whoop) treat all fatigue as cardiovascular. They rely on Resting Heart Rate (RHR) and RMSSD-based Heart Rate Variability (HRV) — primarily indicators of cardiovascular (parasympathetic) recovery.
What they miss: Neuromuscular / Central Nervous System (CNS) exhaustion requires measuring mechanical degradation and sympathetic nervous system state. A user can be "cardiovascularly recovered" while their CNS is fried — leading to injury when the app says "go hard."
The Moat¶
BioThread's proprietary advantage: cross-referencing CV metrics against mechanical and sleep-architecture metrics to detect the gap between cardiovascular recovery and CNS recovery.
Required Data Streams¶
Cardiovascular (CV) Readiness Markers¶
- RHR (Resting Heart Rate): Rolling 7-day average vs. acute overnight average
- HRV (RMSSD): Nightly average
Neuromuscular (CNS) State Markers¶
- Running/Movement Dynamics: Ground Contact Time (GCT), Vertical Oscillation, Stride Length. Degradation at constant pace/HR = primary CNS misfiring indicator.
- Sleep Architecture: Deep Sleep duration vs. REM duration. CNS recovery occurs predominantly during Deep Sleep (Delta wave).
- HF vs. LF HRV: If available via raw R-R intervals, elevated LF/HF ratio = sympathetic dominance (stress/overtraining) even if RMSSD looks normal.
GAP Score Algorithm¶
Two distinct indices calculated from the data streams:
CV Index (Cardiovascular Recovery)¶
CNS Index (Neuromuscular Recovery)¶
CNS_index = w3 * normalize(GCT_baseline - GCT_acute) + w4 * normalize(DeepSleep_ratio) + w5 * normalize(LF_HF_ratio_inverse)
The GAP Score¶
When GAP_Score > Threshold, the system triggers a prescriptive coaching intervention.
Note: w1-w5 are tunable weighting coefficients adjusted during beta testing.
Actionable Scenarios¶
Scenario A: CV Recovered, CNS Depleted¶
- RHR is low, RMSSD is high (CV_index high)
- Ground Contact Time increased 8% during yesterday's run, Deep Sleep severely compromised (CNS_index low)
- Standard app says: "Fully recovered! Go hard today." ❌ (leads to injury)
- BioThread says: "Cardio is recovered, but mechanical metrics indicate severe CNS fatigue. Substitute heavy lifting/sprints with Zone 2 active recovery to prevent neuromuscular injury." ✅
Scenario B: Systemic Fatigue¶
- Both indices depressed
- BioThread says: "Systemic fatigue detected. Total rest day."
Scenario C: CNS Recovered, CV Lagging¶
- CNS_index high, CV_index low
- BioThread says: "Nervous system is fresh but cardiovascular system needs recovery. Good day for technique work or light skill training."
Implementation Phases¶
Phase 1: Data Ingestion¶
- Webhook receiver for Garmin Health API and Apple HealthKit
- Filter for raw granular metrics (not summary data)
- PostgreSQL with time-series alignment
- Continuous data pipeline
Phase 2: Calculation Engine¶
- Python microservice (Pandas/Polars)
- 7-day rolling baselines
- Execute fatigue gap formulas on each new data ingestion
- Store results in time-series
Phase 3: API Output¶
- Endpoint serving GAP_Score status (boolean + score)
- Prescriptive text string for frontend
- Historical trend data for dashboard visualization
Data Sources to Integrate¶
- Garmin Health API (running dynamics, sleep stages, HRV)
- Apple HealthKit (HR, HRV, sleep, workouts)
- Future: Whoop API, Oura API, COROS API
Open Questions¶
- What wearables are most common in our target market (mid-market teams)?
- Can we get raw R-R interval data from Garmin/Apple, or only derived RMSSD?
- How do we validate the weighting coefficients without a large dataset?
- Should Phase 1 start as a standalone proof-of-concept or embedded in the larger Ascent platform?