8000 fix(cbio): give the harness a scan pass that bounds and closes itself by shroominic · Pull Request #205 · shroominic/OpenGlucose · GitHub
[go: up one dir, main page]

Skip to content

fix(cbio): give the harness a scan pass that bounds and closes itself - #205

Closed
shroominic wants to merge 1 commit into
fix/cbio-gs1-harness-lifecyclefrom
fix/cbio-gs1-harness-discovery
Closed

shroominic wants to merge 1 commit into
fix/cbio-gs1-harness-lifecyclefrom
fix/cbio-gs1-harness-discovery

Conversation

@shroominic
Copy link
Copy Markdown
Owner

Closes #201. Base: #204.

The authenticated harness acquired its target with a single filtered scan, and it trusted two signals it does not own: it awaited startScan(...) before arming any bound, and it subscribed to scanResults after the radio was already running. When flutter_blue_plus leaves startScan pending, the acquisition loop never advances and the run reaches neither a target nor its aborted_no_target verdict — the unbounded wait behind the two runs in #199 that burned the full 8-minute test timeout with no artifact.

The app driver and app transport already solve both halves of this on the same phone:

  • packages/cgm_cbio/lib/src/cbio_driver.dart runs a filtered pass and then one unfiltered retry, because this sensor's advertisement does not always carry the service UUID in the field Android filters on. A foreign advertiser is still never surfaced: every result must classify as an FF30 candidate. gs1-session-20260918T051210-...json records the filtered-only failure (aborted_no_target after 90 s).
  • packages/cgm_ble_flutter/lib/src/flutter_blue_plus_transport.dart subscribes to onScanResults before starting, arms its own deadline, and closes the caller's stream before plugin cleanup that can block.

The harness now uses that shape. A pass subscribes before starting the radio, owns a hard deadline, ends on either the plugin's stopped signal or that deadline, stops the scanner on the way out without waiting on a plugin future whose radio already stopped, and records a scan_failed reason when start fails. An empty filtered pass is followed by one unfiltered pass, and the run reports CBIO-A scan-source=filtered|unfiltered so the next reviewer can see which path found the sensor.

No assertion is relaxed, and no part of the safety envelope changes: the allowed-write set, the closed error taxonomy, and every CbioSessionEvidence invariant are untouched.

Device evidence with #202 and #204 in place:

evidence/gs1-session-20260918T055737-cbio_glucose_authenticated_test.json
CBIO-A scan-source=filtered
outcome=completed gattReleased=true notifications=126 glucose 1848, raw 1504 errors=none

The authenticated harness scanned only with an FF30 service filter and trusted
two signals it does not own: it awaited `startScan` before arming any bound, and
it subscribed to `scanResults` after the radio was already running. When the
plugin left `startScan` pending, the acquisition loop never advanced, and the
run burned the full 8-minute test timeout without reaching a verdict.

The app driver does not do either of those. Its filtered pass is followed by one
unfiltered retry, because this sensor's advertisement does not always carry the
service UUID in the field Android filters on, and a foreign advertiser is still
never surfaced: every result has to classify as an FF30 candidate first.

The harness now uses that proven shape. A pass subscribes to `onScanResults`
before starting the radio, owns a hard deadline, ends on either the plugin's
stopped signal or that deadline, and stops the scanner on the way out without
waiting on a plugin future that a stopped radio no longer needs. An empty
filtered pass is followed by one unfiltered pass, and the run now reports which
pass found the target.

Refs #201
@shroominic
Copy link
Copy Markdown
Owner Author

Re-ran the device session from the branch tip (5e85268) so the artifact carries a committed revision rather than -dirty. Nothing in this PR changed after the first run; this is the artifact to cite.

evidence/gs1-session-20260918T060240-cbio_glucose_authenticated_test.json
harnessRevision=5e85268
outcome=completed  targetAcquired=true  gattReleased=true
notifications=126
writes=authentication 1, clock_set 1, glucose_read 1, raw_history_read 1
records: glucose 1782 (1..1782), raw 1520 (1..1520)
errors={}  unitStatus=unverified

INDEX.md records it alongside the three failing artifacts. Run command: make cbio-gs1-evidence DEVICE_ID=<serial> with the three stacked PRs applied; CBIO-A scan-source=filtered found the sensor on the first pass.

One observation handed to the decode lane as #207: every raw glucose field in the 08 and 0A frames reads 0 while the same records carry plausible temperatures, so this artifact proves a completed session, not a usable glucose value.

@shroominic
Copy link
Copy Markdown
Owner Author

Not absorbed by the GS1 consolidation (#209, feature/cbio-gs1). Left open on purpose: the self-owned bounded scan pass (unfiltered fallback plus its own deadline) is not in the consolidated harness. Owner: device-evidence harness lane.

@shroominic
Copy link
Copy Markdown
Owner Author

Carried into #209 (head be9b47a) as 4254acf — the same change, applied to the consolidated branch (conflict resolved as a union with this line's fail-closed vendor-material gate and its G1 comparison work).

The bounded _scanPass owns its whole lifecycle: results are subscribed before the radio starts, the pass ends on the plugin's own stop signal or its own deadline, and a canonicalised FF30 match keeps a foreign advertiser from being surfaced as a sensor — including in the unfiltered fallback pass.

Closing as carried. Carrying PR: #209.

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

0