Address three confirmed review findings:
- Windows were sample-count based, so "7-day" and "last night" claims could be
built from weeks-old data. All signals now use calendar windows anchored on a
reference date (the tool passes today); stale metrics report "no recent data"
and the verdict is withheld instead of presenting old samples as current.
- rhr_signal's `or vals[:-1]` fallback compared the recent week against itself at
the sample minimum, reading a uniformly-ill week as "ok". The baseline is now
disjoint by construction and insufficient baselines return nodata.
- The HRV SWC band had no floor, so a near-constant baseline flagged trivial
fluctuations (50->49) as red "parasympathetic suppression". SWC now floors at
0.05 ln units (~5% rMSSD, on the order of normal day-to-day variation).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NGzHtDvJur9U7ysgRKRUTN
New pure-compute utils/readiness.py (stdlib only, fully unit-tested) assesses
readiness from wellness history: HRV via Plews & Laursen 7-day rolling lnRMSSD vs
baseline +/- SWC, resting-HR and sleep trends, and conventional-direction
subjective inputs (soft warnings only). The get_training_readiness tool fetches
the window, normalizes the date-keyed API response, and renders a banded verdict
with the contributing signals. Verdict is withheld (not fabricated) when HRV is
sparse and fewer than two other core signals have data.
Implements #1. Completes the 0.3.0 coaching-context milestone.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NGzHtDvJur9U7ysgRKRUTN