How it’s built
The Budget Tracker never stores a balance
The most important rule of the accounting archetype: a balance is not a field you update — it is a value you derive by summing an append-only ledger of immutable entries. Break that rule and your numbers drift from the truth; keep it and the ledger is always the single source of truth.
Accounts and entries
Each budget envelope is an account: it holds a name and a planned allocation, but not a running total. Every expense is an immutable entry posted to that envelope. Entries are never edited or deleted.
envelope Groceries allocated $400.00 ← the plan (mutable config) entry $52.10 "market" 2026-07-03 ← immutable facts, entry $18.40 "corner shop" 2026-07-06 append-only entry $31.00 "butcher" 2026-07-09
Balance is derived, not stored
Spent and remaining are computed on every read. There is no balance column to fall out of sync, and no migration needed to add a new view — you just sum the entries a different way.
spent(envelope) = SUM(entry.amount for entry in ledger_of(envelope)) remaining(envelope) = envelope.allocated - spent(envelope)
Corrections are reversals, not deletes
Logged an expense by mistake? We don’t delete the row — that would erase history. Removing an entry posts a compensating reversal: a new entry with the negated amount that references the original. The two net to zero in the sum, so the balance is correct, and the full timeline — including the mistake and its correction — is preserved for audit.
entry $31.00 "butcher" reversalOf: null
entry -$31.00 "Reversal of butcher" reversalOf: <original id>
─────────────────────
net $0.00 ← both hidden from the list, ledger intactWhy this matters beyond budgets
The same archetype — lightweight accounts, an immutable entry ledger, derived balances, reversal instead of mutation — is how real systems track money, loyalty points, prepaid wallets, inventory, and data allowance. Anywhere value flows and an audit trail matters, you reach for it. Envelope budgeting is just the friendliest place to see it work.