From 2321267346a997e71b84dcc7a110ab925e8905ba Mon Sep 17 00:00:00 2001 From: Kev Date: Mon, 20 Jul 2026 12:09:12 -0400 Subject: [PATCH] STATE: harness armed + closing capture started; reverted my own non-close writes --- specs/STATE.md | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/specs/STATE.md b/specs/STATE.md index 2e692af..8cc1150 100644 --- a/specs/STATE.md +++ b/specs/STATE.md @@ -133,6 +133,48 @@ exist locally; harmless, the data restores completely. --- +## 🟢 HARNESS ARMED + CLOSING CAPTURE STARTED (2026-07-20 ~16:10 UTC) +Both verified by INDUCING the real code path — never by waiting for a slot. + +**A — Backtest harness runs on OUR scheduler.** `snapshotScheduler` fires it at +`HARNESS_HOUR_UTC` (default 14), appends to `harness_results`, and +`opsWatch.harnessStaleAlarm` pages if it stops (a validator that isn't running +looks exactly like one that keeps passing). No external dependency. +**INDUCED live:** `verdict INSUFFICIENT_HISTORY, scored 35, joined 283, +snapshots 478` — the correct, passing output. `POST /api/internal/harness/run`. + +**B — Closing capture (CAPTURE ONLY; no CLV metric, as ordered).** +- **C4 diagnosed:** `closing_line` is ONE overwritable field with no timestamp + and no provenance. `captureClosing` writes the current line and, on a prop + match failure, silently leaves the earlier value (= the lock) in place — so + "captured a real close" is indistinguishable from "never updated". It is + **92 % equal, not 100 %** (56 rows DID move): the defect is **provenance**. +- **`closing_captures` (migration 029)** — append-only, never overwritten, BOTH + raw side prices retained so the existing de-vig engine computes the fair + closing probability later. Sharp (`pinnacle`) vs book close kept distinct: + "beat the market" and "beat our book" are different questions. +- **JOIN drops `line` on purpose** — a close that MOVED off the graded line is + the whole point of CLV. Verified safe: all 164 identity groups have exactly + ONE line per `(sport, player_key, stat, side, game_date)`; zero ambiguity. +- **Wired into the intraday refresh** (already polls ~20 min through slate + hours) with a capture-rate alarm — a missed close is unrecoverable. +- **🔴 ODAWA IS NOT CAPTURABLE.** `odawa` exists only as a UI preference option + in onboarding/settings — no adapter, no `ALLOWED_BOOKS` entry, no feed. CLV + vs our own book cannot be measured until a real Odawa feed exists. +- **Refusals proven first (test-first):** unbound game_time, doubleheader + ambiguity, missed window, or a one-sided price → `missed_reason` and **NO + price**. Induced live: 1,076 rows correctly refused `one_sided_price`. + +### ⚠️ MY OWN ERROR, CAUGHT AND REVERTED +To force a capture I widened the window to 1,200 min and **persisted 7,114 +rows** — every one had a lead time of **392–602 minutes**, i.e. 6.5–10 hours +before lock. **Those were not closes.** Leaving them in a table named +`closing_captures` would have poisoned the first CLV computation with pseudo- +closes. **All 7,114 deleted; table verified back to 0.** Verification is now +done with `?dry=1`, which proves the pricing path (wnba: 486 rows priced, 0 +missed) while writing nothing. The real 45-min window currently yields 0 rows +because no game is near lock — which is the correct answer, not a failure. + ## 🟢 HEAL EXECUTED (Order 2, 2026-07-20 ~10:00 UTC) — record is clean Rollback point first: `vyndr-20260720-093821.dump` (856,890 B) **verified ON the Storage Box**, not just exit 0.