Skip to content
Agents Finance
Use caseEvidence: Real case

A personal accountant agent: Claude Code keeps a Beancount ledger and answers emailed receipts with a pull request

Summary: Software engineer Pyry Haulos describes how he moved his personal finances from spreadsheets to a Beancount plain-text ledger run by Claude Code: he emails receipts and statements, and the agent replies with a pull request, reports and a traceable tax calculation. First-hand, self-reported experience, contrasted with three other people doing the same with plain-text accounting.

Published on 12 min read2,662 words

Diagram in four steps: receipts and statements sent by email, Claude Code in an isolated container, a Beancount ledger with rules and reports, and a pull request the person reviews and merges.
Our own diagram of the workflow Pyry Haulos describes.Image: Agents Finance · Own work

What they do and how

The author keeps his personal books as a Beancount ledger in a Git repository and lets Claude Code maintain it. New data arrives by email: he forwards receipts, bank statements or credit card bills, Airut starts a Claude Code session in an isolated container, and the agent books the entries, applies or adds categorisation rules, regenerates reports and opens a pull request with content-aware diffs. A custom tax engine on top of the ledger computes his tax liability so that every figure can be traced back to entries and statements. He also asks questions in plain language, such as whether a forgotten subscription is tax-deductible.

Reported result

Stated by the author, without independent verification: the system replaced spreadsheets, imports now take an email, and Claude has built “a ton” of tooling and reports around the Beancount core. His published example: Claude found a 317.29 EUR LinkedIn charge from 18 October 2025 left uncategorised, moved it to a Finnish deductible work-tools account, added a rule for future charges and updated his 2025 residual tax balance (net impact −160.58 EUR), then confirmed its reasoning citing vero.fi when pressed. No figures on time saved, error rates or a tax authority review are published.

Stated figures. An identified person or organization states that they have used it. The results are stated by the source; we have not audited them.

What has really been tested

On 20 October 2026 we read both of the author's posts, the Airut website and repository metadata (MIT licence, created 3 February 2026, last push 18 October 2026), Jamie Tanna's post, the two Hacker News comments and the Growthy guide. We have not run Airut, have not seen the author's ledger, tooling or prompts, and cannot verify the tax calculation. The tax categories are Finnish; the architecture is what we consider transferable. This is not tax advice.

How to replicate it

Start a Beancount ledger in a private Git repository with a small chart of accounts and opening balances. Let Claude Code write importers for your bank and card exports, a fingerprint per transaction to avoid duplicates, and categorisation rules kept as code. Add balance assertions from each statement and make the agent run the Beancount checker before it proposes anything. Have every change land as a pull request you review, run the agent in a sandbox with no access to the rest of your disk, and only then add email or chat as the front door.

In two sentences

Pyry Haulos, a software engineer, writes that his personal books now live in a Beancount plain-text ledger maintained by Claude Code, and that he feeds it by emailing receipts, bank statements and card bills: the agent answers with a pull request containing the new entries, regenerated reports and diffs he can review before anything is merged. It is a first-hand account from one person, with one detailed worked example and no audited figures, but the architecture is unusually explicit about where the controls sit, and three other people describe converging versions of the same idea.

Who does it and what kind of evidence this is

Haulos publishes the story in a blog post dated 28 March 2026, Building Useful Agents Over Email. Most of the post is about software development: since his first email exchange with Claude Code on 12 January 2026 he says he has built “almost exclusively over email”, with more than 1,000 pull requests across his personal projects. That number is about all his projects, not about bookkeeping.

The finance part is the section titled “Accountant”, and it matters because, in his words, the tool he now uses for everything “originally branched off from a personal plain-text accounting system”. He wanted to leave spreadsheets for a proper double-entry system, chose Beancount, and found that “plain-text accounting is a perfect technology for the age of text-native LLMs”.

Two things to keep in mind when reading it:

  • He has a stake, but not a commercial one in the post. He is the author of Airut, the open-source (MIT) program his setup runs on, and he wants people to use it. Nothing is sold, and the tax software he describes is private.
  • The results are his own description. There are no measurements of time saved or error rates, and nobody outside his household has checked the books or the tax calculation. His categories also follow Finnish tax rules (he names the Finnish term for deductible work expenses), so the tax specifics do not travel.

We therefore classify it as a real, identified case with self-reported results, and we contrast it with other people who describe similar setups in public.

The problem it tackles

Household finances are a small-data, high-annoyance problem. The transactions are few compared with a company’s, but they arrive in many formats (PDF statements, CSV exports, emailed receipts), the categories matter at tax time, and nobody wants to spend evenings on them. Spreadsheets work until you need double entry, history across years or a calculation you can trace.

