Skip to content

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:

  1. Context — what's the problem we're trying to decide.
  2. Decision — what we picked.
  3. 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.