Files
vyndr/web/src/lib/valueState.js
T
builtbykev 6bc18d823c Honesty pass: remove every live fabrication (REMOVE/HIDE only, no feature cut)
Six live untruths corrected — no grade/snapshot/scorer/pipeline touched:
1. /compare — hardcoded Jokic A+/Wembanyama A + fake VERDICT replaced with an
   honest in-development state; removed from Nav + BottomTabBar (route still
   resolves, never the sample). Real two-player build is later.
2. Pricing — founder Desk $34.99→$44.99 (matches lib/checkout.js), Analyst
   $14.99; removed the struck $19.99/$44.99 "regular" numbers and DeskShowcase's
   stale $34.99. First-100 counter is real (ClaimMeter → Stripe countFounderSeats);
   no fake "first 50" desk claim added (no such counter exists).
3. FAQ "NexaPay" → Stripe (verified: live checkout is Next→Express→checkout.stripe.com).
4. FAQ + Features "Brier/CLV published from day one" removed (not surfaced yet) —
   returns when real. Backend Brier compute untouched.
5. MobileEdgeBoard removed from the Slate — its edge% feed was a miscalibrated
   placeholder (masked >40% as "—"); phones now show the real game cards.
6. Price triplet — never-computed model/EV now derives NO_MODEL (honest absent,
   MODEL "—" / "NOT PRICED", no verdict) instead of QUARANTINE's false "we
   suppressed our price / a leg is poisoned" copy. Fixes grade card + LiveHeroProp.

Full suite 3833 green, web build exit 0. Tests updated to the new honest contracts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VsztNChZ7vEvSR61AuMhD1
2026-07-27 06:04:00 -04:00

195 lines
8.0 KiB
JavaScript

