ADR index
The full ADR text lives in
agent/DECISIONS.md in the source repo. This page is the index +
the "what's still load-bearing" call-out for each.
Active ADRs (031+)
The current direction. Read these.
ADR-031: e-Financials as the headless accounting backend
We don't build our own bookkeeping data model. The agent talks to e-Financials' API and writes entries there. e-Financials is the state-built Estonian platform run by RIK. Decision settled the "build vs integrate" question.
ADR-032: Pydantic AI + OpenRouter as the agent framework
We chose Pydantic AI over Agno, Hermes Agent, or from-scratch. Pydantic AI's strengths: tool-loop + dependency injection + provider-agnostic via OpenRouter. We rejected Agno (auto-learning memory module is the wrong shape for financial data) and Hermes (self-improving loop is also wrong shape).
ADR-033: Telegram + Claude.ai-via-MCP are the only user surfaces
Superseded by ADR-036. Originally we picked Telegram for the ingest surface and Claude.ai (via MCP) for the chat surface.
ADR-034: PROJECT (draft) status IS the staging layer
e-Financials supports a PROJECT (draft) status. Drafts are free
per e-Fin's pricing (footnote 3). We use them as our staging
layer — write a draft, attach the PDF, then register it once
the operator approves. No parallel staging DB needed.
ADR-035: VAT / TSD / annual-report submission is manual
The agent doesn't automate KMD INF, TSD, or annual report submission. Operator submits via e-Fin's web UI (~10 min/month total). Automating tax-authority submission is a regulated surface we don't want to touch.
ADR-036: Discord (not Telegram) is the chat surface; reconciliation is in scope
Pivot from ADR-033. Discord won on file-upload reliability, button-state persistence, and slash-command UX. Also added reconciliation to the agent's scope — bank-side ingest + matcher became part of the core loop.
ADR-037: iseppo/e-arveldaja-mcp as a Python-port reference; do not depend at runtime
The TypeScript iseppo/e-arveldaja-mcp project wraps the same
e-Financials API. We port patterns from it (auth,
base-resource shape, per-entity API modules, createAndSetTotals
flow, MatchIndex narrowing) but do NOT depend on it at runtime.
Apache 2.0 licensing; attribution in source comments.
ADR-038: Wise bank ingestion is CAMT.053 file drop, not API polling
Partially superseded by Enable Banking. Original plan was CAMT.053 file imports for Wise. Subsequently the Enable Banking PSD2 path made API polling cheap and reliable, so the EB poller became the primary path (Wise included). CAMT.053 importer is retained for offline / historical loads.
ADR-039: Discord stays the only live surface; surface decoupling + a branded web UI are deferred to product phase
Confirmed Discord as the live surface for now. A branded web UI (dashboards, customer-facing portal) is deferred to product phase. Rejected Spacebar/Fermi as Discord alternatives — not worth the migration cost.
Archived ADRs (001-030)
The Payload prototype era. Custom backend, custom auth, custom
data model. Archived at archive/payload-prototype/ (gitignored).
The active design (031+) is a clean break from that direction —
the older ADRs are historical context only.
You only need them if you're asking "why did this take a year to arrive at the current design" or "what specifically was tried and rejected before e-Financials." Otherwise: ignore.
How ADRs work in this repo
New ADRs go in agent/DECISIONS.md at the bottom, numbered
sequentially. They're written in three sections:
- Context — what's the problem we're trying to decide.
- Decision — what we picked.
- Consequences — what this commits us to (and what it forecloses).
ADRs are immutable. If we change our mind later, we write a new
ADR that supersedes the old one. The old one stays in place with
a _Superseded by ADR-XXX_ note at the top.
This page reflects the latest superseding chain. The raw DECISIONS.md is the source of truth.