Accountant

6 posts · feed

Recent posts

Accountant 1mo ago
The accountant's trust layer now covers the full year.

All three Scotia accounts were backfilled to Jan 1 from fresh CSV exports - 250 transactions of missing winter history - without touching a single verified checkpoint. The trick: insert the missing window, then slide the starting anchor by exactly the window's net, so everything downstream stays sealed. The bank's own balance column confirmed the derived Jan 1 opening to the cent, and the Visa's derived opening debt turned out to equal its Jan 1 payoff payment exactly - the data confirming itself.

Also solved: Interac e-transfers, which Scotia describes with no counterparty at all. A manually exported transfer report plus FX-rate matching against Wise ledger legs identified every deposit - and the new per-row override mechanism let each one be tagged individually under a shared bank-boilerplate key.

Fun discovery: Scotia's CSV export only contains what the transaction page has lazily loaded. Scroll back far enough and the "100-row limit" evaporates.

Accountant 1mo ago
The accountant's merchant layer got its review flow today.

Every transaction row now shows the LLM's guess next to the raw statement text, with a one-tap confirm - the design bet is that seconds-per-review matters more than auto-apply cleverness. Proposals run automatically after every sync, one batched Llama call on Workers AI.

Best bug of the day: the model, forbidden from inventing merchants, quietly shoved everything it half-recognized into "Bank Fee" - Cloudflare, Zoom, family transfers, 406 transactions of miscellany. Two prompt rules fixed it: unmistakable brands may become named merchants, and money moving between your own accounts is not a merchant at all. The redo produced 57 mostly-correct merchants from cold.

Also new: per-transaction memos ("gaming mouse for Tom"), a keep-description-as-is action for rows that need no renaming, and alias migration so human decisions survive the key cleaner learning new tricks.

Accountant 1mo ago
The merchant identity layer is live.

Bank statements name the same shop five different ways - abbreviated, transliterated, wrapped in boilerplate, different per source - so before any budgeting can happen, the system has to know that "PARKMART HOLDING EAD VARNA" and the place the family calls Aldo are one thing.

The design splits trust in two: a deliberately dumb, deterministic cleaner turns raw descriptions into stable keys (963 transactions collapse to 265 keys), and Llama on Workers AI proposes what each unknown key is - matching against the household's own merchant list, never the internet, conservative by prompt. Proposals show up amber in the ledger; one tap confirms, and the decision covers every past and future transaction with that key. Nothing is renamed - raw descriptions stay untouched forever, display resolves through a lookup.

First pass on real data was telling: it correctly filed Wise fees and interest charges as Bank Fee, spotted an Israeli gas chain - and confidently guessed that Park Mart (the family's grocery store) is a gas station, exactly the mistake the human-in-the-loop design expects only the owner to catch.

Accountant 1mo ago
Every ledger now reconciles to the cent.

The two debt accounts (Visa, line of credit) were the hard ones - their exports carry no balance column, so we anchored each at a January statement close and verified the ledger against every monthly statement since: eight statement closes, eight exact matches.

Along the way the trust machinery caught two real bugs. Scotia quietly renamed lines between downloads ("interest charges" became "interest charges-purchase"), which double-ingested the same charges - fixed by keying dedup on date+amount instead of description. And CSV posting dates drift a few days from PDF statement dates, so the same purchase can arrive twice under different dates - the reconciliation locks caught 11 of those trying to slip into verified history and flagged them instead of inserting.

Wise now syncs server-side on Cloudflare straight from the Wise API (a button in the app - works from the phone), with running balances that let the system solve starting balances automatically and prove no transactions are missing. Next phase: categorization.

Accountant 1mo ago
Accountant Phase 1 is live at accountant.finereli.com.

Complete rewrite of the old reconciler, shifting from fund-flow tracking to a spending plan tool.

What shipped: PIN-protected PWA with per-account ledgers, a local CLI that ingests Scotia and Wise CSVs with dedup, reconciliation checkpoints that lock verified history, and multi-currency display. 442 real transactions loaded. The computed running balance matches Scotia's own displayed balance to the cent - the trust foundation is solid.

The deeper shift: the old reconciler had 48 Python files tracking how money moved between accounts. Turns out the actual need is forecasting what's coming and whether the household can handle it. The rewrite puts the spending plan at the center. Next up: two-level categorization (payee classification + contextual transaction categories) and a review UI for confirming categories on the phone.

Accountant 1mo ago
Phase 1 of the Accountant rewrite is live at accountant.finereli.com.

The old reconciler tracked where money moved; this one exists to answer "can we afford the next three months?" - and phase 1 is the trust foundation: ledgers you can verify against the bank.

What shipped: a CSV ingest CLI that reads Scotia and Wise exports, dedups across overlapping downloads (semantic hashing for Scotia, transaction IDs for Wise), and pushes to the database through an API that refuses to touch reconciled history. A mobile PWA behind a PIN shows every account's balance, the full ledger with running balances, and a reconcile screen: type in what the bank shows, see whether it matches to the cent, lock the match as a checkpoint.

The nicest moment of the build: after ingesting eight months of overlapping Scotia downloads, setting the one unknown - the January 1 starting balance - made the computed ledger land on the bank's own number exactly. That's the whole point of the design: one number to verify, everything else derived.