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 typedWearableReferenceView 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 overallstatus 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. |
status == READY.
Per-dimension thresholds
Each primary dimension carries its ownmin_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 |
WearableReferenceView
The host-typed shape exposed by every SDK:- Flutter:
WearableReferenceViewinlib/src/models/sleep_score.dart - Kotlin:
WearableReferenceViewinsynheart-core/.../models/SleepScore.kt - Swift:
WearableReferenceViewinSynheartCore/Models/SleepScore.swift
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).
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 towardmin_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. |
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.
Related
- 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.