Skip to content

repin analytics + protocol to main, kAlgoVersion 53 - #175

Merged
abdulsaheel merged 1 commit into
mainfrom
chore/repin-siblings
Aug 2, 2026
Merged

repin analytics + protocol to main, kAlgoVersion 53#175
abdulsaheel merged 1 commit into
mainfrom
chore/repin-siblings

Conversation

@abdulsaheel

@abdulsaheel abdulsaheel commented Aug 2, 2026

Copy link
Copy Markdown
Collaborator

User description

The sleep-stager rewrite and the protocol RR-bound fix were both merged to their mains but weren't reaching users, because edge was pinned behind. Analytics was two hops back — still sitting on analytics#32's PR-branch head even though #32 merged two days ago.

analytics  cbbe06a -> f0d1153   (main @ #34)
protocol   5bb8606 -> 7edcb3e   (main @ #21)

what this actually ships

analytics#34 — deep/REM go from boolean conjunctions to weighted robust-z scores. The old deep rule AND-ed one informative axis with one null one (rmssd, d -0.13) and one inverted one (mean HR, d +0.31 — deep sleep runs slightly faster than light on the wrist), so all three could only co-fire by luck. That's what produced 30-second deep specks the 3-min bout rule then deleted.

Against 99 PSG-labelled wrist nights:

kappa Deep sens/PPV REM sens/PPV
before 0.036 10.3 / 5.7 30.6 / 12.1
after 0.128 53.0 / 12.9 52.6 / 20.7
held out (49 subj) 0.132 56.0 / 10.9 51.9 / 21.5

Base rates are 4.5% Deep and 14% REM, so the old rules were at or below chance on both.

protocol#21 — bounds realtimeRr to the same 200-2500ms range parseRealtimeHr and parseR24 already enforce, so a misaligned 0x28 frame can't hand a 5ms "beat" to live HRV/coherence. The other half of that commit (historical-family activity/steps_inc null instead of 0) isn't read by edge.

kAlgoVersion 52 -> 53 — every day's hypnogram, stage minutes and sleep-derived scalars change, so every day re-derives.

verification

Per the v43 lesson (a changelog citing a change the pinned SHA never contained), confirmed both SHAs actually contain what this claims:

git show f0d1153:lib/src/onehz/sleep/cardio_stager.dart | grep classifyCardioEpochs
git show 7edcb3e:lib/src/live.dart | grep kMinRrMs

And reproduced CI locally rather than trusting the path overrides — moved pubspec_overrides.yaml aside, pub get, confirmed resolved-ref matches both pins, ran check_sibling_pins.sh (both agree), then analyze + full suite against the real pinned packages.

1088 tests, analyze clean. Lock diff is the four ref lines only, no path: sources.

🤖 Generated with Claude Code


PR Type

Enhancement, Bug fix


Description

  • Bump kAlgoVersion 52 → 53; all days re-derive with new sleep staging

  • Repin openstrap_analytics to f0d1153 (main @ fix(ci): release build fails on committed path dependency_overrides #34): deep/REM boolean rules replaced with weighted robust-z scores

  • Repin openstrap_protocol to 7edcb3e (main @ History View #21): realtimeRr now bounded 200–2500 ms, blocking implausible live HRV beats

  • Both SHAs verified to contain the cited changes (per v43 lesson)


Diagram Walkthrough

flowchart LR
  A["openstrap_analytics\ncbbe06a (PR-branch)"] -- "repin to main @ #34" --> B["openstrap_analytics\nf0d1153 (main)"]
  C["openstrap_protocol\n5bb8606 (pre-#21)"] -- "repin to main @ #21" --> D["openstrap_protocol\n7edcb3e (main)"]
  B -- "sleep-stager rewrite\nkappa 0.036 → 0.128" --> E["kAlgoVersion 53\n(full re-derive)"]
  D -- "realtimeRr 200-2500ms bound\nlive HRV fix" --> E
Loading

File Walkthrough

Relevant files
Enhancement
derivation_engine.dart
Bump kAlgoVersion to 53 with sleep-stager changelog           

lib/compute/derivation_engine.dart

  • Bumps kAlgoVersion from 52 to 53
  • Adds detailed changelog comment explaining the sleep-stager rewrite
    (weighted robust-z replacing boolean conjunctions) and the protocol
    realtimeRr bound fix
  • Documents PSG-labelled benchmark results (kappa 0.036 → 0.128)
    justifying the full re-derive
+16/-1   
Dependencies
pubspec.yaml
Repin both sibling packages to current main SHAs                 

pubspec.yaml

+25/-18 

The sleep-stager rewrite (analytics#34) and the protocol RR-bound fix
(protocol#21) were both on their respective mains but not reaching users,
because edge was still pinned behind. Analytics was two hops back — sitting on
analytics#32's PR-BRANCH head even though #32 merged two days ago.

analytics cbbe06a -> f0d1153 (main @ #34)
protocol  5bb8606 -> 7edcb3e (main @ #21)

analytics#34 replaces the deep/REM boolean conjunctions with weighted robust-z
scores. The old deep rule AND-ed one informative axis with one null one (rmssd,
d -0.13) and one INVERTED one (mean HR, d +0.31 — deep sleep runs slightly
FASTER than light on the wrist), so all three only co-fired by luck. That's what
produced 30-second deep specks the 3-min bout rule then deleted. Against 99
PSG-labelled wrist nights: kappa 0.036 -> 0.128 (0.132 held out), deep
10.3/5.7 -> 53.0/12.9 sens/PPV, REM 30.6/12.1 -> 52.6/20.7.

protocol#21 bounds realtimeRr to the same 200-2500ms range parseRealtimeHr and
parseR24 already use, so a misaligned 0x28 frame can't hand a 5ms "beat" to live
HRV. The other half of that commit (historical-family activity/steps_inc null
instead of 0) isn't read by edge.

kAlgoVersion 52 -> 53: every day's hypnogram, stage minutes and sleep-derived
scalars change, so every day re-derives.

Verified both SHAs actually contain what this claims, per the v43 lesson:
  git show f0d1153:lib/src/onehz/sleep/cardio_stager.dart | grep classifyCardioEpochs
  git show 7edcb3e:lib/src/live.dart | grep kMinRrMs

Reproduced CI locally rather than trusting the path overrides: moved
pubspec_overrides.yaml aside, pub get, confirmed lock resolved-ref matches both
pins, ran check_sibling_pins.sh (both agree), then analyze + full suite against
the REAL pinned packages. 1088 tests, analyze clean. Lock diff is the four ref
lines only — no path: sources.
@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 29ee23fa-abd8-4426-b38f-37e6fea8f3fc

📥 Commits

Reviewing files that changed from the base of the PR and between 5a788da and 4c69f0d.

⛔ Files ignored due to path filters (1)
  • pubspec.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • lib/compute/derivation_engine.dart
  • pubspec.yaml

📝 Walkthrough

Walkthrough

The PR repins openstrap_protocol and openstrap_analytics to revisions with updated processing behavior. It increases kAlgoVersion from 52 to 53 so stored days are re-derived.

Changes

Analytics and protocol updates

Layer / File(s) Summary
Dependency revision pins
pubspec.yaml
The protocol dependency now includes realtime-RR bounds and historical activity/steps null handling. The analytics dependency now includes HR-onset cardio detection and weighted robust-z sleep staging.
Derivation algorithm version
lib/compute/derivation_engine.dart
The changelog records the processing changes. kAlgoVersion increases from 52 to 53 and triggers re-derivation of stored days.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested labels: Review effort 3/5

Suggested reviewers: localhoop, dannymcc

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the dependency repins and the kAlgoVersion 53 increment, which are the main changes in the pull request.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Lock file mismatch

Per AGENTS.md §4.9, pubspec.lock currently records source: path for both siblings and provides no pin guarantee — pubspec.yaml is the source of truth. The diff updates the ref: SHAs in pubspec.yaml but there is no corresponding pubspec.lock update in the PR. If the lock file still resolves the old path-source entries, flutter pub get in CI or on a fresh checkout will not actually pull the new commits, meaning the kAlgoVersion 53 bump ships without the analytics#34 stager rewrite it documents. This is the exact failure mode described in §4.9 (v43 changelog described a fix its pin never contained).

    ref: 7edcb3e377329968118c62cb03a81d95e2f6db8e
openstrap_analytics:
  git:
    url: https://github.com/OpenStrap/analytics.git
    # 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
Missing protocol ref for old pin

The old protocol block had a ref: line (5bb8606...) that is removed in the diff, but the new block adds a new ref: (7edcb3e...) only after the analytics block. Visually the new protocol ref: appears inside the analytics stanza in the diff. While this may be a diff-presentation artifact, if the YAML indentation is wrong and the ref: ends up under openstrap_analytics instead of openstrap_protocol, the protocol package will resolve without a pinned SHA — violating the "full commit SHAs, never branch refs" invariant (§3.6) and potentially riding whatever HEAD resolves to.

ref: 7edcb3e377329968118c62cb03a81d95e2f6db8e

@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
General
Record analytics SHA in version changelog

The changelog comment says "repin analytics to main @ #34" but the pubspec.yaml pin
for openstrap_analytics is f0d115308aa5e9e3c82ee113c3d52e59756121d4. Per invariant
§3.5, a bump citing a sibling change must be backed by the pin — the SHA in
pubspec.yaml must actually contain the cited change. The verification command in
pubspec.yaml checks for classifyCardioEpochs|_remScoreCut = 0.5 in
cardio_stager.dart, but the changelog here does not record that SHA, making it
impossible to audit whether the pin and the changelog describe the same commit. Add
the analytics SHA directly to the changelog line (e.g. analytics main @ f0d1153 #34)
so the invariant is auditable without cross-referencing the pubspec.

lib/compute/derivation_engine.dart [379-394]

-// v53: repin analytics to main @ #34 — the sleep-stager decision layer is
+// v53: repin analytics to main @ f0d115308aa5e9e3c82ee113c3d52e59756121d4 (#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).
+// Repin also moves analytics off the PR-branch head (cbbe06a) to the merge
+// commit on main — same content, now a stable ref.
 const int kAlgoVersion = 53;
Suggestion importance[1-10]: 2

__

Why: This is a stylistic/documentation suggestion about adding a SHA to a comment for auditability. While cross-referencing is a valid concern, the pubspec.yaml already contains the SHA and verification command, making the changelog comment sufficiently traceable. The improvement is marginal and the suggestion adds a long SHA to a comment line that would exceed typical line length conventions.

Low

@abdulsaheel
abdulsaheel merged commit 399e10a into main Aug 2, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant