WIP: preserve YCBT sleep fidelity and explore overnight fragment stitching - #54
Draft
DBozhinovski wants to merge 1 commit into
Draft
WIP: preserve YCBT sleep fidelity and explore overnight fragment stitching#54DBozhinovski wants to merge 1 commit into
DBozhinovski wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Status: WIP / request for design feedback
This is deliberately a draft PR, not a merge-ready recommendation.
The branch contains a tested implementation of one possible solution, but local hardware evidence exposed an ambiguity in what a YCBT sleep-record boundary means. Before narrowing or finalizing the code, I would like feedback on:
Problem
PulseLoop currently treats each complete YCBT sleep record as an independent sleep session. The Today tile then surfaces the longest session for the waking day.
On a real R10M FCF4 (
wearableModelID=r10m, YCBT, firmware 2.32) connected to a Pixel 7, one complete CRC-accepted 1,640-byte sleep-history block contained three records for the same apparent overnight period:Each record had valid header bounds and contiguous timestamped deep/light/REM segments. There were no explicit awake segments covering the gaps.
Observed downstream behavior:
This suggests the ring may be emitting fragments of one overnight session, but the wire data does not prove whether the two gaps mean:
Additional correctness findings
The investigation also exposed less ambiguous pipeline problems:
first timestamp + summed stage minutes.Experimental implementation in this branch
The branch currently:
UNKNOWN;The stitched gaps are represented as
UNKNOWN, while explicitAWAKEremains awake. Daytime naps, different waking days, >3-hour gaps, partial records, and overlapping/duplicate records stay separate.The generic 60-minute nap/session segmentation behavior for other ring families is unchanged.
Tradeoffs
Stitch as one session with
UNKNOWNgapsPros
Cons
UNKNOWNas sleep, so this can turn missing/off-finger/awake time into reported sleep duration.Keep records separate
Pros
Cons
Device-specific versus YCBT-wide behavior
The safe parser/persistence/identity fixes are general. The stitching behavior is proven only on one R10M firmware. Applying it to every YCBT profile may be too broad; gating it behind a model/profile quirk is safer, but requires deciding which devices share this wire semantic.
Health Connect migration
The proposed v2 identity migration deletes only PulseLoop-owned
SleepSessionRecords and rebuilds them from Room. Room and other apps' records are not touched. However, deletion and reinsertion are not atomic, and migration ordering matters: it should not export old fragmented Room rows under new IDs immediately before a corrected sync collapses them.Questions for maintainers / device owners
UNKNOWNcontribute to the exported sleep session, or should unclassified gaps be omitted while retaining broader Room/time-in-bed bounds?Possible directions
My current preference is C + D: keep the general correctness fixes, gate overnight stitching behind an explicit R10M/profile quirk, and distinguish classified sleep from inferred/unknown time rather than silently presenting the entire span as measured sleep.
Verification
:app:assembleDebug: passed.git diff --check: clean.Scope / non-goals