Files
vyndr/specs/free-proof-surface-review-zero.md
builtbykev 4c302b5722 report: free proof surface Review Zero — three of four leads have no data source
Nothing built. Docs only. The premise was that this is cheap assembly over
existing aggregates; verified, it is not.

0.1 FILTERABILITY — the endpoints are NOT filterable. Probed live:
    /api/ledger/accuracy?sport=mlb -> total 937
    ?sport=wnba -> total 937
    ?window=7 -> total 937
    identical payloads; the params are ignored (the req.query reads at
    routes/ledger.js:61-63 belong to a different route than /accuracy at :68).
    Sport and tier CAN be sliced client-side from /api/accuracy's sports map and
    /api/ledger/model's by_tier. TIME WINDOW CANNOT — window_days is fixed at 30
    inside getModelAggregate with no param and no stored series, so
    "accuracy over time" has no data source.

0.3 CLV CANNOT LEAD WITH A NUMBER. /api/ledger/model exposes the aggregate, and
    live it returns beat_close_pct = null and clv_distribution = null despite
    clv_sample 937. They are null BY DESIGN: ledgerService publishes them only
    when clvCaptureReliable() passes, and it does not — the capture is still the
    starved instrument the 07-28 repair improved but did not finish. The trap to
    avoid is exact: clv_beat/clv_sample = 34/937 = 3.6% is computable and would
    be WRONG, because the value is null due to instrument distrust, not a missing
    division. Publishing it would be the marketing fabrication this order most
    forbids. CLV can only lead with an honest absence.

0.2 The honest-record laws are ALREADY enforced at source: buckets return
    A pct:null (n=2), B 60% (512), C 57% (413), D pct:null, F pct:null — thin
    tiers already refuse to round. C genuinely sits below B, which is the
    unflattering truth and must be shown as-is.

0.4 CALIBRATION CURVE has no data source — clv_distribution is null and there is
    no claimed-vs-actual endpoint; the 07-26 calibration work was a one-off
    read-only measurement, never wired to a served surface.

BUILDABLE NOW: tier hit-rates by sport with existing hollows preserved,
client-side sport/tier filtering, the capped 3-call sample, and honest state copy
including a CLV not-yet-publishable panel that names the reliability guard.

NEEDS ITS OWN ORDER FIRST: CLV as a leading number (blocked on capture
reliability, not presentation), accuracy over time (needs a param or daily
series), the calibration curve (needs a claimed-vs-actual endpoint).

RECOMMENDS shipping tier-record-forward with an honest CLV building panel rather
than CLV-forward — CLV-forward with a null cannot lead, and with 3.6% would be a
lie. That preserves the premise's strongest claim (a real thin honest record
out-credibilizes a fake fat one) without inventing a number.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QJs13VsyiSKYQP6rj3NNmc
2026-07-31 07:43:12 -04:00

83 lines
5.1 KiB
Markdown

