From 288e1961755419848369df2e631b906f2093cfb4 Mon Sep 17 00:00:00 2001
From: christopher harris <283105756+cjharriskc-ai@users.noreply.github.com>
Date: Sat, 18 Jul 2026 02:45:02 -0500
Subject: [PATCH 1/2] Launch autonomous universal sports engine
---
.gitattributes | 5 +
.github/PULL_REQUEST_TEMPLATE.md | 32 +
.gitignore | 18 +
AGENTS.md | 10 +
ARCHITECTURE.md | 64 +
AUTONOMOUS_IMPROVEMENT.md | 80 +
AUTONOMY_CONFIG.json | 22 +
DATA_RIGHTS_AND_PROVENANCE.md | 22 +
DOMAIN_NEUTRAL_ADAPTATION_READINESS.md | 12 +
DOMAIN_NEUTRAL_KERNEL_SPEC.md | 22 +
KNOWN_LIMITATIONS.md | 22 +
LICENSE | 21 +
PRIOR_ART_REGISTRY.md | 35 +
QUALITY_GATES.yaml | 61 +
README.md | 176 ++
RESEARCH_CONSTITUTION.md | 12 +
STATUS.md | 53 +
TECHNOLOGY_BAKEOFF.md | 31 +
data/contracts/HISTORICAL_GAMES.md | 24 +
dummy_bridge/DOMAIN_NEUTRAL_PROTOCOL.md | 20 +
pyproject.toml | 38 +
reports/AUTONOMOUS_RECURSIVE_UPGRADE_V3.md | 105 +
reports/AUTONOMY_AUDIT_V3.json | 191 ++
reports/NEGATIVE_CONTROL_REPORT.json | 247 ++
reports/PERFORMANCE_AUDIT_V3_FINAL.json | 261 ++
reports/PERFORMANCE_BENCHMARK.json | 135 +
reports/RELEASE_EVIDENCE.md | 63 +
reports/RELEASE_MANIFEST.json | 260 ++
reports/REPRODUCTION_REPORT.md | 37 +
reports/STRESS_AUDIT_V3.json | 58 +
reports/VALIDATION_REPORT.json | 107 +
.../autonomy_v3_fixture/champion_bundle.json | 937 ++++++
.../improvement_ledger.jsonl | 7 +
.../improvement_report.json | 2652 +++++++++++++++++
.../shadow_adapted_bundle.json | 937 ++++++
scripts/audit_autonomy.py | 196 ++
scripts/audit_performance.py | 101 +
scripts/audit_stress.py | 57 +
scripts/build_release_evidence.py | 224 ++
src/universal_sports_engine/__init__.py | 29 +
src/universal_sports_engine/accuracy.py | 283 ++
src/universal_sports_engine/adaptive.py | 927 ++++++
src/universal_sports_engine/analytical.py | 212 ++
src/universal_sports_engine/autotune.py | 1036 +++++++
src/universal_sports_engine/cli.py | 297 ++
src/universal_sports_engine/core/__init__.py | 1 +
src/universal_sports_engine/core/event_log.py | 158 +
src/universal_sports_engine/core/fidelity.py | 71 +
src/universal_sports_engine/core/replay_io.py | 79 +
.../core/result_integrity.py | 61 +
src/universal_sports_engine/core/rng.py | 45 +
src/universal_sports_engine/core/rules.py | 41 +
src/universal_sports_engine/core/types.py | 114 +
.../dummy_bridge/__init__.py | 1 +
.../dummy_bridge/contracts.py | 92 +
.../league_packs/__init__.py | 1 +
.../league_packs/baseball.py | 173 ++
.../league_packs/basketball.py | 178 ++
.../league_packs/common.py | 121 +
.../league_packs/football.py | 151 +
.../league_packs/hockey.py | 81 +
.../league_packs/registry.py | 45 +
.../league_packs/rule_packs.py | 165 +
src/universal_sports_engine/reference.py | 26 +
src/universal_sports_engine/season.py | 197 ++
src/universal_sports_engine/simulation.py | 92 +
src/universal_sports_engine/validation.py | 147 +
tests/test_accuracy.py | 72 +
tests/test_analytical.py | 31 +
tests/test_cli.py | 184 ++
tests/test_core.py | 138 +
tests/test_dummy_bridge.py | 17 +
tests/test_leagues.py | 64 +
tests/test_recursive_improvement.py | 183 ++
tests/test_season.py | 42 +
tests/test_validation.py | 16 +
76 files changed, 12926 insertions(+)
create mode 100644 .gitattributes
create mode 100644 .github/PULL_REQUEST_TEMPLATE.md
create mode 100644 .gitignore
create mode 100644 AGENTS.md
create mode 100644 ARCHITECTURE.md
create mode 100644 AUTONOMOUS_IMPROVEMENT.md
create mode 100644 AUTONOMY_CONFIG.json
create mode 100644 DATA_RIGHTS_AND_PROVENANCE.md
create mode 100644 DOMAIN_NEUTRAL_ADAPTATION_READINESS.md
create mode 100644 DOMAIN_NEUTRAL_KERNEL_SPEC.md
create mode 100644 KNOWN_LIMITATIONS.md
create mode 100644 LICENSE
create mode 100644 PRIOR_ART_REGISTRY.md
create mode 100644 QUALITY_GATES.yaml
create mode 100644 README.md
create mode 100644 RESEARCH_CONSTITUTION.md
create mode 100644 STATUS.md
create mode 100644 TECHNOLOGY_BAKEOFF.md
create mode 100644 data/contracts/HISTORICAL_GAMES.md
create mode 100644 dummy_bridge/DOMAIN_NEUTRAL_PROTOCOL.md
create mode 100644 pyproject.toml
create mode 100644 reports/AUTONOMOUS_RECURSIVE_UPGRADE_V3.md
create mode 100644 reports/AUTONOMY_AUDIT_V3.json
create mode 100644 reports/NEGATIVE_CONTROL_REPORT.json
create mode 100644 reports/PERFORMANCE_AUDIT_V3_FINAL.json
create mode 100644 reports/PERFORMANCE_BENCHMARK.json
create mode 100644 reports/RELEASE_EVIDENCE.md
create mode 100644 reports/RELEASE_MANIFEST.json
create mode 100644 reports/REPRODUCTION_REPORT.md
create mode 100644 reports/STRESS_AUDIT_V3.json
create mode 100644 reports/VALIDATION_REPORT.json
create mode 100644 reports/autonomy_v3_fixture/champion_bundle.json
create mode 100644 reports/autonomy_v3_fixture/improvement_ledger.jsonl
create mode 100644 reports/autonomy_v3_fixture/improvement_report.json
create mode 100644 reports/autonomy_v3_fixture/shadow_adapted_bundle.json
create mode 100644 scripts/audit_autonomy.py
create mode 100644 scripts/audit_performance.py
create mode 100644 scripts/audit_stress.py
create mode 100644 scripts/build_release_evidence.py
create mode 100644 src/universal_sports_engine/__init__.py
create mode 100644 src/universal_sports_engine/accuracy.py
create mode 100644 src/universal_sports_engine/adaptive.py
create mode 100644 src/universal_sports_engine/analytical.py
create mode 100644 src/universal_sports_engine/autotune.py
create mode 100644 src/universal_sports_engine/cli.py
create mode 100644 src/universal_sports_engine/core/__init__.py
create mode 100644 src/universal_sports_engine/core/event_log.py
create mode 100644 src/universal_sports_engine/core/fidelity.py
create mode 100644 src/universal_sports_engine/core/replay_io.py
create mode 100644 src/universal_sports_engine/core/result_integrity.py
create mode 100644 src/universal_sports_engine/core/rng.py
create mode 100644 src/universal_sports_engine/core/rules.py
create mode 100644 src/universal_sports_engine/core/types.py
create mode 100644 src/universal_sports_engine/dummy_bridge/__init__.py
create mode 100644 src/universal_sports_engine/dummy_bridge/contracts.py
create mode 100644 src/universal_sports_engine/league_packs/__init__.py
create mode 100644 src/universal_sports_engine/league_packs/baseball.py
create mode 100644 src/universal_sports_engine/league_packs/basketball.py
create mode 100644 src/universal_sports_engine/league_packs/common.py
create mode 100644 src/universal_sports_engine/league_packs/football.py
create mode 100644 src/universal_sports_engine/league_packs/hockey.py
create mode 100644 src/universal_sports_engine/league_packs/registry.py
create mode 100644 src/universal_sports_engine/league_packs/rule_packs.py
create mode 100644 src/universal_sports_engine/reference.py
create mode 100644 src/universal_sports_engine/season.py
create mode 100644 src/universal_sports_engine/simulation.py
create mode 100644 src/universal_sports_engine/validation.py
create mode 100644 tests/test_accuracy.py
create mode 100644 tests/test_analytical.py
create mode 100644 tests/test_cli.py
create mode 100644 tests/test_core.py
create mode 100644 tests/test_dummy_bridge.py
create mode 100644 tests/test_leagues.py
create mode 100644 tests/test_recursive_improvement.py
create mode 100644 tests/test_season.py
create mode 100644 tests/test_validation.py
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..fea410f
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,5 @@
+* text=auto eol=lf
+
+*.bat text eol=crlf
+*.cmd text eol=crlf
+*.ps1 text eol=crlf
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000..12de968
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,32 @@
+## What this delivers
+
+Launches Universal Sports Engine 0.3.0: a deterministic, high-throughput,
+multi-league simulation platform with exact replay, bounded recursive calibration,
+online expert weighting, drift-aware shadow monitoring, and content-addressed
+champion governance.
+
+## Why it matters
+
+- Unifies MLB, NBA, WNBA, NCAA MBB, NFL, NCAA Football, and NHL behind a neutral kernel.
+- Preserves sport-specific rules and mechanics in isolated league packs.
+- Separates fast analytical distributions from interpretable event simulation.
+- Makes every autonomous promotion, rejection, weight update, and rollback auditable.
+- Fails closed when integrity, calibration, drift, or reproducibility gates fail.
+
+## Verified evidence
+
+- [ ] Ruff passes.
+- [ ] Strict MyPy passes.
+- [ ] All 67 integration and invariant tests pass.
+- [ ] Release evidence gates pass across all seven leagues.
+- [ ] The 49-control negative and mechanism suite reports zero failures.
+- [ ] The 14,000-game stress audit reports zero failures.
+- [ ] The autonomy audit verifies champion, ledger, shadow-update, and rollback integrity.
+- [ ] A clean wheel rebuild reproduces the expected package contents.
+
+## Evidence boundary
+
+This release verifies mechanics, determinism, replay integrity, autonomy governance,
+and measured local throughput. It does not claim real-world predictive supremacy.
+That requires licensed point-in-time game, roster, injury, event, and tracking data
+plus held-out and prospective validation.
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..077d4a5
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,18 @@
+.venv/
+.repro-venv/
+.repro-v3-venv/
+__pycache__/
+.pytest_cache/
+.ruff_cache/
+.mypy_cache/
+*.egg-info/
+build/
+dist/
+reports/archive/
+reports/COPY_PROOF.json
+reports/HANDOFF_PROOF.json
+reports/COMPREHENSIVE_AUDIT_V2.md
+reports/PERFORMANCE_AUDIT_V2.json
+reports/PERFORMANCE_AUDIT_V3.json
+reports/RECOVERY_AND_COMPLETION_REPORT.md
+reports/STRESS_AUDIT_V2.json
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 0000000..d813013
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,10 @@
+# Universal Sports Engine Rules
+
+- Keep the simulation truth independent from rendering.
+- Preserve deterministic replay: identical versions, inputs, and seed must produce identical events.
+- Keep sport semantics in league packs; the core API must remain domain-neutral.
+- Fail explicitly on invalid state, unknown league IDs, corrupted event chains, and invalid rules.
+- Do not claim real-world calibration from synthetic fixtures or reference anchors.
+- Do not add wagering, sportsbook, brokerage, or live-capital behavior.
+- Keep changes typed, functional, minimal, and covered by integration or replay tests.
+- Never weaken a quality gate because a candidate or league pack fails it.
diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md
new file mode 100644
index 0000000..ac83dce
--- /dev/null
+++ b/ARCHITECTURE.md
@@ -0,0 +1,64 @@
+# Architecture
+
+## Decision
+
+The kernel uses immutable event drafts and a content-addressed event log as the
+source of truth, pure reducers for replay, fixed phase ordering, and label-addressed random draws. This
+combines the strongest parts of the two architectures recovered from the stalled
+Kimi build:
+
+1. Event-sourced state plus hierarchical domain state.
+2. Explicit `PERCEIVE -> DECIDE -> ARBITRATE -> RESOLVE -> APPLY -> PUBLISH` phases.
+3. Independent random namespaces and common-random-number counterfactuals.
+4. Game-granularity parallelism; a single game timeline remains deterministic.
+5. A result-envelope hash that commits to league, final score, seed, event chain,
+ and evidence metadata.
+
+## Layers
+
+```text
+CLI / SDK / domain-neutral bridge
+ |
+Champion governance, recursive calibration, adaptive weights, drift quarantine
+ |
+F0/F1 routing, batch, historical evaluation, counterfactuals
+ |
+League packs and sport-family resolvers
+ |
+Domain-neutral event log, state, rules, RNG, replay
+```
+
+League packs own scoring, timing, possession/inning/drive/shift semantics, and
+reference anchors. The kernel contains no player, ball, puck, inning, possession,
+or scoreboard type.
+
+## Fidelity
+
+- F0: analytical/batch score distribution (implemented; no event path).
+- F1: event-level paths (implemented for every league).
+- F2: spatial-agent contracts and escalation interface (API complete; no tracking calibration).
+- F3: rendering/physics adapter boundary (not implemented without tracking/physics evidence).
+
+The fidelity router selects the lowest evidence-supported fidelity and rejects
+unsupported F2/F3 requests. It never uses visual
+plausibility as a substitute for held-out calibration.
+
+## Integrity and performance
+
+League packs accumulate immutable drafts locally and content-address them once in
+linear time. External replay import recomputes the event chain and result envelope.
+The RNG maps semantic labels directly to BLAKE2b uniform draws, so unrelated model
+changes do not perturb other random namespaces.
+
+## Recursive model governance
+
+The adaptive layer is outside the neutral kernel. Profiles, expert mixtures,
+online calibration state, champion bundles, and decision ledgers are immutable
+and content-addressed. Search may mutate only bounded analytical parameters.
+Promotion is decided on chronological calibration forecasts made before each
+outcome is revealed. Test data, rule packs, evaluators, and quality gates are not
+mutable search inputs.
+
+Online shadow adaptation changes expert weights and interval scale, while two
+loss EWMAs monitor drift. Drifted checkpoints remain auditable but are rejected
+by adaptive simulation until a healthy successor or rollback is selected.
diff --git a/AUTONOMOUS_IMPROVEMENT.md b/AUTONOMOUS_IMPROVEMENT.md
new file mode 100644
index 0000000..5254d8b
--- /dev/null
+++ b/AUTONOMOUS_IMPROVEMENT.md
@@ -0,0 +1,80 @@
+# Autonomous recursive improvement
+
+Version 0.3 adds a bounded model-improvement system around the deterministic
+simulation kernel. It changes analytical model parameters and ensemble weights;
+it cannot edit source code, official rule packs, historical outcomes, split
+boundaries, evaluators, promotion gates, or live-action interfaces.
+
+## Evidence loop
+
+```text
+point-in-time train block
+ -> deterministic population search
+ -> diverse bounded expert pool
+ -> chronological calibration predictions
+ -> outcome revealed once
+ -> expert weights and interval scale updated
+ -> challenger compared with incumbent
+ -> promote or retain
+ -> content-addressed checkpoint and chained ledger
+ -> shadow outcomes update weights and drift state
+ -> healthy, quarantine, recalibrate, or roll back
+```
+
+Training outcomes select bounded score-model parameters. Calibration outcomes
+are consumed prequentially: the ensemble predicts first, then receives the
+outcome exactly once. Test outcomes are excluded from tuning and promotion.
+Shadow outcomes may update an already selected champion but cannot rewrite its
+lineage or erase prior decisions.
+
+## Adjustable state
+
+Each expert contains league-specific home and away score locations, total and
+margin dispersion, and strength-response exponents. Recursive search uses
+deterministic log-space mutations, retains a diverse elite set, and reduces the
+mutation radius by generation.
+
+The selected ensemble applies multiplicative expert weighting using joint score
+likelihood and home-win Brier loss. A separate online calibration state adjusts
+the 90% interval radius. Short- and long-horizon loss estimates produce a drift
+score. A drift alert blocks adaptive simulation until a new governed checkpoint
+or explicit rollback is selected.
+
+## Promotion gates
+
+A challenger must satisfy every preregistered requirement in
+`AUTONOMY_CONFIG.json`:
+
+- minimum composite-loss improvement;
+- no excessive Brier deterioration;
+- no excessive interval-coverage deterioration;
+- finite scores and normalized non-negative weights;
+- healthy calibration state;
+- sufficient non-overlapping train and calibration evidence;
+- valid profile, ensemble, adaptive-state, bundle, and ledger hashes.
+
+Synthetic fixtures can validate learning mechanics but can never certify
+real-world accuracy. Real promotion claims require licensed point-in-time data
+and an untouched test audit after the champion is frozen.
+
+## Commands
+
+```powershell
+.\.venv\Scripts\sports-engine.exe auto-improve `
+ --csv data\point-in-time\historical.csv `
+ --config AUTONOMY_CONFIG.json `
+ --output reports\improvement-run-001
+
+.\.venv\Scripts\sports-engine.exe simulate-adaptive `
+ --bundle reports\improvement-run-001\champion_bundle.json `
+ --league nba --seed 42 --home-strength 1.0 --away-strength 1.0
+
+.\.venv\Scripts\sports-engine.exe adapt-online `
+ --csv data\point-in-time\shadow.csv `
+ --config AUTONOMY_CONFIG.json `
+ --bundle reports\improvement-run-001\champion_bundle.json `
+ --league nba --output reports\nba-shadow-checkpoint-001.json
+```
+
+Output paths are fail-closed: existing improvement artifacts and adaptive
+checkpoints are not overwritten.
diff --git a/AUTONOMY_CONFIG.json b/AUTONOMY_CONFIG.json
new file mode 100644
index 0000000..65b84e3
--- /dev/null
+++ b/AUTONOMY_CONFIG.json
@@ -0,0 +1,22 @@
+{
+ "brier_weight": 2.0,
+ "coverage_weight": 2.0,
+ "drift_threshold": 0.12,
+ "elite_count": 6,
+ "experts_per_ensemble": 6,
+ "generations": 8,
+ "interval_learning_rate": 0.04,
+ "long_decay": 0.03,
+ "maximum_brier_deterioration": 0.01,
+ "maximum_coverage_error_deterioration": 0.03,
+ "minimum_calibration_games": 50,
+ "minimum_drift_observations": 40,
+ "minimum_relative_improvement": 0.01,
+ "minimum_train_games": 100,
+ "mutation_scale": 0.12,
+ "online_learning_rate": 0.25,
+ "population_size": 32,
+ "seed": 20260718,
+ "short_decay": 0.20,
+ "target_coverage": 0.90
+}
diff --git a/DATA_RIGHTS_AND_PROVENANCE.md b/DATA_RIGHTS_AND_PROVENANCE.md
new file mode 100644
index 0000000..7e45ca7
--- /dev/null
+++ b/DATA_RIGHTS_AND_PROVENANCE.md
@@ -0,0 +1,22 @@
+# Data Rights and Provenance
+
+## Local build inputs
+
+No licensed event feed, tracking feed, private injury feed, sportsbook feed, or
+proprietary roster database is present in this repository.
+
+The shipped engine uses:
+
+- deterministic synthetic events generated by the versioned league packs;
+- transparent league-level reference anchors for broad output sanity checks;
+- official rule-source links as provenance pointers for the minimal rule manifests.
+
+The reference anchors are approximate research fixtures. They are not an ingested,
+point-in-time dataset and are labeled `provisional_reference_anchor` everywhere.
+
+## Prohibited promotion
+
+These inputs cannot support a claim of held-out player, team, game, season, spatial,
+or counterfactual accuracy. Such claims require separately licensed data manifests,
+earliest-available timestamps, revisions, train/calibration/test boundaries, and
+independent reproduction.
diff --git a/DOMAIN_NEUTRAL_ADAPTATION_READINESS.md b/DOMAIN_NEUTRAL_ADAPTATION_READINESS.md
new file mode 100644
index 0000000..83c1dfd
--- /dev/null
+++ b/DOMAIN_NEUTRAL_ADAPTATION_READINESS.md
@@ -0,0 +1,12 @@
+# Domain-neutral adaptation readiness
+
+No external project was inspected, imported, or modified during this build.
+
+The reusable boundary consists only of immutable state, action, observation,
+scenario, counterfactual, uncertainty, fidelity, and evidence contracts. A future
+consumer must implement its own domain pack and validation program. Sports rule
+packs, reference anchors, league identities, and generated scores must not cross
+that boundary.
+
+Compatibility is demonstrated by the included non-sports inventory-control fixture.
+There is no live-action, capital, brokerage, sportsbook, or wagering adapter.
diff --git a/DOMAIN_NEUTRAL_KERNEL_SPEC.md b/DOMAIN_NEUTRAL_KERNEL_SPEC.md
new file mode 100644
index 0000000..01d604b
--- /dev/null
+++ b/DOMAIN_NEUTRAL_KERNEL_SPEC.md
@@ -0,0 +1,22 @@
+# Domain-neutral kernel specification
+
+The kernel owns only immutable events, world-state payloads, phase ordering,
+versioned rules, deterministic random draws, replay verification, fidelity routing,
+and evidence metadata. It contains no sports entities or timing assumptions.
+
+## Invariants
+
+- Sequence numbers are contiguous and zero-based.
+- Every event hash commits to its body and prior event hash.
+- Identical root seed and semantic labels produce the same draw.
+- An unavailable fidelity raises instead of silently returning a lower-fidelity answer.
+- A league pack must verify its event stream before publishing a result.
+- Portable replay import verifies the complete chain before returning a result.
+
+## Extension points
+
+- League pack: complete-game resolver and rule manifest.
+- Learned transition: replaces a league transition function without changing evidence contracts.
+- Spatial adapter: produces `SpatialState` values only after league-specific validation.
+- Physics adapter: remains independent of rendering and uses the same event sink.
+- Policy adapter: consumes observations and permitted actions, never omniscient state by default.
diff --git a/KNOWN_LIMITATIONS.md b/KNOWN_LIMITATIONS.md
new file mode 100644
index 0000000..9a25c40
--- /dev/null
+++ b/KNOWN_LIMITATIONS.md
@@ -0,0 +1,22 @@
+# Known Limitations
+
+- The stalled remote Kimi repository was not exported; this is an independent local reconstruction.
+- F1 event paths are calibrated only to broad reference anchors, not licensed held-out data.
+- Player identities, rosters, coaching policies, officials, injuries, fatigue, venues, and weather are contract surfaces rather than calibrated models.
+- F2 spatial trajectories and F3 physics/rendering are intentionally not fabricated without tracking evidence.
+- Rule manifests cover complete-game flow but are not a complete executable transcription of every official rulebook edge case.
+- Generic F1 games resolve a winner; competition-specific regular-season tie and
+ postseason context is not yet a first-class scenario input.
+- The analytical F0 model matches provisional aggregate moments but does not emit
+ sport-valid event sequences or prove game-level predictive skill.
+- Historical evaluation is implemented, but no licensed point-in-time test manifest
+ was supplied, so CRPS, Brier, and coverage results on real games remain unavailable.
+- Recursive tuning currently adjusts F0 analytical score distributions and ensemble
+ weights. It does not fabricate player, tracking, tactical, F2, or F3 calibration.
+- The bundled autonomy audit uses labeled synthetic fixtures solely to prove search,
+ weighting, gating, checkpoint, and replay mechanics. Its promotions are not
+ real-world champions.
+- Windows multi-process calls require an importable script or CLI entrypoint; an
+ interactive/stdin caller receives an explicit error and should use F0 or one worker.
+- Counterfactual pairing reduces simulation noise but does not by itself establish causality.
+- No live feed, wagering, sportsbook, trading, or capital interface exists.
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..db493a3
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2026 ObtuseAI
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/PRIOR_ART_REGISTRY.md b/PRIOR_ART_REGISTRY.md
new file mode 100644
index 0000000..3ec1c1c
--- /dev/null
+++ b/PRIOR_ART_REGISTRY.md
@@ -0,0 +1,35 @@
+# Prior-art registry
+
+The architecture was compared against public research interfaces rather than
+claiming novelty from naming alone.
+
+| System | Relevant capability | Retained lesson | This engine's actual distinction |
+|---|---|---|---|
+| Google Research Football | Physics-based multi-agent sports environment | Keep simulation separate from policy learning | Seven league packs share one event/evidence kernel; F2/F3 are not claimed without calibration |
+| OpenSpiel | Extensive-form, simultaneous-action, imperfect-information games | Preserve legal actions, histories, observations, and replaceable policies | Sports event logs are content-addressed and coupled to versioned rule manifests |
+| PettingZoo Parallel API | Standard simultaneous multi-agent stepping and conformance tests | Keep an adapter boundary for parallel agent research | The core remains dependency-free and uses explicit phase ordering for deterministic game truth |
+| EnvPool and Pgx research | Vectorized, accelerator-oriented environment execution | Treat throughput as measured adapter work | Current release parallelizes complete games with deterministic seed namespaces; no GPU speed claim is made |
+| Population Based Training | Joint model and hyperparameter population evolution | Preserve champion/challenger lineages and bounded exploit/explore cycles | Search is deterministic, parameter-bounded, data-split aware, and cannot mutate evaluator code |
+| Adaptive Conformal Inference | Coverage adaptation under distribution shift | Update interval calibration prospectively and monitor distribution change | A content-addressed state couples interval scaling with expert weights and fail-closed drift quarantine |
+| Prediction with expert advice | Sequential distribution aggregation and performance-based weights | Score before outcome reveal, then update expert weights | Joint score likelihood and Brier loss adjust an auditable league expert pool without erasing prior weights |
+| Optuna | Search/pruning framework design | Declare the search space and prune weak configurations | This dependency-free engine uses a small deterministic search surface tied directly to immutable simulator profiles |
+
+Primary references:
+
+- Google Research Football paper: https://arxiv.org/abs/1907.11180
+- OpenSpiel paper: https://arxiv.org/abs/1908.09453
+- PettingZoo Parallel API: https://pettingzoo.farama.org/api/parallel/
+- EnvPool paper: https://arxiv.org/abs/2206.10558
+- Pgx paper: https://arxiv.org/abs/2303.17503
+- Population Based Training: https://arxiv.org/abs/1711.09846
+- Adaptive Conformal Inference: https://arxiv.org/abs/2106.00170
+- Online aggregation of probabilistic forecasts: https://proceedings.mlr.press/v128/korotin20a/korotin20a.pdf
+- Optuna: https://arxiv.org/abs/1907.10902
+
+The defensible contribution through version 0.3.0 is the combination of portable
+hash-chained sports event paths, label-addressed randomness, seven isolated league
+packs, common-random-number counterfactuals, fail-closed evidence envelopes, and
+content-addressed recursive model governance.
+It is an engineering synthesis, not a claim to have invented event simulation,
+multi-agent environments, digital twins, population search, conformal adaptation,
+or expert weighting.
diff --git a/QUALITY_GATES.yaml b/QUALITY_GATES.yaml
new file mode 100644
index 0000000..366adcd
--- /dev/null
+++ b/QUALITY_GATES.yaml
@@ -0,0 +1,61 @@
+version: 3
+live_wagering: prohibited
+engineering:
+ strict_mypy_required: true
+ ruff_required: true
+ integration_suite_required: true
+kernel:
+ exact_replay_required: true
+ event_hash_chain_required: true
+ result_envelope_hash_required: true
+ monotonic_clock_required: true
+ stable_phase_order_required: true
+ invalid_state_fails_closed: true
+ deterministic_label_addressed_rng_required: true
+leagues:
+ required: [mlb, nba, wnba, ncaambb, nfl, ncaaf, nhl]
+ complete_game_flow_required: true
+ event_log_required: true
+ rule_source_version_required: true
+ maximum_rule_coverage_claim: complete_game_flow_subset
+accuracy:
+ synthetic_data_may_certify_real_world_calibration: false
+ reference_anchor_status: provisional_reference_anchor
+ mean_score_error_within_domain_tolerance: true
+ total_score_sd_error_within_domain_tolerance: true
+ home_advantage_material_reversal_z_minimum: -1.96
+ paired_strength_monotonicity_required: true
+ point_in_time_feature_cutoff_required: true
+ chronological_split_separation_required: true
+ proper_distribution_scores_required_for_historical_evaluation: true
+ held_out_point_in_time_data_required_for_certification: true
+autonomy:
+ configuration_file_required: AUTONOMY_CONFIG.json
+ bounded_parameter_search_required: true
+ deterministic_candidate_generation_required: true
+ train_calibration_test_shadow_separation_required: true
+ prequential_calibration_required: true
+ test_data_may_select_or_tune_candidate: false
+ evaluator_or_rule_mutation_allowed: false
+ complete_failed_trial_ledger_required: true
+ profile_hash_required: true
+ ensemble_hash_required: true
+ adaptive_state_hash_required: true
+ champion_bundle_hash_required: true
+ rollback_hash_required: true
+ drift_quarantine_required: true
+ existing_checkpoint_overwrite_allowed: false
+ synthetic_autonomy_audit_may_certify_real_world_accuracy: false
+performance:
+ reference_report: reports/PERFORMANCE_AUDIT_V3_FINAL.json
+ minimum_f0_games_per_second: 75000
+ minimum_single_worker_f1_games_per_second: 250
+ minimum_best_four_worker_speedup_over_single_worker: 1.20
+stress:
+ minimum_randomized_games: 14000
+ result_integrity_failures_allowed: 0
+ negative_controls_required: true
+domain_neutral_bridge:
+ sport_specific_core_types_allowed: false
+ evidence_metadata_required: true
+ live_action_adapter_allowed: false
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..a48d8f7
--- /dev/null
+++ b/README.md
@@ -0,0 +1,176 @@
+
+
+# Universal Sports Engine
+
+### Deterministic simulation. Recursive calibration. Auditable evolution.
+
+A high-throughput, multi-league sports research engine with exact replay,
+self-tuning analytical ensembles, drift-aware online calibration, and
+content-addressed champion governance.
+
+[](./STATUS.md)
+[](./pyproject.toml)
+[](#seven-leagues-one-kernel)
+[](./reports/RELEASE_EVIDENCE.md)
+[](./LICENSE)
+
+**Research release:** mechanics, integrity, autonomy, and performance are verified.
+Real-world predictive supremacy is not claimed without licensed point-in-time data.
+
+
+
+---
+
+## Why it is different
+
+Universal Sports Engine treats every simulation and model improvement as evidence,
+not theater.
+
+- **Exact by construction** — immutable event streams, deterministic random namespaces,
+ SHA-256 event chains, and complete result-envelope verification.
+- **Fast at two fidelities** — analytical F0 distributions for massive Monte Carlo and
+ event-level F1 paths for interpretable game flow.
+- **Autonomously adaptive** — bounded population search, multiplicative expert weighting,
+ self-calibrating intervals, champion/challenger gates, and prospective shadow updates.
+- **Fail-closed** — drift alerts quarantine adaptive simulation; failed challengers remain
+ in the ledger; existing checkpoints are never silently overwritten.
+- **Portable** — dependency-free runtime, clean Python SDK and CLI, deterministic JSON
+ replay, and a domain-neutral stochastic-control boundary.
+
+## Verified release snapshot
+
+| Dimension | Version 0.3 evidence |
+|---|---:|
+| Supported leagues | 7 |
+| Tests | 67 passed |
+| Negative and mechanism controls | 49 passed, 0 failed |
+| Randomized stress | 14,000 games / 2,003,304 events / 0 failures |
+| F0 throughput | 111K–127K games/second |
+| F1 single-worker throughput | 347–1,011 games/second |
+| F1 four-worker scaling | 1.42×–1.82× |
+| Recursive autonomy arena | 4 promotions / 3 guarded retentions |
+| Calibration and shadow weight changes | 7 / 4 |
+| Shadow drift alerts | 0 |
+
+Machine-readable results live in
+[release evidence](./reports/RELEASE_EVIDENCE.md),
+[performance evidence](./reports/PERFORMANCE_AUDIT_V3_FINAL.json),
+[stress evidence](./reports/STRESS_AUDIT_V3.json), and the
+[autonomy audit](./reports/AUTONOMY_AUDIT_V3.json).
+
+## Architecture
+
+```mermaid
+flowchart TD
+ CLI["CLI / Python SDK"] --> GOV["Champion governance"]
+ GOV --> CAL["Recursive calibration + online weights"]
+ CAL --> F0["F0 analytical distributions"]
+ GOV --> F1["F1 event simulation"]
+ F0 --> PACKS["Seven isolated league packs"]
+ F1 --> PACKS
+ PACKS --> CORE["Deterministic event / rule / RNG kernel"]
+ CORE --> PROOF["Replay + hashes + evidence bundles"]
+ PROOF --> RED["Stress, controls, drift, rollback"]
+```
+
+The neutral kernel contains no player, inning, possession, ball, puck, or scoreboard
+type. Sport semantics remain inside league packs; model governance remains outside
+simulation truth.
+
+## Seven leagues, one kernel
+
+| Family | League packs | Primary F1 unit |
+|---|---|---|
+| Bat and ball | MLB | Pitch / plate appearance / inning |
+| Court invasion | NBA, WNBA, NCAA MBB | Possession / period / game |
+| Gridiron | NFL, NCAA Football | Play / drive / game |
+| Ice invasion | NHL | Event / shift / period |
+
+Each pack owns its rules, scoring, clocks, stochastic transitions, and provisional
+reference anchors. One sport is never treated as a rescaled copy of another.
+
+## Recursive improvement engine
+
+```mermaid
+flowchart LR
+ T["Point-in-time train"] --> S["Bounded population search"]
+ S --> C["Chronological calibration"]
+ C --> W["Expert reweighting + interval adaptation"]
+ W --> G{"All gates pass?"}
+ G -- Yes --> P["Promote + freeze checkpoint"]
+ G -- No --> R["Retain incumbent + record failure"]
+ P --> H["Prospective shadow outcomes"]
+ R --> H
+ H --> D{"Drift?"}
+ D -- Healthy --> W
+ D -- Alert --> Q["Quarantine / recalibrate / rollback"]
+```
+
+Profiles, ensembles, adaptive states, champion bundles, and promotion ledgers all
+carry independent content hashes. Promoted bundles embed the complete incumbent
+model and state, so rollback is self-contained rather than merely documented.
+
+Read the full [autonomous improvement protocol](./AUTONOMOUS_IMPROVEMENT.md).
+
+## Quick start
+
+```powershell
+python -m venv .venv
+.\.venv\Scripts\python.exe -m pip install -e ".[dev]"
+
+.\.venv\Scripts\sports-engine.exe list-leagues
+.\.venv\Scripts\sports-engine.exe simulate --league nba --seed 42
+.\.venv\Scripts\sports-engine.exe simulate-fast `
+ --league nfl --seed 42 --home-strength 1.0 --away-strength 1.0
+```
+
+### Run recursive calibration
+
+```powershell
+.\.venv\Scripts\sports-engine.exe auto-improve `
+ --csv data\point-in-time\historical.csv `
+ --config AUTONOMY_CONFIG.json `
+ --output reports\improvement-run-001
+
+.\.venv\Scripts\sports-engine.exe verify-autonomy `
+ --bundle reports\improvement-run-001\champion_bundle.json `
+ --ledger reports\improvement-run-001\improvement_ledger.jsonl
+```
+
+### Simulate an adaptive champion
+
+```powershell
+.\.venv\Scripts\sports-engine.exe simulate-adaptive `
+ --bundle reports\improvement-run-001\champion_bundle.json `
+ --league nba --seed 42 --home-strength 1.0 --away-strength 1.0
+```
+
+## Evidence and documentation
+
+| Document | Purpose |
+|---|---|
+| [Architecture](./ARCHITECTURE.md) | Kernel, fidelity, and governance boundaries |
+| [Autonomous improvement](./AUTONOMOUS_IMPROVEMENT.md) | Search, weighting, drift, promotion, and rollback |
+| [Quality gates](./QUALITY_GATES.yaml) | Machine-readable non-negotiable release rules |
+| [Release evidence](./reports/RELEASE_EVIDENCE.md) | Current validation and reproducibility snapshot |
+| [Upgrade audit](./reports/AUTONOMOUS_RECURSIVE_UPGRADE_V3.md) | Version 0.3 implementation and results |
+| [Known limitations](./KNOWN_LIMITATIONS.md) | Exact boundaries of demonstrated capability |
+| [Prior art](./PRIOR_ART_REGISTRY.md) | Primary references and defensible distinctions |
+
+## Evidence boundary
+
+The bundled autonomy arena is deliberately synthetic. It proves that the engine can
+discover, reject, promote, reweight, checkpoint, reload, monitor, and roll back models;
+it does **not** turn synthetic outcomes into a claim of real-world accuracy.
+
+Licensed point-in-time game, roster, injury, event, and tracking data are required
+before held-out predictive certification. F2 spatial agents and F3 physics remain
+blocked rather than fabricated.
+
+---
+
+
+
+**Build measurable worlds. Preserve every decision. Believe only what survives.**
+
+
diff --git a/RESEARCH_CONSTITUTION.md b/RESEARCH_CONSTITUTION.md
new file mode 100644
index 0000000..5dff31d
--- /dev/null
+++ b/RESEARCH_CONSTITUTION.md
@@ -0,0 +1,12 @@
+# Research Constitution
+
+1. The engine produces research simulations, not wagers or live actions.
+2. Identical versioned inputs and seeds must reproduce exactly.
+3. Every meaningful transition must be present in a verifiable event stream.
+4. Hard rules are declarative and versioned; inferred behavior remains replaceable.
+5. Sport-specific concepts stay outside the domain-neutral kernel.
+6. Synthetic fixtures test mechanics; they never certify real-world predictive accuracy.
+7. Calibration claims require legally usable point-in-time data and held-out evaluation.
+8. Negative controls, adversarial tests, and failures remain part of the evidence.
+9. Complexity must add measured fidelity, performance, or explanatory value.
+10. Unresolved gaps remain explicit and fail closed.
diff --git a/STATUS.md b/STATUS.md
new file mode 100644
index 0000000..7799431
--- /dev/null
+++ b/STATUS.md
@@ -0,0 +1,53 @@
+# Status
+
+## Executive determination
+
+**VERSION 0.3 ADAPTIVE AUDITED PROVISIONAL MULTI-LEAGUE ENGINE COMPLETE**
+
+Engineering scope is complete for deterministic F0/F1 simulation, portable replay,
+counterfactual branching, batch execution, seasons, tournaments, seven league
+packs, validation, negative controls, fidelity gating, CLI, and the domain-neutral
+future-adaptation bridge.
+
+The audit added strict typing, full result-envelope integrity, temporal and phase
+invariants, confidence-aware reference gates, distributional historical evaluation,
+current rule-source manifests, randomized stress testing, and a distinct analytical
+F0 path.
+
+Version 0.3 adds bounded recursive analytical calibration, deterministic population
+search, online expert weighting, adaptive interval coverage, drift quarantine,
+content-addressed champion checkpoints, rollback lineage, and chained promotion
+ledgers. The seven-league synthetic autonomy arena was exactly reproducible, adjusted
+all seven expert pools, promoted four challengers, and correctly retained three
+incumbents under preregistered guardrails.
+
+Certification is intentionally blocked at held-out real-world calibration because
+the Kimi remote workspace was not exported and no licensed point-in-time event or
+tracking dataset exists in the local handoff.
+
+## Recovery note
+
+The prior remote run stopped during Stage 5 expansion. Its recovery agents remained
+pending for over an hour, and the Kimi memory quota expired before the repository
+was exported. This local build reconstructs the captured architecture and completes
+the executable scope without claiming to possess the lost remote artifacts.
+
+## Verified release evidence
+
+- Static analysis: strict `mypy` and `ruff` passed.
+- Integration/replay suite: 62 tests passed.
+- Reference-anchor run: 500 games per league, 3,500 total; all seven remained
+ `provisional_reference_anchor`.
+- Negative and mechanism controls: 49 executed, zero failures.
+- Randomized stress: 14,000 games and 2,003,304 verified events, zero failures.
+- Performance: F0 exceeded 137,000 games/second in every league; single-worker F1
+ ranged from 372 to 1,204 games/second with full result-envelope hashing.
+- At two workers, F1 throughput improved 2.18x to 4.99x versus the version 0.1
+ evidence benchmark, depending on league.
+- Clean wheel reproduction: package installed in a new virtual environment and
+ independently ran league discovery and an NHL simulation.
+- Kimi desktop process: stopped. The separate Kimi CLI process was preserved.
+- Recursive autonomy audit: seven leagues, eight generations each, 224 candidates
+ per generation wave, four promotions, three guarded retentions, seven weight
+ adjustments, exact bundle reload reproduction, four further prospective-shadow
+ weight changes, zero drift alerts, and exact shadow-checkpoint reproduction.
diff --git a/TECHNOLOGY_BAKEOFF.md b/TECHNOLOGY_BAKEOFF.md
new file mode 100644
index 0000000..00a898a
--- /dev/null
+++ b/TECHNOLOGY_BAKEOFF.md
@@ -0,0 +1,31 @@
+# Technology Bake-off
+
+## Compared architectures
+
+1. Event-sourced immutable kernel with explicit phase ordering and pure reducers.
+2. Coroutine/process-oriented discrete-event simulation with serialized continuation state.
+
+The event-sourced design won because exact replay, branching, failure recovery, and
+cross-platform pickling are direct properties rather than special-case machinery.
+The process-oriented design's strongest ideas were retained: phase frontiers,
+single-timeline determinism, game-level parallelism, and replaceable resolvers.
+
+## Stack decision
+
+The core uses Python 3.12+ and the standard library. This minimizes supply-chain and
+installation risk while preserving multiprocessing and ML interoperability.
+Columnar/GPU accelerators remain optional adapter work once a licensed dataset and a
+measured bottleneck justify them. Rendering is separate from simulation truth.
+
+## Version 0.2 performance decision
+
+Profiling identified tuple-copy event construction, repeated `random.Random`
+initialization, and redundant result-time chain verification as the binding costs.
+Version 0.2 replaced them with linear draft finalization, direct digest-to-uniform
+draws, and one trusted construction pass followed by verification at external
+boundaries.
+
+A binary event encoding prototype was rejected after profiling showed that many
+small `hash.update` and `struct.pack` calls were slower in CPython than one canonical
+JSON serialization. Rejection evidence was preserved instead of retaining an
+architecturally fashionable regression.
diff --git a/data/contracts/HISTORICAL_GAMES.md b/data/contracts/HISTORICAL_GAMES.md
new file mode 100644
index 0000000..2f9c360
--- /dev/null
+++ b/data/contracts/HISTORICAL_GAMES.md
@@ -0,0 +1,24 @@
+# Historical game evaluation contract
+
+The `evaluate-historical` command accepts a UTF-8 CSV with these exact columns:
+
+| Column | Meaning |
+|---|---|
+| `game_id` | Stable unique identifier |
+| `league` | One supported lowercase league ID |
+| `decision_time` | Offset-aware ISO-8601 forecast timestamp |
+| `features_available_at` | Latest feature timestamp; must not exceed decision time |
+| `outcome_time` | Offset-aware ISO-8601 completion timestamp |
+| `home_score`, `away_score` | Non-negative final scores |
+| `home_strength`, `away_strength` | Frozen multipliers within `[0.25, 2.0]` |
+| `split` | `train`, `calibration`, `test`, or prospective `shadow` |
+
+For each league, outcomes in an earlier split must precede decisions in the next
+split. Reporting accepts only test-split games and returns score MAE, home-win Brier
+score, score CRPS, and 50%/90% interval coverage. A successful run is historical
+evaluation evidence, not automatic predictive certification.
+
+Autonomous search may read `train` and perform prequential promotion checks on
+`calibration`. It may not tune on `test`. An already frozen champion may update
+weights, interval scale, and drift state from `shadow` records only after each
+outcome is chronologically available.
diff --git a/dummy_bridge/DOMAIN_NEUTRAL_PROTOCOL.md b/dummy_bridge/DOMAIN_NEUTRAL_PROTOCOL.md
new file mode 100644
index 0000000..fab3719
--- /dev/null
+++ b/dummy_bridge/DOMAIN_NEUTRAL_PROTOCOL.md
@@ -0,0 +1,20 @@
+# Domain-Neutral Dummy Bridge
+
+The bridge exposes immutable `State`, `Action`, `Observation`, `PolicyDecision`,
+`Scenario`, `Counterfactual`, and `Evidence` records. No record imports league,
+player, possession, ball, puck, score, or wagering semantics.
+
+Required adapter operations:
+
+```text
+initialize(scenario, seed) -> state
+observe(state, observer) -> observation
+enumerate_actions(observation, constraints) -> actions
+transition(state, actions, seed_labels) -> state, events
+score(state, objective) -> distribution
+branch(state, intervention, shared_seed) -> paired evidence
+```
+
+The included generic inventory-control fixture is the compatibility proof that the
+contracts are reusable outside sports. A future Dummy adapter must provide its own
+domain pack and must not import sports rules or reference anchors.
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..3a9d857
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,38 @@
+[build-system]
+requires = ["setuptools>=77"]
+build-backend = "setuptools.build_meta"
+
+[project]
+name = "universal-sports-engine"
+version = "0.3.0"
+description = "Deterministic multi-league sports simulation and counterfactual research engine"
+readme = "README.md"
+requires-python = ">=3.12"
+license = "MIT"
+authors = [{ name = "Universal Sports Engine Research Program" }]
+dependencies = []
+
+[project.optional-dependencies]
+dev = ["mypy>=1.16", "pytest>=9.0", "ruff>=0.12"]
+
+[project.scripts]
+sports-engine = "universal_sports_engine.cli:main"
+
+[tool.setuptools.packages.find]
+where = ["src"]
+
+[tool.pytest.ini_options]
+addopts = "-ra --strict-markers"
+testpaths = ["tests"]
+
+[tool.ruff]
+line-length = 100
+target-version = "py312"
+
+[tool.ruff.lint]
+select = ["E", "F", "I", "UP", "B", "SIM", "RUF"]
+
+[tool.mypy]
+python_version = "3.12"
+strict = true
+files = ["src", "scripts"]
diff --git a/reports/AUTONOMOUS_RECURSIVE_UPGRADE_V3.md b/reports/AUTONOMOUS_RECURSIVE_UPGRADE_V3.md
new file mode 100644
index 0000000..8e5f8d5
--- /dev/null
+++ b/reports/AUTONOMOUS_RECURSIVE_UPGRADE_V3.md
@@ -0,0 +1,105 @@
+# Autonomous recursive upgrade audit — version 0.3
+
+## Determination
+
+**ENGINEERING PASS — REAL-WORLD CALIBRATION STILL BLOCKED BY MISSING DATA.**
+
+The isolated Universal Sports Engine now contains a functioning governed
+recursive-improvement system. It can search bounded analytical models, tune
+expert mixtures, adapt interval coverage, detect drift, promote challengers,
+retain incumbents, reproduce checkpoints, verify decision ledgers, and roll
+back a promoted league without changing source code or protected evaluators.
+
+No Dummy workspace or integration was inspected or modified.
+
+## Implemented autonomy stack
+
+- Immutable content-addressed league profiles.
+- Deterministic log-space population mutation.
+- Eight-generation default champion/challenger search.
+- Train-only parameter selection.
+- Chronological prequential calibration evaluation.
+- Joint total/margin likelihood scoring.
+- Home-win Brier guardrail.
+- Adaptive 90% interval scaling.
+- Multiplicative online expert weighting.
+- Short/long loss EWMA drift detection.
+- Fail-closed adaptive simulation during drift alerts.
+- Fully embedded incumbent ensembles and states for self-contained rollback.
+- Hash-verified profile, ensemble, state, bundle, and decision-ledger envelopes.
+- Atomic, no-overwrite checkpoint publication.
+- Prospective shadow-only weight and interval updates.
+- CLI workflows for improve, simulate, adapt, verify, and roll back.
+
+## Seven-league autonomy arena
+
+The arena uses synthetic fixtures solely to test learning mechanics. It is not
+real-world evidence.
+
+| Measure | Result |
+|---|---:|
+| Supported leagues | 7 |
+| Search generations per league | 8 |
+| Population per generation | 32 |
+| Training games per league | 100 |
+| Calibration games per league | 50 |
+| Shadow games per league | 40 |
+| Challengers promoted | 4 |
+| Incumbents retained by guardrails | 3 |
+| Calibration expert pools reweighted | 7 |
+| Shadow expert pools reweighted | 4 |
+| Shadow drift alerts | 0 |
+| Ledger records verified | 7 |
+| Deterministic repeat | PASS |
+| Champion bundle reload | PASS |
+| Shadow bundle reload | PASS |
+| Embedded rollback smoke test | PASS |
+
+MLB was retained despite better aggregate composite loss because its Brier
+guardrail deteriorated beyond the configured limit. NCAAF and NFL were retained
+because their relative improvements did not reach the preregistered threshold.
+This demonstrates that the loop can reject as well as promote.
+
+## Base-engine regression evidence
+
+- Strict MyPy: PASS.
+- Ruff: PASS.
+- Test suite: 67 passed.
+- Randomized stress: 14,000 games, 2,003,304 events, zero integrity failures.
+- F0 throughput after hot-loop optimization: 111,365 to 127,129 games/second
+ for six leagues and 121,071 for NHL in the final benchmark.
+- Single-worker F1: 347 to 1,011 games/second.
+- Four-worker F1 speedup: 1.42x to 1.82x.
+
+Exact machine-readable evidence:
+
+- `reports/AUTONOMY_AUDIT_V3.json`
+- `reports/autonomy_v3_fixture/champion_bundle.json`
+- `reports/autonomy_v3_fixture/shadow_adapted_bundle.json`
+- `reports/autonomy_v3_fixture/improvement_ledger.jsonl`
+- `reports/PERFORMANCE_AUDIT_V3_FINAL.json`
+- `reports/STRESS_AUDIT_V3.json`
+
+## Research basis
+
+The implementation adapts established ideas while making no unsupported novelty
+claim:
+
+- Population Based Training: https://arxiv.org/abs/1711.09846
+- Adaptive Conformal Inference: https://arxiv.org/abs/2106.00170
+- Online probabilistic expert aggregation:
+ https://proceedings.mlr.press/v128/korotin20a/korotin20a.pdf
+- Optuna search-system design: https://arxiv.org/abs/1907.10902
+
+Its defensible distinction is the evidence architecture: deterministic sports
+simulation, point-in-time splits, bounded recursive search, online weighting,
+adaptive coverage, drift quarantine, embedded rollback, and complete
+content-addressed lineage in one dependency-free package.
+
+## Certification boundary
+
+This release proves autonomous learning mechanics, integrity, reproducibility,
+and performance. It cannot prove superior real-world prediction without licensed
+point-in-time game, player, roster, injury, event, and tracking data. Current
+recursive tuning applies to F0 analytical score models; F1 event calibration,
+F2 spatial agents, and F3 physics remain blocked rather than fabricated.
diff --git a/reports/AUTONOMY_AUDIT_V3.json b/reports/AUTONOMY_AUDIT_V3.json
new file mode 100644
index 0000000..c6fad96
--- /dev/null
+++ b/reports/AUTONOMY_AUDIT_V3.json
@@ -0,0 +1,191 @@
+{
+ "bundle_hash": "56c5551d36093708f6da5ad0165f968a12c69c7ede7216959f7a4d532a40d754",
+ "bundle_reproduced": true,
+ "deterministic_recursive_search": true,
+ "evidence_status": "synthetic_autonomy_audit_not_real_world_certification",
+ "leagues": [
+ {
+ "challenger_score": {
+ "composite_loss": 5.628048038203239,
+ "games": 50,
+ "home_win_brier": 0.21438362127823524,
+ "interval_coverage": 0.88,
+ "interval_coverage_error": 0.020000000000000018,
+ "mean_joint_negative_log_likelihood": 5.159280795646769
+ },
+ "decision": "retained_incumbent:brier_guardrail_failed",
+ "generations": 8,
+ "incumbent_score": {
+ "composite_loss": 5.874629433875539,
+ "games": 50,
+ "home_win_brier": 0.20077420341310603,
+ "interval_coverage": 0.96,
+ "interval_coverage_error": 0.05999999999999994,
+ "mean_joint_negative_log_likelihood": 5.353081027049327
+ },
+ "league": "mlb",
+ "promoted": false,
+ "relative_improvement": 0.04197394890142503,
+ "selected_ensemble_hash": "bb0b6a4184ebbf8489abaf3dc3df077d280c14d888340b59c2871215f6df8360",
+ "selected_state_hash": "a23ac9f2ccc36db8368dcd341b0025f12d6d2b188c95ca9013b1dc61b461e78a"
+ },
+ {
+ "challenger_score": {
+ "composite_loss": 8.248030969834542,
+ "games": 50,
+ "home_win_brier": 0.0698963567147646,
+ "interval_coverage": 0.94,
+ "interval_coverage_error": 0.039999999999999925,
+ "mean_joint_negative_log_likelihood": 8.028238256405013
+ },
+ "decision": "promoted",
+ "generations": 8,
+ "incumbent_score": {
+ "composite_loss": 9.310371209830079,
+ "games": 50,
+ "home_win_brier": 0.0654562378544873,
+ "interval_coverage": 0.83,
+ "interval_coverage_error": 0.07000000000000006,
+ "mean_joint_negative_log_likelihood": 9.039458734121103
+ },
+ "league": "nba",
+ "promoted": true,
+ "relative_improvement": 0.11410288763501682,
+ "selected_ensemble_hash": "60e7da6020d67de678c0d044f300847fde90bf16161917510b08c83bfd5dbe96",
+ "selected_state_hash": "fe671acbd9f09da2f1984ffa82fa65ab28b4110cb59498739477866e598f119d"
+ },
+ {
+ "challenger_score": {
+ "composite_loss": 8.761251921087043,
+ "games": 50,
+ "home_win_brier": 0.2309784924355083,
+ "interval_coverage": 0.87,
+ "interval_coverage_error": 0.030000000000000027,
+ "mean_joint_negative_log_likelihood": 8.239294936216025
+ },
+ "decision": "retained_incumbent:minimum_relative_improvement_not_met",
+ "generations": 8,
+ "incumbent_score": {
+ "composite_loss": 8.809151979845048,
+ "games": 50,
+ "home_win_brier": 0.22737367673106743,
+ "interval_coverage": 0.92,
+ "interval_coverage_error": 0.020000000000000018,
+ "mean_joint_negative_log_likelihood": 8.314404626382911
+ },
+ "league": "ncaaf",
+ "promoted": false,
+ "relative_improvement": 0.005437533472869828,
+ "selected_ensemble_hash": "110e0a2b1d912b65c9c8e2421251514d29e036503be2191a6a19c5418d16b42a",
+ "selected_state_hash": "6490ed8bb46c72d47e410317f52bba03128f9076dbe23088cbd0748735b8b91b"
+ },
+ {
+ "challenger_score": {
+ "composite_loss": 8.216060900552336,
+ "games": 50,
+ "home_win_brier": 0.16681685856160933,
+ "interval_coverage": 0.92,
+ "interval_coverage_error": 0.020000000000000018,
+ "mean_joint_negative_log_likelihood": 7.842427183429115
+ },
+ "decision": "promoted",
+ "generations": 8,
+ "incumbent_score": {
+ "composite_loss": 8.578503263410775,
+ "games": 50,
+ "home_win_brier": 0.16468304335835116,
+ "interval_coverage": 0.9,
+ "interval_coverage_error": 0.0,
+ "mean_joint_negative_log_likelihood": 8.249137176694074
+ },
+ "league": "ncaambb",
+ "promoted": true,
+ "relative_improvement": 0.04225006993986202,
+ "selected_ensemble_hash": "3a26b1869b41e662ecdfe044a54229c6e5998280f88a6ad5003326302350654e",
+ "selected_state_hash": "924515d3adfcde4094160bbe9a1c1741be83320aad2c0d1e322f724c309fcb9d"
+ },
+ {
+ "challenger_score": {
+ "composite_loss": 8.35269018511674,
+ "games": 50,
+ "home_win_brier": 0.23858136537417907,
+ "interval_coverage": 0.89,
+ "interval_coverage_error": 0.010000000000000009,
+ "mean_joint_negative_log_likelihood": 7.855527454368383
+ },
+ "decision": "retained_incumbent:minimum_relative_improvement_not_met",
+ "generations": 8,
+ "incumbent_score": {
+ "composite_loss": 8.427984368402127,
+ "games": 50,
+ "home_win_brier": 0.23551834611431333,
+ "interval_coverage": 0.94,
+ "interval_coverage_error": 0.039999999999999925,
+ "mean_joint_negative_log_likelihood": 7.8769476761735
+ },
+ "league": "nfl",
+ "promoted": false,
+ "relative_improvement": 0.008933830438470725,
+ "selected_ensemble_hash": "52cc748b0f03d805bc32644c746152d71b8878f6cb3e9e2e6df533e3cb3718e2",
+ "selected_state_hash": "c56bdf6245fc5a57c735db00e6d448c6670f5a96632121cbfa3e9d7e30dd0e91"
+ },
+ {
+ "challenger_score": {
+ "composite_loss": 4.7671157212113355,
+ "games": 50,
+ "home_win_brier": 0.2228624325270619,
+ "interval_coverage": 0.9,
+ "interval_coverage_error": 0.0,
+ "mean_joint_negative_log_likelihood": 4.321390856157212
+ },
+ "decision": "promoted",
+ "generations": 8,
+ "incumbent_score": {
+ "composite_loss": 4.831941943380519,
+ "games": 50,
+ "home_win_brier": 0.2199413705553162,
+ "interval_coverage": 0.91,
+ "interval_coverage_error": 0.010000000000000009,
+ "mean_joint_negative_log_likelihood": 4.372059202269887
+ },
+ "league": "nhl",
+ "promoted": true,
+ "relative_improvement": 0.013416183995751795,
+ "selected_ensemble_hash": "b4268f4251d62981ee852625c817f48947e9e12aecc39da1b77d4ff869c86289",
+ "selected_state_hash": "9e103f41a8cf8181c03bde20e2b260ff7daa3ca261c7c760e94c10dca68cc368"
+ },
+ {
+ "challenger_score": {
+ "composite_loss": 8.379522034337166,
+ "games": 50,
+ "home_win_brier": 0.16069882492885665,
+ "interval_coverage": 0.9,
+ "interval_coverage_error": 0.0,
+ "mean_joint_negative_log_likelihood": 8.058124384479452
+ },
+ "decision": "promoted",
+ "generations": 8,
+ "incumbent_score": {
+ "composite_loss": 9.188926654018786,
+ "games": 50,
+ "home_win_brier": 0.16577671914460065,
+ "interval_coverage": 0.87,
+ "interval_coverage_error": 0.030000000000000027,
+ "mean_joint_negative_log_likelihood": 8.797373215729584
+ },
+ "league": "wnba",
+ "promoted": true,
+ "relative_improvement": 0.08808478401855853,
+ "selected_ensemble_hash": "369bd1fab70c4fe9c443214b61e5bb1297947388fae8402061d599b6dc5a975d",
+ "selected_state_hash": "b5389b73b296d8ff3307fa1679ea4534b3e0cdb82aba2cf0f5a58625c2587f88"
+ }
+ ],
+ "promotions": 4,
+ "shadow_bundle_hash": "7f1903911221d44a29bbed34a9e13e47e25f0bf8c1ccf3ba880dbc2c2d03722a",
+ "shadow_bundle_reproduced": true,
+ "shadow_drift_alerts": 0,
+ "shadow_weight_adjustments": 4,
+ "total_leagues": 7,
+ "verified_ledger_records": 7,
+ "weight_adjustments": 7
+}
diff --git a/reports/NEGATIVE_CONTROL_REPORT.json b/reports/NEGATIVE_CONTROL_REPORT.json
new file mode 100644
index 0000000..38395ca
--- /dev/null
+++ b/reports/NEGATIVE_CONTROL_REPORT.json
@@ -0,0 +1,247 @@
+[
+ {
+ "control": "mlb.deterministic_replay",
+ "description": "same seed and version",
+ "passed": true
+ },
+ {
+ "control": "mlb.finite_scores",
+ "description": "scores must be finite",
+ "passed": true
+ },
+ {
+ "control": "mlb.event_integrity",
+ "description": "SHA-256 chain verification",
+ "passed": true
+ },
+ {
+ "control": "mlb.result_integrity",
+ "description": "complete result envelope hash verification",
+ "passed": true
+ },
+ {
+ "control": "mlb.seed_sensitivity",
+ "description": "different seed changes the path",
+ "passed": true
+ },
+ {
+ "control": "mlb.strength_monotonicity",
+ "description": "paired stronger home input must increase mean home score",
+ "passed": true
+ },
+ {
+ "control": "mlb.home_advantage_direction",
+ "description": "home advantage must not be statistically materially reversed",
+ "passed": true
+ },
+ {
+ "control": "nba.deterministic_replay",
+ "description": "same seed and version",
+ "passed": true
+ },
+ {
+ "control": "nba.finite_scores",
+ "description": "scores must be finite",
+ "passed": true
+ },
+ {
+ "control": "nba.event_integrity",
+ "description": "SHA-256 chain verification",
+ "passed": true
+ },
+ {
+ "control": "nba.result_integrity",
+ "description": "complete result envelope hash verification",
+ "passed": true
+ },
+ {
+ "control": "nba.seed_sensitivity",
+ "description": "different seed changes the path",
+ "passed": true
+ },
+ {
+ "control": "nba.strength_monotonicity",
+ "description": "paired stronger home input must increase mean home score",
+ "passed": true
+ },
+ {
+ "control": "nba.home_advantage_direction",
+ "description": "home advantage must not be statistically materially reversed",
+ "passed": true
+ },
+ {
+ "control": "wnba.deterministic_replay",
+ "description": "same seed and version",
+ "passed": true
+ },
+ {
+ "control": "wnba.finite_scores",
+ "description": "scores must be finite",
+ "passed": true
+ },
+ {
+ "control": "wnba.event_integrity",
+ "description": "SHA-256 chain verification",
+ "passed": true
+ },
+ {
+ "control": "wnba.result_integrity",
+ "description": "complete result envelope hash verification",
+ "passed": true
+ },
+ {
+ "control": "wnba.seed_sensitivity",
+ "description": "different seed changes the path",
+ "passed": true
+ },
+ {
+ "control": "wnba.strength_monotonicity",
+ "description": "paired stronger home input must increase mean home score",
+ "passed": true
+ },
+ {
+ "control": "wnba.home_advantage_direction",
+ "description": "home advantage must not be statistically materially reversed",
+ "passed": true
+ },
+ {
+ "control": "ncaambb.deterministic_replay",
+ "description": "same seed and version",
+ "passed": true
+ },
+ {
+ "control": "ncaambb.finite_scores",
+ "description": "scores must be finite",
+ "passed": true
+ },
+ {
+ "control": "ncaambb.event_integrity",
+ "description": "SHA-256 chain verification",
+ "passed": true
+ },
+ {
+ "control": "ncaambb.result_integrity",
+ "description": "complete result envelope hash verification",
+ "passed": true
+ },
+ {
+ "control": "ncaambb.seed_sensitivity",
+ "description": "different seed changes the path",
+ "passed": true
+ },
+ {
+ "control": "ncaambb.strength_monotonicity",
+ "description": "paired stronger home input must increase mean home score",
+ "passed": true
+ },
+ {
+ "control": "ncaambb.home_advantage_direction",
+ "description": "home advantage must not be statistically materially reversed",
+ "passed": true
+ },
+ {
+ "control": "nfl.deterministic_replay",
+ "description": "same seed and version",
+ "passed": true
+ },
+ {
+ "control": "nfl.finite_scores",
+ "description": "scores must be finite",
+ "passed": true
+ },
+ {
+ "control": "nfl.event_integrity",
+ "description": "SHA-256 chain verification",
+ "passed": true
+ },
+ {
+ "control": "nfl.result_integrity",
+ "description": "complete result envelope hash verification",
+ "passed": true
+ },
+ {
+ "control": "nfl.seed_sensitivity",
+ "description": "different seed changes the path",
+ "passed": true
+ },
+ {
+ "control": "nfl.strength_monotonicity",
+ "description": "paired stronger home input must increase mean home score",
+ "passed": true
+ },
+ {
+ "control": "nfl.home_advantage_direction",
+ "description": "home advantage must not be statistically materially reversed",
+ "passed": true
+ },
+ {
+ "control": "ncaaf.deterministic_replay",
+ "description": "same seed and version",
+ "passed": true
+ },
+ {
+ "control": "ncaaf.finite_scores",
+ "description": "scores must be finite",
+ "passed": true
+ },
+ {
+ "control": "ncaaf.event_integrity",
+ "description": "SHA-256 chain verification",
+ "passed": true
+ },
+ {
+ "control": "ncaaf.result_integrity",
+ "description": "complete result envelope hash verification",
+ "passed": true
+ },
+ {
+ "control": "ncaaf.seed_sensitivity",
+ "description": "different seed changes the path",
+ "passed": true
+ },
+ {
+ "control": "ncaaf.strength_monotonicity",
+ "description": "paired stronger home input must increase mean home score",
+ "passed": true
+ },
+ {
+ "control": "ncaaf.home_advantage_direction",
+ "description": "home advantage must not be statistically materially reversed",
+ "passed": true
+ },
+ {
+ "control": "nhl.deterministic_replay",
+ "description": "same seed and version",
+ "passed": true
+ },
+ {
+ "control": "nhl.finite_scores",
+ "description": "scores must be finite",
+ "passed": true
+ },
+ {
+ "control": "nhl.event_integrity",
+ "description": "SHA-256 chain verification",
+ "passed": true
+ },
+ {
+ "control": "nhl.result_integrity",
+ "description": "complete result envelope hash verification",
+ "passed": true
+ },
+ {
+ "control": "nhl.seed_sensitivity",
+ "description": "different seed changes the path",
+ "passed": true
+ },
+ {
+ "control": "nhl.strength_monotonicity",
+ "description": "paired stronger home input must increase mean home score",
+ "passed": true
+ },
+ {
+ "control": "nhl.home_advantage_direction",
+ "description": "home advantage must not be statistically materially reversed",
+ "passed": true
+ }
+]
diff --git a/reports/PERFORMANCE_AUDIT_V3_FINAL.json b/reports/PERFORMANCE_AUDIT_V3_FINAL.json
new file mode 100644
index 0000000..a351cdc
--- /dev/null
+++ b/reports/PERFORMANCE_AUDIT_V3_FINAL.json
@@ -0,0 +1,261 @@
+[
+ {
+ "elapsed_seconds": 0.7956835000077263,
+ "events": 0,
+ "fidelity": "F0_ANALYTICAL",
+ "games": 100000,
+ "games_per_second": 125678.11196163924,
+ "league": "mlb",
+ "results": 100000,
+ "workers": 1
+ },
+ {
+ "elapsed_seconds": 1.3158665999944787,
+ "events": 86681,
+ "fidelity": "F1_EVENT",
+ "games": 1000,
+ "games_per_second": 759.9554544542706,
+ "league": "mlb",
+ "workers": 1
+ },
+ {
+ "elapsed_seconds": 1.1424124999903142,
+ "events": 86681,
+ "fidelity": "F1_EVENT",
+ "games": 1000,
+ "games_per_second": 875.3405621948975,
+ "league": "mlb",
+ "workers": 2
+ },
+ {
+ "elapsed_seconds": 0.9006621000007726,
+ "events": 86681,
+ "fidelity": "F1_EVENT",
+ "games": 1000,
+ "games_per_second": 1110.294304600074,
+ "league": "mlb",
+ "workers": 4
+ },
+ {
+ "elapsed_seconds": 0.8979504000162706,
+ "events": 0,
+ "fidelity": "F0_ANALYTICAL",
+ "games": 100000,
+ "games_per_second": 111364.72571111727,
+ "league": "nba",
+ "results": 100000,
+ "workers": 1
+ },
+ {
+ "elapsed_seconds": 2.880733900004998,
+ "events": 200358,
+ "fidelity": "F1_EVENT",
+ "games": 1000,
+ "games_per_second": 347.1337633782367,
+ "league": "nba",
+ "workers": 1
+ },
+ {
+ "elapsed_seconds": 2.5140926000021864,
+ "events": 200358,
+ "fidelity": "F1_EVENT",
+ "games": 1000,
+ "games_per_second": 397.7578232397368,
+ "league": "nba",
+ "workers": 2
+ },
+ {
+ "elapsed_seconds": 1.5892845000198577,
+ "events": 200358,
+ "fidelity": "F1_EVENT",
+ "games": 1000,
+ "games_per_second": 629.2139638859533,
+ "league": "nba",
+ "workers": 4
+ },
+ {
+ "elapsed_seconds": 0.8157341000041924,
+ "events": 0,
+ "fidelity": "F0_ANALYTICAL",
+ "games": 100000,
+ "games_per_second": 122588.96618332622,
+ "league": "wnba",
+ "results": 100000,
+ "workers": 1
+ },
+ {
+ "elapsed_seconds": 2.316987900005188,
+ "events": 161766,
+ "fidelity": "F1_EVENT",
+ "games": 1000,
+ "games_per_second": 431.5948305115279,
+ "league": "wnba",
+ "workers": 1
+ },
+ {
+ "elapsed_seconds": 1.8946968000091147,
+ "events": 161766,
+ "fidelity": "F1_EVENT",
+ "games": 1000,
+ "games_per_second": 527.7889317146625,
+ "league": "wnba",
+ "workers": 2
+ },
+ {
+ "elapsed_seconds": 1.4412796000251547,
+ "events": 161766,
+ "fidelity": "F1_EVENT",
+ "games": 1000,
+ "games_per_second": 693.8279012500745,
+ "league": "wnba",
+ "workers": 4
+ },
+ {
+ "elapsed_seconds": 0.7866054000041913,
+ "events": 0,
+ "fidelity": "F0_ANALYTICAL",
+ "games": 100000,
+ "games_per_second": 127128.54501058238,
+ "league": "ncaambb",
+ "results": 100000,
+ "workers": 1
+ },
+ {
+ "elapsed_seconds": 2.022876900009578,
+ "events": 139472,
+ "fidelity": "F1_EVENT",
+ "games": 1000,
+ "games_per_second": 494.3454542366197,
+ "league": "ncaambb",
+ "workers": 1
+ },
+ {
+ "elapsed_seconds": 1.6672028000175487,
+ "events": 139472,
+ "fidelity": "F1_EVENT",
+ "games": 1000,
+ "games_per_second": 599.8070540605343,
+ "league": "ncaambb",
+ "workers": 2
+ },
+ {
+ "elapsed_seconds": 1.1097719999961555,
+ "events": 139472,
+ "fidelity": "F1_EVENT",
+ "games": 1000,
+ "games_per_second": 901.085988836864,
+ "league": "ncaambb",
+ "workers": 4
+ },
+ {
+ "elapsed_seconds": 0.8237592999939807,
+ "events": 0,
+ "fidelity": "F0_ANALYTICAL",
+ "games": 100000,
+ "games_per_second": 121394.68410339126,
+ "league": "nfl",
+ "results": 100000,
+ "workers": 1
+ },
+ {
+ "elapsed_seconds": 2.0862898000050336,
+ "events": 165521,
+ "fidelity": "F1_EVENT",
+ "games": 1000,
+ "games_per_second": 479.3197953599674,
+ "league": "nfl",
+ "workers": 1
+ },
+ {
+ "elapsed_seconds": 1.8517403000150807,
+ "events": 165521,
+ "fidelity": "F1_EVENT",
+ "games": 1000,
+ "games_per_second": 540.032530475173,
+ "league": "nfl",
+ "workers": 2
+ },
+ {
+ "elapsed_seconds": 1.2846881999867037,
+ "events": 165521,
+ "fidelity": "F1_EVENT",
+ "games": 1000,
+ "games_per_second": 778.3989920747695,
+ "league": "nfl",
+ "workers": 4
+ },
+ {
+ "elapsed_seconds": 0.8141856000002008,
+ "events": 0,
+ "fidelity": "F0_ANALYTICAL",
+ "games": 100000,
+ "games_per_second": 122822.11820004595,
+ "league": "ncaaf",
+ "results": 100000,
+ "workers": 1
+ },
+ {
+ "elapsed_seconds": 2.30761300001177,
+ "events": 181042,
+ "fidelity": "F1_EVENT",
+ "games": 1000,
+ "games_per_second": 433.3482260651589,
+ "league": "ncaaf",
+ "workers": 1
+ },
+ {
+ "elapsed_seconds": 1.9399241000064649,
+ "events": 181042,
+ "fidelity": "F1_EVENT",
+ "games": 1000,
+ "games_per_second": 515.4840851746043,
+ "league": "ncaaf",
+ "workers": 2
+ },
+ {
+ "elapsed_seconds": 1.3367247999995016,
+ "events": 181042,
+ "fidelity": "F1_EVENT",
+ "games": 1000,
+ "games_per_second": 748.097140114684,
+ "league": "ncaaf",
+ "workers": 4
+ },
+ {
+ "elapsed_seconds": 0.8259643000201322,
+ "events": 0,
+ "fidelity": "F0_ANALYTICAL",
+ "games": 100000,
+ "games_per_second": 121070.60801243175,
+ "league": "nhl",
+ "results": 100000,
+ "workers": 1
+ },
+ {
+ "elapsed_seconds": 0.9892554999969434,
+ "events": 65803,
+ "fidelity": "F1_EVENT",
+ "games": 1000,
+ "games_per_second": 1010.8611981465757,
+ "league": "nhl",
+ "workers": 1
+ },
+ {
+ "elapsed_seconds": 0.8409421000105795,
+ "events": 65803,
+ "fidelity": "F1_EVENT",
+ "games": 1000,
+ "games_per_second": 1189.142510509843,
+ "league": "nhl",
+ "workers": 2
+ },
+ {
+ "elapsed_seconds": 0.6960250999836717,
+ "events": 65803,
+ "fidelity": "F1_EVENT",
+ "games": 1000,
+ "games_per_second": 1436.729796128702,
+ "league": "nhl",
+ "workers": 4
+ }
+]
diff --git a/reports/PERFORMANCE_BENCHMARK.json b/reports/PERFORMANCE_BENCHMARK.json
new file mode 100644
index 0000000..c305dee
--- /dev/null
+++ b/reports/PERFORMANCE_BENCHMARK.json
@@ -0,0 +1,135 @@
+[
+ {
+ "elapsed_seconds": 0.13574239998706616,
+ "events": 0,
+ "fidelity": "F0_ANALYTICAL",
+ "games": 10000,
+ "games_per_second": 73668.94942886542,
+ "league": "mlb",
+ "results": 10000,
+ "workers": 1
+ },
+ {
+ "elapsed_seconds": 0.3407911999966018,
+ "events": 8830,
+ "fidelity": "F1_EVENT",
+ "games": 100,
+ "games_per_second": 293.43480700498475,
+ "league": "mlb",
+ "workers": 2
+ },
+ {
+ "elapsed_seconds": 0.14295050001237541,
+ "events": 0,
+ "fidelity": "F0_ANALYTICAL",
+ "games": 10000,
+ "games_per_second": 69954.28486877825,
+ "league": "nba",
+ "results": 10000,
+ "workers": 1
+ },
+ {
+ "elapsed_seconds": 0.4545626000035554,
+ "events": 19954,
+ "fidelity": "F1_EVENT",
+ "games": 100,
+ "games_per_second": 219.99170191128314,
+ "league": "nba",
+ "workers": 2
+ },
+ {
+ "elapsed_seconds": 0.15859930001897737,
+ "events": 0,
+ "fidelity": "F0_ANALYTICAL",
+ "games": 10000,
+ "games_per_second": 63051.980675850646,
+ "league": "wnba",
+ "results": 10000,
+ "workers": 1
+ },
+ {
+ "elapsed_seconds": 0.45809050000389107,
+ "events": 16098,
+ "fidelity": "F1_EVENT",
+ "games": 100,
+ "games_per_second": 218.2974761518752,
+ "league": "wnba",
+ "workers": 2
+ },
+ {
+ "elapsed_seconds": 0.17294249997939914,
+ "events": 0,
+ "fidelity": "F0_ANALYTICAL",
+ "games": 10000,
+ "games_per_second": 57822.68673802678,
+ "league": "ncaambb",
+ "results": 10000,
+ "workers": 1
+ },
+ {
+ "elapsed_seconds": 0.3960789999982808,
+ "events": 13938,
+ "fidelity": "F1_EVENT",
+ "games": 100,
+ "games_per_second": 252.47488506190447,
+ "league": "ncaambb",
+ "workers": 2
+ },
+ {
+ "elapsed_seconds": 0.1276167999894824,
+ "events": 0,
+ "fidelity": "F0_ANALYTICAL",
+ "games": 10000,
+ "games_per_second": 78359.58902608557,
+ "league": "nfl",
+ "results": 10000,
+ "workers": 1
+ },
+ {
+ "elapsed_seconds": 0.40035370000987314,
+ "events": 16529,
+ "fidelity": "F1_EVENT",
+ "games": 100,
+ "games_per_second": 249.7791327956602,
+ "league": "nfl",
+ "workers": 2
+ },
+ {
+ "elapsed_seconds": 0.17455659998813644,
+ "events": 0,
+ "fidelity": "F0_ANALYTICAL",
+ "games": 10000,
+ "games_per_second": 57288.00859251177,
+ "league": "ncaaf",
+ "results": 10000,
+ "workers": 1
+ },
+ {
+ "elapsed_seconds": 0.42027029997552745,
+ "events": 17952,
+ "fidelity": "F1_EVENT",
+ "games": 100,
+ "games_per_second": 237.94210536843323,
+ "league": "ncaaf",
+ "workers": 2
+ },
+ {
+ "elapsed_seconds": 0.1503820999932941,
+ "events": 0,
+ "fidelity": "F0_ANALYTICAL",
+ "games": 10000,
+ "games_per_second": 66497.27594205643,
+ "league": "nhl",
+ "results": 10000,
+ "workers": 1
+ },
+ {
+ "elapsed_seconds": 0.3056190999923274,
+ "events": 6583,
+ "fidelity": "F1_EVENT",
+ "games": 100,
+ "games_per_second": 327.20468060572955,
+ "league": "nhl",
+ "workers": 2
+ }
+]
diff --git a/reports/RELEASE_EVIDENCE.md b/reports/RELEASE_EVIDENCE.md
new file mode 100644
index 0000000..eca2af5
--- /dev/null
+++ b/reports/RELEASE_EVIDENCE.md
@@ -0,0 +1,63 @@
+# Release Evidence
+
+## Determination
+
+**PROVISIONAL MULTI-LEAGUE F0/F1 ENGINE COMPLETE.**
+
+This bundle verifies mechanics, determinism, replay integrity, league coverage,
+reference-anchor sanity, headless execution, and the content-addressed autonomy
+surface. It does not certify real-world predictive accuracy. No licensed point-in-time
+event or tracking dataset was available.
+
+## Reference-anchor validation
+
+| League | Games | Home mean | Away mean | Mean error | Total SD error | Home z | Status |
+|---|---:|---:|---:|---:|---:|---:|---|
+| mlb | 500 | 4.942 | 4.426 | 0.086 | 0.021 | 2.58 | provisional_reference_anchor |
+| nba | 500 | 116.606 | 115.722 | 0.024 | 0.003 | 1.18 | provisional_reference_anchor |
+| wnba | 500 | 84.146 | 83.096 | 0.039 | 0.000 | 1.68 | provisional_reference_anchor |
+| ncaambb | 500 | 69.156 | 67.136 | 0.078 | 0.003 | 3.47 | provisional_reference_anchor |
+| nfl | 500 | 25.882 | 24.500 | 0.124 | 0.022 | 2.26 | provisional_reference_anchor |
+| ncaaf | 500 | 33.456 | 29.822 | 0.154 | 0.057 | 5.46 | provisional_reference_anchor |
+| nhl | 500 | 3.204 | 3.018 | 0.023 | 0.006 | 1.77 | provisional_reference_anchor |
+
+## Negative controls
+
+- Controls executed: 49
+- Failures: 0
+
+## Headless benchmark
+
+| Fidelity | League | Games | Events | Seconds | Games/second |
+|---|---|---:|---:|---:|---:|
+| F0_ANALYTICAL | mlb | 10000 | 0 | 0.136 | 73668.95 |
+| F1_EVENT | mlb | 100 | 8830 | 0.341 | 293.43 |
+| F0_ANALYTICAL | nba | 10000 | 0 | 0.143 | 69954.28 |
+| F1_EVENT | nba | 100 | 19954 | 0.455 | 219.99 |
+| F0_ANALYTICAL | wnba | 10000 | 0 | 0.159 | 63051.98 |
+| F1_EVENT | wnba | 100 | 16098 | 0.458 | 218.30 |
+| F0_ANALYTICAL | ncaambb | 10000 | 0 | 0.173 | 57822.69 |
+| F1_EVENT | ncaambb | 100 | 13938 | 0.396 | 252.47 |
+| F0_ANALYTICAL | nfl | 10000 | 0 | 0.128 | 78359.59 |
+| F1_EVENT | nfl | 100 | 16529 | 0.400 | 249.78 |
+| F0_ANALYTICAL | ncaaf | 10000 | 0 | 0.175 | 57288.01 |
+| F1_EVENT | ncaaf | 100 | 17952 | 0.420 | 237.94 |
+| F0_ANALYTICAL | nhl | 10000 | 0 | 0.150 | 66497.28 |
+| F1_EVENT | nhl | 100 | 6583 | 0.306 | 327.20 |
+
+## Reproducibility
+
+- Source manifest SHA-256: `0dcd0dffdb65bae68c3ad1f05ad37b3a1c47bfddbba13423d130c643f00f2165`
+- Every event stream is invariant-checked and SHA-256 chained during construction.
+- External replay imports reverify both the event chain and complete result envelope.
+- Same input and seed equality is exercised for every league.
+- Cross-worker batch equality is exercised by the integration suite.
+- Recursive profiles, ensembles, adaptive states, champion bundles, and promotion
+ ledgers have independent content hashes.
+- Autonomous search cannot mutate rules, evaluators, split boundaries, or source code.
+
+## Certification boundary
+
+`provisional_reference_anchor` is the strongest supported status. F2 spatial
+calibration, F3 physics/rendering, player/team models, exhaustive rulebooks, and
+held-out predictive validity remain blocked pending licensed data and scoped evidence.
diff --git a/reports/RELEASE_MANIFEST.json b/reports/RELEASE_MANIFEST.json
new file mode 100644
index 0000000..8aa7dd2
--- /dev/null
+++ b/reports/RELEASE_MANIFEST.json
@@ -0,0 +1,260 @@
+{
+ "engine_version": "0.3.0",
+ "evidence_status": "provisional_reference_anchor",
+ "league_ids": [
+ "mlb",
+ "nba",
+ "wnba",
+ "ncaambb",
+ "nfl",
+ "ncaaf",
+ "nhl"
+ ],
+ "source_files": [
+ [
+ "data/contracts/HISTORICAL_GAMES.md",
+ "253328097b260e361eefd368720b4d039ab36a2877eeb027b7acbd04f580c646"
+ ],
+ [
+ "dummy_bridge/DOMAIN_NEUTRAL_PROTOCOL.md",
+ "f612003bdf09839f6f675bb362c5cbae89c8610cfecc863b5a6749aa3a8b8f2f"
+ ],
+ [
+ "scripts/audit_autonomy.py",
+ "df7884929493a1faab7fe6b387e82beba44a0228f99addaa1399d92cfab2e61b"
+ ],
+ [
+ "scripts/audit_performance.py",
+ "a6b24c29cff64161db093c35631b16f8f85f93792752afff1b4f5926fc3c6850"
+ ],
+ [
+ "scripts/audit_stress.py",
+ "728fbce5fb0179bd5461ccc947c801d0d89a3b1faf992ff1486b6bb0e685d3c2"
+ ],
+ [
+ "scripts/build_release_evidence.py",
+ "0bc7a9d90b507bb7e8585b160cc8d6cbf159ccbc274ef960a0569775dac5375a"
+ ],
+ [
+ "src/universal_sports_engine/__init__.py",
+ "3913d4e82adc237821c9311d23987845b8cabc094c992bb60c369fa1e3b0fa77"
+ ],
+ [
+ "src/universal_sports_engine/accuracy.py",
+ "e7a299d519ef8ad45402a0dc10ca47d1571e0cb6a5adfb2f2a898d899ebb8213"
+ ],
+ [
+ "src/universal_sports_engine/adaptive.py",
+ "294d84426f0db394cb7326a33c7899389a3c54794aee8c2888ce0b4e6efe5e27"
+ ],
+ [
+ "src/universal_sports_engine/analytical.py",
+ "f4dc550bfb01a399cf37f48f83489eb1f3e20fb27bfa50d3d370851c75f04d74"
+ ],
+ [
+ "src/universal_sports_engine/autotune.py",
+ "d0b4b0fd5c95d8a87cb44750bfccba721ec94ad0352692ebcc17d859572eabe1"
+ ],
+ [
+ "src/universal_sports_engine/cli.py",
+ "cb8ef9cb378397a2cc4dd661131ab8a345e7ae65b238b5253e0a2ab393e40038"
+ ],
+ [
+ "src/universal_sports_engine/core/__init__.py",
+ "72bad1d11e7bbc22f13745be6bc0ea3cb85b799eaadc778d6ce53f42882de99f"
+ ],
+ [
+ "src/universal_sports_engine/core/event_log.py",
+ "f5f53d302611e688b47f174bd250e7cd1cefaba92b7b6c529e94c2c43439661e"
+ ],
+ [
+ "src/universal_sports_engine/core/fidelity.py",
+ "10e801d8a3239fc8c74012cde6cbd8f70c87f5d07aba1d4817314f11ca103032"
+ ],
+ [
+ "src/universal_sports_engine/core/replay_io.py",
+ "09837a230d5e9cf45e0e2b50cbc5f3fa4d349a1f940f9987dc05ea083f610c84"
+ ],
+ [
+ "src/universal_sports_engine/core/result_integrity.py",
+ "7834d5ca621d0f6a5e12062ef645e9bd133127c6417c0f2a4cfc2f66d7b1f536"
+ ],
+ [
+ "src/universal_sports_engine/core/rng.py",
+ "77ef1313cb4e8e8ccffe4eca4f4fd6e79dd99f4558dbc0f559526dc7fa3c1c6c"
+ ],
+ [
+ "src/universal_sports_engine/core/rules.py",
+ "969692c3ba895b11532252962d02cc3c44eeaac99569f8300ff5f60ea0d66db1"
+ ],
+ [
+ "src/universal_sports_engine/core/types.py",
+ "599b884a78761ff20ebfddd997dfba5b221fc0130192c6472d3b2e72bbe16716"
+ ],
+ [
+ "src/universal_sports_engine/dummy_bridge/__init__.py",
+ "013d0c67eb3017dd3da60bb689563d1e769da1c04183ce5b4f2faa6101a3752d"
+ ],
+ [
+ "src/universal_sports_engine/dummy_bridge/contracts.py",
+ "18b7c319e33dcfeaface05a3edf90758c415bfc79b3a3e8d10cd85620cd230be"
+ ],
+ [
+ "src/universal_sports_engine/league_packs/__init__.py",
+ "a285351dc558ac2bfa53458e108b21e038bfe7eae17462becf3db72b6e28fe68"
+ ],
+ [
+ "src/universal_sports_engine/league_packs/baseball.py",
+ "3001fadb8ab6d7019fbd4bc0ec497d1f4ce707b77f37c56cbf7c6465e1611590"
+ ],
+ [
+ "src/universal_sports_engine/league_packs/basketball.py",
+ "9ed6c6f6fe78fc07760a9d4aeea2809d60a4b60490ee642d0c326bccacbbe020"
+ ],
+ [
+ "src/universal_sports_engine/league_packs/common.py",
+ "1da6b20287e6b3941c75779fd239dfb4d4fbcfdc72285e2e2545c0bf3e32d53d"
+ ],
+ [
+ "src/universal_sports_engine/league_packs/football.py",
+ "5dc3f6722207809170486c7e048bd6b26b1c8e2ded356552cc79c65796dd362c"
+ ],
+ [
+ "src/universal_sports_engine/league_packs/hockey.py",
+ "3099637237c10155ee9c2c16bddf2ffef6896945714e5021432f1abf1de1306b"
+ ],
+ [
+ "src/universal_sports_engine/league_packs/registry.py",
+ "1929f573e3d534f692377c3135456557c9a2dc58920d70c6bde079dd8ec8ae17"
+ ],
+ [
+ "src/universal_sports_engine/league_packs/rule_packs.py",
+ "c6942d5094495273f34150f17488edf25d834b52b7a83aa86caf7bba60864826"
+ ],
+ [
+ "src/universal_sports_engine/reference.py",
+ "e6db7aa5a442dc13297cb95278a7b5436176d71ba77152440e192835956ae77e"
+ ],
+ [
+ "src/universal_sports_engine/season.py",
+ "39c154a839933501bffd6cd89f4017c97df1d7f5acae02236455bec3b9390bf6"
+ ],
+ [
+ "src/universal_sports_engine/simulation.py",
+ "7b4809acd99aa9c8737114500b2985504bb9d12feb588b2e570e431d45097b0e"
+ ],
+ [
+ "src/universal_sports_engine/validation.py",
+ "7a29d749f200d8c59090e2a22e337a0fd78f2ec0f1a4a022320d194ec4538992"
+ ],
+ [
+ "tests/test_accuracy.py",
+ "ab9d80d164d0de9bdd7642516ffbae0cd6e49e2345425601b7fc6e43ddb9ab62"
+ ],
+ [
+ "tests/test_analytical.py",
+ "2c5445b8cace24a8bfeda4f298d2a873f7a5f904ab0b44b5f2cf12446153b2c6"
+ ],
+ [
+ "tests/test_cli.py",
+ "a12f40db8abac0d741c77722f31dddbb8dcced1be3e225856cd215075e91ae46"
+ ],
+ [
+ "tests/test_core.py",
+ "e25832b7db56eed1aab79f0a306aff8fbf8d108f952246e8523ba2c238eba036"
+ ],
+ [
+ "tests/test_dummy_bridge.py",
+ "203b903956ef780f47c1cc901bc946235fe8b46b2604f2bd2afc232a829e5cc4"
+ ],
+ [
+ "tests/test_leagues.py",
+ "4e06ae778e8cfbcec390acccf00651c4e7c38b1d3dfc21e93c6bd15b018f4687"
+ ],
+ [
+ "tests/test_recursive_improvement.py",
+ "7a067a82c06dba39a902ac92d37cf1e0336cb28359e7b6ef0acb6091370d9f32"
+ ],
+ [
+ "tests/test_season.py",
+ "8820c1031c1045dd820ca4447edd95687b3a6a010b035fd03af216203114a068"
+ ],
+ [
+ "tests/test_validation.py",
+ "c88db08d10885e5f3de1f7af4f811fa99be75b67cd76224f0a9342a27523b7ac"
+ ],
+ [
+ ".gitattributes",
+ "1d66749d1ffae745779df1a44bd2404240ff260608514a29a39c4f07c41ec412"
+ ],
+ [
+ ".gitignore",
+ "f6665575bf293d8dfa04b53f3169f5d47822953024ff30d92ca12e7285926c65"
+ ],
+ [
+ "AGENTS.md",
+ "d7f62131fe617bad05e1fdee7fc5d689f3756d26b071126819f5476711f75897"
+ ],
+ [
+ "ARCHITECTURE.md",
+ "6843f39e844690be01bf6719ae4634e9558e69336ff92ec067774c7d121862e7"
+ ],
+ [
+ "AUTONOMOUS_IMPROVEMENT.md",
+ "b3b1bd902365962f8894e84b448372ad8fd693e04ec5220eba31bdc02a94112e"
+ ],
+ [
+ "AUTONOMY_CONFIG.json",
+ "a0a9c26b6d30a298d0f24e453124eee9bef853ea775fbb293a7b6dc2a4f1d9dc"
+ ],
+ [
+ "DATA_RIGHTS_AND_PROVENANCE.md",
+ "b90c2c5b8179241bb20c672e753629ce412ae970911efd58a1ccd239d6663ff3"
+ ],
+ [
+ "DOMAIN_NEUTRAL_ADAPTATION_READINESS.md",
+ "9f6997e284a026ab7e631d804f01580026cd5dca1672abfed1c9b7e44dde4733"
+ ],
+ [
+ "DOMAIN_NEUTRAL_KERNEL_SPEC.md",
+ "5b202d4b74981917969a2b630dc576f709efceb5c9b1f5386cae4ced8450633c"
+ ],
+ [
+ "KNOWN_LIMITATIONS.md",
+ "cea85fbdb3fdff474c3ae7bc372c73786868d0af1011d61ebebaeb75149a35e5"
+ ],
+ [
+ "LICENSE",
+ "4c6516c53530d4eeb6a4773660b7798caeff549b18549d2447a683b2f01487b3"
+ ],
+ [
+ "PRIOR_ART_REGISTRY.md",
+ "aa0eeaf6e898ee3642a4ac4c28d70d0b2e5fdc4e74ae3fcb196256a7e519a301"
+ ],
+ [
+ "pyproject.toml",
+ "f5024d21929be33b54fd178f9270cb1a205a0bd9bd646e842d5d9034e9300354"
+ ],
+ [
+ "QUALITY_GATES.yaml",
+ "1c8cfd93d827e7fa15ee705886bac4f6e7283c03499a06fe42624f7315e659a3"
+ ],
+ [
+ "README.md",
+ "9590baf3181a88e1216c99317ebda0f9a9bb6e3e04814013f83a457c977a4445"
+ ],
+ [
+ "RESEARCH_CONSTITUTION.md",
+ "2bb9bc09e63e74374e8c1ef0fb773eae74e32d0f2f234666e70b26e1e5d89ddf"
+ ],
+ [
+ "STATUS.md",
+ "bdfb72c6fa2732e02680cb9eb1d3f6812a203c35f74b4ae843d3af6a83ed1115"
+ ],
+ [
+ "TECHNOLOGY_BAKEOFF.md",
+ "2b1803c5ac8dcbe3437ea507aa7fc2c926097e0aa28afeb39a6647a36ad105d1"
+ ]
+ ],
+ "source_manifest_sha256": "0dcd0dffdb65bae68c3ad1f05ad37b3a1c47bfddbba13423d130c643f00f2165"
+}
diff --git a/reports/REPRODUCTION_REPORT.md b/reports/REPRODUCTION_REPORT.md
new file mode 100644
index 0000000..00f2478
--- /dev/null
+++ b/reports/REPRODUCTION_REPORT.md
@@ -0,0 +1,37 @@
+# Reproduction report
+
+## Result
+
+**PASS — clean version 0.3 package reproduction**
+
+The project was built as `universal_sports_engine-0.3.0-py3-none-any.whl`,
+installed into the isolated `.repro-v3-venv`, and executed from the Windows
+temporary directory without the editable development package.
+
+- Wheel SHA-256: `4A6C44A0382BF9065DCCE4CAAF333A91BCD8761E142C2AE6EDDCC990F01C9675`
+- Imported package version: `0.3.0`
+- F1 smoke simulation: NHL, seed 42.
+- F0 analytical smoke simulation: NBA, seed 42.
+- Seven-league champion bundle verification: passed.
+- Seven-record promotion-ledger hash-chain verification: passed.
+- Shadow-adapted NBA ensemble simulation: passed.
+- Embedded incumbent rollback smoke test: passed in the development environment.
+
+## Commands
+
+```powershell
+.\.venv\Scripts\python.exe -m pip wheel . --no-deps --wheel-dir dist
+python -m venv .repro-v3-venv
+.\.repro-v3-venv\Scripts\python.exe -m pip install --no-deps --force-reinstall `
+ .\dist\universal_sports_engine-0.3.0-py3-none-any.whl
+.\.repro-v3-venv\Scripts\sports-engine.exe verify-autonomy `
+ --bundle reports\autonomy_v3_fixture\champion_bundle.json `
+ --ledger reports\autonomy_v3_fixture\improvement_ledger.jsonl
+.\.repro-v3-venv\Scripts\sports-engine.exe simulate-adaptive `
+ --bundle reports\autonomy_v3_fixture\shadow_adapted_bundle.json `
+ --league nba --seed 42 --home-strength 1.0 --away-strength 1.0
+```
+
+This proves packaging, deterministic execution, adaptive checkpoint loading,
+ledger integrity, and governed ensemble simulation. It does not constitute
+independent real-world calibration.
diff --git a/reports/STRESS_AUDIT_V3.json b/reports/STRESS_AUDIT_V3.json
new file mode 100644
index 0000000..1fc942d
--- /dev/null
+++ b/reports/STRESS_AUDIT_V3.json
@@ -0,0 +1,58 @@
+[
+ {
+ "elapsed_seconds": 4.125197799992748,
+ "events": 173637,
+ "failures": 0,
+ "games": 2000,
+ "league": "mlb",
+ "maximum_events_per_game": 170
+ },
+ {
+ "elapsed_seconds": 8.791729899996426,
+ "events": 399470,
+ "failures": 0,
+ "games": 2000,
+ "league": "nba",
+ "maximum_events_per_game": 247
+ },
+ {
+ "elapsed_seconds": 7.10191549998126,
+ "events": 322910,
+ "failures": 0,
+ "games": 2000,
+ "league": "wnba",
+ "maximum_events_per_game": 213
+ },
+ {
+ "elapsed_seconds": 6.147122299997136,
+ "events": 279714,
+ "failures": 0,
+ "games": 2000,
+ "league": "ncaambb",
+ "maximum_events_per_game": 195
+ },
+ {
+ "elapsed_seconds": 6.622597000008682,
+ "events": 332517,
+ "failures": 0,
+ "games": 2000,
+ "league": "nfl",
+ "maximum_events_per_game": 300
+ },
+ {
+ "elapsed_seconds": 7.214139299991075,
+ "events": 361722,
+ "failures": 0,
+ "games": 2000,
+ "league": "ncaaf",
+ "maximum_events_per_game": 238
+ },
+ {
+ "elapsed_seconds": 2.8979713000007905,
+ "events": 133334,
+ "failures": 0,
+ "games": 2000,
+ "league": "nhl",
+ "maximum_events_per_game": 104
+ }
+]
diff --git a/reports/VALIDATION_REPORT.json b/reports/VALIDATION_REPORT.json
new file mode 100644
index 0000000..935f46d
--- /dev/null
+++ b/reports/VALIDATION_REPORT.json
@@ -0,0 +1,107 @@
+[
+ {
+ "anchor_away_mean": 4.3,
+ "anchor_home_mean": 4.55,
+ "anchor_total_sd": 4.6,
+ "games": 500,
+ "home_advantage_not_materially_reversed": true,
+ "home_advantage_z_score": 2.5791139686344238,
+ "league": "mlb",
+ "maximum_relative_error": 0.08615384615384623,
+ "observed_away_mean": 4.426,
+ "observed_home_mean": 4.942,
+ "observed_total_sd": 4.696442909266544,
+ "status": "provisional_reference_anchor",
+ "total_sd_relative_error": 0.020965849840553136
+ },
+ {
+ "anchor_away_mean": 113.0,
+ "anchor_home_mean": 116.0,
+ "anchor_total_sd": 20.0,
+ "games": 500,
+ "home_advantage_not_materially_reversed": true,
+ "home_advantage_z_score": 1.1787912709657586,
+ "league": "nba",
+ "maximum_relative_error": 0.024088495575221188,
+ "observed_away_mean": 115.722,
+ "observed_home_mean": 116.606,
+ "observed_total_sd": 19.943931808948808,
+ "status": "provisional_reference_anchor",
+ "total_sd_relative_error": 0.0028034095525596215
+ },
+ {
+ "anchor_away_mean": 80.0,
+ "anchor_home_mean": 82.0,
+ "anchor_total_sd": 17.5,
+ "games": 500,
+ "home_advantage_not_materially_reversed": true,
+ "home_advantage_z_score": 1.6769504546694531,
+ "league": "wnba",
+ "maximum_relative_error": 0.03870000000000005,
+ "observed_away_mean": 83.096,
+ "observed_home_mean": 84.146,
+ "observed_total_sd": 17.492153555237273,
+ "status": "provisional_reference_anchor",
+ "total_sd_relative_error": 0.0004483682721558223
+ },
+ {
+ "anchor_away_mean": 72.0,
+ "anchor_home_mean": 75.0,
+ "anchor_total_sd": 16.5,
+ "games": 500,
+ "home_advantage_not_materially_reversed": true,
+ "home_advantage_z_score": 3.4668051528335053,
+ "league": "ncaambb",
+ "maximum_relative_error": 0.07791999999999992,
+ "observed_away_mean": 67.136,
+ "observed_home_mean": 69.156,
+ "observed_total_sd": 16.456571210309882,
+ "status": "provisional_reference_anchor",
+ "total_sd_relative_error": 0.002632047860007164
+ },
+ {
+ "anchor_away_mean": 21.8,
+ "anchor_home_mean": 23.5,
+ "anchor_total_sd": 13.7,
+ "games": 500,
+ "home_advantage_not_materially_reversed": true,
+ "home_advantage_z_score": 2.259980386724432,
+ "league": "nfl",
+ "maximum_relative_error": 0.12385321100917428,
+ "observed_away_mean": 24.5,
+ "observed_home_mean": 25.882,
+ "observed_total_sd": 14.002859565103122,
+ "status": "provisional_reference_anchor",
+ "total_sd_relative_error": 0.022106537598768117
+ },
+ {
+ "anchor_away_mean": 26.5,
+ "anchor_home_mean": 29.0,
+ "anchor_total_sd": 15.7,
+ "games": 500,
+ "home_advantage_not_materially_reversed": true,
+ "home_advantage_z_score": 5.464024826085687,
+ "league": "ncaaf",
+ "maximum_relative_error": 0.1536551724137932,
+ "observed_away_mean": 29.822,
+ "observed_home_mean": 33.456,
+ "observed_total_sd": 14.809750706882273,
+ "status": "provisional_reference_anchor",
+ "total_sd_relative_error": 0.05670377663170232
+ },
+ {
+ "anchor_away_mean": 2.95,
+ "anchor_home_mean": 3.2,
+ "anchor_total_sd": 2.3,
+ "games": 500,
+ "home_advantage_not_materially_reversed": true,
+ "home_advantage_z_score": 1.7722479332139913,
+ "league": "nhl",
+ "maximum_relative_error": 0.023050847457626988,
+ "observed_away_mean": 3.018,
+ "observed_home_mean": 3.204,
+ "observed_total_sd": 2.3144580359125113,
+ "status": "provisional_reference_anchor",
+ "total_sd_relative_error": 0.006286102570657171
+ }
+]
diff --git a/reports/autonomy_v3_fixture/champion_bundle.json b/reports/autonomy_v3_fixture/champion_bundle.json
new file mode 100644
index 0000000..41dcdde
--- /dev/null
+++ b/reports/autonomy_v3_fixture/champion_bundle.json
@@ -0,0 +1,937 @@
+{
+ "bundle_hash": "56c5551d36093708f6da5ad0165f968a12c69c7ede7216959f7a4d532a40d754",
+ "champions": [
+ {
+ "ensemble": {
+ "ensemble_hash": "bb0b6a4184ebbf8489abaf3dc3df077d280c14d888340b59c2871215f6df8360",
+ "evidence_status": "provisional_reference_anchor",
+ "league": "mlb",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 4.3,
+ "base_home_score": 4.55,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "mlb",
+ "margin_sd": 4.4,
+ "parent_hash": "",
+ "profile_hash": "ed4a36ddf530bc1e400bae06859869e1b8b9bf4c542f53a193c39d949638d53e",
+ "total_score_sd": 4.6
+ }
+ ],
+ "weights": [
+ 1.0
+ ]
+ },
+ "league": "mlb",
+ "promoted": false,
+ "rollback_ensemble": {
+ "ensemble_hash": "bb0b6a4184ebbf8489abaf3dc3df077d280c14d888340b59c2871215f6df8360",
+ "evidence_status": "provisional_reference_anchor",
+ "league": "mlb",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 4.3,
+ "base_home_score": 4.55,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "mlb",
+ "margin_sd": 4.4,
+ "parent_hash": "",
+ "profile_hash": "ed4a36ddf530bc1e400bae06859869e1b8b9bf4c542f53a193c39d949638d53e",
+ "total_score_sd": 4.6
+ }
+ ],
+ "weights": [
+ 1.0
+ ]
+ },
+ "rollback_state": {
+ "drift_score": 0.050688478956998094,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "bb0b6a4184ebbf8489abaf3dc3df077d280c14d888340b59c2871215f6df8360",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 0.8869204367171584,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 5.59425099372921,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 5.8778150675050185,
+ "state_hash": "a23ac9f2ccc36db8368dcd341b0025f12d6d2b188c95ca9013b1dc61b461e78a",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.0
+ ]
+ },
+ "state": {
+ "drift_score": 0.050688478956998094,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "bb0b6a4184ebbf8489abaf3dc3df077d280c14d888340b59c2871215f6df8360",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 0.8869204367171584,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 5.59425099372921,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 5.8778150675050185,
+ "state_hash": "a23ac9f2ccc36db8368dcd341b0025f12d6d2b188c95ca9013b1dc61b461e78a",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.0
+ ]
+ }
+ },
+ {
+ "ensemble": {
+ "ensemble_hash": "60e7da6020d67de678c0d044f300847fde90bf16161917510b08c83bfd5dbe96",
+ "evidence_status": "chronological_calibration_challenger",
+ "league": "nba",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 113.0,
+ "base_home_score": 116.0,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "nba",
+ "margin_sd": 15.0,
+ "parent_hash": "",
+ "profile_hash": "1fd107dd93cec7f199c4979e7334f2ad2c7e7d61e6e5d3fa7a7c6741138e40d1",
+ "total_score_sd": 20.0
+ },
+ {
+ "away_strength_exponent": 0.9632460782428364,
+ "base_away_score": 100.41120048415034,
+ "base_home_score": 101.40842755264546,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 1.1035181164801218,
+ "league": "nba",
+ "margin_sd": 13.736474631089353,
+ "parent_hash": "d4336fc445a68de29aec9f851052ee18e00a6c18e7198fda34d832e4a727eafd",
+ "profile_hash": "6dabbdf2c5066b2dc80eb6e6088fbe21f308472a7241c3d76a36ea7ae27b0dc9",
+ "total_score_sd": 15.530808786290953
+ },
+ {
+ "away_strength_exponent": 0.9299864332685756,
+ "base_away_score": 99.12089973217256,
+ "base_home_score": 102.60460634910284,
+ "evidence_status": "train_search_candidate",
+ "generation": 7,
+ "home_strength_exponent": 1.0374456736407256,
+ "league": "nba",
+ "margin_sd": 14.476747331295748,
+ "parent_hash": "d4336fc445a68de29aec9f851052ee18e00a6c18e7198fda34d832e4a727eafd",
+ "profile_hash": "2c3b39a22523f4f245dcd1afe8fcfc54544020073f6153bd180207f50ca0fa67",
+ "total_score_sd": 15.986652973245818
+ },
+ {
+ "away_strength_exponent": 0.9314639467993735,
+ "base_away_score": 97.55462255575519,
+ "base_home_score": 100.60692741111606,
+ "evidence_status": "train_search_candidate",
+ "generation": 6,
+ "home_strength_exponent": 1.0481985521298671,
+ "league": "nba",
+ "margin_sd": 13.538006034660736,
+ "parent_hash": "1f29dc288a020ac6049537b27f5d91603e2e548bb8639e20fcd8c9527fa9b748",
+ "profile_hash": "d4336fc445a68de29aec9f851052ee18e00a6c18e7198fda34d832e4a727eafd",
+ "total_score_sd": 16.76275018651739
+ },
+ {
+ "away_strength_exponent": 0.8862112258764434,
+ "base_away_score": 100.34400852330234,
+ "base_home_score": 99.90111885665915,
+ "evidence_status": "train_search_candidate",
+ "generation": 7,
+ "home_strength_exponent": 0.9978232275893777,
+ "league": "nba",
+ "margin_sd": 13.709770977740531,
+ "parent_hash": "4cc9fa6c37e99b992fc73dec931c77bbd815b6a14538deb5d0471d5dfe18a3b3",
+ "profile_hash": "2b9ae85a9ff77cddc6e95f95feff238a5aad863eb1b5a6d4d0c1682859f773cf",
+ "total_score_sd": 14.728999472122727
+ },
+ {
+ "away_strength_exponent": 0.9168426579759286,
+ "base_away_score": 98.08693111402029,
+ "base_home_score": 100.24510182059633,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 1.029985233214439,
+ "league": "nba",
+ "margin_sd": 13.914503225184157,
+ "parent_hash": "2c3b39a22523f4f245dcd1afe8fcfc54544020073f6153bd180207f50ca0fa67",
+ "profile_hash": "c24f67abab0bf80575320bbbed67381f38b4de2aeee0cfe291bee9e80ceba669",
+ "total_score_sd": 16.713986694619834
+ }
+ ],
+ "weights": [
+ 0.12893045230055183,
+ 0.17538891395996567,
+ 0.1747196187644406,
+ 0.17386258202490054,
+ 0.17362605222135616,
+ 0.17347238072878526
+ ]
+ },
+ "league": "nba",
+ "promoted": true,
+ "rollback_ensemble": {
+ "ensemble_hash": "938868d720f17e6b997358c0a52254af174a1b3081193720225c3ca7e3eda934",
+ "evidence_status": "provisional_reference_anchor",
+ "league": "nba",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 113.0,
+ "base_home_score": 116.0,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "nba",
+ "margin_sd": 15.0,
+ "parent_hash": "",
+ "profile_hash": "1fd107dd93cec7f199c4979e7334f2ad2c7e7d61e6e5d3fa7a7c6741138e40d1",
+ "total_score_sd": 20.0
+ }
+ ],
+ "weights": [
+ 1.0
+ ]
+ },
+ "rollback_state": {
+ "drift_score": 0.0,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "938868d720f17e6b997358c0a52254af174a1b3081193720225c3ca7e3eda934",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 1.1502737988572285,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 9.584379101566844,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 9.00479793127273,
+ "state_hash": "8938e17f435856b6ce780263706e625583f33790ccd311fee85a1564aa1988dd",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.0
+ ]
+ },
+ "state": {
+ "drift_score": 0.0,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "60e7da6020d67de678c0d044f300847fde90bf16161917510b08c83bfd5dbe96",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 0.9231163463866361,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.475867039772714,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 8.262049524590857,
+ "state_hash": "fe671acbd9f09da2f1984ffa82fa65ab28b4110cb59498739477866e598f119d",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 5.513615121909581e-07,
+ 0.43303118967699145,
+ 0.16262743922906853,
+ 0.13862691445333053,
+ 0.14035629144863276,
+ 0.1253576138304646
+ ]
+ }
+ },
+ {
+ "ensemble": {
+ "ensemble_hash": "110e0a2b1d912b65c9c8e2421251514d29e036503be2191a6a19c5418d16b42a",
+ "evidence_status": "provisional_reference_anchor",
+ "league": "ncaaf",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 26.5,
+ "base_home_score": 29.0,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "ncaaf",
+ "margin_sd": 18.0,
+ "parent_hash": "",
+ "profile_hash": "6c3ad3401f75976c8a0cc1301c7aa9d9ba28a4d78b9bd5ee2432bf29e58493f7",
+ "total_score_sd": 15.7
+ }
+ ],
+ "weights": [
+ 1.0
+ ]
+ },
+ "league": "ncaaf",
+ "promoted": false,
+ "rollback_ensemble": {
+ "ensemble_hash": "110e0a2b1d912b65c9c8e2421251514d29e036503be2191a6a19c5418d16b42a",
+ "evidence_status": "provisional_reference_anchor",
+ "league": "ncaaf",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 26.5,
+ "base_home_score": 29.0,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "ncaaf",
+ "margin_sd": 18.0,
+ "parent_hash": "",
+ "profile_hash": "6c3ad3401f75976c8a0cc1301c7aa9d9ba28a4d78b9bd5ee2432bf29e58493f7",
+ "total_score_sd": 15.7
+ }
+ ],
+ "weights": [
+ 1.0
+ ]
+ },
+ "rollback_state": {
+ "drift_score": 0.053373359494810986,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "110e0a2b1d912b65c9c8e2421251514d29e036503be2191a6a19c5418d16b42a",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 0.9607894391523236,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.821992883967974,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 9.292852281624661,
+ "state_hash": "6490ed8bb46c72d47e410317f52bba03128f9076dbe23088cbd0748735b8b91b",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.0
+ ]
+ },
+ "state": {
+ "drift_score": 0.053373359494810986,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "110e0a2b1d912b65c9c8e2421251514d29e036503be2191a6a19c5418d16b42a",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 0.9607894391523236,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.821992883967974,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 9.292852281624661,
+ "state_hash": "6490ed8bb46c72d47e410317f52bba03128f9076dbe23088cbd0748735b8b91b",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.0
+ ]
+ }
+ },
+ {
+ "ensemble": {
+ "ensemble_hash": "3a26b1869b41e662ecdfe044a54229c6e5998280f88a6ad5003326302350654e",
+ "evidence_status": "chronological_calibration_challenger",
+ "league": "ncaambb",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 72.0,
+ "base_home_score": 75.0,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "ncaambb",
+ "margin_sd": 14.0,
+ "parent_hash": "",
+ "profile_hash": "14be1ec209dc6acf4030c480c7c2c6abf250986580e5da75595419c8fd8028df",
+ "total_score_sd": 16.5
+ },
+ {
+ "away_strength_exponent": 0.9380995927689169,
+ "base_away_score": 64.26338685281874,
+ "base_home_score": 67.90736863209588,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 1.1198826403419602,
+ "league": "ncaambb",
+ "margin_sd": 12.337242613541385,
+ "parent_hash": "d908371efab1b1058ff372457736decc2f22f9d69723d762431e794c4f4582e3",
+ "profile_hash": "05bcc37afeab1ab4bf15ea01c88cd88d9e19e259e85a843ba6904dc94e5285ee",
+ "total_score_sd": 11.844982854797419
+ },
+ {
+ "away_strength_exponent": 0.9839084920688369,
+ "base_away_score": 64.17862932003789,
+ "base_home_score": 66.40814600980535,
+ "evidence_status": "train_search_candidate",
+ "generation": 7,
+ "home_strength_exponent": 1.1265354070594922,
+ "league": "ncaambb",
+ "margin_sd": 11.751801481101191,
+ "parent_hash": "5052bec2704f4278b8055686fdfd6fdaca864456ff8480e6bd1c3a16ff8cd5c2",
+ "profile_hash": "d908371efab1b1058ff372457736decc2f22f9d69723d762431e794c4f4582e3",
+ "total_score_sd": 12.527208607031197
+ },
+ {
+ "away_strength_exponent": 1.0302789332906102,
+ "base_away_score": 64.56603709857632,
+ "base_home_score": 68.11959848451264,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 1.15845619003206,
+ "league": "ncaambb",
+ "margin_sd": 12.172650135194955,
+ "parent_hash": "d908371efab1b1058ff372457736decc2f22f9d69723d762431e794c4f4582e3",
+ "profile_hash": "a3426257638d3914687ea87b35c7948a9df8423501f8509cc563d4635f364bad",
+ "total_score_sd": 12.250367245233734
+ },
+ {
+ "away_strength_exponent": 0.9757805013766029,
+ "base_away_score": 64.69153447008274,
+ "base_home_score": 67.3019953859376,
+ "evidence_status": "train_search_candidate",
+ "generation": 6,
+ "home_strength_exponent": 1.0463799843916333,
+ "league": "ncaambb",
+ "margin_sd": 12.360366882633027,
+ "parent_hash": "035fdaf6642f08d5f653660bf422cf514301df099700740c1740ff66f014aa95",
+ "profile_hash": "5052bec2704f4278b8055686fdfd6fdaca864456ff8480e6bd1c3a16ff8cd5c2",
+ "total_score_sd": 13.12846794130971
+ },
+ {
+ "away_strength_exponent": 1.0525771945812439,
+ "base_away_score": 65.56062542041047,
+ "base_home_score": 67.05886346685132,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 1.0249276075178801,
+ "league": "ncaambb",
+ "margin_sd": 11.814617284868469,
+ "parent_hash": "5052bec2704f4278b8055686fdfd6fdaca864456ff8480e6bd1c3a16ff8cd5c2",
+ "profile_hash": "d5abde343917aae55c5b655aed7e5ce5542a8d6e94ebb6cc5b1dff7aef5b914b",
+ "total_score_sd": 12.842103349942267
+ }
+ ],
+ "weights": [
+ 0.15204731462607787,
+ 0.17053030010320389,
+ 0.17008865902417303,
+ 0.1698776799805041,
+ 0.16875167581778863,
+ 0.16870437044825248
+ ]
+ },
+ "league": "ncaambb",
+ "promoted": true,
+ "rollback_ensemble": {
+ "ensemble_hash": "f4a907f61caeed291d4ccf147414e9c0e97aaef2acbf4a47d08961d80fb12539",
+ "evidence_status": "provisional_reference_anchor",
+ "league": "ncaambb",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 72.0,
+ "base_home_score": 75.0,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "ncaambb",
+ "margin_sd": 14.0,
+ "parent_hash": "",
+ "profile_hash": "14be1ec209dc6acf4030c480c7c2c6abf250986580e5da75595419c8fd8028df",
+ "total_score_sd": 16.5
+ }
+ ],
+ "weights": [
+ 1.0
+ ]
+ },
+ "rollback_state": {
+ "drift_score": 0.0,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "f4a907f61caeed291d4ccf147414e9c0e97aaef2acbf4a47d08961d80fb12539",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 1.0000000000000013,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.386494742786283,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 8.246116288876184,
+ "state_hash": "b00bf20e38b236488432ebaaa42691474cd68631fd141127185217573f05d4f2",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.0
+ ]
+ },
+ "state": {
+ "drift_score": 0.0,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "3a26b1869b41e662ecdfe044a54229c6e5998280f88a6ad5003326302350654e",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 0.9607894391523251,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.174282931387665,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 8.008633532956152,
+ "state_hash": "924515d3adfcde4094160bbe9a1c1741be83320aad2c0d1e322f724c309fcb9d",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 0.001155014984004925,
+ 0.19050882700932764,
+ 0.19279742459698684,
+ 0.14440496188814017,
+ 0.26188724112414913,
+ 0.20924653039739127
+ ]
+ }
+ },
+ {
+ "ensemble": {
+ "ensemble_hash": "52cc748b0f03d805bc32644c746152d71b8878f6cb3e9e2e6df533e3cb3718e2",
+ "evidence_status": "provisional_reference_anchor",
+ "league": "nfl",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 21.8,
+ "base_home_score": 23.5,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "nfl",
+ "margin_sd": 14.0,
+ "parent_hash": "",
+ "profile_hash": "2cf12a1c59550d09aad4853366ee45da48461195286aba2fc665167a2d0accd0",
+ "total_score_sd": 13.7
+ }
+ ],
+ "weights": [
+ 1.0
+ ]
+ },
+ "league": "nfl",
+ "promoted": false,
+ "rollback_ensemble": {
+ "ensemble_hash": "52cc748b0f03d805bc32644c746152d71b8878f6cb3e9e2e6df533e3cb3718e2",
+ "evidence_status": "provisional_reference_anchor",
+ "league": "nfl",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 21.8,
+ "base_home_score": 23.5,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "nfl",
+ "margin_sd": 14.0,
+ "parent_hash": "",
+ "profile_hash": "2cf12a1c59550d09aad4853366ee45da48461195286aba2fc665167a2d0accd0",
+ "total_score_sd": 13.7
+ }
+ ],
+ "weights": [
+ 1.0
+ ]
+ },
+ "rollback_state": {
+ "drift_score": 0.009386081910553939,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "52cc748b0f03d805bc32644c746152d71b8878f6cb3e9e2e6df533e3cb3718e2",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 0.923116346386637,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.229562938300864,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 8.306806290127815,
+ "state_hash": "c56bdf6245fc5a57c735db00e6d448c6670f5a96632121cbfa3e9d7e30dd0e91",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.0
+ ]
+ },
+ "state": {
+ "drift_score": 0.009386081910553939,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "52cc748b0f03d805bc32644c746152d71b8878f6cb3e9e2e6df533e3cb3718e2",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 0.923116346386637,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.229562938300864,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 8.306806290127815,
+ "state_hash": "c56bdf6245fc5a57c735db00e6d448c6670f5a96632121cbfa3e9d7e30dd0e91",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.0
+ ]
+ }
+ },
+ {
+ "ensemble": {
+ "ensemble_hash": "b4268f4251d62981ee852625c817f48947e9e12aecc39da1b77d4ff869c86289",
+ "evidence_status": "chronological_calibration_challenger",
+ "league": "nhl",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 2.95,
+ "base_home_score": 3.2,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "nhl",
+ "margin_sd": 2.4,
+ "parent_hash": "",
+ "profile_hash": "dd2f407da7fec8a4017fec2f6e311c3010d4f874c1d156f9dc4a4d9ba25576c3",
+ "total_score_sd": 2.3
+ },
+ {
+ "away_strength_exponent": 1.3618435036484602,
+ "base_away_score": 2.8140096579368463,
+ "base_home_score": 2.9827709409299437,
+ "evidence_status": "train_search_candidate",
+ "generation": 6,
+ "home_strength_exponent": 1.0164249111888564,
+ "league": "nhl",
+ "margin_sd": 2.4067107458645474,
+ "parent_hash": "c0f59c1041dfffbcb83db90b24931ee0acf8315cd86d375cd903b1869716224f",
+ "profile_hash": "560b8c3bf885c09aba0c04204376e3091a28ca9006785a1e982d822fd4f20158",
+ "total_score_sd": 1.9217750431804201
+ },
+ {
+ "away_strength_exponent": 1.3918430671368498,
+ "base_away_score": 2.8395546024633056,
+ "base_home_score": 3.001160815782975,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 0.9742513551643636,
+ "league": "nhl",
+ "margin_sd": 2.347437453084234,
+ "parent_hash": "7e6cc68f9f179e60b9ad230a27f90dbac843e9dfc33f83849a71a51a37077069",
+ "profile_hash": "b792aed5100d5cfef059e56fe733dc686f999130857572ef57702f98220e5374",
+ "total_score_sd": 1.9848807761955292
+ },
+ {
+ "away_strength_exponent": 1.3675649819385032,
+ "base_away_score": 2.67379397546478,
+ "base_home_score": 3.2244694632163426,
+ "evidence_status": "train_search_candidate",
+ "generation": 5,
+ "home_strength_exponent": 0.9979113276154296,
+ "league": "nhl",
+ "margin_sd": 2.315479052327515,
+ "parent_hash": "3e88d5bd7565e8748490af5a78d84b19a8534868a6331d4d1752f34943540487",
+ "profile_hash": "c0f59c1041dfffbcb83db90b24931ee0acf8315cd86d375cd903b1869716224f",
+ "total_score_sd": 1.8514937320015388
+ },
+ {
+ "away_strength_exponent": 1.365373323994108,
+ "base_away_score": 2.6479224044804157,
+ "base_home_score": 3.0420403168143237,
+ "evidence_status": "train_search_candidate",
+ "generation": 5,
+ "home_strength_exponent": 0.8190424527874777,
+ "league": "nhl",
+ "margin_sd": 2.469930832788603,
+ "parent_hash": "e20a271760ee2ecb08354c7be8fa7b0533bc22ccf66bb8691f131706d6d4193d",
+ "profile_hash": "16e8f92eddd415582a8ca2282946b318fe60e8845d896d93538b603bc8cd0555",
+ "total_score_sd": 1.754941135672797
+ },
+ {
+ "away_strength_exponent": 1.444774898245588,
+ "base_away_score": 2.8087224671677236,
+ "base_home_score": 2.900908465085074,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 0.9764064324855087,
+ "league": "nhl",
+ "margin_sd": 2.4088026880950175,
+ "parent_hash": "560b8c3bf885c09aba0c04204376e3091a28ca9006785a1e982d822fd4f20158",
+ "profile_hash": "cbd5bb21fef457140e843a9455f9d3d073749dc621ad2bef307a40f02fe73c53",
+ "total_score_sd": 1.8330168778160287
+ }
+ ],
+ "weights": [
+ 0.16286673514032046,
+ 0.16755705994655176,
+ 0.16752559730854746,
+ 0.1673849214822694,
+ 0.16737507931387444,
+ 0.1672906068084365
+ ]
+ },
+ "league": "nhl",
+ "promoted": true,
+ "rollback_ensemble": {
+ "ensemble_hash": "382ec0d5185a96f540f91839c8bd6328d408d70a8ec1f16352aa22553c05bcfb",
+ "evidence_status": "provisional_reference_anchor",
+ "league": "nhl",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 2.95,
+ "base_home_score": 3.2,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "nhl",
+ "margin_sd": 2.4,
+ "parent_hash": "",
+ "profile_hash": "dd2f407da7fec8a4017fec2f6e311c3010d4f874c1d156f9dc4a4d9ba25576c3",
+ "total_score_sd": 2.3
+ }
+ ],
+ "weights": [
+ 1.0
+ ]
+ },
+ "rollback_state": {
+ "drift_score": 0.0,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "382ec0d5185a96f540f91839c8bd6328d408d70a8ec1f16352aa22553c05bcfb",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 0.9801986733067568,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 4.723961751695468,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 4.6298625684220225,
+ "state_hash": "7ce259e0d6f333426389c555b9f568c802b7265ae0ac4a6a55ba9f98184c8ee5",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.0
+ ]
+ },
+ "state": {
+ "drift_score": 0.0,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "b4268f4251d62981ee852625c817f48947e9e12aecc39da1b77d4ff869c86289",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 1.0000000000000007,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 4.686936849303858,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 4.605010305685448,
+ "state_hash": "9e103f41a8cf8181c03bde20e2b260ff7daa3ca261c7c760e94c10dca68cc368",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 0.10302384802689585,
+ 0.18136314556312605,
+ 0.15845422350790386,
+ 0.20162059073033012,
+ 0.19463378905316608,
+ 0.16090440311857798
+ ]
+ }
+ },
+ {
+ "ensemble": {
+ "ensemble_hash": "369bd1fab70c4fe9c443214b61e5bb1297947388fae8402061d599b6dc5a975d",
+ "evidence_status": "chronological_calibration_challenger",
+ "league": "wnba",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 80.0,
+ "base_home_score": 82.0,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "wnba",
+ "margin_sd": 14.0,
+ "parent_hash": "",
+ "profile_hash": "a9efcb5f3219e8e9a3df4fdce3b3f767165faa82fe41cf874bdb0716548bb4d9",
+ "total_score_sd": 17.5
+ },
+ {
+ "away_strength_exponent": 1.0251595474377284,
+ "base_away_score": 72.11403431035531,
+ "base_home_score": 71.69042161368746,
+ "evidence_status": "train_search_candidate",
+ "generation": 7,
+ "home_strength_exponent": 1.0938685005129976,
+ "league": "wnba",
+ "margin_sd": 12.553668307327136,
+ "parent_hash": "468447632d3bbfb0286c4335ad436b5f32c841251c8614e5f2096d0b5dbf0a3f",
+ "profile_hash": "af6c47cb9cc880f80388c052e42e219dc4055b7d2c8b6e1346332703b49299e5",
+ "total_score_sd": 13.255930520302046
+ },
+ {
+ "away_strength_exponent": 1.0981336628870195,
+ "base_away_score": 71.11342291633342,
+ "base_home_score": 73.62693210352198,
+ "evidence_status": "train_search_candidate",
+ "generation": 7,
+ "home_strength_exponent": 1.1420227255585949,
+ "league": "wnba",
+ "margin_sd": 12.523765694931425,
+ "parent_hash": "7d2a641dbd76ac6fde3dfa526718e79569f129327958d60c3dfafc464b75af97",
+ "profile_hash": "b83f84e526bc77753ff0561968a83ca3f84f62dad23a54b08c2869b88226c810",
+ "total_score_sd": 13.124434195991878
+ },
+ {
+ "away_strength_exponent": 0.9827239039722672,
+ "base_away_score": 73.07586506043492,
+ "base_home_score": 73.49995936972549,
+ "evidence_status": "train_search_candidate",
+ "generation": 7,
+ "home_strength_exponent": 1.060463397601755,
+ "league": "wnba",
+ "margin_sd": 11.322075003472191,
+ "parent_hash": "02a8002ff7041946836ce1a1fcb8f53773f3b838801f82797911d7fbf267efec",
+ "profile_hash": "6b7ed5b7bfddee7d6ec43ca6649a0fd953a0954c5a818b269d146c55b54ea0e2",
+ "total_score_sd": 13.178399018766651
+ },
+ {
+ "away_strength_exponent": 0.9391411924229954,
+ "base_away_score": 73.82314278504273,
+ "base_home_score": 72.09561563722342,
+ "evidence_status": "train_search_candidate",
+ "generation": 6,
+ "home_strength_exponent": 1.1340765001951492,
+ "league": "wnba",
+ "margin_sd": 12.028397269421774,
+ "parent_hash": "ab7556213fe56f2a8c712da7df880059839437bfee109b7996749fcea6802355",
+ "profile_hash": "5fb5c12d474e17f2c2719e637aa37a3fb53d24a5dda665aa15e1c8ce0cc9961b",
+ "total_score_sd": 14.119914546223248
+ },
+ {
+ "away_strength_exponent": 1.0428759542867176,
+ "base_away_score": 73.34588663690329,
+ "base_home_score": 70.67653549724727,
+ "evidence_status": "train_search_candidate",
+ "generation": 6,
+ "home_strength_exponent": 1.177066395306101,
+ "league": "wnba",
+ "margin_sd": 12.30699982423615,
+ "parent_hash": "7d2a641dbd76ac6fde3dfa526718e79569f129327958d60c3dfafc464b75af97",
+ "profile_hash": "468447632d3bbfb0286c4335ad436b5f32c841251c8614e5f2096d0b5dbf0a3f",
+ "total_score_sd": 13.296762898729602
+ }
+ ],
+ "weights": [
+ 0.14546085482667262,
+ 0.1713210376892588,
+ 0.17089076167696657,
+ 0.1708509658434923,
+ 0.17074437378062704,
+ 0.17073200618298265
+ ]
+ },
+ "league": "wnba",
+ "promoted": true,
+ "rollback_ensemble": {
+ "ensemble_hash": "92022b12c8dd03d4fb005a8a84b4041b3370ee4e401e2e281230d8f6c3b3d284",
+ "evidence_status": "provisional_reference_anchor",
+ "league": "wnba",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 80.0,
+ "base_home_score": 82.0,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "wnba",
+ "margin_sd": 14.0,
+ "parent_hash": "",
+ "profile_hash": "a9efcb5f3219e8e9a3df4fdce3b3f767165faa82fe41cf874bdb0716548bb4d9",
+ "total_score_sd": 17.5
+ }
+ ],
+ "weights": [
+ 1.0
+ ]
+ },
+ "rollback_state": {
+ "drift_score": 0.0,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "92022b12c8dd03d4fb005a8a84b4041b3370ee4e401e2e281230d8f6c3b3d284",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 1.06183654654536,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.828494403135926,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 8.776294316432912,
+ "state_hash": "bb00abb17fee66e3eb9152039b5e33447479ed0e079dd11c90c8fca060eb8d21",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.0
+ ]
+ },
+ "state": {
+ "drift_score": 0.0,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "369bd1fab70c4fe9c443214b61e5bb1297947388fae8402061d599b6dc5a975d",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 1.0,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.093222299641932,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 8.024674327270455,
+ "state_hash": "b5389b73b296d8ff3307fa1679ea4534b3e0cdb82aba2cf0f5a58625c2587f88",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.500943057167728e-05,
+ 0.2966973670938307,
+ 0.07172853425048047,
+ 0.11683643807084605,
+ 0.25589695988228717,
+ 0.25882569127198385
+ ]
+ }
+ }
+ ],
+ "created_at": "2036-11-01T15:00:00+00:00",
+ "protocol_version": "recursive-calibration-v1"
+}
diff --git a/reports/autonomy_v3_fixture/improvement_ledger.jsonl b/reports/autonomy_v3_fixture/improvement_ledger.jsonl
new file mode 100644
index 0000000..4dd207e
--- /dev/null
+++ b/reports/autonomy_v3_fixture/improvement_ledger.jsonl
@@ -0,0 +1,7 @@
+{"bundle_hash":"56c5551d36093708f6da5ad0165f968a12c69c7ede7216959f7a4d532a40d754","challenger_ensemble_hash":"9bab62c591710731cbd22bded37c374b67f4e1696b2d7e5c9c84dea7a104faef","decision":"retained_incumbent:brier_guardrail_failed","incumbent_ensemble_hash":"bb0b6a4184ebbf8489abaf3dc3df077d280c14d888340b59c2871215f6df8360","league":"mlb","previous_hash":"0000000000000000000000000000000000000000000000000000000000000000","promoted":false,"record_hash":"ec6c2c6f847bda1adc27132ce13c22f5601223e9fb846fdf205f5a5fa369289a","relative_improvement":0.04197394890142503,"selected_ensemble_hash":"bb0b6a4184ebbf8489abaf3dc3df077d280c14d888340b59c2871215f6df8360","sequence":0}
+{"bundle_hash":"56c5551d36093708f6da5ad0165f968a12c69c7ede7216959f7a4d532a40d754","challenger_ensemble_hash":"60e7da6020d67de678c0d044f300847fde90bf16161917510b08c83bfd5dbe96","decision":"promoted","incumbent_ensemble_hash":"938868d720f17e6b997358c0a52254af174a1b3081193720225c3ca7e3eda934","league":"nba","previous_hash":"ec6c2c6f847bda1adc27132ce13c22f5601223e9fb846fdf205f5a5fa369289a","promoted":true,"record_hash":"800494d7a652c06af1289cd9a0844edff4ad8138e70c3cc5b4071bbea7576b74","relative_improvement":0.11410288763501682,"selected_ensemble_hash":"60e7da6020d67de678c0d044f300847fde90bf16161917510b08c83bfd5dbe96","sequence":1}
+{"bundle_hash":"56c5551d36093708f6da5ad0165f968a12c69c7ede7216959f7a4d532a40d754","challenger_ensemble_hash":"dcfcefe31dbce66dfd8f5eeb5a1490dc505fd383498a0b0a641ed2b486e155a1","decision":"retained_incumbent:minimum_relative_improvement_not_met","incumbent_ensemble_hash":"110e0a2b1d912b65c9c8e2421251514d29e036503be2191a6a19c5418d16b42a","league":"ncaaf","previous_hash":"800494d7a652c06af1289cd9a0844edff4ad8138e70c3cc5b4071bbea7576b74","promoted":false,"record_hash":"5d38dc91cb98cc6bf5adf95a706ee375d308f33dd07b8360da533029f4ecc391","relative_improvement":0.005437533472869828,"selected_ensemble_hash":"110e0a2b1d912b65c9c8e2421251514d29e036503be2191a6a19c5418d16b42a","sequence":2}
+{"bundle_hash":"56c5551d36093708f6da5ad0165f968a12c69c7ede7216959f7a4d532a40d754","challenger_ensemble_hash":"3a26b1869b41e662ecdfe044a54229c6e5998280f88a6ad5003326302350654e","decision":"promoted","incumbent_ensemble_hash":"f4a907f61caeed291d4ccf147414e9c0e97aaef2acbf4a47d08961d80fb12539","league":"ncaambb","previous_hash":"5d38dc91cb98cc6bf5adf95a706ee375d308f33dd07b8360da533029f4ecc391","promoted":true,"record_hash":"663bab0f65c38070a1ad776a8f3411bf4dd6969e8d3c83cc4a6609d0a99ddcd4","relative_improvement":0.04225006993986202,"selected_ensemble_hash":"3a26b1869b41e662ecdfe044a54229c6e5998280f88a6ad5003326302350654e","sequence":3}
+{"bundle_hash":"56c5551d36093708f6da5ad0165f968a12c69c7ede7216959f7a4d532a40d754","challenger_ensemble_hash":"3998dbc995c7a222b6b34536892eb79abfcf27282bf679a7177ff9539d1f2805","decision":"retained_incumbent:minimum_relative_improvement_not_met","incumbent_ensemble_hash":"52cc748b0f03d805bc32644c746152d71b8878f6cb3e9e2e6df533e3cb3718e2","league":"nfl","previous_hash":"663bab0f65c38070a1ad776a8f3411bf4dd6969e8d3c83cc4a6609d0a99ddcd4","promoted":false,"record_hash":"2c03a252df5234b21819047b01af5292852875ad1525ae5e5cc7c5c6eff41201","relative_improvement":0.008933830438470725,"selected_ensemble_hash":"52cc748b0f03d805bc32644c746152d71b8878f6cb3e9e2e6df533e3cb3718e2","sequence":4}
+{"bundle_hash":"56c5551d36093708f6da5ad0165f968a12c69c7ede7216959f7a4d532a40d754","challenger_ensemble_hash":"b4268f4251d62981ee852625c817f48947e9e12aecc39da1b77d4ff869c86289","decision":"promoted","incumbent_ensemble_hash":"382ec0d5185a96f540f91839c8bd6328d408d70a8ec1f16352aa22553c05bcfb","league":"nhl","previous_hash":"2c03a252df5234b21819047b01af5292852875ad1525ae5e5cc7c5c6eff41201","promoted":true,"record_hash":"0d75bb6c7e011b661fd2724153e03618f67c4b391a04278e6f514b55810579ed","relative_improvement":0.013416183995751795,"selected_ensemble_hash":"b4268f4251d62981ee852625c817f48947e9e12aecc39da1b77d4ff869c86289","sequence":5}
+{"bundle_hash":"56c5551d36093708f6da5ad0165f968a12c69c7ede7216959f7a4d532a40d754","challenger_ensemble_hash":"369bd1fab70c4fe9c443214b61e5bb1297947388fae8402061d599b6dc5a975d","decision":"promoted","incumbent_ensemble_hash":"92022b12c8dd03d4fb005a8a84b4041b3370ee4e401e2e281230d8f6c3b3d284","league":"wnba","previous_hash":"0d75bb6c7e011b661fd2724153e03618f67c4b391a04278e6f514b55810579ed","promoted":true,"record_hash":"a989c50f313f76fdcf811d10fa4a1aeb61229cb92cc6798625c8050ea8ddb49c","relative_improvement":0.08808478401855853,"selected_ensemble_hash":"369bd1fab70c4fe9c443214b61e5bb1297947388fae8402061d599b6dc5a975d","sequence":6}
diff --git a/reports/autonomy_v3_fixture/improvement_report.json b/reports/autonomy_v3_fixture/improvement_report.json
new file mode 100644
index 0000000..a95aedc
--- /dev/null
+++ b/reports/autonomy_v3_fixture/improvement_report.json
@@ -0,0 +1,2652 @@
+{
+ "bundle_hash": "56c5551d36093708f6da5ad0165f968a12c69c7ede7216959f7a4d532a40d754",
+ "config": {
+ "brier_weight": 2.0,
+ "coverage_weight": 2.0,
+ "drift_threshold": 0.12,
+ "elite_count": 6,
+ "experts_per_ensemble": 6,
+ "generations": 8,
+ "interval_learning_rate": 0.04,
+ "long_decay": 0.03,
+ "maximum_brier_deterioration": 0.01,
+ "maximum_coverage_error_deterioration": 0.03,
+ "minimum_calibration_games": 50,
+ "minimum_drift_observations": 40,
+ "minimum_relative_improvement": 0.01,
+ "minimum_train_games": 100,
+ "mutation_scale": 0.12,
+ "online_learning_rate": 0.25,
+ "population_size": 32,
+ "seed": 20260718,
+ "short_decay": 0.2,
+ "target_coverage": 0.9
+ },
+ "results": [
+ {
+ "challenger_calibration_score": {
+ "composite_loss": 5.628048038203239,
+ "games": 50,
+ "home_win_brier": 0.21438362127823524,
+ "interval_coverage": 0.88,
+ "interval_coverage_error": 0.020000000000000018,
+ "mean_joint_negative_log_likelihood": 5.159280795646769
+ },
+ "challenger_ensemble": {
+ "ensemble_hash": "9bab62c591710731cbd22bded37c374b67f4e1696b2d7e5c9c84dea7a104faef",
+ "evidence_status": "chronological_calibration_challenger",
+ "league": "mlb",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 4.3,
+ "base_home_score": 4.55,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "mlb",
+ "margin_sd": 4.4,
+ "parent_hash": "",
+ "profile_hash": "ed4a36ddf530bc1e400bae06859869e1b8b9bf4c542f53a193c39d949638d53e",
+ "total_score_sd": 4.6
+ },
+ {
+ "away_strength_exponent": 0.9732227449430256,
+ "base_away_score": 3.956619631003342,
+ "base_home_score": 4.265680638905987,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 1.3488121287788095,
+ "league": "mlb",
+ "margin_sd": 3.096954687689488,
+ "parent_hash": "546d9ccfa6f1e7bbcbf4b336b82a20ef363c202a0ee7050e6b493d2942c967fd",
+ "profile_hash": "1e225e3282db44a590d7fe4164c7afedf965d81d37860a56c9e77168877e3048",
+ "total_score_sd": 2.997971433630624
+ },
+ {
+ "away_strength_exponent": 1.0020506194854666,
+ "base_away_score": 3.7559409203703473,
+ "base_home_score": 4.304405142231148,
+ "evidence_status": "train_search_candidate",
+ "generation": 7,
+ "home_strength_exponent": 1.3514363631800606,
+ "league": "mlb",
+ "margin_sd": 3.281442209037205,
+ "parent_hash": "39970d6d664e243e4d463473ad46cbdece703e931ee6edd34bd74b01f9c9fd28",
+ "profile_hash": "dcd7ff0ebffb55b5b359da5efb717025fd8573c660a2e7e345656bc34b9125e0",
+ "total_score_sd": 2.963222433665948
+ },
+ {
+ "away_strength_exponent": 1.0273788549103269,
+ "base_away_score": 3.6580735600366596,
+ "base_home_score": 4.437497007165997,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 1.259013229482986,
+ "league": "mlb",
+ "margin_sd": 3.1642287864092484,
+ "parent_hash": "dcd7ff0ebffb55b5b359da5efb717025fd8573c660a2e7e345656bc34b9125e0",
+ "profile_hash": "e4f7053453ee21ce9c6968ae7800eafa3fc2cd9fc8c2b12c81259468196a8850",
+ "total_score_sd": 3.0880724576747483
+ },
+ {
+ "away_strength_exponent": 1.2213532999101544,
+ "base_away_score": 3.6733701204579843,
+ "base_home_score": 4.138570240115561,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 1.575881182476844,
+ "league": "mlb",
+ "margin_sd": 3.253309700750169,
+ "parent_hash": "413908ce0d6230dab53ca9eceb9f0d3b83749fc271af655243bb6f87e00944ee",
+ "profile_hash": "c2b3729772a07d9e222d4bf250c2cf45e1355b4a513e6fe2f719fcbac81ef43f",
+ "total_score_sd": 2.993226404574243
+ },
+ {
+ "away_strength_exponent": 1.0106153431340696,
+ "base_away_score": 3.7409002739768646,
+ "base_home_score": 4.463304408483676,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 1.3765776247768466,
+ "league": "mlb",
+ "margin_sd": 3.1815356151223497,
+ "parent_hash": "546d9ccfa6f1e7bbcbf4b336b82a20ef363c202a0ee7050e6b493d2942c967fd",
+ "profile_hash": "d9b49e85601c4f1455c8b42d1cc14b756baa5508fd4a0af177d4148e192c2085",
+ "total_score_sd": 3.1607384763020856
+ }
+ ],
+ "weights": [
+ 0.15405098422511587,
+ 0.16964579340176075,
+ 0.16958720057856735,
+ 0.1689990874422243,
+ 0.168933830476312,
+ 0.16878310387601975
+ ]
+ },
+ "challenger_state": {
+ "drift_score": 0.04338281227700721,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "9bab62c591710731cbd22bded37c374b67f4e1696b2d7e5c9c84dea7a104faef",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 1.0408107741923895,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 5.422571148674965,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 5.657817534876647,
+ "state_hash": "5a6187460d092b3d9df544e4f38d557be9f92398ada8eb83ef2ee8169a0f7183",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 0.02167441758465728,
+ 0.23486336932707236,
+ 0.2286810040473044,
+ 0.16955067257669437,
+ 0.17545680083210652,
+ 0.16977373563216505
+ ]
+ },
+ "decision": "retained_incumbent:brier_guardrail_failed",
+ "generations": [
+ {
+ "best_profile_hash": "02aea8c53ef3eb59504e2e58a538849985b12f0589ee52a6bb8ce6ec893e048c",
+ "best_train_score": {
+ "composite_loss": 5.835661094796842,
+ "games": 100,
+ "home_win_brier": 0.22551068271785332,
+ "interval_coverage": 0.96,
+ "interval_coverage_error": 0.05999999999999994,
+ "mean_joint_negative_log_likelihood": 5.264639729361136
+ },
+ "candidates_evaluated": 32,
+ "generation": 1
+ },
+ {
+ "best_profile_hash": "752e0c630e79d7456bbdec1d1a0df27cb2b686d9b9a61256f6a882de413883fd",
+ "best_train_score": {
+ "composite_loss": 5.788737848023197,
+ "games": 100,
+ "home_win_brier": 0.22472008581155475,
+ "interval_coverage": 0.95,
+ "interval_coverage_error": 0.04999999999999993,
+ "mean_joint_negative_log_likelihood": 5.239297676400088
+ },
+ "candidates_evaluated": 32,
+ "generation": 2
+ },
+ {
+ "best_profile_hash": "5621c4dd467e48e7c55f8f7fa2142d5d23ac4b087141237c218d82d481c9a570",
+ "best_train_score": {
+ "composite_loss": 5.7453288022752105,
+ "games": 100,
+ "home_win_brier": 0.23018265584794523,
+ "interval_coverage": 0.935,
+ "interval_coverage_error": 0.03500000000000003,
+ "mean_joint_negative_log_likelihood": 5.214963490579319
+ },
+ "candidates_evaluated": 32,
+ "generation": 3
+ },
+ {
+ "best_profile_hash": "650a2de6216b8b4440f6c67d419395d341433f0aed9f9fce5dc05d62c691f57b",
+ "best_train_score": {
+ "composite_loss": 5.687847181033798,
+ "games": 100,
+ "home_win_brier": 0.22589729964465238,
+ "interval_coverage": 0.945,
+ "interval_coverage_error": 0.04499999999999993,
+ "mean_joint_negative_log_likelihood": 5.1460525817444935
+ },
+ "candidates_evaluated": 32,
+ "generation": 4
+ },
+ {
+ "best_profile_hash": "c1595c328c3a8682e66e88617bf4fc3680e6809abc137f9d080ac3e0494db3f9",
+ "best_train_score": {
+ "composite_loss": 5.653447010662879,
+ "games": 100,
+ "home_win_brier": 0.2254208059011755,
+ "interval_coverage": 0.935,
+ "interval_coverage_error": 0.03500000000000003,
+ "mean_joint_negative_log_likelihood": 5.1326053988605285
+ },
+ "candidates_evaluated": 32,
+ "generation": 5
+ },
+ {
+ "best_profile_hash": "04be3eb56818406958242d0a6387c78404f6918c434f0e05e872f82395a00aa5",
+ "best_train_score": {
+ "composite_loss": 5.6210507543139725,
+ "games": 100,
+ "home_win_brier": 0.2253722702087558,
+ "interval_coverage": 0.925,
+ "interval_coverage_error": 0.025000000000000022,
+ "mean_joint_negative_log_likelihood": 5.120306213896461
+ },
+ "candidates_evaluated": 32,
+ "generation": 6
+ },
+ {
+ "best_profile_hash": "dcd7ff0ebffb55b5b359da5efb717025fd8573c660a2e7e345656bc34b9125e0",
+ "best_train_score": {
+ "composite_loss": 5.57430045932439,
+ "games": 100,
+ "home_win_brier": 0.22645342258387796,
+ "interval_coverage": 0.905,
+ "interval_coverage_error": 0.0050000000000000044,
+ "mean_joint_negative_log_likelihood": 5.1113936141566345
+ },
+ "candidates_evaluated": 32,
+ "generation": 7
+ },
+ {
+ "best_profile_hash": "1e225e3282db44a590d7fe4164c7afedf965d81d37860a56c9e77168877e3048",
+ "best_train_score": {
+ "composite_loss": 5.572918687508186,
+ "games": 100,
+ "home_win_brier": 0.2272108241966743,
+ "interval_coverage": 0.9,
+ "interval_coverage_error": 0.0,
+ "mean_joint_negative_log_likelihood": 5.118497039114837
+ },
+ "candidates_evaluated": 32,
+ "generation": 8
+ }
+ ],
+ "incumbent_calibration_score": {
+ "composite_loss": 5.874629433875539,
+ "games": 50,
+ "home_win_brier": 0.20077420341310603,
+ "interval_coverage": 0.96,
+ "interval_coverage_error": 0.05999999999999994,
+ "mean_joint_negative_log_likelihood": 5.353081027049327
+ },
+ "incumbent_ensemble": {
+ "ensemble_hash": "bb0b6a4184ebbf8489abaf3dc3df077d280c14d888340b59c2871215f6df8360",
+ "evidence_status": "provisional_reference_anchor",
+ "league": "mlb",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 4.3,
+ "base_home_score": 4.55,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "mlb",
+ "margin_sd": 4.4,
+ "parent_hash": "",
+ "profile_hash": "ed4a36ddf530bc1e400bae06859869e1b8b9bf4c542f53a193c39d949638d53e",
+ "total_score_sd": 4.6
+ }
+ ],
+ "weights": [
+ 1.0
+ ]
+ },
+ "incumbent_state": {
+ "drift_score": 0.050688478956998094,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "bb0b6a4184ebbf8489abaf3dc3df077d280c14d888340b59c2871215f6df8360",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 0.8869204367171584,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 5.59425099372921,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 5.8778150675050185,
+ "state_hash": "a23ac9f2ccc36db8368dcd341b0025f12d6d2b188c95ca9013b1dc61b461e78a",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.0
+ ]
+ },
+ "league": "mlb",
+ "promoted": false,
+ "relative_improvement": 0.04197394890142503,
+ "selected_ensemble": {
+ "ensemble_hash": "bb0b6a4184ebbf8489abaf3dc3df077d280c14d888340b59c2871215f6df8360",
+ "evidence_status": "provisional_reference_anchor",
+ "league": "mlb",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 4.3,
+ "base_home_score": 4.55,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "mlb",
+ "margin_sd": 4.4,
+ "parent_hash": "",
+ "profile_hash": "ed4a36ddf530bc1e400bae06859869e1b8b9bf4c542f53a193c39d949638d53e",
+ "total_score_sd": 4.6
+ }
+ ],
+ "weights": [
+ 1.0
+ ]
+ },
+ "selected_state": {
+ "drift_score": 0.050688478956998094,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "bb0b6a4184ebbf8489abaf3dc3df077d280c14d888340b59c2871215f6df8360",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 0.8869204367171584,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 5.59425099372921,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 5.8778150675050185,
+ "state_hash": "a23ac9f2ccc36db8368dcd341b0025f12d6d2b188c95ca9013b1dc61b461e78a",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.0
+ ]
+ }
+ },
+ {
+ "challenger_calibration_score": {
+ "composite_loss": 8.248030969834542,
+ "games": 50,
+ "home_win_brier": 0.0698963567147646,
+ "interval_coverage": 0.94,
+ "interval_coverage_error": 0.039999999999999925,
+ "mean_joint_negative_log_likelihood": 8.028238256405013
+ },
+ "challenger_ensemble": {
+ "ensemble_hash": "60e7da6020d67de678c0d044f300847fde90bf16161917510b08c83bfd5dbe96",
+ "evidence_status": "chronological_calibration_challenger",
+ "league": "nba",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 113.0,
+ "base_home_score": 116.0,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "nba",
+ "margin_sd": 15.0,
+ "parent_hash": "",
+ "profile_hash": "1fd107dd93cec7f199c4979e7334f2ad2c7e7d61e6e5d3fa7a7c6741138e40d1",
+ "total_score_sd": 20.0
+ },
+ {
+ "away_strength_exponent": 0.9632460782428364,
+ "base_away_score": 100.41120048415034,
+ "base_home_score": 101.40842755264546,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 1.1035181164801218,
+ "league": "nba",
+ "margin_sd": 13.736474631089353,
+ "parent_hash": "d4336fc445a68de29aec9f851052ee18e00a6c18e7198fda34d832e4a727eafd",
+ "profile_hash": "6dabbdf2c5066b2dc80eb6e6088fbe21f308472a7241c3d76a36ea7ae27b0dc9",
+ "total_score_sd": 15.530808786290953
+ },
+ {
+ "away_strength_exponent": 0.9299864332685756,
+ "base_away_score": 99.12089973217256,
+ "base_home_score": 102.60460634910284,
+ "evidence_status": "train_search_candidate",
+ "generation": 7,
+ "home_strength_exponent": 1.0374456736407256,
+ "league": "nba",
+ "margin_sd": 14.476747331295748,
+ "parent_hash": "d4336fc445a68de29aec9f851052ee18e00a6c18e7198fda34d832e4a727eafd",
+ "profile_hash": "2c3b39a22523f4f245dcd1afe8fcfc54544020073f6153bd180207f50ca0fa67",
+ "total_score_sd": 15.986652973245818
+ },
+ {
+ "away_strength_exponent": 0.9314639467993735,
+ "base_away_score": 97.55462255575519,
+ "base_home_score": 100.60692741111606,
+ "evidence_status": "train_search_candidate",
+ "generation": 6,
+ "home_strength_exponent": 1.0481985521298671,
+ "league": "nba",
+ "margin_sd": 13.538006034660736,
+ "parent_hash": "1f29dc288a020ac6049537b27f5d91603e2e548bb8639e20fcd8c9527fa9b748",
+ "profile_hash": "d4336fc445a68de29aec9f851052ee18e00a6c18e7198fda34d832e4a727eafd",
+ "total_score_sd": 16.76275018651739
+ },
+ {
+ "away_strength_exponent": 0.8862112258764434,
+ "base_away_score": 100.34400852330234,
+ "base_home_score": 99.90111885665915,
+ "evidence_status": "train_search_candidate",
+ "generation": 7,
+ "home_strength_exponent": 0.9978232275893777,
+ "league": "nba",
+ "margin_sd": 13.709770977740531,
+ "parent_hash": "4cc9fa6c37e99b992fc73dec931c77bbd815b6a14538deb5d0471d5dfe18a3b3",
+ "profile_hash": "2b9ae85a9ff77cddc6e95f95feff238a5aad863eb1b5a6d4d0c1682859f773cf",
+ "total_score_sd": 14.728999472122727
+ },
+ {
+ "away_strength_exponent": 0.9168426579759286,
+ "base_away_score": 98.08693111402029,
+ "base_home_score": 100.24510182059633,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 1.029985233214439,
+ "league": "nba",
+ "margin_sd": 13.914503225184157,
+ "parent_hash": "2c3b39a22523f4f245dcd1afe8fcfc54544020073f6153bd180207f50ca0fa67",
+ "profile_hash": "c24f67abab0bf80575320bbbed67381f38b4de2aeee0cfe291bee9e80ceba669",
+ "total_score_sd": 16.713986694619834
+ }
+ ],
+ "weights": [
+ 0.12893045230055183,
+ 0.17538891395996567,
+ 0.1747196187644406,
+ 0.17386258202490054,
+ 0.17362605222135616,
+ 0.17347238072878526
+ ]
+ },
+ "challenger_state": {
+ "drift_score": 0.0,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "60e7da6020d67de678c0d044f300847fde90bf16161917510b08c83bfd5dbe96",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 0.9231163463866361,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.475867039772714,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 8.262049524590857,
+ "state_hash": "fe671acbd9f09da2f1984ffa82fa65ab28b4110cb59498739477866e598f119d",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 5.513615121909581e-07,
+ 0.43303118967699145,
+ 0.16262743922906853,
+ 0.13862691445333053,
+ 0.14035629144863276,
+ 0.1253576138304646
+ ]
+ },
+ "decision": "promoted",
+ "generations": [
+ {
+ "best_profile_hash": "b011c525e5fcde41f45150880a10d718b49123b4346a972b501117575850c6e7",
+ "best_train_score": {
+ "composite_loss": 8.751860362501507,
+ "games": 100,
+ "home_win_brier": 0.10868264922047732,
+ "interval_coverage": 0.965,
+ "interval_coverage_error": 0.06499999999999995,
+ "mean_joint_negative_log_likelihood": 8.404495064060551
+ },
+ "candidates_evaluated": 32,
+ "generation": 1
+ },
+ {
+ "best_profile_hash": "64c7f6fdea7e6368e3c4906023a5721fa005f1ad7e07423c174f515d36c0d58e",
+ "best_train_score": {
+ "composite_loss": 8.576444497887572,
+ "games": 100,
+ "home_win_brier": 0.10440357380938814,
+ "interval_coverage": 0.915,
+ "interval_coverage_error": 0.015000000000000013,
+ "mean_joint_negative_log_likelihood": 8.337637350268796
+ },
+ "candidates_evaluated": 32,
+ "generation": 2
+ },
+ {
+ "best_profile_hash": "184ac8a18b48db182cac3afca98f6f5d07a4f9c8c72fcebc344c8494d9fcb7f6",
+ "best_train_score": {
+ "composite_loss": 8.569914952766858,
+ "games": 100,
+ "home_win_brier": 0.11290839482469123,
+ "interval_coverage": 0.92,
+ "interval_coverage_error": 0.020000000000000018,
+ "mean_joint_negative_log_likelihood": 8.304098163117477
+ },
+ "candidates_evaluated": 32,
+ "generation": 3
+ },
+ {
+ "best_profile_hash": "1f29dc288a020ac6049537b27f5d91603e2e548bb8639e20fcd8c9527fa9b748",
+ "best_train_score": {
+ "composite_loss": 8.38170393584511,
+ "games": 100,
+ "home_win_brier": 0.10487332850355903,
+ "interval_coverage": 0.915,
+ "interval_coverage_error": 0.015000000000000013,
+ "mean_joint_negative_log_likelihood": 8.141957278837992
+ },
+ "candidates_evaluated": 32,
+ "generation": 4
+ },
+ {
+ "best_profile_hash": "1f29dc288a020ac6049537b27f5d91603e2e548bb8639e20fcd8c9527fa9b748",
+ "best_train_score": {
+ "composite_loss": 8.38170393584511,
+ "games": 100,
+ "home_win_brier": 0.10487332850355903,
+ "interval_coverage": 0.915,
+ "interval_coverage_error": 0.015000000000000013,
+ "mean_joint_negative_log_likelihood": 8.141957278837992
+ },
+ "candidates_evaluated": 32,
+ "generation": 5
+ },
+ {
+ "best_profile_hash": "d4336fc445a68de29aec9f851052ee18e00a6c18e7198fda34d832e4a727eafd",
+ "best_train_score": {
+ "composite_loss": 8.363328105496414,
+ "games": 100,
+ "home_win_brier": 0.10512816562646293,
+ "interval_coverage": 0.915,
+ "interval_coverage_error": 0.015000000000000013,
+ "mean_joint_negative_log_likelihood": 8.123071774243488
+ },
+ "candidates_evaluated": 32,
+ "generation": 6
+ },
+ {
+ "best_profile_hash": "2c3b39a22523f4f245dcd1afe8fcfc54544020073f6153bd180207f50ca0fa67",
+ "best_train_score": {
+ "composite_loss": 8.343658978053798,
+ "games": 100,
+ "home_win_brier": 0.10515922355057844,
+ "interval_coverage": 0.91,
+ "interval_coverage_error": 0.010000000000000009,
+ "mean_joint_negative_log_likelihood": 8.113340530952641
+ },
+ "candidates_evaluated": 32,
+ "generation": 7
+ },
+ {
+ "best_profile_hash": "6dabbdf2c5066b2dc80eb6e6088fbe21f308472a7241c3d76a36ea7ae27b0dc9",
+ "best_train_score": {
+ "composite_loss": 8.328365525920297,
+ "games": 100,
+ "home_win_brier": 0.10894498208710375,
+ "interval_coverage": 0.9,
+ "interval_coverage_error": 0.0,
+ "mean_joint_negative_log_likelihood": 8.11047556174609
+ },
+ "candidates_evaluated": 32,
+ "generation": 8
+ }
+ ],
+ "incumbent_calibration_score": {
+ "composite_loss": 9.310371209830079,
+ "games": 50,
+ "home_win_brier": 0.0654562378544873,
+ "interval_coverage": 0.83,
+ "interval_coverage_error": 0.07000000000000006,
+ "mean_joint_negative_log_likelihood": 9.039458734121103
+ },
+ "incumbent_ensemble": {
+ "ensemble_hash": "938868d720f17e6b997358c0a52254af174a1b3081193720225c3ca7e3eda934",
+ "evidence_status": "provisional_reference_anchor",
+ "league": "nba",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 113.0,
+ "base_home_score": 116.0,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "nba",
+ "margin_sd": 15.0,
+ "parent_hash": "",
+ "profile_hash": "1fd107dd93cec7f199c4979e7334f2ad2c7e7d61e6e5d3fa7a7c6741138e40d1",
+ "total_score_sd": 20.0
+ }
+ ],
+ "weights": [
+ 1.0
+ ]
+ },
+ "incumbent_state": {
+ "drift_score": 0.0,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "938868d720f17e6b997358c0a52254af174a1b3081193720225c3ca7e3eda934",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 1.1502737988572285,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 9.584379101566844,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 9.00479793127273,
+ "state_hash": "8938e17f435856b6ce780263706e625583f33790ccd311fee85a1564aa1988dd",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.0
+ ]
+ },
+ "league": "nba",
+ "promoted": true,
+ "relative_improvement": 0.11410288763501682,
+ "selected_ensemble": {
+ "ensemble_hash": "60e7da6020d67de678c0d044f300847fde90bf16161917510b08c83bfd5dbe96",
+ "evidence_status": "chronological_calibration_challenger",
+ "league": "nba",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 113.0,
+ "base_home_score": 116.0,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "nba",
+ "margin_sd": 15.0,
+ "parent_hash": "",
+ "profile_hash": "1fd107dd93cec7f199c4979e7334f2ad2c7e7d61e6e5d3fa7a7c6741138e40d1",
+ "total_score_sd": 20.0
+ },
+ {
+ "away_strength_exponent": 0.9632460782428364,
+ "base_away_score": 100.41120048415034,
+ "base_home_score": 101.40842755264546,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 1.1035181164801218,
+ "league": "nba",
+ "margin_sd": 13.736474631089353,
+ "parent_hash": "d4336fc445a68de29aec9f851052ee18e00a6c18e7198fda34d832e4a727eafd",
+ "profile_hash": "6dabbdf2c5066b2dc80eb6e6088fbe21f308472a7241c3d76a36ea7ae27b0dc9",
+ "total_score_sd": 15.530808786290953
+ },
+ {
+ "away_strength_exponent": 0.9299864332685756,
+ "base_away_score": 99.12089973217256,
+ "base_home_score": 102.60460634910284,
+ "evidence_status": "train_search_candidate",
+ "generation": 7,
+ "home_strength_exponent": 1.0374456736407256,
+ "league": "nba",
+ "margin_sd": 14.476747331295748,
+ "parent_hash": "d4336fc445a68de29aec9f851052ee18e00a6c18e7198fda34d832e4a727eafd",
+ "profile_hash": "2c3b39a22523f4f245dcd1afe8fcfc54544020073f6153bd180207f50ca0fa67",
+ "total_score_sd": 15.986652973245818
+ },
+ {
+ "away_strength_exponent": 0.9314639467993735,
+ "base_away_score": 97.55462255575519,
+ "base_home_score": 100.60692741111606,
+ "evidence_status": "train_search_candidate",
+ "generation": 6,
+ "home_strength_exponent": 1.0481985521298671,
+ "league": "nba",
+ "margin_sd": 13.538006034660736,
+ "parent_hash": "1f29dc288a020ac6049537b27f5d91603e2e548bb8639e20fcd8c9527fa9b748",
+ "profile_hash": "d4336fc445a68de29aec9f851052ee18e00a6c18e7198fda34d832e4a727eafd",
+ "total_score_sd": 16.76275018651739
+ },
+ {
+ "away_strength_exponent": 0.8862112258764434,
+ "base_away_score": 100.34400852330234,
+ "base_home_score": 99.90111885665915,
+ "evidence_status": "train_search_candidate",
+ "generation": 7,
+ "home_strength_exponent": 0.9978232275893777,
+ "league": "nba",
+ "margin_sd": 13.709770977740531,
+ "parent_hash": "4cc9fa6c37e99b992fc73dec931c77bbd815b6a14538deb5d0471d5dfe18a3b3",
+ "profile_hash": "2b9ae85a9ff77cddc6e95f95feff238a5aad863eb1b5a6d4d0c1682859f773cf",
+ "total_score_sd": 14.728999472122727
+ },
+ {
+ "away_strength_exponent": 0.9168426579759286,
+ "base_away_score": 98.08693111402029,
+ "base_home_score": 100.24510182059633,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 1.029985233214439,
+ "league": "nba",
+ "margin_sd": 13.914503225184157,
+ "parent_hash": "2c3b39a22523f4f245dcd1afe8fcfc54544020073f6153bd180207f50ca0fa67",
+ "profile_hash": "c24f67abab0bf80575320bbbed67381f38b4de2aeee0cfe291bee9e80ceba669",
+ "total_score_sd": 16.713986694619834
+ }
+ ],
+ "weights": [
+ 0.12893045230055183,
+ 0.17538891395996567,
+ 0.1747196187644406,
+ 0.17386258202490054,
+ 0.17362605222135616,
+ 0.17347238072878526
+ ]
+ },
+ "selected_state": {
+ "drift_score": 0.0,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "60e7da6020d67de678c0d044f300847fde90bf16161917510b08c83bfd5dbe96",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 0.9231163463866361,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.475867039772714,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 8.262049524590857,
+ "state_hash": "fe671acbd9f09da2f1984ffa82fa65ab28b4110cb59498739477866e598f119d",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 5.513615121909581e-07,
+ 0.43303118967699145,
+ 0.16262743922906853,
+ 0.13862691445333053,
+ 0.14035629144863276,
+ 0.1253576138304646
+ ]
+ }
+ },
+ {
+ "challenger_calibration_score": {
+ "composite_loss": 8.761251921087043,
+ "games": 50,
+ "home_win_brier": 0.2309784924355083,
+ "interval_coverage": 0.87,
+ "interval_coverage_error": 0.030000000000000027,
+ "mean_joint_negative_log_likelihood": 8.239294936216025
+ },
+ "challenger_ensemble": {
+ "ensemble_hash": "dcfcefe31dbce66dfd8f5eeb5a1490dc505fd383498a0b0a641ed2b486e155a1",
+ "evidence_status": "chronological_calibration_challenger",
+ "league": "ncaaf",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 26.5,
+ "base_home_score": 29.0,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "ncaaf",
+ "margin_sd": 18.0,
+ "parent_hash": "",
+ "profile_hash": "6c3ad3401f75976c8a0cc1301c7aa9d9ba28a4d78b9bd5ee2432bf29e58493f7",
+ "total_score_sd": 15.7
+ },
+ {
+ "away_strength_exponent": 0.8683260259816346,
+ "base_away_score": 24.32544109440506,
+ "base_home_score": 23.9566920544987,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 0.9196385820892058,
+ "league": "ncaaf",
+ "margin_sd": 12.289222730603594,
+ "parent_hash": "b39b65c72765ca636d83ad54fac9b5797863f17071eb7aa27e83b50474d7689d",
+ "profile_hash": "f5c9840786b6201da9a65cdb62997dfa335b97af287d2c6b980c0bbbfcf7542e",
+ "total_score_sd": 12.43390868510682
+ },
+ {
+ "away_strength_exponent": 0.9096078610166126,
+ "base_away_score": 24.91082983081627,
+ "base_home_score": 24.123091566470293,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 0.888366435770028,
+ "league": "ncaaf",
+ "margin_sd": 14.129488015416582,
+ "parent_hash": "e5ddbd73ccc308ce1e55fa9938054dfa1ea7f908cd5cbf225f7126bf4a02b217",
+ "profile_hash": "adbde67ffec2e8ed7b8ffcb77148430f8a48f8474b6909042c733f452e3dbe4c",
+ "total_score_sd": 11.709297245021318
+ },
+ {
+ "away_strength_exponent": 0.9584625081284368,
+ "base_away_score": 24.799301032404774,
+ "base_home_score": 25.534785198496447,
+ "evidence_status": "train_search_candidate",
+ "generation": 7,
+ "home_strength_exponent": 0.9298150901925718,
+ "league": "ncaaf",
+ "margin_sd": 13.296087557104656,
+ "parent_hash": "00baeb8e12429682c3490b075bc43d5307c45f8795f1d001fcfa2e608b0541d5",
+ "profile_hash": "e5ddbd73ccc308ce1e55fa9938054dfa1ea7f908cd5cbf225f7126bf4a02b217",
+ "total_score_sd": 12.09023462837543
+ },
+ {
+ "away_strength_exponent": 0.9513800830701528,
+ "base_away_score": 22.81818833797911,
+ "base_home_score": 24.38880028596671,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 1.0526454209993767,
+ "league": "ncaaf",
+ "margin_sd": 12.898275898145506,
+ "parent_hash": "0ecfc92b2fc37be0a1f5a880489f89291077b6a225975bbae56ff56c346d00e4",
+ "profile_hash": "801ef2b56e0cd0e67270c0ee8f648ae4ae4533e1e3ea6cfe96c71be0c035c037",
+ "total_score_sd": 12.434282216811535
+ },
+ {
+ "away_strength_exponent": 0.9590291217112736,
+ "base_away_score": 25.796667803022814,
+ "base_home_score": 24.230975147547593,
+ "evidence_status": "train_search_candidate",
+ "generation": 7,
+ "home_strength_exponent": 1.0513001032404565,
+ "league": "ncaaf",
+ "margin_sd": 12.753597354759721,
+ "parent_hash": "b14988ce746dfe7e73eefc35385c4118256e0f669c5dbfe5136647943d9ae1c6",
+ "profile_hash": "0ecfc92b2fc37be0a1f5a880489f89291077b6a225975bbae56ff56c346d00e4",
+ "total_score_sd": 12.488846147947697
+ }
+ ],
+ "weights": [
+ 0.1571525335874964,
+ 0.16877838486092833,
+ 0.16869532526714723,
+ 0.1685043427773905,
+ 0.16845570292201564,
+ 0.16841371058502197
+ ]
+ },
+ "challenger_state": {
+ "drift_score": 0.06318035279011783,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "dcfcefe31dbce66dfd8f5eeb5a1490dc505fd383498a0b0a641ed2b486e155a1",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 1.0618365465453588,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.643346312203276,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 9.189435981495443,
+ "state_hash": "ec797d592bb5998558dfe65b7764ed1f14871486198573b65024651f0af54523",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 0.11772211665415457,
+ 0.08239082301927475,
+ 0.19548448006488245,
+ 0.22836666496556968,
+ 0.2988350366603923,
+ 0.07720087863572628
+ ]
+ },
+ "decision": "retained_incumbent:minimum_relative_improvement_not_met",
+ "generations": [
+ {
+ "best_profile_hash": "61b843ef21f5631a8c901e13d6f15050d293bb91c8b2edfad3ae1c4332654c38",
+ "best_train_score": {
+ "composite_loss": 8.542187514716256,
+ "games": 100,
+ "home_win_brier": 0.2225168103741196,
+ "interval_coverage": 0.895,
+ "interval_coverage_error": 0.0050000000000000044,
+ "mean_joint_negative_log_likelihood": 8.087153893968017
+ },
+ "candidates_evaluated": 32,
+ "generation": 1
+ },
+ {
+ "best_profile_hash": "bc7dccd2da202fe52b2f0d09d79e6cb29c0db9883772c3b7ccc916b1a3026b63",
+ "best_train_score": {
+ "composite_loss": 8.485121536582794,
+ "games": 100,
+ "home_win_brier": 0.22676481568484308,
+ "interval_coverage": 0.905,
+ "interval_coverage_error": 0.0050000000000000044,
+ "mean_joint_negative_log_likelihood": 8.021591905213107
+ },
+ "candidates_evaluated": 32,
+ "generation": 2
+ },
+ {
+ "best_profile_hash": "bc7dccd2da202fe52b2f0d09d79e6cb29c0db9883772c3b7ccc916b1a3026b63",
+ "best_train_score": {
+ "composite_loss": 8.485121536582794,
+ "games": 100,
+ "home_win_brier": 0.22676481568484308,
+ "interval_coverage": 0.905,
+ "interval_coverage_error": 0.0050000000000000044,
+ "mean_joint_negative_log_likelihood": 8.021591905213107
+ },
+ "candidates_evaluated": 32,
+ "generation": 3
+ },
+ {
+ "best_profile_hash": "6ae365d498c4881221a01750e7aed6ff2ab866801215d6a4debcb41487290f6b",
+ "best_train_score": {
+ "composite_loss": 8.44270924721444,
+ "games": 100,
+ "home_win_brier": 0.22468358566224475,
+ "interval_coverage": 0.9,
+ "interval_coverage_error": 0.0,
+ "mean_joint_negative_log_likelihood": 7.9933420758899505
+ },
+ "candidates_evaluated": 32,
+ "generation": 4
+ },
+ {
+ "best_profile_hash": "6ae365d498c4881221a01750e7aed6ff2ab866801215d6a4debcb41487290f6b",
+ "best_train_score": {
+ "composite_loss": 8.44270924721444,
+ "games": 100,
+ "home_win_brier": 0.22468358566224475,
+ "interval_coverage": 0.9,
+ "interval_coverage_error": 0.0,
+ "mean_joint_negative_log_likelihood": 7.9933420758899505
+ },
+ "candidates_evaluated": 32,
+ "generation": 5
+ },
+ {
+ "best_profile_hash": "6ae365d498c4881221a01750e7aed6ff2ab866801215d6a4debcb41487290f6b",
+ "best_train_score": {
+ "composite_loss": 8.44270924721444,
+ "games": 100,
+ "home_win_brier": 0.22468358566224475,
+ "interval_coverage": 0.9,
+ "interval_coverage_error": 0.0,
+ "mean_joint_negative_log_likelihood": 7.9933420758899505
+ },
+ "candidates_evaluated": 32,
+ "generation": 6
+ },
+ {
+ "best_profile_hash": "e5ddbd73ccc308ce1e55fa9938054dfa1ea7f908cd5cbf225f7126bf4a02b217",
+ "best_train_score": {
+ "composite_loss": 8.437901795595902,
+ "games": 100,
+ "home_win_brier": 0.22329882116741837,
+ "interval_coverage": 0.895,
+ "interval_coverage_error": 0.0050000000000000044,
+ "mean_joint_negative_log_likelihood": 7.981304153261065
+ },
+ "candidates_evaluated": 32,
+ "generation": 7
+ },
+ {
+ "best_profile_hash": "f5c9840786b6201da9a65cdb62997dfa335b97af287d2c6b980c0bbbfcf7542e",
+ "best_train_score": {
+ "composite_loss": 8.43140179731232,
+ "games": 100,
+ "home_win_brier": 0.22248231792931097,
+ "interval_coverage": 0.9,
+ "interval_coverage_error": 0.0,
+ "mean_joint_negative_log_likelihood": 7.986437161453698
+ },
+ "candidates_evaluated": 32,
+ "generation": 8
+ }
+ ],
+ "incumbent_calibration_score": {
+ "composite_loss": 8.809151979845048,
+ "games": 50,
+ "home_win_brier": 0.22737367673106743,
+ "interval_coverage": 0.92,
+ "interval_coverage_error": 0.020000000000000018,
+ "mean_joint_negative_log_likelihood": 8.314404626382911
+ },
+ "incumbent_ensemble": {
+ "ensemble_hash": "110e0a2b1d912b65c9c8e2421251514d29e036503be2191a6a19c5418d16b42a",
+ "evidence_status": "provisional_reference_anchor",
+ "league": "ncaaf",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 26.5,
+ "base_home_score": 29.0,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "ncaaf",
+ "margin_sd": 18.0,
+ "parent_hash": "",
+ "profile_hash": "6c3ad3401f75976c8a0cc1301c7aa9d9ba28a4d78b9bd5ee2432bf29e58493f7",
+ "total_score_sd": 15.7
+ }
+ ],
+ "weights": [
+ 1.0
+ ]
+ },
+ "incumbent_state": {
+ "drift_score": 0.053373359494810986,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "110e0a2b1d912b65c9c8e2421251514d29e036503be2191a6a19c5418d16b42a",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 0.9607894391523236,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.821992883967974,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 9.292852281624661,
+ "state_hash": "6490ed8bb46c72d47e410317f52bba03128f9076dbe23088cbd0748735b8b91b",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.0
+ ]
+ },
+ "league": "ncaaf",
+ "promoted": false,
+ "relative_improvement": 0.005437533472869828,
+ "selected_ensemble": {
+ "ensemble_hash": "110e0a2b1d912b65c9c8e2421251514d29e036503be2191a6a19c5418d16b42a",
+ "evidence_status": "provisional_reference_anchor",
+ "league": "ncaaf",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 26.5,
+ "base_home_score": 29.0,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "ncaaf",
+ "margin_sd": 18.0,
+ "parent_hash": "",
+ "profile_hash": "6c3ad3401f75976c8a0cc1301c7aa9d9ba28a4d78b9bd5ee2432bf29e58493f7",
+ "total_score_sd": 15.7
+ }
+ ],
+ "weights": [
+ 1.0
+ ]
+ },
+ "selected_state": {
+ "drift_score": 0.053373359494810986,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "110e0a2b1d912b65c9c8e2421251514d29e036503be2191a6a19c5418d16b42a",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 0.9607894391523236,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.821992883967974,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 9.292852281624661,
+ "state_hash": "6490ed8bb46c72d47e410317f52bba03128f9076dbe23088cbd0748735b8b91b",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.0
+ ]
+ }
+ },
+ {
+ "challenger_calibration_score": {
+ "composite_loss": 8.216060900552336,
+ "games": 50,
+ "home_win_brier": 0.16681685856160933,
+ "interval_coverage": 0.92,
+ "interval_coverage_error": 0.020000000000000018,
+ "mean_joint_negative_log_likelihood": 7.842427183429115
+ },
+ "challenger_ensemble": {
+ "ensemble_hash": "3a26b1869b41e662ecdfe044a54229c6e5998280f88a6ad5003326302350654e",
+ "evidence_status": "chronological_calibration_challenger",
+ "league": "ncaambb",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 72.0,
+ "base_home_score": 75.0,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "ncaambb",
+ "margin_sd": 14.0,
+ "parent_hash": "",
+ "profile_hash": "14be1ec209dc6acf4030c480c7c2c6abf250986580e5da75595419c8fd8028df",
+ "total_score_sd": 16.5
+ },
+ {
+ "away_strength_exponent": 0.9380995927689169,
+ "base_away_score": 64.26338685281874,
+ "base_home_score": 67.90736863209588,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 1.1198826403419602,
+ "league": "ncaambb",
+ "margin_sd": 12.337242613541385,
+ "parent_hash": "d908371efab1b1058ff372457736decc2f22f9d69723d762431e794c4f4582e3",
+ "profile_hash": "05bcc37afeab1ab4bf15ea01c88cd88d9e19e259e85a843ba6904dc94e5285ee",
+ "total_score_sd": 11.844982854797419
+ },
+ {
+ "away_strength_exponent": 0.9839084920688369,
+ "base_away_score": 64.17862932003789,
+ "base_home_score": 66.40814600980535,
+ "evidence_status": "train_search_candidate",
+ "generation": 7,
+ "home_strength_exponent": 1.1265354070594922,
+ "league": "ncaambb",
+ "margin_sd": 11.751801481101191,
+ "parent_hash": "5052bec2704f4278b8055686fdfd6fdaca864456ff8480e6bd1c3a16ff8cd5c2",
+ "profile_hash": "d908371efab1b1058ff372457736decc2f22f9d69723d762431e794c4f4582e3",
+ "total_score_sd": 12.527208607031197
+ },
+ {
+ "away_strength_exponent": 1.0302789332906102,
+ "base_away_score": 64.56603709857632,
+ "base_home_score": 68.11959848451264,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 1.15845619003206,
+ "league": "ncaambb",
+ "margin_sd": 12.172650135194955,
+ "parent_hash": "d908371efab1b1058ff372457736decc2f22f9d69723d762431e794c4f4582e3",
+ "profile_hash": "a3426257638d3914687ea87b35c7948a9df8423501f8509cc563d4635f364bad",
+ "total_score_sd": 12.250367245233734
+ },
+ {
+ "away_strength_exponent": 0.9757805013766029,
+ "base_away_score": 64.69153447008274,
+ "base_home_score": 67.3019953859376,
+ "evidence_status": "train_search_candidate",
+ "generation": 6,
+ "home_strength_exponent": 1.0463799843916333,
+ "league": "ncaambb",
+ "margin_sd": 12.360366882633027,
+ "parent_hash": "035fdaf6642f08d5f653660bf422cf514301df099700740c1740ff66f014aa95",
+ "profile_hash": "5052bec2704f4278b8055686fdfd6fdaca864456ff8480e6bd1c3a16ff8cd5c2",
+ "total_score_sd": 13.12846794130971
+ },
+ {
+ "away_strength_exponent": 1.0525771945812439,
+ "base_away_score": 65.56062542041047,
+ "base_home_score": 67.05886346685132,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 1.0249276075178801,
+ "league": "ncaambb",
+ "margin_sd": 11.814617284868469,
+ "parent_hash": "5052bec2704f4278b8055686fdfd6fdaca864456ff8480e6bd1c3a16ff8cd5c2",
+ "profile_hash": "d5abde343917aae55c5b655aed7e5ce5542a8d6e94ebb6cc5b1dff7aef5b914b",
+ "total_score_sd": 12.842103349942267
+ }
+ ],
+ "weights": [
+ 0.15204731462607787,
+ 0.17053030010320389,
+ 0.17008865902417303,
+ 0.1698776799805041,
+ 0.16875167581778863,
+ 0.16870437044825248
+ ]
+ },
+ "challenger_state": {
+ "drift_score": 0.0,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "3a26b1869b41e662ecdfe044a54229c6e5998280f88a6ad5003326302350654e",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 0.9607894391523251,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.174282931387665,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 8.008633532956152,
+ "state_hash": "924515d3adfcde4094160bbe9a1c1741be83320aad2c0d1e322f724c309fcb9d",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 0.001155014984004925,
+ 0.19050882700932764,
+ 0.19279742459698684,
+ 0.14440496188814017,
+ 0.26188724112414913,
+ 0.20924653039739127
+ ]
+ },
+ "decision": "promoted",
+ "generations": [
+ {
+ "best_profile_hash": "64b6bb506c3dcb4cfaa4cd8254d947e885306b344a34b5f7ff92a722eee85063",
+ "best_train_score": {
+ "composite_loss": 8.374606997457724,
+ "games": 100,
+ "home_win_brier": 0.13776513594898673,
+ "interval_coverage": 0.935,
+ "interval_coverage_error": 0.03500000000000003,
+ "mean_joint_negative_log_likelihood": 8.029076725559749
+ },
+ "candidates_evaluated": 32,
+ "generation": 1
+ },
+ {
+ "best_profile_hash": "65a5394d5eec4c213c87f895eafdfe93441f7a18d68780cd4bf1c74eb21a4a2c",
+ "best_train_score": {
+ "composite_loss": 8.258482092728922,
+ "games": 100,
+ "home_win_brier": 0.13574660908041764,
+ "interval_coverage": 0.935,
+ "interval_coverage_error": 0.03500000000000003,
+ "mean_joint_negative_log_likelihood": 7.916988874568086
+ },
+ "candidates_evaluated": 32,
+ "generation": 2
+ },
+ {
+ "best_profile_hash": "34aae2ca0c08c9865d7f2ce6d4c93dfaf4e723938132713bef356b71cf6a1fc8",
+ "best_train_score": {
+ "composite_loss": 8.248697462807533,
+ "games": 100,
+ "home_win_brier": 0.1297155386445725,
+ "interval_coverage": 0.955,
+ "interval_coverage_error": 0.05499999999999994,
+ "mean_joint_negative_log_likelihood": 7.879266385518389
+ },
+ "candidates_evaluated": 32,
+ "generation": 3
+ },
+ {
+ "best_profile_hash": "b349e3227ea38b25cb1a7a65f6e732d435cb774719bcd15da0a46f5d60ae6e4c",
+ "best_train_score": {
+ "composite_loss": 8.247592448455915,
+ "games": 100,
+ "home_win_brier": 0.13014343448986546,
+ "interval_coverage": 0.945,
+ "interval_coverage_error": 0.04499999999999993,
+ "mean_joint_negative_log_likelihood": 7.897305579476185
+ },
+ "candidates_evaluated": 32,
+ "generation": 4
+ },
+ {
+ "best_profile_hash": "035fdaf6642f08d5f653660bf422cf514301df099700740c1740ff66f014aa95",
+ "best_train_score": {
+ "composite_loss": 8.197193058468407,
+ "games": 100,
+ "home_win_brier": 0.13015935604396173,
+ "interval_coverage": 0.94,
+ "interval_coverage_error": 0.039999999999999925,
+ "mean_joint_negative_log_likelihood": 7.856874346380485
+ },
+ "candidates_evaluated": 32,
+ "generation": 5
+ },
+ {
+ "best_profile_hash": "5052bec2704f4278b8055686fdfd6fdaca864456ff8480e6bd1c3a16ff8cd5c2",
+ "best_train_score": {
+ "composite_loss": 8.140852763777975,
+ "games": 100,
+ "home_win_brier": 0.13020324963078864,
+ "interval_coverage": 0.92,
+ "interval_coverage_error": 0.020000000000000018,
+ "mean_joint_negative_log_likelihood": 7.840446264516397
+ },
+ "candidates_evaluated": 32,
+ "generation": 6
+ },
+ {
+ "best_profile_hash": "d908371efab1b1058ff372457736decc2f22f9d69723d762431e794c4f4582e3",
+ "best_train_score": {
+ "composite_loss": 8.109286506576968,
+ "games": 100,
+ "home_win_brier": 0.12896937059178779,
+ "interval_coverage": 0.89,
+ "interval_coverage_error": 0.010000000000000009,
+ "mean_joint_negative_log_likelihood": 7.831347765393392
+ },
+ "candidates_evaluated": 32,
+ "generation": 7
+ },
+ {
+ "best_profile_hash": "05bcc37afeab1ab4bf15ea01c88cd88d9e19e259e85a843ba6904dc94e5285ee",
+ "best_train_score": {
+ "composite_loss": 8.098913829080733,
+ "games": 100,
+ "home_win_brier": 0.13147547236343635,
+ "interval_coverage": 0.9,
+ "interval_coverage_error": 0.0,
+ "mean_joint_negative_log_likelihood": 7.835962884353861
+ },
+ "candidates_evaluated": 32,
+ "generation": 8
+ }
+ ],
+ "incumbent_calibration_score": {
+ "composite_loss": 8.578503263410775,
+ "games": 50,
+ "home_win_brier": 0.16468304335835116,
+ "interval_coverage": 0.9,
+ "interval_coverage_error": 0.0,
+ "mean_joint_negative_log_likelihood": 8.249137176694074
+ },
+ "incumbent_ensemble": {
+ "ensemble_hash": "f4a907f61caeed291d4ccf147414e9c0e97aaef2acbf4a47d08961d80fb12539",
+ "evidence_status": "provisional_reference_anchor",
+ "league": "ncaambb",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 72.0,
+ "base_home_score": 75.0,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "ncaambb",
+ "margin_sd": 14.0,
+ "parent_hash": "",
+ "profile_hash": "14be1ec209dc6acf4030c480c7c2c6abf250986580e5da75595419c8fd8028df",
+ "total_score_sd": 16.5
+ }
+ ],
+ "weights": [
+ 1.0
+ ]
+ },
+ "incumbent_state": {
+ "drift_score": 0.0,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "f4a907f61caeed291d4ccf147414e9c0e97aaef2acbf4a47d08961d80fb12539",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 1.0000000000000013,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.386494742786283,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 8.246116288876184,
+ "state_hash": "b00bf20e38b236488432ebaaa42691474cd68631fd141127185217573f05d4f2",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.0
+ ]
+ },
+ "league": "ncaambb",
+ "promoted": true,
+ "relative_improvement": 0.04225006993986202,
+ "selected_ensemble": {
+ "ensemble_hash": "3a26b1869b41e662ecdfe044a54229c6e5998280f88a6ad5003326302350654e",
+ "evidence_status": "chronological_calibration_challenger",
+ "league": "ncaambb",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 72.0,
+ "base_home_score": 75.0,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "ncaambb",
+ "margin_sd": 14.0,
+ "parent_hash": "",
+ "profile_hash": "14be1ec209dc6acf4030c480c7c2c6abf250986580e5da75595419c8fd8028df",
+ "total_score_sd": 16.5
+ },
+ {
+ "away_strength_exponent": 0.9380995927689169,
+ "base_away_score": 64.26338685281874,
+ "base_home_score": 67.90736863209588,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 1.1198826403419602,
+ "league": "ncaambb",
+ "margin_sd": 12.337242613541385,
+ "parent_hash": "d908371efab1b1058ff372457736decc2f22f9d69723d762431e794c4f4582e3",
+ "profile_hash": "05bcc37afeab1ab4bf15ea01c88cd88d9e19e259e85a843ba6904dc94e5285ee",
+ "total_score_sd": 11.844982854797419
+ },
+ {
+ "away_strength_exponent": 0.9839084920688369,
+ "base_away_score": 64.17862932003789,
+ "base_home_score": 66.40814600980535,
+ "evidence_status": "train_search_candidate",
+ "generation": 7,
+ "home_strength_exponent": 1.1265354070594922,
+ "league": "ncaambb",
+ "margin_sd": 11.751801481101191,
+ "parent_hash": "5052bec2704f4278b8055686fdfd6fdaca864456ff8480e6bd1c3a16ff8cd5c2",
+ "profile_hash": "d908371efab1b1058ff372457736decc2f22f9d69723d762431e794c4f4582e3",
+ "total_score_sd": 12.527208607031197
+ },
+ {
+ "away_strength_exponent": 1.0302789332906102,
+ "base_away_score": 64.56603709857632,
+ "base_home_score": 68.11959848451264,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 1.15845619003206,
+ "league": "ncaambb",
+ "margin_sd": 12.172650135194955,
+ "parent_hash": "d908371efab1b1058ff372457736decc2f22f9d69723d762431e794c4f4582e3",
+ "profile_hash": "a3426257638d3914687ea87b35c7948a9df8423501f8509cc563d4635f364bad",
+ "total_score_sd": 12.250367245233734
+ },
+ {
+ "away_strength_exponent": 0.9757805013766029,
+ "base_away_score": 64.69153447008274,
+ "base_home_score": 67.3019953859376,
+ "evidence_status": "train_search_candidate",
+ "generation": 6,
+ "home_strength_exponent": 1.0463799843916333,
+ "league": "ncaambb",
+ "margin_sd": 12.360366882633027,
+ "parent_hash": "035fdaf6642f08d5f653660bf422cf514301df099700740c1740ff66f014aa95",
+ "profile_hash": "5052bec2704f4278b8055686fdfd6fdaca864456ff8480e6bd1c3a16ff8cd5c2",
+ "total_score_sd": 13.12846794130971
+ },
+ {
+ "away_strength_exponent": 1.0525771945812439,
+ "base_away_score": 65.56062542041047,
+ "base_home_score": 67.05886346685132,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 1.0249276075178801,
+ "league": "ncaambb",
+ "margin_sd": 11.814617284868469,
+ "parent_hash": "5052bec2704f4278b8055686fdfd6fdaca864456ff8480e6bd1c3a16ff8cd5c2",
+ "profile_hash": "d5abde343917aae55c5b655aed7e5ce5542a8d6e94ebb6cc5b1dff7aef5b914b",
+ "total_score_sd": 12.842103349942267
+ }
+ ],
+ "weights": [
+ 0.15204731462607787,
+ 0.17053030010320389,
+ 0.17008865902417303,
+ 0.1698776799805041,
+ 0.16875167581778863,
+ 0.16870437044825248
+ ]
+ },
+ "selected_state": {
+ "drift_score": 0.0,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "3a26b1869b41e662ecdfe044a54229c6e5998280f88a6ad5003326302350654e",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 0.9607894391523251,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.174282931387665,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 8.008633532956152,
+ "state_hash": "924515d3adfcde4094160bbe9a1c1741be83320aad2c0d1e322f724c309fcb9d",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 0.001155014984004925,
+ 0.19050882700932764,
+ 0.19279742459698684,
+ 0.14440496188814017,
+ 0.26188724112414913,
+ 0.20924653039739127
+ ]
+ }
+ },
+ {
+ "challenger_calibration_score": {
+ "composite_loss": 8.35269018511674,
+ "games": 50,
+ "home_win_brier": 0.23858136537417907,
+ "interval_coverage": 0.89,
+ "interval_coverage_error": 0.010000000000000009,
+ "mean_joint_negative_log_likelihood": 7.855527454368383
+ },
+ "challenger_ensemble": {
+ "ensemble_hash": "3998dbc995c7a222b6b34536892eb79abfcf27282bf679a7177ff9539d1f2805",
+ "evidence_status": "chronological_calibration_challenger",
+ "league": "nfl",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 21.8,
+ "base_home_score": 23.5,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "nfl",
+ "margin_sd": 14.0,
+ "parent_hash": "",
+ "profile_hash": "2cf12a1c59550d09aad4853366ee45da48461195286aba2fc665167a2d0accd0",
+ "total_score_sd": 13.7
+ },
+ {
+ "away_strength_exponent": 0.8127119203573007,
+ "base_away_score": 18.73783903969967,
+ "base_home_score": 20.3629838465437,
+ "evidence_status": "train_search_candidate",
+ "generation": 7,
+ "home_strength_exponent": 0.9969598684496088,
+ "league": "nfl",
+ "margin_sd": 13.178752280003424,
+ "parent_hash": "2a4a54a4e5c8dc6d6a442fef71835692aebb90bc2c1e15966a6519755e2dd08f",
+ "profile_hash": "afb44b88704aab434182c745d9534462c135846c1314177112e6d2e05e054311",
+ "total_score_sd": 10.627786627666937
+ },
+ {
+ "away_strength_exponent": 0.8020288490154823,
+ "base_away_score": 17.320637029282533,
+ "base_home_score": 20.78051406276197,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 1.0035162330865472,
+ "league": "nfl",
+ "margin_sd": 11.50199515807155,
+ "parent_hash": "f0c50ab49baa7e660afddfb7e8979b224d34b7e1e51061967bc7c420e3abc67f",
+ "profile_hash": "766ad7571886b1fadb0ebe6d1ed5fef1256354b23f78160fdb3e476062950d1b",
+ "total_score_sd": 11.600187239371005
+ },
+ {
+ "away_strength_exponent": 0.8512905575954433,
+ "base_away_score": 18.148896585644028,
+ "base_home_score": 20.480196992727773,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 1.0699568127234662,
+ "league": "nfl",
+ "margin_sd": 12.866386653489073,
+ "parent_hash": "afb44b88704aab434182c745d9534462c135846c1314177112e6d2e05e054311",
+ "profile_hash": "8731bf2b25c094a319db6036857ab0e1bc3ca4a2bdec5bdf1a9a18d92e808d33",
+ "total_score_sd": 10.76790465892871
+ },
+ {
+ "away_strength_exponent": 0.8523283294650763,
+ "base_away_score": 18.30063485469079,
+ "base_home_score": 20.2833663619127,
+ "evidence_status": "train_search_candidate",
+ "generation": 6,
+ "home_strength_exponent": 0.9808436446464107,
+ "league": "nfl",
+ "margin_sd": 11.989103506291487,
+ "parent_hash": "f0c50ab49baa7e660afddfb7e8979b224d34b7e1e51061967bc7c420e3abc67f",
+ "profile_hash": "d283336f28c8bfedd347d047d6ea0f7f46cc810560a6c68068d61c04a67ed2c1",
+ "total_score_sd": 11.197421125439893
+ },
+ {
+ "away_strength_exponent": 0.889604059819956,
+ "base_away_score": 18.70864108022062,
+ "base_home_score": 20.342104976267645,
+ "evidence_status": "train_search_candidate",
+ "generation": 6,
+ "home_strength_exponent": 1.043714861028283,
+ "league": "nfl",
+ "margin_sd": 13.018103895884023,
+ "parent_hash": "26b97d9a0f1cd4902ae67eb0361cc91dfcbac517c715add130f5767739ac22fd",
+ "profile_hash": "c0d93223fd828846c50d5bcb9ec2740583e4e424ee7a8108d37c97a150094301",
+ "total_score_sd": 11.834070501789366
+ }
+ ],
+ "weights": [
+ 0.15930283189149294,
+ 0.168233869783031,
+ 0.16819825924187087,
+ 0.16818069024377116,
+ 0.16810612075332335,
+ 0.16797822808651072
+ ]
+ },
+ "challenger_state": {
+ "drift_score": 0.013888256227233537,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "3998dbc995c7a222b6b34536892eb79abfcf27282bf679a7177ff9539d1f2805",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 1.0202013400267562,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.242249944953999,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 8.356720424078421,
+ "state_hash": "e8735ad2ed9bbb110415c0882bf2e942dde406a658fd584b5d5d4e29841873a7",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 0.1726901759359644,
+ 0.13078316340900142,
+ 0.09577431634417387,
+ 0.10500586465848535,
+ 0.21457752265512625,
+ 0.2811689569972487
+ ]
+ },
+ "decision": "retained_incumbent:minimum_relative_improvement_not_met",
+ "generations": [
+ {
+ "best_profile_hash": "c7a4cb7c5b0eeb744b6a4b507293afafbc809472c5aaddd14f68eda78d3356c5",
+ "best_train_score": {
+ "composite_loss": 8.244992808341305,
+ "games": 100,
+ "home_win_brier": 0.22926206280465272,
+ "interval_coverage": 0.92,
+ "interval_coverage_error": 0.020000000000000018,
+ "mean_joint_negative_log_likelihood": 7.746468682731998
+ },
+ "candidates_evaluated": 32,
+ "generation": 1
+ },
+ {
+ "best_profile_hash": "41239859f3e42113eda589e768b0d61a34d98dcec911a70132774db077b2f665",
+ "best_train_score": {
+ "composite_loss": 8.186941930417184,
+ "games": 100,
+ "home_win_brier": 0.22861016981167537,
+ "interval_coverage": 0.9,
+ "interval_coverage_error": 0.0,
+ "mean_joint_negative_log_likelihood": 7.729721590793833
+ },
+ "candidates_evaluated": 32,
+ "generation": 2
+ },
+ {
+ "best_profile_hash": "41239859f3e42113eda589e768b0d61a34d98dcec911a70132774db077b2f665",
+ "best_train_score": {
+ "composite_loss": 8.186941930417184,
+ "games": 100,
+ "home_win_brier": 0.22861016981167537,
+ "interval_coverage": 0.9,
+ "interval_coverage_error": 0.0,
+ "mean_joint_negative_log_likelihood": 7.729721590793833
+ },
+ "candidates_evaluated": 32,
+ "generation": 3
+ },
+ {
+ "best_profile_hash": "41239859f3e42113eda589e768b0d61a34d98dcec911a70132774db077b2f665",
+ "best_train_score": {
+ "composite_loss": 8.186941930417184,
+ "games": 100,
+ "home_win_brier": 0.22861016981167537,
+ "interval_coverage": 0.9,
+ "interval_coverage_error": 0.0,
+ "mean_joint_negative_log_likelihood": 7.729721590793833
+ },
+ "candidates_evaluated": 32,
+ "generation": 4
+ },
+ {
+ "best_profile_hash": "f0c50ab49baa7e660afddfb7e8979b224d34b7e1e51061967bc7c420e3abc67f",
+ "best_train_score": {
+ "composite_loss": 8.184622781251578,
+ "games": 100,
+ "home_win_brier": 0.23308474872372362,
+ "interval_coverage": 0.895,
+ "interval_coverage_error": 0.0050000000000000044,
+ "mean_joint_negative_log_likelihood": 7.708453283804132
+ },
+ "candidates_evaluated": 32,
+ "generation": 5
+ },
+ {
+ "best_profile_hash": "d283336f28c8bfedd347d047d6ea0f7f46cc810560a6c68068d61c04a67ed2c1",
+ "best_train_score": {
+ "composite_loss": 8.177288848514712,
+ "games": 100,
+ "home_win_brier": 0.22858760020536478,
+ "interval_coverage": 0.895,
+ "interval_coverage_error": 0.0050000000000000044,
+ "mean_joint_negative_log_likelihood": 7.710113648103983
+ },
+ "candidates_evaluated": 32,
+ "generation": 6
+ },
+ {
+ "best_profile_hash": "afb44b88704aab434182c745d9534462c135846c1314177112e6d2e05e054311",
+ "best_train_score": {
+ "composite_loss": 8.174250279460889,
+ "games": 100,
+ "home_win_brier": 0.2287034736025193,
+ "interval_coverage": 0.9,
+ "interval_coverage_error": 0.0,
+ "mean_joint_negative_log_likelihood": 7.716843332255849
+ },
+ "candidates_evaluated": 32,
+ "generation": 7
+ },
+ {
+ "best_profile_hash": "afb44b88704aab434182c745d9534462c135846c1314177112e6d2e05e054311",
+ "best_train_score": {
+ "composite_loss": 8.174250279460889,
+ "games": 100,
+ "home_win_brier": 0.2287034736025193,
+ "interval_coverage": 0.9,
+ "interval_coverage_error": 0.0,
+ "mean_joint_negative_log_likelihood": 7.716843332255849
+ },
+ "candidates_evaluated": 32,
+ "generation": 8
+ }
+ ],
+ "incumbent_calibration_score": {
+ "composite_loss": 8.427984368402127,
+ "games": 50,
+ "home_win_brier": 0.23551834611431333,
+ "interval_coverage": 0.94,
+ "interval_coverage_error": 0.039999999999999925,
+ "mean_joint_negative_log_likelihood": 7.8769476761735
+ },
+ "incumbent_ensemble": {
+ "ensemble_hash": "52cc748b0f03d805bc32644c746152d71b8878f6cb3e9e2e6df533e3cb3718e2",
+ "evidence_status": "provisional_reference_anchor",
+ "league": "nfl",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 21.8,
+ "base_home_score": 23.5,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "nfl",
+ "margin_sd": 14.0,
+ "parent_hash": "",
+ "profile_hash": "2cf12a1c59550d09aad4853366ee45da48461195286aba2fc665167a2d0accd0",
+ "total_score_sd": 13.7
+ }
+ ],
+ "weights": [
+ 1.0
+ ]
+ },
+ "incumbent_state": {
+ "drift_score": 0.009386081910553939,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "52cc748b0f03d805bc32644c746152d71b8878f6cb3e9e2e6df533e3cb3718e2",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 0.923116346386637,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.229562938300864,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 8.306806290127815,
+ "state_hash": "c56bdf6245fc5a57c735db00e6d448c6670f5a96632121cbfa3e9d7e30dd0e91",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.0
+ ]
+ },
+ "league": "nfl",
+ "promoted": false,
+ "relative_improvement": 0.008933830438470725,
+ "selected_ensemble": {
+ "ensemble_hash": "52cc748b0f03d805bc32644c746152d71b8878f6cb3e9e2e6df533e3cb3718e2",
+ "evidence_status": "provisional_reference_anchor",
+ "league": "nfl",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 21.8,
+ "base_home_score": 23.5,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "nfl",
+ "margin_sd": 14.0,
+ "parent_hash": "",
+ "profile_hash": "2cf12a1c59550d09aad4853366ee45da48461195286aba2fc665167a2d0accd0",
+ "total_score_sd": 13.7
+ }
+ ],
+ "weights": [
+ 1.0
+ ]
+ },
+ "selected_state": {
+ "drift_score": 0.009386081910553939,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "52cc748b0f03d805bc32644c746152d71b8878f6cb3e9e2e6df533e3cb3718e2",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 0.923116346386637,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.229562938300864,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 8.306806290127815,
+ "state_hash": "c56bdf6245fc5a57c735db00e6d448c6670f5a96632121cbfa3e9d7e30dd0e91",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.0
+ ]
+ }
+ },
+ {
+ "challenger_calibration_score": {
+ "composite_loss": 4.7671157212113355,
+ "games": 50,
+ "home_win_brier": 0.2228624325270619,
+ "interval_coverage": 0.9,
+ "interval_coverage_error": 0.0,
+ "mean_joint_negative_log_likelihood": 4.321390856157212
+ },
+ "challenger_ensemble": {
+ "ensemble_hash": "b4268f4251d62981ee852625c817f48947e9e12aecc39da1b77d4ff869c86289",
+ "evidence_status": "chronological_calibration_challenger",
+ "league": "nhl",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 2.95,
+ "base_home_score": 3.2,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "nhl",
+ "margin_sd": 2.4,
+ "parent_hash": "",
+ "profile_hash": "dd2f407da7fec8a4017fec2f6e311c3010d4f874c1d156f9dc4a4d9ba25576c3",
+ "total_score_sd": 2.3
+ },
+ {
+ "away_strength_exponent": 1.3618435036484602,
+ "base_away_score": 2.8140096579368463,
+ "base_home_score": 2.9827709409299437,
+ "evidence_status": "train_search_candidate",
+ "generation": 6,
+ "home_strength_exponent": 1.0164249111888564,
+ "league": "nhl",
+ "margin_sd": 2.4067107458645474,
+ "parent_hash": "c0f59c1041dfffbcb83db90b24931ee0acf8315cd86d375cd903b1869716224f",
+ "profile_hash": "560b8c3bf885c09aba0c04204376e3091a28ca9006785a1e982d822fd4f20158",
+ "total_score_sd": 1.9217750431804201
+ },
+ {
+ "away_strength_exponent": 1.3918430671368498,
+ "base_away_score": 2.8395546024633056,
+ "base_home_score": 3.001160815782975,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 0.9742513551643636,
+ "league": "nhl",
+ "margin_sd": 2.347437453084234,
+ "parent_hash": "7e6cc68f9f179e60b9ad230a27f90dbac843e9dfc33f83849a71a51a37077069",
+ "profile_hash": "b792aed5100d5cfef059e56fe733dc686f999130857572ef57702f98220e5374",
+ "total_score_sd": 1.9848807761955292
+ },
+ {
+ "away_strength_exponent": 1.3675649819385032,
+ "base_away_score": 2.67379397546478,
+ "base_home_score": 3.2244694632163426,
+ "evidence_status": "train_search_candidate",
+ "generation": 5,
+ "home_strength_exponent": 0.9979113276154296,
+ "league": "nhl",
+ "margin_sd": 2.315479052327515,
+ "parent_hash": "3e88d5bd7565e8748490af5a78d84b19a8534868a6331d4d1752f34943540487",
+ "profile_hash": "c0f59c1041dfffbcb83db90b24931ee0acf8315cd86d375cd903b1869716224f",
+ "total_score_sd": 1.8514937320015388
+ },
+ {
+ "away_strength_exponent": 1.365373323994108,
+ "base_away_score": 2.6479224044804157,
+ "base_home_score": 3.0420403168143237,
+ "evidence_status": "train_search_candidate",
+ "generation": 5,
+ "home_strength_exponent": 0.8190424527874777,
+ "league": "nhl",
+ "margin_sd": 2.469930832788603,
+ "parent_hash": "e20a271760ee2ecb08354c7be8fa7b0533bc22ccf66bb8691f131706d6d4193d",
+ "profile_hash": "16e8f92eddd415582a8ca2282946b318fe60e8845d896d93538b603bc8cd0555",
+ "total_score_sd": 1.754941135672797
+ },
+ {
+ "away_strength_exponent": 1.444774898245588,
+ "base_away_score": 2.8087224671677236,
+ "base_home_score": 2.900908465085074,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 0.9764064324855087,
+ "league": "nhl",
+ "margin_sd": 2.4088026880950175,
+ "parent_hash": "560b8c3bf885c09aba0c04204376e3091a28ca9006785a1e982d822fd4f20158",
+ "profile_hash": "cbd5bb21fef457140e843a9455f9d3d073749dc621ad2bef307a40f02fe73c53",
+ "total_score_sd": 1.8330168778160287
+ }
+ ],
+ "weights": [
+ 0.16286673514032046,
+ 0.16755705994655176,
+ 0.16752559730854746,
+ 0.1673849214822694,
+ 0.16737507931387444,
+ 0.1672906068084365
+ ]
+ },
+ "challenger_state": {
+ "drift_score": 0.0,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "b4268f4251d62981ee852625c817f48947e9e12aecc39da1b77d4ff869c86289",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 1.0000000000000007,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 4.686936849303858,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 4.605010305685448,
+ "state_hash": "9e103f41a8cf8181c03bde20e2b260ff7daa3ca261c7c760e94c10dca68cc368",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 0.10302384802689585,
+ 0.18136314556312605,
+ 0.15845422350790386,
+ 0.20162059073033012,
+ 0.19463378905316608,
+ 0.16090440311857798
+ ]
+ },
+ "decision": "promoted",
+ "generations": [
+ {
+ "best_profile_hash": "c94b647e306de16066fb67ab8667ee126753d89c3b305a6b3165f8ca75169d55",
+ "best_train_score": {
+ "composite_loss": 4.712218702954687,
+ "games": 100,
+ "home_win_brier": 0.20103508188055405,
+ "interval_coverage": 0.905,
+ "interval_coverage_error": 0.0050000000000000044,
+ "mean_joint_negative_log_likelihood": 4.30014853919358
+ },
+ "candidates_evaluated": 32,
+ "generation": 1
+ },
+ {
+ "best_profile_hash": "92be3c6a04534df6f98bfb1f13e38f92f9d7a7a28942949b69feea86c3e87074",
+ "best_train_score": {
+ "composite_loss": 4.687654166540897,
+ "games": 100,
+ "home_win_brier": 0.19897799109894074,
+ "interval_coverage": 0.9,
+ "interval_coverage_error": 0.0,
+ "mean_joint_negative_log_likelihood": 4.289698184343015
+ },
+ "candidates_evaluated": 32,
+ "generation": 2
+ },
+ {
+ "best_profile_hash": "e20a271760ee2ecb08354c7be8fa7b0533bc22ccf66bb8691f131706d6d4193d",
+ "best_train_score": {
+ "composite_loss": 4.683921153937582,
+ "games": 100,
+ "home_win_brier": 0.19678729831368805,
+ "interval_coverage": 0.905,
+ "interval_coverage_error": 0.0050000000000000044,
+ "mean_joint_negative_log_likelihood": 4.280346557310206
+ },
+ "candidates_evaluated": 32,
+ "generation": 3
+ },
+ {
+ "best_profile_hash": "e20a271760ee2ecb08354c7be8fa7b0533bc22ccf66bb8691f131706d6d4193d",
+ "best_train_score": {
+ "composite_loss": 4.683921153937582,
+ "games": 100,
+ "home_win_brier": 0.19678729831368805,
+ "interval_coverage": 0.905,
+ "interval_coverage_error": 0.0050000000000000044,
+ "mean_joint_negative_log_likelihood": 4.280346557310206
+ },
+ "candidates_evaluated": 32,
+ "generation": 4
+ },
+ {
+ "best_profile_hash": "c0f59c1041dfffbcb83db90b24931ee0acf8315cd86d375cd903b1869716224f",
+ "best_train_score": {
+ "composite_loss": 4.659088406260525,
+ "games": 100,
+ "home_win_brier": 0.1968459811406281,
+ "interval_coverage": 0.9,
+ "interval_coverage_error": 0.0,
+ "mean_joint_negative_log_likelihood": 4.265396443979269
+ },
+ "candidates_evaluated": 32,
+ "generation": 5
+ },
+ {
+ "best_profile_hash": "560b8c3bf885c09aba0c04204376e3091a28ca9006785a1e982d822fd4f20158",
+ "best_train_score": {
+ "composite_loss": 4.654976924535752,
+ "games": 100,
+ "home_win_brier": 0.1966795654368007,
+ "interval_coverage": 0.9,
+ "interval_coverage_error": 0.0,
+ "mean_joint_negative_log_likelihood": 4.261617793662151
+ },
+ "candidates_evaluated": 32,
+ "generation": 6
+ },
+ {
+ "best_profile_hash": "560b8c3bf885c09aba0c04204376e3091a28ca9006785a1e982d822fd4f20158",
+ "best_train_score": {
+ "composite_loss": 4.654976924535752,
+ "games": 100,
+ "home_win_brier": 0.1966795654368007,
+ "interval_coverage": 0.9,
+ "interval_coverage_error": 0.0,
+ "mean_joint_negative_log_likelihood": 4.261617793662151
+ },
+ "candidates_evaluated": 32,
+ "generation": 7
+ },
+ {
+ "best_profile_hash": "560b8c3bf885c09aba0c04204376e3091a28ca9006785a1e982d822fd4f20158",
+ "best_train_score": {
+ "composite_loss": 4.654976924535752,
+ "games": 100,
+ "home_win_brier": 0.1966795654368007,
+ "interval_coverage": 0.9,
+ "interval_coverage_error": 0.0,
+ "mean_joint_negative_log_likelihood": 4.261617793662151
+ },
+ "candidates_evaluated": 32,
+ "generation": 8
+ }
+ ],
+ "incumbent_calibration_score": {
+ "composite_loss": 4.831941943380519,
+ "games": 50,
+ "home_win_brier": 0.2199413705553162,
+ "interval_coverage": 0.91,
+ "interval_coverage_error": 0.010000000000000009,
+ "mean_joint_negative_log_likelihood": 4.372059202269887
+ },
+ "incumbent_ensemble": {
+ "ensemble_hash": "382ec0d5185a96f540f91839c8bd6328d408d70a8ec1f16352aa22553c05bcfb",
+ "evidence_status": "provisional_reference_anchor",
+ "league": "nhl",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 2.95,
+ "base_home_score": 3.2,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "nhl",
+ "margin_sd": 2.4,
+ "parent_hash": "",
+ "profile_hash": "dd2f407da7fec8a4017fec2f6e311c3010d4f874c1d156f9dc4a4d9ba25576c3",
+ "total_score_sd": 2.3
+ }
+ ],
+ "weights": [
+ 1.0
+ ]
+ },
+ "incumbent_state": {
+ "drift_score": 0.0,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "382ec0d5185a96f540f91839c8bd6328d408d70a8ec1f16352aa22553c05bcfb",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 0.9801986733067568,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 4.723961751695468,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 4.6298625684220225,
+ "state_hash": "7ce259e0d6f333426389c555b9f568c802b7265ae0ac4a6a55ba9f98184c8ee5",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.0
+ ]
+ },
+ "league": "nhl",
+ "promoted": true,
+ "relative_improvement": 0.013416183995751795,
+ "selected_ensemble": {
+ "ensemble_hash": "b4268f4251d62981ee852625c817f48947e9e12aecc39da1b77d4ff869c86289",
+ "evidence_status": "chronological_calibration_challenger",
+ "league": "nhl",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 2.95,
+ "base_home_score": 3.2,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "nhl",
+ "margin_sd": 2.4,
+ "parent_hash": "",
+ "profile_hash": "dd2f407da7fec8a4017fec2f6e311c3010d4f874c1d156f9dc4a4d9ba25576c3",
+ "total_score_sd": 2.3
+ },
+ {
+ "away_strength_exponent": 1.3618435036484602,
+ "base_away_score": 2.8140096579368463,
+ "base_home_score": 2.9827709409299437,
+ "evidence_status": "train_search_candidate",
+ "generation": 6,
+ "home_strength_exponent": 1.0164249111888564,
+ "league": "nhl",
+ "margin_sd": 2.4067107458645474,
+ "parent_hash": "c0f59c1041dfffbcb83db90b24931ee0acf8315cd86d375cd903b1869716224f",
+ "profile_hash": "560b8c3bf885c09aba0c04204376e3091a28ca9006785a1e982d822fd4f20158",
+ "total_score_sd": 1.9217750431804201
+ },
+ {
+ "away_strength_exponent": 1.3918430671368498,
+ "base_away_score": 2.8395546024633056,
+ "base_home_score": 3.001160815782975,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 0.9742513551643636,
+ "league": "nhl",
+ "margin_sd": 2.347437453084234,
+ "parent_hash": "7e6cc68f9f179e60b9ad230a27f90dbac843e9dfc33f83849a71a51a37077069",
+ "profile_hash": "b792aed5100d5cfef059e56fe733dc686f999130857572ef57702f98220e5374",
+ "total_score_sd": 1.9848807761955292
+ },
+ {
+ "away_strength_exponent": 1.3675649819385032,
+ "base_away_score": 2.67379397546478,
+ "base_home_score": 3.2244694632163426,
+ "evidence_status": "train_search_candidate",
+ "generation": 5,
+ "home_strength_exponent": 0.9979113276154296,
+ "league": "nhl",
+ "margin_sd": 2.315479052327515,
+ "parent_hash": "3e88d5bd7565e8748490af5a78d84b19a8534868a6331d4d1752f34943540487",
+ "profile_hash": "c0f59c1041dfffbcb83db90b24931ee0acf8315cd86d375cd903b1869716224f",
+ "total_score_sd": 1.8514937320015388
+ },
+ {
+ "away_strength_exponent": 1.365373323994108,
+ "base_away_score": 2.6479224044804157,
+ "base_home_score": 3.0420403168143237,
+ "evidence_status": "train_search_candidate",
+ "generation": 5,
+ "home_strength_exponent": 0.8190424527874777,
+ "league": "nhl",
+ "margin_sd": 2.469930832788603,
+ "parent_hash": "e20a271760ee2ecb08354c7be8fa7b0533bc22ccf66bb8691f131706d6d4193d",
+ "profile_hash": "16e8f92eddd415582a8ca2282946b318fe60e8845d896d93538b603bc8cd0555",
+ "total_score_sd": 1.754941135672797
+ },
+ {
+ "away_strength_exponent": 1.444774898245588,
+ "base_away_score": 2.8087224671677236,
+ "base_home_score": 2.900908465085074,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 0.9764064324855087,
+ "league": "nhl",
+ "margin_sd": 2.4088026880950175,
+ "parent_hash": "560b8c3bf885c09aba0c04204376e3091a28ca9006785a1e982d822fd4f20158",
+ "profile_hash": "cbd5bb21fef457140e843a9455f9d3d073749dc621ad2bef307a40f02fe73c53",
+ "total_score_sd": 1.8330168778160287
+ }
+ ],
+ "weights": [
+ 0.16286673514032046,
+ 0.16755705994655176,
+ 0.16752559730854746,
+ 0.1673849214822694,
+ 0.16737507931387444,
+ 0.1672906068084365
+ ]
+ },
+ "selected_state": {
+ "drift_score": 0.0,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "b4268f4251d62981ee852625c817f48947e9e12aecc39da1b77d4ff869c86289",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 1.0000000000000007,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 4.686936849303858,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 4.605010305685448,
+ "state_hash": "9e103f41a8cf8181c03bde20e2b260ff7daa3ca261c7c760e94c10dca68cc368",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 0.10302384802689585,
+ 0.18136314556312605,
+ 0.15845422350790386,
+ 0.20162059073033012,
+ 0.19463378905316608,
+ 0.16090440311857798
+ ]
+ }
+ },
+ {
+ "challenger_calibration_score": {
+ "composite_loss": 8.379522034337166,
+ "games": 50,
+ "home_win_brier": 0.16069882492885665,
+ "interval_coverage": 0.9,
+ "interval_coverage_error": 0.0,
+ "mean_joint_negative_log_likelihood": 8.058124384479452
+ },
+ "challenger_ensemble": {
+ "ensemble_hash": "369bd1fab70c4fe9c443214b61e5bb1297947388fae8402061d599b6dc5a975d",
+ "evidence_status": "chronological_calibration_challenger",
+ "league": "wnba",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 80.0,
+ "base_home_score": 82.0,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "wnba",
+ "margin_sd": 14.0,
+ "parent_hash": "",
+ "profile_hash": "a9efcb5f3219e8e9a3df4fdce3b3f767165faa82fe41cf874bdb0716548bb4d9",
+ "total_score_sd": 17.5
+ },
+ {
+ "away_strength_exponent": 1.0251595474377284,
+ "base_away_score": 72.11403431035531,
+ "base_home_score": 71.69042161368746,
+ "evidence_status": "train_search_candidate",
+ "generation": 7,
+ "home_strength_exponent": 1.0938685005129976,
+ "league": "wnba",
+ "margin_sd": 12.553668307327136,
+ "parent_hash": "468447632d3bbfb0286c4335ad436b5f32c841251c8614e5f2096d0b5dbf0a3f",
+ "profile_hash": "af6c47cb9cc880f80388c052e42e219dc4055b7d2c8b6e1346332703b49299e5",
+ "total_score_sd": 13.255930520302046
+ },
+ {
+ "away_strength_exponent": 1.0981336628870195,
+ "base_away_score": 71.11342291633342,
+ "base_home_score": 73.62693210352198,
+ "evidence_status": "train_search_candidate",
+ "generation": 7,
+ "home_strength_exponent": 1.1420227255585949,
+ "league": "wnba",
+ "margin_sd": 12.523765694931425,
+ "parent_hash": "7d2a641dbd76ac6fde3dfa526718e79569f129327958d60c3dfafc464b75af97",
+ "profile_hash": "b83f84e526bc77753ff0561968a83ca3f84f62dad23a54b08c2869b88226c810",
+ "total_score_sd": 13.124434195991878
+ },
+ {
+ "away_strength_exponent": 0.9827239039722672,
+ "base_away_score": 73.07586506043492,
+ "base_home_score": 73.49995936972549,
+ "evidence_status": "train_search_candidate",
+ "generation": 7,
+ "home_strength_exponent": 1.060463397601755,
+ "league": "wnba",
+ "margin_sd": 11.322075003472191,
+ "parent_hash": "02a8002ff7041946836ce1a1fcb8f53773f3b838801f82797911d7fbf267efec",
+ "profile_hash": "6b7ed5b7bfddee7d6ec43ca6649a0fd953a0954c5a818b269d146c55b54ea0e2",
+ "total_score_sd": 13.178399018766651
+ },
+ {
+ "away_strength_exponent": 0.9391411924229954,
+ "base_away_score": 73.82314278504273,
+ "base_home_score": 72.09561563722342,
+ "evidence_status": "train_search_candidate",
+ "generation": 6,
+ "home_strength_exponent": 1.1340765001951492,
+ "league": "wnba",
+ "margin_sd": 12.028397269421774,
+ "parent_hash": "ab7556213fe56f2a8c712da7df880059839437bfee109b7996749fcea6802355",
+ "profile_hash": "5fb5c12d474e17f2c2719e637aa37a3fb53d24a5dda665aa15e1c8ce0cc9961b",
+ "total_score_sd": 14.119914546223248
+ },
+ {
+ "away_strength_exponent": 1.0428759542867176,
+ "base_away_score": 73.34588663690329,
+ "base_home_score": 70.67653549724727,
+ "evidence_status": "train_search_candidate",
+ "generation": 6,
+ "home_strength_exponent": 1.177066395306101,
+ "league": "wnba",
+ "margin_sd": 12.30699982423615,
+ "parent_hash": "7d2a641dbd76ac6fde3dfa526718e79569f129327958d60c3dfafc464b75af97",
+ "profile_hash": "468447632d3bbfb0286c4335ad436b5f32c841251c8614e5f2096d0b5dbf0a3f",
+ "total_score_sd": 13.296762898729602
+ }
+ ],
+ "weights": [
+ 0.14546085482667262,
+ 0.1713210376892588,
+ 0.17089076167696657,
+ 0.1708509658434923,
+ 0.17074437378062704,
+ 0.17073200618298265
+ ]
+ },
+ "challenger_state": {
+ "drift_score": 0.0,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "369bd1fab70c4fe9c443214b61e5bb1297947388fae8402061d599b6dc5a975d",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 1.0,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.093222299641932,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 8.024674327270455,
+ "state_hash": "b5389b73b296d8ff3307fa1679ea4534b3e0cdb82aba2cf0f5a58625c2587f88",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.500943057167728e-05,
+ 0.2966973670938307,
+ 0.07172853425048047,
+ 0.11683643807084605,
+ 0.25589695988228717,
+ 0.25882569127198385
+ ]
+ },
+ "decision": "promoted",
+ "generations": [
+ {
+ "best_profile_hash": "f044c42412e598124ded94ae81c65bf1fff0dbaec09540c8e0a09b41317a6ee3",
+ "best_train_score": {
+ "composite_loss": 8.262537971556736,
+ "games": 100,
+ "home_win_brier": 0.11956899659901453,
+ "interval_coverage": 0.93,
+ "interval_coverage_error": 0.030000000000000027,
+ "mean_joint_negative_log_likelihood": 7.963399978358707
+ },
+ "candidates_evaluated": 32,
+ "generation": 1
+ },
+ {
+ "best_profile_hash": "635aaf1f5fe3d09a13232c075cbb713e42ee920b9469346693b2b127f6d6f02c",
+ "best_train_score": {
+ "composite_loss": 8.203497289558689,
+ "games": 100,
+ "home_win_brier": 0.12021767125431083,
+ "interval_coverage": 0.91,
+ "interval_coverage_error": 0.010000000000000009,
+ "mean_joint_negative_log_likelihood": 7.943061947050068
+ },
+ "candidates_evaluated": 32,
+ "generation": 2
+ },
+ {
+ "best_profile_hash": "82f9b0b481716af3737e7fa95a906b7e18fedb39acf1b0790ad359b8e955d1bb",
+ "best_train_score": {
+ "composite_loss": 8.198183950694297,
+ "games": 100,
+ "home_win_brier": 0.12180829510380681,
+ "interval_coverage": 0.905,
+ "interval_coverage_error": 0.0050000000000000044,
+ "mean_joint_negative_log_likelihood": 7.944567360486684
+ },
+ "candidates_evaluated": 32,
+ "generation": 3
+ },
+ {
+ "best_profile_hash": "82f9b0b481716af3737e7fa95a906b7e18fedb39acf1b0790ad359b8e955d1bb",
+ "best_train_score": {
+ "composite_loss": 8.198183950694297,
+ "games": 100,
+ "home_win_brier": 0.12180829510380681,
+ "interval_coverage": 0.905,
+ "interval_coverage_error": 0.0050000000000000044,
+ "mean_joint_negative_log_likelihood": 7.944567360486684
+ },
+ "candidates_evaluated": 32,
+ "generation": 4
+ },
+ {
+ "best_profile_hash": "ab7556213fe56f2a8c712da7df880059839437bfee109b7996749fcea6802355",
+ "best_train_score": {
+ "composite_loss": 8.178515753524696,
+ "games": 100,
+ "home_win_brier": 0.12331051871446606,
+ "interval_coverage": 0.9,
+ "interval_coverage_error": 0.0,
+ "mean_joint_negative_log_likelihood": 7.931894716095764
+ },
+ "candidates_evaluated": 32,
+ "generation": 5
+ },
+ {
+ "best_profile_hash": "5fb5c12d474e17f2c2719e637aa37a3fb53d24a5dda665aa15e1c8ce0cc9961b",
+ "best_train_score": {
+ "composite_loss": 8.15633041978037,
+ "games": 100,
+ "home_win_brier": 0.12327843697814737,
+ "interval_coverage": 0.905,
+ "interval_coverage_error": 0.0050000000000000044,
+ "mean_joint_negative_log_likelihood": 7.8997735458240745
+ },
+ "candidates_evaluated": 32,
+ "generation": 6
+ },
+ {
+ "best_profile_hash": "af6c47cb9cc880f80388c052e42e219dc4055b7d2c8b6e1346332703b49299e5",
+ "best_train_score": {
+ "composite_loss": 8.142843772242365,
+ "games": 100,
+ "home_win_brier": 0.12013774010797616,
+ "interval_coverage": 0.9,
+ "interval_coverage_error": 0.0,
+ "mean_joint_negative_log_likelihood": 7.902568292026413
+ },
+ "candidates_evaluated": 32,
+ "generation": 7
+ },
+ {
+ "best_profile_hash": "af6c47cb9cc880f80388c052e42e219dc4055b7d2c8b6e1346332703b49299e5",
+ "best_train_score": {
+ "composite_loss": 8.142843772242365,
+ "games": 100,
+ "home_win_brier": 0.12013774010797616,
+ "interval_coverage": 0.9,
+ "interval_coverage_error": 0.0,
+ "mean_joint_negative_log_likelihood": 7.902568292026413
+ },
+ "candidates_evaluated": 32,
+ "generation": 8
+ }
+ ],
+ "incumbent_calibration_score": {
+ "composite_loss": 9.188926654018786,
+ "games": 50,
+ "home_win_brier": 0.16577671914460065,
+ "interval_coverage": 0.87,
+ "interval_coverage_error": 0.030000000000000027,
+ "mean_joint_negative_log_likelihood": 8.797373215729584
+ },
+ "incumbent_ensemble": {
+ "ensemble_hash": "92022b12c8dd03d4fb005a8a84b4041b3370ee4e401e2e281230d8f6c3b3d284",
+ "evidence_status": "provisional_reference_anchor",
+ "league": "wnba",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 80.0,
+ "base_home_score": 82.0,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "wnba",
+ "margin_sd": 14.0,
+ "parent_hash": "",
+ "profile_hash": "a9efcb5f3219e8e9a3df4fdce3b3f767165faa82fe41cf874bdb0716548bb4d9",
+ "total_score_sd": 17.5
+ }
+ ],
+ "weights": [
+ 1.0
+ ]
+ },
+ "incumbent_state": {
+ "drift_score": 0.0,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "92022b12c8dd03d4fb005a8a84b4041b3370ee4e401e2e281230d8f6c3b3d284",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 1.06183654654536,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.828494403135926,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 8.776294316432912,
+ "state_hash": "bb00abb17fee66e3eb9152039b5e33447479ed0e079dd11c90c8fca060eb8d21",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.0
+ ]
+ },
+ "league": "wnba",
+ "promoted": true,
+ "relative_improvement": 0.08808478401855853,
+ "selected_ensemble": {
+ "ensemble_hash": "369bd1fab70c4fe9c443214b61e5bb1297947388fae8402061d599b6dc5a975d",
+ "evidence_status": "chronological_calibration_challenger",
+ "league": "wnba",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 80.0,
+ "base_home_score": 82.0,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "wnba",
+ "margin_sd": 14.0,
+ "parent_hash": "",
+ "profile_hash": "a9efcb5f3219e8e9a3df4fdce3b3f767165faa82fe41cf874bdb0716548bb4d9",
+ "total_score_sd": 17.5
+ },
+ {
+ "away_strength_exponent": 1.0251595474377284,
+ "base_away_score": 72.11403431035531,
+ "base_home_score": 71.69042161368746,
+ "evidence_status": "train_search_candidate",
+ "generation": 7,
+ "home_strength_exponent": 1.0938685005129976,
+ "league": "wnba",
+ "margin_sd": 12.553668307327136,
+ "parent_hash": "468447632d3bbfb0286c4335ad436b5f32c841251c8614e5f2096d0b5dbf0a3f",
+ "profile_hash": "af6c47cb9cc880f80388c052e42e219dc4055b7d2c8b6e1346332703b49299e5",
+ "total_score_sd": 13.255930520302046
+ },
+ {
+ "away_strength_exponent": 1.0981336628870195,
+ "base_away_score": 71.11342291633342,
+ "base_home_score": 73.62693210352198,
+ "evidence_status": "train_search_candidate",
+ "generation": 7,
+ "home_strength_exponent": 1.1420227255585949,
+ "league": "wnba",
+ "margin_sd": 12.523765694931425,
+ "parent_hash": "7d2a641dbd76ac6fde3dfa526718e79569f129327958d60c3dfafc464b75af97",
+ "profile_hash": "b83f84e526bc77753ff0561968a83ca3f84f62dad23a54b08c2869b88226c810",
+ "total_score_sd": 13.124434195991878
+ },
+ {
+ "away_strength_exponent": 0.9827239039722672,
+ "base_away_score": 73.07586506043492,
+ "base_home_score": 73.49995936972549,
+ "evidence_status": "train_search_candidate",
+ "generation": 7,
+ "home_strength_exponent": 1.060463397601755,
+ "league": "wnba",
+ "margin_sd": 11.322075003472191,
+ "parent_hash": "02a8002ff7041946836ce1a1fcb8f53773f3b838801f82797911d7fbf267efec",
+ "profile_hash": "6b7ed5b7bfddee7d6ec43ca6649a0fd953a0954c5a818b269d146c55b54ea0e2",
+ "total_score_sd": 13.178399018766651
+ },
+ {
+ "away_strength_exponent": 0.9391411924229954,
+ "base_away_score": 73.82314278504273,
+ "base_home_score": 72.09561563722342,
+ "evidence_status": "train_search_candidate",
+ "generation": 6,
+ "home_strength_exponent": 1.1340765001951492,
+ "league": "wnba",
+ "margin_sd": 12.028397269421774,
+ "parent_hash": "ab7556213fe56f2a8c712da7df880059839437bfee109b7996749fcea6802355",
+ "profile_hash": "5fb5c12d474e17f2c2719e637aa37a3fb53d24a5dda665aa15e1c8ce0cc9961b",
+ "total_score_sd": 14.119914546223248
+ },
+ {
+ "away_strength_exponent": 1.0428759542867176,
+ "base_away_score": 73.34588663690329,
+ "base_home_score": 70.67653549724727,
+ "evidence_status": "train_search_candidate",
+ "generation": 6,
+ "home_strength_exponent": 1.177066395306101,
+ "league": "wnba",
+ "margin_sd": 12.30699982423615,
+ "parent_hash": "7d2a641dbd76ac6fde3dfa526718e79569f129327958d60c3dfafc464b75af97",
+ "profile_hash": "468447632d3bbfb0286c4335ad436b5f32c841251c8614e5f2096d0b5dbf0a3f",
+ "total_score_sd": 13.296762898729602
+ }
+ ],
+ "weights": [
+ 0.14546085482667262,
+ 0.1713210376892588,
+ 0.17089076167696657,
+ 0.1708509658434923,
+ 0.17074437378062704,
+ 0.17073200618298265
+ ]
+ },
+ "selected_state": {
+ "drift_score": 0.0,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "369bd1fab70c4fe9c443214b61e5bb1297947388fae8402061d599b6dc5a975d",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 1.0,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.093222299641932,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 8.024674327270455,
+ "state_hash": "b5389b73b296d8ff3307fa1679ea4534b3e0cdb82aba2cf0f5a58625c2587f88",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.500943057167728e-05,
+ 0.2966973670938307,
+ 0.07172853425048047,
+ 0.11683643807084605,
+ 0.25589695988228717,
+ 0.25882569127198385
+ ]
+ }
+ }
+ ],
+ "status": "chronological_calibration_only_not_real_world_certification"
+}
diff --git a/reports/autonomy_v3_fixture/shadow_adapted_bundle.json b/reports/autonomy_v3_fixture/shadow_adapted_bundle.json
new file mode 100644
index 0000000..b9b5623
--- /dev/null
+++ b/reports/autonomy_v3_fixture/shadow_adapted_bundle.json
@@ -0,0 +1,937 @@
+{
+ "bundle_hash": "7f1903911221d44a29bbed34a9e13e47e25f0bf8c1ccf3ba880dbc2c2d03722a",
+ "champions": [
+ {
+ "ensemble": {
+ "ensemble_hash": "bb0b6a4184ebbf8489abaf3dc3df077d280c14d888340b59c2871215f6df8360",
+ "evidence_status": "provisional_reference_anchor",
+ "league": "mlb",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 4.3,
+ "base_home_score": 4.55,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "mlb",
+ "margin_sd": 4.4,
+ "parent_hash": "",
+ "profile_hash": "ed4a36ddf530bc1e400bae06859869e1b8b9bf4c542f53a193c39d949638d53e",
+ "total_score_sd": 4.6
+ }
+ ],
+ "weights": [
+ 1.0
+ ]
+ },
+ "league": "mlb",
+ "promoted": false,
+ "rollback_ensemble": {
+ "ensemble_hash": "bb0b6a4184ebbf8489abaf3dc3df077d280c14d888340b59c2871215f6df8360",
+ "evidence_status": "provisional_reference_anchor",
+ "league": "mlb",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 4.3,
+ "base_home_score": 4.55,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "mlb",
+ "margin_sd": 4.4,
+ "parent_hash": "",
+ "profile_hash": "ed4a36ddf530bc1e400bae06859869e1b8b9bf4c542f53a193c39d949638d53e",
+ "total_score_sd": 4.6
+ }
+ ],
+ "weights": [
+ 1.0
+ ]
+ },
+ "rollback_state": {
+ "drift_score": 0.050688478956998094,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "bb0b6a4184ebbf8489abaf3dc3df077d280c14d888340b59c2871215f6df8360",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 0.8869204367171584,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 5.59425099372921,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 5.8778150675050185,
+ "state_hash": "a23ac9f2ccc36db8368dcd341b0025f12d6d2b188c95ca9013b1dc61b461e78a",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.0
+ ]
+ },
+ "state": {
+ "drift_score": 0.0,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "bb0b6a4184ebbf8489abaf3dc3df077d280c14d888340b59c2871215f6df8360",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 0.8187307530779836,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 5.772593588641054,
+ "minimum_drift_observations": 40,
+ "observations": 90,
+ "short_decay": 0.2,
+ "short_loss_ewma": 5.757266428023099,
+ "state_hash": "93fbe3e1a46c9dfd370e304f2ad7ef6c236dce229fc2296d7093ef4c56f780c8",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.0
+ ]
+ }
+ },
+ {
+ "ensemble": {
+ "ensemble_hash": "60e7da6020d67de678c0d044f300847fde90bf16161917510b08c83bfd5dbe96",
+ "evidence_status": "chronological_calibration_challenger",
+ "league": "nba",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 113.0,
+ "base_home_score": 116.0,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "nba",
+ "margin_sd": 15.0,
+ "parent_hash": "",
+ "profile_hash": "1fd107dd93cec7f199c4979e7334f2ad2c7e7d61e6e5d3fa7a7c6741138e40d1",
+ "total_score_sd": 20.0
+ },
+ {
+ "away_strength_exponent": 0.9632460782428364,
+ "base_away_score": 100.41120048415034,
+ "base_home_score": 101.40842755264546,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 1.1035181164801218,
+ "league": "nba",
+ "margin_sd": 13.736474631089353,
+ "parent_hash": "d4336fc445a68de29aec9f851052ee18e00a6c18e7198fda34d832e4a727eafd",
+ "profile_hash": "6dabbdf2c5066b2dc80eb6e6088fbe21f308472a7241c3d76a36ea7ae27b0dc9",
+ "total_score_sd": 15.530808786290953
+ },
+ {
+ "away_strength_exponent": 0.9299864332685756,
+ "base_away_score": 99.12089973217256,
+ "base_home_score": 102.60460634910284,
+ "evidence_status": "train_search_candidate",
+ "generation": 7,
+ "home_strength_exponent": 1.0374456736407256,
+ "league": "nba",
+ "margin_sd": 14.476747331295748,
+ "parent_hash": "d4336fc445a68de29aec9f851052ee18e00a6c18e7198fda34d832e4a727eafd",
+ "profile_hash": "2c3b39a22523f4f245dcd1afe8fcfc54544020073f6153bd180207f50ca0fa67",
+ "total_score_sd": 15.986652973245818
+ },
+ {
+ "away_strength_exponent": 0.9314639467993735,
+ "base_away_score": 97.55462255575519,
+ "base_home_score": 100.60692741111606,
+ "evidence_status": "train_search_candidate",
+ "generation": 6,
+ "home_strength_exponent": 1.0481985521298671,
+ "league": "nba",
+ "margin_sd": 13.538006034660736,
+ "parent_hash": "1f29dc288a020ac6049537b27f5d91603e2e548bb8639e20fcd8c9527fa9b748",
+ "profile_hash": "d4336fc445a68de29aec9f851052ee18e00a6c18e7198fda34d832e4a727eafd",
+ "total_score_sd": 16.76275018651739
+ },
+ {
+ "away_strength_exponent": 0.8862112258764434,
+ "base_away_score": 100.34400852330234,
+ "base_home_score": 99.90111885665915,
+ "evidence_status": "train_search_candidate",
+ "generation": 7,
+ "home_strength_exponent": 0.9978232275893777,
+ "league": "nba",
+ "margin_sd": 13.709770977740531,
+ "parent_hash": "4cc9fa6c37e99b992fc73dec931c77bbd815b6a14538deb5d0471d5dfe18a3b3",
+ "profile_hash": "2b9ae85a9ff77cddc6e95f95feff238a5aad863eb1b5a6d4d0c1682859f773cf",
+ "total_score_sd": 14.728999472122727
+ },
+ {
+ "away_strength_exponent": 0.9168426579759286,
+ "base_away_score": 98.08693111402029,
+ "base_home_score": 100.24510182059633,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 1.029985233214439,
+ "league": "nba",
+ "margin_sd": 13.914503225184157,
+ "parent_hash": "2c3b39a22523f4f245dcd1afe8fcfc54544020073f6153bd180207f50ca0fa67",
+ "profile_hash": "c24f67abab0bf80575320bbbed67381f38b4de2aeee0cfe291bee9e80ceba669",
+ "total_score_sd": 16.713986694619834
+ }
+ ],
+ "weights": [
+ 0.12893045230055183,
+ 0.17538891395996567,
+ 0.1747196187644406,
+ 0.17386258202490054,
+ 0.17362605222135616,
+ 0.17347238072878526
+ ]
+ },
+ "league": "nba",
+ "promoted": true,
+ "rollback_ensemble": {
+ "ensemble_hash": "938868d720f17e6b997358c0a52254af174a1b3081193720225c3ca7e3eda934",
+ "evidence_status": "provisional_reference_anchor",
+ "league": "nba",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 113.0,
+ "base_home_score": 116.0,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "nba",
+ "margin_sd": 15.0,
+ "parent_hash": "",
+ "profile_hash": "1fd107dd93cec7f199c4979e7334f2ad2c7e7d61e6e5d3fa7a7c6741138e40d1",
+ "total_score_sd": 20.0
+ }
+ ],
+ "weights": [
+ 1.0
+ ]
+ },
+ "rollback_state": {
+ "drift_score": 0.0,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "938868d720f17e6b997358c0a52254af174a1b3081193720225c3ca7e3eda934",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 1.1502737988572285,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 9.584379101566844,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 9.00479793127273,
+ "state_hash": "8938e17f435856b6ce780263706e625583f33790ccd311fee85a1564aa1988dd",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.0
+ ]
+ },
+ "state": {
+ "drift_score": 0.0,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "60e7da6020d67de678c0d044f300847fde90bf16161917510b08c83bfd5dbe96",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 0.9417645335842497,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.228777215687872,
+ "minimum_drift_observations": 40,
+ "observations": 90,
+ "short_decay": 0.2,
+ "short_loss_ewma": 7.797677877182591,
+ "state_hash": "50f9153230694ee41939e2c093e5fec4dc1a79666b04a7d65f8ac45dcdf6ff9d",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.1033602702294112e-10,
+ 0.5893251182400253,
+ 0.16346399073534934,
+ 0.08860378788601675,
+ 0.08503255688672598,
+ 0.07357454614154653
+ ]
+ }
+ },
+ {
+ "ensemble": {
+ "ensemble_hash": "110e0a2b1d912b65c9c8e2421251514d29e036503be2191a6a19c5418d16b42a",
+ "evidence_status": "provisional_reference_anchor",
+ "league": "ncaaf",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 26.5,
+ "base_home_score": 29.0,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "ncaaf",
+ "margin_sd": 18.0,
+ "parent_hash": "",
+ "profile_hash": "6c3ad3401f75976c8a0cc1301c7aa9d9ba28a4d78b9bd5ee2432bf29e58493f7",
+ "total_score_sd": 15.7
+ }
+ ],
+ "weights": [
+ 1.0
+ ]
+ },
+ "league": "ncaaf",
+ "promoted": false,
+ "rollback_ensemble": {
+ "ensemble_hash": "110e0a2b1d912b65c9c8e2421251514d29e036503be2191a6a19c5418d16b42a",
+ "evidence_status": "provisional_reference_anchor",
+ "league": "ncaaf",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 26.5,
+ "base_home_score": 29.0,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "ncaaf",
+ "margin_sd": 18.0,
+ "parent_hash": "",
+ "profile_hash": "6c3ad3401f75976c8a0cc1301c7aa9d9ba28a4d78b9bd5ee2432bf29e58493f7",
+ "total_score_sd": 15.7
+ }
+ ],
+ "weights": [
+ 1.0
+ ]
+ },
+ "rollback_state": {
+ "drift_score": 0.053373359494810986,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "110e0a2b1d912b65c9c8e2421251514d29e036503be2191a6a19c5418d16b42a",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 0.9607894391523236,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.821992883967974,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 9.292852281624661,
+ "state_hash": "6490ed8bb46c72d47e410317f52bba03128f9076dbe23088cbd0748735b8b91b",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.0
+ ]
+ },
+ "state": {
+ "drift_score": 0.0035082198698251758,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "110e0a2b1d912b65c9c8e2421251514d29e036503be2191a6a19c5418d16b42a",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 0.8869204367171581,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.635516325467263,
+ "minimum_drift_observations": 40,
+ "observations": 90,
+ "short_decay": 0.2,
+ "short_loss_ewma": 8.665811615426467,
+ "state_hash": "758c2e91c5db77d5717b6af5fe29b9bf40a5d2641f67a1fd31a05ed7a8e2a272",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.0
+ ]
+ }
+ },
+ {
+ "ensemble": {
+ "ensemble_hash": "3a26b1869b41e662ecdfe044a54229c6e5998280f88a6ad5003326302350654e",
+ "evidence_status": "chronological_calibration_challenger",
+ "league": "ncaambb",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 72.0,
+ "base_home_score": 75.0,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "ncaambb",
+ "margin_sd": 14.0,
+ "parent_hash": "",
+ "profile_hash": "14be1ec209dc6acf4030c480c7c2c6abf250986580e5da75595419c8fd8028df",
+ "total_score_sd": 16.5
+ },
+ {
+ "away_strength_exponent": 0.9380995927689169,
+ "base_away_score": 64.26338685281874,
+ "base_home_score": 67.90736863209588,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 1.1198826403419602,
+ "league": "ncaambb",
+ "margin_sd": 12.337242613541385,
+ "parent_hash": "d908371efab1b1058ff372457736decc2f22f9d69723d762431e794c4f4582e3",
+ "profile_hash": "05bcc37afeab1ab4bf15ea01c88cd88d9e19e259e85a843ba6904dc94e5285ee",
+ "total_score_sd": 11.844982854797419
+ },
+ {
+ "away_strength_exponent": 0.9839084920688369,
+ "base_away_score": 64.17862932003789,
+ "base_home_score": 66.40814600980535,
+ "evidence_status": "train_search_candidate",
+ "generation": 7,
+ "home_strength_exponent": 1.1265354070594922,
+ "league": "ncaambb",
+ "margin_sd": 11.751801481101191,
+ "parent_hash": "5052bec2704f4278b8055686fdfd6fdaca864456ff8480e6bd1c3a16ff8cd5c2",
+ "profile_hash": "d908371efab1b1058ff372457736decc2f22f9d69723d762431e794c4f4582e3",
+ "total_score_sd": 12.527208607031197
+ },
+ {
+ "away_strength_exponent": 1.0302789332906102,
+ "base_away_score": 64.56603709857632,
+ "base_home_score": 68.11959848451264,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 1.15845619003206,
+ "league": "ncaambb",
+ "margin_sd": 12.172650135194955,
+ "parent_hash": "d908371efab1b1058ff372457736decc2f22f9d69723d762431e794c4f4582e3",
+ "profile_hash": "a3426257638d3914687ea87b35c7948a9df8423501f8509cc563d4635f364bad",
+ "total_score_sd": 12.250367245233734
+ },
+ {
+ "away_strength_exponent": 0.9757805013766029,
+ "base_away_score": 64.69153447008274,
+ "base_home_score": 67.3019953859376,
+ "evidence_status": "train_search_candidate",
+ "generation": 6,
+ "home_strength_exponent": 1.0463799843916333,
+ "league": "ncaambb",
+ "margin_sd": 12.360366882633027,
+ "parent_hash": "035fdaf6642f08d5f653660bf422cf514301df099700740c1740ff66f014aa95",
+ "profile_hash": "5052bec2704f4278b8055686fdfd6fdaca864456ff8480e6bd1c3a16ff8cd5c2",
+ "total_score_sd": 13.12846794130971
+ },
+ {
+ "away_strength_exponent": 1.0525771945812439,
+ "base_away_score": 65.56062542041047,
+ "base_home_score": 67.05886346685132,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 1.0249276075178801,
+ "league": "ncaambb",
+ "margin_sd": 11.814617284868469,
+ "parent_hash": "5052bec2704f4278b8055686fdfd6fdaca864456ff8480e6bd1c3a16ff8cd5c2",
+ "profile_hash": "d5abde343917aae55c5b655aed7e5ce5542a8d6e94ebb6cc5b1dff7aef5b914b",
+ "total_score_sd": 12.842103349942267
+ }
+ ],
+ "weights": [
+ 0.15204731462607787,
+ 0.17053030010320389,
+ 0.17008865902417303,
+ 0.1698776799805041,
+ 0.16875167581778863,
+ 0.16870437044825248
+ ]
+ },
+ "league": "ncaambb",
+ "promoted": true,
+ "rollback_ensemble": {
+ "ensemble_hash": "f4a907f61caeed291d4ccf147414e9c0e97aaef2acbf4a47d08961d80fb12539",
+ "evidence_status": "provisional_reference_anchor",
+ "league": "ncaambb",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 72.0,
+ "base_home_score": 75.0,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "ncaambb",
+ "margin_sd": 14.0,
+ "parent_hash": "",
+ "profile_hash": "14be1ec209dc6acf4030c480c7c2c6abf250986580e5da75595419c8fd8028df",
+ "total_score_sd": 16.5
+ }
+ ],
+ "weights": [
+ 1.0
+ ]
+ },
+ "rollback_state": {
+ "drift_score": 0.0,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "f4a907f61caeed291d4ccf147414e9c0e97aaef2acbf4a47d08961d80fb12539",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 1.0000000000000013,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.386494742786283,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 8.246116288876184,
+ "state_hash": "b00bf20e38b236488432ebaaa42691474cd68631fd141127185217573f05d4f2",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.0
+ ]
+ },
+ "state": {
+ "drift_score": 0.03266449323603947,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "3a26b1869b41e662ecdfe044a54229c6e5998280f88a6ad5003326302350654e",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 0.9801986733067586,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.031293500591644,
+ "minimum_drift_observations": 40,
+ "observations": 90,
+ "short_decay": 0.2,
+ "short_loss_ewma": 8.293631632818368,
+ "state_hash": "fbb1408030fa3f9b6207b7f4c8e4fb9180cc1f2c2cf1f265f61d489e370eb2b9",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.3836249818109066e-05,
+ 0.24749428407453483,
+ 0.1857774825592718,
+ 0.18331698809408464,
+ 0.2330792551989154,
+ 0.15031815382337527
+ ]
+ }
+ },
+ {
+ "ensemble": {
+ "ensemble_hash": "52cc748b0f03d805bc32644c746152d71b8878f6cb3e9e2e6df533e3cb3718e2",
+ "evidence_status": "provisional_reference_anchor",
+ "league": "nfl",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 21.8,
+ "base_home_score": 23.5,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "nfl",
+ "margin_sd": 14.0,
+ "parent_hash": "",
+ "profile_hash": "2cf12a1c59550d09aad4853366ee45da48461195286aba2fc665167a2d0accd0",
+ "total_score_sd": 13.7
+ }
+ ],
+ "weights": [
+ 1.0
+ ]
+ },
+ "league": "nfl",
+ "promoted": false,
+ "rollback_ensemble": {
+ "ensemble_hash": "52cc748b0f03d805bc32644c746152d71b8878f6cb3e9e2e6df533e3cb3718e2",
+ "evidence_status": "provisional_reference_anchor",
+ "league": "nfl",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 21.8,
+ "base_home_score": 23.5,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "nfl",
+ "margin_sd": 14.0,
+ "parent_hash": "",
+ "profile_hash": "2cf12a1c59550d09aad4853366ee45da48461195286aba2fc665167a2d0accd0",
+ "total_score_sd": 13.7
+ }
+ ],
+ "weights": [
+ 1.0
+ ]
+ },
+ "rollback_state": {
+ "drift_score": 0.009386081910553939,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "52cc748b0f03d805bc32644c746152d71b8878f6cb3e9e2e6df533e3cb3718e2",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 0.923116346386637,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.229562938300864,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 8.306806290127815,
+ "state_hash": "c56bdf6245fc5a57c735db00e6d448c6670f5a96632121cbfa3e9d7e30dd0e91",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.0
+ ]
+ },
+ "state": {
+ "drift_score": 0.055956431136555775,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "52cc748b0f03d805bc32644c746152d71b8878f6cb3e9e2e6df533e3cb3718e2",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 0.8693582353988077,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.225798650623538,
+ "minimum_drift_observations": 40,
+ "observations": 90,
+ "short_decay": 0.2,
+ "short_loss_ewma": 8.686084986360328,
+ "state_hash": "7833a83844625da6d292a09a0ef94572dfbd5ed027e33ab1b249eecc21f9fa97",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.0
+ ]
+ }
+ },
+ {
+ "ensemble": {
+ "ensemble_hash": "b4268f4251d62981ee852625c817f48947e9e12aecc39da1b77d4ff869c86289",
+ "evidence_status": "chronological_calibration_challenger",
+ "league": "nhl",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 2.95,
+ "base_home_score": 3.2,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "nhl",
+ "margin_sd": 2.4,
+ "parent_hash": "",
+ "profile_hash": "dd2f407da7fec8a4017fec2f6e311c3010d4f874c1d156f9dc4a4d9ba25576c3",
+ "total_score_sd": 2.3
+ },
+ {
+ "away_strength_exponent": 1.3618435036484602,
+ "base_away_score": 2.8140096579368463,
+ "base_home_score": 2.9827709409299437,
+ "evidence_status": "train_search_candidate",
+ "generation": 6,
+ "home_strength_exponent": 1.0164249111888564,
+ "league": "nhl",
+ "margin_sd": 2.4067107458645474,
+ "parent_hash": "c0f59c1041dfffbcb83db90b24931ee0acf8315cd86d375cd903b1869716224f",
+ "profile_hash": "560b8c3bf885c09aba0c04204376e3091a28ca9006785a1e982d822fd4f20158",
+ "total_score_sd": 1.9217750431804201
+ },
+ {
+ "away_strength_exponent": 1.3918430671368498,
+ "base_away_score": 2.8395546024633056,
+ "base_home_score": 3.001160815782975,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 0.9742513551643636,
+ "league": "nhl",
+ "margin_sd": 2.347437453084234,
+ "parent_hash": "7e6cc68f9f179e60b9ad230a27f90dbac843e9dfc33f83849a71a51a37077069",
+ "profile_hash": "b792aed5100d5cfef059e56fe733dc686f999130857572ef57702f98220e5374",
+ "total_score_sd": 1.9848807761955292
+ },
+ {
+ "away_strength_exponent": 1.3675649819385032,
+ "base_away_score": 2.67379397546478,
+ "base_home_score": 3.2244694632163426,
+ "evidence_status": "train_search_candidate",
+ "generation": 5,
+ "home_strength_exponent": 0.9979113276154296,
+ "league": "nhl",
+ "margin_sd": 2.315479052327515,
+ "parent_hash": "3e88d5bd7565e8748490af5a78d84b19a8534868a6331d4d1752f34943540487",
+ "profile_hash": "c0f59c1041dfffbcb83db90b24931ee0acf8315cd86d375cd903b1869716224f",
+ "total_score_sd": 1.8514937320015388
+ },
+ {
+ "away_strength_exponent": 1.365373323994108,
+ "base_away_score": 2.6479224044804157,
+ "base_home_score": 3.0420403168143237,
+ "evidence_status": "train_search_candidate",
+ "generation": 5,
+ "home_strength_exponent": 0.8190424527874777,
+ "league": "nhl",
+ "margin_sd": 2.469930832788603,
+ "parent_hash": "e20a271760ee2ecb08354c7be8fa7b0533bc22ccf66bb8691f131706d6d4193d",
+ "profile_hash": "16e8f92eddd415582a8ca2282946b318fe60e8845d896d93538b603bc8cd0555",
+ "total_score_sd": 1.754941135672797
+ },
+ {
+ "away_strength_exponent": 1.444774898245588,
+ "base_away_score": 2.8087224671677236,
+ "base_home_score": 2.900908465085074,
+ "evidence_status": "train_search_candidate",
+ "generation": 8,
+ "home_strength_exponent": 0.9764064324855087,
+ "league": "nhl",
+ "margin_sd": 2.4088026880950175,
+ "parent_hash": "560b8c3bf885c09aba0c04204376e3091a28ca9006785a1e982d822fd4f20158",
+ "profile_hash": "cbd5bb21fef457140e843a9455f9d3d073749dc621ad2bef307a40f02fe73c53",
+ "total_score_sd": 1.8330168778160287
+ }
+ ],
+ "weights": [
+ 0.16286673514032046,
+ 0.16755705994655176,
+ 0.16752559730854746,
+ 0.1673849214822694,
+ 0.16737507931387444,
+ 0.1672906068084365
+ ]
+ },
+ "league": "nhl",
+ "promoted": true,
+ "rollback_ensemble": {
+ "ensemble_hash": "382ec0d5185a96f540f91839c8bd6328d408d70a8ec1f16352aa22553c05bcfb",
+ "evidence_status": "provisional_reference_anchor",
+ "league": "nhl",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 2.95,
+ "base_home_score": 3.2,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "nhl",
+ "margin_sd": 2.4,
+ "parent_hash": "",
+ "profile_hash": "dd2f407da7fec8a4017fec2f6e311c3010d4f874c1d156f9dc4a4d9ba25576c3",
+ "total_score_sd": 2.3
+ }
+ ],
+ "weights": [
+ 1.0
+ ]
+ },
+ "rollback_state": {
+ "drift_score": 0.0,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "382ec0d5185a96f540f91839c8bd6328d408d70a8ec1f16352aa22553c05bcfb",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 0.9801986733067568,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 4.723961751695468,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 4.6298625684220225,
+ "state_hash": "7ce259e0d6f333426389c555b9f568c802b7265ae0ac4a6a55ba9f98184c8ee5",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.0
+ ]
+ },
+ "state": {
+ "drift_score": 0.0,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "b4268f4251d62981ee852625c817f48947e9e12aecc39da1b77d4ff869c86289",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 0.9801986733067561,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 4.599749180852678,
+ "minimum_drift_observations": 40,
+ "observations": 90,
+ "short_decay": 0.2,
+ "short_loss_ewma": 4.349387937549807,
+ "state_hash": "253f6e160e5566546bedc54a69316b0bed6def3e7c3d378c94dd56375d59de13",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 0.11399533888828041,
+ 0.19661716688245462,
+ 0.2167900976627797,
+ 0.18688072694737573,
+ 0.14146108610804536,
+ 0.14425558351106413
+ ]
+ }
+ },
+ {
+ "ensemble": {
+ "ensemble_hash": "369bd1fab70c4fe9c443214b61e5bb1297947388fae8402061d599b6dc5a975d",
+ "evidence_status": "chronological_calibration_challenger",
+ "league": "wnba",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 80.0,
+ "base_home_score": 82.0,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "wnba",
+ "margin_sd": 14.0,
+ "parent_hash": "",
+ "profile_hash": "a9efcb5f3219e8e9a3df4fdce3b3f767165faa82fe41cf874bdb0716548bb4d9",
+ "total_score_sd": 17.5
+ },
+ {
+ "away_strength_exponent": 1.0251595474377284,
+ "base_away_score": 72.11403431035531,
+ "base_home_score": 71.69042161368746,
+ "evidence_status": "train_search_candidate",
+ "generation": 7,
+ "home_strength_exponent": 1.0938685005129976,
+ "league": "wnba",
+ "margin_sd": 12.553668307327136,
+ "parent_hash": "468447632d3bbfb0286c4335ad436b5f32c841251c8614e5f2096d0b5dbf0a3f",
+ "profile_hash": "af6c47cb9cc880f80388c052e42e219dc4055b7d2c8b6e1346332703b49299e5",
+ "total_score_sd": 13.255930520302046
+ },
+ {
+ "away_strength_exponent": 1.0981336628870195,
+ "base_away_score": 71.11342291633342,
+ "base_home_score": 73.62693210352198,
+ "evidence_status": "train_search_candidate",
+ "generation": 7,
+ "home_strength_exponent": 1.1420227255585949,
+ "league": "wnba",
+ "margin_sd": 12.523765694931425,
+ "parent_hash": "7d2a641dbd76ac6fde3dfa526718e79569f129327958d60c3dfafc464b75af97",
+ "profile_hash": "b83f84e526bc77753ff0561968a83ca3f84f62dad23a54b08c2869b88226c810",
+ "total_score_sd": 13.124434195991878
+ },
+ {
+ "away_strength_exponent": 0.9827239039722672,
+ "base_away_score": 73.07586506043492,
+ "base_home_score": 73.49995936972549,
+ "evidence_status": "train_search_candidate",
+ "generation": 7,
+ "home_strength_exponent": 1.060463397601755,
+ "league": "wnba",
+ "margin_sd": 11.322075003472191,
+ "parent_hash": "02a8002ff7041946836ce1a1fcb8f53773f3b838801f82797911d7fbf267efec",
+ "profile_hash": "6b7ed5b7bfddee7d6ec43ca6649a0fd953a0954c5a818b269d146c55b54ea0e2",
+ "total_score_sd": 13.178399018766651
+ },
+ {
+ "away_strength_exponent": 0.9391411924229954,
+ "base_away_score": 73.82314278504273,
+ "base_home_score": 72.09561563722342,
+ "evidence_status": "train_search_candidate",
+ "generation": 6,
+ "home_strength_exponent": 1.1340765001951492,
+ "league": "wnba",
+ "margin_sd": 12.028397269421774,
+ "parent_hash": "ab7556213fe56f2a8c712da7df880059839437bfee109b7996749fcea6802355",
+ "profile_hash": "5fb5c12d474e17f2c2719e637aa37a3fb53d24a5dda665aa15e1c8ce0cc9961b",
+ "total_score_sd": 14.119914546223248
+ },
+ {
+ "away_strength_exponent": 1.0428759542867176,
+ "base_away_score": 73.34588663690329,
+ "base_home_score": 70.67653549724727,
+ "evidence_status": "train_search_candidate",
+ "generation": 6,
+ "home_strength_exponent": 1.177066395306101,
+ "league": "wnba",
+ "margin_sd": 12.30699982423615,
+ "parent_hash": "7d2a641dbd76ac6fde3dfa526718e79569f129327958d60c3dfafc464b75af97",
+ "profile_hash": "468447632d3bbfb0286c4335ad436b5f32c841251c8614e5f2096d0b5dbf0a3f",
+ "total_score_sd": 13.296762898729602
+ }
+ ],
+ "weights": [
+ 0.14546085482667262,
+ 0.1713210376892588,
+ 0.17089076167696657,
+ 0.1708509658434923,
+ 0.17074437378062704,
+ 0.17073200618298265
+ ]
+ },
+ "league": "wnba",
+ "promoted": true,
+ "rollback_ensemble": {
+ "ensemble_hash": "92022b12c8dd03d4fb005a8a84b4041b3370ee4e401e2e281230d8f6c3b3d284",
+ "evidence_status": "provisional_reference_anchor",
+ "league": "wnba",
+ "profiles": [
+ {
+ "away_strength_exponent": 1.0,
+ "base_away_score": 80.0,
+ "base_home_score": 82.0,
+ "evidence_status": "provisional_reference_anchor",
+ "generation": 0,
+ "home_strength_exponent": 1.0,
+ "league": "wnba",
+ "margin_sd": 14.0,
+ "parent_hash": "",
+ "profile_hash": "a9efcb5f3219e8e9a3df4fdce3b3f767165faa82fe41cf874bdb0716548bb4d9",
+ "total_score_sd": 17.5
+ }
+ ],
+ "weights": [
+ 1.0
+ ]
+ },
+ "rollback_state": {
+ "drift_score": 0.0,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "92022b12c8dd03d4fb005a8a84b4041b3370ee4e401e2e281230d8f6c3b3d284",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 1.06183654654536,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.828494403135926,
+ "minimum_drift_observations": 40,
+ "observations": 50,
+ "short_decay": 0.2,
+ "short_loss_ewma": 8.776294316432912,
+ "state_hash": "bb00abb17fee66e3eb9152039b5e33447479ed0e079dd11c90c8fca060eb8d21",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 1.0
+ ]
+ },
+ "state": {
+ "drift_score": 0.034010092999338264,
+ "drift_threshold": 0.12,
+ "ensemble_hash": "369bd1fab70c4fe9c443214b61e5bb1297947388fae8402061d599b6dc5a975d",
+ "interval_learning_rate": 0.04,
+ "interval_scale": 1.0408107741923893,
+ "learning_rate": 0.25,
+ "long_decay": 0.03,
+ "long_loss_ewma": 8.300244006128747,
+ "minimum_drift_observations": 40,
+ "observations": 90,
+ "short_decay": 0.2,
+ "short_loss_ewma": 8.582536076694385,
+ "state_hash": "ae0ce766963e2c17eec1ba08d7b118c8c96dcc80952634178f48041eb2454805",
+ "status": "healthy",
+ "target_coverage": 0.9,
+ "weights": [
+ 2.3626823306179495e-07,
+ 0.398845266826086,
+ 0.08337764062148095,
+ 0.15725428716220335,
+ 0.23035294396144723,
+ 0.13016962516054942
+ ]
+ }
+ }
+ ],
+ "created_at": "2036-12-11T15:00:00+00:00",
+ "protocol_version": "recursive-calibration-v1"
+}
diff --git a/scripts/audit_autonomy.py b/scripts/audit_autonomy.py
new file mode 100644
index 0000000..793d7d2
--- /dev/null
+++ b/scripts/audit_autonomy.py
@@ -0,0 +1,196 @@
+"""Audit recursive improvement on explicitly synthetic, non-certifying fixtures."""
+
+from __future__ import annotations
+
+import argparse
+import json
+from dataclasses import asdict
+from datetime import UTC, datetime, timedelta
+from pathlib import Path
+
+from universal_sports_engine.accuracy import HistoricalGame
+from universal_sports_engine.adaptive import (
+ create_profile,
+ reference_profile,
+ sample_profile_scores,
+)
+from universal_sports_engine.autotune import (
+ adapt_champion_on_shadow,
+ champion_for,
+ create_champion_bundle,
+ load_tuning_config,
+ read_champion_bundle,
+ run_recursive_improvement,
+ verify_improvement_ledger,
+ write_champion_bundle,
+ write_improvement_artifacts,
+)
+from universal_sports_engine.league_packs.registry import league_ids
+from universal_sports_engine.reference import ANCHORS
+
+
+def _arguments() -> argparse.Namespace:
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--config", required=True, type=Path)
+ parser.add_argument("--output", required=True, type=Path)
+ parser.add_argument("--artifacts", required=True, type=Path)
+ return parser.parse_args()
+
+
+def _fixtures(config_path: Path) -> tuple[HistoricalGame, ...]:
+ config = load_tuning_config(config_path)
+ games: list[HistoricalGame] = []
+ base_time = datetime(2020, 1, 1, 12, tzinfo=UTC)
+ for league_index, league in enumerate(league_ids()):
+ anchor = ANCHORS[league]
+ reference = reference_profile(league)
+ target = create_profile(
+ league,
+ anchor.mean_home_score * (0.86 + league_index * 0.01),
+ anchor.mean_away_score * (0.88 + league_index * 0.008),
+ anchor.total_score_sd * (0.72 + league_index * 0.02),
+ anchor.margin_sd * (0.76 + league_index * 0.015),
+ 1.12,
+ 0.92,
+ 1,
+ reference.profile_hash,
+ "synthetic_autonomy_audit_target",
+ )
+ shadow_games = config.minimum_drift_observations
+ count = (
+ config.minimum_train_games
+ + config.minimum_calibration_games
+ + shadow_games
+ )
+ for index in range(count):
+ if index < config.minimum_train_games:
+ split = "train"
+ elif index < config.minimum_train_games + config.minimum_calibration_games:
+ split = "calibration"
+ else:
+ split = "shadow"
+ decision = base_time + timedelta(days=league_index * 1_000 + index)
+ home_strength = 0.75 + (index % 11) * 0.05
+ away_strength = 0.78 + (index % 9) * 0.05
+ home_score, away_score = sample_profile_scores(
+ target,
+ config.seed + league_index * 100_000 + index,
+ home_strength,
+ away_strength,
+ )
+ games.append(
+ HistoricalGame(
+ f"{league}-synthetic-{index:04d}",
+ league,
+ decision,
+ decision - timedelta(hours=1),
+ decision + timedelta(hours=3),
+ home_score,
+ away_score,
+ home_strength,
+ away_strength,
+ split,
+ )
+ )
+ return tuple(games)
+
+
+def main() -> None:
+ args = _arguments()
+ config = load_tuning_config(args.config)
+ games = _fixtures(args.config)
+ first = run_recursive_improvement(games, config)
+ second = run_recursive_improvement(games, config)
+ deterministic = first == second
+ calibration_games = tuple(game for game in games if game.split == "calibration")
+ evidence_cutoff = max(game.outcome_time for game in calibration_games).isoformat()
+ bundle = create_champion_bundle(first, "recursive-calibration-v1", evidence_cutoff)
+ write_improvement_artifacts(args.artifacts, first, bundle, config)
+ reloaded = read_champion_bundle(args.artifacts / "champion_bundle.json")
+ bundle_reproduced = reloaded == bundle
+ ledger_records = verify_improvement_ledger(
+ args.artifacts / "improvement_ledger.jsonl",
+ bundle.bundle_hash,
+ )
+ adapted = bundle
+ for league in league_ids():
+ shadow = tuple(
+ game
+ for game in games
+ if game.league == league and game.split == "shadow"
+ )
+ adapted = adapt_champion_on_shadow(
+ adapted,
+ league,
+ shadow,
+ config,
+ max(game.outcome_time for game in shadow).isoformat(),
+ )
+ shadow_path = args.artifacts / "shadow_adapted_bundle.json"
+ write_champion_bundle(shadow_path, adapted)
+ shadow_reproduced = read_champion_bundle(shadow_path) == adapted
+ shadow_weight_adjustments = sum(
+ champion_for(adapted, league).state.weights
+ != champion_for(bundle, league).state.weights
+ for league in league_ids()
+ )
+ shadow_drift_alerts = sum(
+ champion_for(adapted, league).state.status == "drift_alert"
+ for league in league_ids()
+ )
+ promotions = sum(result.promoted for result in first)
+ adjusted_weights = sum(
+ result.challenger_state.weights != result.challenger_ensemble.weights
+ for result in first
+ )
+ report = {
+ "bundle_hash": bundle.bundle_hash,
+ "bundle_reproduced": bundle_reproduced,
+ "deterministic_recursive_search": deterministic,
+ "evidence_status": "synthetic_autonomy_audit_not_real_world_certification",
+ "leagues": [
+ {
+ "challenger_score": asdict(result.challenger_calibration_score),
+ "decision": result.decision,
+ "generations": len(result.generations),
+ "incumbent_score": asdict(result.incumbent_calibration_score),
+ "league": result.league,
+ "promoted": result.promoted,
+ "relative_improvement": result.relative_improvement,
+ "selected_ensemble_hash": result.selected_ensemble.ensemble_hash,
+ "selected_state_hash": result.selected_state.state_hash,
+ }
+ for result in first
+ ],
+ "promotions": promotions,
+ "shadow_bundle_hash": adapted.bundle_hash,
+ "shadow_bundle_reproduced": shadow_reproduced,
+ "shadow_drift_alerts": shadow_drift_alerts,
+ "shadow_weight_adjustments": shadow_weight_adjustments,
+ "verified_ledger_records": ledger_records,
+ "total_leagues": len(first),
+ "weight_adjustments": adjusted_weights,
+ }
+ args.output.parent.mkdir(parents=True, exist_ok=True)
+ if args.output.exists():
+ raise FileExistsError(f"Refusing to overwrite autonomy audit: {args.output}")
+ args.output.write_text(
+ json.dumps(report, allow_nan=False, indent=2, sort_keys=True) + "\n",
+ encoding="utf-8",
+ )
+ if not deterministic or not bundle_reproduced or not shadow_reproduced:
+ raise RuntimeError(
+ "Autonomy audit failed reproducibility: "
+ f"deterministic={deterministic}, bundle_reproduced={bundle_reproduced}, "
+ f"shadow_reproduced={shadow_reproduced}"
+ )
+ if promotions == 0 or adjusted_weights == 0 or shadow_weight_adjustments == 0:
+ raise RuntimeError(
+ "Autonomy audit failed learning controls: "
+ f"promotions={promotions}, weight_adjustments={adjusted_weights}, "
+ f"shadow_weight_adjustments={shadow_weight_adjustments}"
+ )
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/audit_performance.py b/scripts/audit_performance.py
new file mode 100644
index 0000000..287b580
--- /dev/null
+++ b/scripts/audit_performance.py
@@ -0,0 +1,101 @@
+"""Benchmark F0 and F1 throughput across supported worker counts."""
+
+from __future__ import annotations
+
+import argparse
+import json
+import time
+from pathlib import Path
+
+from universal_sports_engine.analytical import simulate_many_analytical
+from universal_sports_engine.league_packs.registry import league_ids
+from universal_sports_engine.simulation import simulate_many
+
+
+def _arguments() -> argparse.Namespace:
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--f1-games", required=True, type=int)
+ parser.add_argument("--f0-games", required=True, type=int)
+ parser.add_argument("--workers", required=True, type=int, nargs="+")
+ parser.add_argument("--seed", required=True, type=int)
+ parser.add_argument("--output", required=True, type=Path)
+ parser.add_argument("--minimum-f0-gps", required=True, type=float)
+ parser.add_argument("--minimum-f1-gps", required=True, type=float)
+ parser.add_argument("--minimum-speedup", required=True, type=float)
+ return parser.parse_args()
+
+
+def _f1_row(league: str, games: int, workers: int, seed: int) -> dict[str, object]:
+ started = time.perf_counter()
+ results = simulate_many(league, games, seed, workers)
+ elapsed = time.perf_counter() - started
+ return {
+ "fidelity": "F1_EVENT",
+ "league": league,
+ "games": games,
+ "workers": workers,
+ "elapsed_seconds": elapsed,
+ "games_per_second": games / elapsed,
+ "events": sum(len(result.events) for result in results),
+ }
+
+
+def _f0_row(league: str, games: int, seed: int) -> dict[str, object]:
+ started = time.perf_counter()
+ results = simulate_many_analytical(league, games, seed, 1.0, 1.0)
+ elapsed = time.perf_counter() - started
+ return {
+ "fidelity": "F0_ANALYTICAL",
+ "league": league,
+ "games": games,
+ "workers": 1,
+ "elapsed_seconds": elapsed,
+ "games_per_second": games / elapsed,
+ "events": 0,
+ "results": len(results),
+ }
+
+
+def _numeric(row: dict[str, object], key: str) -> float:
+ value = row[key]
+ if not isinstance(value, int | float):
+ raise TypeError(f"Expected numeric benchmark field: key={key}, value={value!r}")
+ return float(value)
+
+
+def main() -> None:
+ args = _arguments()
+ if args.f1_games <= 0 or args.f0_games <= 0 or any(worker <= 0 for worker in args.workers):
+ raise ValueError("game and worker counts must be positive")
+ rows: list[dict[str, object]] = []
+ for index, league in enumerate(league_ids()):
+ league_seed = args.seed + index * 1_000_000
+ rows.append(_f0_row(league, args.f0_games, league_seed))
+ rows.extend(
+ _f1_row(league, args.f1_games, workers, league_seed)
+ for workers in args.workers
+ )
+ args.output.parent.mkdir(parents=True, exist_ok=True)
+ args.output.write_text(json.dumps(rows, indent=2, sort_keys=True) + "\n", encoding="utf-8")
+ failures: list[str] = []
+ for league in league_ids():
+ league_rows = tuple(row for row in rows if row["league"] == league)
+ analytical = next(row for row in league_rows if row["fidelity"] == "F0_ANALYTICAL")
+ event_rows = tuple(row for row in league_rows if row["fidelity"] == "F1_EVENT")
+ single = next((row for row in event_rows if row["workers"] == 1), None)
+ if single is None:
+ raise ValueError("Performance gate requires a one-worker benchmark")
+ best = max(event_rows, key=lambda row: _numeric(row, "games_per_second"))
+ if _numeric(analytical, "games_per_second") < args.minimum_f0_gps:
+ failures.append(f"{league}.f0_throughput")
+ if _numeric(single, "games_per_second") < args.minimum_f1_gps:
+ failures.append(f"{league}.f1_throughput")
+ speedup = _numeric(best, "games_per_second") / _numeric(single, "games_per_second")
+ if speedup < args.minimum_speedup:
+ failures.append(f"{league}.parallel_speedup")
+ if failures:
+ raise RuntimeError(f"Performance gates failed: {failures!r}")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/audit_stress.py b/scripts/audit_stress.py
new file mode 100644
index 0000000..b11a933
--- /dev/null
+++ b/scripts/audit_stress.py
@@ -0,0 +1,57 @@
+"""Run deterministic randomized scenario and integrity stress checks."""
+
+from __future__ import annotations
+
+import argparse
+import json
+import time
+from pathlib import Path
+
+from universal_sports_engine.core.result_integrity import verify_result
+from universal_sports_engine.core.rng import unit
+from universal_sports_engine.league_packs.registry import league_ids
+from universal_sports_engine.simulation import simulate_scenario
+
+
+def _arguments() -> argparse.Namespace:
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--games-per-league", required=True, type=int)
+ parser.add_argument("--seed", required=True, type=int)
+ parser.add_argument("--output", required=True, type=Path)
+ return parser.parse_args()
+
+
+def main() -> None:
+ args = _arguments()
+ if args.games_per_league <= 0:
+ raise ValueError(f"games-per-league must be positive: {args.games_per_league}")
+ rows: list[dict[str, object]] = []
+ for league_index, league in enumerate(league_ids()):
+ started = time.perf_counter()
+ event_count = 0
+ maximum_events = 0
+ for game_index in range(args.games_per_league):
+ game_seed = args.seed + league_index * 1_000_000 + game_index
+ home_strength = 0.5 + unit(game_seed, league, "stress", "home")
+ away_strength = 0.5 + unit(game_seed, league, "stress", "away")
+ result = simulate_scenario(league, game_seed, home_strength, away_strength)
+ verify_result(result)
+ event_count += len(result.events)
+ maximum_events = max(maximum_events, len(result.events))
+ elapsed = time.perf_counter() - started
+ rows.append(
+ {
+ "league": league,
+ "games": args.games_per_league,
+ "events": event_count,
+ "maximum_events_per_game": maximum_events,
+ "failures": 0,
+ "elapsed_seconds": elapsed,
+ }
+ )
+ args.output.parent.mkdir(parents=True, exist_ok=True)
+ args.output.write_text(json.dumps(rows, indent=2, sort_keys=True) + "\n", encoding="utf-8")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/build_release_evidence.py b/scripts/build_release_evidence.py
new file mode 100644
index 0000000..7ef69a1
--- /dev/null
+++ b/scripts/build_release_evidence.py
@@ -0,0 +1,224 @@
+"""Generate the auditable release evidence bundle."""
+
+from __future__ import annotations
+
+import argparse
+import hashlib
+import json
+import time
+from dataclasses import asdict
+from pathlib import Path
+
+from universal_sports_engine import __version__
+from universal_sports_engine.analytical import simulate_many_analytical
+from universal_sports_engine.league_packs.registry import league_ids
+from universal_sports_engine.simulation import simulate_many
+from universal_sports_engine.validation import run_negative_controls, validate_all
+
+
+def _arguments() -> argparse.Namespace:
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--games", required=True, type=int)
+ parser.add_argument("--benchmark-games", required=True, type=int)
+ parser.add_argument("--seed", required=True, type=int)
+ parser.add_argument("--workers", required=True, type=int)
+ parser.add_argument("--output", required=True, type=Path)
+ return parser.parse_args()
+
+
+def _write_json(path: Path, value: object) -> None:
+ path.write_text(json.dumps(value, indent=2, sort_keys=True) + "\n", encoding="utf-8")
+
+
+def _source_manifest(root: Path) -> tuple[tuple[str, str], ...]:
+ allowed_roots = (
+ root / "src",
+ root / "tests",
+ root / "scripts",
+ root / "data",
+ root / "dummy_bridge",
+ )
+ files = tuple(
+ sorted(
+ path
+ for allowed_root in allowed_roots
+ for path in allowed_root.rglob("*")
+ if path.is_file()
+ and "__pycache__" not in path.parts
+ and not any(part.endswith(".egg-info") for part in path.parts)
+ )
+ )
+ documents = tuple(
+ sorted(
+ path
+ for path in root.iterdir()
+ if path.is_file()
+ and (
+ path.name in {".gitattributes", ".gitignore", "LICENSE"}
+ or path.suffix in {".json", ".md", ".toml", ".yaml"}
+ )
+ )
+ )
+ return tuple(
+ (
+ path.relative_to(root).as_posix(),
+ hashlib.sha256(path.read_bytes()).hexdigest(),
+ )
+ for path in (*files, *documents)
+ )
+
+
+def _benchmark(games: int, seed: int, workers: int) -> tuple[dict[str, object], ...]:
+ rows: list[dict[str, object]] = []
+ for index, league in enumerate(league_ids()):
+ analytical_games = max(10_000, games * 100)
+ analytical_started = time.perf_counter()
+ analytical_results = simulate_many_analytical(
+ league,
+ analytical_games,
+ seed + index * 100_000,
+ 1.0,
+ 1.0,
+ )
+ analytical_elapsed = time.perf_counter() - analytical_started
+ rows.append(
+ {
+ "fidelity": "F0_ANALYTICAL",
+ "league": league,
+ "games": analytical_games,
+ "workers": 1,
+ "elapsed_seconds": analytical_elapsed,
+ "games_per_second": analytical_games / analytical_elapsed,
+ "events": 0,
+ "results": len(analytical_results),
+ }
+ )
+ started = time.perf_counter()
+ results = simulate_many(league, games, seed + index * 100_000, workers)
+ elapsed = time.perf_counter() - started
+ rows.append(
+ {
+ "fidelity": "F1_EVENT",
+ "league": league,
+ "games": games,
+ "workers": workers,
+ "elapsed_seconds": elapsed,
+ "games_per_second": games / elapsed,
+ "events": sum(len(result.events) for result in results),
+ }
+ )
+ return tuple(rows)
+
+
+def _markdown(
+ validations: tuple[dict[str, object], ...],
+ controls: tuple[dict[str, object], ...],
+ benchmarks: tuple[dict[str, object], ...],
+ manifest_hash: str,
+) -> str:
+ validation_lines = "\n".join(
+ f"| {row['league']} | {row['games']} | {row['observed_home_mean']:.3f} | "
+ f"{row['observed_away_mean']:.3f} | {row['maximum_relative_error']:.3f} | "
+ f"{row['total_sd_relative_error']:.3f} | {row['home_advantage_z_score']:.2f} | "
+ f"{row['status']} |"
+ for row in validations
+ )
+ benchmark_lines = "\n".join(
+ f"| {row['fidelity']} | {row['league']} | {row['games']} | {row['events']} | "
+ f"{row['elapsed_seconds']:.3f} | {row['games_per_second']:.2f} |"
+ for row in benchmarks
+ )
+ control_failures = sum(not bool(row["passed"]) for row in controls)
+ return f"""# Release Evidence
+
+## Determination
+
+**PROVISIONAL MULTI-LEAGUE F0/F1 ENGINE COMPLETE.**
+
+This bundle verifies mechanics, determinism, replay integrity, league coverage,
+reference-anchor sanity, headless execution, and the content-addressed autonomy
+surface. It does not certify real-world predictive accuracy. No licensed point-in-time
+event or tracking dataset was available.
+
+## Reference-anchor validation
+
+| League | Games | Home mean | Away mean | Mean error | Total SD error | Home z | Status |
+|---|---:|---:|---:|---:|---:|---:|---|
+{validation_lines}
+
+## Negative controls
+
+- Controls executed: {len(controls)}
+- Failures: {control_failures}
+
+## Headless benchmark
+
+| Fidelity | League | Games | Events | Seconds | Games/second |
+|---|---|---:|---:|---:|---:|
+{benchmark_lines}
+
+## Reproducibility
+
+- Source manifest SHA-256: `{manifest_hash}`
+- Every event stream is invariant-checked and SHA-256 chained during construction.
+- External replay imports reverify both the event chain and complete result envelope.
+- Same input and seed equality is exercised for every league.
+- Cross-worker batch equality is exercised by the integration suite.
+- Recursive profiles, ensembles, adaptive states, champion bundles, and promotion
+ ledgers have independent content hashes.
+- Autonomous search cannot mutate rules, evaluators, split boundaries, or source code.
+
+## Certification boundary
+
+`provisional_reference_anchor` is the strongest supported status. F2 spatial
+calibration, F3 physics/rendering, player/team models, exhaustive rulebooks, and
+held-out predictive validity remain blocked pending licensed data and scoped evidence.
+"""
+
+
+def main() -> None:
+ args = _arguments()
+ if args.games <= 0 or args.benchmark_games <= 0 or args.workers <= 0:
+ raise ValueError("games, benchmark-games, and workers must be positive")
+ root = Path(__file__).resolve().parents[1]
+ output = args.output.resolve()
+ output.mkdir(parents=True, exist_ok=True)
+ validation_objects = validate_all(args.games, args.seed, args.workers)
+ validations = tuple(asdict(report) for report in validation_objects)
+ controls = tuple(
+ {"control": name, "passed": passed, "description": description}
+ for name, passed, description in run_negative_controls(args.seed)
+ )
+ benchmarks = _benchmark(args.benchmark_games, args.seed, args.workers)
+ source_manifest = _source_manifest(root)
+ manifest_json = json.dumps(source_manifest, sort_keys=True, separators=(",", ":"))
+ manifest_hash = hashlib.sha256(manifest_json.encode()).hexdigest()
+ release_manifest = {
+ "engine_version": __version__,
+ "evidence_status": "provisional_reference_anchor",
+ "league_ids": league_ids(),
+ "source_manifest_sha256": manifest_hash,
+ "source_files": source_manifest,
+ }
+ _write_json(output / "VALIDATION_REPORT.json", validations)
+ _write_json(output / "NEGATIVE_CONTROL_REPORT.json", controls)
+ _write_json(output / "PERFORMANCE_BENCHMARK.json", benchmarks)
+ _write_json(output / "RELEASE_MANIFEST.json", release_manifest)
+ (output / "RELEASE_EVIDENCE.md").write_text(
+ _markdown(validations, controls, benchmarks, manifest_hash),
+ encoding="utf-8",
+ )
+ validation_failures = tuple(
+ row for row in validations if row["status"] != "provisional_reference_anchor"
+ )
+ control_failures = tuple(row for row in controls if not row["passed"])
+ if validation_failures or control_failures:
+ raise RuntimeError(
+ "Release evidence gates failed: "
+ f"validation_failures={len(validation_failures)}, "
+ f"control_failures={len(control_failures)}"
+ )
+
+
+if __name__ == "__main__":
+ main()
diff --git a/src/universal_sports_engine/__init__.py b/src/universal_sports_engine/__init__.py
new file mode 100644
index 0000000..e1c433a
--- /dev/null
+++ b/src/universal_sports_engine/__init__.py
@@ -0,0 +1,29 @@
+"""Universal Sports Engine public API."""
+
+from universal_sports_engine.analytical import (
+ AdaptiveAnalyticalResult,
+ AnalyticalResult,
+ simulate_analytical,
+ simulate_ensemble_analytical,
+ simulate_many_analytical,
+ simulate_profile_analytical,
+)
+from universal_sports_engine.simulation import (
+ counterfactual_game,
+ simulate_game,
+ simulate_many,
+)
+
+__version__ = "0.3.0"
+
+__all__ = [
+ "AdaptiveAnalyticalResult",
+ "AnalyticalResult",
+ "counterfactual_game",
+ "simulate_analytical",
+ "simulate_ensemble_analytical",
+ "simulate_game",
+ "simulate_many",
+ "simulate_many_analytical",
+ "simulate_profile_analytical",
+]
diff --git a/src/universal_sports_engine/accuracy.py b/src/universal_sports_engine/accuracy.py
new file mode 100644
index 0000000..26f4dfc
--- /dev/null
+++ b/src/universal_sports_engine/accuracy.py
@@ -0,0 +1,283 @@
+"""Point-in-time historical evaluation with proper distributional scores."""
+
+from __future__ import annotations
+
+import csv
+import statistics
+from dataclasses import dataclass
+from datetime import datetime
+from itertools import combinations
+from pathlib import Path
+
+from universal_sports_engine.analytical import simulate_many_analytical
+from universal_sports_engine.league_packs.registry import league_ids
+
+
+@dataclass(frozen=True, slots=True)
+class HistoricalGame:
+ game_id: str
+ league: str
+ decision_time: datetime
+ features_available_at: datetime
+ outcome_time: datetime
+ home_score: int
+ away_score: int
+ home_strength: float
+ away_strength: float
+ split: str
+
+
+@dataclass(frozen=True, slots=True)
+class GameForecast:
+ game_id: str
+ league: str
+ home_samples: tuple[int, ...]
+ away_samples: tuple[int, ...]
+
+
+@dataclass(frozen=True, slots=True)
+class AccuracyReport:
+ league: str
+ games: int
+ samples_per_game: int
+ home_score_mae: float
+ away_score_mae: float
+ total_score_mae: float
+ home_win_brier: float
+ home_score_crps: float
+ away_score_crps: float
+ score_interval_50_coverage: float
+ score_interval_90_coverage: float
+ evidence_status: str
+
+
+def _timestamp(value: str, field: str, game_id: str) -> datetime:
+ try:
+ parsed = datetime.fromisoformat(value)
+ except ValueError as error:
+ raise ValueError(
+ f"Invalid ISO-8601 {field} for game {game_id!r}: {value!r}"
+ ) from error
+ if parsed.utcoffset() is None:
+ raise ValueError(f"Timestamp must include an offset: game={game_id!r}, field={field}")
+ return parsed
+
+
+def load_historical_games(path: Path) -> tuple[HistoricalGame, ...]:
+ """Load a strict point-in-time game manifest from CSV."""
+
+ required = {
+ "game_id",
+ "league",
+ "decision_time",
+ "features_available_at",
+ "outcome_time",
+ "home_score",
+ "away_score",
+ "home_strength",
+ "away_strength",
+ "split",
+ }
+ with path.open("r", encoding="utf-8", newline="") as source:
+ reader = csv.DictReader(source)
+ missing = required.difference(reader.fieldnames or ())
+ if missing:
+ raise ValueError(f"Historical CSV is missing columns: {sorted(missing)!r}")
+ games = tuple(
+ HistoricalGame(
+ game_id=row["game_id"],
+ league=row["league"].strip().lower(),
+ decision_time=_timestamp(row["decision_time"], "decision_time", row["game_id"]),
+ features_available_at=_timestamp(
+ row["features_available_at"],
+ "features_available_at",
+ row["game_id"],
+ ),
+ outcome_time=_timestamp(row["outcome_time"], "outcome_time", row["game_id"]),
+ home_score=int(row["home_score"]),
+ away_score=int(row["away_score"]),
+ home_strength=float(row["home_strength"]),
+ away_strength=float(row["away_strength"]),
+ split=row["split"].strip().lower(),
+ )
+ for row in reader
+ )
+ validate_historical_games(games)
+ validate_chronological_splits(games)
+ return games
+
+
+def validate_historical_games(games: tuple[HistoricalGame, ...]) -> None:
+ """Reject leakage, duplicates, invalid outcomes, and ambiguous evaluation splits."""
+
+ if not games:
+ raise ValueError("Historical evaluation requires at least one game")
+ identifiers = tuple(game.game_id for game in games)
+ if len(set(identifiers)) != len(identifiers):
+ raise ValueError("Historical game IDs must be unique")
+ supported = set(league_ids())
+ for game in games:
+ if game.league not in supported:
+ raise ValueError(f"Unsupported historical league: {game.league!r}")
+ if game.features_available_at > game.decision_time:
+ raise ValueError(f"Feature leakage detected for game: {game.game_id}")
+ if game.decision_time >= game.outcome_time:
+ raise ValueError(f"Outcome must occur after decision time: {game.game_id}")
+ if min(game.home_score, game.away_score) < 0:
+ raise ValueError(f"Historical scores must be non-negative: {game.game_id}")
+ if game.split not in {"train", "calibration", "test", "shadow"}:
+ raise ValueError(f"Invalid chronological split for game: {game.game_id}")
+
+
+def validate_chronological_splits(games: tuple[HistoricalGame, ...]) -> None:
+ """Ensure earlier split outcomes precede later split decisions for each league."""
+
+ split_order = ("train", "calibration", "test", "shadow")
+ for league in {game.league for game in games}:
+ league_games = tuple(game for game in games if game.league == league)
+ for earlier, later in combinations(split_order, 2):
+ earlier_games = tuple(game for game in league_games if game.split == earlier)
+ later_games = tuple(game for game in league_games if game.split == later)
+ if not earlier_games or not later_games:
+ continue
+ latest_outcome = max(game.outcome_time for game in earlier_games)
+ earliest_decision = min(game.decision_time for game in later_games)
+ if latest_outcome > earliest_decision:
+ raise ValueError(
+ "Chronological split overlap detected: "
+ f"league={league}, earlier={earlier}, later={later}"
+ )
+
+
+def forecast_historical_games(
+ games: tuple[HistoricalGame, ...],
+ samples_per_game: int,
+ seed: int,
+) -> tuple[GameForecast, ...]:
+ """Generate frozen F0 forecasts for a validated historical manifest."""
+
+ validate_historical_games(games)
+ if samples_per_game <= 0:
+ raise ValueError(f"samples_per_game must be positive: {samples_per_game}")
+ forecasts: list[GameForecast] = []
+ for index, game in enumerate(games):
+ samples = simulate_many_analytical(
+ game.league,
+ samples_per_game,
+ seed + index * 1_000_000,
+ game.home_strength,
+ game.away_strength,
+ )
+ forecasts.append(
+ GameForecast(
+ game.game_id,
+ game.league,
+ tuple(sample.home_score for sample in samples),
+ tuple(sample.away_score for sample in samples),
+ )
+ )
+ return tuple(forecasts)
+
+
+def _crps(samples: tuple[int, ...], outcome: int) -> float:
+ ordered = tuple(sorted(samples))
+ count = len(ordered)
+ first_term = statistics.fmean(abs(sample - outcome) for sample in ordered)
+ pair_term = sum((2 * index - count + 1) * sample for index, sample in enumerate(ordered))
+ return first_term - pair_term / count**2
+
+
+def _quantile(samples: tuple[int, ...], probability: float) -> int:
+ ordered = tuple(sorted(samples))
+ index = min(len(ordered) - 1, max(0, round(probability * (len(ordered) - 1))))
+ return ordered[index]
+
+
+def _covered(samples: tuple[int, ...], outcome: int, interval: float) -> bool:
+ tail = (1.0 - interval) / 2.0
+ return _quantile(samples, tail) <= outcome <= _quantile(samples, 1.0 - tail)
+
+
+def evaluate_forecasts(
+ games: tuple[HistoricalGame, ...],
+ forecasts: tuple[GameForecast, ...],
+) -> AccuracyReport:
+ """Evaluate score distributions and outcome probabilities on frozen games."""
+
+ validate_historical_games(games)
+ if any(game.split != "test" for game in games):
+ raise ValueError("Accuracy reporting accepts only the frozen test split")
+ forecast_by_id = {forecast.game_id: forecast for forecast in forecasts}
+ if len(forecast_by_id) != len(forecasts) or set(forecast_by_id) != {
+ game.game_id for game in games
+ }:
+ raise ValueError("Forecast IDs must exactly match historical game IDs")
+ sample_counts = {len(forecast.home_samples) for forecast in forecasts}
+ if len(sample_counts) != 1 or 0 in sample_counts:
+ raise ValueError("Every forecast must contain the same positive sample count")
+ league_set = {game.league for game in games}
+ league = league_set.pop() if len(league_set) == 1 else "multi_league"
+ home_errors: list[float] = []
+ away_errors: list[float] = []
+ total_errors: list[float] = []
+ brier_scores: list[float] = []
+ home_crps: list[float] = []
+ away_crps: list[float] = []
+ coverage_50: list[bool] = []
+ coverage_90: list[bool] = []
+ for game in games:
+ forecast = forecast_by_id[game.game_id]
+ if forecast.league != game.league or len(forecast.home_samples) != len(
+ forecast.away_samples
+ ):
+ raise ValueError(f"Malformed forecast for game: {game.game_id}")
+ predicted_home = statistics.fmean(forecast.home_samples)
+ predicted_away = statistics.fmean(forecast.away_samples)
+ home_errors.append(abs(predicted_home - game.home_score))
+ away_errors.append(abs(predicted_away - game.away_score))
+ total_errors.append(
+ abs(predicted_home + predicted_away - game.home_score - game.away_score)
+ )
+ home_win_probability = statistics.fmean(
+ float(home > away)
+ for home, away in zip(
+ forecast.home_samples,
+ forecast.away_samples,
+ strict=True,
+ )
+ )
+ if game.home_score > game.away_score:
+ target = 1.0
+ elif game.home_score < game.away_score:
+ target = 0.0
+ else:
+ target = 0.5
+ brier_scores.append((home_win_probability - target) ** 2)
+ home_crps.append(_crps(forecast.home_samples, game.home_score))
+ away_crps.append(_crps(forecast.away_samples, game.away_score))
+ coverage_50.extend(
+ (
+ _covered(forecast.home_samples, game.home_score, 0.50),
+ _covered(forecast.away_samples, game.away_score, 0.50),
+ )
+ )
+ coverage_90.extend(
+ (
+ _covered(forecast.home_samples, game.home_score, 0.90),
+ _covered(forecast.away_samples, game.away_score, 0.90),
+ )
+ )
+ return AccuracyReport(
+ league,
+ len(games),
+ sample_counts.pop(),
+ statistics.fmean(home_errors),
+ statistics.fmean(away_errors),
+ statistics.fmean(total_errors),
+ statistics.fmean(brier_scores),
+ statistics.fmean(home_crps),
+ statistics.fmean(away_crps),
+ statistics.fmean(coverage_50),
+ statistics.fmean(coverage_90),
+ "historical_test_evaluation_not_certification",
+ )
diff --git a/src/universal_sports_engine/adaptive.py b/src/universal_sports_engine/adaptive.py
new file mode 100644
index 0000000..07fc07f
--- /dev/null
+++ b/src/universal_sports_engine/adaptive.py
@@ -0,0 +1,927 @@
+"""Immutable adaptive analytical profiles, ensembles, and online calibration state."""
+
+from __future__ import annotations
+
+import hashlib
+import json
+import math
+from dataclasses import dataclass
+
+from universal_sports_engine.core.rng import choice, normal
+from universal_sports_engine.core.types import UnknownLeagueError
+from universal_sports_engine.reference import ANCHORS
+
+
+@dataclass(frozen=True, slots=True)
+class AnalyticalProfile:
+ """One bounded, content-addressed analytical score model."""
+
+ league: str
+ base_home_score: float
+ base_away_score: float
+ total_score_sd: float
+ margin_sd: float
+ home_strength_exponent: float
+ away_strength_exponent: float
+ generation: int
+ parent_hash: str
+ evidence_status: str
+ profile_hash: str
+
+
+@dataclass(frozen=True, slots=True)
+class ModelEnsemble:
+ """A content-addressed mixture of independently scored profiles."""
+
+ league: str
+ profiles: tuple[AnalyticalProfile, ...]
+ weights: tuple[float, ...]
+ evidence_status: str
+ ensemble_hash: str
+
+
+@dataclass(frozen=True, slots=True)
+class ForecastMoments:
+ """Distribution moments used for scoring and calibrated intervals."""
+
+ home_mean: float
+ away_mean: float
+ total_mean: float
+ margin_mean: float
+ total_sd: float
+ margin_sd: float
+ home_win_probability: float
+
+
+@dataclass(frozen=True, slots=True)
+class ObservationLoss:
+ """Proper and diagnostic scores for one resolved game."""
+
+ joint_negative_log_likelihood: float
+ home_win_brier: float
+ total_covered: bool
+ margin_covered: bool
+ composite_loss: float
+
+
+@dataclass(frozen=True, slots=True)
+class ScoreInput:
+ """One immutable outcome supplied to a batch scoring boundary."""
+
+ home_strength: float
+ away_strength: float
+ home_score: int
+ away_score: int
+
+
+@dataclass(frozen=True, slots=True)
+class AdaptiveState:
+ """Online expert weights, interval calibration, and drift state."""
+
+ ensemble_hash: str
+ weights: tuple[float, ...]
+ learning_rate: float
+ interval_scale: float
+ interval_learning_rate: float
+ target_coverage: float
+ short_loss_ewma: float
+ long_loss_ewma: float
+ short_decay: float
+ long_decay: float
+ drift_threshold: float
+ minimum_drift_observations: int
+ observations: int
+ drift_score: float
+ status: str
+ state_hash: str
+
+
+def _canonical_hash(value: object, personalization: bytes) -> str:
+ encoded = json.dumps(
+ value,
+ allow_nan=False,
+ separators=(",", ":"),
+ sort_keys=True,
+ ).encode()
+ return hashlib.blake2b(encoded, digest_size=32, person=personalization).hexdigest()
+
+
+def _profile_content(
+ league: str,
+ base_home_score: float,
+ base_away_score: float,
+ total_score_sd: float,
+ margin_sd: float,
+ home_strength_exponent: float,
+ away_strength_exponent: float,
+ generation: int,
+ parent_hash: str,
+ evidence_status: str,
+) -> dict[str, str | int | float]:
+ return {
+ "away_strength_exponent": away_strength_exponent,
+ "base_away_score": base_away_score,
+ "base_home_score": base_home_score,
+ "evidence_status": evidence_status,
+ "generation": generation,
+ "home_strength_exponent": home_strength_exponent,
+ "league": league,
+ "margin_sd": margin_sd,
+ "parent_hash": parent_hash,
+ "total_score_sd": total_score_sd,
+ }
+
+
+def create_profile(
+ league: str,
+ base_home_score: float,
+ base_away_score: float,
+ total_score_sd: float,
+ margin_sd: float,
+ home_strength_exponent: float,
+ away_strength_exponent: float,
+ generation: int,
+ parent_hash: str,
+ evidence_status: str,
+) -> AnalyticalProfile:
+ """Validate and content-address a candidate profile."""
+
+ normalized = league.strip().lower()
+ if normalized not in ANCHORS:
+ raise UnknownLeagueError(f"No analytical model for league: {league!r}")
+ values = (
+ base_home_score,
+ base_away_score,
+ total_score_sd,
+ margin_sd,
+ home_strength_exponent,
+ away_strength_exponent,
+ )
+ if any(not math.isfinite(value) for value in values):
+ raise ValueError(f"Profile parameters must be finite: league={normalized!r}")
+ anchor = ANCHORS[normalized]
+ bounds = (
+ (base_home_score, anchor.mean_home_score * 0.40, anchor.mean_home_score * 1.60),
+ (base_away_score, anchor.mean_away_score * 0.40, anchor.mean_away_score * 1.60),
+ (total_score_sd, anchor.total_score_sd * 0.35, anchor.total_score_sd * 2.50),
+ (margin_sd, anchor.margin_sd * 0.35, anchor.margin_sd * 2.50),
+ (home_strength_exponent, 0.25, 2.00),
+ (away_strength_exponent, 0.25, 2.00),
+ )
+ for value, minimum, maximum in bounds:
+ if not minimum <= value <= maximum:
+ raise ValueError(
+ "Profile parameter is outside its fail-closed bound: "
+ f"league={normalized!r}, value={value}, bounds=[{minimum}, {maximum}]"
+ )
+ if generation < 0:
+ raise ValueError(f"generation must be non-negative: {generation}")
+ if generation == 0 and parent_hash:
+ raise ValueError("Generation-zero profiles must not declare a parent hash")
+ if generation > 0 and (
+ len(parent_hash) != 64
+ or any(character not in "0123456789abcdef" for character in parent_hash)
+ ):
+ raise ValueError(
+ "Non-root profiles require a lowercase 64-character parent hash: "
+ f"generation={generation}, parent_hash={parent_hash!r}"
+ )
+ if not evidence_status:
+ raise ValueError("evidence_status must be non-empty")
+ content = _profile_content(
+ normalized,
+ base_home_score,
+ base_away_score,
+ total_score_sd,
+ margin_sd,
+ home_strength_exponent,
+ away_strength_exponent,
+ generation,
+ parent_hash,
+ evidence_status,
+ )
+ profile_hash = _canonical_hash(content, b"USE-PROFILE-V1")
+ return AnalyticalProfile(
+ normalized,
+ base_home_score,
+ base_away_score,
+ total_score_sd,
+ margin_sd,
+ home_strength_exponent,
+ away_strength_exponent,
+ generation,
+ parent_hash,
+ evidence_status,
+ profile_hash,
+ )
+
+
+def reference_profile(league: str) -> AnalyticalProfile:
+ """Return the immutable built-in reference profile for one league."""
+
+ normalized = league.strip().lower()
+ anchor = ANCHORS.get(normalized)
+ if anchor is None:
+ raise UnknownLeagueError(f"No analytical model for league: {league!r}")
+ return create_profile(
+ normalized,
+ anchor.mean_home_score,
+ anchor.mean_away_score,
+ anchor.total_score_sd,
+ anchor.margin_sd,
+ 1.0,
+ 1.0,
+ 0,
+ "",
+ anchor.evidence_status,
+ )
+
+
+def verify_profile(profile: AnalyticalProfile) -> None:
+ """Reject mutated, malformed, or unsupported profile objects."""
+
+ rebuilt = create_profile(
+ profile.league,
+ profile.base_home_score,
+ profile.base_away_score,
+ profile.total_score_sd,
+ profile.margin_sd,
+ profile.home_strength_exponent,
+ profile.away_strength_exponent,
+ profile.generation,
+ profile.parent_hash,
+ profile.evidence_status,
+ )
+ if rebuilt.profile_hash != profile.profile_hash:
+ raise ValueError(
+ "Profile content hash mismatch: "
+ f"expected={rebuilt.profile_hash}, actual={profile.profile_hash}"
+ )
+
+
+def profile_moments(
+ profile: AnalyticalProfile,
+ home_strength: float,
+ away_strength: float,
+) -> ForecastMoments:
+ """Calculate analytical moments without sampling."""
+
+ verify_profile(profile)
+ return _profile_moments_unchecked(profile, home_strength, away_strength)
+
+
+def create_ensemble(
+ league: str,
+ profiles: tuple[AnalyticalProfile, ...],
+ weights: tuple[float, ...],
+ evidence_status: str,
+) -> ModelEnsemble:
+ """Create a normalized immutable ensemble with no hidden experts."""
+
+ normalized = league.strip().lower()
+ if not evidence_status:
+ raise ValueError("Ensemble evidence_status must be non-empty")
+ if not profiles or len(profiles) != len(weights):
+ raise ValueError("Ensemble profiles and weights must have the same positive length")
+ if len({profile.profile_hash for profile in profiles}) != len(profiles):
+ raise ValueError("Ensemble profile hashes must be unique")
+ for profile in profiles:
+ verify_profile(profile)
+ if profile.league != normalized:
+ raise ValueError(
+ f"Ensemble league mismatch: ensemble={normalized!r}, profile={profile.league!r}"
+ )
+ normalized_weights = _normalize_weights(weights, len(profiles))
+ content = {
+ "evidence_status": evidence_status,
+ "league": normalized,
+ "profiles": [profile.profile_hash for profile in profiles],
+ "weights": list(normalized_weights),
+ }
+ ensemble_hash = _canonical_hash(content, b"USE-ENSEMBLE1")
+ return ModelEnsemble(
+ normalized,
+ profiles,
+ normalized_weights,
+ evidence_status,
+ ensemble_hash,
+ )
+
+
+def verify_ensemble(ensemble: ModelEnsemble) -> None:
+ """Verify every expert and the complete ensemble envelope."""
+
+ rebuilt = create_ensemble(
+ ensemble.league,
+ ensemble.profiles,
+ ensemble.weights,
+ ensemble.evidence_status,
+ )
+ if rebuilt.ensemble_hash != ensemble.ensemble_hash:
+ raise ValueError(
+ "Ensemble content hash mismatch: "
+ f"expected={rebuilt.ensemble_hash}, actual={ensemble.ensemble_hash}"
+ )
+
+
+def ensemble_moments(
+ ensemble: ModelEnsemble,
+ weights: tuple[float, ...],
+ home_strength: float,
+ away_strength: float,
+) -> ForecastMoments:
+ """Combine expert distributions with full between-expert variance."""
+
+ verify_ensemble(ensemble)
+ normalized_weights = _normalize_weights(weights, len(ensemble.profiles))
+ return _ensemble_moments_unchecked(
+ ensemble,
+ normalized_weights,
+ home_strength,
+ away_strength,
+ )
+
+
+def _ensemble_moments_unchecked(
+ ensemble: ModelEnsemble,
+ normalized_weights: tuple[float, ...],
+ home_strength: float,
+ away_strength: float,
+) -> ForecastMoments:
+ moments = tuple(
+ _profile_moments_unchecked(profile, home_strength, away_strength)
+ for profile in ensemble.profiles
+ )
+ total_mean = math.fsum(
+ weight * item.total_mean for weight, item in zip(normalized_weights, moments, strict=True)
+ )
+ margin_mean = math.fsum(
+ weight * item.margin_mean
+ for weight, item in zip(normalized_weights, moments, strict=True)
+ )
+ total_variance = math.fsum(
+ weight * (item.total_sd**2 + (item.total_mean - total_mean) ** 2)
+ for weight, item in zip(normalized_weights, moments, strict=True)
+ )
+ margin_variance = math.fsum(
+ weight * (item.margin_sd**2 + (item.margin_mean - margin_mean) ** 2)
+ for weight, item in zip(normalized_weights, moments, strict=True)
+ )
+ home_win_probability = math.fsum(
+ weight * item.home_win_probability
+ for weight, item in zip(normalized_weights, moments, strict=True)
+ )
+ return ForecastMoments(
+ (total_mean + margin_mean) / 2.0,
+ (total_mean - margin_mean) / 2.0,
+ total_mean,
+ margin_mean,
+ math.sqrt(total_variance),
+ math.sqrt(margin_variance),
+ home_win_probability,
+ )
+
+
+def score_observation(
+ ensemble: ModelEnsemble,
+ weights: tuple[float, ...],
+ home_strength: float,
+ away_strength: float,
+ home_score: int,
+ away_score: int,
+ interval_scale: float,
+ brier_weight: float,
+) -> ObservationLoss:
+ """Score one outcome under the exact Gaussian mixture."""
+
+ verify_ensemble(ensemble)
+ normalized_weights = _normalize_weights(weights, len(ensemble.profiles))
+ return _score_observation_unchecked(
+ ensemble,
+ normalized_weights,
+ home_strength,
+ away_strength,
+ home_score,
+ away_score,
+ interval_scale,
+ brier_weight,
+ )
+
+
+def score_observations(
+ ensemble: ModelEnsemble,
+ weights: tuple[float, ...],
+ inputs: tuple[ScoreInput, ...],
+ interval_scale: float,
+ brier_weight: float,
+) -> tuple[ObservationLoss, ...]:
+ """Score a batch after verifying model integrity exactly once."""
+
+ verify_ensemble(ensemble)
+ normalized_weights = _normalize_weights(weights, len(ensemble.profiles))
+ return tuple(
+ _score_observation_unchecked(
+ ensemble,
+ normalized_weights,
+ item.home_strength,
+ item.away_strength,
+ item.home_score,
+ item.away_score,
+ interval_scale,
+ brier_weight,
+ )
+ for item in inputs
+ )
+
+
+def _score_observation_unchecked(
+ ensemble: ModelEnsemble,
+ normalized_weights: tuple[float, ...],
+ home_strength: float,
+ away_strength: float,
+ home_score: int,
+ away_score: int,
+ interval_scale: float,
+ brier_weight: float,
+) -> ObservationLoss:
+ if min(home_score, away_score) < 0:
+ raise ValueError(f"Scores must be non-negative: home={home_score}, away={away_score}")
+ if not math.isfinite(interval_scale) or interval_scale <= 0.0:
+ raise ValueError(f"interval_scale must be finite and positive: {interval_scale}")
+ if not math.isfinite(brier_weight) or brier_weight < 0.0:
+ raise ValueError(f"brier_weight must be finite and non-negative: {brier_weight}")
+ total = home_score + away_score
+ margin = home_score - away_score
+ log_components: list[float] = []
+ expert_moments: list[ForecastMoments] = []
+ for weight, profile in zip(normalized_weights, ensemble.profiles, strict=True):
+ moments = _profile_moments_unchecked(profile, home_strength, away_strength)
+ expert_moments.append(moments)
+ if weight > 0.0:
+ log_components.append(
+ math.log(weight)
+ + _normal_log_density(total, moments.total_mean, moments.total_sd)
+ + _normal_log_density(margin, moments.margin_mean, moments.margin_sd)
+ )
+ joint_nll = -_log_sum_exp(tuple(log_components))
+ win_probability = math.fsum(
+ weight * moments.home_win_probability
+ for weight, moments in zip(normalized_weights, expert_moments, strict=True)
+ )
+ target = 1.0 if margin > 0 else 0.0 if margin < 0 else 0.5
+ brier = (win_probability - target) ** 2
+ combined = _ensemble_moments_unchecked(
+ ensemble,
+ normalized_weights,
+ home_strength,
+ away_strength,
+ )
+ z_value = 1.6448536269514722 * interval_scale
+ total_covered = abs(total - combined.total_mean) <= z_value * combined.total_sd
+ margin_covered = abs(margin - combined.margin_mean) <= z_value * combined.margin_sd
+ return ObservationLoss(
+ joint_nll,
+ brier,
+ total_covered,
+ margin_covered,
+ joint_nll + brier_weight * brier,
+ )
+
+
+def expert_losses(
+ ensemble: ModelEnsemble,
+ home_strength: float,
+ away_strength: float,
+ home_score: int,
+ away_score: int,
+ brier_weight: float,
+) -> tuple[float, ...]:
+ """Score each expert independently for online multiplicative weighting."""
+
+ verify_ensemble(ensemble)
+ return _expert_losses_unchecked(
+ ensemble,
+ home_strength,
+ away_strength,
+ home_score,
+ away_score,
+ brier_weight,
+ )
+
+
+def create_adaptive_state(
+ ensemble: ModelEnsemble,
+ learning_rate: float,
+ interval_learning_rate: float,
+ target_coverage: float,
+ short_decay: float,
+ long_decay: float,
+ drift_threshold: float,
+ minimum_drift_observations: int,
+) -> AdaptiveState:
+ """Initialize a bounded adaptive state from a verified champion."""
+
+ verify_ensemble(ensemble)
+ if not 0.0 < learning_rate <= 2.0:
+ raise ValueError(f"learning_rate must be within (0, 2]: {learning_rate}")
+ if not 0.0 < interval_learning_rate <= 0.25:
+ raise ValueError(
+ "interval_learning_rate must be within (0, 0.25]: "
+ f"{interval_learning_rate}"
+ )
+ if not 0.5 <= target_coverage < 1.0:
+ raise ValueError(f"target_coverage must be within [0.5, 1): {target_coverage}")
+ if not 0.0 < long_decay < short_decay < 1.0:
+ raise ValueError(
+ "EWMA decays must satisfy 0 < long_decay < short_decay < 1: "
+ f"long={long_decay}, short={short_decay}"
+ )
+ if drift_threshold <= 0.0 or not math.isfinite(drift_threshold):
+ raise ValueError(f"drift_threshold must be finite and positive: {drift_threshold}")
+ if minimum_drift_observations <= 0:
+ raise ValueError(
+ f"minimum_drift_observations must be positive: {minimum_drift_observations}"
+ )
+ return _state(
+ ensemble.ensemble_hash,
+ ensemble.weights,
+ learning_rate,
+ 1.0,
+ interval_learning_rate,
+ target_coverage,
+ 0.0,
+ 0.0,
+ short_decay,
+ long_decay,
+ drift_threshold,
+ minimum_drift_observations,
+ 0,
+ 0.0,
+ "healthy",
+ )
+
+
+def update_adaptive_state(
+ state: AdaptiveState,
+ ensemble: ModelEnsemble,
+ home_strength: float,
+ away_strength: float,
+ home_score: int,
+ away_score: int,
+ brier_weight: float,
+) -> tuple[AdaptiveState, ObservationLoss]:
+ """Update weights, coverage, and drift after one chronologically revealed outcome."""
+
+ verify_adaptive_state(state, ensemble)
+ normalized_weights = _normalize_weights(state.weights, len(ensemble.profiles))
+ observation = _score_observation_unchecked(
+ ensemble,
+ normalized_weights,
+ home_strength,
+ away_strength,
+ home_score,
+ away_score,
+ state.interval_scale,
+ brier_weight,
+ )
+ losses = _expert_losses_unchecked(
+ ensemble,
+ home_strength,
+ away_strength,
+ home_score,
+ away_score,
+ brier_weight,
+ )
+ best_loss = min(losses)
+ raw_weights = tuple(
+ weight * math.exp(-state.learning_rate * min(50.0, loss - best_loss))
+ for weight, loss in zip(state.weights, losses, strict=True)
+ )
+ new_weights = _normalize_weights(raw_weights, len(raw_weights))
+ miss_rate = 1.0 - (float(observation.total_covered) + float(observation.margin_covered)) / 2.0
+ target_miss_rate = 1.0 - state.target_coverage
+ interval_scale = min(
+ 4.0,
+ max(
+ 0.25,
+ state.interval_scale
+ * math.exp(state.interval_learning_rate * (miss_rate - target_miss_rate)),
+ ),
+ )
+ observations = state.observations + 1
+ short_loss = (
+ observation.composite_loss
+ if state.observations == 0
+ else state.short_decay * observation.composite_loss
+ + (1.0 - state.short_decay) * state.short_loss_ewma
+ )
+ long_loss = (
+ observation.composite_loss
+ if state.observations == 0
+ else state.long_decay * observation.composite_loss
+ + (1.0 - state.long_decay) * state.long_loss_ewma
+ )
+ drift_score = max(0.0, short_loss - long_loss) / max(1.0, abs(long_loss))
+ status = (
+ "drift_alert"
+ if observations >= state.minimum_drift_observations
+ and drift_score > state.drift_threshold
+ else "healthy"
+ )
+ return (
+ _state(
+ state.ensemble_hash,
+ new_weights,
+ state.learning_rate,
+ interval_scale,
+ state.interval_learning_rate,
+ state.target_coverage,
+ short_loss,
+ long_loss,
+ state.short_decay,
+ state.long_decay,
+ state.drift_threshold,
+ state.minimum_drift_observations,
+ observations,
+ drift_score,
+ status,
+ ),
+ observation,
+ )
+
+
+def verify_adaptive_state(state: AdaptiveState, ensemble: ModelEnsemble) -> None:
+ """Verify state lineage and its content-addressed envelope."""
+
+ verify_ensemble(ensemble)
+ if state.ensemble_hash != ensemble.ensemble_hash:
+ raise ValueError(
+ "Adaptive state belongs to a different ensemble: "
+ f"state={state.ensemble_hash}, ensemble={ensemble.ensemble_hash}"
+ )
+ rebuilt = _state(
+ state.ensemble_hash,
+ state.weights,
+ state.learning_rate,
+ state.interval_scale,
+ state.interval_learning_rate,
+ state.target_coverage,
+ state.short_loss_ewma,
+ state.long_loss_ewma,
+ state.short_decay,
+ state.long_decay,
+ state.drift_threshold,
+ state.minimum_drift_observations,
+ state.observations,
+ state.drift_score,
+ state.status,
+ )
+ if rebuilt.state_hash != state.state_hash:
+ raise ValueError(
+ "Adaptive state content hash mismatch: "
+ f"expected={rebuilt.state_hash}, actual={state.state_hash}"
+ )
+
+
+def sample_profile_scores(
+ profile: AnalyticalProfile,
+ seed: int,
+ home_strength: float,
+ away_strength: float,
+) -> tuple[int, int]:
+ """Sample a score pair from one verified profile."""
+
+ if seed < 0:
+ raise ValueError(f"seed must be non-negative: {seed}")
+ moments = profile_moments(profile, home_strength, away_strength)
+ total = normal(
+ seed,
+ moments.total_mean,
+ moments.total_sd,
+ profile.league,
+ profile.profile_hash,
+ "adaptive_total",
+ )
+ margin = normal(
+ seed,
+ moments.margin_mean,
+ moments.margin_sd,
+ profile.league,
+ profile.profile_hash,
+ "adaptive_margin",
+ )
+ return (
+ _legalize_score(profile.league, (total + margin) / 2.0),
+ _legalize_score(profile.league, (total - margin) / 2.0),
+ )
+
+
+def sample_ensemble_scores(
+ ensemble: ModelEnsemble,
+ weights: tuple[float, ...],
+ seed: int,
+ home_strength: float,
+ away_strength: float,
+) -> tuple[int, int, str]:
+ """Sample a mixture expert deterministically, then sample its score distribution."""
+
+ verify_ensemble(ensemble)
+ normalized_weights = _normalize_weights(weights, len(ensemble.profiles))
+ index = choice(seed, normalized_weights, ensemble.league, ensemble.ensemble_hash, "expert")
+ profile = ensemble.profiles[index]
+ home_score, away_score = sample_profile_scores(
+ profile,
+ seed,
+ home_strength,
+ away_strength,
+ )
+ return home_score, away_score, profile.profile_hash
+
+
+def _state(
+ ensemble_hash: str,
+ weights: tuple[float, ...],
+ learning_rate: float,
+ interval_scale: float,
+ interval_learning_rate: float,
+ target_coverage: float,
+ short_loss_ewma: float,
+ long_loss_ewma: float,
+ short_decay: float,
+ long_decay: float,
+ drift_threshold: float,
+ minimum_drift_observations: int,
+ observations: int,
+ drift_score: float,
+ status: str,
+) -> AdaptiveState:
+ numeric = (
+ learning_rate,
+ interval_scale,
+ interval_learning_rate,
+ target_coverage,
+ short_loss_ewma,
+ long_loss_ewma,
+ short_decay,
+ long_decay,
+ drift_threshold,
+ drift_score,
+ )
+ if any(not math.isfinite(value) for value in numeric):
+ raise ValueError("Adaptive state numeric fields must be finite")
+ if not 0.0 < learning_rate <= 2.0:
+ raise ValueError(f"Adaptive learning_rate is invalid: {learning_rate}")
+ if not 0.25 <= interval_scale <= 4.0:
+ raise ValueError(f"Adaptive interval_scale is invalid: {interval_scale}")
+ if not 0.0 < interval_learning_rate <= 0.25:
+ raise ValueError(
+ f"Adaptive interval_learning_rate is invalid: {interval_learning_rate}"
+ )
+ if not 0.5 <= target_coverage < 1.0:
+ raise ValueError(f"Adaptive target_coverage is invalid: {target_coverage}")
+ if not 0.0 < long_decay < short_decay < 1.0:
+ raise ValueError(
+ "Adaptive EWMA decays are invalid: "
+ f"long_decay={long_decay}, short_decay={short_decay}"
+ )
+ if drift_threshold <= 0.0 or drift_score < 0.0:
+ raise ValueError(
+ "Adaptive drift values are invalid: "
+ f"threshold={drift_threshold}, score={drift_score}"
+ )
+ if minimum_drift_observations <= 0 or observations < 0:
+ raise ValueError(
+ "Adaptive observation counts are invalid: "
+ f"minimum={minimum_drift_observations}, observations={observations}"
+ )
+ if status not in {"healthy", "drift_alert"}:
+ raise ValueError(f"Adaptive status is invalid: {status!r}")
+ normalized_weights = _normalize_weights(weights, len(weights))
+ content: dict[str, object] = {
+ "drift_score": drift_score,
+ "drift_threshold": drift_threshold,
+ "ensemble_hash": ensemble_hash,
+ "interval_learning_rate": interval_learning_rate,
+ "interval_scale": interval_scale,
+ "learning_rate": learning_rate,
+ "long_decay": long_decay,
+ "long_loss_ewma": long_loss_ewma,
+ "minimum_drift_observations": minimum_drift_observations,
+ "observations": observations,
+ "short_decay": short_decay,
+ "short_loss_ewma": short_loss_ewma,
+ "status": status,
+ "target_coverage": target_coverage,
+ "weights": list(normalized_weights),
+ }
+ state_hash = _canonical_hash(content, b"USE-ADAPT-V1")
+ return AdaptiveState(
+ ensemble_hash,
+ normalized_weights,
+ learning_rate,
+ interval_scale,
+ interval_learning_rate,
+ target_coverage,
+ short_loss_ewma,
+ long_loss_ewma,
+ short_decay,
+ long_decay,
+ drift_threshold,
+ minimum_drift_observations,
+ observations,
+ drift_score,
+ status,
+ state_hash,
+ )
+
+
+def _profile_moments_unchecked(
+ profile: AnalyticalProfile,
+ home_strength: float,
+ away_strength: float,
+) -> ForecastMoments:
+ if not 0.25 <= home_strength <= 2.0 or not 0.25 <= away_strength <= 2.0:
+ raise ValueError(
+ "Strength multipliers must be within [0.25, 2.0]: "
+ f"home={home_strength}, away={away_strength}"
+ )
+ home_mean = profile.base_home_score * home_strength**profile.home_strength_exponent
+ away_mean = profile.base_away_score * away_strength**profile.away_strength_exponent
+ margin_mean = home_mean - away_mean
+ home_win_probability = _normal_cdf(margin_mean / profile.margin_sd)
+ return ForecastMoments(
+ home_mean,
+ away_mean,
+ home_mean + away_mean,
+ margin_mean,
+ profile.total_score_sd,
+ profile.margin_sd,
+ home_win_probability,
+ )
+
+
+def _expert_losses_unchecked(
+ ensemble: ModelEnsemble,
+ home_strength: float,
+ away_strength: float,
+ home_score: int,
+ away_score: int,
+ brier_weight: float,
+) -> tuple[float, ...]:
+ total = home_score + away_score
+ margin = home_score - away_score
+ target = 1.0 if margin > 0 else 0.0 if margin < 0 else 0.5
+ losses = []
+ for profile in ensemble.profiles:
+ moments = _profile_moments_unchecked(profile, home_strength, away_strength)
+ joint_nll = -(
+ _normal_log_density(total, moments.total_mean, moments.total_sd)
+ + _normal_log_density(margin, moments.margin_mean, moments.margin_sd)
+ )
+ brier = (moments.home_win_probability - target) ** 2
+ losses.append(joint_nll + brier_weight * brier)
+ return tuple(losses)
+
+
+def _normalize_weights(weights: tuple[float, ...], expected: int) -> tuple[float, ...]:
+ if len(weights) != expected or expected <= 0:
+ raise ValueError(
+ f"Weight count mismatch: expected={expected}, actual={len(weights)}"
+ )
+ if any(not math.isfinite(weight) or weight < 0.0 for weight in weights):
+ raise ValueError(f"Weights must be finite and non-negative: {weights!r}")
+ total = math.fsum(weights)
+ if total <= 0.0:
+ raise ValueError("At least one weight must be positive")
+ if abs(total - 1.0) <= 1e-12:
+ return weights
+ return tuple(weight / total for weight in weights)
+
+
+def _normal_log_density(value: float, mean: float, standard_deviation: float) -> float:
+ if standard_deviation <= 0.0:
+ raise ValueError(f"standard_deviation must be positive: {standard_deviation}")
+ standardized = (value - mean) / standard_deviation
+ return (
+ -0.5 * standardized**2
+ - math.log(standard_deviation)
+ - 0.5 * math.log(2.0 * math.pi)
+ )
+
+
+def _normal_cdf(value: float) -> float:
+ return 0.5 * (1.0 + math.erf(value / math.sqrt(2.0)))
+
+
+def _log_sum_exp(values: tuple[float, ...]) -> float:
+ if not values:
+ raise ValueError("log-sum-exp requires at least one value")
+ maximum = max(values)
+ return maximum + math.log(math.fsum(math.exp(value - maximum) for value in values))
+
+
+def _legalize_score(league: str, value: float) -> int:
+ score = max(0, round(value))
+ if league in {"nfl", "ncaaf"} and score == 1:
+ return 2
+ return score
diff --git a/src/universal_sports_engine/analytical.py b/src/universal_sports_engine/analytical.py
new file mode 100644
index 0000000..658f6f7
--- /dev/null
+++ b/src/universal_sports_engine/analytical.py
@@ -0,0 +1,212 @@
+"""High-throughput F0 score-distribution simulator."""
+
+from __future__ import annotations
+
+from dataclasses import dataclass
+
+from universal_sports_engine.adaptive import (
+ AdaptiveState,
+ AnalyticalProfile,
+ ModelEnsemble,
+ sample_ensemble_scores,
+ sample_profile_scores,
+ verify_adaptive_state,
+ verify_ensemble,
+ verify_profile,
+)
+from universal_sports_engine.core.rng import normal
+from universal_sports_engine.core.types import UnknownLeagueError
+from universal_sports_engine.reference import ANCHORS, ReferenceAnchor
+
+
+@dataclass(frozen=True, slots=True)
+class AnalyticalResult:
+ league: str
+ home_score: int
+ away_score: int
+ seed: int
+ fidelity: str
+ evidence_status: str
+
+
+@dataclass(frozen=True, slots=True)
+class AdaptiveAnalyticalResult:
+ """F0 result with complete adaptive-model lineage."""
+
+ league: str
+ home_score: int
+ away_score: int
+ seed: int
+ fidelity: str
+ evidence_status: str
+ ensemble_hash: str
+ selected_profile_hash: str
+ adaptive_state_hash: str
+
+
+def _legalize_score(league: str, value: float) -> int:
+ score = max(0, round(value))
+ if league in {"nfl", "ncaaf"} and score == 1:
+ return 2
+ return score
+
+
+def simulate_analytical(
+ league: str,
+ seed: int,
+ home_strength: float,
+ away_strength: float,
+) -> AnalyticalResult:
+ """Sample a fast aggregate score pair from explicit provisional moments."""
+
+ normalized = league.strip().lower()
+ anchor = ANCHORS.get(normalized)
+ if anchor is None:
+ raise UnknownLeagueError(f"No analytical model for league: {league!r}")
+ if seed < 0:
+ raise ValueError(f"seed must be non-negative: {seed}")
+ if not 0.25 <= home_strength <= 2.0 or not 0.25 <= away_strength <= 2.0:
+ raise ValueError(
+ "Strength multipliers must be within [0.25, 2.0]: "
+ f"home={home_strength}, away={away_strength}"
+ )
+ return _simulate_analytical_validated(
+ normalized,
+ anchor,
+ seed,
+ home_strength,
+ away_strength,
+ )
+
+
+def _simulate_analytical_validated(
+ league: str,
+ anchor: ReferenceAnchor,
+ seed: int,
+ home_strength: float,
+ away_strength: float,
+) -> AnalyticalResult:
+ home_mean = anchor.mean_home_score * home_strength
+ away_mean = anchor.mean_away_score * away_strength
+ total = normal(
+ seed,
+ home_mean + away_mean,
+ anchor.total_score_sd,
+ league,
+ "analytical_total",
+ )
+ margin = normal(
+ seed,
+ home_mean - away_mean,
+ anchor.margin_sd,
+ league,
+ "analytical_margin",
+ )
+ home_score = _legalize_score(league, (total + margin) / 2.0)
+ away_score = _legalize_score(league, (total - margin) / 2.0)
+ return AnalyticalResult(
+ league,
+ home_score,
+ away_score,
+ seed,
+ "F0_ANALYTICAL",
+ anchor.evidence_status,
+ )
+
+
+def simulate_many_analytical(
+ league: str,
+ games: int,
+ seed: int,
+ home_strength: float,
+ away_strength: float,
+) -> tuple[AnalyticalResult, ...]:
+ """Run aggregate simulations without F1 event construction overhead."""
+
+ if games <= 0:
+ raise ValueError(f"games must be positive: {games}")
+ normalized = league.strip().lower()
+ anchor = ANCHORS.get(normalized)
+ if anchor is None:
+ raise UnknownLeagueError(f"No analytical model for league: {league!r}")
+ if seed < 0:
+ raise ValueError(f"seed must be non-negative: {seed}")
+ if not 0.25 <= home_strength <= 2.0 or not 0.25 <= away_strength <= 2.0:
+ raise ValueError(
+ "Strength multipliers must be within [0.25, 2.0]: "
+ f"home={home_strength}, away={away_strength}"
+ )
+ return tuple(
+ _simulate_analytical_validated(
+ normalized,
+ anchor,
+ seed + index,
+ home_strength,
+ away_strength,
+ )
+ for index in range(games)
+ )
+
+
+def simulate_profile_analytical(
+ profile: AnalyticalProfile,
+ seed: int,
+ home_strength: float,
+ away_strength: float,
+) -> AdaptiveAnalyticalResult:
+ """Sample an explicitly versioned analytical profile."""
+
+ verify_profile(profile)
+ home_score, away_score = sample_profile_scores(
+ profile,
+ seed,
+ home_strength,
+ away_strength,
+ )
+ return AdaptiveAnalyticalResult(
+ profile.league,
+ home_score,
+ away_score,
+ seed,
+ "F0_ADAPTIVE_PROFILE",
+ profile.evidence_status,
+ profile.profile_hash,
+ profile.profile_hash,
+ "",
+ )
+
+
+def simulate_ensemble_analytical(
+ ensemble: ModelEnsemble,
+ state: AdaptiveState,
+ seed: int,
+ home_strength: float,
+ away_strength: float,
+) -> AdaptiveAnalyticalResult:
+ """Sample a governed ensemble using its current adaptive weights."""
+
+ verify_ensemble(ensemble)
+ verify_adaptive_state(state, ensemble)
+ if state.status != "healthy":
+ raise RuntimeError(
+ "Adaptive simulation is fail-closed while drift is unresolved: "
+ f"status={state.status}, drift_score={state.drift_score}"
+ )
+ home_score, away_score, profile_hash = sample_ensemble_scores(
+ ensemble,
+ state.weights,
+ seed,
+ home_strength,
+ away_strength,
+ )
+ return AdaptiveAnalyticalResult(
+ ensemble.league,
+ home_score,
+ away_score,
+ seed,
+ "F0_ADAPTIVE_ENSEMBLE",
+ ensemble.evidence_status,
+ ensemble.ensemble_hash,
+ profile_hash,
+ state.state_hash,
+ )
diff --git a/src/universal_sports_engine/autotune.py b/src/universal_sports_engine/autotune.py
new file mode 100644
index 0000000..44ae19b
--- /dev/null
+++ b/src/universal_sports_engine/autotune.py
@@ -0,0 +1,1036 @@
+"""Deterministic recursive model search and fail-closed champion governance."""
+
+from __future__ import annotations
+
+import hashlib
+import json
+import math
+import os
+import statistics
+from dataclasses import asdict, dataclass
+from datetime import datetime
+from pathlib import Path
+from typing import cast
+
+from universal_sports_engine.accuracy import HistoricalGame, validate_historical_games
+from universal_sports_engine.adaptive import (
+ AdaptiveState,
+ AnalyticalProfile,
+ ModelEnsemble,
+ ObservationLoss,
+ ScoreInput,
+ create_adaptive_state,
+ create_ensemble,
+ create_profile,
+ reference_profile,
+ score_observations,
+ update_adaptive_state,
+ verify_adaptive_state,
+ verify_ensemble,
+)
+from universal_sports_engine.core.rng import normal
+from universal_sports_engine.reference import ANCHORS
+
+type JsonValue = None | bool | int | float | str | list[JsonValue] | dict[str, JsonValue]
+
+
+@dataclass(frozen=True, slots=True)
+class TuningConfig:
+ """Every autonomous search and promotion limit, declared before outcomes."""
+
+ generations: int
+ population_size: int
+ elite_count: int
+ experts_per_ensemble: int
+ mutation_scale: float
+ minimum_train_games: int
+ minimum_calibration_games: int
+ minimum_relative_improvement: float
+ maximum_brier_deterioration: float
+ maximum_coverage_error_deterioration: float
+ brier_weight: float
+ coverage_weight: float
+ online_learning_rate: float
+ interval_learning_rate: float
+ target_coverage: float
+ short_decay: float
+ long_decay: float
+ drift_threshold: float
+ minimum_drift_observations: int
+ seed: int
+
+
+@dataclass(frozen=True, slots=True)
+class AggregateScore:
+ """Chronological aggregate of proper scores and coverage diagnostics."""
+
+ games: int
+ mean_joint_negative_log_likelihood: float
+ home_win_brier: float
+ interval_coverage: float
+ interval_coverage_error: float
+ composite_loss: float
+
+
+@dataclass(frozen=True, slots=True)
+class GenerationReport:
+ """Best immutable candidate from one evolutionary generation."""
+
+ generation: int
+ candidates_evaluated: int
+ best_profile_hash: str
+ best_train_score: AggregateScore
+
+
+@dataclass(frozen=True, slots=True)
+class ImprovementResult:
+ """Complete evidence for one league's champion/challenger decision."""
+
+ league: str
+ promoted: bool
+ decision: str
+ relative_improvement: float
+ incumbent_ensemble: ModelEnsemble
+ incumbent_state: AdaptiveState
+ challenger_ensemble: ModelEnsemble
+ challenger_state: AdaptiveState
+ selected_ensemble: ModelEnsemble
+ selected_state: AdaptiveState
+ incumbent_calibration_score: AggregateScore
+ challenger_calibration_score: AggregateScore
+ generations: tuple[GenerationReport, ...]
+
+
+@dataclass(frozen=True, slots=True)
+class LeagueChampion:
+ """One selected league model plus its rollback lineage."""
+
+ league: str
+ ensemble: ModelEnsemble
+ state: AdaptiveState
+ promoted: bool
+ rollback_ensemble: ModelEnsemble
+ rollback_state: AdaptiveState
+
+
+@dataclass(frozen=True, slots=True)
+class ChampionBundle:
+ """Content-addressed, multi-league model checkpoint."""
+
+ protocol_version: str
+ created_at: str
+ champions: tuple[LeagueChampion, ...]
+ bundle_hash: str
+
+
+def validate_tuning_config(config: TuningConfig) -> None:
+ """Fail before search when a budget or promotion gate is unsafe."""
+
+ positive_integers = (
+ config.generations,
+ config.population_size,
+ config.elite_count,
+ config.experts_per_ensemble,
+ config.minimum_train_games,
+ config.minimum_calibration_games,
+ config.minimum_drift_observations,
+ )
+ if any(value <= 0 for value in positive_integers):
+ raise ValueError(f"Tuning integer limits must be positive: {positive_integers!r}")
+ if config.elite_count > config.population_size:
+ raise ValueError("elite_count cannot exceed population_size")
+ if config.experts_per_ensemble > config.population_size + 1:
+ raise ValueError("experts_per_ensemble exceeds the available candidate pool")
+ bounded = (
+ ("mutation_scale", config.mutation_scale, 0.001, 0.50),
+ (
+ "minimum_relative_improvement",
+ config.minimum_relative_improvement,
+ 0.0,
+ 0.50,
+ ),
+ (
+ "maximum_brier_deterioration",
+ config.maximum_brier_deterioration,
+ 0.0,
+ 0.25,
+ ),
+ (
+ "maximum_coverage_error_deterioration",
+ config.maximum_coverage_error_deterioration,
+ 0.0,
+ 0.25,
+ ),
+ ("brier_weight", config.brier_weight, 0.0, 20.0),
+ ("coverage_weight", config.coverage_weight, 0.0, 20.0),
+ )
+ for name, value, minimum, maximum in bounded:
+ if not math.isfinite(value) or not minimum <= value <= maximum:
+ raise ValueError(f"{name} must be within [{minimum}, {maximum}]: {value}")
+ if config.seed < 0:
+ raise ValueError(f"seed must be non-negative: {config.seed}")
+ create_adaptive_state(
+ create_ensemble("nba", (reference_profile("nba"),), (1.0,), "config_validation"),
+ config.online_learning_rate,
+ config.interval_learning_rate,
+ config.target_coverage,
+ config.short_decay,
+ config.long_decay,
+ config.drift_threshold,
+ config.minimum_drift_observations,
+ )
+
+
+def load_tuning_config(path: Path) -> TuningConfig:
+ """Load an exact, reviewable tuning contract without implicit defaults."""
+
+ raw = cast(object, json.loads(path.read_text(encoding="utf-8")))
+ if not isinstance(raw, dict) or any(not isinstance(key, str) for key in raw):
+ raise ValueError(f"Tuning config must be a JSON object: {path}")
+ value = cast(dict[str, object], raw)
+ expected = {
+ "brier_weight",
+ "coverage_weight",
+ "drift_threshold",
+ "elite_count",
+ "experts_per_ensemble",
+ "generations",
+ "interval_learning_rate",
+ "long_decay",
+ "maximum_brier_deterioration",
+ "maximum_coverage_error_deterioration",
+ "minimum_calibration_games",
+ "minimum_drift_observations",
+ "minimum_relative_improvement",
+ "minimum_train_games",
+ "mutation_scale",
+ "online_learning_rate",
+ "population_size",
+ "seed",
+ "short_decay",
+ "target_coverage",
+ }
+ actual = set(value)
+ if actual != expected:
+ raise ValueError(
+ f"Tuning config fields mismatch: missing={sorted(expected - actual)!r}, "
+ f"unexpected={sorted(actual - expected)!r}"
+ )
+ config = TuningConfig(
+ _required_int(value, "generations"),
+ _required_int(value, "population_size"),
+ _required_int(value, "elite_count"),
+ _required_int(value, "experts_per_ensemble"),
+ _required_float(value, "mutation_scale"),
+ _required_int(value, "minimum_train_games"),
+ _required_int(value, "minimum_calibration_games"),
+ _required_float(value, "minimum_relative_improvement"),
+ _required_float(value, "maximum_brier_deterioration"),
+ _required_float(value, "maximum_coverage_error_deterioration"),
+ _required_float(value, "brier_weight"),
+ _required_float(value, "coverage_weight"),
+ _required_float(value, "online_learning_rate"),
+ _required_float(value, "interval_learning_rate"),
+ _required_float(value, "target_coverage"),
+ _required_float(value, "short_decay"),
+ _required_float(value, "long_decay"),
+ _required_float(value, "drift_threshold"),
+ _required_int(value, "minimum_drift_observations"),
+ _required_int(value, "seed"),
+ )
+ validate_tuning_config(config)
+ return config
+
+
+def tune_league(
+ league: str,
+ games: tuple[HistoricalGame, ...],
+ config: TuningConfig,
+) -> ImprovementResult:
+ """Recursively search train data and promote only on chronological calibration data."""
+
+ validate_tuning_config(config)
+ validate_historical_games(games)
+ normalized = league.strip().lower()
+ league_games = tuple(
+ sorted(
+ (game for game in games if game.league == normalized),
+ key=lambda game: game.decision_time,
+ )
+ )
+ training = tuple(game for game in league_games if game.split == "train")
+ calibration = tuple(game for game in league_games if game.split == "calibration")
+ if len(training) < config.minimum_train_games:
+ raise ValueError(
+ "Insufficient chronological training evidence: "
+ f"league={normalized}, required={config.minimum_train_games}, actual={len(training)}"
+ )
+ if len(calibration) < config.minimum_calibration_games:
+ raise ValueError(
+ "Insufficient chronological calibration evidence: "
+ f"league={normalized}, required={config.minimum_calibration_games}, "
+ f"actual={len(calibration)}"
+ )
+ incumbent_profile = reference_profile(normalized)
+ incumbent = create_ensemble(
+ normalized,
+ (incumbent_profile,),
+ (1.0,),
+ incumbent_profile.evidence_status,
+ )
+ incumbent_score, incumbent_state = evaluate_prequential(incumbent, calibration, config)
+ elites: tuple[AnalyticalProfile, ...] = (incumbent_profile,)
+ all_candidates: dict[str, AnalyticalProfile] = {
+ incumbent_profile.profile_hash: incumbent_profile
+ }
+ reports: list[GenerationReport] = []
+ ranked: tuple[tuple[AggregateScore, AnalyticalProfile], ...] = ()
+ for generation in range(1, config.generations + 1):
+ population: dict[str, AnalyticalProfile] = {
+ profile.profile_hash: profile for profile in elites
+ }
+ candidate_index = 0
+ while len(population) < config.population_size:
+ parent = elites[candidate_index % len(elites)]
+ candidate = mutate_profile(parent, generation, candidate_index, config)
+ population[candidate.profile_hash] = candidate
+ all_candidates[candidate.profile_hash] = candidate
+ candidate_index += 1
+ if candidate_index > config.population_size * 100:
+ raise RuntimeError(
+ "Candidate generation could not produce a unique bounded population: "
+ f"league={normalized}, generation={generation}"
+ )
+ ranked = tuple(
+ sorted(
+ [
+ (score_profile(profile, training, config), profile)
+ for profile in population.values()
+ ],
+ key=lambda row: (row[0].composite_loss, row[1].profile_hash),
+ )
+ )
+ score_rows = tuple((score.composite_loss, profile, score) for score, profile in ranked)
+ elites = tuple(row[1] for row in score_rows[: config.elite_count])
+ best = score_rows[0]
+ reports.append(
+ GenerationReport(generation, len(population), best[1].profile_hash, best[2])
+ )
+ if not ranked:
+ raise RuntimeError("Recursive tuning produced no evaluated candidates")
+ globally_ranked = tuple(
+ sorted(
+ (
+ (score_profile(profile, training, config), profile.profile_hash, profile)
+ for profile in all_candidates.values()
+ ),
+ key=lambda row: (row[0].composite_loss, row[1]),
+ )
+ )
+ selected_profiles: list[AnalyticalProfile] = [incumbent_profile]
+ for _, _, profile in globally_ranked:
+ if profile.profile_hash != incumbent_profile.profile_hash:
+ selected_profiles.append(profile)
+ if len(selected_profiles) >= config.experts_per_ensemble:
+ break
+ selected_train_scores = tuple(
+ score_profile(profile, training, config).composite_loss for profile in selected_profiles
+ )
+ best_train_score = min(selected_train_scores)
+ initial_weights = tuple(
+ math.exp(
+ -config.online_learning_rate
+ * min(50.0, score - best_train_score)
+ )
+ for score in selected_train_scores
+ )
+ challenger = create_ensemble(
+ normalized,
+ tuple(selected_profiles),
+ initial_weights,
+ "chronological_calibration_challenger",
+ )
+ challenger_score, challenger_state = evaluate_prequential(challenger, calibration, config)
+ denominator = max(abs(incumbent_score.composite_loss), 1e-12)
+ relative_improvement = (
+ incumbent_score.composite_loss - challenger_score.composite_loss
+ ) / denominator
+ brier_gate = (
+ challenger_score.home_win_brier
+ <= incumbent_score.home_win_brier + config.maximum_brier_deterioration
+ )
+ coverage_gate = (
+ challenger_score.interval_coverage_error
+ <= incumbent_score.interval_coverage_error
+ + config.maximum_coverage_error_deterioration
+ )
+ improvement_gate = relative_improvement >= config.minimum_relative_improvement
+ drift_gate = challenger_state.status == "healthy"
+ promoted = improvement_gate and brier_gate and coverage_gate and drift_gate
+ reasons: list[str] = []
+ if not improvement_gate:
+ reasons.append("minimum_relative_improvement_not_met")
+ if not brier_gate:
+ reasons.append("brier_guardrail_failed")
+ if not coverage_gate:
+ reasons.append("coverage_guardrail_failed")
+ if not drift_gate:
+ reasons.append("calibration_drift_detected")
+ decision = "promoted" if promoted else "retained_incumbent:" + ",".join(reasons)
+ selected_ensemble = challenger if promoted else incumbent
+ selected_state = challenger_state if promoted else incumbent_state
+ return ImprovementResult(
+ normalized,
+ promoted,
+ decision,
+ relative_improvement,
+ incumbent,
+ incumbent_state,
+ challenger,
+ challenger_state,
+ selected_ensemble,
+ selected_state,
+ incumbent_score,
+ challenger_score,
+ tuple(reports),
+ )
+
+
+def run_recursive_improvement(
+ games: tuple[HistoricalGame, ...],
+ config: TuningConfig,
+) -> tuple[ImprovementResult, ...]:
+ """Tune every league that has explicitly separated train and calibration evidence."""
+
+ validate_tuning_config(config)
+ validate_historical_games(games)
+ eligible = tuple(
+ sorted(
+ league
+ for league in {game.league for game in games}
+ if any(game.league == league and game.split == "train" for game in games)
+ and any(game.league == league and game.split == "calibration" for game in games)
+ )
+ )
+ if not eligible:
+ raise ValueError("No league has both train and calibration evidence")
+ return tuple(tune_league(league, games, config) for league in eligible)
+
+
+def mutate_profile(
+ parent: AnalyticalProfile,
+ generation: int,
+ candidate_index: int,
+ config: TuningConfig,
+) -> AnalyticalProfile:
+ """Apply deterministic bounded log-space mutations to one parent."""
+
+ if generation <= 0 or candidate_index < 0:
+ raise ValueError(
+ f"Mutation coordinates must be non-negative: generation={generation}, "
+ f"candidate_index={candidate_index}"
+ )
+ anchor = ANCHORS[parent.league]
+ scale = config.mutation_scale / math.sqrt(generation)
+
+ def mutate(value: float, minimum: float, maximum: float, field: str) -> float:
+ changed = value * math.exp(
+ normal(
+ config.seed,
+ 0.0,
+ scale,
+ parent.league,
+ generation,
+ candidate_index,
+ field,
+ )
+ )
+ return min(maximum, max(minimum, changed))
+
+ return create_profile(
+ parent.league,
+ mutate(
+ parent.base_home_score,
+ anchor.mean_home_score * 0.40,
+ anchor.mean_home_score * 1.60,
+ "base_home_score",
+ ),
+ mutate(
+ parent.base_away_score,
+ anchor.mean_away_score * 0.40,
+ anchor.mean_away_score * 1.60,
+ "base_away_score",
+ ),
+ mutate(
+ parent.total_score_sd,
+ anchor.total_score_sd * 0.35,
+ anchor.total_score_sd * 2.50,
+ "total_score_sd",
+ ),
+ mutate(
+ parent.margin_sd,
+ anchor.margin_sd * 0.35,
+ anchor.margin_sd * 2.50,
+ "margin_sd",
+ ),
+ mutate(parent.home_strength_exponent, 0.25, 2.00, "home_strength_exponent"),
+ mutate(parent.away_strength_exponent, 0.25, 2.00, "away_strength_exponent"),
+ generation,
+ parent.profile_hash,
+ "train_search_candidate",
+ )
+
+
+def score_profile(
+ profile: AnalyticalProfile,
+ games: tuple[HistoricalGame, ...],
+ config: TuningConfig,
+) -> AggregateScore:
+ """Score a fixed profile without allowing outcome-dependent weight changes."""
+
+ ensemble = create_ensemble(
+ profile.league,
+ (profile,),
+ (1.0,),
+ profile.evidence_status,
+ )
+ return score_fixed_ensemble(ensemble, ensemble.weights, games, 1.0, config)
+
+
+def score_fixed_ensemble(
+ ensemble: ModelEnsemble,
+ weights: tuple[float, ...],
+ games: tuple[HistoricalGame, ...],
+ interval_scale: float,
+ config: TuningConfig,
+) -> AggregateScore:
+ """Score a frozen ensemble on an explicitly supplied chronological block."""
+
+ if not games:
+ raise ValueError("At least one game is required for model scoring")
+ inputs = tuple(
+ ScoreInput(
+ game.home_strength,
+ game.away_strength,
+ game.home_score,
+ game.away_score,
+ )
+ for game in games
+ )
+ observations = score_observations(
+ ensemble,
+ weights,
+ inputs,
+ interval_scale,
+ config.brier_weight,
+ )
+ return _aggregate(observations, config)
+
+
+def evaluate_prequential(
+ ensemble: ModelEnsemble,
+ games: tuple[HistoricalGame, ...],
+ config: TuningConfig,
+) -> tuple[AggregateScore, AdaptiveState]:
+ """Predict before each outcome, then adjust weights and intervals exactly once."""
+
+ if not games:
+ raise ValueError("Prequential evaluation requires at least one chronological game")
+ state = create_adaptive_state(
+ ensemble,
+ config.online_learning_rate,
+ config.interval_learning_rate,
+ config.target_coverage,
+ config.short_decay,
+ config.long_decay,
+ config.drift_threshold,
+ config.minimum_drift_observations,
+ )
+ observations = []
+ for game in sorted(games, key=lambda item: item.decision_time):
+ state, observation = update_adaptive_state(
+ state,
+ ensemble,
+ game.home_strength,
+ game.away_strength,
+ game.home_score,
+ game.away_score,
+ config.brier_weight,
+ )
+ observations.append(observation)
+ return _aggregate(tuple(observations), config), state
+
+
+def create_champion_bundle(
+ results: tuple[ImprovementResult, ...],
+ protocol_version: str,
+ created_at: str,
+) -> ChampionBundle:
+ """Freeze selected champions with explicit rollback hashes."""
+
+ if not results:
+ raise ValueError("Champion bundle requires at least one improvement result")
+ _validate_bundle_identity(protocol_version, created_at)
+ champions = tuple(
+ LeagueChampion(
+ result.league,
+ result.selected_ensemble,
+ result.selected_state,
+ result.promoted,
+ result.incumbent_ensemble,
+ result.incumbent_state,
+ )
+ for result in sorted(results, key=lambda item: item.league)
+ )
+ content = {
+ "champions": [_champion_to_dict(champion) for champion in champions],
+ "created_at": created_at,
+ "protocol_version": protocol_version,
+ }
+ bundle_hash = _json_hash(content, b"USE-BUNDLE-V1")
+ return ChampionBundle(protocol_version, created_at, champions, bundle_hash)
+
+
+def verify_champion_bundle(bundle: ChampionBundle) -> None:
+ """Verify all model/state hashes and the bundle checkpoint envelope."""
+
+ if not bundle.champions:
+ raise ValueError("Champion bundle must not be empty")
+ for champion in bundle.champions:
+ verify_ensemble(champion.ensemble)
+ verify_adaptive_state(champion.state, champion.ensemble)
+ verify_ensemble(champion.rollback_ensemble)
+ verify_adaptive_state(champion.rollback_state, champion.rollback_ensemble)
+ if champion.league != champion.ensemble.league:
+ raise ValueError(f"Champion league mismatch: {champion.league!r}")
+ if champion.league != champion.rollback_ensemble.league:
+ raise ValueError(f"Rollback league mismatch: {champion.league!r}")
+ rebuilt = create_champion_bundle_from_champions(
+ bundle.champions,
+ bundle.protocol_version,
+ bundle.created_at,
+ )
+ if rebuilt.bundle_hash != bundle.bundle_hash:
+ raise ValueError(
+ "Champion bundle content hash mismatch: "
+ f"expected={rebuilt.bundle_hash}, actual={bundle.bundle_hash}"
+ )
+
+
+def create_champion_bundle_from_champions(
+ champions: tuple[LeagueChampion, ...],
+ protocol_version: str,
+ created_at: str,
+) -> ChampionBundle:
+ """Rebuild a bundle from parsed champion records."""
+
+ if not champions:
+ raise ValueError("Champion bundle requires at least one champion")
+ _validate_bundle_identity(protocol_version, created_at)
+ content = {
+ "champions": [_champion_to_dict(champion) for champion in champions],
+ "created_at": created_at,
+ "protocol_version": protocol_version,
+ }
+ return ChampionBundle(
+ protocol_version,
+ created_at,
+ champions,
+ _json_hash(content, b"USE-BUNDLE-V1"),
+ )
+
+
+def write_improvement_artifacts(
+ output: Path,
+ results: tuple[ImprovementResult, ...],
+ bundle: ChampionBundle,
+ config: TuningConfig,
+) -> None:
+ """Atomically publish a model checkpoint, report, and chained decision ledger."""
+
+ verify_champion_bundle(bundle)
+ output.mkdir(parents=True, exist_ok=True)
+ targets = (
+ output / "champion_bundle.json",
+ output / "improvement_report.json",
+ output / "improvement_ledger.jsonl",
+ )
+ existing = tuple(path for path in targets if path.exists())
+ if existing:
+ raise FileExistsError(
+ "Refusing to overwrite autonomous evidence artifacts: "
+ f"{tuple(str(path) for path in existing)!r}"
+ )
+ bundle_value = _bundle_to_dict(bundle)
+ report_value: JsonValue = {
+ "bundle_hash": bundle.bundle_hash,
+ "config": cast(JsonValue, asdict(config)),
+ "results": cast(JsonValue, [asdict(result) for result in results]),
+ "status": "chronological_calibration_only_not_real_world_certification",
+ }
+ ledger = _ledger_records(results, bundle.bundle_hash)
+ _atomic_write(targets[0], _json_text(bundle_value))
+ _atomic_write(targets[1], _json_text(report_value))
+ _atomic_write(
+ targets[2],
+ "".join(_json_line(record) for record in ledger),
+ )
+
+
+def read_champion_bundle(path: Path) -> ChampionBundle:
+ """Load and fully verify a champion checkpoint."""
+
+ value = cast(dict[str, JsonValue], json.loads(path.read_text(encoding="utf-8")))
+ champions_value = cast(list[JsonValue], value["champions"])
+ champions = tuple(
+ _champion_from_dict(cast(dict[str, JsonValue], item)) for item in champions_value
+ )
+ bundle = ChampionBundle(
+ cast(str, value["protocol_version"]),
+ cast(str, value["created_at"]),
+ champions,
+ cast(str, value["bundle_hash"]),
+ )
+ verify_champion_bundle(bundle)
+ return bundle
+
+
+def champion_for(bundle: ChampionBundle, league: str) -> LeagueChampion:
+ """Resolve one verified league champion or fail explicitly."""
+
+ verify_champion_bundle(bundle)
+ normalized = league.strip().lower()
+ for champion in bundle.champions:
+ if champion.league == normalized:
+ return champion
+ raise KeyError(f"Champion bundle has no league: {normalized!r}")
+
+
+def adapt_champion_on_shadow(
+ bundle: ChampionBundle,
+ league: str,
+ games: tuple[HistoricalGame, ...],
+ config: TuningConfig,
+ created_at: str,
+) -> ChampionBundle:
+ """Update one champion only after chronologically revealed shadow outcomes."""
+
+ validate_tuning_config(config)
+ validate_historical_games(games)
+ champion = champion_for(bundle, league)
+ normalized = champion.league
+ shadow = tuple(
+ sorted(
+ (
+ game
+ for game in games
+ if game.league == normalized and game.split == "shadow"
+ ),
+ key=lambda game: game.decision_time,
+ )
+ )
+ if not shadow:
+ raise ValueError(f"No shadow outcomes available for league: {normalized!r}")
+ if any(game.league != normalized or game.split != "shadow" for game in games):
+ raise ValueError(
+ "Online adaptation accepts exactly one league and shadow-split records only"
+ )
+ state = champion.state
+ for game in shadow:
+ state, _ = update_adaptive_state(
+ state,
+ champion.ensemble,
+ game.home_strength,
+ game.away_strength,
+ game.home_score,
+ game.away_score,
+ config.brier_weight,
+ )
+ updated = LeagueChampion(
+ champion.league,
+ champion.ensemble,
+ state,
+ champion.promoted,
+ champion.rollback_ensemble,
+ champion.rollback_state,
+ )
+ champions = tuple(
+ updated if item.league == normalized else item for item in bundle.champions
+ )
+ return create_champion_bundle_from_champions(
+ champions,
+ bundle.protocol_version,
+ created_at,
+ )
+
+
+def write_champion_bundle(path: Path, bundle: ChampionBundle) -> None:
+ """Atomically write one independently verifiable model checkpoint."""
+
+ verify_champion_bundle(bundle)
+ path.parent.mkdir(parents=True, exist_ok=True)
+ if path.exists():
+ raise FileExistsError(f"Refusing to overwrite champion checkpoint: {path}")
+ _atomic_write(path, _json_text(_bundle_to_dict(bundle)))
+
+
+def verify_improvement_ledger(path: Path, bundle_hash: str) -> int:
+ """Verify sequence, bundle binding, and the complete ledger hash chain."""
+
+ lines = tuple(line for line in path.read_text(encoding="utf-8").splitlines() if line)
+ if not lines:
+ raise ValueError(f"Improvement ledger is empty: {path}")
+ previous_hash = "0" * 64
+ for sequence, line in enumerate(lines):
+ parsed = cast(object, json.loads(line))
+ if not isinstance(parsed, dict) or any(not isinstance(key, str) for key in parsed):
+ raise ValueError(f"Malformed improvement ledger record: sequence={sequence}")
+ record = cast(dict[str, JsonValue], parsed)
+ actual_hash = cast(str, record.get("record_hash"))
+ content = {key: value for key, value in record.items() if key != "record_hash"}
+ if content.get("sequence") != sequence:
+ raise ValueError(
+ "Improvement ledger sequence mismatch: "
+ f"expected={sequence}, actual={content.get('sequence')!r}"
+ )
+ if content.get("previous_hash") != previous_hash:
+ raise ValueError(f"Improvement ledger previous hash mismatch: sequence={sequence}")
+ if content.get("bundle_hash") != bundle_hash:
+ raise ValueError(f"Improvement ledger bundle mismatch: sequence={sequence}")
+ expected_hash = _json_hash(content, b"USE-LEDGER-V1")
+ if actual_hash != expected_hash:
+ raise ValueError(
+ "Improvement ledger record hash mismatch: "
+ f"sequence={sequence}, expected={expected_hash}, actual={actual_hash}"
+ )
+ previous_hash = actual_hash
+ return len(lines)
+
+
+def rollback_champion(
+ bundle: ChampionBundle,
+ league: str,
+ created_at: str,
+) -> ChampionBundle:
+ """Create a new checkpoint with one league restored to its embedded incumbent."""
+
+ champion = champion_for(bundle, league)
+ restored = LeagueChampion(
+ champion.league,
+ champion.rollback_ensemble,
+ champion.rollback_state,
+ False,
+ champion.rollback_ensemble,
+ champion.rollback_state,
+ )
+ champions = tuple(
+ restored if item.league == champion.league else item for item in bundle.champions
+ )
+ return create_champion_bundle_from_champions(
+ champions,
+ bundle.protocol_version,
+ created_at,
+ )
+
+
+def _aggregate(
+ observations: tuple[ObservationLoss, ...],
+ config: TuningConfig,
+) -> AggregateScore:
+ if not observations:
+ raise ValueError("Cannot aggregate an empty observation sequence")
+ nll = statistics.fmean(
+ observation.joint_negative_log_likelihood for observation in observations
+ )
+ brier = statistics.fmean(
+ observation.home_win_brier for observation in observations
+ )
+ coverage = statistics.fmean(
+ (
+ float(observation.total_covered)
+ + float(observation.margin_covered)
+ )
+ / 2.0
+ for observation in observations
+ )
+ coverage_error = abs(coverage - config.target_coverage)
+ composite = nll + config.brier_weight * brier + config.coverage_weight * coverage_error
+ if any(not math.isfinite(value) for value in (nll, brier, coverage, composite)):
+ raise RuntimeError("Non-finite model score blocks autonomous promotion")
+ return AggregateScore(
+ len(observations),
+ nll,
+ brier,
+ coverage,
+ coverage_error,
+ composite,
+ )
+
+
+def _champion_to_dict(champion: LeagueChampion) -> dict[str, JsonValue]:
+ return {
+ "ensemble": _ensemble_to_dict(champion.ensemble),
+ "league": champion.league,
+ "promoted": champion.promoted,
+ "rollback_ensemble": _ensemble_to_dict(champion.rollback_ensemble),
+ "rollback_state": cast(JsonValue, asdict(champion.rollback_state)),
+ "state": cast(JsonValue, asdict(champion.state)),
+ }
+
+
+def _champion_from_dict(value: dict[str, JsonValue]) -> LeagueChampion:
+ ensemble = _ensemble_from_dict(cast(dict[str, JsonValue], value["ensemble"]))
+ rollback_ensemble = _ensemble_from_dict(
+ cast(dict[str, JsonValue], value["rollback_ensemble"])
+ )
+ state = _state_from_dict(cast(dict[str, JsonValue], value["state"]))
+ rollback_state = _state_from_dict(cast(dict[str, JsonValue], value["rollback_state"]))
+ return LeagueChampion(
+ cast(str, value["league"]),
+ ensemble,
+ state,
+ cast(bool, value["promoted"]),
+ rollback_ensemble,
+ rollback_state,
+ )
+
+
+def _state_from_dict(state_value: dict[str, JsonValue]) -> AdaptiveState:
+ return AdaptiveState(
+ cast(str, state_value["ensemble_hash"]),
+ tuple(cast(list[float], state_value["weights"])),
+ cast(float, state_value["learning_rate"]),
+ cast(float, state_value["interval_scale"]),
+ cast(float, state_value["interval_learning_rate"]),
+ cast(float, state_value["target_coverage"]),
+ cast(float, state_value["short_loss_ewma"]),
+ cast(float, state_value["long_loss_ewma"]),
+ cast(float, state_value["short_decay"]),
+ cast(float, state_value["long_decay"]),
+ cast(float, state_value["drift_threshold"]),
+ cast(int, state_value["minimum_drift_observations"]),
+ cast(int, state_value["observations"]),
+ cast(float, state_value["drift_score"]),
+ cast(str, state_value["status"]),
+ cast(str, state_value["state_hash"]),
+ )
+
+
+def _ensemble_to_dict(ensemble: ModelEnsemble) -> dict[str, JsonValue]:
+ return {
+ "ensemble_hash": ensemble.ensemble_hash,
+ "evidence_status": ensemble.evidence_status,
+ "league": ensemble.league,
+ "profiles": cast(JsonValue, [asdict(profile) for profile in ensemble.profiles]),
+ "weights": cast(JsonValue, list(ensemble.weights)),
+ }
+
+
+def _ensemble_from_dict(value: dict[str, JsonValue]) -> ModelEnsemble:
+ profiles = tuple(
+ AnalyticalProfile(
+ cast(str, profile["league"]),
+ cast(float, profile["base_home_score"]),
+ cast(float, profile["base_away_score"]),
+ cast(float, profile["total_score_sd"]),
+ cast(float, profile["margin_sd"]),
+ cast(float, profile["home_strength_exponent"]),
+ cast(float, profile["away_strength_exponent"]),
+ cast(int, profile["generation"]),
+ cast(str, profile["parent_hash"]),
+ cast(str, profile["evidence_status"]),
+ cast(str, profile["profile_hash"]),
+ )
+ for profile in cast(list[dict[str, JsonValue]], value["profiles"])
+ )
+ return ModelEnsemble(
+ cast(str, value["league"]),
+ profiles,
+ tuple(cast(list[float], value["weights"])),
+ cast(str, value["evidence_status"]),
+ cast(str, value["ensemble_hash"]),
+ )
+
+
+def _bundle_to_dict(bundle: ChampionBundle) -> JsonValue:
+ return {
+ "bundle_hash": bundle.bundle_hash,
+ "champions": [_champion_to_dict(champion) for champion in bundle.champions],
+ "created_at": bundle.created_at,
+ "protocol_version": bundle.protocol_version,
+ }
+
+
+def _ledger_records(
+ results: tuple[ImprovementResult, ...],
+ bundle_hash: str,
+) -> tuple[dict[str, JsonValue], ...]:
+ previous_hash = "0" * 64
+ records: list[dict[str, JsonValue]] = []
+ for sequence, result in enumerate(sorted(results, key=lambda item: item.league)):
+ content: dict[str, JsonValue] = {
+ "bundle_hash": bundle_hash,
+ "challenger_ensemble_hash": result.challenger_ensemble.ensemble_hash,
+ "decision": result.decision,
+ "incumbent_ensemble_hash": result.incumbent_ensemble.ensemble_hash,
+ "league": result.league,
+ "previous_hash": previous_hash,
+ "promoted": result.promoted,
+ "relative_improvement": result.relative_improvement,
+ "selected_ensemble_hash": result.selected_ensemble.ensemble_hash,
+ "sequence": sequence,
+ }
+ record_hash = _json_hash(content, b"USE-LEDGER-V1")
+ record = {**content, "record_hash": record_hash}
+ records.append(record)
+ previous_hash = record_hash
+ return tuple(records)
+
+
+def _json_hash(value: object, personalization: bytes) -> str:
+ encoded = json.dumps(
+ value,
+ allow_nan=False,
+ separators=(",", ":"),
+ sort_keys=True,
+ ).encode()
+ return hashlib.blake2b(encoded, digest_size=32, person=personalization).hexdigest()
+
+
+def _json_text(value: JsonValue) -> str:
+ return json.dumps(value, allow_nan=False, indent=2, sort_keys=True) + "\n"
+
+
+def _json_line(value: JsonValue) -> str:
+ return json.dumps(value, allow_nan=False, separators=(",", ":"), sort_keys=True) + "\n"
+
+
+def _atomic_write(path: Path, content: str) -> None:
+ temporary = path.with_name(f".{path.name}.tmp")
+ temporary.write_text(content, encoding="utf-8")
+ os.replace(temporary, path)
+
+
+def _required_int(value: dict[str, object], key: str) -> int:
+ item = value[key]
+ if isinstance(item, bool) or not isinstance(item, int):
+ raise ValueError(f"Tuning config field must be an integer: key={key!r}, value={item!r}")
+ return item
+
+
+def _required_float(value: dict[str, object], key: str) -> float:
+ item = value[key]
+ if isinstance(item, bool) or not isinstance(item, (int, float)):
+ raise ValueError(f"Tuning config field must be numeric: key={key!r}, value={item!r}")
+ return float(item)
+
+
+def _validate_bundle_identity(protocol_version: str, created_at: str) -> None:
+ if not protocol_version:
+ raise ValueError("protocol_version must be non-empty")
+ try:
+ timestamp = datetime.fromisoformat(created_at)
+ except ValueError as error:
+ raise ValueError(f"created_at must be ISO-8601: {created_at!r}") from error
+ if timestamp.utcoffset() is None:
+ raise ValueError(f"created_at must include an offset: {created_at!r}")
diff --git a/src/universal_sports_engine/cli.py b/src/universal_sports_engine/cli.py
new file mode 100644
index 0000000..636e3b5
--- /dev/null
+++ b/src/universal_sports_engine/cli.py
@@ -0,0 +1,297 @@
+"""Command-line interface for simulation, validation, and evidence inspection."""
+
+from __future__ import annotations
+
+import argparse
+import json
+from dataclasses import asdict
+from pathlib import Path
+
+from universal_sports_engine.accuracy import (
+ evaluate_forecasts,
+ forecast_historical_games,
+ load_historical_games,
+)
+from universal_sports_engine.analytical import (
+ simulate_analytical,
+ simulate_ensemble_analytical,
+)
+from universal_sports_engine.autotune import (
+ adapt_champion_on_shadow,
+ champion_for,
+ create_champion_bundle,
+ load_tuning_config,
+ read_champion_bundle,
+ rollback_champion,
+ run_recursive_improvement,
+ verify_improvement_ledger,
+ write_champion_bundle,
+ write_improvement_artifacts,
+)
+from universal_sports_engine.core.replay_io import read_result, write_result
+from universal_sports_engine.core.types import GameResult
+from universal_sports_engine.league_packs.registry import league_identities, league_ids
+from universal_sports_engine.season import round_robin_schedule, simulate_season
+from universal_sports_engine.simulation import counterfactual_game, simulate_game
+from universal_sports_engine.validation import validate_all, validate_league
+
+
+def _parser() -> argparse.ArgumentParser:
+ parser = argparse.ArgumentParser(prog="sports-engine")
+ subparsers = parser.add_subparsers(dest="command", required=True)
+ subparsers.add_parser("list-leagues")
+
+ simulate = subparsers.add_parser("simulate")
+ simulate.add_argument("--league", required=True, choices=league_ids())
+ simulate.add_argument("--seed", required=True, type=int)
+ simulate.add_argument("--export", required=False, type=Path)
+
+ simulate_fast = subparsers.add_parser("simulate-fast")
+ simulate_fast.add_argument("--league", required=True, choices=league_ids())
+ simulate_fast.add_argument("--seed", required=True, type=int)
+ simulate_fast.add_argument("--home-strength", required=True, type=float)
+ simulate_fast.add_argument("--away-strength", required=True, type=float)
+
+ season = subparsers.add_parser("simulate-season")
+ season.add_argument("--league", required=True, choices=league_ids())
+ season.add_argument("--teams", required=True, type=int)
+ season.add_argument("--rounds", required=True, type=int)
+ season.add_argument("--seed", required=True, type=int)
+
+ replay = subparsers.add_parser("verify-replay")
+ replay.add_argument("--path", required=True, type=Path)
+
+ evaluate = subparsers.add_parser("evaluate-historical")
+ evaluate.add_argument("--csv", required=True, type=Path)
+ evaluate.add_argument("--samples", required=True, type=int)
+ evaluate.add_argument("--seed", required=True, type=int)
+
+ auto_improve = subparsers.add_parser("auto-improve")
+ auto_improve.add_argument("--csv", required=True, type=Path)
+ auto_improve.add_argument("--config", required=True, type=Path)
+ auto_improve.add_argument("--output", required=True, type=Path)
+
+ adaptive = subparsers.add_parser("simulate-adaptive")
+ adaptive.add_argument("--bundle", required=True, type=Path)
+ adaptive.add_argument("--league", required=True, choices=league_ids())
+ adaptive.add_argument("--seed", required=True, type=int)
+ adaptive.add_argument("--home-strength", required=True, type=float)
+ adaptive.add_argument("--away-strength", required=True, type=float)
+
+ adapt_online = subparsers.add_parser("adapt-online")
+ adapt_online.add_argument("--csv", required=True, type=Path)
+ adapt_online.add_argument("--config", required=True, type=Path)
+ adapt_online.add_argument("--bundle", required=True, type=Path)
+ adapt_online.add_argument("--league", required=True, choices=league_ids())
+ adapt_online.add_argument("--output", required=True, type=Path)
+
+ verify_autonomy = subparsers.add_parser("verify-autonomy")
+ verify_autonomy.add_argument("--bundle", required=True, type=Path)
+ verify_autonomy.add_argument("--ledger", required=True, type=Path)
+
+ rollback = subparsers.add_parser("rollback-champion")
+ rollback.add_argument("--bundle", required=True, type=Path)
+ rollback.add_argument("--league", required=True, choices=league_ids())
+ rollback.add_argument("--created-at", required=True)
+ rollback.add_argument("--output", required=True, type=Path)
+
+ validate = subparsers.add_parser("validate")
+ validate.add_argument("--league", required=True, choices=("all", *league_ids()))
+ validate.add_argument("--games", required=True, type=int)
+ validate.add_argument("--seed", required=True, type=int)
+ validate.add_argument("--workers", required=False, type=int, default=1)
+
+ counterfactual = subparsers.add_parser("counterfactual")
+ counterfactual.add_argument("--league", required=True, choices=league_ids())
+ counterfactual.add_argument("--seed", required=True, type=int)
+ counterfactual.add_argument("--home-strength", required=True, type=float)
+ counterfactual.add_argument("--away-strength", required=True, type=float)
+ return parser
+
+
+def _result_summary(result: GameResult) -> dict[str, object]:
+ return {
+ "league": result.league,
+ "home_score": result.home_score,
+ "away_score": result.away_score,
+ "seed": result.seed,
+ "event_count": len(result.events),
+ "final_event_hash": result.events[-1].event_hash,
+ "result_hash": result.result_hash,
+ "metadata": dict(result.metadata),
+ }
+
+
+def main() -> None:
+ args = _parser().parse_args()
+ output: object
+ if args.command == "list-leagues":
+ output = [asdict(identity) for identity in league_identities()]
+ elif args.command == "simulate":
+ result = simulate_game(args.league, args.seed)
+ if args.export is not None:
+ write_result(args.export, result)
+ output = _result_summary(result)
+ elif args.command == "simulate-fast":
+ output = asdict(
+ simulate_analytical(
+ args.league,
+ args.seed,
+ args.home_strength,
+ args.away_strength,
+ )
+ )
+ elif args.command == "simulate-season":
+ if args.teams < 2:
+ raise ValueError(f"teams must be at least two: {args.teams}")
+ teams = tuple(f"team-{index:02d}" for index in range(args.teams))
+ strengths = tuple((team, 1.0) for team in teams)
+ schedule = round_robin_schedule(teams, args.rounds, args.seed)
+ season_result = simulate_season(args.league, schedule, strengths)
+ output = {
+ "league": season_result.league,
+ "games": len(season_result.games),
+ "standings": [asdict(row) for row in season_result.standings],
+ }
+ elif args.command == "verify-replay":
+ output = _result_summary(read_result(args.path))
+ elif args.command == "evaluate-historical":
+ manifest_games = load_historical_games(args.csv)
+ games = tuple(game for game in manifest_games if game.split == "test")
+ if not games:
+ raise ValueError("Historical manifest contains no test-split games")
+ output = asdict(
+ evaluate_forecasts(
+ games,
+ forecast_historical_games(games, args.samples, args.seed),
+ )
+ )
+ elif args.command == "auto-improve":
+ manifest_games = load_historical_games(args.csv)
+ config = load_tuning_config(args.config)
+ results = run_recursive_improvement(manifest_games, config)
+ calibration_games = tuple(
+ game for game in manifest_games if game.split == "calibration"
+ )
+ if not calibration_games:
+ raise ValueError("Historical manifest contains no calibration-split games")
+ evidence_cutoff = max(game.outcome_time for game in calibration_games).isoformat()
+ bundle = create_champion_bundle(results, "recursive-calibration-v1", evidence_cutoff)
+ write_improvement_artifacts(args.output, results, bundle, config)
+ output = {
+ "bundle_hash": bundle.bundle_hash,
+ "champions": [
+ {
+ "league": result.league,
+ "promoted": result.promoted,
+ "decision": result.decision,
+ "relative_improvement": result.relative_improvement,
+ "ensemble_hash": result.selected_ensemble.ensemble_hash,
+ "adaptive_state_hash": result.selected_state.state_hash,
+ }
+ for result in results
+ ],
+ "output": str(args.output.resolve()),
+ "status": "chronological_calibration_only_not_real_world_certification",
+ }
+ elif args.command == "simulate-adaptive":
+ bundle = read_champion_bundle(args.bundle)
+ champion = champion_for(bundle, args.league)
+ output = asdict(
+ simulate_ensemble_analytical(
+ champion.ensemble,
+ champion.state,
+ args.seed,
+ args.home_strength,
+ args.away_strength,
+ )
+ )
+ elif args.command == "adapt-online":
+ manifest_games = load_historical_games(args.csv)
+ shadow_games = tuple(
+ game
+ for game in manifest_games
+ if game.league == args.league and game.split == "shadow"
+ )
+ if not shadow_games:
+ raise ValueError(
+ f"Historical manifest contains no shadow games for league: {args.league!r}"
+ )
+ config = load_tuning_config(args.config)
+ bundle = read_champion_bundle(args.bundle)
+ evidence_cutoff = max(game.outcome_time for game in shadow_games).isoformat()
+ adapted = adapt_champion_on_shadow(
+ bundle,
+ args.league,
+ shadow_games,
+ config,
+ evidence_cutoff,
+ )
+ if args.output.exists():
+ raise FileExistsError(f"Refusing to overwrite adaptive checkpoint: {args.output}")
+ write_champion_bundle(args.output, adapted)
+ updated = champion_for(adapted, args.league)
+ output = {
+ "bundle_hash": adapted.bundle_hash,
+ "league": updated.league,
+ "observations": updated.state.observations,
+ "status": updated.state.status,
+ "drift_score": updated.state.drift_score,
+ "weights": updated.state.weights,
+ "output": str(args.output.resolve()),
+ }
+ elif args.command == "verify-autonomy":
+ bundle = read_champion_bundle(args.bundle)
+ output = {
+ "bundle_hash": bundle.bundle_hash,
+ "champions": len(bundle.champions),
+ "ledger_records": verify_improvement_ledger(args.ledger, bundle.bundle_hash),
+ "status": "verified",
+ }
+ elif args.command == "rollback-champion":
+ bundle = read_champion_bundle(args.bundle)
+ rolled_back = rollback_champion(
+ bundle,
+ args.league,
+ args.created_at,
+ )
+ if args.output.exists():
+ raise FileExistsError(f"Refusing to overwrite rollback checkpoint: {args.output}")
+ write_champion_bundle(args.output, rolled_back)
+ restored = champion_for(rolled_back, args.league)
+ output = {
+ "bundle_hash": rolled_back.bundle_hash,
+ "league": restored.league,
+ "ensemble_hash": restored.ensemble.ensemble_hash,
+ "state_hash": restored.state.state_hash,
+ "status": "rolled_back_to_embedded_incumbent",
+ "output": str(args.output.resolve()),
+ }
+ elif args.command == "validate":
+ reports = (
+ validate_all(args.games, args.seed, args.workers)
+ if args.league == "all"
+ else (validate_league(args.league, args.games, args.seed, args.workers),)
+ )
+ output = [asdict(report) for report in reports]
+ elif args.command == "counterfactual":
+ paired = counterfactual_game(
+ args.league,
+ args.seed,
+ args.home_strength,
+ args.away_strength,
+ )
+ output = {
+ "baseline": _result_summary(paired.baseline),
+ "intervention": _result_summary(paired.intervention),
+ "home_score_delta": paired.home_score_delta,
+ "away_score_delta": paired.away_score_delta,
+ "shared_seed": paired.shared_seed,
+ }
+ else:
+ raise AssertionError(f"Unhandled command: {args.command}")
+ print(json.dumps(output, indent=2, sort_keys=True))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/src/universal_sports_engine/core/__init__.py b/src/universal_sports_engine/core/__init__.py
new file mode 100644
index 0000000..8accbbd
--- /dev/null
+++ b/src/universal_sports_engine/core/__init__.py
@@ -0,0 +1 @@
+"""Domain-neutral deterministic simulation kernel."""
diff --git a/src/universal_sports_engine/core/event_log.py b/src/universal_sports_engine/core/event_log.py
new file mode 100644
index 0000000..19b0a62
--- /dev/null
+++ b/src/universal_sports_engine/core/event_log.py
@@ -0,0 +1,158 @@
+"""Content-addressed event creation, verification, and replay."""
+
+from __future__ import annotations
+
+import hashlib
+import json
+import math
+from collections.abc import Callable
+
+from universal_sports_engine.core.types import (
+ Event,
+ EventDraft,
+ EventIntegrityError,
+ WorldState,
+)
+
+GENESIS_HASH = "0" * 64
+Reducer = Callable[[WorldState, Event], WorldState]
+
+
+def _event_hash(sequence: int, draft: EventDraft, prior_hash: str) -> str:
+ body = {
+ "schema": "USE-EVENT-V2",
+ "sequence": sequence,
+ "clock_ms": draft.clock_ms,
+ "phase": int(draft.phase),
+ "kind": draft.kind,
+ "actor_id": draft.actor_id,
+ "payload": list(draft.payload),
+ "prior_hash": prior_hash,
+ }
+ encoded = json.dumps(
+ body,
+ sort_keys=True,
+ separators=(",", ":"),
+ ensure_ascii=False,
+ allow_nan=False,
+ ).encode()
+ return hashlib.sha256(encoded).hexdigest()
+
+
+def _validate_draft(draft: EventDraft) -> None:
+ if draft.clock_ms < 0:
+ raise ValueError(f"Event clock must be non-negative: {draft.clock_ms}")
+ if not draft.kind or not draft.actor_id:
+ raise ValueError(f"Event kind and actor_id must be non-empty: {draft!r}")
+ keys = tuple(key for key, _ in draft.payload)
+ if len(keys) != len(set(keys)):
+ raise ValueError(f"Event payload contains duplicate keys: {keys!r}")
+ for _, value in draft.payload:
+ if isinstance(value, float) and not math.isfinite(value):
+ raise ValueError(f"Event payload floats must be finite: {value}")
+
+
+def append_event(events: tuple[Event, ...], draft: EventDraft) -> tuple[Event, ...]:
+ """Return a new event tuple containing a correctly chained event."""
+
+ sequence = len(events)
+ prior_hash = events[-1].event_hash if events else GENESIS_HASH
+ _validate_draft(draft)
+ event = Event(
+ sequence=sequence,
+ clock_ms=draft.clock_ms,
+ phase=draft.phase,
+ kind=draft.kind,
+ actor_id=draft.actor_id,
+ payload=draft.payload,
+ prior_hash=prior_hash,
+ event_hash=_event_hash(sequence, draft, prior_hash),
+ )
+ return (*events, event)
+
+
+def chain_drafts(drafts: tuple[EventDraft, ...]) -> tuple[Event, ...]:
+ """Hash a complete draft stream in linear time without tuple-copy amplification."""
+
+ events: list[Event] = []
+ prior_hash = GENESIS_HASH
+ prior_clock = 0
+ prior_phase = -1
+ for sequence, draft in enumerate(drafts):
+ _validate_draft(draft)
+ if draft.clock_ms < prior_clock:
+ raise ValueError(
+ f"Event clock regressed at index {sequence}: {draft.clock_ms} < {prior_clock}"
+ )
+ if draft.clock_ms == prior_clock and int(draft.phase) < prior_phase:
+ raise ValueError(
+ "Event phase regressed at a shared clock: "
+ f"index={sequence}, phase={draft.phase.name}, prior_phase={prior_phase}"
+ )
+ event_hash = _event_hash(sequence, draft, prior_hash)
+ events.append(
+ Event(
+ sequence,
+ draft.clock_ms,
+ draft.phase,
+ draft.kind,
+ draft.actor_id,
+ draft.payload,
+ prior_hash,
+ event_hash,
+ )
+ )
+ prior_hash = event_hash
+ prior_clock = draft.clock_ms
+ prior_phase = int(draft.phase)
+ return tuple(events)
+
+
+def verify_events(events: tuple[Event, ...]) -> None:
+ """Verify sequence numbers and the complete SHA-256 chain."""
+
+ prior_hash = GENESIS_HASH
+ prior_clock = 0
+ prior_phase = -1
+ for expected_sequence, event in enumerate(events):
+ draft = EventDraft(
+ clock_ms=event.clock_ms,
+ phase=event.phase,
+ kind=event.kind,
+ actor_id=event.actor_id,
+ payload=event.payload,
+ )
+ _validate_draft(draft)
+ if event.clock_ms < prior_clock:
+ raise EventIntegrityError(
+ f"Event clock regressed at index {expected_sequence}: "
+ f"{event.clock_ms} < {prior_clock}"
+ )
+ if event.clock_ms == prior_clock and int(event.phase) < prior_phase:
+ raise EventIntegrityError(
+ f"Event phase regressed at shared clock index {expected_sequence}"
+ )
+ expected_hash = _event_hash(expected_sequence, draft, prior_hash)
+ if event.sequence != expected_sequence or event.prior_hash != prior_hash:
+ raise EventIntegrityError(
+ f"Broken event chain at index {expected_sequence}: "
+ f"sequence={event.sequence}, prior_hash={event.prior_hash}"
+ )
+ if event.event_hash != expected_hash:
+ raise EventIntegrityError(
+ f"Event hash mismatch at index {expected_sequence}: "
+ f"expected={expected_hash}, actual={event.event_hash}"
+ )
+ prior_hash = event.event_hash
+ prior_clock = event.clock_ms
+ prior_phase = int(event.phase)
+
+
+def replay(initial_state: WorldState, events: tuple[Event, ...], reducer: Reducer) -> WorldState:
+ """Verify and reduce an event stream into an immutable world state."""
+
+ verify_events(events)
+ state = initial_state
+ for event in events:
+ state = reducer(state, event)
+ return state
diff --git a/src/universal_sports_engine/core/fidelity.py b/src/universal_sports_engine/core/fidelity.py
new file mode 100644
index 0000000..70b1e2f
--- /dev/null
+++ b/src/universal_sports_engine/core/fidelity.py
@@ -0,0 +1,71 @@
+"""Evidence-gated simulation-fidelity contracts and routing."""
+
+from __future__ import annotations
+
+from dataclasses import dataclass
+from enum import IntEnum
+
+from universal_sports_engine.core.types import Payload
+
+
+class Fidelity(IntEnum):
+ """Supported resolution levels in increasing computational detail."""
+
+ ANALYTICAL = 0
+ EVENT = 1
+ SPATIAL = 2
+ PHYSICS = 3
+
+
+@dataclass(frozen=True, slots=True)
+class FidelityRequest:
+ requires_event_path: bool
+ requires_spatial_path: bool
+ requires_physics: bool
+
+
+@dataclass(frozen=True, slots=True)
+class FidelityDecision:
+ selected: Fidelity
+ supported_maximum: Fidelity
+ reason_codes: tuple[str, ...]
+
+
+@dataclass(frozen=True, slots=True)
+class Vector2:
+ x: float
+ y: float
+
+
+@dataclass(frozen=True, slots=True)
+class SpatialState:
+ entity_id: str
+ position: Vector2
+ velocity: Vector2
+ uncertainty: Payload
+
+
+class FidelityUnavailableError(RuntimeError):
+ """Raised when a request exceeds the evidence-supported fidelity."""
+
+
+def route_fidelity(request: FidelityRequest, supported_maximum: Fidelity) -> FidelityDecision:
+ """Choose the least expensive fidelity satisfying an explicit request."""
+
+ required = Fidelity.ANALYTICAL
+ reason = "aggregate_distribution_requested"
+ if request.requires_event_path:
+ required = Fidelity.EVENT
+ reason = "event_path_requested"
+ if request.requires_spatial_path:
+ required = Fidelity.SPATIAL
+ reason = "spatial_path_requested"
+ if request.requires_physics:
+ required = Fidelity.PHYSICS
+ reason = "physics_resolution_requested"
+ if required > supported_maximum:
+ raise FidelityUnavailableError(
+ "Requested fidelity exceeds the calibrated implementation: "
+ f"required={required.name}, supported={supported_maximum.name}"
+ )
+ return FidelityDecision(required, supported_maximum, (reason,))
diff --git a/src/universal_sports_engine/core/replay_io.py b/src/universal_sports_engine/core/replay_io.py
new file mode 100644
index 0000000..1c3ce55
--- /dev/null
+++ b/src/universal_sports_engine/core/replay_io.py
@@ -0,0 +1,79 @@
+"""Portable JSON export and verified import for simulation results."""
+
+from __future__ import annotations
+
+import json
+from pathlib import Path
+
+from universal_sports_engine.core.result_integrity import verify_result
+from universal_sports_engine.core.types import Event, GameResult, Phase
+
+
+def result_to_json(result: GameResult) -> str:
+ """Serialize a result without discarding evidence or hash-chain fields."""
+
+ body = {
+ "league": result.league,
+ "home_score": result.home_score,
+ "away_score": result.away_score,
+ "seed": result.seed,
+ "events": [
+ {
+ "sequence": event.sequence,
+ "clock_ms": event.clock_ms,
+ "phase": int(event.phase),
+ "kind": event.kind,
+ "actor_id": event.actor_id,
+ "payload": list(event.payload),
+ "prior_hash": event.prior_hash,
+ "event_hash": event.event_hash,
+ }
+ for event in result.events
+ ],
+ "metadata": list(result.metadata),
+ "result_hash": result.result_hash,
+ }
+ return json.dumps(body, sort_keys=True, separators=(",", ":"))
+
+
+def result_from_json(encoded: str) -> GameResult:
+ """Deserialize a result and fail if its event chain was changed."""
+
+ raw = json.loads(encoded)
+ events = tuple(
+ Event(
+ sequence=int(item["sequence"]),
+ clock_ms=int(item["clock_ms"]),
+ phase=Phase(int(item["phase"])),
+ kind=str(item["kind"]),
+ actor_id=str(item["actor_id"]),
+ payload=tuple((str(key), value) for key, value in item["payload"]),
+ prior_hash=str(item["prior_hash"]),
+ event_hash=str(item["event_hash"]),
+ )
+ for item in raw["events"]
+ )
+ result = GameResult(
+ league=str(raw["league"]),
+ home_score=int(raw["home_score"]),
+ away_score=int(raw["away_score"]),
+ seed=int(raw["seed"]),
+ events=events,
+ metadata=tuple((str(key), value) for key, value in raw["metadata"]),
+ result_hash=str(raw["result_hash"]),
+ )
+ verify_result(result)
+ return result
+
+
+def write_result(path: Path, result: GameResult) -> None:
+ """Write one portable replay artifact."""
+
+ path.parent.mkdir(parents=True, exist_ok=True)
+ path.write_text(result_to_json(result), encoding="utf-8")
+
+
+def read_result(path: Path) -> GameResult:
+ """Read and verify one portable replay artifact."""
+
+ return result_from_json(path.read_text(encoding="utf-8"))
diff --git a/src/universal_sports_engine/core/result_integrity.py b/src/universal_sports_engine/core/result_integrity.py
new file mode 100644
index 0000000..bb1bce1
--- /dev/null
+++ b/src/universal_sports_engine/core/result_integrity.py
@@ -0,0 +1,61 @@
+"""Content addressing and verification for complete result envelopes."""
+
+from __future__ import annotations
+
+import hashlib
+import json
+
+from universal_sports_engine.core.event_log import verify_events
+from universal_sports_engine.core.types import Event, EventIntegrityError, GameResult, Payload
+
+
+def compute_result_hash(
+ league: str,
+ home_score: int,
+ away_score: int,
+ seed: int,
+ events: tuple[Event, ...],
+ metadata: Payload,
+) -> str:
+ """Hash every externally meaningful result field."""
+
+ if not events:
+ raise ValueError("A complete result requires at least one event")
+ body = {
+ "schema": "USE-RESULT-V1",
+ "league": league,
+ "home_score": home_score,
+ "away_score": away_score,
+ "seed": seed,
+ "event_count": len(events),
+ "final_event_hash": events[-1].event_hash,
+ "metadata": list(metadata),
+ }
+ encoded = json.dumps(
+ body,
+ sort_keys=True,
+ separators=(",", ":"),
+ ensure_ascii=False,
+ allow_nan=False,
+ ).encode()
+ return hashlib.sha256(encoded).hexdigest()
+
+
+def verify_result(result: GameResult) -> None:
+ """Verify event integrity and the complete published result envelope."""
+
+ if not result.league or result.seed < 0 or min(result.home_score, result.away_score) < 0:
+ raise EventIntegrityError(f"Invalid result envelope values: {result!r}")
+ verify_events(result.events)
+ expected = compute_result_hash(
+ result.league,
+ result.home_score,
+ result.away_score,
+ result.seed,
+ result.events,
+ result.metadata,
+ )
+ if result.result_hash != expected:
+ raise EventIntegrityError(
+ f"Result hash mismatch: expected={expected}, actual={result.result_hash}"
+ )
diff --git a/src/universal_sports_engine/core/rng.py b/src/universal_sports_engine/core/rng.py
new file mode 100644
index 0000000..07b6e26
--- /dev/null
+++ b/src/universal_sports_engine/core/rng.py
@@ -0,0 +1,45 @@
+"""Order-independent deterministic random primitives."""
+
+from __future__ import annotations
+
+import hashlib
+import math
+
+
+def _digest(root_seed: int, labels: tuple[str | int, ...]) -> bytes:
+ encoded = "\x1f".join((str(root_seed), *(str(label) for label in labels))).encode()
+ return hashlib.blake2b(encoded, digest_size=8, person=b"USE-RNG2").digest()
+
+
+def unit(root_seed: int, *labels: str | int) -> float:
+ """Return a deterministic U[0, 1) draw addressed by semantic labels."""
+
+ return int.from_bytes(_digest(root_seed, labels), "big") / 2**64
+
+
+def choice(root_seed: int, weights: tuple[float, ...], *labels: str | int) -> int:
+ """Select a weighted index without mutable global or shared RNG state."""
+
+ if not weights or any(weight < 0 for weight in weights):
+ raise ValueError(f"Weights must be a non-empty non-negative tuple: {weights!r}")
+ total = math.fsum(weights)
+ if total <= 0:
+ raise ValueError(f"At least one weight must be positive: {weights!r}")
+ threshold = unit(root_seed, *labels) * total
+ cumulative = 0.0
+ for index, weight in enumerate(weights):
+ cumulative += weight
+ if threshold < cumulative:
+ return index
+ return len(weights) - 1
+
+
+def normal(root_seed: int, mean: float, standard_deviation: float, *labels: str | int) -> float:
+ """Return a deterministic normal draw via Box-Muller."""
+
+ if standard_deviation < 0:
+ raise ValueError("standard_deviation must be non-negative")
+ u1 = max(unit(root_seed, *labels, "u1"), 1e-15)
+ u2 = unit(root_seed, *labels, "u2")
+ z = math.sqrt(-2.0 * math.log(u1)) * math.cos(2.0 * math.pi * u2)
+ return mean + standard_deviation * z
diff --git a/src/universal_sports_engine/core/rules.py b/src/universal_sports_engine/core/rules.py
new file mode 100644
index 0000000..697702f
--- /dev/null
+++ b/src/universal_sports_engine/core/rules.py
@@ -0,0 +1,41 @@
+"""Declarative rule-pack validation."""
+
+from __future__ import annotations
+
+from dataclasses import dataclass
+
+
+@dataclass(frozen=True, slots=True)
+class Rule:
+ rule_id: str
+ description: str
+ source: str
+ effective_season: int
+
+
+@dataclass(frozen=True, slots=True)
+class RulePack:
+ league: str
+ version: str
+ coverage_status: str
+ source_version: str
+ rules: tuple[Rule, ...]
+
+
+def validate_rule_pack(pack: RulePack) -> None:
+ """Fail closed on incomplete or duplicate declarative rules."""
+
+ if (
+ not pack.league
+ or not pack.version
+ or not pack.coverage_status
+ or not pack.source_version
+ or not pack.rules
+ ):
+ raise ValueError(f"Incomplete rule pack: {pack!r}")
+ identifiers = tuple(rule.rule_id for rule in pack.rules)
+ if len(set(identifiers)) != len(identifiers):
+ raise ValueError(f"Duplicate rule IDs in {pack.league} {pack.version}: {identifiers!r}")
+ for rule in pack.rules:
+ if not rule.description or not rule.source or rule.effective_season < 1900:
+ raise ValueError(f"Incomplete rule definition: {rule!r}")
diff --git a/src/universal_sports_engine/core/types.py b/src/universal_sports_engine/core/types.py
new file mode 100644
index 0000000..ea78aa9
--- /dev/null
+++ b/src/universal_sports_engine/core/types.py
@@ -0,0 +1,114 @@
+"""Immutable domain-neutral simulation contracts."""
+
+from __future__ import annotations
+
+from dataclasses import dataclass
+from enum import IntEnum
+
+type Scalar = str | int | float | bool | None
+type Payload = tuple[tuple[str, Scalar], ...]
+
+
+class Phase(IntEnum):
+ """Stable total ordering for simultaneous simulation work."""
+
+ PERCEIVE = 0
+ DECIDE = 1
+ ARBITRATE = 2
+ RESOLVE = 3
+ APPLY = 4
+ PUBLISH = 5
+
+
+@dataclass(frozen=True, slots=True)
+class Event:
+ """One immutable, content-addressed state transition record."""
+
+ sequence: int
+ clock_ms: int
+ phase: Phase
+ kind: str
+ actor_id: str
+ payload: Payload
+ prior_hash: str
+ event_hash: str
+
+
+@dataclass(frozen=True, slots=True)
+class EventDraft:
+ """Hash-free event description accepted by the event log."""
+
+ clock_ms: int
+ phase: Phase
+ kind: str
+ actor_id: str
+ payload: Payload
+
+
+@dataclass(frozen=True, slots=True)
+class WorldState:
+ """Immutable generic state represented as sorted key/value pairs."""
+
+ sequence: int
+ clock_ms: int
+ values: Payload
+
+
+@dataclass(frozen=True, slots=True)
+class GameResult:
+ """League-neutral result emitted by every complete-game simulator."""
+
+ league: str
+ home_score: int
+ away_score: int
+ seed: int
+ events: tuple[Event, ...]
+ metadata: Payload
+ result_hash: str
+
+
+@dataclass(frozen=True, slots=True)
+class Evidence:
+ """Versioned evidence metadata for downstream consumers."""
+
+ engine_version: str
+ domain_pack_version: str
+ scenario_hash: str
+ seed: int
+ validation_tier: str
+ limitations: tuple[str, ...]
+
+
+class SimulationError(RuntimeError):
+ """Base class for explicit simulation failures."""
+
+
+class InvalidStateError(SimulationError):
+ """Raised when a transition would produce an illegal state."""
+
+
+class EventIntegrityError(SimulationError):
+ """Raised when an event hash chain cannot be verified."""
+
+
+class UnknownLeagueError(SimulationError):
+ """Raised when no registered league pack matches the requested ID."""
+
+
+class ParallelExecutionUnavailableError(SimulationError):
+ """Raised when the current host cannot safely spawn deterministic workers."""
+
+
+def payload(**values: Scalar) -> Payload:
+ """Create a deterministic immutable payload."""
+
+ return tuple(sorted(values.items()))
+
+
+def payload_get(values: Payload, key: str) -> Scalar:
+ """Read a payload key or raise an actionable error."""
+
+ for item_key, value in values:
+ if item_key == key:
+ return value
+ raise KeyError(f"Payload key is missing: {key}")
diff --git a/src/universal_sports_engine/dummy_bridge/__init__.py b/src/universal_sports_engine/dummy_bridge/__init__.py
new file mode 100644
index 0000000..44b8d17
--- /dev/null
+++ b/src/universal_sports_engine/dummy_bridge/__init__.py
@@ -0,0 +1 @@
+"""Domain-neutral bridge for later Dummy world-model adaptation."""
diff --git a/src/universal_sports_engine/dummy_bridge/contracts.py b/src/universal_sports_engine/dummy_bridge/contracts.py
new file mode 100644
index 0000000..e62105e
--- /dev/null
+++ b/src/universal_sports_engine/dummy_bridge/contracts.py
@@ -0,0 +1,92 @@
+"""Sport-agnostic state, policy, scenario, and evidence contracts."""
+
+from __future__ import annotations
+
+from dataclasses import dataclass
+
+from universal_sports_engine.core.types import Evidence, GameResult, Payload, payload, payload_get
+
+
+@dataclass(frozen=True, slots=True)
+class State:
+ state_id: str
+ observed: Payload
+ latent: Payload
+ exogenous: Payload
+ history_hash: str
+
+
+@dataclass(frozen=True, slots=True)
+class Action:
+ action_id: str
+ actor_id: str
+ parameters: Payload
+
+
+@dataclass(frozen=True, slots=True)
+class Observation:
+ observer_id: str
+ state_id: str
+ values: Payload
+ uncertainty: Payload
+
+
+@dataclass(frozen=True, slots=True)
+class PolicyDecision:
+ action_distribution: Payload
+ selected_action_id: str
+ confidence: float
+ explanation_codes: tuple[str, ...]
+ abstain: bool
+
+
+@dataclass(frozen=True, slots=True)
+class Scenario:
+ scenario_id: str
+ initial_state: State
+ constraints: Payload
+ objective: Payload
+
+
+@dataclass(frozen=True, slots=True)
+class Counterfactual:
+ source_scenario_id: str
+ intervention: Action
+ shared_seed: int
+
+
+def evidence_from_result(result: GameResult) -> Evidence:
+ """Translate a result into a domain-neutral, fail-closed evidence envelope."""
+
+ return Evidence(
+ engine_version=str(payload_get(result.metadata, "engine_version")),
+ domain_pack_version=str(payload_get(result.metadata, "domain_pack_version")),
+ scenario_hash=str(payload_get(result.metadata, "scenario_hash")),
+ seed=result.seed,
+ validation_tier=str(payload_get(result.metadata, "validation_tier")),
+ limitations=(
+ "No licensed point-in-time event or tracking data in the local build.",
+ "Reference-anchor validation does not certify real-world predictive accuracy.",
+ "No wagering or live-action adapter is present.",
+ ),
+ )
+
+
+def generic_fixture(seed: int) -> tuple[State, Action, Observation]:
+ """Prove the bridge does not require a sport-specific concept."""
+
+ state = State(
+ state_id=f"inventory-{seed}",
+ observed=payload(inventory=10, demand_signal=0.6),
+ latent=payload(true_demand=None),
+ exogenous=payload(weather_index=0.2),
+ history_hash="fixture",
+ )
+ action = Action("reorder", "controller", payload(quantity=3))
+ observation = Observation(
+ "controller",
+ state.state_id,
+ state.observed,
+ payload(demand_signal_sd=0.1),
+ )
+ return state, action, observation
diff --git a/src/universal_sports_engine/league_packs/__init__.py b/src/universal_sports_engine/league_packs/__init__.py
new file mode 100644
index 0000000..e0c357b
--- /dev/null
+++ b/src/universal_sports_engine/league_packs/__init__.py
@@ -0,0 +1 @@
+"""League-specific simulation packs."""
diff --git a/src/universal_sports_engine/league_packs/baseball.py b/src/universal_sports_engine/league_packs/baseball.py
new file mode 100644
index 0000000..f3521e5
--- /dev/null
+++ b/src/universal_sports_engine/league_packs/baseball.py
@@ -0,0 +1,173 @@
+"""Pitch/plate-appearance/inning simulation for the MLB pack."""
+
+from __future__ import annotations
+
+from dataclasses import dataclass
+
+from universal_sports_engine.core.rng import choice, unit
+from universal_sports_engine.core.types import EventDraft, GameResult, Phase, payload
+from universal_sports_engine.league_packs.common import (
+ LeagueIdentity,
+ draft_event,
+ finalize_result,
+)
+
+MLB = LeagueIdentity("mlb", "Major League Baseball", "bat_and_ball", "mlb-2026.2", 2026)
+
+
+@dataclass(frozen=True, slots=True)
+class BaseballConfig:
+ innings: int
+ outcome_weights: tuple[float, ...]
+ outcome_names: tuple[str, ...]
+ home_outcome_shift: float
+
+
+CONFIG = BaseballConfig(
+ innings=9,
+ outcome_weights=(0.693, 0.083, 0.137, 0.047, 0.005, 0.035),
+ outcome_names=("out", "walk", "single", "double", "triple", "home_run"),
+ home_outcome_shift=0.010,
+)
+
+
+def _adjusted_weights(
+ config: BaseballConfig,
+ strength: float,
+ outcome_shift: float,
+) -> tuple[float, ...]:
+ delta = max(-0.08, min(0.08, (strength - 1.0) * 0.08 + outcome_shift))
+ return (
+ config.outcome_weights[0] - delta,
+ config.outcome_weights[1],
+ config.outcome_weights[2] + delta * 0.50,
+ config.outcome_weights[3] + delta * 0.25,
+ config.outcome_weights[4],
+ config.outcome_weights[5] + delta * 0.25,
+ )
+
+
+def _advance(
+ outcome: str,
+ bases: tuple[bool, bool, bool],
+ seed: int,
+ labels: tuple[str | int, ...],
+) -> tuple[tuple[bool, bool, bool], int, int]:
+ first, second, third = bases
+ if outcome == "out":
+ return bases, 0, 1
+ if outcome == "walk":
+ runs = int(first and second and third)
+ return (True, first or second, (second and first) or third), runs, 0
+ if outcome == "single":
+ second_scores = second and unit(seed, *labels, "second_scores") < 0.72
+ third_scores = third
+ new_third = (second and not second_scores) or (
+ first and unit(seed, *labels, "first_to_third") < 0.28
+ )
+ return (True, first, new_third), int(second_scores) + int(third_scores), 0
+ if outcome == "double":
+ first_scores = first and unit(seed, *labels, "first_scores") < 0.52
+ runs = int(second) + int(third) + int(first_scores)
+ return (False, True, first and not first_scores), runs, 0
+ if outcome == "triple":
+ return (False, False, True), int(first) + int(second) + int(third), 0
+ if outcome == "home_run":
+ return (False, False, False), 1 + int(first) + int(second) + int(third), 0
+ raise ValueError(f"Unknown baseball outcome: {outcome}")
+
+
+def simulate_mlb(seed: int, home_strength: float, away_strength: float) -> GameResult:
+ """Simulate a complete game with deterministic plate-appearance events."""
+
+ drafts: list[EventDraft] = []
+ scores = {"home": 0, "away": 0}
+ inning = 1
+ clock_ms = 0
+ while inning <= CONFIG.innings or scores["home"] == scores["away"]:
+ if inning > 20:
+ winner = "home" if unit(seed, "mlb", "tie_break") < 0.5 else "away"
+ scores[winner] += 1
+ clock_ms += 1
+ drafts.append(
+ draft_event(
+ clock_ms,
+ Phase.RESOLVE,
+ "administrative_tie_break",
+ winner,
+ payload(inning=inning, runs=1),
+ )
+ )
+ break
+ for batting in ("away", "home"):
+ if inning >= CONFIG.innings and batting == "home" and scores["home"] > scores["away"]:
+ break
+ strength = away_strength if batting == "away" else home_strength
+ outcome_shift = CONFIG.home_outcome_shift if batting == "home" else 0.0
+ bases = (False, inning >= 10, False)
+ outs = 0
+ plate_appearance = 0
+ while outs < 3:
+ outcome_index = choice(
+ seed,
+ _adjusted_weights(CONFIG, strength, outcome_shift),
+ "mlb",
+ inning,
+ batting,
+ plate_appearance,
+ )
+ outcome = CONFIG.outcome_names[outcome_index]
+ labels: tuple[str | int, ...] = ("mlb", inning, batting, plate_appearance)
+ bases, runs, outs_added = _advance(outcome, bases, seed, labels)
+ outs += outs_added
+ scores[batting] += runs
+ clock_ms += 24_000
+ drafts.append(
+ draft_event(
+ clock_ms,
+ Phase.APPLY,
+ "plate_appearance",
+ batting,
+ payload(
+ inning=inning,
+ half=batting,
+ outcome=outcome,
+ outs=outs,
+ runs=runs,
+ home_score=scores["home"],
+ away_score=scores["away"],
+ ),
+ )
+ )
+ plate_appearance += 1
+ if plate_appearance > 100:
+ raise RuntimeError(f"MLB half-inning exceeded safety bound: inning={inning}")
+ if (
+ inning >= CONFIG.innings
+ and batting == "home"
+ and scores["home"] > scores["away"]
+ ):
+ break
+ drafts.append(
+ draft_event(
+ clock_ms,
+ Phase.PUBLISH,
+ "inning_complete",
+ "official",
+ payload(
+ inning=inning,
+ home_score=scores["home"],
+ away_score=scores["away"],
+ ),
+ )
+ )
+ inning += 1
+ return finalize_result(
+ MLB,
+ scores["home"],
+ scores["away"],
+ seed,
+ tuple(drafts),
+ home_strength,
+ away_strength,
+ )
diff --git a/src/universal_sports_engine/league_packs/basketball.py b/src/universal_sports_engine/league_packs/basketball.py
new file mode 100644
index 0000000..68d1352
--- /dev/null
+++ b/src/universal_sports_engine/league_packs/basketball.py
@@ -0,0 +1,178 @@
+"""Possession-level basketball family with distinct league packs."""
+
+from __future__ import annotations
+
+from dataclasses import dataclass
+
+from universal_sports_engine.core.rng import choice, normal
+from universal_sports_engine.core.types import EventDraft, GameResult, Phase, payload
+from universal_sports_engine.league_packs.common import (
+ LeagueIdentity,
+ draft_event,
+ finalize_result,
+)
+
+
+@dataclass(frozen=True, slots=True)
+class BasketballConfig:
+ identity: LeagueIdentity
+ team_possessions: int
+ possession_sd: float
+ outcome_weights: tuple[float, ...]
+ game_minutes: int
+ home_outcome_shift: float
+
+
+CONFIGS = {
+ "nba": BasketballConfig(
+ LeagueIdentity(
+ "nba",
+ "National Basketball Association",
+ "court_invasion",
+ "nba-2025-26.2",
+ 2025,
+ ),
+ 99,
+ 4.5,
+ (0.13, 0.34, 0.07, 0.29, 0.17),
+ 48,
+ 0.009,
+ ),
+ "wnba": BasketballConfig(
+ LeagueIdentity(
+ "wnba",
+ "Women's National Basketball Association",
+ "court_invasion",
+ "wnba-2026.2",
+ 2026,
+ ),
+ 80,
+ 4.0,
+ (0.16, 0.34, 0.09, 0.29, 0.12),
+ 40,
+ 0.0075,
+ ),
+ "ncaambb": BasketballConfig(
+ LeagueIdentity(
+ "ncaambb",
+ "NCAA Men's Basketball",
+ "court_invasion",
+ "ncaambb-2025-26.2",
+ 2025,
+ ),
+ 69,
+ 5.0,
+ (0.18, 0.34, 0.09, 0.28, 0.11),
+ 40,
+ 0.013,
+ ),
+}
+
+OUTCOMES = ("turnover", "empty", "free_throw", "two_pointer", "three_pointer")
+POINTS = (0, 0, 1, 2, 3)
+
+
+def _weights(
+ config: BasketballConfig,
+ strength: float,
+ outcome_shift: float,
+) -> tuple[float, ...]:
+ delta = max(-0.06, min(0.06, (strength - 1.0) * 0.10 + outcome_shift))
+ return (
+ config.outcome_weights[0],
+ config.outcome_weights[1] - delta,
+ config.outcome_weights[2],
+ config.outcome_weights[3] + delta * 0.65,
+ config.outcome_weights[4] + delta * 0.35,
+ )
+
+
+def simulate_basketball(
+ league: str,
+ seed: int,
+ home_strength: float,
+ away_strength: float,
+) -> GameResult:
+ """Simulate a regulation game plus deterministic overtime possessions."""
+
+ config = CONFIGS[league]
+ possessions_per_team = max(
+ 40,
+ round(normal(seed, config.team_possessions, config.possession_sd, league, "pace")),
+ )
+ drafts: list[EventDraft] = []
+ scores = {"home": 0, "away": 0}
+ total_possessions = possessions_per_team * 2
+ clock_total_ms = config.game_minutes * 60_000
+ possession = 0
+ overtime = 0
+ while possession < total_possessions or scores["home"] == scores["away"]:
+ if possession >= total_possessions:
+ overtime += 1
+ if overtime > 8:
+ side = "home" if possession % 2 == 0 else "away"
+ scores[side] += 1
+ drafts.append(
+ draft_event(
+ clock_total_ms + overtime * 300_000,
+ Phase.RESOLVE,
+ "administrative_tie_break",
+ side,
+ payload(points=1, overtime=overtime),
+ )
+ )
+ break
+ total_possessions += 20
+ side = "home" if possession % 2 == 0 else "away"
+ strength = home_strength if side == "home" else away_strength
+ outcome_shift = config.home_outcome_shift if side == "home" else 0.0
+ outcome_index = choice(
+ seed,
+ _weights(config, strength, outcome_shift),
+ league,
+ "possession",
+ possession,
+ )
+ points = POINTS[outcome_index]
+ scores[side] += points
+ regulation_fraction = min(1.0, (possession + 1) / max(1, possessions_per_team * 2))
+ clock_ms = round(regulation_fraction * clock_total_ms) + overtime * 300_000
+ drafts.append(
+ draft_event(
+ clock_ms,
+ Phase.APPLY,
+ "possession",
+ side,
+ payload(
+ possession=possession,
+ outcome=OUTCOMES[outcome_index],
+ points=points,
+ overtime=overtime,
+ home_score=scores["home"],
+ away_score=scores["away"],
+ ),
+ ),
+ )
+ possession += 1
+ drafts.append(
+ draft_event(
+ drafts[-1].clock_ms,
+ Phase.PUBLISH,
+ "game_complete",
+ "official",
+ payload(
+ home_score=scores["home"],
+ away_score=scores["away"],
+ overtime=overtime,
+ ),
+ )
+ )
+ return finalize_result(
+ config.identity,
+ scores["home"],
+ scores["away"],
+ seed,
+ tuple(drafts),
+ home_strength,
+ away_strength,
+ )
diff --git a/src/universal_sports_engine/league_packs/common.py b/src/universal_sports_engine/league_packs/common.py
new file mode 100644
index 0000000..62aaa5f
--- /dev/null
+++ b/src/universal_sports_engine/league_packs/common.py
@@ -0,0 +1,121 @@
+"""Shared immutable league-pack data types and helpers."""
+
+from __future__ import annotations
+
+import hashlib
+import json
+from dataclasses import dataclass
+
+from universal_sports_engine.core.event_log import append_event, chain_drafts
+from universal_sports_engine.core.result_integrity import compute_result_hash
+from universal_sports_engine.core.types import (
+ Event,
+ EventDraft,
+ GameResult,
+ Payload,
+ Phase,
+ payload,
+)
+
+ENGINE_VERSION = "0.3.0"
+
+
+@dataclass(frozen=True, slots=True)
+class LeagueIdentity:
+ league_id: str
+ display_name: str
+ family: str
+ pack_version: str
+ season: int
+
+
+def add_event(
+ events: tuple[Event, ...],
+ clock_ms: int,
+ phase: Phase,
+ kind: str,
+ actor_id: str,
+ values: Payload,
+) -> tuple[Event, ...]:
+ """Append an event without exposing hash-chain mechanics to league packs."""
+
+ return append_event(
+ events,
+ EventDraft(
+ clock_ms=clock_ms,
+ phase=phase,
+ kind=kind,
+ actor_id=actor_id,
+ payload=values,
+ ),
+ )
+
+
+def draft_event(
+ clock_ms: int,
+ phase: Phase,
+ kind: str,
+ actor_id: str,
+ values: Payload,
+) -> EventDraft:
+ """Create an immutable event draft for linear-time finalization."""
+
+ return EventDraft(clock_ms, phase, kind, actor_id, values)
+
+
+def scenario_hash(league: str, seed: int, home_strength: float, away_strength: float) -> str:
+ body = json.dumps(
+ {
+ "league": league,
+ "seed": seed,
+ "home_strength": home_strength,
+ "away_strength": away_strength,
+ },
+ sort_keys=True,
+ separators=(",", ":"),
+ ).encode()
+ return hashlib.sha256(body).hexdigest()
+
+
+def finalize_result(
+ identity: LeagueIdentity,
+ home_score: int,
+ away_score: int,
+ seed: int,
+ drafts: tuple[EventDraft, ...],
+ home_strength: float,
+ away_strength: float,
+) -> GameResult:
+ """Verify the event log and build the common result envelope."""
+
+ events = chain_drafts(drafts)
+ metadata = payload(
+ engine_version=ENGINE_VERSION,
+ domain_pack_version=identity.pack_version,
+ family=identity.family,
+ season=identity.season,
+ scenario_hash=scenario_hash(
+ identity.league_id,
+ seed,
+ home_strength,
+ away_strength,
+ ),
+ validation_tier="provisional_reference_anchor",
+ )
+ result_hash = compute_result_hash(
+ identity.league_id,
+ home_score,
+ away_score,
+ seed,
+ events,
+ metadata,
+ )
+ return GameResult(
+ league=identity.league_id,
+ home_score=home_score,
+ away_score=away_score,
+ seed=seed,
+ events=events,
+ metadata=metadata,
+ result_hash=result_hash,
+ )
diff --git a/src/universal_sports_engine/league_packs/football.py b/src/universal_sports_engine/league_packs/football.py
new file mode 100644
index 0000000..2fd553e
--- /dev/null
+++ b/src/universal_sports_engine/league_packs/football.py
@@ -0,0 +1,151 @@
+"""Play/drive/game simulation for professional and college football."""
+
+from __future__ import annotations
+
+from dataclasses import dataclass
+
+from universal_sports_engine.core.rng import choice, unit
+from universal_sports_engine.core.types import EventDraft, GameResult, Phase, payload
+from universal_sports_engine.league_packs.common import (
+ LeagueIdentity,
+ draft_event,
+ finalize_result,
+)
+
+
+@dataclass(frozen=True, slots=True)
+class FootballConfig:
+ identity: LeagueIdentity
+ drives_per_team: int
+ drive_outcome_weights: tuple[float, ...]
+ home_outcome_shift: float
+
+
+CONFIGS = {
+ "nfl": FootballConfig(
+ LeagueIdentity("nfl", "National Football League", "gridiron", "nfl-2025.2", 2025),
+ 11,
+ (0.58, 0.02, 0.16, 0.24),
+ 0.028,
+ ),
+ "ncaaf": FootballConfig(
+ LeagueIdentity("ncaaf", "NCAA Football", "gridiron", "ncaaf-2025.2", 2025),
+ 12,
+ (0.55, 0.01, 0.16, 0.28),
+ 0.037,
+ ),
+}
+
+DRIVE_OUTCOMES = ("no_score", "safety", "field_goal", "touchdown")
+DRIVE_POINTS = (0, 2, 3, 7)
+
+
+def _weights(
+ config: FootballConfig,
+ strength: float,
+ outcome_shift: float,
+) -> tuple[float, ...]:
+ delta = max(-0.08, min(0.08, (strength - 1.0) * 0.10 + outcome_shift))
+ return (
+ config.drive_outcome_weights[0] - delta,
+ config.drive_outcome_weights[1],
+ config.drive_outcome_weights[2] + delta * 0.35,
+ config.drive_outcome_weights[3] + delta * 0.65,
+ )
+
+
+def _play_count(seed: int, league: str, drive: int, side: str) -> int:
+ return 3 + int(unit(seed, league, "drive", drive, side, "plays") * 8)
+
+
+def simulate_football(
+ league: str,
+ seed: int,
+ home_strength: float,
+ away_strength: float,
+) -> GameResult:
+ """Simulate play events grouped into drives, regulation, and overtime."""
+
+ config = CONFIGS[league]
+ drafts: list[EventDraft] = []
+ scores = {"home": 0, "away": 0}
+ total_drives = config.drives_per_team * 2
+ drive = 0
+ clock_ms = 0
+ overtime = 0
+ while drive < total_drives or scores["home"] == scores["away"]:
+ if drive >= total_drives:
+ overtime += 1
+ total_drives += 2
+ if overtime > 8:
+ scores["home"] += 1
+ clock_ms += 1
+ drafts.append(
+ draft_event(
+ clock_ms,
+ Phase.RESOLVE,
+ "administrative_tie_break",
+ "home",
+ payload(points=1, overtime=overtime),
+ )
+ )
+ break
+ side = "home" if drive % 2 == 0 else "away"
+ strength = home_strength if side == "home" else away_strength
+ outcome_shift = config.home_outcome_shift if side == "home" else 0.0
+ plays = _play_count(seed, league, drive, side)
+ field_position = 25
+ for play in range(plays):
+ yards = round((unit(seed, league, drive, play, "yards") - 0.35) * 18)
+ field_position = max(0, min(100, field_position + yards))
+ clock_ms += 34_000
+ drafts.append(
+ draft_event(
+ clock_ms,
+ Phase.APPLY,
+ "play",
+ side,
+ payload(
+ drive=drive,
+ play=play,
+ yards=yards,
+ field_position=field_position,
+ overtime=overtime,
+ ),
+ ),
+ )
+ outcome_index = choice(
+ seed,
+ _weights(config, strength, outcome_shift),
+ league,
+ "drive_result",
+ drive,
+ )
+ points = DRIVE_POINTS[outcome_index]
+ scores[side] += points
+ drafts.append(
+ draft_event(
+ clock_ms,
+ Phase.PUBLISH,
+ "drive_complete",
+ side,
+ payload(
+ drive=drive,
+ outcome=DRIVE_OUTCOMES[outcome_index],
+ points=points,
+ overtime=overtime,
+ home_score=scores["home"],
+ away_score=scores["away"],
+ ),
+ ),
+ )
+ drive += 1
+ return finalize_result(
+ config.identity,
+ scores["home"],
+ scores["away"],
+ seed,
+ tuple(drafts),
+ home_strength,
+ away_strength,
+ )
diff --git a/src/universal_sports_engine/league_packs/hockey.py b/src/universal_sports_engine/league_packs/hockey.py
new file mode 100644
index 0000000..91a28d9
--- /dev/null
+++ b/src/universal_sports_engine/league_packs/hockey.py
@@ -0,0 +1,81 @@
+"""Shift/shot/game simulation for the NHL pack."""
+
+from __future__ import annotations
+
+from universal_sports_engine.core.rng import unit
+from universal_sports_engine.core.types import EventDraft, GameResult, Phase, payload
+from universal_sports_engine.league_packs.common import (
+ LeagueIdentity,
+ draft_event,
+ finalize_result,
+)
+
+NHL = LeagueIdentity("nhl", "National Hockey League", "ice_invasion", "nhl-2025-26.2", 2025)
+
+
+def simulate_nhl(seed: int, home_strength: float, away_strength: float) -> GameResult:
+ """Simulate regulation shifts, shots, overtime, and a shootout if needed."""
+
+ drafts: list[EventDraft] = []
+ scores = {"home": 0, "away": 0}
+ shifts = 120
+ for shift in range(shifts):
+ side = "home" if shift % 2 == 0 else "away"
+ strength = home_strength * 1.02 if side == "home" else away_strength
+ shot_probability = min(0.78, max(0.30, 0.52 * strength))
+ clock_ms = round((shift + 1) / shifts * 3_600_000)
+ if unit(seed, "nhl", "shot", shift) < shot_probability:
+ goal_probability = min(0.20, max(0.04, 0.095 * strength))
+ goal = unit(seed, "nhl", "goal", shift) < goal_probability
+ if goal:
+ scores[side] += 1
+ drafts.append(
+ draft_event(
+ clock_ms,
+ Phase.APPLY,
+ "shot",
+ side,
+ payload(
+ shift=shift,
+ goal=goal,
+ home_score=scores["home"],
+ away_score=scores["away"],
+ ),
+ ),
+ )
+ if (shift + 1) % 40 == 0:
+ drafts.append(
+ draft_event(
+ clock_ms,
+ Phase.PUBLISH,
+ "period_complete",
+ "official",
+ payload(
+ period=(shift + 1) // 40,
+ home_score=scores["home"],
+ away_score=scores["away"],
+ ),
+ ),
+ )
+ overtime = scores["home"] == scores["away"]
+ if overtime:
+ overtime_winner = "home" if unit(seed, "nhl", "overtime") < 0.54 else "away"
+ scores[overtime_winner] += 1
+ drafts.append(
+ draft_event(
+ 3_900_000,
+ Phase.RESOLVE,
+ "overtime_goal_or_shootout",
+ overtime_winner,
+ payload(home_score=scores["home"], away_score=scores["away"]),
+ )
+ )
+ return finalize_result(
+ NHL,
+ scores["home"],
+ scores["away"],
+ seed,
+ tuple(drafts),
+ home_strength,
+ away_strength,
+ )
diff --git a/src/universal_sports_engine/league_packs/registry.py b/src/universal_sports_engine/league_packs/registry.py
new file mode 100644
index 0000000..2bbc96e
--- /dev/null
+++ b/src/universal_sports_engine/league_packs/registry.py
@@ -0,0 +1,45 @@
+"""League-pack registry and strict dispatcher."""
+
+from __future__ import annotations
+
+from collections.abc import Callable
+
+from universal_sports_engine.core.types import GameResult, UnknownLeagueError
+from universal_sports_engine.league_packs.baseball import MLB, simulate_mlb
+from universal_sports_engine.league_packs.basketball import CONFIGS as BASKETBALL_CONFIGS
+from universal_sports_engine.league_packs.basketball import simulate_basketball
+from universal_sports_engine.league_packs.common import LeagueIdentity
+from universal_sports_engine.league_packs.football import CONFIGS as FOOTBALL_CONFIGS
+from universal_sports_engine.league_packs.football import simulate_football
+from universal_sports_engine.league_packs.hockey import NHL, simulate_nhl
+
+Simulator = Callable[[int, float, float], GameResult]
+
+
+def league_identities() -> tuple[LeagueIdentity, ...]:
+ """Return every supported league in stable order."""
+
+ basketball = tuple(config.identity for config in BASKETBALL_CONFIGS.values())
+ football = tuple(config.identity for config in FOOTBALL_CONFIGS.values())
+ return (MLB, *basketball, *football, NHL)
+
+
+def league_ids() -> tuple[str, ...]:
+ return tuple(identity.league_id for identity in league_identities())
+
+
+def simulator_for(league: str) -> Simulator:
+ """Resolve a simulator or fail explicitly with the supported set."""
+
+ normalized = league.strip().lower()
+ if normalized == "mlb":
+ return simulate_mlb
+ if normalized in BASKETBALL_CONFIGS:
+ return lambda seed, home, away: simulate_basketball(normalized, seed, home, away)
+ if normalized in FOOTBALL_CONFIGS:
+ return lambda seed, home, away: simulate_football(normalized, seed, home, away)
+ if normalized == "nhl":
+ return simulate_nhl
+ raise UnknownLeagueError(
+ f"Unknown league {league!r}; supported leagues: {', '.join(league_ids())}"
+ )
diff --git a/src/universal_sports_engine/league_packs/rule_packs.py b/src/universal_sports_engine/league_packs/rule_packs.py
new file mode 100644
index 0000000..da65d62
--- /dev/null
+++ b/src/universal_sports_engine/league_packs/rule_packs.py
@@ -0,0 +1,165 @@
+"""Versioned rule-source manifests for supported complete-game flows."""
+
+from __future__ import annotations
+
+from universal_sports_engine.core.rules import Rule, RulePack, validate_rule_pack
+from universal_sports_engine.core.types import UnknownLeagueError
+
+
+def _rule(rule_id: str, description: str, source: str, season: int) -> Rule:
+ return Rule(rule_id, description, source, season)
+
+
+PACKS = {
+ "mlb": RulePack(
+ "mlb",
+ "2026.2",
+ "complete_game_flow_subset",
+ "2026 Official Baseball Rules",
+ (
+ _rule(
+ "game.innings",
+ "Regulation consists of nine innings.",
+ "https://mktg.mlbstatic.com/mlb/official-information/"
+ "2026-official-baseball-rules.pdf",
+ 2026,
+ ),
+ _rule(
+ "extra.runner",
+ "Regular-season extra innings use the configured automatic runner.",
+ "https://mktg.mlbstatic.com/mlb/official-information/"
+ "2026-official-baseball-rules.pdf",
+ 2026,
+ ),
+ ),
+ ),
+ "nba": RulePack(
+ "nba",
+ "2025-26.2",
+ "complete_game_flow_subset",
+ "2025-26 NBA Rulebook",
+ (
+ _rule(
+ "game.length",
+ "Regulation uses four 12-minute periods.",
+ "https://official.nba.com/rulebook/",
+ 2025,
+ ),
+ _rule(
+ "overtime",
+ "Tied regulation games continue through five-minute overtime periods.",
+ "https://official.nba.com/rulebook/",
+ 2025,
+ ),
+ ),
+ ),
+ "wnba": RulePack(
+ "wnba",
+ "2026.2",
+ "complete_game_flow_subset",
+ "2026 WNBA Official Rule Book",
+ (
+ _rule(
+ "game.length",
+ "Regulation uses four 10-minute periods.",
+ "https://www.wnba.com/wnba-rule-book",
+ 2026,
+ ),
+ _rule(
+ "overtime",
+ "Tied regulation games continue through overtime.",
+ "https://www.wnba.com/wnba-rule-book",
+ 2026,
+ ),
+ ),
+ ),
+ "ncaambb": RulePack(
+ "ncaambb",
+ "2025-26.2",
+ "complete_game_flow_subset",
+ "2025-26 NCAA Men's Basketball Rules",
+ (
+ _rule(
+ "game.length",
+ "Regulation uses two 20-minute halves.",
+ "https://www.ncaa.org/sports/2013/11/6/basketball-rules-of-the-game.aspx",
+ 2025,
+ ),
+ _rule(
+ "overtime",
+ "Tied regulation games continue through overtime.",
+ "https://www.ncaa.org/sports/2013/11/6/basketball-rules-of-the-game.aspx",
+ 2025,
+ ),
+ ),
+ ),
+ "nfl": RulePack(
+ "nfl",
+ "2025.2",
+ "complete_game_flow_subset",
+ "2025 NFL Rulebook",
+ (
+ _rule(
+ "game.length",
+ "Regulation uses four 15-minute periods.",
+ "https://operations.nfl.com/rules-officiating/2025-nfl-rulebook",
+ 2025,
+ ),
+ _rule(
+ "overtime.possessions",
+ "Both teams receive an overtime possession opportunity under 2025 rules.",
+ "https://operations.nfl.com/rules-officiating/2025-nfl-rulebook",
+ 2025,
+ ),
+ ),
+ ),
+ "ncaaf": RulePack(
+ "ncaaf",
+ "2025.2",
+ "complete_game_flow_subset",
+ "2025 NCAA Football Rules",
+ (
+ _rule(
+ "game.length",
+ "Regulation uses four periods.",
+ "https://www.ncaa.org/championships/playing-rules/football-playing-rules/",
+ 2025,
+ ),
+ _rule(
+ "overtime",
+ "Tied games use alternating overtime possessions.",
+ "https://www.ncaa.org/championships/playing-rules/football-playing-rules/",
+ 2025,
+ ),
+ ),
+ ),
+ "nhl": RulePack(
+ "nhl",
+ "2025-26.2",
+ "complete_game_flow_subset",
+ "2025-26 NHL Official Rules",
+ (
+ _rule(
+ "game.length",
+ "Regulation uses three 20-minute periods.",
+ "https://media.nhl.com/site/asset/public/ext/2025-26/2025-26Rules.pdf",
+ 2025,
+ ),
+ _rule(
+ "overtime",
+ "Tied regular-season games proceed to overtime and then a shootout.",
+ "https://media.nhl.com/site/asset/public/ext/2025-26/2025-26Rules.pdf",
+ 2025,
+ ),
+ ),
+ ),
+}
+
+
+def rule_pack_for(league: str) -> RulePack:
+ normalized = league.strip().lower()
+ pack = PACKS.get(normalized)
+ if pack is None:
+ raise UnknownLeagueError(f"No rule pack for league: {league!r}")
+ validate_rule_pack(pack)
+ return pack
diff --git a/src/universal_sports_engine/reference.py b/src/universal_sports_engine/reference.py
new file mode 100644
index 0000000..a3d24e9
--- /dev/null
+++ b/src/universal_sports_engine/reference.py
@@ -0,0 +1,26 @@
+"""Transparent provisional league-level reference anchors."""
+
+from __future__ import annotations
+
+from dataclasses import dataclass
+
+
+@dataclass(frozen=True, slots=True)
+class ReferenceAnchor:
+ mean_home_score: float
+ mean_away_score: float
+ total_score_sd: float
+ margin_sd: float
+ tolerance_fraction: float
+ evidence_status: str
+
+
+ANCHORS = {
+ "mlb": ReferenceAnchor(4.55, 4.30, 4.60, 4.40, 0.25, "provisional_reference_anchor"),
+ "nba": ReferenceAnchor(116.0, 113.0, 20.0, 15.0, 0.20, "provisional_reference_anchor"),
+ "wnba": ReferenceAnchor(82.0, 80.0, 17.5, 14.0, 0.22, "provisional_reference_anchor"),
+ "ncaambb": ReferenceAnchor(75.0, 72.0, 16.5, 14.0, 0.22, "provisional_reference_anchor"),
+ "nfl": ReferenceAnchor(23.5, 21.8, 13.7, 14.0, 0.25, "provisional_reference_anchor"),
+ "ncaaf": ReferenceAnchor(29.0, 26.5, 15.7, 18.0, 0.25, "provisional_reference_anchor"),
+ "nhl": ReferenceAnchor(3.20, 2.95, 2.30, 2.40, 0.30, "provisional_reference_anchor"),
+}
diff --git a/src/universal_sports_engine/season.py b/src/universal_sports_engine/season.py
new file mode 100644
index 0000000..fee8ad6
--- /dev/null
+++ b/src/universal_sports_engine/season.py
@@ -0,0 +1,197 @@
+"""Deterministic schedules, standings, seasons, and knockout tournaments."""
+
+from __future__ import annotations
+
+from dataclasses import dataclass
+
+from universal_sports_engine.core.types import GameResult
+from universal_sports_engine.simulation import simulate_scenario
+
+
+@dataclass(frozen=True, slots=True)
+class ScheduledGame:
+ game_id: str
+ home_team_id: str
+ away_team_id: str
+ seed: int
+
+
+@dataclass(frozen=True, slots=True)
+class Standing:
+ team_id: str
+ wins: int
+ losses: int
+ points_for: int
+ points_against: int
+
+
+@dataclass(frozen=True, slots=True)
+class SeasonResult:
+ league: str
+ schedule: tuple[ScheduledGame, ...]
+ games: tuple[GameResult, ...]
+ standings: tuple[Standing, ...]
+
+
+@dataclass(frozen=True, slots=True)
+class TournamentResult:
+ league: str
+ rounds: tuple[tuple[ScheduledGame, ...], ...]
+ games: tuple[GameResult, ...]
+ champion_team_id: str
+
+
+def round_robin_schedule(
+ team_ids: tuple[str, ...],
+ rounds: int,
+ seed: int,
+) -> tuple[ScheduledGame, ...]:
+ """Create a reproducible round-robin schedule using the circle method."""
+
+ if len(team_ids) < 2 or len(set(team_ids)) != len(team_ids):
+ raise ValueError(f"team_ids must contain at least two unique values: {team_ids!r}")
+ if rounds <= 0:
+ raise ValueError(f"rounds must be positive: {rounds}")
+ rotation: tuple[str | None, ...] = team_ids if len(team_ids) % 2 == 0 else (*team_ids, None)
+ games: list[ScheduledGame] = []
+ sequence = 0
+ for repetition in range(rounds):
+ current = rotation
+ for round_index in range(len(current) - 1):
+ half = len(current) // 2
+ left = current[:half]
+ right = tuple(reversed(current[half:]))
+ for pair_index, (first, second) in enumerate(zip(left, right, strict=True)):
+ if first is None or second is None:
+ continue
+ reverse = (round_index + repetition + pair_index) % 2 == 1
+ home, away = (second, first) if reverse else (first, second)
+ games.append(ScheduledGame(f"game-{sequence:05d}", home, away, seed + sequence))
+ sequence += 1
+ current = (current[0], current[-1], *current[1:-1])
+ return tuple(games)
+
+
+def _strength(team_id: str, strengths: tuple[tuple[str, float], ...]) -> float:
+ for candidate_id, value in strengths:
+ if candidate_id == team_id:
+ return value
+ raise KeyError(f"Missing team strength: {team_id}")
+
+
+def _validate_strengths(
+ team_ids: tuple[str, ...],
+ strengths: tuple[tuple[str, float], ...],
+) -> None:
+ strength_ids = tuple(team_id for team_id, _ in strengths)
+ if len(strength_ids) != len(set(strength_ids)):
+ raise ValueError("Team strength IDs must be unique")
+ if set(strength_ids) != set(team_ids):
+ raise ValueError("Team strengths must exactly cover scheduled teams")
+ for team_id, value in strengths:
+ if not 0.25 <= value <= 2.0:
+ raise ValueError(f"Team strength is outside [0.25, 2.0]: {team_id}={value}")
+
+
+def simulate_season(
+ league: str,
+ schedule: tuple[ScheduledGame, ...],
+ strengths: tuple[tuple[str, float], ...],
+) -> SeasonResult:
+ """Simulate a frozen schedule and calculate deterministic standings."""
+
+ if not schedule:
+ raise ValueError("Season schedule must contain at least one game")
+ game_ids = tuple(game.game_id for game in schedule)
+ if len(game_ids) != len(set(game_ids)):
+ raise ValueError("Scheduled game IDs must be unique")
+ if any(game.home_team_id == game.away_team_id for game in schedule):
+ raise ValueError("A team cannot play itself")
+ scheduled_team_ids = tuple(
+ sorted(
+ {
+ team
+ for game in schedule
+ for team in (game.home_team_id, game.away_team_id)
+ }
+ )
+ )
+ _validate_strengths(scheduled_team_ids, strengths)
+ games = tuple(
+ simulate_scenario(
+ league,
+ game.seed,
+ _strength(game.home_team_id, strengths),
+ _strength(game.away_team_id, strengths),
+ )
+ for game in schedule
+ )
+ team_ids = scheduled_team_ids
+ standings: list[Standing] = []
+ for team_id in team_ids:
+ wins = 0
+ points_for = 0
+ points_against = 0
+ for scheduled, result in zip(schedule, games, strict=True):
+ if scheduled.home_team_id == team_id:
+ points_for += result.home_score
+ points_against += result.away_score
+ wins += int(result.home_score > result.away_score)
+ elif scheduled.away_team_id == team_id:
+ points_for += result.away_score
+ points_against += result.home_score
+ wins += int(result.away_score > result.home_score)
+ played = sum(team_id in (game.home_team_id, game.away_team_id) for game in schedule)
+ standings.append(Standing(team_id, wins, played - wins, points_for, points_against))
+ ordered = tuple(
+ sorted(
+ standings,
+ key=lambda row: (
+ -row.wins,
+ -(row.points_for - row.points_against),
+ row.team_id,
+ ),
+ )
+ )
+ return SeasonResult(league, schedule, games, ordered)
+
+
+def simulate_tournament(
+ league: str,
+ team_ids: tuple[str, ...],
+ strengths: tuple[tuple[str, float], ...],
+ seed: int,
+) -> TournamentResult:
+ """Simulate a seeded single-elimination bracket with no hidden reshuffling."""
+
+ if (
+ len(team_ids) < 2
+ or len(team_ids) & (len(team_ids) - 1)
+ or len(set(team_ids)) != len(team_ids)
+ ):
+ raise ValueError(f"team count must be a power of two greater than one: {len(team_ids)}")
+ _validate_strengths(team_ids, strengths)
+ remaining = team_ids
+ rounds: list[tuple[ScheduledGame, ...]] = []
+ all_games: list[GameResult] = []
+ game_index = 0
+ while len(remaining) > 1:
+ scheduled_round: list[ScheduledGame] = []
+ winners: list[str] = []
+ for pair_index in range(0, len(remaining), 2):
+ home = remaining[pair_index]
+ away = remaining[pair_index + 1]
+ scheduled = ScheduledGame(f"tournament-{game_index:05d}", home, away, seed + game_index)
+ result = simulate_scenario(
+ league,
+ scheduled.seed,
+ _strength(home, strengths),
+ _strength(away, strengths),
+ )
+ scheduled_round.append(scheduled)
+ all_games.append(result)
+ winners.append(home if result.home_score > result.away_score else away)
+ game_index += 1
+ rounds.append(tuple(scheduled_round))
+ remaining = tuple(winners)
+ return TournamentResult(league, tuple(rounds), tuple(all_games), remaining[0])
diff --git a/src/universal_sports_engine/simulation.py b/src/universal_sports_engine/simulation.py
new file mode 100644
index 0000000..80a60ee
--- /dev/null
+++ b/src/universal_sports_engine/simulation.py
@@ -0,0 +1,92 @@
+"""Public simulation, batch, and paired counterfactual APIs."""
+
+from __future__ import annotations
+
+import os
+from concurrent.futures import ProcessPoolExecutor
+from dataclasses import dataclass
+
+import __main__
+from universal_sports_engine.core.types import (
+ GameResult,
+ ParallelExecutionUnavailableError,
+)
+from universal_sports_engine.league_packs.registry import simulator_for
+
+
+@dataclass(frozen=True, slots=True)
+class CounterfactualResult:
+ baseline: GameResult
+ intervention: GameResult
+ home_score_delta: int
+ away_score_delta: int
+ shared_seed: int
+
+
+def simulate_scenario(
+ league: str,
+ seed: int,
+ home_strength: float,
+ away_strength: float,
+) -> GameResult:
+ """Simulate one explicit scenario."""
+
+ if seed < 0:
+ raise ValueError(f"seed must be non-negative: {seed}")
+ if not 0.25 <= home_strength <= 2.0 or not 0.25 <= away_strength <= 2.0:
+ raise ValueError(
+ "Strength multipliers must be within [0.25, 2.0]: "
+ f"home={home_strength}, away={away_strength}"
+ )
+ return simulator_for(league)(seed, home_strength, away_strength)
+
+
+def simulate_game(league: str, seed: int) -> GameResult:
+ """Simulate a neutral-strength complete game."""
+
+ return simulate_scenario(league, seed, 1.0, 1.0)
+
+
+def _batch_task(task: tuple[str, int]) -> GameResult:
+ league, seed = task
+ return simulate_game(league, seed)
+
+
+def simulate_many(league: str, games: int, seed: int, workers: int) -> tuple[GameResult, ...]:
+ """Simulate a reproducible batch, optionally across processes."""
+
+ if games <= 0:
+ raise ValueError(f"games must be positive: {games}")
+ if workers <= 0:
+ raise ValueError(f"workers must be positive: {workers}")
+ if workers == 1:
+ return tuple(simulate_game(league, seed + index) for index in range(games))
+ main_file = str(getattr(__main__, "__file__", ""))
+ if os.name == "nt" and (not main_file or main_file.startswith("<")):
+ raise ParallelExecutionUnavailableError(
+ "Windows process workers require an importable __main__ file; "
+ "run through sports-engine, pytest, or a script guarded by "
+ "if __name__ == '__main__'"
+ )
+ tasks = ((league, seed + index) for index in range(games))
+ with ProcessPoolExecutor(max_workers=workers) as executor:
+ return tuple(executor.map(_batch_task, tasks, chunksize=max(1, games // (workers * 4))))
+
+
+def counterfactual_game(
+ league: str,
+ seed: int,
+ home_strength: float,
+ away_strength: float,
+) -> CounterfactualResult:
+ """Compare an intervention with a neutral baseline using shared random labels."""
+
+ baseline = simulate_scenario(league, seed, 1.0, 1.0)
+ intervention = simulate_scenario(league, seed, home_strength, away_strength)
+ return CounterfactualResult(
+ baseline=baseline,
+ intervention=intervention,
+ home_score_delta=intervention.home_score - baseline.home_score,
+ away_score_delta=intervention.away_score - baseline.away_score,
+ shared_seed=seed,
+ )
diff --git a/src/universal_sports_engine/validation.py b/src/universal_sports_engine/validation.py
new file mode 100644
index 0000000..55359cf
--- /dev/null
+++ b/src/universal_sports_engine/validation.py
@@ -0,0 +1,147 @@
+"""Reference-anchor validation and negative controls."""
+
+from __future__ import annotations
+
+import math
+import statistics
+from dataclasses import dataclass
+
+from universal_sports_engine.core.event_log import verify_events
+from universal_sports_engine.core.result_integrity import verify_result
+from universal_sports_engine.league_packs.registry import league_ids
+from universal_sports_engine.reference import ANCHORS
+from universal_sports_engine.simulation import simulate_game, simulate_many, simulate_scenario
+
+
+@dataclass(frozen=True, slots=True)
+class ValidationReport:
+ league: str
+ games: int
+ observed_home_mean: float
+ observed_away_mean: float
+ observed_total_sd: float
+ anchor_total_sd: float
+ total_sd_relative_error: float
+ anchor_home_mean: float
+ anchor_away_mean: float
+ maximum_relative_error: float
+ home_advantage_z_score: float
+ home_advantage_not_materially_reversed: bool
+ status: str
+
+
+def validate_league(league: str, games: int, seed: int, workers: int) -> ValidationReport:
+ """Compare simulations with transparent non-certifying reference anchors."""
+
+ anchor = ANCHORS[league]
+ results = simulate_many(league, games, seed, workers)
+ home_scores = tuple(result.home_score for result in results)
+ away_scores = tuple(result.away_score for result in results)
+ totals = tuple(home + away for home, away in zip(home_scores, away_scores, strict=True))
+ margins = tuple(home - away for home, away in zip(home_scores, away_scores, strict=True))
+ observed_home = statistics.fmean(home_scores)
+ observed_away = statistics.fmean(away_scores)
+ relative_home = abs(observed_home - anchor.mean_home_score) / max(1.0, anchor.mean_home_score)
+ relative_away = abs(observed_away - anchor.mean_away_score) / max(1.0, anchor.mean_away_score)
+ maximum_error = max(relative_home, relative_away)
+ observed_total_sd = statistics.pstdev(totals)
+ total_sd_error = abs(observed_total_sd - anchor.total_score_sd) / anchor.total_score_sd
+ margin_standard_error = statistics.pstdev(margins) / math.sqrt(games)
+ home_advantage_z_score = (
+ (observed_home - observed_away) / margin_standard_error
+ if margin_standard_error > 0
+ else math.inf
+ )
+ home_advantage_not_materially_reversed = home_advantage_z_score >= -1.96
+ status = (
+ anchor.evidence_status
+ if max(maximum_error, total_sd_error) <= anchor.tolerance_fraction
+ and home_advantage_not_materially_reversed
+ else "failed_reference_anchor"
+ )
+ return ValidationReport(
+ league=league,
+ games=games,
+ observed_home_mean=observed_home,
+ observed_away_mean=observed_away,
+ observed_total_sd=observed_total_sd,
+ anchor_total_sd=anchor.total_score_sd,
+ total_sd_relative_error=total_sd_error,
+ anchor_home_mean=anchor.mean_home_score,
+ anchor_away_mean=anchor.mean_away_score,
+ maximum_relative_error=maximum_error,
+ home_advantage_z_score=home_advantage_z_score,
+ home_advantage_not_materially_reversed=home_advantage_not_materially_reversed,
+ status=status,
+ )
+
+
+def validate_all(games: int, seed: int, workers: int) -> tuple[ValidationReport, ...]:
+ return tuple(
+ validate_league(league, games, seed + index * 10_000, workers)
+ for index, league in enumerate(league_ids())
+ )
+
+
+def run_negative_controls(seed: int) -> tuple[tuple[str, bool, str], ...]:
+ """Run deterministic, integrity, independence, and finite-output controls."""
+
+ controls: list[tuple[str, bool, str]] = []
+ for league in league_ids():
+ first = simulate_game(league, seed)
+ second = simulate_game(league, seed)
+ deterministic = first == second
+ controls.append((f"{league}.deterministic_replay", deterministic, "same seed and version"))
+ finite = math.isfinite(first.home_score) and math.isfinite(first.away_score)
+ controls.append((f"{league}.finite_scores", finite, "scores must be finite"))
+ try:
+ verify_events(first.events)
+ integrity = True
+ except RuntimeError:
+ integrity = False
+ controls.append((f"{league}.event_integrity", integrity, "SHA-256 chain verification"))
+ try:
+ verify_result(first)
+ result_integrity = True
+ except RuntimeError:
+ result_integrity = False
+ controls.append(
+ (
+ f"{league}.result_integrity",
+ result_integrity,
+ "complete result envelope hash verification",
+ )
+ )
+ changed = simulate_game(league, seed + 1) != first
+ controls.append((f"{league}.seed_sensitivity", changed, "different seed changes the path"))
+ strong = tuple(
+ simulate_scenario(league, seed + index, 1.25, 1.0).home_score
+ for index in range(64)
+ )
+ weak = tuple(
+ simulate_scenario(league, seed + index, 0.75, 1.0).home_score
+ for index in range(64)
+ )
+ monotonic = statistics.fmean(strong) > statistics.fmean(weak)
+ controls.append(
+ (
+ f"{league}.strength_monotonicity",
+ monotonic,
+ "paired stronger home input must increase mean home score",
+ )
+ )
+ neutral = tuple(simulate_game(league, seed + 1_000 + index) for index in range(512))
+ home_mean = statistics.fmean(result.home_score for result in neutral)
+ away_mean = statistics.fmean(result.away_score for result in neutral)
+ margins = tuple(result.home_score - result.away_score for result in neutral)
+ margin_standard_error = statistics.pstdev(margins) / math.sqrt(len(margins))
+ z_score = (home_mean - away_mean) / margin_standard_error
+ home_advantage = z_score >= -1.96
+ controls.append(
+ (
+ f"{league}.home_advantage_direction",
+ home_advantage,
+ "home advantage must not be statistically materially reversed",
+ )
+ )
+ return tuple(controls)
diff --git a/tests/test_accuracy.py b/tests/test_accuracy.py
new file mode 100644
index 0000000..d11ed9d
--- /dev/null
+++ b/tests/test_accuracy.py
@@ -0,0 +1,72 @@
+from __future__ import annotations
+
+from dataclasses import replace
+from datetime import UTC, datetime, timedelta
+
+import pytest
+
+from universal_sports_engine.accuracy import (
+ HistoricalGame,
+ evaluate_forecasts,
+ forecast_historical_games,
+ validate_chronological_splits,
+ validate_historical_games,
+)
+
+
+def _games() -> tuple[HistoricalGame, ...]:
+ decision = datetime(2025, 1, 1, 12, tzinfo=UTC)
+ return tuple(
+ HistoricalGame(
+ f"game-{index}",
+ "nba",
+ decision + timedelta(days=index),
+ decision + timedelta(days=index, hours=-1),
+ decision + timedelta(days=index, hours=3),
+ 112 + index,
+ 108 + index,
+ 1.0,
+ 1.0,
+ "test",
+ )
+ for index in range(4)
+ )
+
+
+def test_historical_forecast_evaluation_is_reproducible() -> None:
+ games = _games()
+ first = forecast_historical_games(games, 200, 77)
+ second = forecast_historical_games(games, 200, 77)
+ assert first == second
+ report = evaluate_forecasts(games, first)
+ assert report.games == 4
+ assert report.samples_per_game == 200
+ assert 0.0 <= report.home_win_brier <= 1.0
+ assert 0.0 <= report.score_interval_90_coverage <= 1.0
+ assert report.evidence_status == "historical_test_evaluation_not_certification"
+
+
+def test_historical_manifest_rejects_temporal_leakage() -> None:
+ games = _games()
+ leaked = replace(games[0], features_available_at=games[0].decision_time + timedelta(seconds=1))
+ with pytest.raises(ValueError, match="leakage"):
+ validate_historical_games((leaked, *games[1:]))
+
+
+def test_accuracy_report_rejects_non_test_records() -> None:
+ games = _games()
+ forecasts = forecast_historical_games(games, 20, 9)
+ with pytest.raises(ValueError, match="test split"):
+ evaluate_forecasts((replace(games[0], split="train"), *games[1:]), forecasts)
+
+
+def test_split_validator_rejects_overlapping_outcomes() -> None:
+ games = _games()
+ training = replace(
+ games[0],
+ split="train",
+ outcome_time=games[1].decision_time + timedelta(hours=1),
+ )
+ testing = replace(games[1], split="calibration")
+ with pytest.raises(ValueError, match="overlap"):
+ validate_chronological_splits((training, testing))
diff --git a/tests/test_analytical.py b/tests/test_analytical.py
new file mode 100644
index 0000000..e0dc043
--- /dev/null
+++ b/tests/test_analytical.py
@@ -0,0 +1,31 @@
+from __future__ import annotations
+
+import statistics
+
+import pytest
+
+from universal_sports_engine.analytical import simulate_analytical, simulate_many_analytical
+from universal_sports_engine.core.types import UnknownLeagueError
+from universal_sports_engine.league_packs.registry import league_ids
+from universal_sports_engine.reference import ANCHORS
+
+
+@pytest.mark.parametrize("league", league_ids())
+def test_analytical_path_is_deterministic_and_tracks_reference_moments(league: str) -> None:
+ first = simulate_many_analytical(league, 2_000, 44_000, 1.0, 1.0)
+ second = simulate_many_analytical(league, 2_000, 44_000, 1.0, 1.0)
+ assert first == second
+ anchor = ANCHORS[league]
+ home_mean = statistics.fmean(result.home_score for result in first)
+ away_mean = statistics.fmean(result.away_score for result in first)
+ assert abs(home_mean - anchor.mean_home_score) / anchor.mean_home_score < 0.08
+ assert abs(away_mean - anchor.mean_away_score) / anchor.mean_away_score < 0.08
+
+
+def test_analytical_path_rejects_invalid_inputs() -> None:
+ with pytest.raises(UnknownLeagueError):
+ simulate_analytical("missing", 1, 1.0, 1.0)
+ with pytest.raises(ValueError, match="non-negative"):
+ simulate_analytical("nba", -1, 1.0, 1.0)
+ with pytest.raises(ValueError, match="Strength"):
+ simulate_analytical("nba", 1, 3.0, 1.0)
diff --git a/tests/test_cli.py b/tests/test_cli.py
new file mode 100644
index 0000000..ae0d312
--- /dev/null
+++ b/tests/test_cli.py
@@ -0,0 +1,184 @@
+from __future__ import annotations
+
+import json
+import subprocess
+import sys
+from pathlib import Path
+
+
+def _run(*arguments: str) -> object:
+ completed = subprocess.run(
+ [sys.executable, "-m", "universal_sports_engine.cli", *arguments],
+ check=True,
+ capture_output=True,
+ text=True,
+ )
+ return json.loads(completed.stdout)
+
+
+def test_list_leagues_cli() -> None:
+ output = _run("list-leagues")
+ assert {item["league_id"] for item in output} == {
+ "mlb",
+ "nba",
+ "wnba",
+ "ncaambb",
+ "nfl",
+ "ncaaf",
+ "nhl",
+ }
+
+
+def test_simulate_cli() -> None:
+ output = _run("simulate", "--league", "wnba", "--seed", "123")
+ assert output["league"] == "wnba"
+ assert output["event_count"] > 0
+
+
+def test_simulate_fast_cli() -> None:
+ output = _run(
+ "simulate-fast",
+ "--league",
+ "nba",
+ "--seed",
+ "123",
+ "--home-strength",
+ "1.0",
+ "--away-strength",
+ "1.0",
+ )
+ assert output["league"] == "nba"
+ assert output["fidelity"] == "F0_ANALYTICAL"
+
+
+def test_export_and_verify_replay_cli(tmp_path) -> None:
+ replay_path = tmp_path / "game.json"
+ created = _run("simulate", "--league", "nfl", "--seed", "9", "--export", str(replay_path))
+ verified = _run("verify-replay", "--path", str(replay_path))
+ assert created == verified
+
+
+def test_simulate_season_cli() -> None:
+ output = _run(
+ "simulate-season",
+ "--league",
+ "wnba",
+ "--teams",
+ "4",
+ "--rounds",
+ "1",
+ "--seed",
+ "9",
+ )
+ assert output["games"] == 6
+ assert len(output["standings"]) == 4
+
+
+def test_evaluate_historical_cli(tmp_path) -> None:
+ csv_path = tmp_path / "historical.csv"
+ csv_path.write_text(
+ "game_id,league,decision_time,features_available_at,outcome_time,"
+ "home_score,away_score,home_strength,away_strength,split\n"
+ "g1,nhl,2025-01-01T12:00:00+00:00,2025-01-01T11:00:00+00:00,"
+ "2025-01-01T15:00:00+00:00,3,2,1.0,1.0,test\n",
+ encoding="utf-8",
+ )
+ output = _run(
+ "evaluate-historical",
+ "--csv",
+ str(csv_path),
+ "--samples",
+ "100",
+ "--seed",
+ "7",
+ )
+ assert output["games"] == 1
+ assert output["evidence_status"] == "historical_test_evaluation_not_certification"
+
+
+def test_windows_interactive_parallelism_fails_with_actionable_error() -> None:
+ if sys.platform != "win32":
+ return
+ completed = subprocess.run(
+ [
+ sys.executable,
+ "-c",
+ "from universal_sports_engine.simulation import simulate_many; "
+ "simulate_many('nba', 2, 1, 2)",
+ ],
+ check=False,
+ capture_output=True,
+ text=True,
+ )
+ assert completed.returncode != 0
+ assert "importable __main__ file" in completed.stderr
+
+
+def test_auto_improve_and_adaptive_simulation_cli(tmp_path: Path) -> None:
+ csv_path = tmp_path / "autonomy.csv"
+ rows = [
+ "game_id,league,decision_time,features_available_at,outcome_time,"
+ "home_score,away_score,home_strength,away_strength,split"
+ ]
+ for index in range(8):
+ day = index + 1
+ split = "train" if index < 4 else "calibration"
+ rows.append(
+ f"g{index},nhl,2025-01-{day:02d}T12:00:00+00:00,"
+ f"2025-01-{day:02d}T11:00:00+00:00,"
+ f"2025-01-{day:02d}T15:00:00+00:00,3,2,1.0,1.0,{split}"
+ )
+ csv_path.write_text("\n".join(rows) + "\n", encoding="utf-8")
+ config_path = tmp_path / "config.json"
+ config_path.write_text(
+ json.dumps(
+ {
+ "brier_weight": 2.0,
+ "coverage_weight": 1.0,
+ "drift_threshold": 1.0,
+ "elite_count": 2,
+ "experts_per_ensemble": 2,
+ "generations": 1,
+ "interval_learning_rate": 0.04,
+ "long_decay": 0.03,
+ "maximum_brier_deterioration": 0.1,
+ "maximum_coverage_error_deterioration": 0.1,
+ "minimum_calibration_games": 4,
+ "minimum_drift_observations": 10,
+ "minimum_relative_improvement": 0.0,
+ "minimum_train_games": 4,
+ "mutation_scale": 0.1,
+ "online_learning_rate": 0.2,
+ "population_size": 4,
+ "seed": 7,
+ "short_decay": 0.2,
+ "target_coverage": 0.9,
+ }
+ ),
+ encoding="utf-8",
+ )
+ artifacts = tmp_path / "artifacts"
+ improved = _run(
+ "auto-improve",
+ "--csv",
+ str(csv_path),
+ "--config",
+ str(config_path),
+ "--output",
+ str(artifacts),
+ )
+ assert improved["champions"][0]["league"] == "nhl"
+ adaptive = _run(
+ "simulate-adaptive",
+ "--bundle",
+ str(artifacts / "champion_bundle.json"),
+ "--league",
+ "nhl",
+ "--seed",
+ "12",
+ "--home-strength",
+ "1.0",
+ "--away-strength",
+ "1.0",
+ )
+ assert adaptive["fidelity"] == "F0_ADAPTIVE_ENSEMBLE"
diff --git a/tests/test_core.py b/tests/test_core.py
new file mode 100644
index 0000000..b9f8d24
--- /dev/null
+++ b/tests/test_core.py
@@ -0,0 +1,138 @@
+from __future__ import annotations
+
+import json
+from dataclasses import replace
+
+import pytest
+
+from universal_sports_engine import __version__
+from universal_sports_engine.core.event_log import append_event, chain_drafts, replay, verify_events
+from universal_sports_engine.core.fidelity import (
+ Fidelity,
+ FidelityRequest,
+ FidelityUnavailableError,
+ route_fidelity,
+)
+from universal_sports_engine.core.replay_io import result_from_json, result_to_json
+from universal_sports_engine.core.rng import choice, normal, unit
+from universal_sports_engine.core.types import (
+ EventDraft,
+ EventIntegrityError,
+ Phase,
+ WorldState,
+ payload,
+ payload_get,
+)
+from universal_sports_engine.league_packs.common import ENGINE_VERSION
+from universal_sports_engine.simulation import simulate_game
+
+
+def test_random_draws_are_label_addressed_and_repeatable() -> None:
+ first = unit(42, "game", 1, "shot")
+ assert first == unit(42, "game", 1, "shot")
+ assert first != unit(42, "game", 2, "shot")
+ assert choice(42, (0.2, 0.8), "choice") in (0, 1)
+ assert normal(42, 5.0, 2.0, "normal") == normal(42, 5.0, 2.0, "normal")
+
+
+def test_package_and_evidence_versions_match() -> None:
+ assert __version__ == ENGINE_VERSION == "0.3.0"
+
+
+def test_rng_rejects_invalid_inputs() -> None:
+ with pytest.raises(ValueError, match="non-empty"):
+ choice(1, (), "invalid")
+ with pytest.raises(ValueError, match="non-negative"):
+ choice(1, (1.0, -1.0), "invalid")
+ with pytest.raises(ValueError, match="non-negative"):
+ normal(1, 0.0, -1.0, "invalid")
+
+
+def test_unit_draw_is_always_half_open() -> None:
+ draws = tuple(unit(99, "draw", index) for index in range(10_000))
+ assert all(0.0 <= draw < 1.0 for draw in draws)
+
+
+def test_event_chain_verifies_and_detects_tampering() -> None:
+ events = append_event(
+ (),
+ EventDraft(10, Phase.APPLY, "increment", "system", payload(amount=2)),
+ )
+ events = append_event(
+ events,
+ EventDraft(20, Phase.PUBLISH, "complete", "system", payload(done=True)),
+ )
+ verify_events(events)
+ tampered = (replace(events[0], event_hash="f" * 64), events[1])
+ with pytest.raises(EventIntegrityError, match="hash mismatch"):
+ verify_events(tampered)
+
+
+def test_replay_uses_a_pure_reducer() -> None:
+ events = append_event(
+ (),
+ EventDraft(10, Phase.APPLY, "increment", "system", payload(amount=2)),
+ )
+ initial = WorldState(0, 0, payload(total=1))
+
+ def reducer(state: WorldState, event) -> WorldState:
+ total = int(payload_get(state.values, "total"))
+ amount = int(payload_get(event.payload, "amount"))
+ return WorldState(event.sequence + 1, event.clock_ms, payload(total=total + amount))
+
+ final = replay(initial, events, reducer)
+ assert payload_get(initial.values, "total") == 1
+ assert payload_get(final.values, "total") == 3
+
+
+def test_portable_result_round_trip_verifies_hash_chain() -> None:
+ result = simulate_game("mlb", 104)
+ assert result_from_json(result_to_json(result)) == result
+
+
+def test_portable_result_rejects_score_tampering() -> None:
+ result = simulate_game("mlb", 104)
+ body = json.loads(result_to_json(result))
+ body["home_score"] += 1
+ with pytest.raises(EventIntegrityError, match="Result hash mismatch"):
+ result_from_json(json.dumps(body))
+
+
+def test_fidelity_router_fails_closed_above_supported_level() -> None:
+ event_request = FidelityRequest(True, False, False)
+ assert route_fidelity(event_request, Fidelity.EVENT).selected is Fidelity.EVENT
+ spatial_request = FidelityRequest(True, True, False)
+ with pytest.raises(FidelityUnavailableError, match="exceeds"):
+ route_fidelity(spatial_request, Fidelity.EVENT)
+
+
+def test_event_builder_rejects_clock_and_phase_regressions() -> None:
+ with pytest.raises(ValueError, match="clock regressed"):
+ chain_drafts(
+ (
+ EventDraft(10, Phase.APPLY, "first", "system", payload(value=1)),
+ EventDraft(9, Phase.APPLY, "second", "system", payload(value=2)),
+ )
+ )
+ with pytest.raises(ValueError, match="phase regressed"):
+ chain_drafts(
+ (
+ EventDraft(10, Phase.PUBLISH, "first", "system", payload(value=1)),
+ EventDraft(10, Phase.APPLY, "second", "system", payload(value=2)),
+ )
+ )
+
+
+def test_event_builder_rejects_nonfinite_payload() -> None:
+ with pytest.raises(ValueError, match="finite"):
+ chain_drafts(
+ (
+ EventDraft(
+ 0,
+ Phase.APPLY,
+ "invalid",
+ "system",
+ payload(value=float("nan")),
+ ),
+ )
+ )
diff --git a/tests/test_dummy_bridge.py b/tests/test_dummy_bridge.py
new file mode 100644
index 0000000..ee2095f
--- /dev/null
+++ b/tests/test_dummy_bridge.py
@@ -0,0 +1,17 @@
+from __future__ import annotations
+
+from universal_sports_engine.dummy_bridge.contracts import evidence_from_result, generic_fixture
+from universal_sports_engine.simulation import simulate_game
+
+
+def test_generic_fixture_contains_no_sports_semantics() -> None:
+ state, action, observation = generic_fixture(8)
+ serialized = repr((state, action, observation)).lower()
+ prohibited = ("league", "player", "ball", "puck", "possession", "wager")
+ assert not any(term in serialized for term in prohibited)
+
+
+def test_evidence_preserves_provisional_boundary() -> None:
+ evidence = evidence_from_result(simulate_game("nhl", 8))
+ assert evidence.validation_tier == "provisional_reference_anchor"
+ assert any("No licensed point-in-time" in limitation for limitation in evidence.limitations)
diff --git a/tests/test_leagues.py b/tests/test_leagues.py
new file mode 100644
index 0000000..c1d6b36
--- /dev/null
+++ b/tests/test_leagues.py
@@ -0,0 +1,64 @@
+from __future__ import annotations
+
+import pytest
+
+from universal_sports_engine.core.event_log import verify_events
+from universal_sports_engine.core.types import UnknownLeagueError, payload_get
+from universal_sports_engine.league_packs.registry import league_ids
+from universal_sports_engine.league_packs.rule_packs import rule_pack_for
+from universal_sports_engine.simulation import (
+ counterfactual_game,
+ simulate_game,
+ simulate_many,
+ simulate_scenario,
+)
+
+
+@pytest.mark.parametrize("league", league_ids())
+def test_every_league_completes_with_replayable_events(league: str) -> None:
+ result = simulate_game(league, 17)
+ assert result.league == league
+ assert result.home_score >= 0
+ assert result.away_score >= 0
+ assert result.events
+ verify_events(result.events)
+ assert payload_get(result.metadata, "validation_tier") == "provisional_reference_anchor"
+
+
+@pytest.mark.parametrize("league", league_ids())
+def test_every_league_is_exactly_deterministic(league: str) -> None:
+ assert simulate_game(league, 2718) == simulate_game(league, 2718)
+
+
+@pytest.mark.parametrize("league", league_ids())
+def test_every_league_has_a_valid_versioned_rule_pack(league: str) -> None:
+ pack = rule_pack_for(league)
+ assert pack.league == league
+ assert pack.rules
+ assert pack.coverage_status == "complete_game_flow_subset"
+ assert pack.source_version
+
+
+def test_unknown_league_fails_explicitly() -> None:
+ with pytest.raises(UnknownLeagueError, match="supported leagues"):
+ simulate_game("unknown", 1)
+
+
+def test_invalid_scenario_fails_explicitly() -> None:
+ with pytest.raises(ValueError, match="non-negative"):
+ simulate_scenario("nba", -1, 1.0, 1.0)
+ with pytest.raises(ValueError, match="Strength"):
+ simulate_scenario("nba", 1, 3.0, 1.0)
+
+
+def test_batch_is_stable_across_worker_counts() -> None:
+ sequential = simulate_many("nba", 6, 100, 1)
+ parallel = simulate_many("nba", 6, 100, 2)
+ assert parallel == sequential
+
+
+def test_counterfactual_preserves_seed_and_baseline() -> None:
+ paired = counterfactual_game("nfl", 99, 1.2, 0.8)
+ assert paired.shared_seed == 99
+ assert paired.baseline == simulate_game("nfl", 99)
+ assert paired.intervention.seed == paired.baseline.seed
diff --git a/tests/test_recursive_improvement.py b/tests/test_recursive_improvement.py
new file mode 100644
index 0000000..a99a2ef
--- /dev/null
+++ b/tests/test_recursive_improvement.py
@@ -0,0 +1,183 @@
+from __future__ import annotations
+
+import json
+from dataclasses import replace
+from datetime import UTC, datetime, timedelta
+
+import pytest
+
+from universal_sports_engine.accuracy import HistoricalGame
+from universal_sports_engine.adaptive import (
+ create_adaptive_state,
+ create_ensemble,
+ create_profile,
+ reference_profile,
+ sample_profile_scores,
+ update_adaptive_state,
+)
+from universal_sports_engine.analytical import simulate_ensemble_analytical
+from universal_sports_engine.autotune import (
+ TuningConfig,
+ champion_for,
+ create_champion_bundle,
+ read_champion_bundle,
+ rollback_champion,
+ tune_league,
+ verify_improvement_ledger,
+ write_improvement_artifacts,
+)
+from universal_sports_engine.reference import ANCHORS
+
+
+def _config() -> TuningConfig:
+ return TuningConfig(
+ 3,
+ 10,
+ 3,
+ 4,
+ 0.18,
+ 24,
+ 16,
+ 0.0,
+ 0.03,
+ 0.08,
+ 2.0,
+ 1.0,
+ 0.35,
+ 0.04,
+ 0.90,
+ 0.20,
+ 0.03,
+ 0.50,
+ 20,
+ 77,
+ )
+
+
+def _synthetic_games() -> tuple[HistoricalGame, ...]:
+ anchor = ANCHORS["nba"]
+ target = create_profile(
+ "nba",
+ anchor.mean_home_score * 0.84,
+ anchor.mean_away_score * 0.86,
+ anchor.total_score_sd * 0.72,
+ anchor.margin_sd * 0.78,
+ 1.18,
+ 0.91,
+ 1,
+ reference_profile("nba").profile_hash,
+ "synthetic_test_target",
+ )
+ start = datetime(2024, 1, 1, 12, tzinfo=UTC)
+ games: list[HistoricalGame] = []
+ for index in range(48):
+ split = "train" if index < 30 else "calibration"
+ decision = start + timedelta(days=index)
+ home_strength = 0.80 + (index % 9) * 0.05
+ away_strength = 0.82 + (index % 7) * 0.05
+ home_score, away_score = sample_profile_scores(
+ target,
+ 9_000 + index,
+ home_strength,
+ away_strength,
+ )
+ games.append(
+ HistoricalGame(
+ f"nba-synthetic-{index:03d}",
+ "nba",
+ decision,
+ decision - timedelta(hours=1),
+ decision + timedelta(hours=3),
+ home_score,
+ away_score,
+ home_strength,
+ away_strength,
+ split,
+ )
+ )
+ return tuple(games)
+
+
+def test_recursive_tuning_is_deterministic_and_checkpointed(tmp_path) -> None:
+ games = _synthetic_games()
+ first = tune_league("nba", games, _config())
+ second = tune_league("nba", games, _config())
+ assert first == second
+ assert len(first.generations) == 3
+ assert first.selected_state.observations == 18
+ bundle = create_champion_bundle(
+ (first,),
+ "test-recursive-v1",
+ max(game.outcome_time for game in games).isoformat(),
+ )
+ artifacts = tmp_path / "artifacts"
+ write_improvement_artifacts(artifacts, (first,), bundle, _config())
+ path = artifacts / "champion_bundle.json"
+ loaded = read_champion_bundle(path)
+ assert loaded == bundle
+ assert (
+ verify_improvement_ledger(
+ artifacts / "improvement_ledger.jsonl",
+ bundle.bundle_hash,
+ )
+ == 1
+ )
+ champion = champion_for(loaded, "nba")
+ result = simulate_ensemble_analytical(champion.ensemble, champion.state, 12, 1.0, 1.0)
+ assert result.ensemble_hash == champion.ensemble.ensemble_hash
+ rolled_back = rollback_champion(loaded, "nba", "2025-01-01T00:00:00+00:00")
+ restored = champion_for(rolled_back, "nba")
+ assert restored.ensemble == champion.rollback_ensemble
+ assert restored.state == champion.rollback_state
+ ledger_path = artifacts / "improvement_ledger.jsonl"
+ record = json.loads(ledger_path.read_text(encoding="utf-8"))
+ record["decision"] = "tampered"
+ ledger_path.write_text(json.dumps(record) + "\n", encoding="utf-8")
+ with pytest.raises(ValueError, match="record hash mismatch"):
+ verify_improvement_ledger(ledger_path, bundle.bundle_hash)
+
+
+def test_online_weights_reward_the_better_expert() -> None:
+ anchor = ANCHORS["nba"]
+ good = create_profile(
+ "nba",
+ anchor.mean_home_score * 0.82,
+ anchor.mean_away_score * 0.83,
+ anchor.total_score_sd * 0.75,
+ anchor.margin_sd * 0.80,
+ 1.0,
+ 1.0,
+ 1,
+ reference_profile("nba").profile_hash,
+ "synthetic_good",
+ )
+ bad = reference_profile("nba")
+ ensemble = create_ensemble("nba", (good, bad), (0.5, 0.5), "synthetic_ensemble")
+ state = create_adaptive_state(ensemble, 0.4, 0.04, 0.90, 0.20, 0.03, 1.0, 20)
+ for index in range(40):
+ home_score, away_score = sample_profile_scores(good, 20_000 + index, 1.0, 1.0)
+ state, _ = update_adaptive_state(
+ state,
+ ensemble,
+ 1.0,
+ 1.0,
+ home_score,
+ away_score,
+ 2.0,
+ )
+ assert state.weights[0] > state.weights[1]
+ assert state.observations == 40
+
+
+def test_adaptive_simulation_fails_closed_on_drift() -> None:
+ profile = reference_profile("nhl")
+ ensemble = create_ensemble("nhl", (profile,), (1.0,), "test")
+ state = create_adaptive_state(ensemble, 0.2, 0.04, 0.90, 0.20, 0.03, 0.10, 4)
+ drifted = replace(state, status="drift_alert")
+ with pytest.raises(ValueError, match="content hash mismatch"):
+ simulate_ensemble_analytical(ensemble, drifted, 1, 1.0, 1.0)
+
+
+def test_tuning_rejects_insufficient_chronological_evidence() -> None:
+ with pytest.raises(ValueError, match="Insufficient chronological training"):
+ tune_league("nba", _synthetic_games()[:10], _config())
diff --git a/tests/test_season.py b/tests/test_season.py
new file mode 100644
index 0000000..4099a34
--- /dev/null
+++ b/tests/test_season.py
@@ -0,0 +1,42 @@
+from __future__ import annotations
+
+import pytest
+
+from universal_sports_engine.season import (
+ round_robin_schedule,
+ simulate_season,
+ simulate_tournament,
+)
+
+
+def test_round_robin_and_standings_are_reproducible() -> None:
+ teams = ("alpha", "beta", "gamma", "delta")
+ strengths = tuple((team, 1.0) for team in teams)
+ schedule = round_robin_schedule(teams, 2, 55)
+ assert len(schedule) == 12
+ first = simulate_season("ncaambb", schedule, strengths)
+ second = simulate_season("ncaambb", schedule, strengths)
+ assert first == second
+ assert sum(row.wins for row in first.standings) == len(schedule)
+ assert sum(row.losses for row in first.standings) == len(schedule)
+
+
+def test_knockout_tournament_returns_one_champion() -> None:
+ teams = ("alpha", "beta", "gamma", "delta")
+ strengths = tuple((team, 1.0) for team in teams)
+ result = simulate_tournament("nhl", teams, strengths, 91)
+ assert result.champion_team_id in teams
+ assert len(result.games) == 3
+ assert tuple(len(round_games) for round_games in result.rounds) == (2, 1)
+
+
+def test_invalid_season_inputs_fail_explicitly() -> None:
+ with pytest.raises(ValueError, match="unique"):
+ round_robin_schedule(("same", "same"), 1, 1)
+ with pytest.raises(ValueError, match="power of two"):
+ simulate_tournament("nba", ("one", "two", "three"), (), 1)
+ with pytest.raises(ValueError, match="at least one"):
+ simulate_season("nba", (), ())
+ schedule = round_robin_schedule(("one", "two"), 1, 1)
+ with pytest.raises(ValueError, match="exactly cover"):
+ simulate_season("nba", schedule, (("one", 1.0),))
diff --git a/tests/test_validation.py b/tests/test_validation.py
new file mode 100644
index 0000000..8b3eb16
--- /dev/null
+++ b/tests/test_validation.py
@@ -0,0 +1,16 @@
+from __future__ import annotations
+
+from universal_sports_engine.league_packs.registry import league_ids
+from universal_sports_engine.validation import run_negative_controls, validate_all
+
+
+def test_all_reference_anchor_validations_are_honestly_provisional() -> None:
+ reports = validate_all(500, 700, 1)
+ assert tuple(report.league for report in reports) == league_ids()
+ assert all(report.status == "provisional_reference_anchor" for report in reports)
+
+
+def test_negative_controls_pass() -> None:
+ controls = run_negative_controls(2026)
+ failures = tuple(control for control in controls if not control[1])
+ assert not failures, failures
From 2b3e585830c2fe9c119305c77a71e6c0a8af2cca Mon Sep 17 00:00:00 2001
From: christopher harris <283105756+cjharriskc-ai@users.noreply.github.com>
Date: Sat, 18 Jul 2026 02:49:11 -0500
Subject: [PATCH 2/2] Add remote quality verification
---
.github/workflows/quality.yml | 54 ++++++++++++++++++++++++++++
reports/PERFORMANCE_BENCHMARK.json | 56 +++++++++++++++---------------
reports/RELEASE_EVIDENCE.md | 30 ++++++++--------
reports/RELEASE_MANIFEST.json | 12 +++++--
scripts/build_release_evidence.py | 1 +
5 files changed, 108 insertions(+), 45 deletions(-)
create mode 100644 .github/workflows/quality.yml
diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml
new file mode 100644
index 0000000..55961fc
--- /dev/null
+++ b/.github/workflows/quality.yml
@@ -0,0 +1,54 @@
+name: Quality
+
+on:
+ pull_request:
+ push:
+ branches:
+ - main
+
+permissions:
+ contents: read
+
+concurrency:
+ group: quality-${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+jobs:
+ verify:
+ name: Python 3.12 verification
+ runs-on: ubuntu-latest
+ timeout-minutes: 15
+
+ steps:
+ - name: Check out source
+ uses: actions/checkout@v4
+
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: "3.12"
+ cache: pip
+
+ - name: Install project
+ run: python -m pip install --upgrade pip && python -m pip install -e ".[dev]"
+
+ - name: Lint
+ run: python -m ruff check .
+
+ - name: Type-check
+ run: python -m mypy src scripts
+
+ - name: Test
+ run: python -m pytest -q
+
+ - name: Build wheel
+ run: python -m pip wheel . --no-deps --wheel-dir dist
+
+ - name: Verify release gates
+ run: >-
+ python scripts/build_release_evidence.py
+ --games 500
+ --benchmark-games 100
+ --seed 20260718
+ --workers 2
+ --output "${{ runner.temp }}/release-evidence"
diff --git a/reports/PERFORMANCE_BENCHMARK.json b/reports/PERFORMANCE_BENCHMARK.json
index c305dee..b6517b8 100644
--- a/reports/PERFORMANCE_BENCHMARK.json
+++ b/reports/PERFORMANCE_BENCHMARK.json
@@ -1,134 +1,134 @@
[
{
- "elapsed_seconds": 0.13574239998706616,
+ "elapsed_seconds": 0.12223709997488186,
"events": 0,
"fidelity": "F0_ANALYTICAL",
"games": 10000,
- "games_per_second": 73668.94942886542,
+ "games_per_second": 81808.22354305584,
"league": "mlb",
"results": 10000,
"workers": 1
},
{
- "elapsed_seconds": 0.3407911999966018,
+ "elapsed_seconds": 0.3034494000021368,
"events": 8830,
"fidelity": "F1_EVENT",
"games": 100,
- "games_per_second": 293.43480700498475,
+ "games_per_second": 329.5442337315408,
"league": "mlb",
"workers": 2
},
{
- "elapsed_seconds": 0.14295050001237541,
+ "elapsed_seconds": 0.08154599997214973,
"events": 0,
"fidelity": "F0_ANALYTICAL",
"games": 10000,
- "games_per_second": 69954.28486877825,
+ "games_per_second": 122630.17196938272,
"league": "nba",
"results": 10000,
"workers": 1
},
{
- "elapsed_seconds": 0.4545626000035554,
+ "elapsed_seconds": 0.41247360000852495,
"events": 19954,
"fidelity": "F1_EVENT",
"games": 100,
- "games_per_second": 219.99170191128314,
+ "games_per_second": 242.43975856378012,
"league": "nba",
"workers": 2
},
{
- "elapsed_seconds": 0.15859930001897737,
+ "elapsed_seconds": 0.13489250000566244,
"events": 0,
"fidelity": "F0_ANALYTICAL",
"games": 10000,
- "games_per_second": 63051.980675850646,
+ "games_per_second": 74133.10598869638,
"league": "wnba",
"results": 10000,
"workers": 1
},
{
- "elapsed_seconds": 0.45809050000389107,
+ "elapsed_seconds": 0.3936280999914743,
"events": 16098,
"fidelity": "F1_EVENT",
"games": 100,
- "games_per_second": 218.2974761518752,
+ "games_per_second": 254.0469036691383,
"league": "wnba",
"workers": 2
},
{
- "elapsed_seconds": 0.17294249997939914,
+ "elapsed_seconds": 0.15269150002859533,
"events": 0,
"fidelity": "F0_ANALYTICAL",
"games": 10000,
- "games_per_second": 57822.68673802678,
+ "games_per_second": 65491.530295578,
"league": "ncaambb",
"results": 10000,
"workers": 1
},
{
- "elapsed_seconds": 0.3960789999982808,
+ "elapsed_seconds": 0.34768939996138215,
"events": 13938,
"fidelity": "F1_EVENT",
"games": 100,
- "games_per_second": 252.47488506190447,
+ "games_per_second": 287.6130247603378,
"league": "ncaambb",
"workers": 2
},
{
- "elapsed_seconds": 0.1276167999894824,
+ "elapsed_seconds": 0.13669269997626543,
"events": 0,
"fidelity": "F0_ANALYTICAL",
"games": 10000,
- "games_per_second": 78359.58902608557,
+ "games_per_second": 73156.79624249389,
"league": "nfl",
"results": 10000,
"workers": 1
},
{
- "elapsed_seconds": 0.40035370000987314,
+ "elapsed_seconds": 0.37054779997561127,
"events": 16529,
"fidelity": "F1_EVENT",
"games": 100,
- "games_per_second": 249.7791327956602,
+ "games_per_second": 269.8707157526824,
"league": "nfl",
"workers": 2
},
{
- "elapsed_seconds": 0.17455659998813644,
+ "elapsed_seconds": 0.09823079995112494,
"events": 0,
"fidelity": "F0_ANALYTICAL",
"games": 10000,
- "games_per_second": 57288.00859251177,
+ "games_per_second": 101801.06448258116,
"league": "ncaaf",
"results": 10000,
"workers": 1
},
{
- "elapsed_seconds": 0.42027029997552745,
+ "elapsed_seconds": 0.4321784999920055,
"events": 17952,
"fidelity": "F1_EVENT",
"games": 100,
- "games_per_second": 237.94210536843323,
+ "games_per_second": 231.3858741280508,
"league": "ncaaf",
"workers": 2
},
{
- "elapsed_seconds": 0.1503820999932941,
+ "elapsed_seconds": 0.14026539999758825,
"events": 0,
"fidelity": "F0_ANALYTICAL",
"games": 10000,
- "games_per_second": 66497.27594205643,
+ "games_per_second": 71293.41947602147,
"league": "nhl",
"results": 10000,
"workers": 1
},
{
- "elapsed_seconds": 0.3056190999923274,
+ "elapsed_seconds": 0.2912550999899395,
"events": 6583,
"fidelity": "F1_EVENT",
"games": 100,
- "games_per_second": 327.20468060572955,
+ "games_per_second": 343.341627334437,
"league": "nhl",
"workers": 2
}
diff --git a/reports/RELEASE_EVIDENCE.md b/reports/RELEASE_EVIDENCE.md
index eca2af5..24ca359 100644
--- a/reports/RELEASE_EVIDENCE.md
+++ b/reports/RELEASE_EVIDENCE.md
@@ -30,24 +30,24 @@ event or tracking dataset was available.
| Fidelity | League | Games | Events | Seconds | Games/second |
|---|---|---:|---:|---:|---:|
-| F0_ANALYTICAL | mlb | 10000 | 0 | 0.136 | 73668.95 |
-| F1_EVENT | mlb | 100 | 8830 | 0.341 | 293.43 |
-| F0_ANALYTICAL | nba | 10000 | 0 | 0.143 | 69954.28 |
-| F1_EVENT | nba | 100 | 19954 | 0.455 | 219.99 |
-| F0_ANALYTICAL | wnba | 10000 | 0 | 0.159 | 63051.98 |
-| F1_EVENT | wnba | 100 | 16098 | 0.458 | 218.30 |
-| F0_ANALYTICAL | ncaambb | 10000 | 0 | 0.173 | 57822.69 |
-| F1_EVENT | ncaambb | 100 | 13938 | 0.396 | 252.47 |
-| F0_ANALYTICAL | nfl | 10000 | 0 | 0.128 | 78359.59 |
-| F1_EVENT | nfl | 100 | 16529 | 0.400 | 249.78 |
-| F0_ANALYTICAL | ncaaf | 10000 | 0 | 0.175 | 57288.01 |
-| F1_EVENT | ncaaf | 100 | 17952 | 0.420 | 237.94 |
-| F0_ANALYTICAL | nhl | 10000 | 0 | 0.150 | 66497.28 |
-| F1_EVENT | nhl | 100 | 6583 | 0.306 | 327.20 |
+| F0_ANALYTICAL | mlb | 10000 | 0 | 0.122 | 81808.22 |
+| F1_EVENT | mlb | 100 | 8830 | 0.303 | 329.54 |
+| F0_ANALYTICAL | nba | 10000 | 0 | 0.082 | 122630.17 |
+| F1_EVENT | nba | 100 | 19954 | 0.412 | 242.44 |
+| F0_ANALYTICAL | wnba | 10000 | 0 | 0.135 | 74133.11 |
+| F1_EVENT | wnba | 100 | 16098 | 0.394 | 254.05 |
+| F0_ANALYTICAL | ncaambb | 10000 | 0 | 0.153 | 65491.53 |
+| F1_EVENT | ncaambb | 100 | 13938 | 0.348 | 287.61 |
+| F0_ANALYTICAL | nfl | 10000 | 0 | 0.137 | 73156.80 |
+| F1_EVENT | nfl | 100 | 16529 | 0.371 | 269.87 |
+| F0_ANALYTICAL | ncaaf | 10000 | 0 | 0.098 | 101801.06 |
+| F1_EVENT | ncaaf | 100 | 17952 | 0.432 | 231.39 |
+| F0_ANALYTICAL | nhl | 10000 | 0 | 0.140 | 71293.42 |
+| F1_EVENT | nhl | 100 | 6583 | 0.291 | 343.34 |
## Reproducibility
-- Source manifest SHA-256: `0dcd0dffdb65bae68c3ad1f05ad37b3a1c47bfddbba13423d130c643f00f2165`
+- Source manifest SHA-256: `7de72acb29259942070b5d8c0bd1532e8c6a58a5a5ecce6cf8ef76634175e272`
- Every event stream is invariant-checked and SHA-256 chained during construction.
- External replay imports reverify both the event chain and complete result envelope.
- Same input and seed equality is exercised for every league.
diff --git a/reports/RELEASE_MANIFEST.json b/reports/RELEASE_MANIFEST.json
index 8aa7dd2..6720e5d 100644
--- a/reports/RELEASE_MANIFEST.json
+++ b/reports/RELEASE_MANIFEST.json
@@ -11,6 +11,14 @@
"nhl"
],
"source_files": [
+ [
+ ".github/PULL_REQUEST_TEMPLATE.md",
+ "5b47fed04e57c5d858113040675e621d72265c881fd9680cfec5433c4dd99dd4"
+ ],
+ [
+ ".github/workflows/quality.yml",
+ "5bdb93402626a6ddc4dd0ddee2801c2f2c3f6169333226b10fddb6dbf37a9b6a"
+ ],
[
"data/contracts/HISTORICAL_GAMES.md",
"253328097b260e361eefd368720b4d039ab36a2877eeb027b7acbd04f580c646"
@@ -33,7 +41,7 @@
],
[
"scripts/build_release_evidence.py",
- "0bc7a9d90b507bb7e8585b160cc8d6cbf159ccbc274ef960a0569775dac5375a"
+ "810c664d62d72735a95e5f45a25520e95aa2efd2b7f065fc332f81d2f0ab94e8"
],
[
"src/universal_sports_engine/__init__.py",
@@ -256,5 +264,5 @@
"2b1803c5ac8dcbe3437ea507aa7fc2c926097e0aa28afeb39a6647a36ad105d1"
]
],
- "source_manifest_sha256": "0dcd0dffdb65bae68c3ad1f05ad37b3a1c47bfddbba13423d130c643f00f2165"
+ "source_manifest_sha256": "7de72acb29259942070b5d8c0bd1532e8c6a58a5a5ecce6cf8ef76634175e272"
}
diff --git a/scripts/build_release_evidence.py b/scripts/build_release_evidence.py
index 7ef69a1..1a4381b 100644
--- a/scripts/build_release_evidence.py
+++ b/scripts/build_release_evidence.py
@@ -32,6 +32,7 @@ def _write_json(path: Path, value: object) -> None:
def _source_manifest(root: Path) -> tuple[tuple[str, str], ...]:
allowed_roots = (
+ root / ".github",
root / "src",
root / "tests",
root / "scripts",