Knowledge

Set up a local-first Bookkeeper agent team in Agent Zero

A from-zero guide to install a confidentiality-preserving bookkeeping/accounting agent team (Bookkeeper, Collector, Coder, Auditor) into an Agent Zero harness — for humans and their AI agents. OSS-only, no paid services by default, confidential data kept local. Owning your own AI Workshop.

playbook agent-zero how-to bookkeeping local-first privacy

Draft: not yet reviewed/published by a human.

Set up a local-first Bookkeeper agent team in Agent Zero

This page does two jobs:

  1. For the owner — stand up a small team of AI agents that keeps the books for a self-employed person (or small business) while keeping every confidential figure on your own machine. You do not write code or run commands; your agent does the install. The only things you do by hand are create the four agents in the Agent Zero launcher and, optionally, turn on at-rest encryption on the host later.
  2. For the owner's AI agent (Agent Zero or similar) — paste this page's URL into the chat and the agent creates the team from the templates below, asks only for what it cannot make itself, and never puts confidential data where a cloud model can see it.

The whole design rests on one rule. No monetary value ever passes through a model's tokens. Amounts move file → code → ledger. A model may read data to decide (a category, an account mapping, "these two rows are a candidate match") but never to transcribe a number. Every feature is checked against this rule.

This is bookkeeping/accounting now; tax preparation comes later. The MVP deliverable is a working collection + bookkeeping team that can safely add features — not a complete tax system up front.


How the team is shaped (read once)

Four agents, two of them inside your trusted local zone (they may see plaintext), one deliberately outside it, and one watching the wire between them.

Agent Where it runs Model Sees confidential data? Job
Bookkeeper Trusted local Local model only Yes (plaintext) Owns the ledger; makes decisions/categories; drives deterministic OSS tools; never transcribes amounts
Collector Trusted local Local model; optional Computer Use Yes (its own exports/screenshots) Pulls data in: bank/exchange CSV, portal downloads, invoice/receipt OCR. Isolates hostile web content from the ledger loop
Coder Outside the zone Cloud-capable is fine Never Authors/fixes ingestion scripts and solves data problems using public docs/repos only. Lives with no access to your data store
Auditor Gatekeeper Local model Only the messages, not the store Inspects every Bookkeeper/Collector ↔ Coder message, both directions, for leaks

Why a Coder at all if it can't see the data? Ingestion is where things break (a bank changes its CSV columns). The Coder fixes those parsers — but only ever from code-generated redacted/synthetic fixtures, never a real file. When the Bookkeeper says "this parser chokes on field X," the Auditor strips any real account number or name before that report reaches the cloud model, and reviews code coming back for anything that looks like exfiltration.

Why a separate Collector? A hostile bank page can't directly steer the privileged ledger loop. Its content becomes files that get sanitized/typed at the boundary, and Computer Use (browser automation) lives on one agent without touching Bookkeeper's core.


Part A — For the owner (human)

A0. What you need

Requirement Notes
An Agent Zero container (the agent-zero/agent-zero Docker image) Already running if you're reading this in a chat with your agent.
A local model for the trusted agents Bookkeeper/Collector/Auditor must run on a model that stays on your machine (Ollama, LM Studio, llama.cpp, etc.). Configure it in Agent Zero Settings → models.
Optional: a cloud model — only for the Coder The Coder may use a powerful cloud model precisely because it never touches your data.
Optional, later: at-rest encryption on the host See A4. Not needed to start.

Owners don't code in this workflow. All installs and configuration are run by your agent (Part B). You create four agents in the launcher and paste a short block into each — that's it.

A1. Create the four agents

In the Agent Zero launcher / dashboard, press + (new agent) four times. For each one set only these options in the create-agent panel:

Agent Profile Model role Notes
Bookkeeper bookkeeper local chat + utility Keep it pointed at your local model
Collector collector local chat (+ Computer Use if you want portal downloads) Can run browser/Computer Use inside the container
Coder coder cloud-capable Put this one in its own isolated workspace/project so it physically has no path to your data store
Auditor auditor local utility Small/fast model is fine

If the four profiles don't exist yet, your agent creates them (Part B) — you still just pick them from the panel.

A2. Hand each agent its instructions

Open the Bookkeeper chat and paste the block below (the full per-agent scripts are in Part B; repeat for Collector, Coder, Auditor):

Read https://ownersclub.ai/knowledge/playbooks/bookkeeper-agent-team/
and follow Part B to set me up as the <ROLE> agent of the Bookkeeper team.
Ask me before installing anything, and never send confidential data to the Coder.

A3. Give it your first data (the boring, safe path)

Start with CSV exports — a bank statement and/or an exchange export. The very first milestone is deliberately no AI in the money path: your files go through deterministic code into a Beancount ledger, and you get a register / balance sheet / income statement back. If that works without any model touching a number, every later feature inherits the same guarantee.

A4. Optional: turn on at-rest encryption later

By default your Bookkeeper's data sits in its workspace in plaintext (protected only by disk/VM encryption and container isolation). When you want it encrypted at rest, the standard tool is gocryptfs — but it needs the host to grant the container FUSE access:

# host/orchestration level — your agent CANNOT add these from inside the container
docker run --device /dev/fuse --cap-add SYS_ADMIN ... agent0ai/agent-zero

