Skip to content
← Free FDE training guides

Free learning / 45-minute adapter proof lab

Read every page before claiming the credit is missing

Build a scoped pagination adapter. Follow the credit onto a second page, reproduce false missing-credit and false-match results, and withhold incomplete evidence.

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

Engineering lab library / Run locally

Collect every page before comparing.

Follow thirteen synthetic reads, reproduce two collection defects and inspect when the financial comparison must not run. Keep both Python files in one folder.

Synthetic records. No provider key or model inference. Runs locally with the standard library.

  1. Start here / Python 3.11+ · Standard library

    Paginated financial extract lab

    Collect thirteen local response scenarios, compare two broken modes and prove when reconciliation must not run.

    Python 3.11+ · standard library · keep both files together

A case handler asks, “Has the expected credit appeared?” Your first API response succeeds and contains no rows. That seems like an answer, until the next page contains the credit. The engineering problem is how you collected the evidence.

This original workshop connects an API adapter to the financial comparison from the reconciliation workbook. Start there if case, ledger entry or provisional credit is unfamiliar. Here you build the missing bridge: a complete, scoped read that can support a comparison.

Allow 45–60 minutes. Use Python 3.11 or newer. All records and provider responses are invented. The lab calls local functions, makes no HTTP or model calls and writes no financial records. The protected Academy lesson adds worked review, knowledge checks and a receiving-owner challenge.

1. Understand the job before writing the loop

An adapter translates a source system's contract into the input your application expects. In the previous lab, the comparison received a complete credit extract. An actual integration must establish that property rather than accept a model-generated complete: true.

Think of a statement spread across several pages. Reading the first sheet does not tell you everything on the statement. The application has to know how to continue, when the read has finished and whether every page belongs to the same question.

TermPlain-language meaningQuestion to ask the source owner
PageOne portion of a collectionWhat marks the end?
CursorA source-supplied continuation valueHow do we reuse it without changing the query?
ScopeThe exact workspace, case, account and original transaction being readWhich references must remain fixed?
SnapshotA defined version of the source collectionCan all pages represent the same version?
Complete extractAll rows returned under the agreed scope and termination rulesWhat evidence establishes coverage?
Page budgetA limit on how many source calls this attempt may makeWhere does unfinished work go?

This workshop's source promises a pinned snapshot. That promise is fictional and explicit. Pagination alone does not provide it, and a completed snapshot is not proof that the facts are still current when someone later acts.

2. Follow the credit onto the next page

The invented contract fixes four references on every request. The first response selects snapshot 7. Later requests send that same snapshot and scope with the supplied cursor. Each response must contain an explicit next_cursor string; "" means the collection ended.

ReadScopeSnapshotEntriesContinuation
Page oneSame case and account7NoneSYNTHETIC-CURSOR-A
Page twoSame case and account7SYNTHETIC-CREDIT-9Empty: end

The guarded collector makes two calls and then invokes the existing comparison. It returns matched_snapshot. The broken first-page collector makes one call and reports missing_credit. The financial source did not change; the collector stopped too soon.

There is a second trap: page one can contain a matching credit while page two contains another distinct entry. Stopping early then produces a false match. Complete collection protects against both unsupported absence and unsupported agreement.

Use the visual below to follow the request, continuation, coverage check and receiving owner. Its example is a teaching trace; running the Python file produces the actual reports.

UNDERSTAND THE SYSTEM

An empty page can still have a next page

Follow an invented credit lookup from the staff question to the complete snapshot. The cursor is a continuation instruction; it does not say whether a credit exists.

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

One case, one scope

The operations team asks whether the expected credit appears. Keep the workspace, account, case and original transaction fixed through the read.

CONNECTED TO
  • Read the scoped collection: Page one
Read the connections in plain English
  1. 01
    One case, one scope → Page one

    The initial request has no cursor; the fictional provider pins a source snapshot.

  2. 02
    Page one → Page two

    Keep the same query scope and snapshot; never invent a page number from the token.

  3. 03
    Page one → Same snapshot?

    No entries, but the next cursor is present.

  4. 04
    Page two → Same snapshot?

    The scope and snapshot agree and the continuation is empty.

  5. 05
    Same snapshot? → Reconciliation

    Only a terminal, coherent read can feed the comparison.

  6. 06
    Same snapshot? → Receiving owner

    A failed page, changed scope or changed snapshot withholds reconciliation.

  7. 07
    Reconciliation → Receiving owner

    Keep the comparison, next action and separate investigation state.

Check your understanding: Page one contains one matching credit. Can you stop early?

No. The next page might contain another distinct credit. The lab's first-page defect hides that second entry and produces a false match. Finish the scoped snapshot or withhold the comparison.

3. Run the paginated extract lab

Download fde-financial-extract.py and its required companion fde-financial-reconciliation.py into the same folder. The collector calls the existing financial comparator only after it establishes the complete extract.

Code example
python3 fde-financial-extract.py
python3 fde-financial-extract.py --json > extract-guarded.json
python3 fde-financial-extract.py --stop-after-first --json > extract-first-page.json
python3 fde-financial-extract.py --allow-mixed-snapshots --json > extract-mixed.json

The last two commands deliberately remove different rules. Run them separately. Exit 0 means the program produced a report; it is not a grade or proof that an integration is ready.

