docs: /api/books contract + crown gate (Book Comparison order)
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:
@@ -296,3 +296,28 @@ Every graded read (snapshot `grades:{sport}`, `/api/snapshot/:sport`, `/api/hero
|
||||
|
||||
DESIGN: the triplet + VALUE marker + refusal copy are Session-2 design surfaces
|
||||
(reveal card, board row, hero). Backend ships the fields; rendering is Design's.
|
||||
|
||||
## Book Comparison — `/api/books` (per-book price display, snapshot-locked)
|
||||
|
||||
Data-only layer for the (still-unrouted) `BookComparison.tsx` grid. Never touches
|
||||
the grade path.
|
||||
|
||||
- `GET /api/books/:sport/:player/:stat?side=over|under` → the honest per-prop
|
||||
grid: `{ player, stat, line, side, books:[{book,line,over_odds,under_odds,
|
||||
isBest}], bestBook, bestOdds, bookCount, savings, crowned }`. HONEST-ABSENT:
|
||||
a single-book prop returns that one book with `isBest:false, bestBook:null,
|
||||
crowned:false` — never a placeholder second row. `:player` is matched by
|
||||
`nameKey` (accent/dot/nickname-folded).
|
||||
- `GET /api/books/:sport?side=&limit=` → "best lines tonight" (`bestLines`, sorted
|
||||
by savings). This is a CROWN claim, so it returns `[]` while the crown is gated
|
||||
off. Response `source` = `bookprices` (snapshot-locked store serving) or
|
||||
`odds-cache` (fallback before first snapshot) — also the deploy fingerprint.
|
||||
- **The crown is threshold-gated + OFF by default** (`BOOK_CROWN_ENABLED=1` to
|
||||
enable). Pre-registered gate: median same-line spread ≥8¢ OR ≥2 implied-prob
|
||||
pts (`scripts/measure-book-spread.js`). Measured 2026-07-27 on the live feed:
|
||||
MLB median 5¢/0.95pp, WNBA 7¢/1.38pp → NOT met → crown does NOT ship. Render
|
||||
books WITHOUT crowning one until a future measurement clears the bar.
|
||||
- Source store: `bookprices:{sport}` (Redis, SNAP_TTL), written by
|
||||
`snapshotService` from the pre-dedup multi-book `props`. Grouped
|
||||
`{player, stat_type, books:[...]}`, normalized-name-keyed. DISPLAY-ONLY —
|
||||
fenced from grade/selector/challenger/ledger.
|
||||
|
||||
Reference in New Issue
Block a user