labrador: WHOOP MG identity, R17 parser, R16 recognition - #54
Conversation
Reviewer's GuideIntroduces a standalone WHOOP MG Labrador parsing surface: revision-17 live filtered-ECG decoding, revision-16 historical raw-record recognition with lossless preservation, Maverick HELLO identification, and gen5 historical-command framing, with extensive bounds, CRC, reassembly, and wire-conformance tests. Sequence diagram for Labrador frame validation and parsingsequenceDiagram
participant FrameReassembler
participant Frame
participant LabradorR17
participant LabradorR16Raw
FrameReassembler->>Frame: reassemble bytes
Frame->>Frame: decodable
alt revision 17 live or allowed stored packet
Frame->>LabradorR17: tryParseFrame(f, allowStored)
LabradorR17->>LabradorR17: parse(inner, allowStored)
LabradorR17-->>Frame: decoded samples and metadata
else revision 16 historical packet
Frame->>LabradorR16Raw: tryParseFrame(f)
LabradorR16Raw->>LabradorR16Raw: tryParse(inner)
LabradorR16Raw-->>Frame: common header and exact inner bytes
end
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Warning Review limit reachedNext included review available in 46 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (2)
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (9)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthroughThe PR adds public WHOOP MG Labrador R17 and R16 wire-format parsers, supports gen5 historical-abort framing, adds MAVERICK detection, and expands command, parser, and frame-reassembly tests. ChangesLabrador protocol support
Priority: ⬇️ Low — Defer the WHOOP MG Labrador parsing support because it is a parsing-only protocol expansion with lifecycle, policy, and storage explicitly out of scope. Estimated code review effort: 4 (Complex) | ~45 minutes Merge Risk: ⚪ Minimal · up to The new Labrador parsing and Gen5 command support are covered by validation and protocol-conformance tests, with no actionable merge risk identified. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Gen5HelloInfo.isMaverick: revision-1 HELLO with optical discriminator in [0,38) — the official 5.458.0 MAVERICK interval (physical MG reports 0; the ordinary WHOOP 5.0 reports 82 and stays GOOSE). Never read through a non-rev-1 layout; UUID/name/command acceptance are not MG evidence. LabradorR17: the live (type 43) filtered-ECG record, source-proven field map at inner[3..25] plus signed i16 LE samples from 26. Bounds: fixed fields present, count <= 100, 26+2*count bytes available, no fixed total length; aligned tail bytes kept unnamed. Samples stay input-referred integer microvolts — no rescale, no wrist sign flip, no lead claim. Stored type-47 R17 only on explicit opt-in (the official foreground flow never enables it). Standalone rather than a Gen5HistoricalRecord: live frames never reach that type-47 dispatch, and its inner[2] flags/ppg-rate meaning does not apply. LabradorR16Raw: recognises historical type-47 revision-16 raw ECG and keeps the exact inner bytes with the common sequence/strap-time header only — the body is not source-closed. cmdAbortHistorical gains a profile parameter so a gen5 caller pads the bodyless opcode 20 through the normal framer; gen4 default is byte-identical. Tests: identity boundaries, 0/49/100 samples, count >100, count beyond bytes, every fixed-field truncation, i16 signs, flag and unreadable bits, tail preservation, R16 recognition, 1,584-byte R16 reassembly under adversarial chunking (embedded 0xAA/fake header), and exact Labrador list bytes in doc_conformance.
5b2cd5a to
61349b4
Compare
Sourcery withdrew this approval because the latest commits introduced blocking findings.
WHOOP MG (Maverick) Labrador ECG on the wire: identity, the live R17 parser, and
recognition of the historical R16 raw record. Parsing only — no lifecycle, no
policy, no storage. The consuming feature lands separately in edge.
What this adds
Gen5HelloInfo.isMaverick(lib/src/control.dart) —helloRevision == 1 && opticalDiscriminator < 38, the official MAVERICK interval. Never read through anon-revision-1 layout. A physical MG reports 0; an ordinary WHOOP 5.0 reports 82
and stays
isWhoop5.cmdAbortHistorical(seq, {profile})(lib/src/commands.dart) — gen5 callerspad the bodyless opcode 20 through the normal framer (
[35][seq][20][00]). Thegen4 default is byte-identical to before.
lib/src/labrador.dart(new)LabradorR17— the live type-43 revision-17 packet. Type 47 is accepted onlywith
allowStored. Bounds: fixed fields through offset 25, count <= 100,26 + 2*countbytes, no fixed total length, and the tail is preservedunnamed. Samples are signed i16 LE with no rescale, no sign flip and no lead
claim;
variabilityRawis null on0xffffand carries no unit.LabradorFlags(bits 0-3) andLabradorUnreadableMask(bits 0-3 +reasons).LabradorR16Raw— the historical type-47 revision-16 record, RECOGNISED butnot decoded: only the proven common header (sequence, strap time) is read and
the exact inner bytes are retained. The body layout is not source-closed, so
no body field is invented here.
It is deliberately standalone rather than folded into the gen5 historical decoder
family: that family never sees live type-43 frames, and its
inner[2]/ppgSampleRateHzmeaning does not apply.Evidence
Field offsets, the sample scale and the 500 Hz -> 100 Hz relationship come from
the retained MG fixtures and firmware trace, not from inference.
LabradorR16Rawdecodes no body field precisely because that layout is NOT closed — a candidate
packing exists and fails validation, which is why it stays out of this parser.
Tests
labrador_r17_test,labrador_r16_test,labrador_reassembly_test(a1,584-byte framed R16 through
FrameReassemblerat 1/7/20/244/512/1583/1584/4096byte chunkings, split at the header end, inside the CRC32, and on an embedded
fake
aa 01header, followed by an R18),gen5_hello_maverick_test, and exactLabrador list bytes added to
doc_conformance_test.Verified against current
main:dart analyzeclean,dart test649 passing.Summary by Sourcery
Support WHOOP MG Labrador ECG packet recognition and parsing while keeping historical raw records lossless and gen4 command behavior compatible.
New Features:
Bug Fixes:
Enhancements:
Tests:
Summary by CodeRabbit
New Features
Bug Fixes
Tests