# VYNDR — PRODUCT COMPLETION MATRIX Canonical board. Supersedes STATE.md's narrative. Re-derived from repo (`b0a51c8`), prod (`api.vyndr.app` / `vyndr.app`, checked 2026-07-27), and the design bundle (`specs/design-reference/*`). Every cell cites a file, a route, or a prod check. **DONE = all five YES:** DESIGNED (spec exists) · BUILT (code exists) · WIRED (a user can reach it) · LIVE (serving in prod now) · HONEST (real data, not fabricated/inflated/ placeholder). A built-but-unrouted component is **WIRED: NO** regardless of code quality. > **HONESTY PASS applied 2026-07-27 (6bc18d8):** every KNOWN live fabrication removed/hidden > — see the "HONESTY PASS" section at the end. HONEST cells for rows 19/20/24 updated (✓). ## SURFACE MATRIX — 16 of ~26 fully done (Book Comparison wired 2026-07-29) | # | Surface | DESIGNED | BUILT | WIRED | LIVE | HONEST | DONE | Evidence / what's missing | |---|---|---|---|---|---|---|---|---| | 1 | Landing / hero | YES | YES | YES | YES | YES | ✅ | `Landing.dc.html`; `app/page.tsx`; nav logo; prod `/`→200; Hero/TopSignals/ClaimMeter/ModelRecord all fetch real + self-hide | | 2 | Dashboard / Slate | YES | YES | YES | YES | YES | ✅ | `Mobile.dc.html`; `Slate.tsx`+`vyndr/GameCard`; Nav "Slate"; prod `/dashboard`→200; snapshot grades real (wnba 25/mlb 5 today) | | 3 | Scan flow (S6/S7) | YES | YES | YES | YES | YES | ✅ | `Scanner States.dc.html`; `scan/page.tsx`+`ProcessingGrade`; Nav "Read"; prod 200; real grade, honest `NoMarketState` | | 4 | Grade result card | YES | YES | YES | YES | YES | ✅ | `System.dc.html` reveal; `GradeResultCard.tsx` (3 importers); `/scan`; real grade. Sub-sections (alt ladder, books) gated/absent — see #17/#18 | | 5 | Grade display / badge | YES | YES | YES | YES | YES | ✅ | `HANDOFF.md:41`; `GradeBadge.tsx`; dashboard/scan/many; prod grades B/C real, no fake A | | 6 | Ledger | YES | YES | YES | YES | YES | ✅ | `Intelligence.dc.html` S4; `ledger/page.tsx`+`ClvBadge`; Nav "Ledger"; prod 200; n≥20 gate honored | | 7 | Tier-record | YES | YES | YES | YES | YES* | ✅ | `HANDOFF.md:33`; `TierRecord.tsx` (6 routes); n≥20 gate. *A-tier "edge glow" is ranking-as-credibility, not proven ROI (honest-but-thin) | | 8 | Pricing | YES | YES | YES | YES | YES | ✅ | `Mobile.dc.html`; `Pricing.tsx`+`ClaimMeter`+`DeskShowcase`; Nav/Footer; prod 200; Stripe real, mocks removed | | 9 | Public profile `/u` | YES | YES | YES | YES | YES | ✅ | `System.dc.html` /u; `PublicProfile.tsx`; OPEN_ROUTE share link; prod `/api/profiles/test`→404 (privacy honest) | | 10 | Player profile | YES | YES | YES | YES | YES | ✅ | `Mobile.dc.html` PLAYER; `player/[name]`; reachable via `playerHref` links; prod `/api/stats/player`→found:true (archetype/propDNA/season) | | 11 | Team hub | YES | YES | YES | YES | YES* | ✅ | `Mobile.dc.html` TEAM HUB; `TeamHub.tsx`; `TeamLink` on cards; prod `/api/team/NYY`→26 roster. *MLB real; NBA/WNBA partial roster | | 12 | Explore | YES | YES | YES | YES | YES | ✅ | `Intelligence.dc.html`; `ExploreHub.tsx`+`FuturesBoard`/`NewsWire`; Nav; prod 200; real leaders/futures, "TRACKED·NOT GRADED" label | | 13 | WIRE / ticker | YES | YES | YES | YES | YES | ✅ | `System.dc.html` WIRE; `vyndr/Ticker.tsx`; root layout; prod `/api/ticker`→30 real items | | 14 | Streaks / hot list | YES | YES | YES | YES | YES | ✅ | `System.dc.html`; landing panels + Explore; prod `/api/streaks/mlb`→240 (computed), self-hide honest | | 15 | Live tracking | PARTIAL | YES | YES | YES | YES | ⚠️ | `liveTrackingService`+`StatStrip.LiveTracker`; Slate polls `/api/live`; prod hasLive:false now (valid empty). DESIGNED: no dedicated bundle artboard | | 16 | Parlay lab | PARTIAL | YES | YES | YES | YES | ⚠️ | `System.dc.html` PARLAY BUILDER (not named "Lab"); `parlay/page.tsx`+`ParlayPanel`; `#parlay` drawer; prod `/api/parlay/grade`→real A- | | 17 | Alt-line ladder | PARTIAL | YES | PARTIAL | YES | YES | ❌ | Champion `alt_lines` real (prod: 5 rungs w/ edge_pct) but **Desk-tier only** (`tierGating.js:55`); proj-v1 `proj_ladder` ledger-only. DESIGNED: only Offseason grouping, no prop alt-stack | | 18 | **Book comparison (S2)** | YES | YES | **YES✓** | YES | YES | ✅ | ✓WIRED 2026-07-29: `BookComparisonPanel` (self-fetches `/api/books`) on the GradeResultCard; renders per-book lines (books differ), single-book honest state, crown OFF (`BOOK_CROWN_ENABLED=false`, no best claim). Push-to-book + movement strip deliberately HELD | | 19 | Price triplet | YES | YES | YES | YES | YES✓ | ❌ | ✓HONESTY PASS: null model/EV now NO_MODEL (honest-absent), no false "poisoned" copy. Still ❌: EV layer doesn't *produce* model_odds/ev (separate build) | | 20 | **Compare (H2H)** | PARTIAL | in-dev | NO | YES | YES✓ | ❌ | ✓HONESTY PASS: fabrication removed → honest in-development state, pulled from Nav+BottomTabBar. Real two-player build pending (awaiting real build) | | 21 | Newsletter | YES | YES | YES | PARTIAL | YES | ❌ | `NewsletterCapture.tsx` on `/`,`/welcome`; subscribe validates live; send internal-only. LIVE: Listmonk env config `CANNOT DETERMINE` from prod | | 22 | Slip reader | PARTIAL | YES | PARTIAL | YES | YES | ❌ | `slip/page.tsx`; prod 200; **0 nav links → orphan** (deep-link only). DESIGNED: `a1-s9` spec, not the design bundle | | 23 | Article media / share (S3) | YES | PARTIAL | NO | PARTIAL | YES | ❌ | `Intelligence.dc.html` ARTICLE MEDIA; `ShareCard.tsx` **0 real importers = DEAD**; OG `opengraph-image.tsx` IS live. In-article archetype figures not built | | 24 | Calibration / edge board | YES | YES | NO | NO | YES✓ | ❌ | ✓HONESTY PASS: placeholder-edge% `MobileEdgeBoard` REMOVED from the Slate (phones show real cards). Component kept as dead code until a real edge feed exists | | 25 | System / Intelligence terminal | YES | YES | **NO** | PARTIAL | YES | ❌ | `System.dc.html`/`Intelligence.dc.html`; `/terminal`→redirect to `/dashboard`; `/intelligence` REAL but **orphan (0 nav links)**; `/system` no page (prod 404) | | 26 | Offseason hub (S-2) | YES | PARTIAL | NO | NO | — | ❌ | `Offseason.dc.html` full spec; **no `/offseason` page** (prod 404); logic only inline in `FuturesBoard`/`NewsWire` on Explore | Prod endpoints confirmed LIVE + real: `/api/snapshot/{mlb,wnba}`, `/api/accuracy` (n=763), `/api/ledger/accuracy`, `/api/ticker`, `/api/books/mlb`, `/api/streaks`, `/api/hotlist`, `/api/live`, `/api/schedule`, `/api/stats/{player,leaders}`, `/api/team`, `/api/parlay/grade`. ## MODEL MATRIX — champion serves; every challenger is ledger-only | Component | EXISTS | PROVEN | PROMOTED (serving) | USED (a surface reads it) | Evidence | |---|---|---|---|---|---| | Champion (engine1) | YES | PARTIAL→**promising** | YES | YES | `analyzeViaEngine1.js`; `enriched`→`snapshot`/`grades`. SKEW AUDIT 2026-07-29: on takeable MLB overs (n=62) champion p_win→CLV **partial r=0.375, SIG p≈0.003**; SURVIVES the mechanical baseline (no-edge CLV +1.5pt n=20 vs high-edge +8.6pt n=37 → **+7.1pt marginal**). De-vig clean (same-book pairing); close well-defined (DK/MGM r=0.92). PROMISING, NOT confirmed (thin n; lock-staleness check BLOCKED; 1 sig result among many) | | arch-v1 | YES | NO | NO | NO | `challengerProjection.js`; rides `withChallenger`→**ledger only** (`:693`). "measured, never served" (`ledgerService.js:251`) | | contact-v1 | YES | NO | NO | NO | `contactChallenger.js`; ledger col `p_win_contact` only | | proj-v1 / v1.1 | YES | **NO (tested 2026-07-29)** | NO | NO | `projectionChallenger.js` (MLB-batting only). PROOF ORDER verdict: **NOT PROVEN** on n=45 takeable MLB overs — edge-CLV partial-r (controlling price) = 0.245 (n.s.); ~half the raw signal is the shared −fair_prob_lock term (mechanical); and the CHAMPION out-predicts it (champ partial-CLV 0.380 sig, champ-edge→hit 0.25 vs proj 0.12). Ledger-only | | Champion alt-ladder | YES | NO | YES | Desk-only | `analyzeViaEngine1.js:486`; real re-grades ±1 line; `gradeAdapter.js:100` maps to card **Desk-gated** | | proj-v1 `proj_ladder` | YES | NO | NO | NO | `distribution.js:100`; ledger-only, reaches no card | | Price gate / EV | YES | PARTIAL | PARTIAL | PARTIAL | fields on `enriched`; hero gates on `isTakeable`+`ev_pct` (`heroPropService.js:78`). **But prod grades show ev_pct/p_win/model_odds/value/takeable = NULL** — built, served-schema, not producing | ### Ladder question (Phase 2.6) — VERIFIED: proj-v1.1 DOES compute rungs above the line `projection/distribution.js:100` `ladder()` computes `P(stat ≥ k)` for a fixed rung set `k = 1..LADDER_MAX` (default 4), **independent of the listed line** — so for a line of 1.5 (tradedRung=2) it emits rungs 1 (below), 2 (at), **3 and 4 (ABOVE)**, each a real negative-binomial survival prob (`projectionChallenger.js:183,200`). "Ladder-up **works**" — sole cap is `LADDER_MAX=4`. **BUT `proj_ladder` is ledger-only and reaches no user surface.** So "ladder up from the listed line to find value" is *computed and never wired*. ## HONEST-STATE SUMMARY ### 3.7 — What a PAYING USER sees right now that is not true 1. **`/compare` — fabricated grades, nav-linked + public.** Hardcoded Jokić A+ / Wembanyama A + fake "VYNDR VERDICT" (`compare/page.tsx:10-62`). No data behind it. **The single worst live lie.** 2. **FAQ — phantom processor.** "We use NexaPay" (`FAQ.tsx:28`); every legal/pricing page says Stripe. Also founder price inconsistency ($24.99 vs $19.99). 3. **FAQ + Features — Brier/CLV over-claim.** "Brier score and CLV… published / from day one · Public accuracy by tier" (`FAQ.tsx:498`, `Features.tsx:323`). No Brier surfaced anywhere; CLV held. `CANNOT DETERMINE` a live Brier surface — because none exists. 4. **Mobile edge board — placeholder edge%.** `MobileEdgeBoard.tsx:44` renders a miscalibrated edge feed, masking >40% to "—". The numbers ≤40% still come from a placeholder pipeline. Live on mobile Slate. 5. **Price triplet / EV markers advertised-and-absent.** Grade schema carries `ev_pct`/`p_win`/`model_odds`/`value`/`takeable`; all **NULL on live grades** — the "model price" leg and VALUE marker don't render though the design promises them. Not inflated (verified honest): grades are B/C only with A/D/F below n≥20 → `pct:null` everywhere; `AccuracyBadge`/`ModelRecord`/`TierRecord`/ledger all honor the n≥20 gate and self-hide. Hit-rate (59%, n=763) shows **without ROI/CLV** (CLV frequently null) — thin, not false. ### 3.8 — The graveyard (built, no user can reach it) 1. **`BookComparison.tsx`** — 0 importers. Backend `/api/books` is live + honest; nothing renders it. (S2 headliner.) 2. **`ShareCard.tsx`** — 0 real importers (S3 share cards). 3. **`components/GameCard.tsx` (legacy)** — type-only import; superseded by `vyndr/GameCard`. 4. **proj-v1 `proj_ladder`** — the above-line probability ladder; computed, ledger-only, never served. 5. **arch-v1 + contact-v1** — challengers, ledger-only, never served ("measured, never served"). 6. **`TerminalTemplates.tsx`** — all SAMPLE data; `/terminal` redirects → effectively unrouted. 7. **`DemoScan.tsx`** — defined, never rendered. 8. **`/intelligence`** — REAL signals feed, but 0 nav links (orphan; reachable only by typing the URL). 9. **`/soccer`, `/marketplace`** — REAL pages, 0 nav links (orphans). 10. **`/notifications`** — `RouteStub`, unreachable. 11. **Offseason hub** — full design spec, no page built (prod `/offseason`→404). ## FULLY DONE (all five YES) — 15 Landing · Dashboard/Slate · Scan flow · Grade result card · Grade badge · Ledger · Tier-record · Pricing · Public profile `/u` · Player profile · Team hub · Explore · WIRE/Ticker · Streaks/Hot list · Live tracking. ## NEAREST TO DONE (one column from YES) — the shortlist a single order could finish | Surface | The one gap | Finish move | |---|---|---| | **Book comparison (S2)** | WIRED: NO | Route `BookComparison.tsx` onto the card from the live `/api/books` store (crown stays off — measured flat). *Backend already shipped.* | | **Parlay lab** | DESIGNED: PARTIAL | Accept the System "PARLAY BUILDER" spec as the lab spec (functionally live) — a doc call, not a build. | | **Compare (H2H)** | HONEST: NO | Replace the hardcoded SAMPLE with a real two-player fetch, or pull it from nav until real. | | **Price triplet** | HONEST: PARTIAL | Make the price-aware EV layer actually produce `p_win`/`ev_pct`/`model_odds` on served grades (built, not firing). | | **Newsletter** | LIVE: PARTIAL | Confirm/enable Listmonk env (config `CANNOT DETERMINE` from outside). | | **Slip reader** | WIRED: PARTIAL | Add one nav/More-sheet link (page is live + honest). | | **Calibration / edge board** | HONEST: NO | Fix the placeholder edge% feed (backend), or hide the board until real. | Two-plus columns out (bigger builds): **Alt-line ladder** (design + wire the served probability ladder), **System/Intelligence terminal** (wire the orphan `/intelligence`), **Article media/S3** (build in-article figures; `ShareCard` dead), **Offseason hub** (no page at all). *Tags: all cells VERIFIED against repo/prod/bundle except — Newsletter LIVE (Listmonk env) and a live Brier surface = CANNOT DETERMINE (none found). Nothing BLOCKED.* --- # HONESTY PASS — applied 2026-07-27 (commit 6bc18d8, deployed) Removed/hid every KNOWN live fabrication. REMOVE/HIDE only — no grade, snapshot, scorer, pipeline, or real feature touched. Updated HONEST cells: | Item | Was | Now | |---|---|---| | /compare (row 20) | HONEST: NO — hardcoded Jokić A+/Wembanyama A + fake VERDICT, nav-linked | Honest **in-development** state; removed from Nav + BottomTabBar. Real two-player build **pulled, awaiting real build**. | | Pricing (founder copy) | $34.99 desk / struck $19.99 / FAQ $24.99 — wrong | Founder **Desk $44.99** (matches lib/checkout.js), **Analyst $14.99**; struck "regular" numbers removed; DeskShowcase $34.99→$44.99. First-100 counter is REAL (ClaimMeter→Stripe). No "first 50" desk claim (no such counter). | | FAQ processor | "NexaPay" | **Stripe** (verified live: Next→Express→checkout.stripe.com). `nexapay.ts` + its webhook route were **PURGED 2026-07-27** (NexaPay Purge order) — cross-project contamination, never a real VYNDR path. Provider-side env/keys + the orphaned `user_profiles.nexapay_customer_id` column flagged for Kev. | | FAQ + Features "Brier/CLV published from day one" | INFLATED (not surfaced) | Removed. Returns when Brier/CLV are actually surfaced. Backend Brier compute untouched. | | Calibration / edge board (row 24) | HONEST: NO — MobileEdgeBoard placeholder edge% (masked >40%) | **Removed** from the Slate; phones show the real game cards. Component kept as dead code (hidden, not deleted) until a real edge feed exists. | | Price triplet (row 19) | HONEST: PARTIAL — null model/EV rendered "MODEL READ WITHHELD · poisoned" (false quarantine) | New **NO_MODEL** honest-absent state: MODEL "—" / "NOT PRICED", no verdict. Fixes grade card + LiveHeroProp. EV layer still doesn't *produce* values (separate build). | ## KEPT ON THE BOARD (real work to finish — NOT cut) - **Article media / S3 (row 23)** — real feature + free SEO/distribution. Finish, don't delete. Only the false "Brier/CLV" claim about it was corrected. - **Newsletter / THE WIRE (row 21, 13)** — real. Capture live, honest. ## FUTURE MODEL INPUT (logged only — not built this order) - **News / line-movement signal** — injuries, scratches, lineups, weather move props before books reprice. Wire later as a model input. This is **ADDITIVE** to the media surfaces, not a replacement for them. ## KNOWN HONESTY GAPS (not fixed this order — logged, not fabrication) - **Hit rate 59% (n=763) shown without ROI/CLV** — thin, not false. ROI/CLV surfacing is a later build. - **"0 pushes = mis-scoring" — RETIRED 2026-07-29 as a false alarm** (premise re-verified, report-only). The displayed hit/miss denominators are NOT corrupted by a hidden push bug: the feed is still 100% half-numbers (0 whole lines in 117,970 captured market lines / 6,050 snapshots / 1,141 ledger rows / 173 lock_lines), all 992 settled actuals are integers, and the smallest actual-vs-line gap in the whole ledger is 0.5. Expected pushes = exactly 0. See the verdict block below. - **CLV instrument REPAIRED 2026-07-28** (commit 6552281). Was: 59 usable closing_prob. Now: **406** (MLB 248, WNBA 158) — the collapse was `attachClosingProb`'s `.limit(50000)`/no-ORDER-BY read + write-once `market_unavailable`, NOT capture (95% per-prop coverage) or the join (0 key mismatches). **CLV finding, straight: MLB unders lag the close (mean −9.1 prob-pts, 74% lose); MLB overs +2.0; WNBA flat.** → the +4.57% MLB-C and over/under asymmetry are substantially stale-line artifacts. This UNBLOCKS the proof order (proj-v1.1), which gates promoting p_win/ev to served grades. **Honest state after this order: "no KNOWN live fabrications" — not "provably none."** The audit was thorough (repo + prod), but absence of a claim of falsehood is not a proof of universal truth. --- # proj-v1.1 TAKEABLE-EDGE PROOF — verdict 2026-07-29 (report-only, read-only) **N-gate PASSED: overlap = 45** (settled ∩ proj-v1.1 ∩ MLB over ∩ CLV close ∩ fair_prob_lock ∩ takeable −160..+200). The CLV repair is what made n≥30 reachable. Edge basis = `proj_p_over_line − proj_book_implied` (de-vigged fair, VERIFIED not raw book). **VERDICT: NOT PROVEN.** proj-v1.1's takeable-edge does NOT beat the champion or clearly beat the close on MLB overs. - Phase 1 buckets (descriptive; only the neg bucket clears ≥15): 6%+ edge (n=11) shows hit 70% / fair-ROI +0.57 / CLV +12.95pts — but even negative-edge rows show +2.7pt CLV (whole over-side is elevated = the stale-high concern). - Phase 2 partial correlation (the real test): raw r(edge,CLV)=0.455 → **partial r(edge,CLV | price)=0.245, n.s.** at n=45 (t≈1.64, p≈0.11). ~half the raw signal is the shared −fair_prob_lock term (mechanical). proj predicts the close itself only weakly (partial r(proj,close|lock)=0.281, n.s.). - Phase 2.6 champion comparison (same 45 rows): **the CHAMPION out-predicts proj-v1.1** — champ-edge→hit r=0.250 vs proj 0.120; champ partial-CLV=0.380 (SIGNIFICANT, p≈0.01) vs proj 0.245 (n.s.). Positive-edge fair-ROI comparable (proj +0.39 n=19, champ +0.34 n=26). - Shown, not judged: MLB unders (n=20) CLV −9.34pts, r(edge,CLV)=−0.03 (contaminated, zero signal); WNBA — proj-v1.1 does not run (MLB-batting only), N/A. **Conditional dependency (moot):** the verdict was to be conditional on the under-capture audit clearing the over-side. It's moot — proj-v1.1 fails Phase 2.6 (loses to the champion) BEFORE the audit applies, so NOT PROVEN regardless. The stale-high concern is corroborated (whole-over-side baseline +CLV; half of proj's signal mechanical). **Notable:** the one statistically-defensible edge signal here is the **CHAMPION's** p_win predicting CLV on takeable MLB overs (partial 0.380, p≈0.01) — NOT proj-v1.1. That champion signal is itself still audit-gated (if MLB overs are whole-side stale-high, even it is suspect). **What accrues a re-test:** ~20-25 more settled takeable MLB-over rows (to test proj's residual ~0.245 partial against zero), AND proj-v1.1 must demonstrate it beats the champion — which it currently does not. Promotion stays HELD. --- # OVER-SIDE SKEW AUDIT — verdict 2026-07-29 (report-only, read-only) Gates the champion's over-CLV signal (partial r=0.375, p≈0.003, n=62 takeable MLB overs — 0.2 CONFIRMED). **THE THREE NUMBERS (Phase 4), n at each:** - Mechanical baseline CLV (champ-edge ≤ 0, "no edge"): **+1.51 pts** (n=20) - Champion high-edge CLV (champ-edge ≥ 0.05): **+8.64 pts** (n=37) - **DIFFERENCE = the real edge: +7.14 pts** **VERDICT: SURVIVES BASELINE.** The marginal (+7.1) is ~5× the mechanical floor (+1.5) and the price-controlled partial correlation stays significant. The skew is essentially ONE-SIDED (unders lag −7.0 overall; overs carry only a small +1.5 floor, NOT the +7 a symmetric two-sided over-skew would show). De-vig is CLEAN (`analyzeViaEngine1.js:539` pairs over+under from the same book/fetch — no fresh/stale pairing). Close is well-defined (draftkings vs betmgm over-prob r=0.921, n=151). **→ GREENLIGHTS building the takeable-edge grade ON THE CHAMPION (engine1 p_win), NOT proj-v1.1** (which lost the proof). This is the project's first edge signal to survive an adversarial audit. **FLAGGED — promising, NOT confirmed:** - Thin n (62 overs / 37 high-edge / 20 baseline). - Phase 2 lock-staleness check is **BLOCKED**: multi-book lines AT LOCK are not retained (`bookprices` is Redis current-only), so we cannot fully rule out that part of the baseline is lock-time staleness. The de-vig being clean + the small baseline make a large hidden skew unlikely, but it's not excluded. - Sharp (pinnacle) reference covers only **8** props (sharp-CLV +3.17pt, directional hint only). - This is one significant result among many computed this session — do not overstate. **What would strengthen it:** retain multi-book at lock (enables the sharp/consensus lock-staleness check), and accrue more settled takeable MLB-over rows. Held: no promotion, no served p_win/ev, no capture fix — diagnosis only. **UPDATE 2026-07-29 (commit c7067c8): the lock-multi-book gap is now CLOSED.** New `lock_lines` table (migration 033, applied+tracked) persists each graded prop's per-book lines at the lock moment (`lockLineCapture` in `snapshotService`, fenced RLS-service-role-only, grade byte-identical proven). This unblocks the staleness audit for FUTURE rows — it does NOT retroactively fix the existing 62. Confirmation still needs weeks of accrued lock+close+outcome. Populates from the next snapshot tick. --- # HERO RANKING FIX — 2026-07-29 (commit 41b86e3, deployed) The landing/hero (matrix row 1) selection was silently broken: it ranked on `ev_pct`, which is NULL on served grades, and **`Number(null) === 0`** made every prop tie at EV 0 → the "top read" was the FIRST takeable A/B prop in cache order — **arbitrary, dressed as ranked** (prod served Kelsey Mitchell, the #6 read by p_win). FIXED: rank by the **champion's p_win** (the only promising edge signal) among A/B **takeable-priced** reads (`isTakeable` −160..+200, same band as the proof/audit); strict-null guard; takeable filter excludes chalk; **no backfill** → honest empty state when nothing qualifies. p_win is ranking-only (never exposed; the route strips it). Display-only — reads caches, writes to nothing. No proven-edge/+EV/best-bet claim, no CLV/ROI/edge number. This makes the champion's p_win a real (display) consumer for the first time. Fingerprint VERIFIED: hero is the max-p_win read across sports (WNBA A), not old code's first-in-order MLB pick (Schanuel −135); untakeable chalk excluded. Visual auth-gated → data fingerprint. --- # PUSH-SCORING PREMISE VERIFY — verdict 2026-07-29 (report-only, read-only) Tested the standing ruling "push scoring is correct — do not touch." That ruling rested on "100% half-number lines → pushes structurally impossible," which was true for the data it was made on. If whole-number lines had entered the feed since, 0 pushes across settled rows would be a real mis-scoring bug the ruling was shielding. **The premise HOLDS — the ruling stands.** **Phase 1 — feed distribution, 4 independent populations, per sport AND per market (never blended):** | population | what it covers | rows with a line | whole-number lines | |---|---|---|---| | `closing_captures` | raw captured market lines, 5 books, `book`+`sharp`, Jul 20-29 continuous | **117,970** | **0** | | `model_snapshots` | every graded prop **incl. grader refusals** (not survivorship-filtered) | 6,050 | **0** | | `ledger_entries` (public) | the settled public record, 11 markets | 1,141 | **0** | | `lock_lines` | TODAY's lock-time per-book lines (freshest feed, migration 033) | 173 | **0** | Per-market: MLB hits / doubles / rbi / total_bases / stolen_bases / runs / strikeouts / home_runs / walks / earned_runs / outs / hits_allowed and WNBA points / rebounds / assists / threes — **every market's min AND max line ends in `.5`** (e.g. MLB strikeouts 2.5-8.5, WNBA points 5.5-26.5, MLB outs 3.5-19.5). No whole-number market is hiding inside a blended fraction. **Phase 2 — the push branch would fire.** `outcomeService.js:151` `if (a === l) return 'push'`, reached **after** `Number()` + `Number.isFinite` guards on both operands — a sound numeric compare, not the `Number(null) === 0` string-vs-number class that hit the hero. It is the **single scoring chokepoint** (`ledgerService.js:31` imports `settleResult`; no parallel hit/miss derivation exists in `src/`), it is **unit-tested live** (`outcomeService.test.js:38`, `nbaSettlement.test.js:104`), and both `ledger_entries.outcome` and `outcomes.result` CHECK constraints **include `'push'`** — a real push would score, write, and persist end-to-end. **Phase 2.6 — the decisive number.** Across 992 settled rows carrying an actual: **0 exact ties, 0 fractional actuals, and the smallest actual-vs-line gap is 0.5** — the arithmetic minimum between an integer result and a half-number line. **VERDICT: RULING HOLDS.** Expected push rate is **exactly 0 (P = 0), not "low"** — 0/992 is *forced*, not chance. The "implausible" flag mistook an arithmetic impossibility for a suspicious absence; the row closes honestly. Stale n corrected: the flag said 470 settled, it is now **1,097** (593 hit / 399 miss / 105 void / 44 unsettled-today). Nothing modified — no scoring, settlement, re-settle, or backfill. **No latent bug either.** Because the branch is correct and covered, a whole-number market entering later (NFL/NHL are code-wired but out of season; whole-number strikeout props exist at some books) would be scored as a push automatically. The residual is a **monitoring** gap, not a scoring gap: nothing alerts on the first whole-number line to enter the feed. Logged, not built. --- # EDGE_PCT SCALE DIAGNOSIS — 2026-07-29 (report-only, read-only). Fork REPORTED, not chosen. **What it is (0.1).** `analyzeViaEngine1.js:265-270` — `edge_pct = ((projection − line) / line) × 100`, signed by direction, where `projection = l5_avg ?? l20_avg ?? {stat}_per_90 ?? xg_per_90`. **Independent of `p_win`** (so NOT tainted by the overconfidence that damns `ev_pct`) but it takes **no price input at all**, so it cannot express a betting edge. **Arithmetically correct, MISLABELLED:** honest as "% the projection differs from the line," **a lie at any scale as "EDGE."** Two independent implementations — backend `edgePctFor` and `web/src/lib/gradeAdapter.js:25-31 computeEdge`; the grade card renders the WEB one, so a backend-only fix would miss it. **The cap (0.2).** `SANE_EDGE_MAX = 40` (`deskShowcaseService.js:31`: *"beyond this the (model-line)/line value isn't a market edge"*), mirrored in `slateAdapter.js:613` and `MobileEdgeBoard.tsx:45`. A self-declared plausibility bound from an earlier order, not a derived statistical one. **Mechanism (0.3) = SMALL-DENOMINATOR EXPLOSION** — not units, not inversion, not a missing ×100. `line` is the denominator and **86% of MLB rows (562/655) sit at line 0.5**. Max 620 = a ~3.6 projection on a 0.5 line. | population | n | >cap 40 | >100 | median | p95 | max | min | |---|---|---|---|---|---|---|---| | **MLB** | 655 | 65.8% (>50) | 13.6% | **60** | 180 | **620** | −86.7 | | **WNBA** | 486 | 4.9% (>50) | **0%** | 12 | 49 | 77.8 | −51.7 | | blended | 1,141 | **44.0% (502)** | 7.8% | — | — | 620 | — | Per line (the proof): MLB 0.5 → 73.0% over cap, max 620 · MLB 1.5 → 43.8%, max 153 · WNBA 12.5 → 6.7% · **WNBA 26.5 → max 1.9.** Matrix figures re-verified: **51.5% is stale → 44.0%; worst 620 is exact.** **Shape: structurally broken for MLB, sane for WNBA** — and the scale is a *function of line size*, so the metric is incomparable across markets **by construction**. No rescaling fixes that. **Surfaces (Phase 2) — the "~13" count is NOT confirmed. Three surfaces RENDER it:** | surface | live | access | role | user sees at 620 | |---|---|---|---|---| | `GradeResultCard.tsx:182,216,325` | YES (3 importers) | **auth-gated `/scan`** → **TAGGED FOR CHROME AUDIT** | display | **"+620% edge", raw + GREEN** | | `DeskShowcase.tsx:40` | YES | **PUBLIC** `/pricing` | display | **"—"** (already honest) | | `SoccerGradeResult.tsx:229` | YES | orphan `/soccer` (0 nav links, public by URL) | display | raw uncapped `X.X% edge` | | `MobileEdgeBoard.tsx:47` | **DEAD** (0 importers) | — | sort+display | "—" (pulled in honesty pass) | | `PropRow:45`, `GradeCard:32`, `ledger/page:40` | live components | — | **type-only, never rendered** | nothing | | `contentTemplateService.js:164` | public `/api/content` | API | string | uncapped — **no page fetches it** | **🔴 IT DRIVES TWO LIVE SORTS (the fork's load-bearing answer).** 1. `slateAdapter.selectTopGrades:469-471` — `grade → confidence → |edge| desc` → **dashboard TOP GRADES top-10** (`dashboard/page.tsx:419`). **97.3% of rows (1110/1141) sit in a (date,sport,grade,confidence) tie group of ≥2** (biggest 56), so |edge| is operative for essentially the whole slate — the **de facto ordering** of that leaderboard. 2. `analyzeViaEngine1.js:506` — the Desk **alt-line ladder** is sorted by `edge_pct` desc. **Two scale-INDEPENDENT defects inside that sort** (`Math.abs(numOr(g.edge, -Infinity))`): **(i) abs()** on an already-direction-signed value ranks the model's strongest *disagreements* equal to its strongest agreements (**177 negative-edge rows**: 58 B / 118 C / 1 F, worst −86.7); **(ii)** `Math.abs(-Infinity) = Infinity` → a **missing edge sorts FIRST**. The `Number(null)` fabrication class again, new costume. **Phase 4 correction — "nothing renders `ev_pct`" is WRONG.** `PriceTriplet.tsx:60,67,76` renders `${pct(ev)} EV`, live and wired (scan → `gradeAdapter:143`). It shows nothing only because `ev_pct` is NULL on served grades → `valueState.js:121` falls to **NO_MODEL honest-absent**. The right metric already has a live honest render site, **starved of data, not unwired** — and the card's "EDGE" row sits exactly where a price-aware number belongs. **THE FORK (reported, not chosen).** - **FIX** — dishonest: no rescaling turns a price-free projection gap into an edge (renaming, not fixing); it silently re-ranks the dashboard top-10 (the hero-class bug just fixed); needs BOTH implementations. - **HIDE** — cheap: 3 render sites, each already has a null branch (no layout breaks), and DeskShowcase already proves the honest "—" pattern in-product. Not load-bearing for layout anywhere. - **RECOMMENDED: HIDE the number and re-point the sort at `p_win`** — the hero order established p_win is on 100% of recent ledger rows and is the only signal that survived an adversarial audit. Repairing a key that is a 0.5-line artifact is not worth it. End state: **p_win ranks · ev_pct displays · edge_pct retires.** The abs()/null-first sort defects deserve their own small order either way. *Nothing changed: no edge_pct, scale, surface, sort, grade, ledger, or accruing edge touched.* --- # GRADE-BOARD SORT FIX — 2026-07-29 (spec `specs/grade-board-sort.md`, shipped) Display ORDERING only. Fixes two defects that were wrong at ANY scale, independent of edge_pct's separate retirement (Order B, still held). **Defects removed.** `selectTopGrades` ranked on `Math.abs(numOr(g.edge, -Infinity))`: `abs()` on an already-direction-signed value ranked the model's strongest **disagreements** level with its agreements (177 public ledger rows carry a negative edge); and `Math.abs(-Infinity) === Infinity` made a **missing** signal sort **FIRST** — absent data as the top pick. Now: `grade → confidence → takeable-gated p_win (nulls LAST) → SIGNED edge (nulls LAST) → input order`, scales never mixed. The alt-line ladder (`analyzeViaEngine1:506`) no longer sorts by `edge_pct`; it is ordered highest-p_win-first via the monotonic line rule (line-ASC for an over, line-DESC for an under) at zero added compute. **Three premise breaks found report-first.** (1) **`/api/props/top-graded` 404s in prod** — the dashboard board's feed does not exist, so that board renders receipts/empty and the sort orders nothing there today; the prior order's "97.3% of rows tie → the edge key decides the board" was a ledger measurement wrongly extrapolated to it. (2) **p_win is stripped for unentitled tiers by design** (`snapshotGating`, Session 67 — "shipping p_win is shipping the model price"); verified live, prod `/api/snapshot` carries p_win on **0/8 MLB and 0/25 WNBA** grades, so the browser path uses the signed edge and only entitled callers rank on p_win. (3) **Ladder rungs carry no per-rung price**, so the hero's takeable gate is inapplicable there. **Verified on real data, both sports, both paths.** Unentitled: WNBA (n=25) ordering CHANGED, MLB (n=8) unchanged; signed edge non-increasing within every (grade,confidence) tie group — 20 pairs, 0 violations. Entitled: 40 real ledger rows with p_win+locked_odds — p_win-descending, untakeable chalk not promoted, 36 pairs, 0 violations. **Hero consistency, honestly:** same signal + same gate, different precedence by contract (board = grade-tier-first "top GRADES"; hero = p_win-first "top read"). They agree exactly **within** the leading tier (verified); across tiers the board may lead with an A the hero doesn't pick. Not a contradiction — do not "fix" it by making the board ignore grade. **Floor:** 310 suites / 3864 tests green, web build exit 0. **Post-deploy fingerprint (`b85b351`), both halves verified:** the deployed `/dashboard` chunk was polled across the deploy boundary — attempts 1-3 carried the OLD `Math.abs(...-1/0)` key, attempt 4 flipped to the new comparator with the old one GONE (before/after observed, not inferred); API health 200 on snapshot/mlb, snapshot/wnba, accuracy. The backend ladder was **induced on demand** on live MLB game logs rather than waiting for a cron slot: OVER @0.5 → `0.5•(C) 1(C) 1.5(F)` (line-ASC PASS), UNDER @1.5 → `2.5(C) 2(C) 1.5•(C) 1(C) 0.5(F)` (line-DESC PASS). Only the *rendered* Desk card remains unverified anonymously → tagged for the Chrome audit, no visual faked. **Held:** edge_pct rescale/display retirement, building the missing `/api/props/top-graded` selector, exposing p_win to unentitled tiers. --- # /api/props/top-graded SERVER SELECTOR — 2026-07-29 (spec `specs/top-graded-selector.md`, shipped) The dashboard TOP GRADES board had no feed. **The handler NEVER existed in any commit** (searched `git rev-list --all`) — so the three axios callers (cheatsheetGenerator, gradeOfTheDay, widget) plus the Next proxy had always received `[]`. Contract recovered from those consumers, not guessed. **The leak boundary — the whole point of doing it server-side.** The browser cannot rank on `p_win` for all tiers because `stripModelPrice` deliberately withholds it from unentitled tiers ("shipping p_win is shipping the price in a different base", S67). Order of operations: `read cache → RANK with p_win (every tier) → map rows incl. model fields → stripModelPrice(rows, tier) → serialize`. A free caller gets the paid RANKING without the paid VALUES. Tier resolution FAILS CLOSED to `free`; `Cache-Control` is `private` under a bearer token, `public` otherwise. **Populated-path risk found and handled:** the board's populated branch had never run in prod, and `dashboard/page.tsx:463` calls `g.stat.replace(/_/g,' ')` **unguarded** — `toRow` requires string `player`+`stat`, a finite `line`, uppercases `sport` for `SportPill`, and drops unrenderable rows. **One shared ranking definition:** new `src/utils/gradeRanking.js`; `heroPropService` now imports `takeablePWin` (was an inline copy, behaviour unchanged), the selector imports `rankGrades`, and the web mirror is cross-checked by test. Board is grade-first ("top GRADES"), hero is p_win-first ("top read") — they differ by design and agree within the leading tier. **Honest limit:** the Next proxy forwards no Authorization and caches under a shared key, so via the dashboard every viewer receives the free-tier payload — correct order, no paid values. That is the safe default (forwarding auth into a shared cache is how paid payloads leak); per-tier delivery through the proxy needs a tier-keyed cache and is NOT done here. **Verified:** 311 suites / 3882 tests green (18 new, leak test on POPULATED p_win), web build exit 0. **Post-deploy fingerprint (`72a14dc`) — the boundary proven in production:** 404→200 captured across the deploy boundary; the anonymous live order is *1. Brionna Jones (edge 29.4) · 2. Rhyne Howard (edge 42.9)* — an edge-only sort would lead with Howard (and the local induction over the stripped snapshot did), so **server-side p_win ordered it** (Brionna .90 @−106 > Howard .745 @−120) while the payload carries **PAID FIELDS: NONE**. A bogus bearer token also yields no paid fields (fail-closed proven in prod). The board's proxy path now returns 10 props, so TOP GRADES **renders** instead of falling back to empty. The rendered board is client-side → tagged for the Chrome audit, not faked. --- # MODEL ARCHITECTURE RECOVERY MAP — 2026-07-30 (report-only) → `specs/model-architecture-recovery-map.md` **The live grade uses 0 of the 3 specced layers.** Every audited metric (calibration, CLV, skew audit, takeable floor, p_win→CLV r=0.375) is measured on the SHADOW model. Those findings stand — the shadow model served every real grade — but none are evidence about the specced engine, which has never been measured. | Specced component | State | |---|---| | Layer 1 Similarity (`python/utils/similarity.py`, 101 ln) | BUILT · NOT WIRED · **NOT DEPLOYED** | | Layer 2 Bayesian (`python/utils/bayesian.py`, 320 ln) | BUILT · NOT WIRED · **NOT DEPLOYED** — and its "sport-agnostic math / per-sport parameters" claim is TRUE of the built code | | Layer 3 grade scale (`grade_thresholds.json`) | BUILT · **WIRED BACKWARDS** — the table maps PROBABILITY→GRADE; the live JS reads it in reverse to manufacture `confidence` from an already-chosen letter | | Per-sport market-efficiency scaling | **SPECCED-BUT-ABSENT** | | Live champion (`engine1` + `probabilityEstimator`) | BUILT · WIRED — but the letter is a factor-index with **zero probability input**, and `p_win` is computed separately and never feeds it | **The Python engine is not in the deploy image at all** (no python/pip in `Dockerfile`; `app.js` only health-checks it). **The sport boundary is NOT clean on the live path** — adding a sport is a ~10-file core edit with four documented silent-failure modes, so "make a sport a module" is itself a prerequisite build. **Per-sport records DO exist** (`sports.mlb` n=526/62% vs pooled `overall` n=937/58%, each with its own n≥20 gate) — the rule to enforce is that a new sport renders `sports.{sport}`, never `overall`. **Park×weather is a CHALLENGER, not the champion** ("measured, never served"); xwOBA and bullpen-leash are absent entirely. Recovery is dependency-ordered in the map: decide the grading basis → pick a runtime (recommend porting Bayesian to Node) → wire Layer 2 → reconnect Layer 3 forward → Layer 1 → per-sport efficiency → challenger promotion → sport-as-module → NFL/CFB. MLB is specced as the reference module. --- # FULL-OUTPUT GRADE MAPPING + COLLAPSE COST — 2026-07-30 (report-only) → `specs/full-output-grade-mapping.md` Track-B 1 of 3. The three-layer engine is **BUILT but NOT WIRED and NOT DEPLOYED** (re-verified), so no posterior/CI is produced today. Measured instead against the collapse that actually exists — three of them: estimator components dropped; **`p_win` excluded from the grade entirely** (the severe one — the letter is a factor index with zero probability input); and `grade_thresholds.json` read backwards to manufacture `confidence`. Market-efficiency scaling is never computed at all. **THE MEASUREMENT (354 settled rows, locked pre-game p_win — forward, not lookahead):** | basis | ALL (n=354) | MLB (n=224) | WNBA (n=130) | |---|---|---|---| | champion letter → outcome r | **0.0050** (p≈0.93, null) | 0.0686 (n.s.) | −0.0986 | | probability letter → outcome r | **0.1313** (p≈0.013) | **0.2356** (p≈0.0004) | **−0.1258** | **The served letter is INVERTED between its only two populated tiers — B 52.4% (n=168) vs C 56.9% (n=174).** Probability letters spread 30.8%→70.0%, use 10-11 of 11 letters (champion uses 3-4), and split ROI −1.42% (A-family n=78) vs −26.62% (C-/D/F n=51). **Verdict: costly on MLB, and un-collapsing does NOT help WNBA** (both correlations inverse there) — so the full-output challenger must be **MLB-FIRST**. Five falsifiable mapping rules are specced (R2 "uncertainty grades down" stated explicitly and droppable if it fails). **Hard requirement on the build order: persist per-row `n`, `SE`, and pre-adjustment `p`** — without them R2/R4 can never be adjudicated. **Re-adjudication flagged:** p_win→CLV, the skew audit, **proj-v1.1's "NOT PROVEN" (judged against the collapsed champion — not final)**, the C1 takeable floor, the calibration curves, and **ROI-by-grade — with B/C inverted, "MLB-C +4.57%" is likely an artifact of a meaningless letter.** --- # MARKET-EFFICIENCY SCALING CHECK — 2026-07-30 (report-only). **VERDICT: FLAT.** **Premise correction first (measured):** the claim that "full-output and collapsed grades agree 100%" does not hold — on 512 rows carrying both they agree **17.8%**, and **33.8% differ by 3+ tiers**. The prior discrimination result stands (champion letter r=0.0050 null vs probability r=0.1313; MLB 0.0686 n.s. vs 0.2356 p≈0.0004). Repo unchanged between orders. **The collapse was not a phantom and the re-adjudication list stays open.** **0.1 `marketEfficiency.js` does not exist** — zero occurrences of `market_efficiency` / `efficiency_score` anywhere. The spec's 0.85/0.60/0.55 values DO appear in `grade_thresholds.json` but those are **probability bands**, a coincidental overlap, not efficiency scores. **0.2 The base edge thresholds do not exist either** — `engine1.js` has **zero `edge` references**; the grade is an additive factor index, not an edge-vs-threshold comparison. So `threshold = base × efficiency` has **no host**. **Phase 1 dispositive: `engine1.js` has ZERO `sport` references.** Sport is not an input to `computeFactors`, so per-market or per-sport scaling is structurally impossible in the live grader — not merely unwired. Applies to the champion. **Phase 2:** the matched-edge test is confounded (edge isn't the grading input — the same market emits B and C at one edge). The discriminating aggregate: mean grade index **wnba points 4.71** (mean edge 10.2) vs **mlb hits 4.58** (69.5) vs **mlb total_bases 4.32** (84.9) — the efficient market earns the highest grades on one-eighth the edge, the opposite of the spec. **Scope:** a flat threshold is a grade-CALIBRATION gap — it does **not** touch the projection or the CLV edge (which measured `p_win`, never the letter), so it is not a third shadow-model alarm. But it is **not independently bounded**: with no threshold step to multiply, efficiency scaling presupposes probability grading. It is rule **R4 of `specs/full-output-grade-mapping.md`** and belongs to that MLB-first challenger. --- # TAKEABLE TAGGING BUILT · EFFICIENCY CHALLENGER BLOCKED — 2026-07-31 → `specs/takeable-tagging.md` **Champion grade byte-identical (verified by diff).** Additive tags only. **BLOCKED — the efficiency challenger.** Review Zero found all three inputs ABSENT: efficiency scores (zero occurrences anywhere), base edge thresholds (`engine1.js` has zero `edge` references — the grade is not edge-vs-threshold), and the claimed ±0.05 additive nudge (the only 0.05s on the grade path are a teammate-absence feature, a bvp cutoff, and the shrink-toward-0.5 term). With no additive scaling to swap, no threshold to multiply, and **zero `sport` references in `engine1.js`**, a differs-in-exactly-one-thing challenger cannot be constructed. It needs **R1 probability grading** first (`specs/full-output-grade-mapping.md`); shipping R1+R4 together would attribute an R1-driven re-letter to the efficiency fix. Coverage compounds it: **9 of 11 live markets have no specced score.** **BUILT — ledger takeable tagging (deferred C2).** `src/config/takeableStandard.js`: floor on the minus side, **uncapped plus** — deliberately NOT `valueEngine.isTakeable` (the −160..+200 promotion band). A +400 prop is not promotable but IS takeable; a test locks the divergence. Absent price → `null`, never `false`. The floor is **policy, not derived**, and each row records `takeable_floor` so a re-derivation can re-tag. Migration 034 applied + tracked. **Backfill: 1,254 rows → 1,246 tagged (781 takeable / 465 below floor), 8 NULL with `null_despite_price = 0`; settled 1,163 and graded 1,254 unchanged.** **NOT applied — the model-version boundary tag:** no scaling change shipped, so no boundary exists; stamping one would record a model transition that never happened. 312 suites / 3,890 tests green, web build exit 0. --- # EDGE-SHADING CHALLENGER — built + measured 2026-07-31 → `specs/edge-shading-challenger.md` Challenger only; champion byte-identical; nothing promoted. The mechanic is sound and built (`adjusted = raw_edge × f(e)`, `f` bounded to (0,1], one fixed bar that never moves; same raw 6% edge → **A** in soft `mlb:total_bases`, **B** in sharp `nba:points`, unit-proven). **But the measurement says the flooding is NOT fixed:** on 1,250 live rows the challenger grades **79.0% A / 80.9% A-or-B** (MLB 93.4% A) vs champion 0.2% A. **Why — two findings.** (1) **The shading is a no-op on the live board: 0 of 1,250 rows are actually shaded.** 96.5% are unscored (f=1) and the one scored market present is the anchor (f=1.0 by construction); `mlb:strikeouts` and `nba:points` are absent from the ledger entirely (our basketball is `wnba`). (2) **The input scale is the bug, not the placement.** Against a fixed 5% bar the RAW edge already clears A on 100% of MLB doubles and 89.6% of hits, with MLB's median raw edge at 60% — twelve times the bar. **Applying the sharpest score in the spec (f=0.647) to every row still leaves 75.8% clearing A.** A multiplier bounded ≤1 cannot close a 12× overshoot. `edge_pct` is a price-free `(proj−line)/line` gap whose scale is a function of line size — not a betting edge, so no fixed betting-edge bar is meaningful against it. **Unblocking needs the input replaced (`p_win` vs `fair_prob`, both already stored), not the multiply moved**, plus scores fit from our own record for the 9 of 11 live markets that have none. 313 suites / 3,899 tests green, web build exit 0. --- # PROMOTION GATE NOT PASSED · ORDER B SHIPPED — 2026-07-31 → `specs/edge-pct-display-retirement.md` **No flip.** Champion grade byte-identical; projection/p_win/CLV untouched. **Gate: 3 of 4 prerequisites fail.** Scores are estimated priors (and the premise's NBA 0.72 / WNBA 0.68 are not in the code — there is no WNBA score); **the version-boundary tag never landed** (`modelEras.js` has zero shading refs); **no rollback flag exists**. Takeable tags did land (034). **The approved delta is wrong.** Approved 43.6% re-letter, efficient tighten / soft hold. Measured on 1,250 rows: **97.4% change, 79.8% UP**, → **79.0% A-family (MLB 93.4%)** vs champion 0.2%, with **0 rows actually shaded**. The re-letter is entirely the grading-basis switch, not efficiency shading (inert: 96.5% of markets unscored, the one scored market is the f=1 anchor). Flipping would mint A's across 79% of an append-only record on a letter with r ≈ 0.005 vs outcomes. **Order B shipped:** edge_pct display retired from GradeResultCard (strip, EDGE cell → `—`, ladder rung) and SoccerGradeResult; DeskShowcase kept; **computation + signed-edge sort fallback survive** (deleting them re-breaks the 07-29 sort fix). Two build-breakers fixed; two pre-existing sign-colour tests superseded by the stronger "no edge figure renders at all". 314 suites / 3,908 tests green, web build exit 0. --- # MATRIX REFRESH — 2026-07-31 → full re-derivation in `specs/pre-audit-status-pull.md` Re-derived from repo `10aaaeb` + live prod probes (nothing inherited). **15 of 26 fully done.** **No promotion has occurred.** The shading challenger is imported by zero production files and live grades carry **0.0% A-family** (MLB `{B:1,C:4}`, WNBA `{B:15,C:10}`). Neither the "92.9%" nor the "43.6%" re-letter figure was ever measured here; the challenger's real numbers were 97.4% would-change / 79.8% up / 79.0% A, with **0 of 1,250 rows actually shaded**. **Changed since the last matrix:** row 18 **Book comparison → DONE** (`BookComparisonPanel` routed to the grade card — the headline dead component is resolved); row 4 **Grade card HONEST improved** (edge_pct display retired, `EDGE` renders `—`); row 17 ladder rung % also retired. **Still dead code:** `ShareCard` (0 real importers), `MobileEdgeBoard` (0, correctly hidden), `DemoScan` (0). **Still orphaned (live, 0 nav links):** `/intelligence`, `/soccer`, `/marketplace`, `/notifications`, `/slip`, `/compare`, `/parlay` (drawer-only). **404:** `/system`, `/offseason`. **LIVE-but-not-HONEST: none found.** **Design is NOT complete:** Live tracking, Slip reader and Newsletter are shipped but have **no design artboard** — design is the gap, not build. Offseason is the reverse (designed, never built). **Chrome audit manifest: 11 items**, four of which need an **entitled Desk session** (grade card entitled half, alt-line ladder, entitled top-graded board, ledger). --- # BOUNDARY NOT WRITTEN + BUILD TRIAGE — 2026-07-31 → `specs/incomplete-surface-triage.md` **No promotion exists, so no recalibration boundary was written** (writing one would fabricate a model transition in an append-only record). Proofs: every deployed `code_sha` in the last 5 days is a documented session commit stamped `engine1@2026-07-20`; daily A-family share 07-24→07-30 is flat at 0.0-1.6% with no step change; `efficiencyShading` has zero production importers. Neither the 92.9% nor the 43.6% re-letter figure is attested — the only measured numbers (full board, 1,250 rows) were 97.4% would-change / 79.8% up / 79.0% A, with **0 rows actually shaded**. **Triage: 14 surfaces, 5 waves.** W1 wiring (`/intelligence`, `/slip`, `/parlay`, `/marketplace` after a copy pass) · W2 design-only artboards (Live tracking, Slip reader, Newsletter — built/live/honest, DESIGN is the only gap) · W3 self-contained (`/compare`, ShareCard host, `/notifications`) · W4 model-gated (price-triplet MODEL leg + edge board — need `p_win` vs `fair_prob`; `edge_pct` would re-ship the 620% lie) · W5 quota/sport-gated (`/soccer` blocked on odds-api 0/500, `/system`, Offseason). --- # WAVE 1 WIRED — 2026-07-31 → `specs/wave1-wiring.md` Three surfaces **proven to work with real data, then linked**; `/marketplace` completed honestly. No grade/ledger/model/scoring change. - **`/intelligence`** → nav-linked + **added to GATED_ROUTES** (its feed 401s signed-out). Gating is server-side by tier (desk 50 / non-desk 8), never blur-over-full-data. **`/system` is NOT a duplicate to build** — `System.dc.html` is a multi-surface artboard whose INTELLIGENCE section is already this page; the 404 is correct. - **`/slip`** → nav-linked after parsing a real DraftKings slip **3/3 legs**. Layout-rigid: an unsupported layout returns **zero legs, never wrong ones**; real-world hit-rate CANNOT DETERMINE yet. - **`/parlay`** → **direct nav link** (was drawer-hash only); stays OPEN as the free parlay funnel. - **`/marketplace`** → every item now states **"Not built yet."**; subhead: *not a purchase, not a pre-order, not a promise of a ship date*; **no profit claim**; the waitlist capture was already real. Matrix effect: rows 16 (Parlay lab), 22 (Slip reader) and 25 (`/intelligence` half) move from **WIRED: NO → YES**. 315 suites / 3,920 tests green, web build exit 0. --- # WAVE 3 — 2026-07-31 → `specs/wave3-compare-and-resolution-tail.md` **`/compare` BUILT** (row 20 → real). A same-market head-to-head on the live player feed: rows aligned on measures both sides share, `NO DATA` for an unresolved side, `—` never 0 for a one-sided measure, refusal when neither resolves, and **NO VERDICT**. Live-verified: Judge vs Ohtani, 5 of 5 shared measures; bogus name → NO DATA. **Resolution tail — ALL FIVE outputs scoped, none shipped** (rows 23 ShareCard, `/notifications`, result posts, recap): share-card generation **SPEC'D-NOT-BUILT** (absent from the resolve fanout; renderer has zero callers) · push/Telegram/Discord **BUILT-NOT-FIRING** (env-gated; `push_subscriptions` and `user_notifications` both **0 rows**) · recap **SPEC'D-NOT-BUILT** (no file). **And nothing calls `/api/grading/resolve` — there is no ESPN poller in the repo**, so the tail is unreachable regardless. The live settle path emits ops alerts only, with zero user-facing output. 316 suites / 3,930 tests green, web build exit 0. --- # DESIGN-vs-BUILD GAP AUDIT — 2026-07-31 → `specs/design-vs-build-gap-audit.md` **61 implementable items** enumerated from `specs/design-reference/` (Jul 22) against the current repo: **BUILT-TO-SPEC 20 · BUILT-BUT-DRIFTED 7 · PARTIAL 16 · ABSENT 18.** The design is ahead of the build; the gap is implementation, not design. **Biggest gap:** the glyph library — **38 of 83 SVGs wired (46%)**, and the design implies **74 display archetypes vs the registry's 41**. **Drift on recently-built surfaces:** book comparison (wired 07-29) has **no crown, no disagreement axis, no SPLIT chip, no movement strip**; the mobile tab bar lacks the designed **READ-FAB**; calibration gates at **n≥20 vs the designed N30**. **Correction to the earlier status pull:** the **Newsletter IS designed** (S5 "The Report") → design-exists-needs-build. Only **Live tracking** and **Slip reader** are genuinely design-missing. **Six-wave ordered build list:** self-contained (glyphs, primitives, boundary-channel blue) → scanner- nudge-gated → model-gated (Price Triplet EV leg, calibration curve) → **resolution-pipeline-gated (share-card masters — the tail has no generation step and no trigger)** → licensing-gated (book logos, push-to-book) → large surface builds (Offseason, S3 media, The Report, S2 primitives). --- # D1-A SHIPPED — 2026-07-31 (design self-contained wave, part A) Backend untouched. **Glyphs:** 6 classifier-backed combat marks wired from the package SVGs (GLYPHS 38→44), replacing emoji fallbacks; 39 package SVGs with no classifier deliberately NOT wired (they'd render nothing) and 2 classifier-backed archetypes have no package SVG — both held for D1-B. **Boundary channel completed:** PriceTriplet's `NO_MODEL` was the last boundary state rendering in neutral text; it now uses `--priced-out`, so the blue law covers every "can't hand you this" state. **Reaction primitives** (`lib/reactions.js` + keyframes) at exact HANDOFF timings, with `nudge()` refusing a no-op so it can never run as an idle loop. **READ-FAB** at exact geometry (50px / translateY(-14px) / 6px ring). Audit correction: the `#0E0E14` card token was already tokenised. 317 suites / 3,946 tests green, web build exit 0. **Not done, carried in D1:** row-hover rationale, IntersectionObserver reveal, team-gradient chips.