# FREE PROOF SURFACE — REVIEW ZERO (report; surface NOT built)
2026-07-31. Nothing built. `git diff` = docs only.
The order's premise is that this is assembly over existing honest aggregates ("Code's *cheap*
claim — verify it"). **Verified: it is NOT cheap, and three of the four things the surface is
supposed to lead with have no data source today.** Building the page anyway would mean
inventing numbers — the one thing the order forbids most explicitly.
## 0.1 — FILTERABILITY: **THE ENDPOINTS ARE NOT FILTERABLE. VERIFIED BY PROBE.**
`/api/ledger/accuracy` accepts nothing. Live:
?sport=mlb -> overall.total 937
?sport=wnba -> overall.total 937
?window=7 -> overall.total 937
Identical payload every time — the params are ignored (the `req.query.sport/tier` reads at
`routes/ledger.js:61-63` belong to a DIFFERENT route, not `/accuracy` at `:68`).
**What CAN be sliced today:** `/api/accuracy` returns a real **`sports` map** (`mlb`, `wnba`)
each with its own `sample`/`byGrade`/`min_sample`, and `/api/ledger/model` returns `by_tier`.
So **sport and tier are servable client-side from existing payloads.**
**TIME WINDOW IS NOT.** `window_days` is fixed at **30** inside `getModelAggregate`; there is no
param and no historical series. **"Accuracy over time" has no data source** — it needs a backend
param (or a stored daily series), which is a build, not assembly.
## 0.3 — 🔴 CLV CANNOT LEAD WITH A NUMBER. THE CANONICAL AGGREGATE RETURNS NULL.
CLV *is* exposed — `/api/ledger/model``aggregate` — and here is the live payload:
settled 937 · hits 547 · misses 390 · hit_pct 58 · pending 91
clv_sample 937 · clv_beat 34 · clv_faded … · clv_flat …
beat_close_pct = null ← the number the surface was to lead with
clv_distribution = null
window_days 30 · min_sample 20
`beat_close_pct` and `clv_distribution` are **null by design**: `ledgerService` publishes them
only when `clvCaptureReliable() && settled >= 20 && clv_sample > 0`. The reliability guard is
false — the capture is still the starved instrument the 07-28 repair improved but did not
finish (closing_prob 59→406 of ~1,250 rows).
**So the honest CLV headline today is an ABSENCE, not a percentage.** And the temptation to
avoid is precise: `clv_beat / clv_sample` = **34/937 = 3.6%** is computable and would be
**wrong** — it is null *because the instrument is not trustworthy*, not because nobody did the
division. **Publishing 3.6% as "beat close" would be exactly the marketing fabrication this
order forbids.** CLV leads with *"tracking since … · building · not yet publishable"* and names
why — which is defensible, but it is a different surface from the one specced.
## 0.2 — HONEST-RECORD LAWS: **ALREADY HONORED. PRESERVE, DON'T REBUILD.**
`/api/ledger/accuracy` buckets: **A `{hits:1,total:2,pct:null}` · B `{309/512, pct:60}` ·
C `{235/413, pct:57}` · D `{1/5, pct:null}` · F `{1/5, pct:null}`.** Thin tiers already return
**`pct: null`, not a rounded number** — the hollow law is enforced at the source. **C at 57% is
genuinely below B at 60%**, which is the honest, unflattering truth and must be shown as-is.
## 0.4 — CALIBRATION CURVE: **NO DATA SOURCE.**
The pack's S4 curve needs *claimed vs actual per probability bucket*. `clv_distribution` is null,
and there is **no claimed-vs-actual endpoint at all**. The 07-26 calibration diagnosis was a
one-off read-only measurement, never wired to a served surface. **The curve cannot be assembled
from anything live** — it is a build.
## WHAT IS ACTUALLY BUILDABLE NOW (honest assembly, no new metrics)
1. **Tier hit-rates by sport** — real: overall 937 @ 58%, plus per-sport `mlb`/`wnba` splits and
`byGrade` buckets **with the existing `pct:null` hollows preserved**.
2. **Sport + tier filtering** — client-side over `/api/accuracy`'s `sports` map. No backend work.
3. **The capped 3-call rotating sample** — already served on the snapshot (Build 1), resolved-only.
4. **Honest state copy** — "tracking since · n building · promising, accruing", and the CLV panel
as an explicit *not-yet-publishable* state naming the reliability guard.
## WHAT NEEDS A BUILD FIRST (and should be its own order)
- **CLV as a leading number** ← blocked on capture reliability, not on presentation.
- **Accuracy over time** ← needs a windowed param or a stored daily series.
- **Calibration curve** ← needs a claimed-vs-actual endpoint.
## RECOMMENDATION
Ship the surface as **tier-record-forward with an honest CLV "building" panel**, not
CLV-forward — because CLV-forward with a null cannot lead, and CLV-forward with 3.6% would be a
lie. Then unblock CLV (capture reliability) and add the curve/time-series as their own orders.
That keeps the strongest claim of the premise intact — *a real thin honest record
out-credibilizes a fake fat one* — without inventing a single number.
## TAGS
VERIFIED: filter params ignored (probed); `beat_close_pct`/`clv_distribution` null on the live
canonical aggregate; hollow law already enforced at source; no calibration endpoint exists.
CANNOT DETERMINE: none. **BLOCKED: CLV-forward lead, accuracy-over-time, calibration curve.**