Salvage v2 engine onto main + wire into Today page - #19
Merged
Conversation
Selectively port the v2 data/model platform from the frontier-enhancements branch onto main's base, deliberately excluding the v2 pages, the st.navigation changes, and the product-surface work. Brings over, from the v2 tip: - src/contracts, src/features, src/markets, src/backtesting, src/decisions, src/catalog, src/quality, src/monitoring, src/labels, src/normalization, src/pipelines (orchestrator + deterministic replay), src/pick6, src/api, src/ui helpers - Manifest-backed training, model registry, calibration, and baselines - Generative plate-appearance model and coherent game simulator (plate_appearance, game_simulator, prop_coherence, pa_outcome_model) - Ingestion lineups/pitcher-availability with real MLB Stats API shapes, raw store, and content-addressed silver archive - Gold artifact publisher (deterministic, fail-closed) + run_gold_publish - Migrations, config contracts, CI workflow, and 102 passing tests Adds pyproject + uv.lock with statsmodels for the legacy pages' lowess trendlines. Legacy pages/predictions/page_utils are untouched. Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
Ignore the v2 lakehouse artifacts (data/bronze, data/silver, data/gold) and the uv cache (.tmp) so regenerated outputs never clutter git status. Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
First engine integration on the salvage branch: the home page's game cards now derive run line and over/under from one coherent joint score distribution anchored to the legacy team-strength moneyline, so all three markets reconcile instead of using separate ad-hoc formulas. - predictions.py: add _coherent_game_distribution(home_prob) which builds an independent-Poisson ScoreDistribution via bisection on the home/away run-rate ratio; run line uses dist.run_line_probabilities(-1.5) and O/U uses dist.total_probabilities(posted) - Fail-closed O/U: missing or unparseable prices now mean no O/U recommendation instead of a fabricated 50/50 implied edge - Fix ESPN odds parsing: totals odds arrive as floats (-106.0); _parse and _parse_american now coerce through float, so real O/U prices are read (previously every totals price failed to parse and showed unavailable) - Update the game-card caption to describe the coherent-distribution method Verified: 102 tests pass; live-feed screenshot shows Over 8.0 at -106 with the engine's coherent probability, moneyline and run line unchanged. Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
Replace the W% logistic moneyline anchor with team-stats-driven run rates, so the moneyline, run line, and totals all fall out of one coherent distribution built from actual per-season runs scored/allowed. - predictions.py: add _team_run_rate() blending a team's RS_per_G offense with the opponent's RA_per_G defense (geometric mean, regressed toward league average); _coherent_game_distribution() now takes the two team names and the standings, builds the Poisson distribution directly, and drops the bisection entirely - The win-probability bar and moneyline now use dist.home_moneyline() instead of _estimate_win_prob; remove the now-dead W% logistic call - Update the card caption to describe the team-stats method Verified: 102 tests pass; live screenshot shows the Cardinals@Cubs card flip from the W%-logistic 73/27 to a team-stats 53/47 with the run line and over/under reconciling to the same distribution. Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
Three runtime errors surfaced when running the app in a browser: - pages/1_Today.py: st.secrets.get() raised StreamlitSecretNotFoundError when no secrets.toml exists, crashing the Today page. Read ODDS_API_KEY from the environment only (.env feeds it via src.ingestion.config). - page_utils.py: _fetch_pitcher_stats returned mixed str/int values, so the Stat/Value dataframe failed pyarrow serialization with ArrowTypeError. Coerce every value to str. - page_utils.py: silence pandas FutureWarnings - add observed=False to groupby calls and include_groups=False to groupby.apply, so a future pandas version does not change behavior or break. Verified: 102 tests pass; the game-context cache builds with -W error::FutureWarning; the Today page renders with zero exceptions. Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
The v2 CI runs ruff format --check and ruff check over the whole tree, but main's legacy pages, scripts, and page_utils were never ruff-conformant, so the PR's CI failed on formatting. - ruff format over src tests scripts predictions.py pages page_utils.py - ruff check --fix: remove unused imports/variables, sort import blocks - Restore the add_betting_oracle_footer re-export in page_utils (used by tests/test_runline_favorite.py) with a noqa so ruff keeps it - Rename ambiguous single-letter variable l -> losses in _fetch_team_standings Verified: ruff check + format clean across the tree, 102 tests pass, mypy clean, deterministic replay passes, compileall clean. Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Selectively ports the v2 data/model engine from the frontier-enhancements experiment onto main, then wires it into the legacy Today page game cards. No v2 pages or navigation changes.
Engine (salvage/v2-core):
Today page wiring:
Verified: 102 tests pass, deterministic replay, live-feed screenshots show coherent card numbers.