Commit Graph

3 Commits

Author SHA1 Message Date
builtbykev f0543b57a4 Product identity + widen books for DISPLAY, model input byte-identical
IDENTITY (CLAUDE.md top + MASTER-PLAN header). VYNDR is a PREDICTIVE MODEL:
it projects what a player will DO and picks accurately. Market edge is a
BYPRODUCT of a good prediction, never the success criterion. Success =
the forecast is honest about its own confidence AND still ranks --
calibration and resolution, both. No edge/CLV term belongs in a pass/fail
gate; they are diagnostics we report, not thresholds a model must clear.
A model tuned to beat a closing line has been fitted to the market instead
of to the game.

Per-sport doctrine (Phillips 2022, classify by what players DO not by
position): each sport is its own model -- own variables, archetypes,
conditions, calibration, honest ceiling. Shared across sports: ONLY the
Bayesian inference math.

Truth Law: no fabricated data; honest-absent over invented; label
limitations in-band; provisional stays provisional until re-run;
documented is not verified.

PHASE 2 -- AGGREGATOR WIDENING (live). normalizeProps now emits every
DISPLAY book instead of 5 of 18. Before this we discarded 13 books of our
own accord and 64.8% of the MLB slate was invisible to users. Every prop
carries book_role (both/takeable/reference/dfs/offshore) so the display
layer can say WHAT a price is -- a fixed-payout DFS number and a two-way
sportsbook price are not interchangeable objects. Unknown books are still
dropped.

PHASE 3 -- MODEL GATE (the model does not move). bookRoles splits
MODEL_BOOKS (the legacy allow-list, character for character) from
DISPLAY_BOOKS. Both model paths re-filter before they pick a line:
gradeSlateService.dedupeProps (before first-row-wins AND before the limit)
and intradayRefreshService.indexOddsProps (which RE-GRADES at the current
line -- without the gate, widening would have silently moved locked lines
onto books the model has never been calibrated against). A test asserts
the graded set is byte-identical through the widening.

CURRENT_RULER_VERSION stays v1_first_book. The gate lifts only when the
MLB calibration is re-run on the consensus ruler and v2 is promoted.

HONEST FRAMING, recorded in the plan: this is an AGGREGATOR win and it
does NOT fix the model. WNBA still abstains -- a model problem, not a
coverage problem; it is better covered than MLB. MLB isotonic still
provisional. The consensus is MARKET, not SHARP: pinnacle, matchbook and
polymarket are 0% on both sports, so no sharp anchor exists in our feed.

Two superseded tests updated to stronger properties rather than deleted:
roleOf now names the KIND of book, and the normalizer test asserts the
display set widens WHILE the model set does not.

Gates: 4,027 tests / 322 suites green; next build exit 0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QJs13VsyiSKYQP6rj3NNmc
2026-08-01 00:50:54 -04:00
builtbykev c38db1ad65 Fix: the incumbent ruler respects the allow-list (correcting my own model)
My first delta run modelled the incumbent as first-row-wins over the RAW
feed and reported that an EXCLUDED book was "the market" on 69% of MLB
prop-lines, with prizepicks alone at 47%. That is WRONG and I caught it
before it went anywhere.

normalizeProps applies ALLOWED_BOOKS BEFORE gradeSlateService.dedupeProps
runs, so DFS books never reach the incumbent. The allow-list, for all the
coverage it costs, does keep DFS out of the ruler.

incumbentFairProb now takes the allow-list (defaulting to the live
ALLOWED_BOOKS) and reproduces the real chain. Two tests lock it, including
that a prop with no admitted book has NO incumbent -- it is never graded
at all, which is the real loss and is already measured as invisible_props.

Overstating the incumbent's badness would have been as dishonest as
understating it, and more persuasive.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QJs13VsyiSKYQP6rj3NNmc
2026-07-31 23:47:13 -04:00
builtbykev a55dd2a6a0 Order Zero Phase 2: three-way book split + challenger consensus ruler
CHALLENGER-FIRST. The live ruler is byte-identical: CURRENT_RULER_VERSION
is still v1_first_book, nothing here writes a cache, a grade or a ledger
row, and no live code path calls consensusRuler yet.

bookRoles.js splits one allow-list into three, because it was answering
two different questions -- "can we show this?" and "can we price against
this?" -- with the same list, which is what bent the ruler.

  TAKEABLE  the user can actually bet here (drives best price / shopping)
  REFERENCE may price the fair-prob ruler; never surfaced as a place to bet
  EXCLUDED  DFS pick'em + offshore, permanently barred from all pricing

Two deliberate calls, both evidence-based:

- The six PropLine-phantom books (caesars/fanatics/bet365/hardrockbet/
  pointsbet/thescore) are KEPT despite the order saying remove. They
  returned zero PropLine quotes, but PropLine is not our only provider and
  the odds-api backup path may carry them. A book that never appears is
  never matched, which costs nothing; deleting them risks silently
  dropping real books on the backup with no upside. Recorded in
  PHANTOM_ON_PROPLINE rather than enacted as a deletion.

- REFERENCE = exchanges + pinnacle + bovada + the four US majors, chosen
  off the measured coverage curve rather than theory. exchange_only is
  cleanest (order-book, ~zero vig) but covers 14.3% of MLB and 5.6% of
  WNBA; adding the US majors gives 28.1% / 46.3%. pinnacle, matchbook and
  polymarket measured 0% on both sports and add nothing. The honest
  limitation is recorded in the config: this is a MARKET consensus, not a
  SHARP one.

consensusRuler.js: median de-vigged fair_prob across >=2 reference books
posting BOTH sides at the SAME line. Median so one stale exchange cannot
drag it. Different lines are never averaged, one-sided quotes never rule,
and n<2 falls back to single-book LABELLED as such with the v1 stamp --
never silently mixed, because a column holding both is two rulers wearing
one name.

The challenger delta runs over the live feed and reports incumbent_book_
roles, which is the real headline: the incumbent is literally first-row-
wins, so it reports what KIND of book has been acting as "the market".
DFS pick'em has the highest coverage in the feed, so a DFS book can be it.

18 ruler tests + 37 total in the two new suites. Full suite 4021 passed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QJs13VsyiSKYQP6rj3NNmc
2026-07-31 23:44:37 -04:00