SignalTuned SignalTuned

Rankings tuned to the signal, not the noise.

Need help? Sign in

Model Card

Every engine version. Every change. Every accuracy review.

Current production version: v1.6.111. 144 releases on record.

Every change documented. Every version archived.

SignalTuned doesn't ship "the latest rankings." It ships a specific, versioned engine with every parameter spelled out. When a parameter changes, the version increments and the change shows up here with the reason. When the engine runs an accuracy review against real outcomes, the results show up here too.

Every ranking the engine produces carries a manifest_hash tied to one of these versions. Click the hash on any rankings page to see which engine version generated that output.

v1.6.111 current

2026-06-06

v1.6.110

2026-06-06

v1.6.107

2026-06-05

v1.6.106

2026-06-05

v1.6.105

2026-06-05

v1.6.104

2026-06-04

v1.6.103

2026-06-04

v1.6.102

2026-06-03

v1.6.101

2026-06-02

STAGED (flag-OFF) the QB shrinkage elite-skip — primary lever for the +2.50 PPG QB backtest bias. Ported the redraft DISC-R8 elite-skip to dynasty: metrics.apply_shrinkage now accepts config.shrinkage.elite_skip {enabled:false, positions:[QB], elite_mult:1.0} and, when ON, skips Bayesian shrinkage for a thin-sample player whose weighted_ppg > elite_mult x positional prior (a demonstrated above-prior producer is durable, not a one-year wonder dragged toward a sub-replacement prior). Root cause per docs/SPEC_qb_shrinkage_fix_2026-06-02.md: the dominant of two shrinkage ops; young producing QBs (Daniels class) are the affected set. FLAG STAYS OFF: the candidate's QB CI crosses zero on the thin cohort (n~33), so ship only after 2026 actuals tighten it AND a clean full-engine backtest clears (3 prior QB attempts false-SHIP'd on proxies). Flag-OFF = no ranking change; walk-forward caches re-stamp identical (the proof). Files: metrics.py, engine_config.json, engine_config.schema.json.

v1.6.100

2026-06-02

v1.6.99

2026-06-01

v1.6.98

2026-06-01

v1.6.97

2026-05-30

v1.6.96

2026-05-30

v1.6.95

2026-05-28

v1.6.94

2026-05-28

v1.6.93

2026-05-28

v1.6.92

2026-05-28

v1.6.91

2026-05-27

v1.6.90

2026-05-27

v1.6.89

2026-05-27

v1.6.88

2026-05-27

v1.6.87

2026-05-27

v1.6.86

2026-05-27

v1.6.85

2026-05-27

v1.6.84

2026-05-26

v1.6.83

2026-05-26

v1.6.82

2026-05-26

v1.6.78

2026-05-26

v1.6.77

2026-05-26

v1.6.76

2026-05-26

v1.6.75

2026-05-26

v1.6.74

2026-05-26

v1.6.73

2026-05-26

v1.6.72

2026-05-26

v1.6.71

2026-05-26

v1.6.70

2026-05-26

v1.6.69

2026-05-26

v1.6.68

2026-05-26

v1.6.67

2026-05-26

v1.6.66

2026-05-26

v1.6.65

2026-05-26

v1.6.64

2026-05-26

v1.6.63

2026-05-25

v1.6.62

2026-05-24

v1.6.61

2026-05-24

v1.6.60

2026-05-24

v1.6.59

2026-05-24

v1.6.58

2026-05-24

v1.6.57

2026-05-23

v1.6.56

2026-05-23

v1.6.55

2026-05-22

v1.6.54

2026-05-22

v1.6.53

2026-05-22

v1.6.52

2026-05-22

v1.6.51

2026-05-22

v1.6.50

2026-05-22

v1.6.49

2026-05-22

v1.6.48

2026-05-22

v1.6.47

2026-05-22

v1.6.46

2026-05-21

v1.6.45

2026-05-21

v1.6.44

2026-05-20

v1.6.43

2026-05-20

v1.6.42

2026-05-20

v1.6.41

2026-05-20

v1.6.40

2026-05-19

v1.6.39

2026-05-19

v1.6.38

2026-05-19

v1.6.37

