Skip to content
Get access

Reconciliation · PG-25

Reconciliation by relationship: many sources, one verified number

Billing totals, terminal batches, channel payouts and the bank deposit tie into one ledger — with every match, exception and adjustment on one traversable evidence path.

  • 2..N sides per run
  • versioned match rules
  • typed assertion edges
  • review-gated write-back
  • sealed evidence bundle

Reconciliation by relationship starts from one question: does every number in the close trace to the bank? A reconciliation run in Ledgerbook AI accepts two to many sides — billing totals, terminal batches, channel reports, PSP settlements, bank statements — matches them pairwise or against a declared control total, and records each hop's counts and deltas. Matches, settlements and adjustments are typed edges on one lineage graph — the **Financial Event Web**: the typed lineage graph plus the reconciliation assertion edges laid over it, in which billing records, terminal batches, channel statements and bank lines are nodes that must tally against the postings they claim to explain. It is a single traversable path from source to bank. Exceptions carry a reason code, an owner and aging; corrections are proposed as provisional entries that post only through review gates, never on their own. Runs, matches, the rule registry — deterministic, tolerance **and scored-rule** passes — N-sided control totals, assertion edges, review-gated write-back, a KPI subset (auto-match rate, exception rate, aged open value, drift status) and the sealed basic evidence bundle ship at PH-1. Fuzzy and model-based matching, which run above the core, and the full KPI/SLA projection surface are Roadmap (PH-2).

Verified 2026-09-19 · source: reconciliation engine reference FR-150–157, lineage FR-525–527

Reconciliation primitives

2..N

sides per run, including a declared control total · FR-152

8

controlled reason codes on every match decision — eight in the shipped vocabulary today, extensible as policy data · FR-151

≤ 4 hops

per scoped graph projection, stamped by its knowledge watermark · API-reconcile

0

findings that post without an approval event — proposals run the same gates as any entry · FR-154

N-sided control totals: billing, terminals, channels and bank — one verified number

A run accepts two to many sides. At least one side may be a declared control total — a source-system total, a PSP settlement batch total or a bank statement total — and the run matches pairwise, against an anchor side, or as a chain of custody across hops. Scope is always (scenario, book): no source system is re-exported to make a number fit.

PH-1

Strategies are explicit, per direction

1:1, 1:many and many:1 are selected per direction and recorded on the run — a single payment matching three ledger lines is a documented strategy, not an accident. Re-runs are idempotent on the rule-registry version, the window and the source hashes, so replaying a period cannot double-count it.

FR-150/152 · PH-1

PH-1

A missing side completes the run — never shortens it

When a declared side does not arrive, the run records MISSING_SIDE and completes explicitly. The gap stays visible as an exception with an owner, instead of quietly reconciling a chain that was never complete.

FR-152 · PH-1

Chain of custody — per-hop counts and deltas under tolerances

Hop model · trace: FR-152/153/155, lineage FR-525–527 · run states: created → running → completed | aborted
HopSidesRecorded asA break lands as
1 Billing total → ledger receivables trues_up_to against the declared control total Exception with residual, reason code and owner
2 Terminal batches → ledger sales matches edges under the batch strategy DUPLICATE_SUSPECT / AMOUNT_MISMATCH
3 Channel report → PSP settlement settleswithheld_from for the fees FEE_DIFF or TIMESTAMP_DRIFT
4 PSP settlement → payout → bank deposit clears / deposits_as through clearing accounts In-transit aging past the policy window → finding

Clearing and in-transit accounts carry an expected-zero or expected-balance assertion over a window; items stale past policy raise findings with an owner and escalation · FR-155 · PH-1

The assertion-edge graph — unresolved edges are the exceptions

