STATE: Session 67 — price layer gated at two doors, read card wired
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VCNgGSt5qvcLxaeQqa7Zpj
This commit is contained in:
+94
-1
@@ -1,5 +1,5 @@
|
||||
# VYNDR — STATE OF THE WORLD
|
||||
### As of `8cf9cbf` (main, DEPLOYED + fingerprinted live), 2026-07-20. This file opens every future session. **Start with the CURRENT STATUS + OPEN ITEMS block below.**
|
||||
### As of `4e2f488` (main, DEPLOYED + fingerprinted live), 2026-07-20. This file opens every future session. **Start with the CURRENT STATUS + OPEN ITEMS block below.**
|
||||
|
||||
---
|
||||
|
||||
@@ -131,6 +131,99 @@ exist locally; harmless, the data restores completely.
|
||||
`specs/snapshot-retention.md` (Phase 2 report + schema) ·
|
||||
`specs/audit-data/grade-collapse.md` · `specs/audit-data/gate-simulation.md`.
|
||||
|
||||
---
|
||||
|
||||
# 🟢 SESSION 67 — PRICE LAYER GATED + WIRED (2026-07-20)
|
||||
|
||||
## ⚠️ THE PREMISE WAS WRONG TWICE — read before trusting a "wire the fields" order
|
||||
1. **There is no `/api/slate`.** The board reads `GET /api/snapshot/:sport`.
|
||||
2. **The snapshot already carried the price fields.** `book_odds`, `fair_odds`,
|
||||
`model_odds`, `p_win`, `ev_pct`, `value`, `takeable`, `fair_prob`,
|
||||
`devig_method` were all live. Nothing needed adding.
|
||||
3. **`fairLine` does not exist** (zero hits repo-wide). The Option-A
|
||||
"derive from fairLine" instruction had no referent — `fair_odds` is already
|
||||
a real de-vigged American price.
|
||||
|
||||
## Phase 0.5 gates — all PASS, verified numerically
|
||||
- **Is it a price?** Yes. `fair_odds` = American odds from
|
||||
`impliedProbToAmerican` inside `devigTwoWay`; `fair_prob` is the probability.
|
||||
Both distinct from `line` (the stat threshold).
|
||||
- **Numeric match?** **8/8 EXACT.** Recomputed `fair_odds`+`fair_prob`
|
||||
independently from stored raw over/under prices; every value matched to the
|
||||
integer and to 3dp.
|
||||
- **Poison-independent on quarantine rows?** **YES, proven on the quarantined
|
||||
cohort itself.** `devigTwoWay(over, under)` takes market prices only — no
|
||||
model term is reachable — and the 8 rows recomputed above are all
|
||||
`wrong_opponent_grade`. The poison is in the GRADE, not the price. So
|
||||
**quarantine suppresses the MODEL leg only; the fair leg stands.**
|
||||
|
||||
## 🔴 THE REAL FINDING — the model price was PUBLIC
|
||||
`GET /api/snapshot/:sport` is unauthenticated and was serving `model_odds`,
|
||||
`p_win`, `ev_pct`, `value`, `takeable` to anonymous callers on **25/25 live
|
||||
rows**. The Session-66 gate on `/api/analyze` was bypassed entirely.
|
||||
**`/api/hero-prop` was a SECOND door** — it reads Redis directly via
|
||||
`heroPropService`, so the first fix didn't cover it.
|
||||
|
||||
**`src/utils/snapshotGating.js` strips FIVE fields, not one** —
|
||||
`model_odds` is the price, **`p_win` IS the price in another base**, and
|
||||
**`ev_pct` is INVERTIBLE** (ev = f(p_win, book_odds); book_odds is public, so
|
||||
ev hands the price over). `value`/`takeable` bound it. Market legs
|
||||
(`book_odds`, `fair_odds`, `fair_prob`, `overround`, `devig_method`) stay on
|
||||
**every** tier — **the fair leg is never the paywall**.
|
||||
`src/utils/requestTier.js` resolves tier from a bearer token when present and
|
||||
**FAILS CLOSED to `free`** on every error path, so a resolution failure can
|
||||
only withhold, never leak. Responses now vary by entitlement → `/:sport` and
|
||||
`/hero-prop` emit `private` Cache-Control for authenticated callers and both
|
||||
Next proxies forward the bearer token.
|
||||
|
||||
## Read card — why it was empty, and the fix
|
||||
A manual scan carries **no market** (`{player, stat, line, direction}`), so the
|
||||
engine has no over/under to de-vig — `book_odds`/`fair_odds` were legitimately
|
||||
absent. `lookupSnapshotPrices` in the Next `/api/scan` route recovers them from
|
||||
the pre-graded snapshot (the same cache-only read it already did for locked
|
||||
odds + team). Join is EXACT on **player + stat + line + side** (`fair_odds` is
|
||||
side-specific) and returns nothing unless book AND fair are both present — a
|
||||
user-chosen line the board never graded borrows no other line's price.
|
||||
|
||||
## 🔴 LIVE INDUCTION CAUGHT A SECOND CLASS OF BUG
|
||||
With the leg stripped, `LiveHeroProp` forwarded everything to `PriceTriplet`
|
||||
**except `model_price_locked`** → `deriveValueState` fell to the
|
||||
missing-model-price branch and the landing page told every anonymous visitor
|
||||
**"MODEL READ WITHHELD"** — quarantine's copy, which says our own data is
|
||||
untrustworthy. Nothing was poisoned; it was the paywall.
|
||||
**A paywall must never wear poison's face.** Unit tests and markup review both
|
||||
passed this; only rendering the deployed page caught it.
|
||||
|
||||
## Live fingerprint (anonymous, cache-busted)
|
||||
- Snapshot: model fields `[]`, market fields intact, `model_price_locked: true`
|
||||
- Read card `/api/scan`: `book -150 · fair -126 · model null · locked true`
|
||||
- Landing hero renders: **BOOK −153 · ◆FAIR −129 (amber) · MODEL [LOCK BAR]**,
|
||||
verdict **"MODEL PRICE ON ANALYST"** + UNLOCK CTA
|
||||
- `/dashboard`, `/ledger`, `/parlay` — 200, no triplet, unchanged. No consumer
|
||||
reads `ev_pct`/`model_odds`/`p_win`, so the strip broke nothing.
|
||||
|
||||
## 📊 FAIR-LEG ABSENCE: 0.0%
|
||||
636 graded rows: 636 with book, 636 with fair, **0 one-sided**. The hero number
|
||||
is not a sometimes-number on current data.
|
||||
|
||||
## ⚠️ PRODUCT CALL PARKED FOR KEV
|
||||
The landing hero is anonymous, so it now shows the LOCK instead of the full
|
||||
triplet it showed this morning (`VALUE +21.1% VS FAIR`). That follows the
|
||||
stated free-tier rule exactly, but trades a strong shop-window moment for gate
|
||||
consistency. **Reversal is one line** — add `model_price: true` to the free
|
||||
tier in `src/config/tiers.js`, or special-case the hero route.
|
||||
|
||||
## Still open
|
||||
- **Quarantine flag is NOT available at snapshot build.** No service writes
|
||||
`quarantine_reason` (manual SQL only); it's a retrospective judgement, so a
|
||||
fresh row can never carry it. The component handles the state if it ever
|
||||
arrives; wiring an always-null field was refused.
|
||||
- **Slate row** still held — `lib/marketBreadth.js` computes LINES only.
|
||||
- **Ledger / public profile** still out — no fair-odds column.
|
||||
- Screenshots unavailable again (browser capture tool errored all session);
|
||||
substituted computed-style readback per state.
|
||||
|
||||
|
||||
---
|
||||
|
||||
# 🟢 SESSION 66 — PRICE-LAYER TOKENS + THE PRICE TRIPLET (2026-07-20)
|
||||
|
||||
Reference in New Issue
Block a user