# The Settlement Journal (/docs/billing/settlement-journal)



Most systems treat money integrity as a convention: the code is careful, the
tests are good, and everyone hopes. The settlement journal makes it a
**property of the storage itself**. Every committed transaction is a set of
balanced entries in integer micro-units that nets to zero per currency — and
the database refuses, at commit time, any transaction that does not.

<LedgerSpecimen />

## The model [#the-model]

Classic double-entry, tenant-scoped, in `int64` micros (1,000,000 µ = 1 unit;
floats never appear):

<TypeTable
  type="{
  Account: { type: &#x22;row&#x22;, description: &#x22;One (tenant, type, owner, currency) tuple, created lazily on first posting. Types: buyer_wallet, held_funds, seller_payable, platform_fee, external_settlement.&#x22; },
  Entry: { type: &#x22;leg&#x22;, description: &#x22;A debit or credit of a strictly positive amount against one account. Sign lives in the direction, so a zero-value leg is unrepresentable.&#x22; },
  Transaction: { type: &#x22;unit&#x22;, description: &#x22;Two or more entries that net to zero per currency, posted atomically. Kinds mirror the settlement lifecycle: hold, capture, release, direct-commit, claw-back.&#x22; },
  Settlement: { type: &#x22;state&#x22;, description: &#x22;Per unit of work and party — identified by (decision, recipient) or the award's settlement ref — transitioning held → committed/released under optimistic locking.&#x22; },
}"
/>

## Three layers of enforcement [#three-layers-of-enforcement]

<Steps>
  <Step>
    **The posting engine cannot express an imbalance.** Pure constructors build
    each transaction's legs from the settlement event; a transaction that fails
    zero-sum validation never leaves the domain layer. Zero legs are omitted, not
    zero-valued.
  </Step>

  <Step>
    **The database enforces it again at commit.** Deferred constraint triggers on
    *both* the transaction header and the entries reject an unbalanced set, a
    single-legged transaction, and the empty-transaction hole — even against a
    future writer that bypasses the Go engine entirely. Composite foreign keys
    make a cross-tenant or cross-currency entry structurally impossible, and
    row-level security is *forced*, so even the table owner cannot read across
    tenants.
  </Step>

  <Step>
    **Append-only, forever.** Update and delete are rejected by trigger on
    transactions, entries, and idempotency claims. There is no correction — only a
    new compensating transaction: a release reverses a hold, a claw-back reverses
    a commit, and the ledger's history is the audit trail.
  </Step>
</Steps>

## Posting rules [#posting-rules]

A settlement moves through states, and each transition posts one balanced
transaction. Reversal is never an edit — it is a new compensating posting:

```mermaid
stateDiagram-v2
    [*] --> pending
    pending --> held: hold
    held --> committed: capture
    held --> pending: release
    pending --> committed: direct commit
    committed --> reversed: claw-back
    reversed --> [*]: compensating entries only
```

One capture of a single unit of work, as the entries actually land — the sum is
what the database checks at commit:

| Leg                  | Direction | Micros      |
| -------------------- | --------- | ----------- |
| Buyer wallet         | debit     | −57 250 000 |
| Worker payable       | credit    | +54 387 500 |
| Platform fee         | credit    | +2 862 500  |
| **Net per currency** |           | **0**       |

Each settlement event posts one balanced transaction:

<StateGrid label="Event → entries">
  <StateCard title="hold" code="pending → held" tone="gold">
    Reserve the gross from the buyer's wallet into held funds when a winner is
    committed with a hold.
  </StateCard>

  <StateCard title="capture" code="held → committed" tone="commit">
    Drain held funds into the seller's payable and the platform fee. Guarded by
    a versioned state transition — a capture and a release racing for the same
    hold produce exactly one winner.
  </StateCard>

  <StateCard title="direct commit" code="charge" tone="worker">
    The single-step charge path, keyed per unit of work *and* party — a
    decision that charges two recipients produces two independent settlements,
    never a collision.
  </StateCard>

  <StateCard title="claw-back" code="warranty return" tone="halt">
    A <Term name="Warranty" /> return posts the reversing entries and stamps
    the settlement reversed — once. A second reversal attempt is a typed state
    error, not a double refund.
  </StateCard>
</StateGrid>

## Idempotency with teeth [#idempotency-with-teeth]

Every posting carries a key derived from the event's **stable identity** —
never a per-call UUID — plus a fingerprint of its economic content. A replay
converges on the original transaction. A reused key whose fingerprint differs —
same event id, different money — fails loudly as a conflict. And the
tenant-context guard means a caller that forgets its tenant scope gets an
error, not a silent no-op against an invisible row.

## Rolling out beside the ledger [#rolling-out-beside-the-ledger]

The journal does not replace the existing ledger — it **co-writes beside it,
atomically**. With the settlement flag on, a charge writes its legacy ledger
row and its balanced journal transaction in one database transaction: both
commit or neither does. Data the journal cannot faithfully express — an amount
that rounds to zero micros, a malformed currency — skips the journal with a
logged reason and never fails the charge. Reconciliation compares specific
account movements against the ledger, transaction by transaction, before
anything reads from the journal as truth.

<Fact label="The receipt seam">
  Committed journal transactions flow into the work's <Term name="Receipt" />
  as settlement evidence — linked after commit, best-effort, converging on
  retries — so *what moved* and *what was proven* reference each other without
  either being able to corrupt the other.
</Fact>

<Fact label="Rollout">
  Off by default behind `settlement.journal_enabled`, with per-tenant
  enablement for staged rollout. The flag gates only the co-write — flag-off
  behavior is byte-identical to the pre-journal system.
</Fact>

## Where to go deeper [#where-to-go-deeper]

<Cards>
  <Card title="Settlement" href="/docs/primitives/settlement">
    The primitive this journal implements.
  </Card>

  <Card title="Warranty" href="/docs/primitives/warranty">
    The review window whose returns become compensating claw-backs.
  </Card>

  <Card title="Agent procurement" href="/docs/strategies/agent-procurement">
    Where the cleared price the journal settles comes from.
  </Card>

  <Card title="Usage metering" href="/docs/billing/usage-metering">
    The micro-unit metering the journal's amounts are denominated in.
  </Card>
</Cards>