Why this is optional and deferred: a typical Agent Zero container (including the one supervising this install) has no /dev/fuse and no SYS_ADMIN, so gocryptfs cannot run there. The team is designed to work now and to adopt gocryptfs cleanly once you relaunch its container with those two flags from the host. Until then, treat "at rest" as "protected by your disk/VM encryption," and stop the agents before treating data as truly at rest.


Part B — For the AI agent (paste this)

You are the owner's supervising/installing agent, not a member of the team. You author and wire up the four agents; you do not run bookkeeping yourself, and you must never install the team's runtime into your own supervising container. Provision it in each agent's own workspace/container.

B1. What the agent should do

You are installing a local-first Bookkeeper team for this owner.

Roles to create (Agent Zero profiles under usr/agents/<name>/):
  bookkeeper  collector  coder  auditor

Hard rules you must follow:
  - INVARIANT: no monetary value is ever produced or copied by an LLM. Amounts move
    file -> deterministic code -> ledger. A model may emit only categorical decisions
    (category, account mapping, "candidate match id X") or typed values consumed by code.
  - The Bookkeeper + Collector are TRUSTED-LOCAL and may read plaintext confidential data.
    The Coder is UNTRUSTED-to-data: it must never receive a real file, screenshot, or
    value. Outbound reports to the Coder are code-generated REDACTED/SYNTHETIC fixtures.
  - Every Bookkeeper/Collector <-> Coder message passes an Auditor scan BOTH directions:
    outbound = secret/pattern scrub (accounts, names, addresses, amounts, keys) + no raw
    attachments; inbound = review generated code for exfil/supply-chain risk before it runs.
  - Make widening structurally impossible: the Coder's workspace has NO path to the data store.
  - OSS-only, no paid services by default. Our own code is AGPL-3.0. Consume third-party
    tools as separate programs (subprocess / file handoff), unmodified; do not link GPL-
    2.0-only code into our single AGPL program. Keep Beancount/rotki as subprocesses for
    architecture, not license-dodging.
  - Log EVERY user interaction and agent action to an append-only, hash-chained JSONL event
    log (who/when, decision, rule/tool fired, input file hashes). Corrections are appended,
    never overwritten. The log must load into a Jupyter notebook for owner replay/review.
  - Ask the owner before installing dependencies. Do not provision runtime deps into the
    supervising container.

B2. Hard rules for the agent (the two safety axes)

Axis Concern Mechanism
Vertical (inside the trusted zone) Model must not corrupt numbers; hostile web content must not drive the loop Deterministic kernel + OSS ledger; model = NL↔typed-facts edges only; Collector quarantines the internet
Horizontal (between agents) Confidential data must not reach the cloud Coder Physical separation + default-deny channel + Auditor as defense-in-depth

A suite that cannot distinguish "blocked" from "inapplicable" is theatre. When you test the confidentiality boundary, prove a real benign leak is blocked and a benign redacted bug report passes — both directions.

B3. Tooling to rely on (don't rebuild it)

Function Tool Note
Ledger engine Beancount (subprocess) Per-posting cost supports per-wallet basis
Ledger UI Fava Verify license from repo
Crypto data collection rotki (subprocess) AGPL — process boundary
Invoice/receipt OCR invoice2data MIT
Market/exchange data ccxt + first-class CSV import Provider-agnostic; a vendor's free tier is not infrastructure
Dedup/matching deterministic Python scorer first Add ML later if it earns its keep

Schema hooks to honor now, even before tax: per-wallet cost basis (Rev. Proc. 2024-28 ended universal pooling for 2025+) is a schema requirement, and reconciliation must be a diff, not a merge — both sides keep their figures and differences get explained, never averaged.

B4. Build order (get a working team first, then extend safely)

  1. P0 Foundations — confirm the target container is real Linux; stand up the Bookkeeper workspace; wire the four profiles to the right model roles; re-establish any tool claims on this runtime before relying on them.
  2. P1 Collection + bookkeeping, zero AI in money path — CSV → typed facts → Beancount → register/balance sheet/income statement; deterministic dedup scorer; audit-trail v1 (hash-chained JSONL).
  3. P2 Team topology + confidentiality plumbing — isolated Coder workspace, default-deny channel, synthetic-fixture handoff, bidirectional Auditor scan.
  4. P3 Ingestion hardening — local model turns receipts/emails into typed facts under constrained decoding; Collector Computer Use (host or container, owner's choice); "no copy-paste-through-model" tests.
  5. P4 Merge kernel + reconciliation — invariants: no-create / no-delete / sum-preserve-per-currency / idempotent / orphan-free; diff-not-merge with explanation.
  6. P5 Tax preparation (later) · P6 Formal layer (future, gated) — only once the collection+bookkeeping team is working and safe to extend.

B5. If the owner wants at-rest encryption now

Relaunch the Bookkeeper container from the host with --device /dev/fuse --cap-add SYS_ADMIN, install gocryptfs there, mount the plaintext view before the container starts (systemd RequiresMountsFor= or a wrapper, so bind mounts never point at ciphertext), and pass -allow_other if the agent user differs from the mounting user. Passphrase is piped/typed at startup — never a keyfile sitting next to the ciphertext. Until that's done, say plainly that data is protected by disk/VM encryption only.


What this design does not do (yet)

  • No tax e-filing, no paid services. Tax preparation is a later phase; when added it starts as working papers over Beancount with an MIT cross-check oracle, and any IRS e-file path is an optional integration the owner wires up themselves.
  • No assumption that encryption works everywhere. At-rest gocryptfs is opt-in and host-granted; the team ships working without it.