Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion lib/compute/derivation_engine.dart
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,22 @@ import 'substrate.dart';
// ~17.5% of subjects get WORSE from personalization), and (3) discarding
// pre-tracking profiles, which cannot be repaired, so they rebuild honestly.
// Bump so every day re-stages without the corrupt blend.
const int kAlgoVersion = 52;
// v53: repin analytics to main @ #34 — the sleep-stager decision layer is
// rewritten. Deep and REM were boolean conjunctions AND-ing one informative
// axis with one null one (rmssd, Cohen's d -0.13 deep / -0.02 REM) and one
// INVERTED one (mean HR, d +0.31 for deep, i.e. deep sleep runs slightly
// FASTER than light on the wrist), so all three could only co-fire by
// coincidence — which is why deep sleep came out as isolated 30-second specks
// that the 3-min minimum-bout rule then deleted. Scored against 99 PSG-labelled
// wrist nights those rules managed kappa 0.036, with deep PPV 5.7% against a
// 4.5% base rate and REM 12.1% against 14.0% — at or below chance for both.
// Now weighted robust-z scores (weights = the measured effect sizes) over
// Rk / hrSd / sdnn / lfhf, with rmssd and mean HR dropped: kappa 0.128, 0.132
// on held-out subjects, deep 53.0/12.9 and REM 52.6/20.7 sens/PPV. Every day's
// hypnogram, stage minutes and sleep-derived scalars change, so every day must
// re-derive. Also picks up the protocol realtimeRr bound (live HRV no longer
// sees implausible sub-100ms "beats" from a misaligned 0x28 frame).
const int kAlgoVersion = 53;

// Fold idempotency, the minimum-nights warm-up, and legacy-payload handling
// all live in SleepProfilePolicy (pure, unit-tested) — see
Expand Down
8 changes: 4 additions & 4 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -964,17 +964,17 @@ packages:
dependency: "direct main"
description:
path: "."
ref: cbbe06addec1cb78b4ea2c75f64e8a281ac09294
resolved-ref: cbbe06addec1cb78b4ea2c75f64e8a281ac09294
ref: f0d115308aa5e9e3c82ee113c3d52e59756121d4
resolved-ref: f0d115308aa5e9e3c82ee113c3d52e59756121d4
url: "https://github.com/OpenStrap/analytics.git"
source: git
version: "1.0.0"
openstrap_protocol:
dependency: "direct main"
description:
path: "."
ref: "5bb8606964f2d94d9a73dc42c57416cb74282d52"
resolved-ref: "5bb8606964f2d94d9a73dc42c57416cb74282d52"
ref: "7edcb3e377329968118c62cb03a81d95e2f6db8e"
resolved-ref: "7edcb3e377329968118c62cb03a81d95e2f6db8e"
url: "https://github.com/OpenStrap/protocol.git"
source: git
version: "1.0.0"
Expand Down
43 changes: 25 additions & 18 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,27 +41,34 @@ dependencies:
# hexToBytes rejects odd-length hex instead of silently flooring it. This
# PR sat unpinned for a full day after merging — see fix/issues #22 for
# why (edge's own release pipeline shipped the pre-fix decoder).
# NOTE: this ref predates protocol fix/issues#21 (realtimeRr RR-bound,
# historical-family activity/steps_inc null-vs-0) — repin again once #21
# merges to pick those up too.
# Verified present: `git show <sha>:lib/src/framing.dart | grep 'crc8(Uint8List'`.
ref: 5bb8606964f2d94d9a73dc42c57416cb74282d52
# protocol main @ #21 merge. Picks up the realtimeRr RR-bound (live.dart
# accepted ANY positive int16 as an interval, unlike parseRealtimeHr and
# parseR24 which both gate 200-2500ms, so a misaligned 0x28 frame could
# hand a 5ms "beat" to live HRV/coherence) plus the historical-family
# activity/steps_inc null-instead-of-0 fix. Edge does not read the latter
# two fields, so only the RR bound is behaviour-visible here.
# Verified present: `git show <sha>:lib/src/live.dart | grep -c kMinRrMs`.
ref: 7edcb3e377329968118c62cb03a81d95e2f6db8e
openstrap_analytics:
git:
url: https://github.com/OpenStrap/analytics.git
# PR-BRANCH HEAD, not main — OpenStrap/analytics#32 (fix/issue-170-...)
# is open, not yet merged. Repin to the merge commit on main once it
# lands (same pattern v49 used briefly for protocol/analytics PR heads).
# autoDetectWorkouts now bypasses the motion-confirmation gate on a
# genuine HR-onset (fast rise vs. immediately-preceding baseline),
# fixing low-limb-swing cardio (cycling/rowing) going undetected while
# still rejecting slow-drifting elevations (fever/heat/anxiety) that
# have no discernible onset.
# Verified present at THIS sha: `git show <sha>:lib/src/onehz/workout/auto_detect.dart | grep onsetRiseBpm`.
# Moved to the branch's new head (cbbe06a) after CodeRabbit caught a real
# off-by-one in the onset window on analytics#32 (earlyMean was 181s vs
# preMean's 180s) — fixed there, not worth a separate edge changelog line.
ref: cbbe06addec1cb78b4ea2c75f64e8a281ac09294
# analytics main @ #34 merge. Two hops in one: #32 (the HR-onset bypass
# for low-limb-swing cardio) had already merged and this pin was still
# sitting on its PR-branch head, and #34 lands the sleep-stager rewrite.
#
# #34 replaces the deep/REM boolean conjunctions with weighted robust-z
# scores. Measured against 99 PSG-labelled wrist nights (DREAMT), the old
# rules scored kappa 0.036 — deep PPV 5.7% against a 4.5% base rate, REM
# 12.1% against 14.0%, i.e. at or below chance — because the deep rule
# AND-ed one good axis, one null axis (rmssd, d -0.13) and one INVERTED
# axis (mean HR, d +0.31), so they could only co-fire by luck. That is
# what produced 30-second deep specks the 3-min bout rule then deleted.
# Now kappa 0.128 (0.132 held out), deep 53.0/12.9 sens/PPV, REM
# 52.6/20.7. Cutoffs are calibrated on OUR captures, not DREAMT — the
# DREAMT-optimal values under-called REM badly on real WHOOP data.
# Verified present: `git show <sha>:lib/src/onehz/sleep/cardio_stager.dart
# | grep -E 'classifyCardioEpochs|_remScoreCut = 0.5'`.
ref: f0d115308aa5e9e3c82ee113c3d52e59756121d4

# BLE — flutter_blue_plus is the maintained cross-platform GATT client.
flutter_blue_plus: ^1.36.8
Expand Down
Loading