Skip to content

feat(diagnostics): attribute forced re-scores as newData yes/no (battery) - #1192

Merged
ryanbr merged 1 commit into
mainfrom
feat/rescore-attribution-logging
Aug 9, 2026
Merged

ryanbr merged 1 commit into
mainfrom
feat/rescore-attribution-logging

Conversation

@ryanbr

@ryanbr ryanbr commented Aug 9, 2026

Copy link
Copy Markdown
Owner

Why

A testing-build capture (WHOOP 4.0, flapping link) showed ~186 full 18-day analyzeRecent sweeps in 7.5 hours — but the strap log never said why each ran or whether new data drove it, so the empty-offload re-score waste behind #1005 / #1146 couldn't be quantified.

What it measures

The post-offload pass re-scores with force: true on both platforms (Swift's analyzeRecent(force: Bool = true) default; Android's #836 forced pass), so a completed but empty/duplicate offload (rows=0, common on a flapping link) still folds the whole raw store for zero new data. This adds one line at that forced re-score:

re-score: trigger=post-offload newData=no (empty/duplicate offload — nothing changed since last run)

newData=no compares the pre-run HR fingerprint (rowCount:maxTs) to the watermark the last successful run advanced. Those lines are the wasted re-scores — turning "186 sweeps" into a measured count of how many folded 18M rows for nothing.

  • Android: at the WhoopBleClient post-offload trigger (vs NoopPrefs.analyzeWatermark).
  • Swift: inside analyzeRecent, gated on force, using the fingerprint it already computes (:385).

Scope

Log-only, no behaviour change — the pass still runs. I deliberately did not touch the re-score/reconnect logic (the analyzeRecent skip is a known data-loss trap); this measures first, per the instrument-first pattern (#1117, #688). The reconnect backoff-reset half is already legible in the existing attempt N, held Xs line by design (see the linkUpSinceMs comment — "a run of drops that all say attempt 1 with a short held is that bug, with no instrumentation needed"), so no new logging there.

Verification

  • compileFullDebugKotlin ✅; app-build running (IntelligenceEngine.swift is app-target). Diagnostic sink line only — no analytics/stored-data change.

…ery)

A testing-build capture showed ~186 full 18-day analyzeRecent sweeps in 7.5 hours on a
flapping WHOOP 4.0 link — but the strap log never said WHY each ran or whether new data
drove it, so the empty-offload re-score waste (#1005/#1146) couldn't be measured.

The post-offload pass re-scores with force:true on BOTH platforms, so a completed but
EMPTY/duplicate offload (rows=0, common on a flapping link) still folds the whole raw
store for zero new data. This logs, at that forced re-score, whether the pre-run HR
fingerprint (rowCount:maxTs) still equals the watermark the last successful run
advanced:

  re-score: trigger=post-offload newData=no (empty/duplicate offload — nothing changed)

`newData=no` lines are the wasted re-scores — turning "186 sweeps" into a measured count
of how many folded 18M rows for nothing.

- Android: at the WhoopBleClient post-offload trigger (compares to NoopPrefs watermark).
- Swift: inside analyzeRecent, gated on `force`, at the fingerprint it already computes.

Log-only, no behaviour change (the pass still runs). NOT touching the re-score/reconnect
logic — measuring first, per the instrument-first pattern (#1117, #688). The reconnect
backoff-reset half is already legible in the existing `attempt N, held Xs` line by
design (the linkUpSinceMs comment), so no new logging there.
@ryanbr
ryanbr merged commit d94d568 into main Aug 9, 2026
5 checks passed
@ryanbr
ryanbr deleted the feat/rescore-attribution-logging branch August 9, 2026 12:21
simoncad7 pushed a commit to simoncad7/noop that referenced this pull request Aug 17, 2026
…ery) (ryanbr#1192)

A testing-build capture showed ~186 full 18-day analyzeRecent sweeps in 7.5 hours on a
flapping WHOOP 4.0 link — but the strap log never said WHY each ran or whether new data
drove it, so the empty-offload re-score waste (ryanbr#1005/ryanbr#1146) couldn't be measured.

The post-offload pass re-scores with force:true on BOTH platforms, so a completed but
EMPTY/duplicate offload (rows=0, common on a flapping link) still folds the whole raw
store for zero new data. This logs, at that forced re-score, whether the pre-run HR
fingerprint (rowCount:maxTs) still equals the watermark the last successful run
advanced:

  re-score: trigger=post-offload newData=no (empty/duplicate offload — nothing changed)

`newData=no` lines are the wasted re-scores — turning "186 sweeps" into a measured count
of how many folded 18M rows for nothing.

- Android: at the WhoopBleClient post-offload trigger (compares to NoopPrefs watermark).
- Swift: inside analyzeRecent, gated on `force`, at the fingerprint it already computes.

Log-only, no behaviour change (the pass still runs). NOT touching the re-score/reconnect
logic — measuring first, per the instrument-first pattern (ryanbr#1117, ryanbr#688). The reconnect
backoff-reset half is already legible in the existing `attempt N, held Xs` line by
design (the linkUpSinceMs comment), so no new logging there.
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