> ## Documentation Index
> Fetch the complete documentation index at: https://docs.neobank.proofof.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Idempotent financial intents and reconciliation

> Financial and card mutations persist as idempotent intents before provider submission, with at-least-once delivery and indeterminate reconciliation.

# ADR 0005: Persist financial intent before provider submission

This record defines safe write and retry behavior.

## Context

Perflo documents idempotency for only four agent operations. A timeout after a money write may mean that the provider received and executed it.

## Decision

Require `Idempotency-Key` on financial and card mutations. Store the actor, route, key, canonical request hash, operation, and outbox event in one PostgreSQL transaction before provider work.

Treat delivery as at least once. A possible submission enters `indeterminate`; reconciliation checks a stable provider operation reference and never retries blindly.

The dispatcher claims one outbox row immediately before processing it with a five-minute lease. An abandoned claim becomes eligible again. The worker commits `submitting` before provider I/O. If delivery later resumes with an operation still in `submitting`, it marks the operation `indeterminate` without calling the provider. Mandate execution takes the mandate lock before this transition; suspension or revocation cancels queued `accepted` reservations, while a committed `submitting` transition is the linearization point after which submission has begun.

Provider writes that must complete in the request path follow the same state rule. Beneficiary and card writes commit `submitting` before provider I/O. A scheduled reconciler marks stale synchronous submissions `indeterminate` and never resubmits them. Card projections move to `indeterminate` with their operation, allowing a later provider read or operator investigation to resolve the state.

## Consequences

Equal retries return the original operation even if mutable prerequisites later expire. Reusing a key with different input returns HTTP 409. Clients retain the same idempotency key and confirmation intent through transport retries. Provider operation lookup and write idempotency remain production requirements. The replay window, the replay marker, and record retention are decided in ADR-0018.

## Rejected alternatives

* **Untracked request-bound writes**: client disconnects and upstream timeouts lose durable state.
* **Exactly-once claim**: no distributed system boundary supports that guarantee here.
