averagejoematt method

the method · under the hood

The Methods Registry

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

The modules below back every entry here. The statistical cores are pure, deterministic, stdlib-only Python with no AI and no I/O (ADR-105's "deterministic computation before any LLM verdict" rule, made literal); where an entry documents the declared scope of an LLM-assisted layer, the registered function is that pure policy itself — fingerprinted the same way.

stats_core.py — lambdas/common/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/experiment/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.

conversation_enrichment.py — lambdas/ai/conversation_enrichment.py

The conversational-capture enrichment layer (#1577) — coach check-in answers, habit reflections, and field-note responses coded by the same LLM enrichment pass as journal text. The entry registered here is its pure, deterministic SCOPE POLICY: these signals are ANALYSIS-ONLY in v1 — they seed hypothesis candidates and are visible as context, but they do not move character or flourishing scoring.

Correlation

6 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.

source: stats_core.py::lag1_autocorr

Effective sample size (n_eff)

Single series: n_eff = n·(1-r1)/(1+r1). Paired (Pyper & Peterman 1998): n_eff = n·(1-r1x·r1y)/(1+r1x·r1y)

Window
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.
Used by
correlation_report, tools_training correlation reads.

source: stats_core.py::fisher_ci

Correlation evidence score (Evidence Bar)

score = 0.5·s_n + 0.3·s_ci + 0.2·s_fdr, s_n = min(1, log1p(n_eff-2)/log1p(88)) (0 at n_eff≤2, ~0.67 at n_eff=21, 1.0 at n_eff≥90), s_ci = max(0, 1 - width of the 95% Fisher CI on r), s_fdr = 1 if fdr_significant is True else 0

Window
The same (r, n, n_eff, fdr_significant) a caller already computed for one correlation claim — no lookback of its own.
Limitations
Tolerant of None/garbage inputs (returns the honest low/zero shape rather than raising) since it sits on a public serving path. `level` (high/medium/low) mirrors charts.js's client-side n thresholds (≥21/≥8) so the served level and every existing confidence treatment read the same grammar. `ci95`/`ci_width` are None (never a fabricated band) when no CI is computable; `fdr_significant` is None (never coerced to False) when the batch was never checked. #1372's ONE deterministic source for the public Evidence Bar — no authored strength grades anywhere, every component computed.
Used by
The Evidence Bar on /api/vitals correlations (site_api_discovery.py) and the correlation ledger surface (site_api_ledger.py) — every published correlation claim's per-claim evidence readout.

source: stats_core.py::correlation_evidence

Interval estimation

2 stats

Moving-block bootstrap CI

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

Randomization inference

2 stats

Start-point randomization test (SCED)

For every candidate start k the pre-declared window could have produced: T(k) = mean(post_k) - mean(pre_k), washout excluded identically at each; one-sided p = #{T(k) at least as extreme as the observed split} / k_valid

Window
The full daily series of the pre-registered criterion metric, from baseline_days before the declared window's first candidate through the experiment's end — one continuous series, so every candidate start sees the same data.
Limitations
Only valid when the start was actually DRAWN at random from the frozen window (experiment_design.draw_start_date) — applied to a hand-picked start it is decorative, not inferential. Exact under the randomization performed, so no independence assumption is needed (the autocorrelation objection to parametric tests on N=1 daily series does not apply), but resolution is capped at p = 1/k: a 7-14 day window can never report below 1/7-1/14, which is a granularity floor, not high precision. Candidates with a thin arm (< 5 points after gaps) are excluded and reported in n_excluded; a pure pre-existing linear trend scores p ≈ 1 by construction — the coincident-trend confound the design exists to defeat.
Minimum n
2
Used by
experiment_design.randomization_test — the end_experiment close-path analysis for randomized-start designs (#1413); reported on /data/ experiment cards next to the effect + CI, and in the analysis summary sentence.

source: stats_core.py::start_point_randomization_test

BSTS-lite synthetic-control counterfactual (the Ghost)

y_t = beta·[1, controls_t] + mu_t + eps_t with mu a local-level random walk; beta by OLS on the pre-period, level variances by maximum innovations likelihood over a fixed signal-to-noise grid; post-period ghost = frozen level + regression, variance P_T + t·sigma_eta² + sigma_eps² + OLS prediction covariance

Window
The pre-period declared in the FROZEN design spec (pre_days before the intervention start, default 28) for fitting; the washout-trimmed post-period for the effect. Only days where the criterion AND every declared control have values — gaps dropped and counted, never imputed.
Limitations
Spec (controls, pre-window, MAPE gate) is frozen at pre-registration — applied post-hoc it is spec shopping, which the design gate exists to forbid. The ghost is withheld with a stated reason when the pre-period one-step-ahead MAPE exceeds the frozen gate, when fewer than 14 aligned pre-days exist, or when MAPE is unevaluable (criterion near zero). First-order only: a local level plus static regression — no seasonality or dynamic coefficients, so a strong weekly cycle the controls don't carry inflates MAPE and (correctly) withholds the ghost. The effect CI uses the full forecast-error covariance (shared level error correlates post days); the interval widens with distance from start by construction — the model's honesty about extrapolation, drawn as-is on the card.
Minimum n
14
Used by
experiment_design.counterfactual_analysis — the end_experiment close path for designs that froze a counterfactual spec (#1410); rendered on /data/ experiment cards as the ghost trace + widening band, and in the analysis summary sentence.

source: bsts_lite.py::fit_counterfactual

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)

ewaₜ = α·xₜ + (1-α)·ewaₜ₋₁, with α = 1 - exp(-1/decay_days); optional warm-start seed

Window
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).
Used by
acwr_compute_lambda.py (EWMA-ACWR, #543); mcp/helpers.compute_ewa.

source: stats_core.py::ewma_series

Changepoint detection

1 stat

Changepoint detection (abrupt level shift)

Binary segmentation: recursively finds the strongest single-changepoint split (CUSUM-style max-statistic scan, _single_changepoint) in each sub-segment, up to max_changepoints (default 3); each accepted break must clear a Bonferroni-corrected confidence gate (default 0.99) AND a |Cohen's d| ≥ min_effect (default 1.0) magnitude gate

Window
Caller-supplied chronological series (None/non-numeric dropped, order kept); the one registered consumer runs it over a 60-day lookback (CHANGEPOINT_WINDOW_DAYS) and only surfaces breaks dated within the trailing 28 days (CHANGEPOINT_RECENT_DAYS) as actionable.
Limitations
Needs ≥ 2·min_segment (default 7) clean points on both sides of a candidate split or returns status 'insufficient_data' with an empty changepoint list — no shift is ever claimed that can't be tested. Finds abrupt LEVEL shifts only, not gradual drift (see the platform's separate slow-drift window comparison) or seasonal breaks. Binary segmentation is greedy (strongest break first), not exhaustive, so a real but smaller simultaneous break can be missed. SCOPE NOTE (#542, the deliberately weaker exemplar of this hygiene pass, #3449): as of this entry the only registered consumer is the daily-insight compute's priority-3/4 injection into the DAILY EMAIL BRIEF, a private single-recipient surface — not the public website. This entry documents it anyway because the registry's contract is 'every stat the platform publishes', and a personal daily brief is a publication surface even though it is not public; re-scope this note if a public consumer is added.
Minimum n
14
Used by
daily_insight_compute_lambda.py's _compute_changepoints (IC-31, #542) — HRV / Resting HR / Weight level-shift detection injected into the daily brief's priority queue. No public website consumer as of #3449.

source: stats_core.py::detect_changepoints

Multiple comparisons

1 stat

Benjamini-Hochberg FDR correction

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 dozens of 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

9 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.
Used by
The calibration scoreboard's reliability curve.

source: stats_core.py::reliability_bins

Calibration summary (n, Brier, reliability, verdict)

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. Also reports `skilled` (Brier skill > 0?) — calibrated (reliability: stated confidence tracks observed rates) and skilled (beats the base rate) are different claims, and the summary carries both so no surface can conflate them (#1370). Reports `accuracy_ci95` — the 95% Wilson interval on the same confirmed/n, same percentage-point units as accuracy_pct — whenever n > 0 (#3450, ADR-105): a bare accuracy_pct off a small n reads as more precise than it is (21.6% vs. 'somewhere between 11% and 37%' are different decisions at n=37).
Used by
/api/calibration, /api/coach_team's per-coach calibration line.

source: calibration_core.py::score_pairs

Pooled calibration card scored against a stratified base rate

Pooled Brier over every stratum's pairs; reference Brier = Σ n_i · bs_ref_i / Σ n_i where bs_ref_i is stratum i's OWN base-rate Brier; skill = 1 − brier / reference. Over/under-confidence is tripped by the worst stratum's n-weighted reliability gap (among strata with n ≥ 5), not the pooled gap

Window
Every resolved pair on the platform, partitioned by stratum (coach calls · hypothesis bets · interval forecasts), to date.
Limitations
Pooling strata with different base rates and scoring the pool against ONE pooled base rate can manufacture a positive skill no stratum has (the pooled reference is worse than either stratum's own, so knowing the stratum beats it) — the 2026-09-05 lifetime card read skilled / well-calibrated while both strata were unskilled (#3550). Against the stratified reference, pooled skill > 0 is impossible unless a stratum beats its own climatology; `skilled` is additionally forced False when no stratum is skilled, and each stratum's own n / Brier / skill / gap is served on the card. Same n ≥ 5 verdict floor and the same fixed ±0.15 gap trip as calibration_verdict (a documented ADR-105 exception). A stratum with n < 2 or every outcome identical contributes no reference — unknown, never counted as unskilled.
Minimum n
5
Used by
/api/calibration's platform + platform.lifetime cards; the State of Matthew calibration section.

source: calibration_core.py::score_strata

Directional trend verdict (up / down / flat)

slope = (EWMA_now - EWMA_prior_lag7) / |EWMA_prior_lag7| over the metric's trailing 30d series (decay 0.87); slope > +0.02 → up, < -0.02 → down, else flat

Window
Trailing 30 days of the predicted metric, minimum 9 observations (else no verdict, not a flat one).
Limitations
The ±2% band is a FIXED editorial choice, not derived from each metric's own trailing variance — a documented exception to the ADR-105 'thresholds from personal variance' rule, dated 2026-09-02 (#3448). Its reach is the dominant live scoring path: every machine spec re-routed to directional evaluation by the #813 rescue (1,207/1,207 live specs at stamping) is judged against this one band, so a high-variance metric can clear it on noise and a low-variance metric's real signal can be absorbed as flat. Re-derive trigger: once a per-metric trailing-variance baseline exists over a clean cycle window (the September 2026 n≥30 read is the first candidate), the band is derived from it as its own measured change.
Minimum n
9
Used by
Coach prediction grading — since #4617 only a direction call with no filing date (every dated call is graded by directional_window_verdict).

source: coach_prediction_evaluator.py::_get_ewma_trend

Direction call graded across its own window (up / down / flat)

change = last reading − first reading of [filed day, filed day + stated window]; band = median |day-to-day change| of the window's readings (÷ √k for an N-day-average call, comparing the mean of the first k and last k readings, k = min(N, readings ÷ 2)); change > band → up, < −band → down, else flat

Window
The call's own stated window (the domain-clamped window when none is stated), from the day it was filed — genesis for a call sealed before day one. Readings after the window's last day never enter. At least 4 readings, the first and last within 2 days of their edges, else no verdict (never a flat one).
Limitations
The band is derived from the subject's own day-to-day variance inside the window (ADR-105), about one standard deviation of the first-minus-last difference a no-change series would produce — so a single noisy edge reading (a partial day of steps) can still decide a raw-reading call; the N-day-average calls smooth it. The median step includes any real trend per day, which widens the band slightly on a steadily moving series. Replaced the latest-readings EWMA check (#4617): two sealed weight calls it graded flat sat on a window where the served weigh-ins fell more than ten pounds.
Minimum n
4
Used by
Coach prediction grading — every dated direction call, and every machine spec the #813 rescue re-routes.

source: prediction_direction_window.py::measure

Over/under-confident verdict

Weighted mean gap = Σ(bin_n · (bin_mean_confidence - bin_observed_rate)) / Σ(bin_n); gap > 0.15 → over-confident, gap < -0.15 → under-confident; otherwise well-calibrated only when Brier skill > 0 — a skill ≤ 0 surface reads not-yet-skillful instead (#1370)

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. 'Well-calibrated' asserts reliability AND skill: a forecaster whose stated confidence tracks observed rates but whose Brier skill is ≤ 0 (worse than always guessing the base rate) reads 'not_yet_skillful' — reliability alone never earns the flattering verdict (ADR-104/105, #1370). An undefined skill (degenerate base rate) is treated as unknown, not as unskilled.
Minimum n
5

source: calibration_core.py::score_pairs

Coarse credibility label (nascent / not-yet-skillful / developing / reliable / authoritative)

n < 3 → nascent. Brier skill ≤ 0 → not-yet-skillful. 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. A negative Brier skill (worse than the base rate) can never render the reliable/authoritative rungs, however good the raw Brier looks against an extreme base rate — it reads not-yet-skillful (#1370).
Used by
Coach cards that need a single at-a-glance credibility word.

source: calibration_core.py::score_pairs

Provenance

1 stat

Conversational enrichment signals — analysis-only scope

scope = analysis_only (v1, #1577): LLM-coded signals from coach check-in answers, habit reflections, field-note responses and — since #1708 — reactions to the coach's weekly Horizons pick (channel prescription_reaction) seed HYPO_CANDIDATE# rows (channel-tagged) and are visible as enriched context, but they do NOT enter character or flourishing scoring. Absence of conversation is 'no data', never a zero (ADR-104). Dedup vs the journal (AC4): content-hash equality, or a ≥40-char normalized containment match.

Window
Rolling 14-day sweep on the daily 6:30 AM enrichment cadence; each record is coded once (re-coded only on a schema bump or explicit force).
Limitations
These numbers are a language model's (Haiku) reading of short conversational prose — never sensor data, and shorter/noisier input than a journal entry. ANALYSIS-ONLY by declared policy: promotion into character or flourishing scoring requires personal-variance thresholds derived from an observed baseline FIRST (ADR-105) plus a human re-review of this entry — the fingerprint below trips if the policy function changes without that review. Causal hints survive only the deterministic verbatim-quote grounding gate (ADR-104). Enrichment pauses at budget tier 1 (internal band, ADR-125); paused windows are visible as unenriched records, never fabricated. The #1708 prescription_reaction channel inherits this scope unchanged: it calibrates the DETERMINISTIC Horizons reaction ledger (counts only, no model verdict) and moves no scoring.
Used by
journal_analyzer_lambda HYPO_CANDIDATE# aggregation (channel provenance on every quote) → the weekly hypothesis engine's candidate seeding; enriched context wherever enriched_* fields are read.

source: conversation_enrichment.py::enrichment_policy

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