Fix/oura live console trusted stream#56
Merged
ryanbr merged 2 commits intoJul 8, 2026
Merged
Conversation
The Live Body Console derives every status from activeConnection (= live.connected && live.bonded). `bonded` carries WHOOP encrypted-bond semantics and is deliberately never set by the Oura path (ryanbr#69), so a connected, authenticated, streaming ring fell through every WHOOP branch to "Radio connected, stream not yet trusted." — even while HR was live. Add a display-only `ringStreaming` predicate (live.connected && live.streamingLiveHR) and route the status layer through it: mode detail, connection pill, mode badge, mode color, and the Heart rate / Connection signal-trust tiles now read a ring stream as an active, trusted stream. activeConnection itself is untouched, so bond-only feature gates (buzz, alarm, HRV snapshot, encrypted control) still correctly key off the WHOOP bond. Wear/Worn stats stay gated on activeConnection to avoid a false "On wrist" until the ring's wear signal is confirmed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…le-trusted-stream
Author
|
I need to test it, but having issues to build, as the built application do not use the same environment as the new built 8.3.4 (for instance it is using now the Containers folder). I'll see how to redo the build in a proper way |
ryanbr
added a commit
that referenced
this pull request
Jul 8, 2026
Android: recognize the Oura ring's live stream as trusted in the Live console (#56 parity)
tanarchytan
pushed a commit
to tanarchytan/noop
that referenced
this pull request
Jul 8, 2026
… console (ryanbr#56 parity) iOS PR ryanbr#56 makes the Live view treat an actively-streaming non-WHOOP source (the Oura ring) as a trusted stream instead of "connecting / not yet trusted". Android had the identical WHOOP-only status logic, but couldn't be fixed the same way because LiveState.streamingLiveHR was an unfilled stub (hardcoded false) that nothing drove — the ring's HR reaches the UI via publishExternalLiveHr, which set connected=true but never streamingLiveHR. So the parity here is two parts: 1. Plumb the signal. publishExternalLiveHr (the non-WHOOP live-HR seam, invoked ONLY while WHOOP's own BLE is paused) now sets streamingLiveHR=true, and clearedBiometrics + the two remaining connected=false transitions clear it, keeping the invariant streamingLiveHR ⟹ connected. bonded stays false, so the buzz/alarm/HRV feature gates keep keying off the WHOOP bond — the ring never claims those. 2. Status copy (LiveScreen), mirroring iOS: a `ringStreaming = connected && streamingLiveHR` predicate feeds the mode badge ("STREAMING"), the pill ("Streaming", green), the mode colour (accent), the detail ("Heart rate stream is active."), and the signal-trust tiles (Heart rate "Streaming now", Connection "Streaming / Live stream, no WHOOP bond"). Every ringStreaming branch sits AFTER the WHOOP activeConnection checks, so a bonded WHOOP is unaffected. On Android the signal is driven for any external live source (ring, FTMS machine, generic HR strap) — a superset of iOS's Oura-only, and correct for all of them. Compiles (compileFullReleaseKotlin) and the BLE unit tests pass.
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.
What this PR does
The fix
In Strand/Screens/LiveView.swift I added a display-only predicate:
private var ringStreaming: Bool { live.connected && live.streamingLiveHR }
and taught the status layer to treat it as a trusted live stream, across all the places that were WHOOP-only:
Crucially, I left activeConnection itself untouched, so the actual bond-only feature gates (buzz, alarm, HRV snapshot, encrypted control) still correctly key off the
WHOOP bond — the ring shouldn't claim those.
One caveat I intentionally left alone
The Wear state / Worn stats still gate on activeConnection, so they'll read "Unknown" for the ring. I didn't route those through ringStreaming because I couldn't
confirm the Oura path drives live.worn (WRIST_ON/OFF) — showing a false "On wrist" would be worse than "Unknown". If the ring does report wear, say the word and I'll
wire those up too.
Type of change
How it was tested
Checklist
swift testinPackages/<name>)android/(./gradlew testFullDebugUnitTest)StrandDesigntokens — no hardcoded colors, fonts, or spacingdocs/CONTRIBUTING.mdStrand.xcodeproj/) or any secrets/keystoresRelated issues