[#75] Configurable reserve requirement: shore by the bond market or go insolvent #76

Merged
robertismo merged 2 commits from 75-reserve into master 2026-09-29 22:07:21 +00:00
Owner

Reserve requirement, shored by the bond market (issue #75)

Your three questions, answered first:

  1. What was the existing mechanism? The finance phase had a shoring rule: when cash could not cover deposit interest + operating expense, the bank force-borrowed exactly the shortfall from the bond market before paying. What it did NOT do: anything about the deposit PRINCIPAL. A bank could be insolvent on equity (liabilities > assets) with cash in hand and no debt, while cheap bonds sat on the market — the equity test killed it without ever giving the bond market a chance to shore the position. That is the exact case you saw.

  2. Was it fundamentally a 0% reserve? Yes. Nothing required cash to be held against deposits. The only cash gate was "can you pay this turn's interest," which is a flow test, not a reserve.

  3. Can we impose a reserve requirement in config? Now yes: reserve_ratio, default 0.10, settable in config JSON and the wizard. It means 10% of deposits must be held in CASH, enforced BEFORE PnL and insolvency resolve.

The mechanism (9450a9f):

  • Each finance turn, reserve = reserve_ratio × deposits is computed first.
  • If the bank is short, it force-borrows the shortfall (plus its bills) from the bond market — merged into the bond-take fill, exactly the minimum take that makes the position viable.
  • If the market CAN shore it up, the bank continues to PnL with its reserve met.
  • If the market CANNOT, the bank is insolvent on the spot — logged as "X cannot meet the 10% reserve: the bond market could not shore up Y" — and goes through the normal public auction. Its bills and offer aging still run so the corpse's books match the other insolvency paths.
  • reserve_ratio: 0 restores the old behavior exactly.
  • The take-bonds screen now shows the requirement up front: "RESERVE: 10% of deposits = 5,000 held in cash (short 3,200)" or "reserve met", so a human sees the minimum take needed to stay viable before choosing.
  • Brains can read it: (config 'reserve-ratio).

Verification: three new regression tests (shored-by-market survives with the bond debt on its books; unshorable dies with cash in hand, proving the reserve trigger; ratio 0 is a strict no-op). Full go test . and go vet ./... green. Spectate smoke: 0 [ai errors, 0 divergences, reserve trigger observed firing. A 20-game direction bench across all 13 presets completes with normal bankruptcy dynamics and no structural breakage — win distribution shifts a bit under the new constraint, which is expected: the four brains were tuned pre-reserve and may deserve a retuning pass later.

## Reserve requirement, shored by the bond market (issue #75) **Your three questions, answered first:** 1. **What was the existing mechanism?** The finance phase had a shoring rule: when cash could not cover deposit interest + operating expense, the bank force-borrowed exactly the shortfall from the bond market before paying. What it did NOT do: anything about the deposit PRINCIPAL. A bank could be insolvent on equity (liabilities > assets) with cash in hand and no debt, while cheap bonds sat on the market — the equity test killed it without ever giving the bond market a chance to shore the position. That is the exact case you saw. 2. **Was it fundamentally a 0% reserve?** Yes. Nothing required cash to be held against deposits. The only cash gate was "can you pay this turn's interest," which is a flow test, not a reserve. 3. **Can we impose a reserve requirement in config?** Now yes: `reserve_ratio`, default `0.10`, settable in config JSON and the wizard. It means 10% of deposits must be held in CASH, enforced BEFORE PnL and insolvency resolve. **The mechanism (`9450a9f`):** - Each finance turn, `reserve = reserve_ratio × deposits` is computed first. - If the bank is short, it force-borrows the shortfall (plus its bills) from the bond market — merged into the bond-take fill, exactly the minimum take that makes the position viable. - If the market CAN shore it up, the bank continues to PnL with its reserve met. - If the market CANNOT, the bank is insolvent on the spot — logged as "X cannot meet the 10% reserve: the bond market could not shore up Y" — and goes through the normal public auction. Its bills and offer aging still run so the corpse's books match the other insolvency paths. - `reserve_ratio: 0` restores the old behavior exactly. - The take-bonds screen now shows the requirement up front: "RESERVE: 10% of deposits = 5,000 held in cash (short 3,200)" or "reserve met", so a human sees the minimum take needed to stay viable before choosing. - Brains can read it: `(config 'reserve-ratio)`. **Verification:** three new regression tests (shored-by-market survives with the bond debt on its books; unshorable dies with cash in hand, proving the reserve trigger; ratio 0 is a strict no-op). Full `go test .` and `go vet ./...` green. Spectate smoke: 0 `[ai` errors, 0 divergences, reserve trigger observed firing. A 20-game direction bench across all 13 presets completes with normal bankruptcy dynamics and no structural breakage — win distribution shifts a bit under the new constraint, which is expected: the four brains were tuned pre-reserve and may deserve a retuning pass later.
[#75] Configurable reserve requirement: shore by the bond market or go insolvent
All checks were successful
build / build (push) Successful in 24s
9450a9fbe5
First-time contributor

@Winnie key feature here though is that players have an opportunity to shore their position prior to PnL, and during the bond taking phase, and for a human player this should be a direct menu item to tell, if any, what debt amount they need to take to stay in. I hope that is made very clear.

@Winnie key feature here though is that players have an opportunity to shore their position prior to PnL, and during the bond taking phase, and for a human player this should be a direct menu item to tell, if any, what debt amount they need to take to stay in. I hope that is made very clear.
Author
Owner

Understood - the shore-up number will be a direct, unmissable menu item on the take-bonds screen, computed with the exact same math the finance phase enforces: the minimum bond debt to take so the position survives PnL and insolvency. Working it in now, with a quick-take option so one keystroke takes exactly that amount. Commenting again with the transcript once it's verified.

Understood - the shore-up number will be a direct, unmissable menu item on the take-bonds screen, computed with the exact same math the finance phase enforces: the minimum bond debt to take so the position survives PnL and insolvency. Working it in now, with a quick-take option so one keystroke takes exactly that amount. Commenting again with the transcript once it's verified.
Author
Owner

Done — the shore-up opportunity is now a direct menu item on the take-bonds screen, before you choose anything, computed with the exact same math the finance phase enforces. Transcript from a scripted game (10% reserve, cash drained to 0 by my own bond commitments):

  SHORE UP: minimum take to stay in = 5,800 (10% reserve 5,000 + bills 800 − cash 0).
  The finance phase force-borrows it; if the market cannot cover it, the bank is insolvent.

  Bank 1 — TAKE BONDS  (fixed term 10 turns, face 1,000) — 1 standing offers (the entire market; yours retire)
  PRICE       UNITS TURNS LEFT IMPLIED / TURN
  1000           70        10        0.0000%  (yours)
  TOTAL          70,000                  0.0000%
  cash wanted (Enter to skip, s = shore-up 5,800):
  • s takes exactly the shore-up amount — one keystroke, same preview/confirm flow as any take. In this case the cheapest money was my own standing offer, so the preview showed "retires 6 of your own units, 6000 cash back — no new debt" and the engine did exactly that.
  • When the position is already covered: SHORE UP: none needed — 5,200 cash covers the 10% reserve (5,000) and bills (800).
  • One honest caveat gets printed when it applies: bond takes add cash and debt in equal amounts, so they cannot repair a negative net position — if equity is already underwater, the line says so instead of letting a shore-up take end in the auction anyway.

Both branches verified in the smoke run above, tests/vet green, spectate clean (the line never leaks into headless games).

Done — the shore-up opportunity is now a direct menu item on the take-bonds screen, before you choose anything, computed with the exact same math the finance phase enforces. Transcript from a scripted game (10% reserve, cash drained to 0 by my own bond commitments): ``` SHORE UP: minimum take to stay in = 5,800 (10% reserve 5,000 + bills 800 − cash 0). The finance phase force-borrows it; if the market cannot cover it, the bank is insolvent. Bank 1 — TAKE BONDS (fixed term 10 turns, face 1,000) — 1 standing offers (the entire market; yours retire) PRICE UNITS TURNS LEFT IMPLIED / TURN 1000 70 10 0.0000% (yours) TOTAL 70,000 0.0000% cash wanted (Enter to skip, s = shore-up 5,800): ``` - **`s` takes exactly the shore-up amount** — one keystroke, same preview/confirm flow as any take. In this case the cheapest money was my own standing offer, so the preview showed "retires 6 of your own units, 6000 cash back — no new debt" and the engine did exactly that. - When the position is already covered: `SHORE UP: none needed — 5,200 cash covers the 10% reserve (5,000) and bills (800)`. - One honest caveat gets printed when it applies: bond takes add cash and debt in equal amounts, so they cannot repair a negative net position — if equity is already underwater, the line says so instead of letting a shore-up take end in the auction anyway. Both branches verified in the smoke run above, tests/vet green, spectate clean (the line never leaks into headless games).
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
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!76
No description provided.