d103ecf4c3
BYTE-IDENTICAL. The audit found no consumer getting the wrong axis, so this is a disambiguation, not a bug fix. 4,131 tests / 331 suites green. STEP 1 AUDIT -- and the order's premise was wrong in a useful way: the four accruing challengers read the flag ZERO times (not four) the ranking gate wants PROMOTION, gets promotion [correct] the ledger column holds the LEDGER band, consumed as such the UI (LiveHeroProp) TYPES a `takeable` field it never renders THERE ARE THREE DEFINITIONS, NOT TWO -- and I only found the third by tracing the ranking gate: 1. IDENTITY can it be bet? book identity (takeability) 2. LEDGER BAND worth recording? odds >= -160, UNCAPPED plus 3. PROMOTION worth crowning? -160..+200, i.e. band PLUS a ceiling (2) and (3) genuinely disagree, and I measured it rather than asserting it: 439 rows -- 28.2% of all takeable=true ledger rows -- carry prices above +200, up to +1300. A +1300 longshot is a real bet worth RECORDING and not one worth CROWNING. Both are correct for their own purpose. THE DANGER WAS NEVER THE LOGIC. It was that three questions shared one word, so a reader could not tell which answer they held -- and hits, which must model thin/juiced/one-sided REAL markets, would have been the next reader to guess wrong. RESOLUTION: all three now have distinct names in config/takeability.js; gradeRanking calls isWithinPromotionBand so its intent is self-evident (a test pins it byte-identical to the old valueEngine call across the whole price range); the ledger dual-writes within_price_band with `takeable` kept as a documented DEPRECATED MIRROR so nothing breaks. Column comments in the database now say what each column actually holds. I did NOT redefine `takeable` in place. Four readers and a ranking gate sit on it, and silently changing its meaning under cover of a naming change is exactly the class of move this session keeps removing. Gates: 4,131 tests / 331 suites green; next build exit 0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QJs13VsyiSKYQP6rj3NNmc