Project 01 · household finance software

A budget app built for one household. Mine.

Level$ pulls in real accounts through Plaid, splits spending across categories two people actually argue about, and answers a phone call about any of it — no app open, no login, just a question about where the money went.

Most budgeting apps assume one person is doing the budgeting. Ours is a household of two, one income that moves and one that doesn’t, a mortgage, daycare, and a running disagreement about the dining-out line. The apps we tried wanted us to categorize everything by hand, forgot what we’d decided last month, and had nothing to say when one of us just wanted to ask “can we afford this?” without opening a laptop.

Level$ started as the fix for our own household. It stayed narrow on purpose — categories that map to how a family actually spends, a shared source of truth for what “spent” means so the number on the screen and the number read back over the phone are never allowed to disagree, and a security model built for the fact that this thing touches real bank accounts, not sample data.

See it work

This is a real budget, not a screenshot. The numbers are sample data, but the math underneath — category totals, split transactions, the running remainder — is the same function the live app and the voice line both call.

Sample data · same lib/spend.ts as production · nothing here is written anywhere
Income
$9,000
Allocated
$4,350
Spent — Sep 2026
$3,750
Unallocated
$4,650
Budget — drag the numbers
🏠
Mortgage + HOA
$1,500 spent
🏫
Daycare
$750 spent
🛡️
Insurance
$200 spent
🛒
Groceries
$350 spent
Gas
$100 spent
🍽️
Dining Out + Bars
$200 spent
🧸
Kids Stuff
$150 spent
🐷
Bank Savings
$500 spent
Recent transactions
LandlordMortgage + HOA
$1,500
Primrose SchoolDaycare
$750
Geico InsuranceInsurance
$200
Savings TransferBank Savings
$500
Trader Joe'sGroceries
$200
Whole FoodsGroceries
$150
BP GasGas
$60
Sync that doesn’t depend on someone opening the app

A Plaid webhook fires on new transactions, and a nightly cron job re-syncs anyway, on the assumption the webhook will eventually get missed. Both were briefly broken by an auth rule that redirected machine callers to a sign-in page — the kind of bug that only shows up when you go looking for why the data went stale, which is exactly why the cron exists as a second, independent check on the first.

A second lock on the parts that touch money

Signing in gets you into the household. A separate PIN, throttled against guessing and checked in constant time, gates anything that can move a number. Two people share one login in most family software; this treats that as a reason for a second barrier, not a reason to skip it.

One calculation, called from two places

Category totals, ignore rules, and split-transaction math live in a single module, imported by the app screen and by the voice line’s tools. Nothing recomputes the same number a second way — because the fastest way to lose someone’s trust in a finance app is to tell them two different totals for the same month.

Voice AIGrounding & attestationIn progress

Building a phone line that isn’t allowed to make numbers up

A callable agent over real account data is a weekend build. The hard part is proving it: a system that mechanically checks every spoken figure against a real tool call, a parity assertion that catches the agent computing the right-sounding wrong number, and a failure taxonomy built from real calls instead of a demo script.

Read the full writeup