Every statistic this platform publishes — its formula, the window it runs over, and what it can't tell you — generated straight from the source modules below, not hand-written. If the code changes, this page is built to go stale until a human re-verifies it (see the fingerprint note).
Where this comes from
Two modules currently back every number here — both pure, deterministic, stdlib-only Python with no AI and no I/O (ADR-105's "deterministic computation before any LLM verdict" rule, made literal).
stats_core.py — lambdas/stats_core.py
The one sanctioned statistics module (ADR-105, story #529) — pure, stdlib-only, deterministic. Replaced three divergent Pearson-r implementations and two p-value copies that used to disagree with each other.
calibration_core.py — lambdas/calibration_core.py
The one prediction-calibration scorer (#538, ADR-105) — grades every forecast the platform makes against what actually happened, so the public calibration scoreboard, /api/coach_team, and the coach track-record tool all read the same numbers.
Correlation
5 stats
Pearson correlation (r)
r = Σ(x-x̄)(y-ȳ) / √(Σ(x-x̄)² · Σ(y-ȳ)²), clamped to [-1, 1]
Window
Whatever paired series the caller passes in — the function has no lookback of its own. The platform's primary caller, the weekly correlation compute, passes a 90-day rolling window (LOOKBACK_DAYS).
Limitations
Requires n ≥ min_n (default 3, callers commonly raise this to 5); returns None below that threshold or when either series has zero variance. Measures linear association only — a real non-linear relationship can score near zero. Not corrected for day-to-day autocorrelation on its own (see effective_sample_size) — a raw r without the effective-n-based p-value/CI overstates confidence on daily physiological series.
Minimum n
3
Used by
The correlation engine (/method/intelligence/), tools_training zone-2 and exercise-efficiency correlations, get_cross_source_correlation.
source: stats_core.py::pearson_r
Lag-1 autocorrelation
r1 = Σ(xₜ-x̄)(xₜ₊₁-x̄) / Σ(xₜ-x̄)², clamped to [-1, 1]
Window
Caller-supplied series, in the order given — treats the series as one continuous sequence with no gap-awareness (a missing day is not distinguished from a lag of 1).
Limitations
Returns 0.0 (no detectable memory) below n=3 or zero variance, which makes the downstream effective-n correction a no-op rather than an error. A helper, not a reported statistic on its own — it feeds effective_sample_size.
Same series/window as the r or mean it's correcting.
Limitations
Clamped to [2, n] — a negative-autocorrelation 'bonus' (n_eff > n) is discarded so the correction only ever moves toward conservatism, never inflates apparent evidence. First-order (Bartlett/AR(1)) only — does not model higher-order or seasonal autocorrelation. The core answer to the ADR-105 rule that daily physiological series (recovery, HRV, weight) are not i.i.d. and raw n overstates the evidence.
Used by
Every correlation surface: correlation_report (mcp/helpers.py), tools_training, the weekly correlation compute.
source: stats_core.py::effective_sample_size
Pearson p-value
Two-tailed via the t-distribution: t = r·√df / √(1-r²), df = n-2; erf-based normal approximation with a small-df shrink z = t·√(df/(df+2)) below df=30
Window
Takes fractional n, so it composes directly with effective_sample_size's autocorrelation-corrected n_eff rather than the raw observation count.
Limitations
None when |r| ≥ 1 or n ≤ 2. Accurate to ~3 decimals for df > 10, conservative (slightly wider) below — a stated intentional trade-off, not an unhandled edge case. Always compute on n_eff for daily series, never raw n (ADR-105).
Used by
correlation_report (the ONE correlation-reporting helper, replacing 6 duplicate copies), tools_training.
source: stats_core.py::pearson_p_value
Correlation confidence interval (Fisher z)
z_r = atanh(r); CI = tanh(z_r ± z_crit·SE), SE = 1/√(n-3)
Window
Same n as the r it's bounding — pass effective_sample_size's n_eff for autocorrelated daily series.
Limitations
None when |r| ≥ 1 or n ≤ 3. Supports exactly four confidence levels (0.80, 0.90, 0.95, 0.99) — anything else raises ValueError rather than silently approximating.
Percentile CI over 1000 resamples of contiguous blocks (default block length n^(1/3), floored at 2) — preserves short-range autocorrelation that i.i.d. resampling would destroy
Window
Caller-supplied series (paired or single); a fixed seed (1337) makes the interval reproducible for identical input — same data always yields the same interval.
Limitations
Needs n ≥ 5, and at least 100 of the 1000 replicates must produce a valid statistic or the call returns None (e.g. degenerate resamples with zero variance). Default statistic is Pearson r (paired) or the mean (single series); a custom stat may be passed in. Only 4 confidence levels supported (see fisher_ci).
Minimum n
5
Used by
weight_trend.py (the weight-rate confidence interval on /api/journey, #535).
source: stats_core.py::moving_block_bootstrap_ci
Bootstrap CI for a mean difference
Block-resamples baseline and window series independently (1000 replicates each), returns the percentile CI of mean(window) - mean(baseline)
Window
The two series the caller defines as 'baseline' and 'window' — the n-of-1 experiment primitive: is this metric different in the test window than before it started, and by how much?
Limitations
Both series need n ≥ 5 or the call returns None. Independent block-resampling means it does not account for any correlation between the baseline and window periods themselves (e.g. a slow seasonal drift spanning both).
Minimum n
5
Used by
experiment_design.py (evaluate_design) — the n-of-1 pre-registered experiment analysis (#539).
source: stats_core.py::bootstrap_mean_diff_ci
Effect size
1 stat
Cohen's d (effect size)
d = (mean(window) - mean(baseline)) / pooled SD, pooled SD from both groups' sample variances
Window
The same two caller-supplied series as bootstrap_mean_diff_ci — the two are always reported together (a CI without a size, or a size without a CI, is half the honesty bar).
Limitations
None when either group has n < 2 or pooled SD is 0. A standardized magnitude, not a significance test — always report alongside the bootstrap CI, never alone.
Used by
experiment_design.py (evaluate_design).
source: stats_core.py::cohens_d
Forecasting
3 stats
EWMA fit (simple exponential smoothing)
level update: levelₜ = levelₜ₋₁ + α·(xₜ - levelₜ₋₁); α chosen by deterministic grid search over 0.05–0.95 (step 0.05) minimizing one-step-ahead squared error when not given explicitly
Window
Caller-supplied series in chronological order.
Limitations
Needs ≥ 4 clean points or returns None. The grid search always picks the same α for the same data (ties go to the smaller α) — deterministic, no randomness, per ADR-105's 'deterministic computation before any LLM verdict' rule.
Used by
ewma_forecast (below); indirectly, the forecast engine.
source: stats_core.py::ewma_fit
EWMA h-step-ahead forecast
Point forecast = final smoothed level; interval width σ_h = σ·√(1 + (h-1)·α²) where σ is the sample SD of one-step-ahead residuals
Window
Caller-supplied series; the platform's forecast engine runs this daily at 0.80 confidence — chosen deliberately below the more common 0.95 so the 'did the interval cover the outcome ~80% of the time?' calibration question is answerable in weeks, not months.
Limitations
Needs ≥ min_n clean points (default 10) and ≥ 3 residuals or returns None. An EXPECTATION extrapolated from the series' own recent pattern — never a causal claim. Supports only the 4 fisher_ci confidence levels.
Minimum n
10
Used by
forecast_engine_lambda.py — daily expectations graded into the calibration ledger.
source: stats_core.py::ewma_forecast
EWMA series (exponentially-weighted moving average)
Caller-supplied chronological series; EWMA-ACWR runs it with a 7-day (acute) and 28-day (chronic) time-constant over the daily Whoop-strain series.
Limitations
Recent observations are weighted most, older ones decay smoothly — unlike a flat rolling mean, which weights its whole window equally and drops days off a cliff at the edge. ACWR = EWMA(acute)/EWMA(chronic) is a COUPLED ratio: the acute load is a mathematical component of the chronic load, so they move together by construction (Lolli et al. 2019) — a directional signal, not a precise injury predictor. The Gabbett zone thresholds it is compared against are population-derived (ADR-105 r4).
Sort p-values ascending; adjusted p(k) = min(1, m/(k+1) · p(k)), then enforced monotone non-decreasing from the largest rank down
Window
Applied across one batch of simultaneous comparisons (e.g. all correlation pairs computed by one tool call) — not across the platform's entire history of tests.
Limitations
None entries (untestable pairs) pass through unadjusted and don't count toward m. Controls the FALSE DISCOVERY rate, not the false-positive rate of any single test — with ~23 simultaneous correlation pairs, some individually-significant p-values will still be flagged non-significant after correction, by design.
Used by
correlation_report (per-tool FDR across every correlation in a batch).
source: stats_core.py::bh_fdr
Calibration
6 stats
Brier score
mean((p - y)²) over all (stated probability, realized outcome) pairs
Window
Every resolved prediction to date for the surface being scored (a coach, the hypothesis engine, or platform-wide) — grows as more predictions resolve, never a fixed lookback.
Limitations
0.0 is perfect, 0.25 is the always-say-50% baseline, 1.0 is confidently-wrong-every-time. None when there are no valid (probability in [0,1], outcome in {0,1}) pairs — an unresolved or too-new coach shows no score rather than a misleading 0.
Used by
The calibration scoreboard (/method/calibration/), /api/calibration, /api/coach_team, the coach track-record MCP tool.
source: stats_core.py::brier_score
Brier skill score
1 - (Brier score / Brier score of the base-rate climatology forecast)
Window
Same pair set as the Brier score it's compared against.
Limitations
None when fewer than 2 pairs or every outcome is identical (skill is undefined against a degenerate base rate). 1.0 is perfect, 0.0 means no better than always guessing the observed base rate, negative means worse than that baseline — the honest 'does stated confidence beat just guessing the average?' number.
Used by
The calibration scoreboard.
source: stats_core.py::brier_skill_score
Reliability curve (calibration bins)
Splits [0,1] into n_bins equal bands (default 10); each non-empty bin reports mean stated confidence vs. observed outcome rate
Window
Same pair set as the Brier score for that surface.
Limitations
Empty list when there are no valid pairs. Bins with very few points can show a noisy observed rate — the bin's n is always reported alongside so a 1-of-1 bin isn't read as strong evidence.
Composes brier_score + brier_skill_score + reliability_bins over the same (confidence, outcome) pairs into one summary dict
Window
Every resolved prediction for the coach/surface being scored, to date.
Limitations
Needs at least 1 resolved pair to report accuracy_pct; the calibration verdict (over/under-confident) needs ≥ 5. Below those thresholds the relevant field is None rather than a guess dressed as a number.
Weighted mean gap = Σ(bin_n · (bin_mean_confidence - bin_observed_rate)) / Σ(bin_n); gap > 0.15 → over-confident, gap < -0.15 → under-confident, else well-calibrated
Window
Same reliability bins as reliability_bins for that surface.
Limitations
Requires n ≥ 5 resolved predictions AND at least one non-empty bin, else 'insufficient_data'. The ±0.15 threshold is a fixed editorial choice (not derived from this platform's own variance) — a documented exception to the ADR-105 'thresholds from personal variance' rule, tracked as a candidate for future recalibration once more predictions resolve.
n < 3 → nascent. Brier ≤ 0.15 AND n ≥ 12 → authoritative. Brier ≤ 0.20 → reliable. Else → developing
Window
Same pair set as the Brier score for that surface.
Limitations
A coarse, backward-compatible label kept for surfaces that pre-date the Brier-based scorer — always shown alongside the underlying Brier score and n, never as a substitute for them. The 0.15/0.20 cut points are fixed, not personal-variance-derived.
Used by
Coach cards that need a single at-a-glance credibility word.
source: calibration_core.py::score_pairs
This page is generated by scripts/v4_build_methods.py from lambdas/methods_registry.py, the same registry served machine-readably at /api/methods. Each entry records a hash of the function it documents at the time its prose was last verified; a test in tests/test_methods_registry.py fails if the code changes without the entry being reviewed again — so this registry can be incomplete, but it cannot silently lie about a stat it already documents. generated, not authored