Skip to content

Gate gen5 GET_DATA_RANGE decode on outer command status - #1

Merged
matsvarn merged 1 commit into
mainfrom
fix/gen5-data-range-status-gate
Sep 25, 2026
Merged

matsvarn merged 1 commit into
mainfrom
fix/gen5-data-range-status-gate

Conversation

@matsvarn

Copy link
Copy Markdown
Owner

Why

A failed Gen5 GET_DATA_RANGE reply can keep a plausible body from an earlier successful read, including revision byte 1. The current decoder checks only the revision byte. It therefore reports stale range_oldest/range_newest, trim_ts/current_read_ts, and pages_behind (including raw_old_page/read_page) as current values.

The app's single GET_DATA_RANGE consumer (ble_engine.dart) does not check the outer status before it adopts these fields as the backlog target and writes the band_backlog ledger row. A stale read cursor makes the band's drain position look stalled or rewound. That would corrupt the cursor-movement evidence the interrupted-sync trial relies on.

Change

  • This ports the behavior of OpenStrap/protocol 11919c3 (gate get_data_range on outer cmd status OpenStrap/protocol#55) to the fork's decoder, which carries the read-cursor fields from 0df79ff.
  • On Gen5, both decode blocks now require outer status 1. Together they cover every field this opcode emits.
  • Gen4 stays ungated because its status-byte semantics are unconfirmed. This matches the existing GET_CLOCK policy.
  • The gate has the same shape as upstream's, to keep a later upstream sync conflict-free.

Verification

Check Result
New Gen5 status 0/2/3 test on the original decoder (0df79ff) Failed as expected: status=0 key=range_oldest was emitted
Same test with this change Passes. No range, backlog, or cursor key is emitted
Gen5 status 1 All fields are emitted with their expected values, including the cursor fields
Gen4 status 0/1/2/3 Unchanged. All fields are emitted
dart analyze --fatal-infos (Dart 3.11.4) No issues
dart test (full suite) 616 passed, 4 skipped (the skipped tests need an external capture)
dart format --set-exit-if-changed Flags 39 files. main at 0df79ff flags the same 39, and nothing flagged is on a line this PR adds

No hardware verification yet. The synthetic replies cover the decoder only. The physical interrupted-sync trial runs after the app pins this commit.

Other upstream-only fixes reviewed (not included)

I checked these against the commands the current app sends. The app frames every Gen5 command through buildCommand(..., session.band), and none of them is needed for the capture path:

A failed gen5 reply can keep a plausible body from an earlier successful
read, including revision byte 1. The decoder trusted that body and
emitted range_oldest/range_newest, trim_ts/current_read_ts and
pages_behind (with raw_old_page/read_page) as current values. A stale
read cursor makes the band's drain position look stalled or rewound in
the band_backlog ledger.

Port the behaviour of OpenStrap/protocol 11919c3 (OpenStrap#55) to the fork's
decoder, covering the read-cursor fields this fork adds. Gen4 stays
ungated because its status byte semantics are unconfirmed, matching the
existing GET_CLOCK policy.
@matsvarn

Copy link
Copy Markdown
Owner Author

Hosted CI on the exact head 4bab607: https://github.com/matsvarn/openband5-protocol/actions/runs/36137606205 passed on Dart 3.5.0 and stable. It was run via workflow_dispatch because the fork recorded no push or pull_request runs; see the note in the handoff.

@matsvarn

Copy link
Copy Markdown
Owner Author

Independent review (Grok 4.7, high reasoning): CLEAN, no findings. It reproduced the base failure (status=0 key=range_oldest) on 0df79ff and confirmed the focused tests pass on 4bab607. It also confirmed profile.isGen5 covers every Gen5-family profile, including MG/Maverick/Puffin, and that the follow-up list is accurate.

@matsvarn
matsvarn marked this pull request as ready for review September 25, 2026 13:10
@matsvarn
matsvarn merged commit 2c1bf3c into main Sep 25, 2026
2 checks passed
matsvarn added a commit to matsvarn/openband5-app that referenced this pull request Sep 25, 2026
Repin openstrap_protocol to 2c1bf3c5 (matsvarn/openband5-protocol#1
merge). Gen5 GET_DATA_RANGE now decodes only on outer status 1, so a
failed reply's stale body can no longer reach band_backlog as a current
range or read cursor during an interrupted sync. Gen4 is unchanged.

No kAlgoVersion bump: the only protocol lib/ change is that
command-reply gate. No record decode or metric input moves.
kProtocolPin, pubspec.yaml and pubspec.lock agree.
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