Every match, exception and adjustment decision is itself a provenance event, so the whole run exports as OCEL 2.1 alongside the entries it touched. Every relationship a reconciliation establishes is a typed edge on the lineage graph. The registry is exactly twelve types: matches, partially_settles, settles, eliminates, trues_up_to, withheld_from, deposits_as, posted_as, aggregates, clears, responds_to and derives_from. Each edge carries its state, the rule-registry version that produced it, the actor or tool, and an evidence path. Edges supersede; they never mutate — and evidence that cannot be resolved fails closed.

Edge states · trace: FR-153 · a rejected or expired edge leaves the set unresolved, and the conservation residual constructs the exception case
StateMeansLeaves the audit trail as
proposed Suggested by a rule pass, or proposed by an agent over MCP A reviewable proposal — never a posting
confirmed Asserted by a human decision or an approved run decision The traversable hop an auditor follows
rejected Explicitly refused — the sides do not belong together An unresolved edge set: the exception
expired · superseded Timed out, or replaced by a newer assertion A superseding chain — both versions stay visible

Every adjustment links back

A proposed adjustment carries a responds_to edge resolving to exactly one exception case, so the posting that settled a finding can always be found from the finding — and the finding from the posting.

FR-154, FR-527 · PH-1

Read the graph scoped and as-believed

The graph projection queries by scope, period, edge types within 4 hops and state, and every result is stamped by its knowledge watermark — the same as-of discipline as every other read. Interactive hot-graph projections stay on the roadmap.

FR-525–527 · PH-1 · hot projections FR-524 Roadmap

Write-back is a loop you review: finding → proposal → approval → posting

Reconciliation proposes; people approve. An exception becomes a proposed provisional entry — bound to the reason code and to the finding that produced it — and that proposal posts through the same lifecycle and materiality gates as any other entry.

  • Finding exception + conservation residual

    An unresolved edge set with a reason code, an owner and an aging band. What does not tie — the residual — is part of the finding, not a footnote.

  • Proposal provisional entry · content-hash bound

    A provisional entry from a reason-code template — unbooked fees, FX drift, chargeback provisions, missing channel sales, suspense clearing — carrying derived_from → the finding and the run. A proposal that would not balance is rejected, never guessed.

  • Approval T0/T1 gates, evaluated server-side

    Materiality tiers decide whether a human approves; the decision is bound to the proposal's content hash, so any edit voids it. Agents can propose; they cannot approve, finalize or correct.

  • Posting responds_to → exactly one exception

    The posted adjustment resolves the finding through a typed edge. Finding, proposal, approval and posting are one queryable record — the whole chain, not four systems' logs.

REST · write-back proposal PH-1: proposal only
# Turn a finding into a reviewable proposal — never a postingPOST /v1/reconcile/findings/{id}/adjustments
{
  "reason_code":  "FEE_DIFF",
  "template":     "unbooked_psp_fee",
  "derived_from": ["finding_f_9a1", "run_r_204"]
}

← 202 { "proposal_ids": ["prov_7f3c"],
        "evidence_hash": "sha256:41b0…",
        # posts only after the T0/T1 gate and a hash-bound approval
        "state": "proposed" }

Read the reconciliation quickstart

Match rules and reason codes are registry data — configuration, not code

Matching runs as an explicit, versioned cascade: a deterministic pass, a tolerance pass, and a scored pass that arrives with PH-2. Rules are business-editable through the API — versioned, prioritized, never hidden in adapter code — and every run pins the registry version it used, so a re-run pinned to the same version reproduces identical decisions.

Cascade · trace: FR-151 · every decision records the rule, its version, the score and the reason code
PassWhat it matchesTypical knobsPhase
a · deterministic Exact amount, reference and counterparty keys Key composition per rail PH-1
b · tolerance Amounts and dates inside declared windows ±abs / ±% per currency, date window per rail, FX tolerance PH-1
c · scored Fuzzy descriptors, set and group rules Score thresholds and priorities Roadmap

The controlled reason-code vocabulary

