Skip to content

fix: explain unavailable WHOOP 5 recovery history - #2055

Closed
Trillient wants to merge 1 commit into
ryanbr:mainfrom
Trillient:fix/whoop5-rr-gap-notice
Closed

Trillient wants to merge 1 commit into
ryanbr:mainfrom
Trillient:fix/whoop5-rr-gap-notice

Conversation

@Trillient

@Trillient Trillient commented Sep 10, 2026 •

Copy link
Copy Markdown

Superseded by #2056, which adds the requested regression tests on top of the explanation now in main.

What this PR does

WHOOP 5 legacy R-R rows are excluded after #2046 because their units are unknown. When that leaves a scored night without HRV or Charge, both Apple Today layouts and Android now explain the gap: “Earlier WHOOP 5 beats cannot be scored for HRV or Charge. Re-sync your strap to recover available history.”

Persist the reason with the computed night, carry it through cached scoring, and clear it when labelled history restores valid input or the day is removed from a nonempty scoring pass. The notice follows the selected day and stays hidden for WHOOP 4, ordinary calibration, and displayed imported values. Copy is included in the existing Apple and Android locales.

Android keeps the existing 55,700-byte JaCoCo limit by grouping nightly auxiliary reads and metric writes. The sleep fallback and score formulas are unchanged.

Type of change

  • Bug fix
  • New feature
  • Refactor / cleanup
  • Documentation
  • CI / tooling

How it was tested

IntelligenceRRSourceTests (Swift) and Whoop5RRSqliteTest (Kotlin) exercise the actual nightly scoring and persisted notice through three cases:

  1. Legacy WHOOP 5 history produces no HRV/Charge and a visible explanation, even with a seeded baseline.
  2. Zero-insert source promotion restores valid HRV/Charge, clears the explanation, and remains clear on a cache hit.
  3. WHOOP 4 and ordinary calibration gaps do not acquire the warning.

Additional checks cover sleep boundaries, suspect timestamps, cold repository reload, flag-only refresh, skipped-day cleanup, and isolation between computed sources. Temporarily forcing the persisted flag to always zero or always one made the relevant new tests fail on both platforms; the final implementation was restored before validation.

  • macOS app build and 65 targeted app tests passed, including the nightly pipeline, paired R-R captures, Liquid Charge carry, and Today explainability.
  • iOS simulator build passed for both architectures.
  • All 541 WhoopStore tests passed.
  • Android: all 27 R-R/store/budget tests passed. Full local suite: 5,847 tests, 6 skipped; the only failures were the two previously reproduced RecoveryDriversTest exact half-tie assertions on JetBrains JDK 21.0.8 (-0.5 versus -0.4999999999999929).
  • Translation audit, source-comment lint, and whitespace checks passed.

Checklist

  • Swift package tests pass for the package touched
  • Android full unit suite passes locally — JVM-specific rounding assertions described above
  • UI changes use design tokens for colors, fonts, and spacing
  • No hardcoded hex frame bytes; protocol decoders are unchanged
  • Follows docs/CONTRIBUTING.md
  • No generated Xcode project, credentials, or private captures committed

Related issues

Follow-up to #2046 and its review. Related to #1505.

@Trillient Trillient closed this Sep 10, 2026
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