feat(calories): price sub-gate walking minutes from measured cadence (CADENCE-Adults) - #52
Merged
Conversation
…(CADENCE-Adults) MOT-02 knowingly traded walking away: the HR-flex gate bills nothing below the ACSM moderate floor because Keytel has no fitted data there, so a walk at 95 bpm added ZERO active kcal for its entire duration (edge report: "Walking calories are not counted" — the workout and its steps record fine, Active energy never moves). MT-05 established the 1 Hz accel cannot fill that gap. Measured cadence can: it is the one signal on this platform that actually resolves gait (the 100 Hz pedometer), and CADENCE-Adults (Tudor-Locke et al. 2019, IJBNPA 16:8) publishes the cadence↔MET line for exactly this region — heuristic thresholds 100/110/120/130 steps/min for 3/4/5/6 METs. dailyEnergy gains an optional cadenceSpmPerMin series, index-aligned with hrPerMin (null = nobody measured that minute — which is most minutes; the pedometer only runs while the phone holds the live link): - A minute the HR gate accepts bills by HR alone, exactly as before. HR sees intensity cadence cannot, and a minute is never billed twice. - A minute the HR gate refuses (below flex, or no HR at all — measured gait stands on its own), whose measured cadence is at/above the study's own moderate floor (100 spm), bills (MET − 1) basal-minutes of surplus via the new metFromCadenceSpm — linear between the published anchors, clamped at both ends of the fitted range (under 100 spm the study does not price it; over 130 spm is running, which drives HR over the gate and bills there). - The result record gains a `walking` component (already included in `active`) so callers can disclose how much of the day's active energy came from measured walking rather than HR. - No cadence series → byte-identical behaviour to before. - Misaligned series throws; unusable anchors still abstain, cadence or not. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015TxisrChNFxtVMXFFNRGtV
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 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 |
DropTabl
added a commit
to DropTabl/edge
that referenced
this pull request
Aug 26, 2026
…(v77)
The reported bug ("Walking calories are not counted"): a Walking workout
records fine, its steps count fine, and the day's Active energy never moves.
Root cause is not a wiring or sync failure — MOT-02's HR-flex gate
deliberately bills nothing below the ACSM moderate floor, and a walk lives
entirely below it. The session's own bout number (which bills sub-gate
samples at the resting rate) made the gap read like a sync bug.
The analytics half (OpenStrap/analytics#52) prices sub-gate minutes from
MEASURED cadence — CADENCE-Adults' published 100/110/120/130 spm ↔ 3/4/5/6
METs line, the one gait signal this platform actually has after MT-05 ruled
the 1 Hz accel out. This is the edge half:
- lib/compute/step_cadence.dart: the ONE windows→minutes cadence mapping,
from the day's RESOLVED live_coverage spans (credited, never raw rows, so
band/phone overlap cannot double-price a step). Partial coverage pro-rates
DOWN — a walk's boundary minute under-bills rather than half a minute of
walking pricing a full MET-minute; untouched minutes are null, unmeasured.
- Both energy passes feed it through that one mapping: the coordinator's
canonical wakeDayEnergy AND the pipeline's early-read mirror
(DayBundleInput carries the spans across the isolate), so the early read
and the derived day bill a walk identically instead of the number growing
when the coordinator's pass lands.
- wakeDayEnergy filters the cadence series in the SAME pass as the off-skin
HR filter — dropping an HR entry without its cadence would price every
later cadence against the wrong minute (pinned by test).
- The TDEE block discloses the term (live_coverage_pedometer in inputs_used,
walking kcal in the note) only on days it actually priced something.
- kAlgoVersion 76 → 77. A day with no pedometer coverage derives
byte-identical to v76.
PIN GATE: the pubspec analytics pin is NOT flipped yet — it must move to the
OpenStrap/analytics#52 merge SHA (together with kAnalyticsPin) before this
can merge, per invariant OpenStrap#5. Draft until then.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015TxisrChNFxtVMXFFNRGtV
DropTabl
added a commit
to DropTabl/edge
that referenced
this pull request
Aug 26, 2026
… exists to consume All three pin locations move together to analytics main @ a077a4a, the OpenStrap/analytics#52 merge commit: the cadence→MET walking term in Calories.dailyEnergy (CADENCE-Adults). Unlike the usual repin this one exists to move a number — that number IS this branch's change, priced in by the kAlgoVersion 77 bump and the v77 migration. The hop is exactly OpenStrap#52 and nothing else (calories.dart + its tests).
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.
The gap
MOT-02 raised the HR-flex gate to the ACSM moderate floor and its own changelog measured the cost: billed wake minutes fell to 4.9%, median daily active energy to 48 kcal. That was the right call for HR — Keytel has no fitted data below the exercise domain — but it left walking priced at zero: a one-hour walk at 95 bpm adds nothing to Active energy for its entire duration. This is now a user-facing bug report on edge ("Walking calories are not counted": the workout and steps record fine, Active Calories never move). MT-05 already established the 1 Hz accel channel cannot fill this gap (Brage's branches can't read a 1 Hz gravity vector).
The fix
Measured cadence is the one signal on this platform that actually resolves gait — the 100 Hz pedometer — and CADENCE-Adults (Tudor-Locke et al. 2019, IJBNPA 16:8) publishes the cadence↔MET line for exactly this region: heuristic thresholds 100/110/120/130 steps/min ↔ 3/4/5/6 METs.
Calories.dailyEnergygains an optionalcadenceSpmPerMinseries, index-aligned withhrPerMin(null = nobody measured that minute):(MET − 1)basal-minutes of surplus via the newmetFromCadenceSpm— linear between the published anchors, clamped at both ends of the fitted range: under 100 spm the study does not price it (the same "only exercise-domain minutes bill" philosophy the HR gate already holds); over 130 spm is running, which drives HR over the gate and bills there.walkingcomponent (already folded intoactive) so callers can disclose how much of the day came from measured walking.ALGORITHMS.md gets the row + citation.
Numbers
80 kg / 180 cm / 30 y male (Mifflin 1780 kcal/day): a one-hour walk at 110 spm bills 60 × 3 × 1.24 ≈ 222 kcal of walking surplus — previously 0.
Tests
New
walking cadence term (CADENCE-Adults)group: the published MET anchors and clamps, the reported below-gate walk billing, the no-double-billing invariant, unmeasured/ambling/non-finite minutes staying basal, gait-on-off-skin-HR minutes billing, misalignment throwing, and anchor abstention unchanged.dart analyzeclean; full suite green (591 tests).Edge side (per-minute cadence from
live_coverage, threading throughwakeDayEnergyand the pipeline mirror,kAlgoVersionbump + pin) follows as a draft PR on OpenStrap/edge once this lands.