🛁 🛁 🛁 The Ultimate Bookkeeping System (TUBS) 🛁 🛁 🛁
Multi-homed data
Your bookkeeping data already lives in many places: your bank, your invoicing
tool, your time tracker, your accountant's package. TUBS does not ask you to
move it all into one new system. Instead, a record can live in several systems
at once, and the copies are kept in step. Three building blocks do this:
- syncables
reads each platform's API, driven by its OpenAPI description.
- Devonian
translates each platform's records to a shared model and back, using lenses.
- Reflector
is the sync engine that keeps the copies in step.
Computed cells
Like a spreadsheet, some values are formulas over other values: an invoice
total, an account balance, the VAT for a quarter. The design principle is
store the formula, not the value. When copies from different systems
are merged, a stored total can silently go stale; a formula is recomputed from
the merged data.
The same idea covers the rules of bookkeeping. An invariant, such as "the
balance equals the sum of the transactions", is a computed cell that must be
true. If a merge breaks one, it shows up as something to review and fix,
instead of as silent corruption.
Commit messages
Like a Git repository, TUBS keeps not only the current state but also its
history, with a message for every change saying why it was made: "marked
invoice 2026-041 as paid, matched to bank line 3812". Changes proposed by
people, by apps and by AI agents are recorded the same way. They can be
reviewed before they are applied, and traced back afterwards.
🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁
🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁
🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁
🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁
🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁
🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁
🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁
🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁
🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁
🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁
🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁 🛁