Skip to content
← Free FDE training guides

Free learning / 50-minute reconciliation lab

Financial reconciliation: when matching amounts are not enough

Learn case and ledger matching, distinguish a repeated delivery from two credit entries, and run thirteen synthetic comparisons before handing over an exception.

No account needed. Use your own copy for writing and keep the original as a reference.

Engineering lab library / Run locally

Explain the difference. Prove the comparison.

Predict thirteen cases, reproduce a false credit-kind match and distinguish repeated delivery from two distinct ledger entries.

Real read-only Python comparisons of invented case and credit records. No database, model, network or money movement. A match describes this snapshot; it does not close a case.

  1. Start here / Python 3.11+ · Standard library

    Case-to-ledger reconciliation lab

    Compare thirteen actual read-only results, reproduce a false match and investigate duplicate entry identities.

    Python 3.11+ · standard library only · synthetic USD records

A colleague asks, “The money is back. Can I finish this case?” The case expects temporary credit, but a credit record says final. Both say USD 125.00. Before you build an agent, learn to explain that difference.

Reconciliation means comparing related records, explaining differences and getting those differences resolved by the responsible owners. This original workshop gives you a visual explanation, a runnable comparison and a review exercise. Start with Financial-services business 101 if the terms are new.

Allow 50–70 minutes. You need Python 3.11 or newer and a terminal. Every record is invented; there are no accounts, keys, packages, network calls or financial writes. The advanced Academy reconciliation lesson adds architecture decisions, worked examples and knowledge checks under the existing training access controls.

1. Understand the two stories

Think about comparing an order and a shipment. Equal quantities do not establish the same order, and a shipping label does not prove delivery. In this exercise, the case tracks an investigation and an expected credit. The ledger extract describes the credit entries actually observed. You need both, with their meanings intact.

TermWhat it means hereWhat it does not prove
CaseThe investigation and expected actionThat money was posted
Original transactionThe debit being disputedThe identity of a later credit
Ledger entryOne identified accounting recordThe final investigation outcome
Posting stateWhether this credit is pending, posted or reversedThat all case work is complete
Provisional creditTemporary credit during the applicable investigation processA final case decision
Reconciliation exceptionA specific unresolved difference or missing recordPermission to edit either source
Duplicate deliveryAn identical repeat of the same stable entry IDThat two different entries are the same financial effect

The lab's case expects one positive USD credit. Its extract contains only credit records for that case, not a complete general ledger. This is a deliberately small business contract, not a universal bank matching algorithm.

2. Follow one disagreement

Read these two synthetic records before stepping through the diagram:

FieldCase expectationObserved credit
CaseSYNTHETIC-CASE-104SYNTHETIC-CASE-104
AccountSYNTHETIC-ACCOUNT-7SYNTHETIC-ACCOUNT-7
Original transactionSYNTHETIC-DEBIT-81SYNTHETIC-DEBIT-81
Amount and currency12500 minor units, USD12500 minor units, USD
Credit kindprovisionalfinal
Separate stateinvestigation opencredit posted

The amount is USD 125.00, represented by an integer to avoid binary floating-point equality surprises. Other currencies may use different scales. Keep currency explicit; this lab never converts or nets amounts.

The references and money agree. The credit kind does not. A useful handoff names that disagreement and asks the case and ledger owners to resolve it. It does not rewrite final as provisional to make the comparison pass.

UNDERSTAND THE SYSTEM

Check the credit type as well as the amount

Compare one invented dispute case with its credit extract. Step through the records, the disagreement and the handoff. These are teaching fixtures, not a live ledger.

FOLLOW ONE EXAMPLE

See what moves and why.

Authored illustration
01 / EXPLORE THE PARTSTap a part to explain it
Direction of information or workReturn / feedback

WHAT THIS PART DOES

Case expectation

The case expects a provisional credit for a particular disputed debit. The investigation is still open.

CONNECTED TO
  • Expected references: Same transaction?
Read the connections in plain English
  1. 01
    Case expectation → Same transaction?

    Read the identity of the expected business event.

  2. 02
    Credit extract → Same transaction?

    Validate the scoped records; do not join on amount alone.

  3. 03
    Same transaction? → Compare the meaning

    Only the matching scope enters this comparison.

  4. 04
    Credit extract → Compare the meaning

    USD 125.00 posted final is not an expected provisional credit.

  5. 05
    Compare the meaning → Reconciliation owner

    Route the specific mismatch without changing either source.

  6. 06
    Reconciliation owner → Supported handoff

    Document unresolved work and a receiving owner.

Check your understanding: Two USD 125.00 records arrive. Can you remove one as a duplicate?

Only an identical repeat of the same stable entry ID is a duplicate delivery in this exercise. Two different entry IDs may represent two financial effects. Preserve both and investigate; equal amounts are not an identity.

3. Run the reconciliation lab

Download fde-financial-reconciliation.py from the lab panel into a local folder. Predict the four highlighted distinctions: wrong credit kind, repeated delivery, two distinct entries and incomplete extract. Then run:

Code example
python3 fde-financial-reconciliation.py
python3 fde-financial-reconciliation.py --json > reconciliation-guarded.json
python3 fde-financial-reconciliation.py --omit-credit-kind --json > reconciliation-broken.json

The first command prints a compact report. The JSON preserves each case's full input and result. Inspect state, reason, matched_entry_ids, duplicate_deliveries, owner, next_action and trace together. The records are read-only; running the lab changes no case or ledger.

