Inspiration

For generations, Indonesian warung owners and tradespeople kept a buku kas — a handwritten ledger book recording every rupiah in, every rupiah out, and every kasbon (a customer's tab). The book was the business's memory. It is dead now: records scatter across chat threads, scraps of paper, and fading memory, and money quietly disappears — a kasbon forgotten here, a materials cost untracked there. The author is a house painter; the kasbon problem is not a persona, it is Tuesday.

What it does

Dead Ledger resurrects the book as a web app that answers three questions at a glance: who still owes me, how much came in and went out, and what is my balance?

  • Write in the book — record money in, money out, or a kasbon (person, amount, due date) in seconds. Amounts accept the way Indonesians actually write them: 250.000 means 250,000 rupiah.
  • The daily picture — a "Today" strip (in / out / net) next to the all-time totals, because the paper book was a daily ritual.
  • Chase the ghosts — unsettled debts glow candle-amber, overdue ones flare red, settled ones fade like ghosts laid to rest; one tap marks a debt paid without erasing its history.
  • The book never dies again — everything lives in the browser (localStorage). No account, no server, no signal needed; corrupt data falls back to an empty book instead of crashing.

How we built it

Spec-first with Kiro CLI — see the write-up below. Zero dependencies: vanilla HTML/CSS/JS, a pure-function ledger core (createEntry, parseAmount, computeTotals, computeDailyTotals, markSettled, filterEntries, isOverdue), unit + property-based tests with node:test, hosted as a static site.

Challenges

  • Dates that lie: an early draft used UTC dates, so a worker opening the book before 07:00 in Jakarta saw yesterday. The steering doc already said "local date, never UTC" — a spec-consistency pass caught the drift and every date now flows through one localToday() helper.
  • Amounts that lie: 300.000 typed the Indonesian way parsed as 300 rupiah. A dedicated parseAmount with grouping rules and tests fixed it.
  • Zero-budget realism: the target phone is a low-end Android on 1 Mbps Wi-Fi. That constraint — not fashion — is why there is no framework, no build step, and no account system.

Accomplishments

A complete, tested resurrection of a dead technology that its real audience can use today, built end-to-end (spec → design → tasks → code → tests) inside Kiro's workflow, with the entire .kiro/ directory shipped in the repo as the paper trail.

What we learned

Spec-driven development feels slower for the first hour and faster for every hour after: the requirements doc became the test plan, the steering docs became standing orders the agent could not drift from, and the hooks made "did you run the tests?" a question nobody had to ask.

What's next

Installable PWA with an icon on the home screen; a "nag list" that formats a polite WhatsApp reminder for an overdue kasbon; optional encrypted backup export for people who change phones.

Built With

Share this project:

Updates

Submission history