v0.5.0: exhaustive GAAP accounting review + ample tests #78

Closed
opened 2026-09-29 22:26:24 +00:00 by Winnie · 10 comments
Owner

v0.5.0 work stream 1 of 3 (Robert's checklist, #26).

Exhaustive review of the GAAP accounting: the financial reports and the books must be in line with how these would actually be displayed in real-world financial operations. Every line of finance.go (report / income statement / cash-flow statement) gets audited against real GAAP presentation conventions, and every assumption gets a regression test. Ample tests, including invariants checked against actual play and benchmarks: the equity-change == net-income identity every turn, the cash-flow reconciliation, acquisition accounting, bond discount/interest recognition, loan amortization and write-off timing, deposit interest accrual.

Acceptance: an audit document (findings + corrections) and a test suite that pins the corrected behavior; no ACCT/CF divergence in spectate and bench runs.

v0.5.0 work stream 1 of 3 (Robert's checklist, #26). Exhaustive review of the GAAP accounting: the financial reports and the books must be in line with how these would actually be displayed in real-world financial operations. Every line of finance.go (report / income statement / cash-flow statement) gets audited against real GAAP presentation conventions, and every assumption gets a regression test. Ample tests, including invariants checked against actual play and benchmarks: the equity-change == net-income identity every turn, the cash-flow reconciliation, acquisition accounting, bond discount/interest recognition, loan amortization and write-off timing, deposit interest accrual. Acceptance: an audit document (findings + corrections) and a test suite that pins the corrected behavior; no ACCT/CF divergence in spectate and bench runs.
Author
Owner

Dispatch: I'm on issue #78 (GAAP accounting audit). Plan: (1) audit every line of the financial reports/books against real GAAP presentation; (2) fix all deviations; (3) add regression tests pinning every corrected assumption; (4) deliver docs/gaap-audit.md + PR from branch 78-gaap. First step: fresh worktree off origin/master in bankdev, then read finance.go/game.go line by line. Commenting before every step per the workflow rules.

Dispatch: I'm on issue #78 (GAAP accounting audit). Plan: (1) audit every line of the financial reports/books against real GAAP presentation; (2) fix all deviations; (3) add regression tests pinning every corrected assumption; (4) deliver docs/gaap-audit.md + PR from branch 78-gaap. First step: fresh worktree off origin/master in bankdev, then read finance.go/game.go line by line. Commenting before every step per the workflow rules.
Author
Owner

Baseline green (build+test+vet on a4cdd7d, fresh worktree /root/bw-78-gaap off origin/master). I've now read finance.go, game.go, config.go and the existing regression tests line by line.

Initial audit findings (details going into docs/gaap-audit.md):

  1. BOND DISCOUNT TIMING (biggest): fillBonds recognizes the full discount as income/expense AT TAKE TIME and books assets at face. Real GAAP (ASC 310-20/835): a zero-coupon-style bond is carried at amortized cost and the discount is accrued over the bond's life — issuer interest expense and holder interest income accrue each turn, converging to face at maturity. Fix: amortize both sides in financePhase; balance sheet carries BondInvestments at amortized cost and BondDebt at carrying value (face − unamortized discount).

  2. WRITE-OFF TIMING: the dead-loan path spreads the loss over TurnsLeft ('the loss is amortized over the loan's remaining term'). GAAP (ASC 310-10-35): an impairment is recognized WHEN INCURRED — the full loss in the turn the loan dies (the skill's own stated rule — the code contradicts it). Fix: full charge-off at default via an allowance (loans shown net of allowance); recoveries reverse the allowance as income.

  3. CASH-FLOW CLASSIFICATION: deposits flow in FINANCING. For a BANK, changes in customer deposits are OPERATING cash flows (ASC 942-230-45; bank statements show 'change in deposits' in operating). Bond borrowings/repayments stay in financing. Fix: move DepositsNet to operating.

  4. CF statement lacks the standard bottom: no beginning/end-of-period cash reconciliation. Fix: add 'Cash at beginning of turn' / 'Cash at end of turn' and GAAP section wording ('Net cash provided by (used in)...').

  5. INCOME STATEMENT ORDER: no interest-income/interest-expense grouping, no net-interest-income subtotal, recovery income listed apart from write-offs instead of netting into a provision-for-credit-losses line, bargain gain has a generic label. Fix: regroup per bank P&L conventions.

  6. Dead Report.Accrued field never populated. Remove.

  7. money() renders '-0' for negative zero lines. Fix.

Now writing docs/gaap-audit.md, then the code fixes, then the regression tests. Comments after each step.

Baseline green (build+test+vet on a4cdd7d, fresh worktree /root/bw-78-gaap off origin/master). I've now read finance.go, game.go, config.go and the existing regression tests line by line. Initial audit findings (details going into docs/gaap-audit.md): 1. BOND DISCOUNT TIMING (biggest): fillBonds recognizes the full discount as income/expense AT TAKE TIME and books assets at face. Real GAAP (ASC 310-20/835): a zero-coupon-style bond is carried at amortized cost and the discount is accrued over the bond's life — issuer interest expense and holder interest income accrue each turn, converging to face at maturity. Fix: amortize both sides in financePhase; balance sheet carries BondInvestments at amortized cost and BondDebt at carrying value (face − unamortized discount). 2. WRITE-OFF TIMING: the dead-loan path spreads the loss over TurnsLeft ('the loss is amortized over the loan's remaining term'). GAAP (ASC 310-10-35): an impairment is recognized WHEN INCURRED — the full loss in the turn the loan dies (the skill's own stated rule — the code contradicts it). Fix: full charge-off at default via an allowance (loans shown net of allowance); recoveries reverse the allowance as income. 3. CASH-FLOW CLASSIFICATION: deposits flow in FINANCING. For a BANK, changes in customer deposits are OPERATING cash flows (ASC 942-230-45; bank statements show 'change in deposits' in operating). Bond borrowings/repayments stay in financing. Fix: move DepositsNet to operating. 4. CF statement lacks the standard bottom: no beginning/end-of-period cash reconciliation. Fix: add 'Cash at beginning of turn' / 'Cash at end of turn' and GAAP section wording ('Net cash provided by (used in)...'). 5. INCOME STATEMENT ORDER: no interest-income/interest-expense grouping, no net-interest-income subtotal, recovery income listed apart from write-offs instead of netting into a provision-for-credit-losses line, bargain gain has a generic label. Fix: regroup per bank P&L conventions. 6. Dead Report.Accrued field never populated. Remove. 7. money() renders '-0' for negative zero lines. Fix. Now writing docs/gaap-audit.md, then the code fixes, then the regression tests. Comments after each step.
Author
Owner

Engine changes implemented and pushed to the worktree: finance.go + game.go rewritten per the audit (bond discount amortization both sides, amortized-cost/carrying-value balance sheet lines, immediate loan charge-off via allowance, deposits reclassified to operating cash flows, restructured balance sheet / income statement / cash-flow statement with cash reconciliation, money() -0 fix, dead Report.Accrued removed). go build + the full existing test suite (incl. acquisition_accounting, acq_dead_loans, reserve, bond_units, award, bidall, iterlog, lisp, hook) is GREEN — all pre-existing regression tests pass unchanged with the new measurement bases.

Now writing the new regression test files: gaap statement-layout tests, bond discount amortization tests, write-off/allowance tests, cash-flow classification tests, and a full-game invariant test.

Engine changes implemented and pushed to the worktree: finance.go + game.go rewritten per the audit (bond discount amortization both sides, amortized-cost/carrying-value balance sheet lines, immediate loan charge-off via allowance, deposits reclassified to operating cash flows, restructured balance sheet / income statement / cash-flow statement with cash reconciliation, money() -0 fix, dead Report.Accrued removed). go build + the full existing test suite (incl. acquisition_accounting, acq_dead_loans, reserve, bond_units, award, bidall, iterlog, lisp, hook) is GREEN — all pre-existing regression tests pass unchanged with the new measurement bases. Now writing the new regression test files: gaap statement-layout tests, bond discount amortization tests, write-off/allowance tests, cash-flow classification tests, and a full-game invariant test.

@Winnie also on the report negatives should be in parenthesis.

@Winnie also on the report negatives should be in parenthesis.
Author
Owner

Noted and added to the audit spec: negatives in the financial reports render parenthesized per standard accounting presentation — Loan write-offs (1,941), not -1941. Applies across the balance sheet, income statement, and cash-flow statement. Passing the ruling to the working agent now; the audit doc will record it.

Noted and added to the audit spec: negatives in the financial reports render parenthesized per standard accounting presentation — `Loan write-offs (1,941)`, not `-1941`. Applies across the balance sheet, income statement, and cash-flow statement. Passing the ruling to the working agent now; the audit doc will record it.
Author
Owner

Parenthesized-negatives ruling incorporated (Robert's mid-task ruling): new moneyParen helper renders every negative line on the balance sheet, income statement and cash-flow statement as (1,941) — never -1,941. All three statements updated line by line, plus the audit doc records the ruling. Also fixed while there: money() never grouped negative numbers (-1234, not -1,234) — now grouped; and two of my own new tests had cashPrev-snapshot bugs (fixed).

VERIFICATION SO FAR: go build green, go vet green, full go test green (all pre-existing tests + 18 new regression tests). Spectate smoke (gate config, seed 7): 0 [ai errors, 0 ACCT DIVERGENCE, 0 CF DIVERGENCE — sample report shows the new layout (grouped balance sheet w/ total liabilities+equity, net-interest-income P&L, deposits in operating, cash reconciliation, parens on (800)/(20,362)). Quick bench 30x13 = 390 games: 0 divergences, empire 114 / mill 106 / vault 63 / adapt 88.

Next: push branch 78-gaap, open the PR, request review.

Parenthesized-negatives ruling incorporated (Robert's mid-task ruling): new moneyParen helper renders every negative line on the balance sheet, income statement and cash-flow statement as (1,941) — never -1,941. All three statements updated line by line, plus the audit doc records the ruling. Also fixed while there: money() never grouped negative numbers (-1234, not -1,234) — now grouped; and two of my own new tests had cashPrev-snapshot bugs (fixed). VERIFICATION SO FAR: go build green, go vet green, full go test green (all pre-existing tests + 18 new regression tests). Spectate smoke (gate config, seed 7): 0 [ai errors, 0 ACCT DIVERGENCE, 0 CF DIVERGENCE — sample report shows the new layout (grouped balance sheet w/ total liabilities+equity, net-interest-income P&L, deposits in operating, cash reconciliation, parens on (800)/(20,362)). Quick bench 30x13 = 390 games: 0 divergences, empire 114 / mill 106 / vault 63 / adapt 88. Next: push branch 78-gaap, open the PR, request review.
Author
Owner

Committed and pushing: branch 78-gaap at 83201ce, 6 files, +1209/−100 (finance.go, game.go, three new test files, docs/gaap-audit.md). Bench artifacts from the verification runs were reverted before the commit — the PR carries only the audit, fixes, and tests. Pushing now, then opening the PR.

Committed and pushing: branch 78-gaap at 83201ce, 6 files, +1209/−100 (finance.go, game.go, three new test files, docs/gaap-audit.md). Bench artifacts from the verification runs were reverted before the commit — the PR carries only the audit, fixes, and tests. Pushing now, then opening the PR.
Author
Owner

DONE. PR #82 open: #82 — branch 78-gaap @ 83201ce, review requested from robertismo.

Key findings (full detail in docs/gaap-audit.md, committed to the PR):

  1. Bond discount was recognized in one lump at take time, assets booked at face → now amortized over the bond's life (ASC 310-20/835-30): amortized-cost assets, face-minus-unamortized-discount debts, zero recognition at take.
  2. Loan write-offs were spread over the remaining term → now fully charged off in the turn the loan dies (ASC 310-10-35) via an allowance; balance sheet shows loans net of allowance; recoveries reverse the allowance as income.
  3. Deposit flows sat in financing → moved to operating (ASC 942-230: deposits are a bank's core operating liability).
  4. CF statement now closes with the beginning/end cash reconciliation; acquisition line 'net of cash acquired'.
  5. Income statement regrouped: interest income → interest expense → NET INTEREST INCOME → credit losses net of recoveries → operating expense → bargain gain.
  6. Parenthesized negatives per your ruling: every negative line renders (1,941) via moneyParen; money() also fixed for '-0' and negative grouping. Dead Report.Accrued removed.

Tests: 18 new regressions (bond amortization, write-off/allowance/recovery, statement layout + money formats, cash-flow classification, full seeded AI-game invariant). All pre-existing tests pass unchanged. Verified: build+vet+test green, spectate smoke 0/0/0, bench 390 games with 0 divergences. Awaiting review.

DONE. PR #82 open: https://git.machinetele.com/Winnie/bankwars/pulls/82 — branch 78-gaap @ 83201ce, review requested from robertismo. Key findings (full detail in docs/gaap-audit.md, committed to the PR): 1. Bond discount was recognized in one lump at take time, assets booked at face → now amortized over the bond's life (ASC 310-20/835-30): amortized-cost assets, face-minus-unamortized-discount debts, zero recognition at take. 2. Loan write-offs were spread over the remaining term → now fully charged off in the turn the loan dies (ASC 310-10-35) via an allowance; balance sheet shows loans net of allowance; recoveries reverse the allowance as income. 3. Deposit flows sat in financing → moved to operating (ASC 942-230: deposits are a bank's core operating liability). 4. CF statement now closes with the beginning/end cash reconciliation; acquisition line 'net of cash acquired'. 5. Income statement regrouped: interest income → interest expense → NET INTEREST INCOME → credit losses net of recoveries → operating expense → bargain gain. 6. Parenthesized negatives per your ruling: every negative line renders (1,941) via moneyParen; money() also fixed for '-0' and negative grouping. Dead Report.Accrued removed. Tests: 18 new regressions (bond amortization, write-off/allowance/recovery, statement layout + money formats, cash-flow classification, full seeded AI-game invariant). All pre-existing tests pass unchanged. Verified: build+vet+test green, spectate smoke 0/0/0, bench 390 games with 0 divergences. Awaiting review.
Author
Owner

Heartbeat check at 22:51Z. Issue #78 is silent: last comment is id 917 at 22:40:07Z ('DONE. PR #82 open, review requested'). Verified since then: PR #82 merged, master at 94174124d4 (22:41:14Z), branch 78-gaap at 83201ce. Issue #78 is still open with no closing comment after the merge. #78 agent, please report immediately: if the GAAP audit is complete, close the issue with the ship note, same ritual as #79. (Verified facts only.)

Heartbeat check at 22:51Z. Issue #78 is silent: last comment is id 917 at 22:40:07Z ('DONE. PR #82 open, review requested'). Verified since then: PR #82 merged, master at 94174124d4 (22:41:14Z), branch 78-gaap at 83201ce. Issue #78 is still open with no closing comment after the merge. #78 agent, please report immediately: if the GAAP audit is complete, close the issue with the ship note, same ritual as #79. (Verified facts only.)
Author
Owner

Ship note - #78 merged via PR #82, closing. Branch 78-gaap @ 83201cec3b landed on master in merge 94174124d4 (22:41:14Z): 6 files, +1209/-100. Shipped: bond discount amortized over the bond's life (amortized cost), loan write-offs recognized in full in the defaulting turn net of a per-loan allowance (recoveries reverse it), deposits classified as operating cash flows (ASC 942), cash-flow statement closes with cash at beginning/end of turn, income statement regroups interest income -> interest expense -> net interest income -> credit losses net of recoveries -> op expense -> bargain gain, and every negative report line renders parenthesized via the new moneyParen helper per Robert's ruling. Full findings in docs/gaap-audit.md; three new test files pin the behaviors.

**Ship note - #78 merged via PR #82, closing.** Branch 78-gaap @ 83201cec3b landed on master in merge 94174124d4 (22:41:14Z): 6 files, +1209/-100. Shipped: bond discount amortized over the bond's life (amortized cost), loan write-offs recognized in full in the defaulting turn net of a per-loan allowance (recoveries reverse it), deposits classified as operating cash flows (ASC 942), cash-flow statement closes with cash at beginning/end of turn, income statement regroups interest income -> interest expense -> net interest income -> credit losses net of recoveries -> op expense -> bargain gain, and every negative report line renders parenthesized via the new moneyParen helper per Robert's ruling. Full findings in docs/gaap-audit.md; three new test files pin the behaviors.
Sign in to join this conversation.
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#78
No description provided.