Documentation Index
Fetch the complete documentation index at: https://docs.synheart.ai/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The Self-Reference Model (SRM) is the per-subject longitudinal baseline engine inside the native runtime. It ingests vendor-agnostic daily wearable values, maintains rolling per-dimension statistics, and emits a typed WearableReferenceView that downstream scoring (recovery, readiness) consumes as “the user’s normal.”
It is the data model behind the reference field on Baselines. Hosts never write SRM state directly — they push daily values, and the runtime maintains the model.
Dimensions
The SRM tracks 11 dimensions. Five are primary: they gate the overall maturity state. The remaining six are secondary — populated when available, used by specific scorers, but not required for the model to be considered ready.
| Dimension | Tier | Window | Notes |
|---|
sleep_need | primary | 14d | 30d buffer retained |
sleep_regularity | primary | 14d | |
hrv_rmssd | primary | 30d | 2-MAD outlier exclusion |
resting_hr | primary | 14d | 2-MAD outlier exclusion |
recovery_score | primary | 30d | |
hrv_sdnn | secondary | 30d | Apple Health SDNN, tracked separately from RMSSD |
deep_sleep_min | secondary | 7d | μ/σ |
rem_sleep_min | secondary | 7d | μ/σ |
daily_strain | secondary | 14d | |
motion_steps_est | secondary | 14d | 2-MAD outlier exclusion |
hrv_hr_std_bpm | secondary | 30d | Overnight HR standard deviation |
Maturity states
The overall status field on WearableReferenceView has four values, emitted by the runtime as uppercase strings:
| Status | Meaning |
|---|
EMPTY | No reference exists, or all dimensions absent. |
WARMING | At least one primary dimension present, but not all five at sufficient confidence. |
READY | All five primary dimensions present, each at or above its per-dimension min_confidence. Downstream personalized scoring is unlocked. |
STALE | Was READY; at least one primary dimension has decayed past its staleness_days window or fallen to zero confidence. |
Personalized scoring (e.g. recovery Stage 3) gates on status == READY.
Per-dimension thresholds
Each primary dimension carries its own min_days, min_confidence, and staleness_days:
| Dimension | min_days | min_confidence | staleness_days |
|---|
sleep_need | 7 | 0.50 | 7 |
sleep_regularity | 5 | 0.50 | 7 |
hrv_rmssd | 10 | 0.50 | 7 |
resting_hr | 5 | 0.45 | 10 |
recovery_score | 7 | 0.50 | 5 |
Confidence ramps up linearly over the first three days after a gap resumes, and decays exponentially when observations stop arriving.
WearableReferenceView
The host-typed shape exposed by every SDK:
status: String // "EMPTY" | "WARMING" | "READY" | "STALE"
modelVersion: String?
recentSleepScoreMedian: Int?
dimensions: Map<String, Number> // per-dimension central value
confidence: Map<String, Double> // 0.0 – 1.0 per dimension
Cross-language parity:
- Flutter:
WearableReferenceView in lib/src/models/sleep_score.dart
- Kotlin:
WearableReferenceView in synheart-core/.../models/SleepScore.kt
- Swift:
WearableReferenceView in SynheartCore/Models/SleepScore.swift
Kotlin types dimensions as Map<String, Number>; Swift and Dart use the platform numeric type (Double / num). Shape is otherwise byte-equivalent across platforms.
Source fidelity
The engine distinguishes two input fidelities:
- Raw observation — direct samples (e.g. an HR trace the runtime aggregated itself).
- Provider summary — pre-computed vendor metrics (e.g. a Whoop recovery score).
Both count equally toward min_days. Confidence is weighted by raw_ratio — a dimension fed only by provider summaries matures, but at discounted confidence relative to one fed by raw samples.
Backfill parity
Nights ingested via Health backfill and nights ingested live are treated identically by the SRM — backfilled days count toward min_days the same as live days. Backfill events carry a backfilled flag for telemetry; this does not change their weight in the model.
Late backfill (events older than seven days) does not trigger an incremental recompute; the runtime performs a full recompute instead.
Snapshot lifecycle
The runtime exposes export and load over FFI so hosts can persist longitudinal state across cold starts:
| FFI symbol | When the host calls it |
|---|
synheart_core_export_srm_snapshot | On app background / session end. The host writes the returned JSON to its own secure store (Keychain, EncryptedSharedPreferences). |
synheart_core_load_srm_snapshot | On app cold start, after the runtime handle is created. Schema or config mismatch is rejected; the caller must invoke recompute() afterward — load alone does not produce a new WearableReferenceView. |
synheart_core_wipe_local_data | On user consent revocation or account wipe. Clears the SRM snapshot along with other local stores. |
The Baselines.reset() facade method clears the host-side cache only — it does not wipe the runtime’s SRM snapshot. Use the FFI wipe call for runtime state.
- Baselines facade — host-facing read API over the latest reference + recent-scores ring.
- Scoring models — recovery/readiness/sleep scorers that consume the reference view; personalized stage gates on
status == READY.
- Health backfill — cold-start path that seeds the SRM from platform health stores.
- Runtime FFI — snapshot export/load and direct SRM accessors.