Every break carries one of these codes, and each code binds the adjustment templates that can answer it — so a finding cannot be closed with an unrelated posting.

  • AMOUNT_MISMATCH — the amounts differ beyond the applied tolerance.
  • TIMESTAMP_DRIFT — the value date falls outside the rail's date window.
  • MISSING_REFERENCE — no reference or counterparty key to bind on.
  • DUPLICATE_SUSPECT — the same economic event may have arrived twice.
  • FX_DIFF — the conversion leaves a difference beyond the FX tolerance.
  • FEE_DIFF — a withheld fee differs from the expected schedule.
  • UNMAPPED — no active mapping profile covers the row; it lands in suspense.
  • MISSING_SIDE — a declared side never arrived; the run completes explicitly.

Reason codes feed materiality evaluation on every proposal · FR-151/154 · PH-1

Roadmap: what is not shipped yet Roadmap

Two pieces are already in PH-1, so this strip reads as the delta only: clearing and in-transit aging with auto-clear and escalation, and the basic sealed evidence bundle a completed run can produce. Everything below arrives with PH-2.

  • Fuzzy descriptor matching and set/group scored passes, with score thresholds as registry data. Roadmap
  • Model-based suggesters — scoring models stay outside the core, above the ledger. Roadmap
  • Full KPI/SLA projections: auto-match rate, exception rate, open value aged 0–30 / 31–60 / 60+, days-to-reconcile and automation rate — replayable from the event log and driving alerts. Roadmap
  • Hot graph projections for interactive traversal; cold per-export materialisation is the default. Roadmap

Traces: FR-151 scored pass, FR-156, FR-524 · PH-2 · PH-1 baseline: FR-155 clearing aging, FR-157 basic bundle

Frequently asked

What is N-sided reconciliation?

N-sided reconciliation ties more than two sources into one verified number: a run accepts two to many sides — billing totals, terminal batches, channel reports, PSP settlements and the bank — matches them pairwise or against a declared control total, and reports each hop's counts and deltas under tolerance. Unresolved matches become exceptions on the evidence graph, never silent adjustments. The hop model →

How do you reconcile sales from billing, terminals and channels against the bank?

The ledger matches the chain, not just the endpoints: channel batch to PSP settlement to payout to bank deposit, each hop scored against versioned match rules with reason codes for every break. Differences route to an exception queue with an owner and aging; each exception links to the evidence path that explains it, and any correction is proposed as a provisional adjustment for review.

Do reconciliation adjustments post themselves?

No. Reconciliation proposes; people approve. Ledgerbook turns each exception into a proposed provisional entry — bound to the reason code and the finding that produced it — and that proposal posts only through the same lifecycle and materiality gates as any other entry. An adjustment that would not balance is rejected, not guessed; nothing posts silently. The review-gated loop →

How do you prove a completed reconciliation to an auditor?

A completed run can produce a sealed evidence bundle: a manifest of file digests, a KPI snapshot and the rule versions that were pinned, signed, with an external chain-checkpoint reference and a seven-year retention floor — byte-reproducible and verifiable offline. Completeness and accuracy, the two assertions auditors test, are what the bundle carries. Basic sealed bundles ship at PH-1; fuller audit evidence packages are Roadmap (PH-2). How verification works →

What Ledgerbook is not

Three boundaries, and the first one is a design decision rather than a limitation.

  • No model-based matching in the core (NG-4). The deterministic rule and tolerance engine is core; probabilistic and scored matching is application-layer. That split is deliberate — a match an auditor has to accept must be reproducible from recorded rules, not from a model version nobody kept.
  • No exception-queue screens (NG-1). Runs, matches, exception cases, reason codes and reviewer actions are ours as objects and events. The queue your team works, and the routing around it, belong to the application on top.
  • No money movement (NG-3). We tell you the bank and the books disagree, and by how much, and raise the adjustment as a proposal. Moving money to resolve it happens in your treasury or payment system, never here.

Put one verified number in the close

Tie billing, terminals, channels and bank into one ledger — and keep the evidence path to defend it. Proposals stay proposals until your policy approves them.