You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix(cbio): judge the live surface by receipt time, not a sensor clock - #175
buildLiveActivityPayload asked only the first question. For cbio that answer is
permanently null, so isStale was permanently true — and the raw/provisional
branch above it hard-coded isStale: true as well, so every cbio surface took a
constant path regardless of link health.
RED
cd openhealth && flutter test test/cbio_live_freshness_test.dart
On 17db5b4 (the base this branch forks):
exit 1
Expected: false
Actual: <true>
a batch accepted 30 s ago is a fresh surface
test/cbio_live_freshness_test.dart 60:5
00:00 +3 -1: Some tests failed.
A batch ingested 30 s ago and a session that ingested nothing were
indistinguishable.
GREEN
Same command on this branch:
exit 0
00:00 +17: All tests passed!
The fix
liveSurfaceFreshnessAt({snapshot, reading, now}) and liveSurfaceIsStale(...)
in session_presentation.dart become the single place that answers "how old is
this surface". A timestamped driver is still judged by its reading time; cbio
is judged by historySync.lastSyncAt. No recordedAt is fabricated, and the
receipt time is clamped so a future value cannot read as fresh.
live_activity_payload.dart uses that clock for both the provisional branch
and the reading branch, replacing isStale: true and the inline 10-minute
comparison. The window is unchanged at 10 minutes, now liveSurfaceStaleAfter.
recordedAtIso8601 is untouched: it still carries only a sensor timestamp, so
cbio still publishes null there. Receipt freshness never crosses the platform
boundary as a sensor time.
Tests added
cbio freshness is the receipt clock, not a missing sensor clock — 30 s and
9 min are fresh, 25 min is stale.
a cbio session that never ingested anything is stale.
receipt freshness never becomes a published sensor timestamp — the flag can
flip while recordedAtIso8601, lastReadingText and valueText stay redacted.
a timestamped driver still judges freshness from its own reading — a stale lastSyncAt does not override a fresh sensor reading for another driver.
Verification
cd openhealth && flutter test — exit 0, +484: All tests passed!
flutter test test/cbio_live_freshness_test.dart test/live_activity_payload_test.dart — exit 0, +17
flutter analyze — No issues found!
dart format --output=none --set-exit-if-changed lib/src/session_presentation.dart lib/src/live_activity_payload.dart test/cbio_live_freshness_test.dart — clean
Scope note
No lock-screen behaviour changes here. cbio still does not publish to the Live
Activity: shouldPublishLiveActivity rejects a raw or provisional reading, and
every cbio reading is both. This lane closes the latent staleness contract so
that whichever lane makes cbio publishable does not inherit a flag that is always true. shouldPublishLiveActivity is deliberately not touched.
Fixture values are synthetic (AA:BB:CC:DD:EE:FF, CGMTEST-style records); no
credential material and no real device address appear in this change.
Rebase reminder (comment only, no edits to this branch).
The lane head is now 05785b0 (#192 merged). This PR is still based on 17db5b4; the merge-base is fine, but expect a conflict in packages/cgm_cbio/lib/src/cbio_glucose_session.dart around credential resolution. Resolve it by keeping the injected path:
the session resolves CbioCredentials once per session into _resolved, before the transport is touched, and every mask/unmask/builder call receives _streamKey/the material explicitly;
CbioCompiledAuthMaterialProvider and the compiled constants are gone; a build without material fails closed with cbio.auth.material;
the lane also reads _clockReferenceEpochSeconds (set in _writeClock) when it derives the record-index anchor, so keep that field and the _historyReadingsFor(anchor) / metadata spread when you resolve.
Rebase onto feature/cbio-gs1-app-live before review so CI runs against the lane head.
Rebased onto the lane tip 9de5544 (05785b0 + #193 + #197) and force-pushed; the PR is one commit again, now fe7cc0c.
One amendment, because the lane moved under this PR: #197 gives a GS1 record a real timestamp whenever the session holds a clock anchor, so CgmReading.recordedAt is no longer "null by design" for this driver. liveSurfaceFreshnessAt now judges an anchored record by that time and only falls back to the receipt time (historySync.lastSyncAt) for a record the anchor does not cover. The receipt time is still staleness-only and is never published as a sensor time; the doc comment says so.
Verification on the rebased head: openhealth flutter test 492 passed, flutter analyze clean, dart format clean on both touched files.
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
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.
Closes #174.
The defect
Timestamps locate two different things in this codebase, and they were being
collapsed into one:
CgmReading.recordedAtCgmHistorySyncState.lastSyncAtbuildLiveActivityPayloadasked only the first question. For cbio that answer ispermanently
null, soisStalewas permanentlytrue— and the raw/provisionalbranch above it hard-coded
isStale: trueas well, so every cbio surface took aconstant path regardless of link health.
RED
On
17db5b4(the base this branch forks):A batch ingested 30 s ago and a session that ingested nothing were
indistinguishable.
GREEN
Same command on this branch:
The fix
liveSurfaceFreshnessAt({snapshot, reading, now})andliveSurfaceIsStale(...)in
session_presentation.dartbecome the single place that answers "how old isthis surface". A timestamped driver is still judged by its reading time; cbio
is judged by
historySync.lastSyncAt. NorecordedAtis fabricated, and thereceipt time is clamped so a future value cannot read as fresh.
live_activity_payload.dartuses that clock for both the provisional branchand the reading branch, replacing
isStale: trueand the inline 10-minutecomparison. The window is unchanged at 10 minutes, now
liveSurfaceStaleAfter.recordedAtIso8601is untouched: it still carries only a sensor timestamp, socbio still publishes
nullthere. Receipt freshness never crosses the platformboundary as a sensor time.
Tests added
cbio freshness is the receipt clock, not a missing sensor clock— 30 s and9 min are fresh, 25 min is stale.
a cbio session that never ingested anything is stale.receipt freshness never becomes a published sensor timestamp— the flag canflip while
recordedAtIso8601,lastReadingTextandvalueTextstay redacted.a timestamped driver still judges freshness from its own reading— a stalelastSyncAtdoes not override a fresh sensor reading for another driver.Verification
cd openhealth && flutter test— exit 0,+484: All tests passed!flutter test test/cbio_live_freshness_test.dart test/live_activity_payload_test.dart— exit 0,+17flutter analyze—No issues found!dart format --output=none --set-exit-if-changed lib/src/session_presentation.dart lib/src/live_activity_payload.dart test/cbio_live_freshness_test.dart— cleanScope note
No lock-screen behaviour changes here. cbio still does not publish to the Live
Activity:
shouldPublishLiveActivityrejects a raw or provisional reading, andevery cbio reading is both. This lane closes the latent staleness contract so
that whichever lane makes cbio publishable does not inherit a flag that is always
true.shouldPublishLiveActivityis deliberately not touched.Fixture values are synthetic (
AA:BB:CC:DD:EE:FF,CGMTEST-style records); nocredential material and no real device address appear in this change.