ScenarioGuarded collectionDownstream comparison
credit-on-page-twoTwo pages, one snapshot, end reachedmatched_snapshot
second-credit-on-page-twoBoth distinct entries retainedmultiple_credit_entries
terminal-emptyEnd reached with no entriesmissing_credit
empty-middle-pageContinue through an empty middle pagematched_snapshot
failed-later-pagepage_unavailableNot called
changed-snapshotsnapshot_changedNot called
changed-scopescope_changedNot called
repeated-cursorcursor_cycleNot called
page-budgetpage_budget_exhaustedNot called
malformed-continuationinvalid_pageNot called
expired-cursorcursor_expiredNot called
wrong-account-rowentry_scope_changedNot called
invalid-money-shapeinvalid_entryNot called

For each result, inspect source_pages, collection.trace, collection.requests, collection.extract, reconciliation and handoff. A withheld run can have observed rows in its trace while extract and reconciliation remain null. That distinction is intentional: partial observations are diagnostic evidence, not an authorized financial conclusion.

The trace contains invented data for teaching. Do not copy a whole-response logging pattern into a real financial integration; production evidence needs the organization's access, redaction and retention controls.

4. Repair the right boundary

Compare credit-on-page-two and second-credit-on-page-two across the guarded and first-page reports. Keep source_pages identical. Explain why the same early-stop defect creates opposite errors: one missed credit and one hidden extra credit.

Then compare changed-snapshot across the guarded and mixed-snapshot reports. The second page is terminal, but it describes snapshot 8. The broken mode combines it with snapshot 7 and allows a match. Reaching the end does not repair the inconsistency.

In collect, find the three separate responsibilities:

  1. Check the response, scope, snapshot and row shape.
  2. Continue with the returned cursor while enforcing a request budget and detecting cycles.
  3. Publish an extract only at the explicit end; otherwise withhold it.

Do not repair these failures by changing the financial comparator, dropping rows or asking a model to “be more careful.” The comparator can only reason about the evidence it receives.

5. Change the code and test an unfamiliar case

In your own copy, add a fixture to scenarios() with an empty first page, an empty second page and a credit on page three. Predict three calls and a match, then run it. Lower its max_pages to 2. Predict no complete extract and no downstream comparison, then verify those two fields.

Next, leave a response envelope correct but change the account on its credit row. Explain why the envelope is not enough. The collector must withhold the row instead of joining it to the requested account by amount.

Finally, run a fresh timeout experiment with this companion script in the same folder:

Code example
import runpy

lab = runpy.run_path("fde-financial-extract.py")
calls = []

def fetch_page(scope, cursor, snapshot):
    calls.append((cursor, snapshot))
    if cursor:
        raise TimeoutError("Synthetic final-page timeout")
    return lab["page"]([lab["ENTRY"]], "SYNTHETIC-CURSOR-A")

result = lab["collect"](fetch_page, lab["SCOPE"])
assert result["reason"] == "transport_unavailable"
assert result["extract"] is None
assert result["observed_rows"] == 1
assert len(calls) == 2
print("The observed credit stayed out of a complete extract.")

Keep your prediction beside the actual report and changed code. Add another case without copying one of the named scenarios. A passing result should explain a business consequence, not just satisfy a label.

6. Rehearse the receiving conversation

Use 20 minutes with a peer or facilitator. If working alone, record self-rehearsal and leave independent review outstanding.

TimeReceiver's challengeEvidence to show
4 minutesExplain an empty page without codeScope, continuation and the unresolved customer question
6 minutesMove the credit to another pageYour prediction, changed fixture and actual calls
5 minutesMake the last page unavailableNo complete extract, no comparison, integration owner
5 minutesRemove the snapshot guaranteeThe exact contract gap and the next owner decision

Write two distinct handoffs. “The read stopped at page two with 503; integration operations must resolve coverage” is different from “The complete scoped snapshot contains no expected credit; ledger operations must investigate.” Neither statement closes the investigation or authorizes a credit.

For a real adapter, establish source permissions, consistency and freshness, bounded request duration and response size, cursor expiry, retry limits, cancellation and privacy-aware evidence retention. The local page-count proof does not test those external properties. If a source cannot pin a snapshot, agree its actual supported read strategy before calling the result a coherent snapshot.

7. Keep your proof and continue

Keep the changed collector, the unchanged comparator, three original reports, your unfamiliar fixture, the timeout proof and both owner handoffs. A receiver should reproduce the result without relying on your narration.

Continue to the receiving-review workbook with a precise claim: this synthetic collector distinguishes an unfinished read from a complete financial comparison. Real source integration remains a separate engineering task.

Primary reference checked 23 October 2026: Google AIP-158 pagination guidance describes opaque continuation tokens, empty pages and keeping query parameters consistent. It does not define this workshop's financial or snapshot contract. All scenarios, code and instruction here are original LockedIn Labs material.

Before you move on

Keep the evidence of your work.

  • A source contract separating page success, snapshot consistency and collection completeness.
  • Three reproducible reports and unfamiliar fixture results.
  • A receiving handoff that names the right owner for unfinished collection work.

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

Bring the source contract, actual page trace and financial result into a receiving-owner review. 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 ↑