2026-05-18

v1.6.36

2026-05-18

v1.6.35

2026-05-18

v1.6.34

2026-05-18

v1.6.33

2026-05-18

v1.6.32

2026-05-18

v1.6.31

2026-05-18

v1.6.29

2026-05-18

v1.6.28

2026-05-18

v1.6.27

2026-05-18

v1.6.26

2026-05-18

v1.6.25

2026-05-17

v1.6.24

2026-05-17

v1.6.23

2026-05-17

v1.6.22

2026-05-17

v1.6.21

2026-05-17

v1.6.20

2026-05-17

v1.6.19

2026-05-13

v1.6.18

2026-05-13

v1.6.17

2026-05-13

v1.6.16

2026-05-13

v1.6.15

2026-05-13

v1.6.14

2026-05-13

v1.6.13

2026-05-13

v1.6.12

2026-05-12

v1.6.11

2026-05-12

v1.6.10

2026-05-12

v1.6.10

2026-05-12

v1.6.9

2026-05-12

v1.6.8

2026-05-12

v1.6.7

2026-05-12

Sprint C accuracy ship: WR age curve flattened to 1.0 across all ages (REBUILT_WR_CURVE in age_curves_rebuilt.py). Rationale: AS-7 ablation (Session 93) showed disabling the WR age curve improves WR MAE_dyn by 0.43 ppg/year; AS-8 minimal-engine head-to-head confirmed flat-curve naive baseline beats production WR MAE_dyn by 0.44. Sprint C experiments with curve reshape (AS-2-informed lifts; naive piecewise shape) both WORSENED WR MAE (4.27, 4.91 vs baseline 2.89 on 2019). Root cause: the LTV horizon math (7-season weighted average of weighted_ppg × age_factor) interacts non-linearly with non-flat values — only TRUE flat (age_factor=1.0 at every age) reproduces AS-7's improvement. Walk-forward AB 2019-2024 aggregate vs v1.6.6: QB MAE_dyn 3.891 → 3.690 (-0.20); RB 3.216 → 3.085 (-0.13); WR 2.702 → 2.268 (-0.43); TE 2.332 → 2.205 (-0.13). vs naive baseline (AS-8): QB now beats naive by 0.74; TE by 0.05; WR ties within 0.005; RB still loses by 0.16 (next sprint target). Trade-off disclosure: flat WR curve removes dynasty age-discrimination from WR dynasty_ppg — a 30-year-old WR with weighted_ppg=10 is valued the same as a 25-year-old at 10. This is intentionally optimizing for year-1 projection MAE; multi-year dynasty value differentiation is preserved in ltv_discounted (sum, not average) and in archetype modifiers. Old REBUILT_WR_CURVE values preserved in age_curves_rebuilt.py comment block for rollback. No other curves touched.

v1.6.6

2026-05-12

