[#100] Clear the loan shelf at game start — bench runs are byte-identical again (Closes #100) #101

Merged
robertismo merged 1 commit from 100-nondet into master 2026-09-30 10:31:30 +00:00
Owner

Root cause found and fixed.

The bug: openLoanOffers is the one phase-scratch global the engine reads before it writes — turn-1 deposit hooks call (market-loans) before the game's own shelf opens. The bench iterates its preset map in random order, so the previous preset's LAST shelf bled into the next preset's first-turn deposit decisions. Identical binaries, same seeds, different run orders → different turn-1 rates → close games flipped. That is the +-1 win in bond-economy/micro-economy (the presets where the deposit decisions most distort the attrition outcome), plus the small equity drift elsewhere.

The fix: run() clears openLoanOffers at game start. A fresh game's turn-1 deposit phase sees an honest empty market, every time, in any order.

Regression test (stale_shelf_test.go): plants a stale shelf, runs a probe brain whose deposit hook posts the turn-1 shelf length and sticks with it — must post 0 (empty market) and the shelf must still open normally during the game. Fails without the fix, passes with it.

Verification: the two identical 30-game benches that previously differed by 84 lines (adapt 14<->15, super 6<->7, equity drift) are now byte-identical (0 diff lines). go build, full test suite, go vet clean.

Impact for #97: per-preset tables are now exact; the team can compare across agents and runs without the +-1 noise.

Root cause found and fixed. **The bug**: `openLoanOffers` is the one phase-scratch global the engine reads before it writes — turn-1 deposit hooks call `(market-loans)` before the game's own shelf opens. The bench iterates its preset map in random order, so the previous preset's LAST shelf bled into the next preset's first-turn deposit decisions. Identical binaries, same seeds, different run orders → different turn-1 rates → close games flipped. That is the +-1 win in bond-economy/micro-economy (the presets where the deposit decisions most distort the attrition outcome), plus the small equity drift elsewhere. **The fix**: `run()` clears `openLoanOffers` at game start. A fresh game's turn-1 deposit phase sees an honest empty market, every time, in any order. **Regression test** (stale_shelf_test.go): plants a stale shelf, runs a probe brain whose deposit hook posts the turn-1 shelf length and sticks with it — must post 0 (empty market) and the shelf must still open normally during the game. Fails without the fix, passes with it. **Verification**: the two identical 30-game benches that previously differed by 84 lines (adapt 14<->15, super 6<->7, equity drift) are now byte-identical (0 diff lines). go build, full test suite, go vet clean. Impact for #97: per-preset tables are now exact; the team can compare across agents and runs without the +-1 noise.
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Winnie/bankwars!101
No description provided.