Skip to content

Oura: log WHY a UTC anchor was rejected — iOS + Android (#91)#123

Merged
ryanbr merged 1 commit into
mainfrom
oura-anchor-reject-logging-91
Jul 9, 2026
Merged

Oura: log WHY a UTC anchor was rejected — iOS + Android (#91)#123
ryanbr merged 1 commit into
mainfrom
oura-anchor-reject-logging-91

Conversation

@ryanbr

@ryanbr ryanbr commented Jul 9, 2026

Copy link
Copy Markdown
Owner

Cross-platform diagnostic observability for #91 (Oura anchor never lands → history samples stay unanchored → no sleep/daily data). Reimplements the intent of #96 correctly, and supersedes it.

Approach

Each driver exposes a pure, read-only isPlausibleAnchorEpoch(epoch) — the same 2020–2035 window the .timeSync/.rtcBeacon ingest already gates on. OuraLiveSource, on receiving a 0x42/0x85 event, uses it to log the precise rejection:

  • 0x42 time-sync with an implausible epoch → log the offending epoch value.
  • 0x85 RTC beacon with an implausible epoch → log it. A beacon merely ignored because a primary anchor already exists is normal and deliberately not logged (no noise).

It also fixes a latent bug: the "UTC time anchor acquired" line fired on the first time-sync unconditionally — even when that sync was rejected as implausible. It now announces "acquired" only when the sync actually anchored.

Why not #96's implementation

#96 does not compile — it logs off a d.hasAnchor property that doesn't exist anywhere in the tree (its own PR body claims to add it, but the commit doesn't). Beyond that: it added a Boolean return to setAnchorIfPlausible that's never used (dead code + unused-variable warnings), de-privatised the method for no caller, and its messages were wrong (the 0x85 "primary already set" branch can never fire via !hasAnchor; the 0x42 epoch was divided by 1000). Reading the driver's own predicate compiles, uses the real signal, and logs the right reason with the right value.

Files & verification

Drivers (OuraDriver.swift / OuraDriver.kt): the predicate. Sources (OuraLiveSource.swift / .kt): the logging. Plus a pinned-boundary unit test on both platforms (Swift + Kotlin twins).

  • Android: :app:compileFullDebugKotlin + OuraDriverTest pass locally.
  • iOS: the OuraProtocol package builds + all 33 OuraDriverTests pass on WSL (pure Swift, no SQLite wall), so the driver predicate + test are verified. The OuraLiveSource.swift log wiring is self-reviewed and rides the next iOS build (app target can't compile on WSL).

Diagnostic observability for #91 (Oura anchor never lands -> history samples stay
unanchored -> no sleep/daily). Reimplements the intent of #96 correctly.

Each driver exposes a pure, read-only isPlausibleAnchorEpoch(epoch) predicate
(the same 2020-2035 window setAnchorIfPlausible / the .timeSync/.rtcBeacon ingest
already gate on). OuraLiveSource uses it, on receiving a 0x42/0x85 event, to log
the precise rejection:
 - 0x42 time-sync with an implausible epoch -> log the offending epoch.
 - 0x85 RTC beacon with an implausible epoch -> log it. A beacon merely blocked
   because a primary anchor already exists is NORMAL and deliberately NOT logged.

Also fixes a latent bug: the "UTC time anchor acquired" line fired on the FIRST
time-sync unconditionally, even when that sync was rejected as implausible; it now
announces "acquired" only when the sync actually anchored.

Why not #96's approach: it added a Boolean return to setAnchorIfPlausible but never
used it (dead code + unused-variable warnings), de-privatised the method for no
caller, and keyed the logs off a d.hasAnchor property that DOESN'T EXIST -> it did
not compile. And its messages were wrong (0x85 'primary already set' can never fire
via !hasAnchor; the 0x42 epoch was divided by 1000). This version reads the driver's
own plausibility predicate, so it compiles, uses the real signal, and logs the right
reason with the right value.

Adds a pinned-boundary unit test on both platforms (Swift + Kotlin twins).

Verified: Android :app:compileFullDebugKotlin + OuraDriverTest pass; iOS
OuraProtocol package builds + all 33 OuraDriverTests pass (both on WSL). The
OuraLiveSource.swift log wiring rides the next iOS build (app target can't compile
on WSL).
@ryanbr ryanbr merged commit 232a63b into main Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant