dCLV close leg: read priced captures only (the unfixed twin)

computeDirectionalForRow selected the latest closing_captures row with no
missed_reason filter, while its sibling attachClosingProb has had one since the
CLV instrument repair. closing_captures records a refusal for every prop x book
x side on every cycle after first pitch, so a refusal always carries a later
captured_at than the last real price - latest-first returned a refusal on
26,448 of 26,448 identity groups, and computeDirectionalClv refuses on a
missedReason. That is why dclv_state has been 'unknown' on 100% of rows since
Session 64.

Measured on 600 real settled rows: 100% unknown becomes flat 45.8%, negative
23.0%, positive 22.8%, unknown 8.3%. ClvBadge will render MOVED TOWARD US 114
and MOVED AWAY 117 per 600 - near-symmetric, which is the honest shape.

Existing rows do not recompute (first-computation-wins). The re-stamp is
described in BUILD-STATE, not run.

The grade is untouched. No rows deleted.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kev
2026-08-12 00:14:12 -04:00
parent 7c8ef8b12e
commit 2271f46ab2
4 changed files with 222 additions and 0 deletions
+28
View File
@@ -3,6 +3,34 @@
## Last Updated
2026-08-12
## Fix B1 (2026-08-12) — dCLV close-leg filter ✅
4,780 tests / 372 suites, web build exit 0. **Grade untouched (0 grade-related
diff lines); no rows deleted or archived.**
- Added `.is('missed_reason', null)` + both-odds-not-null to the close leg
(`ledgerService:625`), matching `attachClosingProb:455`. Filter applied BEFORE
the limit, so it is "latest PRICED" not "latest, hopefully priced".
- **dCLV: 100% `unknown` → flat 45.8% / negative 23.0% / positive 22.8% /
unknown 8.3%** on 600 real settled rows. ClvBadge (analyst/desk) will render
**MOVED TOWARD US 114 · MOVED AWAY 117** per 600 rows — ~38% of rows gain a
badge that showed nothing before.
- 8 regression tests, incl. one proving the fixture actually exercises the old
bug (an unfiltered read returns `unknown` on the same data).
- **`missed_window` is now genuinely unread** — the precondition the RECLAIM
order correctly stopped on.
### RE-STAMP DECISION (described, NOT run)
14,083 settled rows carry a persisted `dclv_state='unknown'`. `settleLedger` is
first-computation-wins, so they will NOT recompute. To correct them:
`UPDATE ledger_entries SET dclv_computed_at = NULL WHERE dclv_state = 'unknown'`
then re-run the settle pass — it would recompute from the (unchanged, immutable)
`closing_captures` and `model_snapshots` history. Arguments both ways:
FOR — those rows are wrong, and the history to fix them exists.
AGAINST — first-computation-wins exists so a badge a user saw never flips;
these rows currently show NO badge, so a re-stamp only ADDS badges (it cannot
flip a shown one), which weakens the objection considerably.
Recommend running it, as its own order, AFTER the fix has been live a full slate
and the new-row distribution is confirmed against the simulation.
## DEPLOY (2026-08-12 03:10 UTC) — A1–A7 LIVE, grade unchanged ✅
Commit **f61ec6b** pushed to gitea, auto-deployed by Coolify, first slot wrote
2026-08-12T03:10:52Z. Pre-deploy gate: 4,772 tests / 371 suites, web build exit