/* ============================================================
VYNDR — THE PRICE-LAYER LAW (Session 66).
Plain CommonJS so .tsx components import it AND the Jest suite requires it
directly (same pattern as colorContract.js / vyndrTokens.js / playerName.js).
ONE function decides what a price row is allowed to SAY. The triplet renders
whatever this returns and never re-derives a verdict of its own, so there is
exactly one place where "is this value?" is answered.
THE FIVE HONESTY STATES (design: `Vyndr Price Triplet.dc.html`, ACT 01):
VALUE green — ev >= VALUE_EV_THRESHOLD *AND* the book price is
inside the takeable band. Both. Raw positive EV is
NOT value: +11.7% EV at -210 is a juiced price we
will not call a play.
PRICED_OUT blue — real edge, untakeable price. We won't call a juiced
price a value, and we won't pretend the edge wasn't
there. This state exists so green never has to lie
in either direction.
NO_EDGE grey — the honest number is already priced. Stated at full
voice, never hidden. That "no" is the instrument
working.
QUARANTINE amber — the MODEL leg is withheld (graded against inputs we
no longer trust). Book and fair still render: we
never hide the honest fair number because a
different leg is poisoned. RARE — as of Jul 2026 the
only quarantined rows are one frozen historical
cohort, so this is not a routine state.
REFUSAL dim — no fair price we'd defend. Nothing renders. No
fabricated price, no empty gauge.
TRUTH LAW: the triplet never prints a number it can't stand behind. A leg
with no value renders absent, never a zero and never a placeholder.
============================================================ */
/* ---- Backend mirror -----------------------------------------------------
These MUST match src/config/valueEngine.js. The browser can't require the
backend module, so the constants are duplicated here and a test
(priceTriplet.test.js) reads BOTH files and fails if they drift — the same
guard used for playerName.js. If you tune the band, tune it in both. */
const TAKEABLE_ODDS_CEILING = -160; // most-juiced favourite we'll promote
const TAKEABLE_ODDS_MAX = 200; // longest dog we'll promote
const VALUE_EV_THRESHOLD = 2; // a real edge, not rounding
const STATES = Object.freeze({
VALUE: 'VALUE',
PRICED_OUT: 'PRICED_OUT',
NO_EDGE: 'NO_EDGE',
QUARANTINE: 'QUARANTINE',
REFUSAL: 'REFUSAL',
// Not a verdict — a display state. The model leg exists and is honest, the
// viewer just isn't entitled to it (free tier). Book + fair render normally.
NO_VERDICT_LOCKED: 'NO_VERDICT_LOCKED',
// Honesty pass: the model price was never COMPUTED (the EV layer isn't
// producing p_win/model_odds yet) — NOT quarantined, NOT locked. The model
// leg renders absent ('—'), book + fair stand, and NO verdict is claimed.
// This exists so a never-priced row never wears QUARANTINE's "we suppressed
// our own price / a leg is poisoned" copy, which asserts a deliberate act
// that did not happen.
NO_MODEL: 'NO_MODEL',
});
/** Strict numeric parse — `Number(null) === 0` is the fabrication bug this
* whole layer exists to prevent, so nothing coerces. */
function num(v) {
if (v == null || v === '') return null;
const n = typeof v === 'number' ? v : Number(v);
return Number.isFinite(n) ? n : null;
}
/** isTakeable(american) — inside the promotable band. Mirrors valueEngine. */
function isTakeable(american) {
const a = num(american);
if (a == null) return false;
return a >= TAKEABLE_ODDS_CEILING && a <= TAKEABLE_ODDS_MAX;
}
/** isValue(american, evPct) — takeable AND clears the EV threshold. Both. */
function isValue(american, evPct) {
const ev = num(evPct);
return isTakeable(american) && ev != null && ev >= VALUE_EV_THRESHOLD;
}
/**
* deriveValueState(row) — the single verdict function.
*
* row: { book_odds, fair_odds, model_odds, ev_pct, quarantine_reason,
* refused, model_price_locked }
*
* Order matters and encodes the honesty ordering:
* 1. REFUSAL first — with no fair price there is nothing honest to show.
* 2. QUARANTINE next — the model leg is untrustworthy, so no verdict may be
* computed from it, but book+fair still stand.
* 3. Then the three real verdicts.
* A locked (free-tier) model leg is NOT quarantine and NOT refusal: the data
* exists and is honest, the viewer just isn't entitled to it — so the verdict
* is withheld rather than asserted, and book+fair render normally.
*/
function deriveValueState(row = {}) {
const fair = num(row.fair_odds);
const book = num(row.book_odds);
// 1. Refusal — no fair price we'd defend (or no market to price against).
if (row.refused === true || fair == null || book == null) return STATES.REFUSAL;
// 2. Quarantine — model leg withheld; book + fair still render.
if (row.quarantine_reason) return STATES.QUARANTINE;
// Free-tier lock: entitled data withheld, not absent. No verdict is claimed
// (the verdict IS the model leg), but this is not quarantine — the row is
// honest, it's just gated.
if (row.model_price_locked === true) return STATES.NO_VERDICT_LOCKED;
const model = num(row.model_odds);
const ev = num(row.ev_pct);
// Without a model price or an EV there is no verdict to render. This is an
// absent leg, NOT a quarantine: we never computed it, so we must not claim we
// "suppressed" or "poisoned" it. Book + fair still stand; the model leg goes
// honestly absent and no verdict is asserted.
if (model == null || ev == null) return STATES.NO_MODEL;
// 3. The three real verdicts.
if (isValue(book, ev)) return STATES.VALUE;
if (ev >= VALUE_EV_THRESHOLD) return STATES.PRICED_OUT; // edge, untakeable price
return STATES.NO_EDGE;
}
/** valueStateColor(state) — the ONE mapping from verdict to token.
* Green appears here exactly once, on VALUE, and nowhere else. */
function valueStateColor(state) {
switch (state) {
case STATES.VALUE:
return 'var(--g-a)';
case STATES.PRICED_OUT:
return 'var(--priced-out)';
case STATES.QUARANTINE:
return 'var(--amber)';
case STATES.NO_EDGE:
case STATES.REFUSAL:
case STATES.NO_VERDICT_LOCKED:
case STATES.NO_MODEL:
default:
return 'var(--text-2)';
}
}
function impliedProb(american) {
const a = num(american);
if (a == null) return null;
return a > 0 ? 100 / (a + 100) : -a / (-a + 100);
}
/**
* modelVsFair(modelOdds, fairOdds) — the "+2.9% VS FAIR" figure on the verdict
* line. It is the gap between OUR price and the honest de-vigged price, in
* implied-probability PERCENTAGE POINTS (not a ratio, and NOT book-vs-fair).
*
* Derived from the design file's own two worked examples, both of which this
* reproduces exactly:
* STATE 1 book +125 · fair +110 · model +98 → "+2.9% VS FAIR"
* STATE 3 book +118 · fair +104 · model +112 → "-1.8% VS FAIR"
* Positive = the model prices it SHORTER than fair (we think it's likelier
* than the honest number says). Null unless both legs are real.
*/
function modelVsFair(modelOdds, fairOdds) {
const pm = impliedProb(modelOdds);
const pf = impliedProb(fairOdds);
if (pm == null || pf == null) return null;
return Math.round((pm - pf) * 1000) / 10;
}
/** fmtOddsAmerican(v) — display an American price, or null for honest absence.
* Never returns '0', never returns a placeholder number. */
function fmtOddsAmerican(v) {
const n = num(v);
if (n == null) return null;
const r = Math.round(n);
return r > 0 ? `+${r}` : String(r);
}
module.exports = {
STATES,
TAKEABLE_ODDS_CEILING,
TAKEABLE_ODDS_MAX,
VALUE_EV_THRESHOLD,
isTakeable,
isValue,
deriveValueState,
valueStateColor,
modelVsFair,
impliedProb,
fmtOddsAmerican,
};