Repository navigation
Description
Summary
The decompiled WHOOP Android app models more BLE service families than NOOP currently scans/connects to. NOOP currently supports WHOOP 4 (61080001-...) and the Maverick/Goose WHOOP 5/MG family (fd4b0001-...). The official app also defines separate PUFFIN, MONUMENT, and SYMPHONY UUID families.
This should start as detection/diagnostic support, not full functional support, because the decompile suggests different connection/framing paths for at least some variants.
Evidence from decompiled app
op0.o defines six strap generations:
GEN_4MAVERICKPUFFINGOOSEMONUMENTSYMPHONY
Relevant decompiled references:
/whoop-decompiled/sources/op0/o.javaCompanion.a()returnsGEN_4, MAVERICK, GOOSE, MONUMENT, SYMPHONYCompanion.c()returns onlyPUFFIN, suggesting a separate Puffin connection pathGOOSEreuses theMAVERICKUUIDs
/whoop-decompiled/sources/op0/p.javaPUFFIN:11500001-6215-11ee-8c99-0242ac120002MONUMENT:8a580001-2fe8-4796-9267-b87a2b0c8234SYMPHONY:59830001-5955-419b-bb8d-c8262926af23
The same 0001/0002/0003/0004/0005/0007 pattern exists for each family:
- service
- command write
- command notify
- events notify
- data notify
- memfault notify
Current NOOP state
NOOP currently has only two primary families wired:
- WHOOP 4:
61080001-8d6d-82b8-614a-1c8cb0f8dcc6 - WHOOP 5/MG:
fd4b0001-cce1-4033-93ce-002d5875f58a
Examples:
Packages/WhoopProtocol/Sources/WhoopProtocol/DeviceFamily.swiftStrand/BLE/WhoopModel.swiftandroid/app/src/main/java/com/noop/ble/WhoopBleClient.kt
Important caveat
Do not implement this as a blind UUID swap.
The decompiled yh0.a path throws for Castle generations (MONUMENT, SYMPHONY) with the message that Rev1 command packets are not supported and Rev2CommandPacket should be used. That means Monument/Symphony likely need separate framing/packet handling, not just the existing fd4b logic under different UUIDs.
PUFFIN also appears to have a distinct connection path in jw1/*.
Proposed scope
- Add explicit protocol metadata for the extra service families.
- Add scan/diagnostic logging that can identify these services when present.
- Do not advertise full support until connection/framing is verified on hardware.
- For Puffin, investigate whether the existing WHOOP 5 frame path can be reused after UUID substitution.
- For Monument/Symphony, treat as unsupported-detected until Rev2 framing is mapped.
Acceptance criteria
- NOOP docs/protocol metadata list
PUFFIN,MONUMENT, andSYMPHONYUUID families. - If a device advertises one of these services, the strap log records a clear detected-but-unsupported message rather than silently missing it.
- Existing WHOOP 4 and
fd4bWHOOP 5/MG scan/connect behavior is unchanged. - No Castle/Rev2 commands are sent unless the correct framing is implemented and tested.
Activity
Instrument the WHOOP 4.0 sleep-onset decision (ryanbr#271) (ryanbr#337)
ryanbr commentedon Jul 21, 2026
Good direction, and the caveat is spot-on — detection-only (log "detected-but-unsupported"), no blind UUID swap, and Monument/Symphony (Castle) genuinely need Rev2 framing, not the fd4b path under new UUIDs. Scoping to metadata + scan-detection with no Castle/Rev2 commands and unchanged 4.0/fd4b behaviour is the right call. The UUIDs are protocol facts, fine to reimplement + attribute like the other RE work.
One thing to resolve before implementing — a naming collision. NOOP already uses "puffin" throughout as its codename for the fd4b / WHOOP 5.0/MG framing:
PuffinPacketType,puffinCommandFrame/Framing,PuffinExperiment,PuffinFrameRecorder,DeviceFamily.swift("Whoop 5.0 / MG … 'puffin' packet types"),docs/PROTOCOL.md("WHOOP 5.0 ('puffin') protocol"). But the decompile'sop0taxonomy lists PUFFIN as a separate UUID family (11500001), distinct from MAVERICK/GOOSE — and MAVERICK/GOOSE are thefd4bUUIDs NOOP actually implements.So:
PUFFIN. What NOOP calls "puffin" is really Maverick/Goose (fd4b); the app's realPUFFIN (11500001)is a device NOOP has never handled.11500001family named "puffin," it collides badly with the existing puffin naming everywhere. The new family needs a distinct name, and the fd4b "puffin" codename should stay untouched.b-nnett/goose(its fd4b framing is Maverick/Goose in the app's own taxonomy). Worth a one-line clarification in PROTOCOL.md whichever way this lands.Implementation notes
DeviceFamily/scanServicestructure on both platforms.11500001advertisement logs the unsupported message and does not attempt a connect or send any command.Priority read: Monument/Symphony (and possibly
PUFFIN 11500001) look like future/unreleased generations the app models speculatively, so this is forward-looking groundwork rather than a fix for something users hit today — useful, but lower urgency than the reported bugs.Happy to implement the detection-only version once the naming for the new family is settled (i.e. what to call the
11500001family so it doesn't clash with the fd4b "puffin" codename).Instrument the WHOOP 4.0 sleep-onset decision (ryanbr#271) (ryanbr#337)
feat(diagnostics): attribute forced re-scores as newData yes/no (batt…
Instrument the WHOOP 4.0 sleep-onset decision (ryanbr#271) (ryanbr#337)
feat(diagnostics): attribute forced re-scores as newData yes/no (batt…