Hero ranking fix: rank by champion p_win among takeable, honest empty state

Review Zero found the hero's ACTUAL behavior was worse than "unknown": it ranks
on ev_pct (heroPropService v2), but ev_pct is NULL on served grades and
Number(null)===0 made Number.isFinite(Number(null)) TRUE — so every prop tied at
EV 0 and the "top read" was really the FIRST takeable A/B prop in cache order
(arbitrary, dressed as ranked).

v3: rank by the CHAMPION's p_win (the only signal with a promising, not proven,
edge — its takeable-MLB-over CLV survived the skew audit) among A/B, TAKEABLE-
priced reads (isTakeable band -160..+200, same as the proof/audit). Strict
null guard kills the Number(null)=0 bug. Takeable filter is mandatory (raw p_win
crowns -300 chalk). NO backfill: nothing qualifies → honest empty state
(available:false, reason:'no_qualifying_read'), never a weak recent read.

p_win is RANKING-ONLY, server-side — toHero never exposes it and the route strips
it. Framing unchanged in substance (model number vs book number, grade,
timestamp) — no proven-edge / +EV / best-bet claim, no CLV/ROI/edge number.
Display-only: reads snapshot caches, writes to nothing (no grade/ledger/lock_lines).
Full suite 3852 green, web build exit 0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VsztNChZ7vEvSR61AuMhD1
This commit is contained in:
Kev
2026-07-29 04:43:21 -04:00
parent e7ec501054
commit 41b86e3874
3 changed files with 72 additions and 57 deletions
+7 -7
View File
@@ -7,13 +7,13 @@ import PriceTriplet from './vyndr/PriceTriplet';
/**
* Daily hero prop card (Truth-Everywhere Part 2, item 5).
*
* A live RULE, not a hand-picked example: the graded prop where VYNDR disagrees
* MOST with the market — largest |model - consensus| gap, A/B grades only —
* fetched from /api/hero-prop (which reads the pre-graded snapshot). The card
* shows the disagreement explicitly (the book's number vs ours) with the real
* grade timestamp. Empty slate → the most recent real graded read. Nothing
* cached → the card hides. There is NO static fallback — the old Jokic
* "Example" card is gone.
* A live RULE, not a hand-picked example (hero-ranking-fix, 2026-07-29): the
* HIGHEST-CONFIDENCE read at a takeable price — the champion's top p_win among
* A/B, takeable-priced props — fetched from /api/hero-prop (which reads the
* pre-graded snapshot). The card shows the model's number vs the book's, with the
* real grade timestamp — a high-confidence read, NOT a claim of proven edge / +EV /
* best bet (no CLV/ROI/edge number is shown). Nothing qualifies → the card HIDES
* (honest empty state — no backfilled weak read, no static "Example" fallback).
*/
type Hero = {