Session 93 Option-C ramp moderation. v1.6.5 walk-forward AB returned numbers identical to v1.6.4 across all four positions to two decimal places (QB MAE 3.89 / bias +2.58 / r 0.458; TE r 0.658). Diagnosis update: the QB age curve smoothing in v1.6.4 / rollback in v1.6.5 had no engine-level effect — the actual driver of the v1.6.4 regression (vs v1.6.3 baseline QB bias +2.35, TE r 0.719) was the rookie_development_ramp.QB change from [0.88, 0.94, 1.0] to [0.50, 0.70, 0.85, 1.0]. The mechanism cascade is ramp -> rookie projections -> P13/VOS positional priors -> TE r drop. Surgical fix: bracket the ramp magnitude to find the smallest step back from [0.50, ...] that still flips the Maye/Mendoza/Simpson inversion. Sandbox bracket sweep: [0.50, 0.70, 0.85, 1.0] gives Maye QB5 / Mendoza QB9 (4-rank gap, baseline); [0.55, 0.75, 0.88, 1.0] gives Maye QB5 / Mendoza QB7 (2-rank gap, robust); [0.60, 0.78, 0.90, 1.0] gives Maye QB5 / Mendoza QB6 (1-rank gap, thin); [0.65, 0.80, 0.90, 1.0] inverts back to Mendoza QB4 / Maye QB6. v1.6.6 selects [0.55, 0.75, 0.88, 1.0] — smallest step back with a robust safety margin on the inversion fix. Predicted effect on walk-forward AB: partial recovery of QB bias toward +2.35 and TE r toward 0.719, since the ramp magnitude on year-0 (the dominant lever) is 10% less aggressive vs v1.6.5. Pending: walk-forward AB validation. QB curve stays at restored trim-25% values (no rollback of v1.6.5's curve restore).

v1.6.5

2026-05-12

Session 93 surgical rollback of v1.6.4 QB age curve smoothing. Walk-forward AB on v1.6.4 regressed two of the four positions: QB bias drifted further from zero (+2.35 -> +2.57 wPPG, wrong direction; decision rule was 'bias improves toward 0' -> FAILED) and TE r dropped -0.061 (0.719 -> 0.658), with TE hit@top-12 dropping -8pp (62% -> 54%) despite TE curves / ramp / config block being untouched in v1.6.4 (suspected P13 / VOS cascade from QB-side positional priors shifting). WR untouched (curves not modified). RB MAE +0.14 worse, bias slightly improved. Diagnosis: the smoothed QB curve lifted peak-age values (27: 0.880->0.97, 28: 0.935->0.99), which are the ages most QB-seasons sit in across the walk-forward cohort, so cohort-aggregate projection went UP and over-projection bias got WORSE. The rookie ramp change (rookie_development_ramp.QB = [0.50, 0.70, 0.85, 1.0]) was the surgical lever that actually flipped the Maye / Mendoza / Simpson rookie inversion -- hand-calc confirmed Mendoza year-0 multiplier 0.88->0.50 = -43% year-0 PPG hit did the bulk of the LTV drop. v1.6.5 restores REBUILT_QB_CURVE in age_curves_rebuilt.py to the original trim-25% values and KEEPS rookie_development_ramp.QB at [0.50, 0.70, 0.85, 1.0]. Predicted result: Maye lands QB5-7 (smaller relative gap to Mendoza than v1.6.4 showed, but inversion still flipped vs v1.6.3 baseline). v1.6.4 entry marked superseded_by=v1.6.5 for audit trail; not deleted. Methodology note: this ship violated the AB-harness-before-wire-in gating rule formalized 2026-05-11 -- the one-player smoke check on Maye placement was not a population-level accuracy validation. Rule re-affirmed: any age curve / ramp / projection-parameter change MUST run through walk_forward_backtest before wire-in.

v1.6.4

2026-05-11

Session 92 rookie ranking inversion fix. Two related changes addressing Drake Maye / Mendoza / Simpson QB ranking inversion: (1) QB age curve smoothing in age_curves_rebuilt.py REBUILT_QB_CURVE. Pre-smooth values had 4 monotonicity violations (22>23, 26>27, 32<33, and 36->37->38->39 ascending from 0.771 to 0.951 — survivor-bias inversion implying a 39-year-old QB produces 95% of peak). Smoothed values enforce strict monotonicity ascending 22->29 and descending 30->41, with late-career magnitudes aligned to CLAUDE.md framework ("Decline gradual; effectively done Late 30s"). Concretely: 23: 0.773->0.84, 27: 0.880->0.97, 32: 0.894->0.93, 36: 0.771->0.68, 38: 0.933->0.46, 39: 0.951->0.32, 40: 0.848->0.20. (2) Rookie development ramp for QB steepened from [0.88, 0.94, 1.0] to [0.50, 0.70, 0.85, 1.0]. Old ramp projected a #1-pick QB at 17-18 ppg in year 1, ~equal to a 2nd-year vet's weighted_ppg. New ramp aligns year-0 projection with empirical year-1 outcomes (Mahomes was a backup year 1; Allen/Hurts/Lawrence/Burrow/Stroud/Daniels/Williams all had material year-1 growing pains). Combined effect on top-15 dynasty QB: Maye 24 lifts QB7->QB3; Mendoza 22 (#1 pick proj) drops QB2->QB5; Simpson 22 (#13 pick proj) drops QB6->QB14. Late-career QBs (Wilson 37, Rodgers 42, Cousins 38) drop out of top-25 entirely. RB/WR/TE curves untouched. Pending: walk-forward AB validation.

v1.6.3

2026-05-10

Sprint C bias_correction calibration shipped. Per-position bias_w (actual - weighted_ppg) measured on 2021-2023 multi-year backtest post-Pattern-13b-flip and post-12-age-curve-tweaks. All four positions show direction-consistent bias across all 3 ref years. Applied with 0.30 conservative blend (matches accuracy_review.blend_factor). QB: 0.0 -> +0.62 (was systematically under). RB: 0.0 -> -0.54 (was systematically over — likely committee volume discount under-corrects). WR: 0.0 -> -0.12 (small over). TE: 0.0 -> -0.03 (basically calibrated; shipped as documentation). Affects projected_season_ppg column only — dynasty_ppg / ltv_discounted unchanged. Dynasty-layer over-discount on RB/WR/TE (separate concern: dynasty_ppg under-projects despite weighted_ppg being calibrated/over) tracked as follow-up task.

v1.6.2

2026-05-10

Sprint C consensus age-curve tweaks applied (12 ages across RB/WR/TE). All 12 ages flagged as 'too_pessimistic' by 3/3 reference years 2021-2023 in the multi-year backtest run on 2026-05-09. RB ages 25/29/31, WR ages 25/33/34, TE ages 26/27/30/32/33/34. Updates use the standard blend_factor=0.30 conservative weight from the existing accuracy_review pipeline. QB had 0 consensus signals; QB calibration deferred to a post-Pattern-13b-flip re-run.

v1.7.0

2026-05-09

Pattern 13b/c flip ON. qb_use_v2_ltv: false -> true after ab_harness validation on 2021-2024 snapshots. Verdict SHIP: 3/4 seasons pass kill criterion (dMAE <= -0.10). 2022: -0.80, 2023: -0.51, 2024: -0.47, 2021: +0.40 (single regression dominated by 3 wins). Net win directly attacks the QB +2.18 bias_w from Sprint C 2015-2024 backtest. Session 77 _apply_young_qb_ceiling guard prevents the double-boost interaction with young_qb_ceiling that originally rejected Pattern 13b on 2026-05-05. v2 path uses age_curves_v2.dynasty_lifetime_value_v2 (relative-factor formula) for QB position only; other positions still use v1 absolute or te_use_v2_ltv path.

future_pick_discount_market_align_2026-05-09

lasso_residual_te_2026-05-09

future_pick_discount_2026-05-09

lift_signals_round3_2026-05-09

lift_signals_round2_2026-05-09

lift_signals_enabled_2026-05-09

v1.6.1

2026-05-02

v1.5.1

2026-04-28

Task #28: added edge_score block for Personalized Edge Score

v1.4.9

2026-04-26

Redraft improvement wave: (1) Age curve rates doubled based on LOO backtest evidence. (2) QB starter-upgrade detection block added. (3) Opportunity blend config block added.

v1.4.8

2026-04-26

Per-position recency weight optimization (S-3). 6 weight changes. Scores: QB=0.3425, RB=0.4340, WR=0.4466, TE=0.4463.

v1.4.7

2026-04-26

Redraft Monte Carlo optimization (S-2) — format: standard. 7 parameter changes. Best composite score: 0.4139.

v1.4.6

2026-04-26

Per-position recency weight optimization (S-3). 12 weight changes. Scores: QB=0.3363, RB=0.4305, WR=0.4626, TE=0.4669.

v1.4.5

2026-04-26

Redraft Monte Carlo optimization (S-2) — format: full_ppr_te_premium. 6 parameter changes. Best composite score: 0.4199.

v1.4.4

2026-04-26

Per-position recency weight optimization (S-3). 6 weight changes. Scores: QB=0.3401, RB=0.4322, WR=0.4568, TE=0.4594.

v1.4.3

2026-04-26

Redraft Monte Carlo optimization (S-2) — format: half_ppr. 7 parameter changes. Best composite score: 0.4181.

v1.4.2

2026-04-26

Per-position recency weight optimization (S-3). 12 weight changes. Scores: QB=0.3403, RB=0.4305, WR=0.4626, TE=0.4649.

v1.4.1

2026-04-26

Redraft Monte Carlo optimization (S-2) — format: full_ppr. 7 parameter changes. Best composite score: 0.4205.

v1.4.0

2026-04-26

Per-format parameter architecture. Format-sensitive redraft params (recency_weights, td_regression, shrinkage, position_recency_weights) moved under redraft.formats.{format_key}. Engine resolves format from LeagueConfig.scoring_format at runtime. half_ppr_te_premium is fully optimized (v1.3.5); other formats seeded and pending MC runs.

v1.3.5

2026-04-25

Per-position recency weight optimization (S-3). 12 weight changes. Scores: QB=0.3397, RB=0.4324, WR=0.4568, TE=0.4653.

v1.3.1

2026-04-25

Redraft Monte Carlo optimization (S-2). 7 parameter changes. Best composite score: 0.4196.

v1.3.0

2026-04-25

v1.2.5

2026-04-25

v1.2.2

2026-04-25

YoY production delta as trajectory momentum signal for RB and WR. production_delta = ppg_most_recent_full_season - ppg_prior_full_season computed in weighted_ppg_for_player() (metrics.py) from full_records sorted by season desc. Exposed as production_delta column in enrich_production_metrics(). New _apply_trajectory_momentum_bonus() method in rankings_engine.py — parallel to _apply_young_qb_ceiling(), applied immediately after. Eligible: RB and WR, ascending/early_peak trajectory, ≥4.0 weighted_ppg, ≥2 full seasons. Ascending (delta ≥ +1.5 ppg): bonus_pct = delta × 0.012, capped at +18% dynasty_ppg. Falling (delta ≤ -1.5 ppg): penalty_pct = |delta| × 0.008, capped at -12% dynasty_ppg. Config-driven in trajectory_momentum block. momentum_bonus_applied column added for accuracy_review tracking.

v1.2.3

2026-04-25

Per-player LTV uncertainty bands (P25/P75/CV). compute_player_ltv_bands() added to monte_carlo.py — multiplicative noise model: production_factor × availability_factor × age_curve_factor, each drawn from a clamped Gaussian. 1000 simulations per player, pure NumPy (no engine re-run). Production sigma scales with seasons_included (1 season: 0.28, 4+: 0.08). Injury sigma scales with injury_risk tier (low_risk: 0.04, high_risk: 0.18). Age curve sigma fixed at 0.08 (population mean has ~8% individual stdev). CV = (P75-P25)/median — risk metric. risk_profile: safe_floor (CV<0.15), balanced (0.15-0.28), boom_bust (CV≥0.28). ltv_p25/ltv_p75/ltv_cv/risk_profile added to all rankings output rows. Trade analyzer: risk_profile surfaces in _player_summary() and _build_narrative() flags mismatched risk profiles between trade sides. Config-driven in player_ltv_bands block.

v1.2.4

2026-04-25

Position-specific recency weights. Bug fix: global recency_weights from engine_config.json were NOT flowing to weighted_ppg_for_player() in metrics.py — hardcoded module constant (3.0/2.0/1.0) was used instead of Monte Carlo-optimized values (2.966/0.9/0.279). Fixed by threading recency_weights param through weighted_ppg_for_player() -> enrich_production_metrics() -> build_player_rankings_base() -> _build_base() in rankings_engine.py. position_recency_weights added to engine_config.json: RB (4.5/0.65/0.15 — heavy current-season, least autocorrelated), QB (2.2/1.3/0.60 — flatter, most autocorrelated), WR (3.5/0.85/0.22 — moderate), TE (2.6/1.1/0.40 — sticky once established). Per-position override picked in enrich_production_metrics() before calling weighted_ppg_for_player(). Falls back to global weights if position absent. ModelParameters.position_recency_weights loaded from config. Pre-backtest calibration — accuracy_review.py will refine annually.

v1.2.1

2026-04-25

College school quality multiplier in rookie_model. Dominator rating at Alabama (P4_strong, ×1.0) ≠ NDSU (FCS, ×0.78). 5-tier system: P4_strong (1.0), P4_avg (0.95), G5 (0.87), FCS (0.78), unrated (0.90, default). Multiplier applied to raw college production stats BEFORE baseline subtraction in project_peak_ppg() — so a 35% target share at FCS becomes effectively 27.3% before the 20% baseline is subtracted, compressing the contribution from 15pp to 7.3pp. Applies to: college_target_share, college_rush_share, college_completion_pct, college_pass_ypa. Config-driven in rookie_model.school_quality. School lookup is case-insensitive; handles nflverse abbreviated formats (Penn St., Ohio St., North Dakota St.). school_name parameter added to project_peak_ppg(); get_rookie_rows() passes p.get('school'). school_quality_mult and school_quality_tier exposed in output rows.

v1.1.8

2026-04-24

Bayesian shrinkage on weighted_ppg for thin-sample players. Formula: w = n/(n+k), shrunk_ppg = w*player_ppg + (1-w)*position_prior. k=3.0, min_seasons_no_shrink=4. Prior = mean weighted_ppg of above-replacement players at each position. Only applied to above-replacement players (below-replacement are not shrunk toward starter mean). Rookies (seasons_included=0 or is_rookie=True) are always skipped. Key corrections: McCaffrey 21.4->16.3 (1 qualifying season / injury history), Daniels 20.9->19.0, Nabers 14.6->11.4, Bowers 15.0->13.0, Gibbs 18.5->14.9. 81 above-replacement players affected out of 825. Mean delta: +0.32 ppg. raw_weighted_ppg column preserved for transparency.

v1.1.9

2026-04-24

Rookie development ramp in LTV calculation. Adds per-year additional multipliers applied ON TOP OF the age curve factor for is_rookie=True rows in dynasty_lifetime_value(). Corrects survivor bias: age-21 WR factor (0.72) was derived from all 21-year-olds including experienced ones; true year-1 rookies produce ~55-65% of career peak (implied factor ~0.61), not 72%. Ramps: WR [0.85, 0.92, 1.0], TE [0.80, 0.88, 0.95, 1.0], RB [0.92, 0.97, 1.0], QB [0.88, 0.94, 1.0]. Config-driven in rookie_development_ramp block. Implementation: _load_development_ramps() in age_curves.py; dynasty_lifetime_value() accepts development_ramp parameter; _ltv_row() in enrich_age_curves() detects is_rookie and passes position ramp. No effect on non-rookie players.

v1.2.0

2026-04-25

Injury type granularity: structural ceiling discount applied to weighted_ppg BEFORE LTV calculation. Distinct from existing injury_discount (post-LTV availability factor). Structural injuries (seasons with <5 games = ACL proxy) now permanently bend the peak ceiling, propagating through the full 7-season LTV projection. New InjuryProfile fields: structural_ceiling_factor, n_structural_injuries, healthy_seasons_since_structural. Formula: base_ceiling[pos] - age_penalty(age_at_injury - cliff_age) + recovery_credit(healthy_seasons_since) × compound_multiplier^(n_structural-1). Config block: injury_model.structural_injury in engine_config.json. Pipeline: rankings_engine._apply_structural_ceiling() runs after rookie injection, before enrich_age_curves(). Availability discount (injury_model.alpha/floor) unchanged and still applied post-LTV.

v1.1.7

2026-04-24

Rookie model: 3-fix calibration. Fix 1 — base_ceiling raised via bias calibration against 2019-2023 classes (n=284): QB 12.0→16.09 (+34%), RB 11.0→13.66 (+24%), WR 10.0→11.94 (+19%), TE 8.0→7.63 (-5%). Fix 2 — elite athleticism breakout multiplier: SS≥elite_threshold +15-20%, SS≥mod_threshold +7-10%, applied pre-pick_factor; TE thresholds raised to 116/110 (vs 110/105) to avoid over-projection. Fix 3 — QB draft round starter bonus: R1 +7.0, R2 +3.5, R3 +1.5 ppg (pre-mult additive). All breakout/starter-bonus thresholds now config-driven in engine_config.json rookie_model block.

v1.1.6

2026-04-21

Superflex QB dynasty corrections. (1) young_qb_ceiling.min_weighted_ppg: 10.0 → 4.0 — was blocking ascending QBs with limited samples (Maye 7.49, Williams 8.24, Stroud 8.11). (2) young_qb_ceiling.bonus_per_year_to_peak: 0.0362 → 0.18 — previous value produced ~11% max bonus for a 23yo QB; new value produces ~30-55% for ascending QBs 3 years from peak. (3) young_qb_ceiling.cap: 1.1 → 1.55 — allows meaningful upside for franchise QBs with thin sample. (4) superflex_qb_dynasty_premium multiplier: 1.12 — applies to all QB dynasty_ppg in superflex dynasty leagues to reflect structural scarcity (20 starter slots vs ~16 reliable starters). Known remaining issue: 30-32yo QBs (Mayfield, Goff, Murray) still overranked relative to PP due to flat QB age curve 31-34 in engine_config; will partially self-correct with 2025 data load. (5) young_qb_ceiling.archetypes_eligible: added dual_threat — Maye and Williams were miscategorized as dual_threat based on rookie scrambling stats, blocking their ceiling bonus. Trajectory filter (ascending/early_peak) already prevents veteran dual-threat QBs like Jackson from qualifying. (6) young_qb_ceiling.trajectories_eligible: [ascending, early_peak] → [ascending] only. early_peak included established starters (Daniels 25.7, Purdy 26.7, Nix 26.5) who were being over-boosted. Developmental ceiling bonus should only apply to true ascending QBs with thin samples.

v1.1.5

2026-04-21

Reference season advanced to 2025 after full 2025 season data loaded via Sleeper fetch. Recency weight index 0 now maps to 2025. Former-starter discount now correctly identifies QBs who backed up in 2025. ACTIVE_THRESHOLD unchanged at 2024 (broad pool). Backtest re-run and Monte Carlo optimization pending.

v1.1.4

2026-04-20

Monte Carlo optimization (S-1). 32 parameter changes. Best composite score: 0.4029.

v1.1.3

2026-04-20

Multi-year backtest parameter update (20 reference years). 35 parameter changes applied.

v1.1.2

2026-04-19

Multi-year backtest parameter update (reference years: 2019/2020/2021). 20 parameter changes applied.

v1.1.1

2026-04-19

Multi-year backtest parameter update (reference years: 2019/2020/2021). 17 parameter changes applied.

v1.1.0

2026-04-19

Backtest-driven corrections using 2019 reference year (2015–2019 training, 2020–2024 evaluation, n=320 players). Four targeted fixes: (1) RB age curve recalibrated at ages 26–33 — original cliff was too steep, causing systematic -1.9 to -3.8 ppg underranking of 26–30 year old RBs; ages 26/27/28/29 factors raised from 0.94/0.83/0.70/0.55 to 0.97/0.92/0.84/0.72. (2) RB peak window extended from [22,26] to [22,28] — data shows productive prime runs through age 28. (3) QB pocket_passer post_peak_modifier raised from 1.10 to 1.15 — veteran pocket QBs (Brady, Brees, Rodgers, Roethlisberger) were underranked because age cliff was too aggressive after 35; base QB curve also flattened at 36–39. (4) confidence_flags.age_uncertainty_rb_over lowered from 28 to 27 — flagging uncertainty one year earlier to match actual production cliff. Overall backtest: r=0.769 overall, RB bias improved by recalibration. WR model was most accurate (r=0.754, bias +0.18). QB had highest variance (stdev 4.92) driven by backup QBs with inflated starter-season wPPG.

Accuracy review
reference_year2019
training_years2015-2019
evaluation_years2020-2024
n_players320
overall_r0.769
overall_mae2.27
overall_bias-0.43
tier_exact_hit_rate0.375
tier_within_1_hit_rate0.803
PositionnrbiasMAE
QB460.491-0.43.59
RB870.732-1.212.52
WR1210.7540.181.89
TE660.697-0.561.7

v1.0.0

2026-04-18

Initial parameters. Baseline from POC build. All values theory-grounded, not yet back-tested against actual outcomes. Includes: young_qb_ceiling block (ascending pocket QB bonus), trade_model block (trade analyzer constants).