qonto-assistant/INTENT.md

135 lines
5.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# INTENT
> This file explains why **qonto-assistant** exists — the problem it solves,
> the principle that governs its boundaries, and what it must never become.
> Blueprint: `specs/ArchitectureBlueprint.md`. Origin: binky-control
> BINKY-WP-0005 (Qonto custody + first read-only pull) and the multi-harness
> policy-drift problem (2026-07-21).
## Why it exists
Binky (and later other tenants) need agents to **see** bank reality —
balances, transactions, cost-run-rate signals — so the company control plane
can operate without founder spreadsheet archaeology. Credentials already live
in OpenBao (`tenants/binky/qonto-api`); the thirdparty REST API works.
What fails as scale:
- Wiring vendor MCP or bank keys into **every** coding agent / harness
(Claude, Codex, Cursor, Grok, agent-harness, …) creates **policy drift**.
- Qonto API keys are **not** scope-limited server-side: there is no
“read-only key.” Spend and volume-cost actions must be blocked **before**
the vendor sees them.
- Agent-harness is the session policy shell, not the place to reimplement
bank rules per runtime. llm-connect is LLM routing, not domain tools.
**qonto-assistant** exists so that **one governed domain service** is the
only component allowed to hold the bank credential and speak Qontos
protocol. All harnesses are clients of that service. Policy is code + tests
in one place.
## Purpose
`qonto-assistant` is a **policy-governed Qonto domain assistant**: a dual
surface (**REST + MCP**) for agentic and scripted finance awareness under a
hard **no spend / no volume-cost** policy (v1).
Core principle:
> Harnesses never hold the bank key. The assistant is the choke point.
> Default deny. Reads for control-plane awareness; payments stay Red lane
> (human in the Qonto app).
## Primary utility
### As a multi-harness finance tool
- Streamable-HTTP **MCP** for interactive agents (one client config, no
secrets in MCP configs).
- Stable **REST** for rhythm sessions, CostRunRate refresh, CI smoke, and
non-MCP clients.
- Shared **policy kernel** on every call (tool id + arguments + actor
claims) — not connect-time allow-lists alone.
### As a custody-aware connector
- Fetches secrets only via the sanctioned OpenBao path (ops-warden catalog
`binky-qonto-api` / CCR-2026-0008 pattern).
- Optional flex-auth gate: `finance.qonto.read` (and later finer scopes).
- Audit metadata (who/what/decision) without logging secret material.
### As dogfood for Operational Knowledge
- Internal use on Binky is product evidence (governed bank access for agent
fleets). May graduate to multi-tenant `tenants/<slug>/qonto-api` later.
## Strategic role
```text
OpenBao custody (existing)
+ sole Qonto client identity
+ default-deny tool catalog
+ dual MCP + REST
= consistent finance awareness across every harness
```
It sits **below** agent-harness (session runtime) and **beside** other domain
connectors (email-connect). It does not replace DATEV/StB/DUO; it complements
them with operational bank visibility.
## Governing principles
1. **One policy, many clients** — never reimplement bank rules per harness.
2. **Default deny** — only explicitly allowed read capabilities exist in v1.
3. **No token passthrough** — clients authenticate *to the assistant*; the
assistant alone authenticates *to Qonto*.
4. **Semantic policy, not vendor dump** — we design a safe catalog; we do
not auto-mirror vendor write tools.
5. **Platform fit** — flex-auth, OpenBao, ops-warden, State Hub evidence; no
parallel IAM.
6. **Autonomy lanes** — map to binky-control AutonomyPolicy: reads Green/Blue;
plan change / transfers / API key minting remain Red.
## What it must never become
- **Not a payments engine.** No transfers, SEPA, card issuance, or
fee-bearing create operations in v1 (and only via explicit future DEC +
Red/Yellow gates thereafter).
- **Not a full accounting system.** DATEV / StB / DUO stay authoritative for
books.
- **Not a generic MCP gateway.** Fleet gateways may sit *in front* later;
domain policy lives here.
- **Not an LLM router.** Provider selection stays in llm-connect.
- **Not a scheduler.** Cadence stays in activity-core / agent-harness.
- **Not a secret store.** OpenBao remains custody; this service is a
short-lived consumer.
- **Not a per-harness plugin bag.** Client integration is thin: URL +
workload identity + tool profile name.
## Relationship to other repos
| Repo | Relationship |
| --- | --- |
| `binky-control` | First tenant / consumer; CostRunRate, AutonomyPolicy, business policy source |
| `ops-warden` / `railiance-platform` | Credential front door and CCR/policy for `tenants/…/qonto-api` |
| `agent-harness` | Grants profile `finance-qonto-read` pointing at this service only |
| `llm-connect` | Models that *talk*; this service *acts* on bank data |
| `flex-auth` | Authorization decisions for who may call |
| `email-connect` | Sibling pattern: purpose-built connector, not raw vendor wiring |
## Success looks like
1. Every agent that needs Qonto data uses **only** this service.
2. A single policy change (e.g. tighten export) applies fleet-wide.
3. No bank API key appears in harness env, MCP client configs, or chat.
4. Deny decisions are tested and audited; spend tools are not registered.
5. CostRunRate and Finance Steward can refresh from REST without ad-hoc scripts
holding secrets.
## Normative references
- `specs/ArchitectureBlueprint.md` — architecture and phased delivery
- `research/2026-07-21-mcp-gateway-and-governed-domain-assistant.md` — external
pattern research
- binky-control `integrations/qonto-mcp.md` — custody and first-pull evidence
- agent-harness ADR-001 / INTENT — session runtime boundaries