Stop persisting missed_window refusals (halt the bleed at source)
missed_window means 'this capture pass ran after first pitch'. It is a fact about our cron cadence, not the market: once a game starts the same prop emits a fresh refusal every ~20 minutes for the rest of the night, per book, per side. Measured over 7 days of production that is 332,608 rows/day - 83.1% of all closing_captures writes, ~66 MB/day - and since B1 filtered both readers, nothing reads them. The filter lives in persist(), not buildCaptureRows(), and that is the whole trick: the caller computes the capture-rate alarm from the full in-memory array, so filtering at build time would have blinded the ops alarm to the exact condition it exists to catch. captureRateAlarm is pure; a test asserts the caller still passes the full array, and that a 10-priced/90-late pass still fires at 0.10. Narrow by design: one_sided_price still persists (liquidity signal), priced captures unchanged, and the rare fault refusals still persist because each names a pipeline fault worth seeing. A missed_window row carrying a price is kept. Growth drops 400,469 -> 67,862 rows/day. The 4.2M historical rows are now static, so the cleanup is a calm decision rather than a race. Nothing deleted. Grade untouched. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2116,6 +2116,31 @@ phased plan in the Session-57 conversation / BUILD-STATE Next section).
|
||||
- **This makes `missed_window` genuinely unread**, which is the precondition the
|
||||
reclaim order stopped on. The reclaim is still downstream and still needs R2.
|
||||
|
||||
## B2 — stop writing the refusals nothing reads (non-obvious)
|
||||
- **`missed_window` is a fact about OUR CRON CADENCE, not the market.** Once a
|
||||
game starts, `buildCaptureRows` emits a refusal for that prop on EVERY ~20-min
|
||||
cycle for the rest of the night, x every book, x BOTH sides. Measured
|
||||
**332,608 rows/day — 83.1% of all closing_captures writes — ~66 MB/day**, read
|
||||
by nothing since B1 filtered both readers.
|
||||
- **THE FILTER LIVES IN `persist()`, NOT `buildCaptureRows()`, AND THAT IS THE
|
||||
WHOLE TRICK.** The caller computes `captureRateAlarm({eligible: rows.length,
|
||||
captured})` from the FULL in-memory array. Filtering at build time would have
|
||||
silently blinded the ops alarm to exactly the condition it exists to catch —
|
||||
a capture pass running late. `captureRateAlarm` is pure (two numbers, no DB),
|
||||
so it never touched the stored rows; a test asserts the caller still passes the
|
||||
full array.
|
||||
- **NARROW BY DESIGN.** `one_sided_price` still persists (real liquidity signal,
|
||||
standing feature candidate). Priced captures unchanged. `unbound_game_time` /
|
||||
`doubleheader_ambiguous` / `fetch_failed` still persist — 0 rows on record, and
|
||||
each names a pipeline fault worth seeing, which `missed_window` does not.
|
||||
A `missed_window` row that somehow carries a price is KEPT (`isUnreadRefusal`
|
||||
requires both odds null) — do not over-cut.
|
||||
- `CLOSING_PERSIST_MISSED_WINDOW=1` restores the old behaviour.
|
||||
- **The bleed was the fire; the 4.2M backlog is the scar.** Growth drops
|
||||
**400,469 → 67,862 rows/day (−83.1%)**, ~80 MB/day → ~13.5 MB/day. The
|
||||
historical 4,236,398 rows are now STATIC — the cleanup can be scheduled
|
||||
calmly instead of raced, and it no longer regrows after a delete.
|
||||
|
||||
## Active Skills
|
||||
- vyndr-voice (all user-facing output)
|
||||
- prop-analysis (grading methodology)
|
||||
|
||||
Reference in New Issue
Block a user