Files
firefly/docs/superpowers/specs/2026-08-23-accounting-agent-architecture-design.md
T
jakeandClaude Fable 5 0e1097bdff Amend spec: automatic wallet ingestion via email receipts
Jake wants no manual CSV exports. Wallets (Cash App/Venmo/PayPal) are
now fed by parsed transaction-receipt emails as the primary path, with
browser-automation statement fetch as reconciliation backstop and the
CSV drop folder demoted to break-glass fallback. Finance inbox decided:
finance@ordinatorlabs.com (IONOS IMAP; jbnel.dev has no MX). IMAP
connector promoted from Phase 5 into Phase 2.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uv7wnzF6Xv6fmaRjFTiMMq
2026-08-24 00:34:21 -05:00

156 lines
8.8 KiB
Markdown

# Personal Accounting Agent — Architecture Design
**Date:** 2026-08-23
**Status:** Approved (Jake, 2026-08-23)
**Scope:** Master architecture and phase decomposition. Each phase gets its own spec and implementation plan; this document is the frame they hang on.
## Purpose
Build a personal accounting agent around the existing Firefly III stack at
`https://firefly.jbnel.dev`. The agent:
1. Monitors account balances across all institutions.
2. Assesses spending trends, tracks budgets, and forecasts cashflow.
3. Prepares utility and other bill payments, executing only with Jake's explicit approval.
4. Alerts Jake to pertinent information through Telegram, ntfy, and email.
5. Maintains account records (statements, bill PDFs) in a structured local folder, with cloud sync later.
6. Keeps all record data queryable — ledger data in Firefly, everything else in a dedicated agent database.
## Decisions
These were settled in the design conversation and bind all phases:
| Decision | Choice |
|---|---|
| Primary bank feed | SimpleFIN Bridge (read-only, ~$1.50/mo) |
| Coverage strategy | Connector layer: SimpleFIN plus per-institution connectors until NFCU, TFCU, Cash App, Venmo, and PayPal are all covered. Verify real coverage per institution early; assume nothing. |
| Wallet feeds (Cash App, Venmo, PayPal) | *(Amended 2026-08-24 — Jake wants automation, no manual CSV.)* Primary: per-transaction email receipts parsed from the finance inbox (near-real-time; these apps support no aggregators). Backstop: browser automation fetches monthly statements/CSVs for reconciliation. Manual CSV drop folder is break-glass fallback only. PayPal may later upgrade to its Transaction Search API via business account. |
| Finance inbox | `finance@ordinatorlabs.com` — dedicated IONOS mailbox (ordinatorlabs.com already has IONOS MX; jbnel.dev has no mail hosting). Agent polls IONOS IMAP. Optional later: forward `finance@jbnel.dev` into it. |
| Bill-pay autonomy | Prep + approval. The agent tracks, verifies funding, and asks. Money never moves without an explicit approval from Jake. |
| Runtime | Hybrid. One Python worker container does deterministic work on schedules; scheduled Claude sessions do judgment work (analysis, forecast narrative, anomaly triage). |
| Notification channels | Telegram bot (interactive: alerts, approvals), ntfy (urgent push), email (digests, receipts). Routed by message class. |
| Document acquisition | Dedicated finance email inbox via IMAP first; browser-automation downloads later for billers that never email PDFs. |
| Business accounts | Separate Firefly instance when a venture opens. This instance stays purely personal. The connector layer is account-agnostic so it can serve both. |
| Agent state | `agentdb`: a separate database in the existing Postgres container. |
## Architecture
One new container, `agent`, joins the existing compose stack (Firefly III core,
Data Importer, Postgres 16, Redis, cron) behind Traefik. The worker is a Python
3.12 application under `agent/` in this repo, structured as modules with hard
boundaries so any module can become its own service during the planned k8s
migration:
- **Connectors** — pull data from sources on schedules. Each connector
implements one interface: fetch → emit canonical records. Initial set:
SimpleFIN poller, CSV drop-folder watcher, IMAP inbox poller. Later: browser
automation jobs.
- **Sync engine** — normalizes connector output into canonical models
(transaction, balance, document, bill), deduplicates, and pushes to Firefly
via its REST API using a personal access token.
- **Notifier** — one interface, three sinks (Telegram, ntfy, SMTP). Message
class determines routing: interactive requests and real-time alerts go to
Telegram, urgent one-way pushes to ntfy, digests and receipts to email.
- **Rules engine** — deterministic checks after each sync: low balance, large
or unusual transaction, failed sync, upcoming bill without positioned funds.
- **Bill module** — maintains the bill calendar in `agentdb` from Firefly
bills and parsed bill emails; runs the approval workflow.
- **Scheduler** — APScheduler; every job idempotent and individually
triggerable for testing.
Claude sessions run on schedules outside the container (Claude Code
routines/cron). They read the Firefly API and `agentdb`, write analysis and
narratives out through the notifier, and never write directly to the ledger.
The agent container exposes the notifier to them as one token-authenticated
HTTP endpoint (`POST /notify`), reachable only on the internal Docker network
or via SSH tunnel — never through Traefik.
### Data flow
```
SimpleFIN ─┐
CSV drop ─┼→ Connectors → canonical models → dedup → Firefly API (ledger)
IMAP ─┤ │
Browser ─┘ └→ agentdb (documents, bills,
sync runs, approvals)
Firefly API + agentdb → Claude sessions → Notifier → Telegram / ntfy / email
```
Deduplication: use the source's external ID where one exists (SimpleFIN
provides one); otherwise a content hash of date + amount + account + normalized
description. Firefly's own duplicate detection is the backstop, never the
primary mechanism.
### agentdb schema (v1)
- `sync_runs` — one row per connector execution: connector, started, finished, status, counts, error.
- `documents` — index of filed records: path, sha256, institution, account, doc type, period, source, received date.
- `bills` — calendar: payee, expected amount, due date, funding account, autopay flag, status.
- `approvals` — bill-pay approvals: bill, amount, requested at, approved/denied at, Telegram message ref, executed at.
## Safety and error handling
- **Idempotent imports.** Dedup keys make every retry safe.
- **Escalating failure alerts.** Every connector run logs to `sync_runs`; three
consecutive failures for a connector escalate to ntfy.
- **Secrets stay server-side.** `.env` on the host only, never in the repo.
Aggregator access is read-only.
- **Approval integrity.** An approval exists only as an `approvals` row created
by Jake's own Telegram interaction. The executor re-checks the approval
immediately before acting and refuses stale or amount-mismatched approvals.
- **Payment receipts.** Every browser-automation payment run captures
screenshots and files them as documents.
## Documents
Local folder structure (exact layout specified in the Phase 5 spec):
`records/<institution>/<account>/<year>/` with normalized filenames
(`2026-08-nfcu-checking-statement.pdf`). Every filed document gets a
`documents` row. Cloud sync via rclone; Jake picks the target during Phase 5.
## Testing
TDD throughout (superpowers test-driven-development skill). Connectors test
against recorded fixtures: captured SimpleFIN JSON, real Venmo/Cash App/PayPal
CSV exports, sample bill emails. The Firefly client tests against a throwaway
local Firefly via a compose test profile. One end-to-end smoke test proves
fixture → dedup → Firefly.
## Deployment
The stack runs on a remote host behind Traefik; this repo is the config source.
Assumed workflow: SSH to the host, `git pull`, `docker compose up -d`. Confirm
the exact workflow during Phase 1 planning and record it in the Phase 1 spec.
## Phases
Each phase is its own sub-project: spec → plan → implementation. Later phases
may not start until the prior phase runs in production.
1. **Foundation** — Firefly configured for API use (personal access token,
asset accounts created); `agent/` skeleton: Dockerfile, config loading,
scheduler with a heartbeat job, `agentdb` migrations, compose service,
deployed to the host.
2. **Ingestion** — SimpleFIN → Firefly sync with dedup; verified coverage for
NFCU and TFCU; IMAP receipt connector (promoted from Phase 5) parsing
Cash App/Venmo/PayPal transaction emails from the finance inbox; CSV
drop-folder connector kept as break-glass fallback.
3. **Alerts & monitoring** — notifier with all three sinks; rules engine:
low balance, large/unusual transaction, sync failure, negative trend.
4. **Analysis & forecasting** — scheduled Claude sessions: weekly spending
review, budget tracking, recurring-transaction detection, 30/60/90-day
cashflow forecast, monthly digest.
5. **Documents** — PDF extraction and filing from the finance inbox (IMAP
plumbing already live from Phase 2), browser-automation statement
downloads, document index, cloud sync target chosen and wired.
6. **Bills** — bill calendar, funding checks, Telegram approve/deny flow,
browser automation for approved payments and statement downloads.
7. **Later** — business Firefly instance when a venture opens; k8s migration
per `k8s/README.md`.
## Out of scope
- Investment portfolio management and tax preparation.
- Multi-user support; this system serves Jake alone.
- Modifying Firefly III itself; the agent is strictly an API consumer.