ScenarioGuarded reasonWhat you should explain
matched-provisionalmatched_snapshotMatching temporary credit leaves the investigation open
wrong-transactionreference_mismatchAn equal amount can belong to another transaction
amount-mismatchamount_mismatchA one-cent difference stays visible
currency-mismatchcurrency_mismatchEUR and USD are not interchangeable
pending-creditcredit_not_postedPending is not posted
wrong-credit-kindcredit_kind_mismatchProvisional and final carry different meanings
missing-creditmissing_creditThe complete scoped extract has no expected entry
repeated-deliverymatched_snapshotOne entry ID, identical content, one repeated delivery
conflicting-entryconflicting_entryOne ID carries different payloads; no last-arrival guess
two-credit-entriesmultiple_credit_entriesTwo different IDs need an explanation, not deduplication by amount
partial-extractincomplete_extractMissing coverage means unknown, not absent
reversed-creditunsupported_posting_stateA reversed record cannot support a posted-credit statement
matched-finalmatched_snapshotMatching final evidence still does not certify notices or close a case

In the deliberately broken report, only wrong-credit-kind changes its decision: the code falsely calls the snapshot matched. Compare expected_kind and kind in its inputs. Both processes can exit successfully; only the guarded comparison preserves this business rule. The other twelve scenarios retain their guarded business decisions; the trace records the omitted check wherever it was reached.

4. Change the code and prove the boundary

In a copy of the script, add these scenarios to scenarios(). Predict the result before running:

Code example
("wrong-account", case,
 replace(extract, entries=(replace(entry, account_id="SYNTHETIC-ACCOUNT-OTHER"),))),
("debit-direction", case,
 replace(extract, entries=(replace(entry, direction="debit"),))),
("unknown-posting", case,
 replace(extract, entries=(replace(entry, status="unrecognized"),))),

Expect reference_mismatch, invalid_credit and unsupported_posting_state. Each should leave matched_entry_ids empty. Keep the original input, your prediction, actual trace and next owner. Repeat the run and explain why the same snapshot should produce the same result.

Then challenge the contract: what if a valid credit is split into two entries? The current one-credit rule deliberately requests reconciliation. Do not weaken it to “sum everything.” First agree which entries belong together, how reversals and versions work, and what the business considers a complete match. Write a counterexample that would fool a simple sum before implementing your extension.

5. Design the adapter an FDE would have to ship

The complete flag and record fields are trusted fixtures. In a deployed system, a server-side adapter must establish the permitted workspace and account, source identity, pagination coverage, version and freshness. A model or caller cannot grant itself that authority. HTTP 200 for one page is not proof that you saw every relevant record.

The duplicate rule assumes an immutable snapshot. If the real source revises entries under the same ID, represent and order those revisions explicitly; taking the latest network arrival is not a version strategy. Source changes between reads also need an agreed snapshot or reconciliation policy. This local script does not prove concurrent adapters, production authorization or eventual consistency.

An agent can help explain a verified difference or draft a handoff. Keep record comparison deterministic, preserve source evidence and give unresolved work an accountable owner. Choosing the reconciliation interval, case closure rules and customer communication process belongs with the institution's authorized owners.

6. Rehearse the receiving-owner review

Use a peer, facilitator or recorded self-rehearsal. A worksheet does not book a mentor. Allow 15 minutes:

  1. Explain case, transaction, entry and provisional credit without field names.
  2. Show the wrong-credit-kind inputs and reproduce the deliberately broken match.
  3. Compare repeated-delivery with two-credit-entries. Explain why you keep both distinct IDs.
  4. Have the reviewer change the account or posting state and predict the result.
  5. Hand over one exception and identify the adapter evidence still needed.

Use this sample as a structure, then write your own from an unseen case:

Text example
Case: SYNTHETIC-CASE-104
Source: SYNTHETIC-EXTRACT-4, complete scoped teaching fixture
Expected: posted provisional credit, USD 125.00
Observed: posted final credit, USD 125.00, SYNTHETIC-CREDIT-9
Difference: credit_kind_mismatch
Owner: case and ledger operations
Next action: resolve the credit-kind mapping against authoritative records
Remaining case work: investigation open; communications checked separately

Keep the dictionary, diagram explanation, guarded and broken reports, changed code, unseen results and review notes. A receiving engineer should be able to reproduce the exception without your narration.

7. Sources and next practice

Sources checked 22 October 2026. The comparison rules, records and review exercise are original teaching material.

  • CFPB Regulation E, error-resolution procedures distinguishes provisional credit, investigation and final resolution for its scope. This lab does not implement legal deadlines or determine applicability to another financial product.
  • Python decimal documentation explains exact decimal arithmetic and why binary floating-point equality matters in accounting. Our bounded USD exercise uses integer minor units.

Continue with the receiving-owner review workbook, or open the protected financial reconciliation lesson for architecture challenges and knowledge checks.

Before you move on

Keep the evidence of your work.

  • A case-to-ledger dictionary and a visual explanation of the difference.
  • Guarded and broken reports plus three unseen input cases.
  • An exception packet with source evidence, next owner and an adapter test contract.

Keep these in your own working copy. Reading this page does not save work or record completion.

Suggested next free session

Review a portfolio with a receiver

Turn the reconciliation exception and its proof into a review another engineer can reproduce. This is a suggested sequence; choose the practice that addresses your current gap.

Open the next free guide
Have Academy access?

Continue with worked explanations, practice and review in the related lesson.

Open the related Academy lesson →
Back to top ↑