Plain-text accounting tools such as Beancount, Ledger and hledger solve the record-keeping side: the whole ledger is a text file, every transaction must balance, and the file can be versioned in Git and diffed like code. What they never solved is the effort of feeding them. That is the gap a coding agent fills: reading messy inputs, writing importers and rules, and keeping the file valid.

Tools and architecture

Diagram in four steps: receipts and statements sent by email, Claude Code in an isolated container, a Beancount ledger with rules and reports, and a pull request the person reviews and merges.
The workflow as described by the author · Agents Finance, own work

From the two posts and the Airut documentation, the pieces are:

  1. The ledger. A Beancount file (or set of files) in a Git repository. Beancount is open source, records double-entry transactions in plain text, and its checker reports an error when an entry does not balance or a balance assertion fails.
  2. Tooling written by the agent. Haulos says that while Claude “could just read and edit the books directly”, over time it has built “a ton of custom tooling and reporting” on top of the Beancount core. His flight summary mentions end-to-end tests for a reconcile.py script, a continuous-integration check that transaction fingerprints are unique, a fix for transfers between entities, and imports of his 2025 accounts.
  3. A tax engine. He describes “a custom DAG-based tax reporting engine” that computes his tax liability “with full transparency, making everything traceable to the ledger and statements”.
  4. The runner. Airut maps an email or Slack thread to a Claude Code session. According to his February post and the project site, each task gets its own workspace and runs in a rootless Podman container; network traffic goes through a proxy with a per-repository allowlist; the container only receives surrogate credentials that the proxy swaps for real ones on approved requests; and the allowlists are read from the repository’s default branch, so the agent cannot loosen them without a merged pull request.
  5. The review step. Results come back in the same email thread as a pull request “with links to generated reports and content-aware diffs”. He reviews and merges.
Five rows describing the controls: isolated container with an allowlist proxy, surrogate credentials, configuration read from the default branch, Beancount balance checks and assertions, and human review of every pull request.
Where the controls sit · Agents Finance, own work

In February he wrote that this sandboxing model is one he is “comfortable using for real work on projects with credentials and financial data”. That is the key design choice: the agent works with full permissions inside the box, and the box decides what it can reach.

Step by step: how to build something similar

The author does not publish his ledger, prompts or tax engine, so this is our reconstruction of a minimal version, using public tools and the habits the four people below describe. Adapt it to your country.

1. Start the ledger by hand

Create a private repository with a main.beancount file, a short chart of accounts (assets, liabilities, income, expenses, equity) and opening balances taken from real statements. Keep it small: you can split accounts later, and every extra account is one more choice for the model to get wrong.

2. Let the agent write importers, not entries

Give Claude Code a sample export from each bank or card and ask it to write an importer script that turns the file into Beancount transactions. Jamie Tanna, who did this for his UK tax return with Ledger, gave the model only the CSV headers and not the raw data, and let it write the conversion scripts. That keeps personal data out of the prompt while the code is being built.

3. Fingerprint every transaction

A Hacker News commenter (zellyn) who built a similar system in an evening with Claude Code advises making the agent “generate fingerprints for each transaction so it’s easy to add individual overrides”. Haulos’s tooling has a CI check for fingerprint uniqueness. Fingerprints make re-imports safe and let you pin a manual correction to one transaction.

4. Keep categorisation as rules in the repository

When you correct a category, ask the agent to add a rule, not just to edit the entry. In Haulos’s LinkedIn example the agent did both: it moved the transaction and “added a reusable categorization rule so future LinkedIn charges get auto-categorized”. Rules are reviewable code; one-off edits are not.

5. Assert balances and run the checker every time

Add a balance assertion for each account on each statement date and instruct the agent (for example in its CLAUDE.md) that nothing is proposed unless the Beancount checker passes. Balance assertions are what turn “the agent says it imported the statement” into “the ledger matches the bank on that date”.

6. Make every change a pull request

Have the agent work on a branch and open a pull request with the diff and a short report (new entries, uncategorised items, changed balances). Review it the way you would review a new bookkeeper’s first month: read the flagged items and spot-check totals against the statements.

7. Sandbox before you automate the front door

Only once the loop works from the terminal, add email or chat. Run the agent in a container that can see the ledger repository and nothing else, with network access limited to what it needs. The abound comment below shows why.

8. Add reports and tax views last

Once the ledger is trustworthy, ask for queries and reports (spending by category, net worth, tax-relevant totals for a period). Ask the agent to show the query behind each figure so you can re-run it, which is what makes the number traceable.

A concrete example (as published)

The one fully worked example in the post starts with a passing thought: Haulos realised that a LinkedIn Pro subscription he had let renew “might be tax-deductible”, and emailed Claude a single sentence: “I paid for LinkedIn Pro at some point last year.”

