[#91] Reject non-finite AI values and fail the bank (Closes #91) #92

Merged
robertismo merged 1 commit from 91-nan into master 2026-09-30 01:35:46 +00:00
Owner

Implements the ruling on #91: "if an AI produces NaN, reject the value and fail the bank, putting it up for auction when appropriate."

What changed

Every place an AI value enters the engine now sanitizes it. finiteAI() rejects NaN and ±Inf; a rejected value is replaced with a safe 0 (or the action is skipped) and the bank is flagged via aiFault() — logged to the game log AND stderr so headless benches surface it — then bankrupted in financePhase's post-pass, the same pass that handles unreserved positions, so the corpse is auctioned normally.

Coverage — the six action builtins and the five hook-return sites:

  • set-deposit-rate, bid-loans, bid-loan, offer-bond (price and size), take-bonds, bid-acquisition
  • deposit-rate, loan-bids (per-pair), bond-offers (per-lot), bond-take, bankruptcy-bid hook returns

A faulted bank's remaining actions this turn are skipped or zeroed, its books stay finite, and the auction price can never be NaN again.

Insurance: the report loop now logs NON-FINITE EQUITY (game log + stderr) if equity is ever NaN/Inf, so any residual non-AI path can't hide either.

Tests (nan_guard_test.go):

  • NaN deposit rate → value rejected, bank faulted, bankrupted, auctioned; every other bank's equity/cash/deposits stay finite
  • NaN bankruptcy bid → bid rejected as 0, bidder faulted and bankrupted
  • NaN loan bid → bid rejected, bank faulted
  • the original repro shape (NaN bids at an auction) → game log free of "NaN", all books finite
  • finiteAI classification

Verified: go build, go test -count=1 (full suite), go vet, spectate smoke seed 33 → 0 ai errors, 0 divergence, 0 non-finite lines.

The brain-side cause of the original bug (pow base going negative in the auction haircut) is a separate fix on the #80 branch; this PR makes the whole class loud instead of silent regardless of the brain.

Implements the ruling on #91: "if an AI produces NaN, reject the value and fail the bank, putting it up for auction when appropriate." **What changed** Every place an AI value enters the engine now sanitizes it. `finiteAI()` rejects NaN and ±Inf; a rejected value is replaced with a safe 0 (or the action is skipped) and the bank is flagged via `aiFault()` — logged to the game log AND stderr so headless benches surface it — then bankrupted in financePhase's post-pass, the same pass that handles unreserved positions, so the corpse is auctioned normally. Coverage — the six action builtins and the five hook-return sites: - `set-deposit-rate`, `bid-loans`, `bid-loan`, `offer-bond` (price and size), `take-bonds`, `bid-acquisition` - `deposit-rate`, `loan-bids` (per-pair), `bond-offers` (per-lot), `bond-take`, `bankruptcy-bid` hook returns A faulted bank's remaining actions this turn are skipped or zeroed, its books stay finite, and the auction price can never be NaN again. **Insurance**: the report loop now logs `NON-FINITE EQUITY` (game log + stderr) if equity is ever NaN/Inf, so any residual non-AI path can't hide either. **Tests** (nan_guard_test.go): - NaN deposit rate → value rejected, bank faulted, bankrupted, auctioned; every other bank's equity/cash/deposits stay finite - NaN bankruptcy bid → bid rejected as 0, bidder faulted and bankrupted - NaN loan bid → bid rejected, bank faulted - the original repro shape (NaN bids at an auction) → game log free of "NaN", all books finite - `finiteAI` classification **Verified**: go build, go test -count=1 (full suite), go vet, spectate smoke seed 33 → 0 ai errors, 0 divergence, 0 non-finite lines. The brain-side cause of the original bug (pow base going negative in the auction haircut) is a separate fix on the #80 branch; this PR makes the whole class loud instead of silent regardless of the brain.
Winnie changed title from [#91] Reject non-finite AI values and fail the bank to [#91] Reject non-finite AI values and fail the bank (Closes #91) 2026-09-30 01:35:41 +00:00
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!92
No description provided.