Repository navigation
Whoop5Config: add the 16th R22 enable flag (enable_sig12) from a real capture (#103) - #224
Merged
Merged
Conversation
… capture (ryanbr#103) The shipped enableR22Sequence carried the 15 flags transcribed from judes.club's frame-builder. A real on-strap iOS HCI capture of the official app (WHOOP 5.0, ryanbr#103) reproduced those 15 byte-for-byte in the same order and then wrote a 16th SET_FF_VALUE: `enable_sig12` = ASCII '2'. Append it so NOOP's enable sequence matches what the official app actually writes on every connect. Its effect is undocumented (like enable_sig11_during_sleep); it uses the identical SET_CONFIG encoding, so no framing change. Mirror in Whoop5Config.kt, bump both golden tests (15 → 16 flags, seqs 1…16) with a byte-level guard on the new flag, and fix the two "15 flags" references in docs/WHOOP5_DEEP_DATA.md. Verification: swift test green (253/253). Kotlin twin mirrored but not compiled (no Android SDK here). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Author
|
✅ Kotlin twin now verified (was flagged untested). Method: the app module needs the Android SDK + full Gradle dependency graph (disk-constrained here), but Result: both WHOOP5 protocol test classes green — 16 tests OK, including |
DX23876
pushed a commit
to DX23876/noop
that referenced
this pull request
Jul 22, 2026
… capture (ryanbr#103) (ryanbr#224) The shipped enableR22Sequence carried the 15 flags transcribed from judes.club's frame-builder. A real on-strap iOS HCI capture of the official app (WHOOP 5.0, ryanbr#103) reproduced those 15 byte-for-byte in the same order and then wrote a 16th SET_FF_VALUE: `enable_sig12` = ASCII '2'. Append it so NOOP's enable sequence matches what the official app actually writes on every connect. Its effect is undocumented (like enable_sig11_during_sleep); it uses the identical SET_CONFIG encoding, so no framing change. Mirror in Whoop5Config.kt, bump both golden tests (15 → 16 flags, seqs 1…16) with a byte-level guard on the new flag, and fix the two "15 flags" references in docs/WHOOP5_DEEP_DATA.md. Verification: swift test green (253/253). Kotlin twin mirrored but not compiled (no Android SDK here). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
DX23876
added a commit
to DX23876/noop
that referenced
this pull request
Aug 4, 2026
…a row A WHOOP export carries several wordings for the same habit — WHOOP re-worded its journal questions over the years and the importer keeps question_text verbatim on purpose. The question string is the key everywhere: the journal table's primary key, byBehaviour in Insights, the coach's pattern analyser. So the same habit reads as two, each with half its history and a correspondingly weak ranking. Only whitespace and casing folded before this (ryanbr#224); a re-wording did not. Merging is a reading, not an edit. JournalCatalogItem gains `aliases` — the wordings folded onto it, verbatim, decoding as empty for every catalog written before now — and Repository folds journal reads through it at the one door the journal comes in by, so Insights, the coach and the logging card cannot disagree about what counts as one behaviour. Not one row is rewritten, moved or deleted, and separating restores the split exactly. Where two folded wordings answer the same day, the winner is a real stored row, picked by a rule a person can predict: native beats imported (mergeJournal's own precedence, because a typed answer is the user's latest word), then the target's own wording, then the earlier merge. Yes/no is never OR-ed and numbers are never summed — "it said yes somewhere" would invent a day. journal has no modified-at column, so "the newest wins" is not available and is not pretended. Candidates are proposed, never applied: edit mode grows a "Possible duplicates" review listing each wording with its stored answer count (one GROUP BY, not the whole history in memory), proposing the wording with the most answers as the survivor so the smaller history is the one that moves. Similarity reuses CoachMemory.tokens — the tokeniser the coach's own duplicate check runs on, now nonisolated since it is pure — over the question minus its opener, with a blunt suffix trim so "use"/"used" meet. A declined pair is remembered. Verified: Strand (macOS) and NOOPiOS build; 1778 tests, 0 failures (+12 pinning the fold's precedence, that no day is lost, that an untouched catalog folds byte-identically to mergeJournal, and the finder's hits and misses); WhoopStore 334 green; i18n audit clean. Not verified on device, and worth knowing: the catalog (renames, groups, hidden items — and now merges) is NOT in the .noopbak whitelist, so none of it survives a backup restore today. That predates this change; flagged rather than widened here, since the whitelist is a byte-identical cross-platform contract.
simoncad7
pushed a commit
to simoncad7/noop
that referenced
this pull request
Aug 17, 2026
… capture (ryanbr#103) (ryanbr#224) The shipped enableR22Sequence carried the 15 flags transcribed from judes.club's frame-builder. A real on-strap iOS HCI capture of the official app (WHOOP 5.0, ryanbr#103) reproduced those 15 byte-for-byte in the same order and then wrote a 16th SET_FF_VALUE: `enable_sig12` = ASCII '2'. Append it so NOOP's enable sequence matches what the official app actually writes on every connect. Its effect is undocumented (like enable_sig11_during_sleep); it uses the identical SET_CONFIG encoding, so no framing change. Mirror in Whoop5Config.kt, bump both golden tests (15 → 16 flags, seqs 1…16) with a byte-level guard on the new flag, and fix the two "15 flags" references in docs/WHOOP5_DEEP_DATA.md. Verification: swift test green (253/253). Kotlin twin mirrored but not compiled (no Android SDK here). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
10 tasks done
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
What
The shipped
Whoop5Config.enableR22Sequencecarried the 15 feature flags transcribed from judes.club's frame-builder. A real on-strap iOS HCI capture of the official app (WHOOP 5.0, #103) reproduced those 15 byte-for-byte in the same order, and then wrote a 16thSET_FF_VALUE:This appends
enable_sig12(ASCII'2') so NOOP's enable sequence matches what the official app actually writes on every connect.Notes
'1'values), which is itself worth having.enable_sig12's effect is undocumented (same asenable_sig11_during_sleep). It uses the identical SET_CONFIG encoding, so there is no framing change — only one more entry in the table.Cross-platform + tests
Whoop5Config.swift+ AndroidWhoop5Config.kttwin.docs/WHOOP5_DEEP_DATA.md.Verification
cd Packages/WhoopProtocol && swift test→ 253/253 green. Kotlin twin mirrored but not compiled (no Android SDK in my environment) — please run./gradlew testFullDebugUnitTest.Refs #103.
🤖 Generated with Claude Code