Per-sport rank guard + edge diagnostic-only display + delta report

DELTA MEASURED on live prod grades (live ordering unchanged): MLB 7/8
props move (87.5%), mean 2.5 places, TOP READ CHANGES (corey seager hits
1.5 under -> jake burger hits 0.5 over). WNBA 25/25 move, mean 4.1, max 12.
This is a large re-ordering, not a tweak.

Caveat recorded rather than buried: MLB had only 8 graded props at
measurement time. The percentages are real; the sample is one small slate.
Re-run before the flip -- it is one call.

PER-SPORT DOCTRINE ENFORCED IN CODE. WNBA moves the most and must NOT
adopt this: its p_win is anti-predictive, so ranking that board by p_win
would sort it by a signal measured to point the WRONG WAY -- worse than
the incumbent, not better. A comment would not have stopped a future flip
from going global, so FORECAST_RANKED_SPORTS = Set(['mlb']) gates the
forecast_rank stamp, with tests asserting no sport inherits MLB's result.
A sport joins only by passing its own holdout.

EDGE IS NOW DIAGNOSTIC-ONLY IN DISPLAY. MobileEdgeBoard.EdgeCell rendered
green (--g-a) for positive edge and red (--miss) for negative. Two things
were wrong: green/red IS a quality claim on a quantity that does not
predict, and ROW-GRAMMAR reserves red for settled-negative ONLY -- a
negative diagnostic is not a settled loss. Now neutral mono with a
diagnostic tooltip; header reads "MKT GAP · DIAGNOSTIC". The number is
still shown -- no display went blank. DeskShowcase neutralised likewise.

PINNACLE LOGGED, NOT ENSHRINED. Per the order, "market-not-sharp" is
PENDING-RECOVERY rather than a confirmed permanent limitation. The single
question for PropLine is in BLOCKERS.md with its evidence, and MASTER-PLAN
now carries the pending status instead of the permanent claim.

Live sorts remain byte-identical: selectTopGrades, flattenToEdgeBoard and
topGradedService all still call the incumbent.

Gates: 4,041 tests / 323 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
This commit is contained in:
Kev
2026-08-01 01:29:20 -04:00
parent 86d123945c
commit ef4ac60b81
8 changed files with 242 additions and 10 deletions
+18 -4
View File
@@ -43,14 +43,28 @@ function rampOpacity(rank: number): number {
// the pipeline's miscalibrated placeholder (seen live: 60/100/140). Rendering
// "+140%" would fabricate a signal, so we show it absent. Backend fix pending.
const SANE_EDGE_MAX = 40;
// EDGE IS A DIAGNOSTIC, NOT A QUALITY SIGNAL (2026-08-01).
//
// This used to render green (--g-a, the A-grade colour) for a positive edge and
// red (--miss) for a negative one. Both were wrong:
// 1. Green/red IS a quality claim, and edge does not predict outcomes —
// measured on n=200 settled MLB rows, corr(edge, outcome) = -0.010 under
// the incumbent ruler and -0.022 under the consensus ruler.
// 2. ROW-GRAMMAR reserves red for settled-negative ONLY (miss/dead/stale/
// faded). A negative diagnostic is not a settled loss.
// It now renders in neutral mono. The number is still shown — it is a real
// measurement and worth keeping visible — it just no longer claims anything.
function EdgeCell({ edge }: { edge: number | null }) {
if (edge == null || Math.abs(edge) > SANE_EDGE_MAX) {
return <span className="mono" style={{ fontSize: 12, fontWeight: 700, color: 'var(--text-2)', width: 48, textAlign: 'right' }}></span>;
}
const pos = edge >= 0;
return (
<span className="mono" style={{ fontSize: 12, fontWeight: 700, color: pos ? 'var(--g-a)' : 'var(--miss)', width: 48, textAlign: 'right' }}>
{pos ? '+' : ''}{edge.toFixed(1)}%
<span
className="mono"
title="Model probability minus the book's implied probability. Diagnostic only — not a ranking or a quality signal."
style={{ fontSize: 12, fontWeight: 700, color: 'var(--text-1)', width: 48, textAlign: 'right' }}
>
{edge >= 0 ? '+' : ''}{edge.toFixed(1)}%
</span>
);
}
@@ -77,7 +91,7 @@ export default function MobileEdgeBoard({
{/* EDGE BOARD header */}
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '12px 16px 8px' }}>
<span className="mono" style={{ fontSize: 10, letterSpacing: '0.24em', color: 'var(--text-0)', fontWeight: 700 }}>EDGE BOARD</span>
<span className="mono" style={{ fontSize: 8.5, letterSpacing: '0.14em', color: 'var(--text-2)' }}>EDGE </span>
<span className="mono" style={{ fontSize: 8.5, letterSpacing: '0.14em', color: 'var(--text-2)' }}>MKT GAP · DIAGNOSTIC</span>
</div>
{/* Ranked rows */}