Paradaux

PAR-58

0

Investigate taxation system bug in StateCraft

DoneHighrianTreasuryBug

Taxation appears broken: players with no money show no tax (a global 1% is applied), but SCGovernment receives no funds. Investigate whether this is StateCraft-specific or also affects DemocracyCraft.

Technical notes — this looks like a per-server misconfiguration, not a code bug. On StateCraft, tax.balance.government-account is set to DCGovernment, but LedgerServiceImpl.bootstrapGovernmentAccounts() only creates starting-balances, the tax-income account (SCGovernment) and the fines account — it never bootstraps the balance-tax destination. So findGovernmentAccountByName("DCGovernment") returns null, BalanceTaxService.resolveDestinationAccountId() logs a WARN and silently falls back to the default tax account (SCGovernment). Money is collected and credited to SCGovernment — but the configured DCGovernment stays empty, which reads as "not receiving funds."

The "no-money players pay no tax" part is correct/expected: processLoginLocked returns early at balance ≤ 0 and the 0% bracket.

Fix: set SC's tax.balance.government-account to SCGovernment; and/or bootstrap the balance-tax destination like the others + upgrade the silent WARN fallback to a startup validation error (a misrouted tax destination is a money-integrity issue).

Comments

tesks · Jun 4, 2026, 9:57 AM

Code context — this looks like a per-server misconfiguration, not a code bug. On StateCraft, tax.balance.government-account is set to DCGovernment, but LedgerServiceImpl.bootstrapGovernmentAccounts() only creates starting-balances, the tax-income account (SCGovernment) and the fines account — it never bootstraps the balance-tax destination. So findGovernmentAccountByName("DCGovernment") returns null, BalanceTaxService.resolveDestinationAccountId() logs a WARN and silently falls back to the default tax account (SCGovernment). Money is collected and credited to SCGovernment — but the configured DCGovernment stays empty, which reads as "SCGovernment not receiving funds."

The "players with no money pay no tax" part is correct/expected: processLoginLocked returns early at balance ≤ 0 and at the 0% bracket.

Fix: set SC's tax.balance.government-account to SCGovernment; and/or bootstrap the balance-tax destination like the others + upgrade the silent WARN fallback to a startup validation error (a misrouted tax destination is a money-integrity issue).

tesks · Jun 5, 2026, 6:57 AM

Skipping — this is a live-config fix, not a code change. As diagnosed, StateCraft's tax.balance.government-account is set to DCGovernment, which is never bootstrapped, so resolveDestinationAccountId logs a WARN and silently falls back to the default tax account — money is collected, just credited to the wrong (fallback) account, so the configured DCGovernment looks empty. The fix is to set SC's tax.balance.government-account to a bootstrapped account (e.g. SCGovernment) on the live server config — the agent can't touch live config. (Optional code hardening for later: upgrade the silent WARN fallback to a fail-fast startup validation so a misrouted tax destination can't happen silently — flag if wanted.)

tesks · Jun 11, 2026, 11:21 AM

DC control-case validation (prod DB) — confirms config-issue, not a code bug

Ran the validation against DC prod. DC is HEALTHY. This supports the documented diagnosis that the SC failure is a per-server tax.balance.government-account misconfiguration (can't query SC from here).

(1) GOVERNMENT accounts exist

All expected bootstrapped accounts are present on DC:

  • DCGovernmentaccount_id 2, balance 4,520,750.45
  • starting-balances — account_id 1
  • GovernmentFines — account_id 3
  • Eco — account_id 104245
  • SCGovernmentaccount_id 88937, balance 0.00 (exists but inert on DC — see below)

(20 GOVERNMENT accounts total, incl. DCGovernment{AV,JUD,OR}, GovReserve, TreasuryIngest, etc.)

(2) Balance-tax inflow to DCGovernment (last 30 days)

ledger_postings (amount > 0) JOIN ledger_txns, filtered to tax messages, account_id = 2:

postingstotal inflowearliestlatest
1,0081,649,525.652026-05-30 19:502026-06-11 11:15 (today)

Example messages (plugin_system = treasury):

  • Personal balance tax (1h 59m @ 1%/wk) — 13.38
  • Personal balance tax (18h 53m @ 1%/wk) — 142.93
  • Personal balance tax (1h 1m @ 1%/wk) — 7.72

(3) Tax destination is actually receiving money — and the mirror confirms the mechanism

  • DCGovernment (the configured destination on DC) is receiving balance tax, continuously, up to today.
  • SCGovernment on DC (account_id 88937): 0 tax postings, 0.00 inflow over 30 days.

This is the exact inverse of the reported SC symptom. On DC the config points at a bootstrapped DCGovernment and money lands there; on SC the config points at DCGovernment which is not bootstrapped, so resolveDestinationAccountId() WARN-falls-back to the default tax account (SCGovernment). The fact that on DC SCGovernment is the inert one and DCGovernment is the live one demonstrates the routing is config-driven, not code-broken.

Conclusion

DC is NOT affected — it is a valid healthy control. The SC issue is the documented misconfiguration: tax.balance.government-account = DCGovernment on a server where that account is never bootstrapped.

Recommended next step

No DB remediation on DC (data is correct — do not run any write). Apply the fix already in the ticket on the SC live config:

  1. Set SC's tax.balance.government-account to a bootstrapped account (e.g. SCGovernment).
  2. (Optional code hardening, separate ticket if desired) Upgrade the silent WARN fallback in BalanceTaxService.resolveDestinationAccountId() to a fail-fast startup validation — a misrouted tax destination is a money-integrity issue and should not degrade silently.

Classification: config-issue. No code change required for the core fix; the agent cannot touch SC live config.

Activity

  • paradaux changed status to Status → Done
  • tesks commented
  • paradaux description: Description updated
  • paradaux changed status to Status → Planned
  • tesks commented
  • tesks moved to Moved to Treasury
  • tesks changed status to Status → Backlog
  • tesks description: Description updated
  • tesks commented
  • tesks assigned Assigned to rian