id: d3f0995378d5481e81a73e25c60c169a
parent_id: 46dd8c5a64994fd8a6287b47a949a364
item_type: 1
item_id: 60976d006f58404387784a6b90ebf04c
item_updated_time: 1782194468107
title_diff: "[]"
body_diff: "[{\"diffs\":[[0,\"ion \"],[-1,\"confirmed (see Data Pipeline)\"],[1,\"— **fix applied to scraper, pending reload verification**\"],[0,\".\\\n\\\nP\"]],\"start1\":158,\"start2\":158,\"length1\":37,\"length2\":65},{\"diffs\":[[0,\".\\\n\\\n---\\\n\\\n\"],[1,\"## D4 — Dealer button almost always reported as seat 0 ⚠️ FIXED (pending verify)\\\n\\\n**Root cause (scraper):** `collectTableState()` (table_dom.ts) correctly detects the\\\ndealer from the `<div class=\\\"dealer___ position-N___\\\">` div and stores it in\\\n**`snap.dealerSeat`** (e.g. `2`). But `buildGameStart()` (parser.ts:650) **ignored\\\n`dealerSeat`** and keyed solely off `snap.dealerName`, which is `null` whenever the\\\ndealer's position→player-name match fails → silently defaulted to `0`. Result:\\\n`dealer=0` in 19/20 hands.\\\n\\\n**Fix applied (super-marvin-userscripts, scraper — in scope):**\\\n`parser.ts` `buildGameStart` now prefers the directly-detected `snap.dealerSeat`,\\\nfalling back to the name lookup, then 0 only on true failure:\\\n```ts\\\nconst dealerSeat = snap?.dealerSeat ?? (snap?.dealerName ? this.seatForName(snap.dealerName) : 0);\\\n```\\\nBuilt to `torn/dist/torn.user.js`. **User must refresh the Torn page** to load it.\\\nVerification: next `game_start` should report the real dealer (e.g. `dealer=2` when\\\nFuckFuck/seat 2 deals) and rotate each hand; server `btn`/`sb`/`bb` tags should align.\\\n\\\n**Impact:** A wrong `button_seat` corrupted all downstream position logic\\\n(`our_position`, BTN/SB/BB tags, position-aware preflop thresholds) → bot played as if\\\nalways on the button → loose open-limp/call (J5s, Q8s, A8o, JTs). Likely the root cause\\\nof \\\"preflop limps with anything\\\". Should resolve once the button is correct.\\\n\\\n**Seat model confirmed by user:** 9 seats (0–8), hero/Bolsa always seat 0, seats go\\\nclockwise, empty seats still count. Dealer div carries `position-N___` directly on the\\\nchip (e.g. `<div class=\\\"dealer___L2uAh position-2___jgFym\\\"></div>`).\\\n\\\n---\\\n\\\n\"],[0,\"## OVERN\"]],\"start1\":366,\"start2\":366,\"length1\":16,\"length2\":1679},{\"diffs\":[[0,\"way.\"],[-1,\" A set of 9s in 8-way shows ~65% MC equity → checks instead of betting.\"],[0,\"\\\n- R\"]],\"start1\":2336,\"start2\":2336,\"length1\":79,\"length2\":8},{\"diffs\":[[0,\"_nl`\"],[-1,\"\\\n- 14 unit tests, 9 test hands from live session\"],[0,\"\\\n\\\n##\"]],\"start1\":2623,\"start2\":2623,\"length1\":56,\"length2\":8},{\"diffs\":[[0,\"ses\\\n\"],[-1,\"- **Bot NEVER bets or raises postflop when first-in** (checked-to spots)\\\n\"],[0,\"- Pa\"]],\"start1\":2764,\"start2\":2764,\"length1\":81,\"length2\":8},{\"diffs\":[[0,\"ions\"],[-1,\" (check/fold/call)\"],[0,\" but\"]],\"start1\":2807,\"start2\":2807,\"length1\":26,\"length2\":8},{\"diffs\":[[0,\")\\\n- \"],[-1,\"This c\"],[1,\"C\"],[0,\"onfi\"]],\"start1\":2859,\"start2\":2859,\"length1\":14,\"length2\":9},{\"diffs\":[[0,\"sue \"],[-1,\"— need lower cap for wider betting range\"],[1,\"(separate from D4).\"],[0,\"\\\n\\\n--\"]],\"start1\":2890,\"start2\":2890,\"length1\":48,\"length2\":27},{\"diffs\":[[0,\"2.0`\"],[-1,\" — **but still too tight per replay analysis**\"],[0,\"\\\n- [\"]],\"start1\":3592,\"start2\":3592,\"length1\":54,\"length2\":8},{\"diffs\":[[0,\"B+BB\"],[-1,\"; grace period not yet implemented\"],[0,\")\\\n\\\n-\"]],\"start1\":3815,\"start2\":3815,\"length1\":42,\"length2\":8},{\"diffs\":[[0,\"th)\\\n\"],[-1,\"**Impact:** If hero c-bets and opponent min-raises, bot shoves full stack regardless of depth.\\\n\\\n\"],[0,\"### \"]],\"start1\":3988,\"start2\":3988,\"length1\":104,\"length2\":8},{\"diffs\":[[0,\"d-to\"],[-1,\" (NEW)\"],[0,\"\\\n**R\"]],\"start1\":4048,\"start2\":4048,\"length1\":14,\"length2\":8},{\"diffs\":[[0,\"e:**\"],[-1,\" `determine_bet_adjustment()` with\"],[0,\" `be\"]],\"start1\":4064,\"start2\":4064,\"length1\":42,\"length2\":8},{\"diffs\":[[0,\"way.\"],[-1,\" MC equity for sets/overpairs in 6-8 way pots is often 55-65%.\\\n**Evidence:** Hand replay shows 0/6 match on aggressive postflop decisions (bot always checks).\"],[0,\"\\\n**F\"]],\"start1\":4122,\"start2\":4122,\"length1\":166,\"length2\":8},{\"diffs\":[[0,\"-1.5\"],[-1,\" (sweep will confirm optimal value). Also\"],[1,\";\"],[0,\" con\"]],\"start1\":4167,\"start2\":4167,\"length1\":49,\"length2\":9},{\"diffs\":[[0,\"_base`.\\\n\"],[-1,\"\\\n\"],[0,\"### B2: \"]],\"start1\":4200,\"start2\":4200,\"length1\":17,\"length2\":16},{\"diffs\":[[0,\"s)\\\n\\\n\"],[-1,\"### D4: Dealer button almost always reported as seat 0 ⚠️ HIGH (NEW, 2026-06-23 live)\\\n**Verified 2026-06-23 live session (20 hands).** The scraper reports `dealer_seat=0`\\\n(hero's seat) in **19/20 hands**; only 1 hand had the correct `dealer=7`.\\\n- **Blinds ARE correctly detected**: `SmallBlind`/`BigBlind` player_actions arrive with\\\n  correct seats + amounts and rotate properly (SB/BB at 0/1 → 8/0 → 7/8 → 6/7 …).\\\n- **The button is the broken piece.** A wrong `button_seat` corrupts all downstream\\\n  position logic: `our_position`, BTN/SB/BB tags, and the position-aware preflop\\\n  thresholds. The bot thinks hero is BTN nearly every hand → loose open-limp/call\\\n  behaviour (e.g. J5s limp-call on a seat the bot labels BTN). Symptom in context:\\\n  `hero=0(BTN…)` + `bb=0` simultaneously (button == big blind, impossible 3+ handed).\\\n- **Correct button is derivable**: clockwise = +1 mod num_seats, so the button is one\\\n  seat before the SB → `button_seat = (sb_seat + num_seats − 1) % num_seats`.\\\n  Confirmed by the one good hand (`dealer=7`, `SB=8`).\\\n- **Likely root cause of the reported \\\"preflop limps with anything\\\".**\\\n- **Fix options:** (a) userscript: fix dealer detection in `parser.ts`; (b) server-side\\\n  reconciliation: derive `button_seat` from the reliably-detected SB seat. (b) is robust\\\n  and lives in this repo (`table_state.rs`).\\\n- Also observed: dead-seat blind skips (SB=0/BB=3, SB=1/BB=3 when an intervening seat\\\n  sits out) — normal poker, but `compute_blind_seats` synthesis would mis-handle them.\\\n\\\n---\\\n\\\n## Production Config (cash_nl.toml)\\\n\\\n| Parameter | Value | Purpose |\\\n|-----------|-------|---------|\\\n| call_base | 0.50 | Base call threshold |\\\n| call_ppot_base | 0.32 | Draw calling threshold |\\\n| call_w_draw | 0.80 | Draw weight for call threshold |\\\n| call_w_pot_odds | 0.78 | Pot odds adjustment weight |\\\n\"],[1,\"---\\\n\\\n## Production Config (cash_nl.toml)\\\n\\\n| Parameter | Value | Purpose |\\\n|-----------|-------|---------|\\\n| call_base | 0.50 \"],[0,\"| ca\"]],\"start1\":4836,\"start2\":4836,\"length1\":1837,\"length2\":133},{\"diffs\":[[0,\"_cap\"],[-1,\" |\"],[0,\" 1.2 |\"],[-1,\" Max multi-way call exponent |\\\n|\"],[0,\" bet\"]],\"start1\":4975,\"start2\":4975,\"length1\":48,\"length2\":14},{\"diffs\":[[0,\"_cap\"],[-1,\" |\"],[0,\" 2.0 \"],[-1,\"| Max multi-way bet exponent **← likely\"],[1,\"(←\"],[0,\" nee\"]],\"start1\":4993,\"start2\":4993,\"length1\":54,\"length2\":15},{\"diffs\":[[0,\"eds lowering\"],[-1,\"** |\\\n\"],[1,\") \"],[0,\"| bet_flop_b\"]],\"start1\":5007,\"start2\":5007,\"length1\":29,\"length2\":26},{\"diffs\":[[0,\"base\"],[-1,\" |\"],[0,\" 0.52 |\"],[-1,\" Flop betting threshold **← likely needs lowering** |\\\n| bet_turn_base | 0.70 | Turn betting threshold |\\\n| raise_base | 0.80 | Value raise threshold |\\\n| raise_w_bluff | 0.30 | Bluff raise discount |\\\n| raise_w_draw | 0.50 | Draw raise discount |\\\n| bet_value_fraction | 0.67 | Dry board value sizing |\\\n| bet_wet_fraction | 0.75 | Wet board sizing |\\\n| bet_bluff_fraction | 0.40 | Bluff sizing |\\\n|\"],[0,\" swe\"]],\"start1\":5032,\"start2\":5032,\"length1\":409,\"length2\":15},{\"diffs\":[[0,\"mode\"],[-1,\" |\"],[0,\" false |\"],[-1,\" Live entropy randomization |\"],[0,\"\\\n\\\n--\"]],\"start1\":5050,\"start2\":5050,\"length1\":47,\"length2\":16},{\"diffs\":[[0,\"4** \"],[-1,\"(dealer button stuck at 0) — derive button from SB seat (server-side); likely fixes loose p\"],[1,\"✅ fix applied — verify after page \"],[0,\"re\"],[-1,\"f\"],[0,\"lo\"],[-1,\"p\"],[1,\"ad\"],[0,\"\\\n2. \"]],\"start1\":5104,\"start2\":5104,\"length1\":105,\"length2\":48},{\"diffs\":[[0,\"ults\"],[-1,\" to production config\"],[0,\"\\\n3. \"]],\"start1\":5198,\"start2\":5198,\"length1\":29,\"length2\":8},{\"diffs\":[[0,\" fix\"],[-1,\", prevents catastrophic amount parsing\"],[0,\"\\\n4. \"]],\"start1\":5233,\"start2\":5233,\"length1\":46,\"length2\":8},{\"diffs\":[[0,\"g) —\"],[-1,\" add\"],[0,\" sta\"]],\"start1\":5269,\"start2\":5269,\"length1\":12,\"length2\":8},{\"diffs\":[[0,\"heck\"],[-1,\" before AllIn\"],[0,\"\\\n5. \"]],\"start1\":5287,\"start2\":5287,\"length1\":21,\"length2\":8},{\"diffs\":[[0,\"iod)\"],[-1,\" — timestamp tracking in resetHand\\\n6. **D1** (missing antes) — server-side pot reconciliation\"],[1,\"\\\n6. **D1** (missing antes)\"]],\"start1\":5323,\"start2\":5323,\"length1\":97,\"length2\":30}]"
metadata_diff: {"new":{},"deleted":[]}
encryption_cipher_text: 
encryption_applied: 0
updated_time: 2026-06-23T06:07:19.806Z
created_time: 2026-06-23T06:07:19.806Z
type_: 13