According to the reply he quotes, the agent:

  • found the transaction: 317.29 EUR on 18 October 2025 on one of his Visa cards, booked to Expenses:Personal:Uncategorized;
  • recategorised it to a Finnish deductible work-tools account;
  • added a rule so future LinkedIn charges are categorised automatically;
  • updated the opening balance of his 2025 residual tax to reflect the extra deduction, with a net tax impact of −160.58 EUR;
  • noted that, because the estimated residual tax had already been paid, he should expect a refund when filing.

He then “pressed it to check if all of this was correct”, and it confirmed with an explanation citing vero.fi (the Finnish Tax Administration) and other sources. Whether the deduction holds is a question for the Finnish rules and his tax return; what the example shows is the shape of the work: a vague question becomes a located transaction, a reviewable change to the ledger, a new rule and a recalculated tax figure, all in one pull request.

Declared results and other voices

Haulos’s own claims are qualitative: spreadsheets replaced by double entry, imports reduced to sending an email, and an “accountant that reads email 24/7, and not only does bookkeeping, but also develops the tooling to do so efficiently”. He publishes no time or accuracy figures.

Other people describe the same pattern in public:

  • Jamie Tanna (1 February 2026) used Ledger and hledger to prepare his first UK self-assessment return. Claude Sonnet 4.5 wrote the scripts converting Stripe, Stripe Connect and Hyperwallet exports, using only the CSV headers, and he then answered each section of the return with hledger queries. He says he would only use a local model for sensitive documents such as payslips and statements, and was testing a small open-weight model for PDFs.
  • zellyn (Hacker News, 4 January 2026) says Claude Code built a whole plain-text finance system from downloaded bank files “in an hour”, then spent the night refining categorisation rules.
  • SOLAR_FIELDS (Hacker News, 11 August 2026) says Claude has done their business books on a Beancount ledger “for the past year or so” and that “it’s worked quite well”. One sentence, no details.
  • Bobby Huang, a CPA partner, published a guide in July 2026 presenting Claude with Beancount as a community pattern for keeping a permanent ledger across sessions, with uncertain transactions flagged for review rather than guessed.

None of these is a controlled comparison, but they point the same way: the plain-text format plus a coding agent removes most of the friction that used to make plain-text accounting a hobby for programmers.

Limitations and risks

  • Privacy and reach. An agent that can read your disk can read more than your ledger. On Hacker News, abound reports that while converting a nonprofit’s books to Beancount, Claude “found my personal Beancount ledger elsewhere on my hard drive and modelled its plan on that”, which they call “a bit of an overreach” and a reason to sandbox agents from now on. Haulos’s container-per-task design is a direct answer to that risk; a laptop session in permissive mode is not.
  • Hosted models see your data. Statements, receipts and tax documents go to the model provider unless you run a local model. Tanna draws that line explicitly.
  • Tax logic is the riskiest part. A traceable calculation is still only as right as the rules encoded in it, and the model’s confirmation that it is correct is not a review. Haulos’s example ends with the agent citing the tax authority, which is useful, but the rules are Finnish and the result is unverified.
  • Self-built tooling needs maintenance. Tens of thousands of lines of agent-written code (Airut alone is 35,000 lines of Python, he says) are an asset only if they are tested; Haulos invests heavily in tests, which most households will not.
  • Single-person evidence. One author, one worked example, no external audit.

Common errors

  • Letting the agent write entries directly into the main branch. Without a pull request and a passing checker, a wrong import becomes history.
  • Skipping balance assertions. Without them, duplicates and missing transactions go unnoticed until year end.
  • Letting the model invent accounts. Restrict categorisation to accounts that already exist, and add new ones deliberately.
  • Correcting entries instead of rules. The same mistake comes back next month.
  • Giving the agent your whole home directory. Mount only the ledger repository.
  • Treating the agent’s confidence as tax advice. Check deductions against the official source and, when the stakes justify it, an adviser.

Conclusions

This case is interesting less for the email trick than for the combination underneath it: a text ledger that a machine can validate, an agent that writes tools and rules instead of one-off edits, a sandbox that limits what it can reach, and a pull request as the moment a person decides. Each piece exists separately; Haulos’s contribution is to show them working together on his real personal finances. For a household or a sole trader, the transferable lesson is to start with the ledger, the checker and the review step, and to add the convenient front door last.

Sources

We wrote this entry in our own words from the sources above and checked that the links worked on October 20, 2026. Is anything incorrect? Tell us.

Newsletter

The Agents Finance weekly newsletter

Once a week, the new use cases, prompts and tutorials on AI in finance and ERPs. No spam; unsubscribe in one click.

Controller: Agents Finance. Purpose: sending you the weekly newsletter. Legal basis: your consent, which you can withdraw at any time with the unsubscribe link in every email. Processor: Mailrelay (WEBLEGAL SL). Rights: access, rectification, erasure and the rest, by writing to [email protected].

Related entries

Keep exploring