Home › Use Cases › Check each aid disbursement against the enrolment record it was paid on
Use caseUC0357
🧪 Use-case kit · runnable

Check each aid disbursement against the enrolment record it was paid on

A small, forkable project that does one job end to end. Run once for real, and every figure on these pages captured from that run.

The business caseThe problem this solves

An aid award is made against an ASSUMED enrolment load months before a term begins. What the student was actually registered in on the census date is a different fact, and it lives in a register keyed by hand, corrected late, and printed with a status column that is not the whole truth: a row can read ENROLLED and be a registration dropped at the window three weeks earlier, and a row can read DROPPED and be one the student held all term because the drop was rescinded. On 29 of the 64 files in this corpus the registrar's own census total is wrong, and on 44 the bursar's own reconciliation panel reports the wrong answer. The only record of any of it is a sentence printed under the row. Opening one disbursement file, reading every note printed under every register row, totalling the aid-eligible hours by hand, banding them against the program's full-time load, looking up the fund's proration, checking the progress determination against the disbursement date, and netting the other aid against the cost-of-attendance budget.

Audience

A financial aid office reconciling a term's disbursements, and the internal auditor who has to say afterwards which of them the enrolment record supported. Every number on these pages came from one real run of this code, not from a vendor page.

The inputThe actual disbursement file

The corpus is 64 disbursement file, 0.19 MB (txt 64). It is generated because it has to be. A real disbursement file is a student's education record and their financial circumstances in one document, and the exact shapes measured here — a suspended student whose appeal was refused, a disbursement paid on hours the student did not hold — are the rows a college would least want published, about the people least able to object. There is no personal data in this corpus at all: no name, no date of birth, no contact detail, no national identifier and no account number. evals/check_labels.py sweeps all 64 files for seven families of identifier on every run and reports 0.

The corpus

  • The 64 disbursement filegenerated from a fixed seed, so no real record, person or institution appears in it.
  • Where each came fromdata/SOURCES.md states where every byte came from AND what the generator costs the measurement, including the three structural leaks it was rebuilt to close and the two shortcut measurements that prove they are closed.

Swap this folder for your own material and the kit is pointed at your disbursement file. That is the whole change — there is no database to migrate.

One disbursement file, as the model receives itADR-0001.txt · 1 of 64
==============================================================================
AID DISBURSEMENT RECONCILIATION FILE                       ADR-0001
Institution: INS-2100 - Marchbank State College (invented)
Student: STU-40013   Term: 2026-SP   Period: 2026-01-12 to 2026-05-08   Procedure: DER-2026
==============================================================================

AWARD AND PERIOD AS THE AID OFFICE HOLDS IT
  award id                          AWD-3000
  fund                                  PELL   Federal Pell Grant
  scheduled award                    2178.00   for this payment period
  assumed load                     full-time
  full-time load                      12.000   credit hours
  program                     BS Applied Mathematics
  program aid-eligible                   yes
  term aid-eligible                      yes
  census date                     2026-01-26
  disbursement date               2026-01-26
  tolerance amount                      5.00   or less
  tolerance pct                         0.50   pct of eligible or less
  period                           full-term

ENROLMENT REGISTER AS THE REGISTRAR PRINTS IT
  ROW        COURSE        HOURS  BASIS  STATUS      LAST ACTION  MEMO
  ENR-0101   BIO-2320      3.000  GR     DROPPED     2026-01-31   section 05
      NOTE: dropped on 2026-01-19 inside the add period and the registration was off the census extract
  ENR-0102   CIS-2415      4.000  GR     ENROLLED    2025-11-13   section 07
  ENR-0103   LIB-1000      1.000  GR     DROPPED     2025-11-13   section 03
      NOTE: this section was dropped on 2026-01-19 in a swap for another section already listed above
  ENR-0104   NUR-2101      4.000  GR     ENROLLED    2026-01-06   section 05

Abridged — the file continues.

The outcomeWhat a good result looks like

One disbursement in, one row out: which registrations this procedure treats differently from the register that printed them, each with the row quoted verbatim; the progress status in force at the disbursement date; and then, in pure code, the aid-eligible census load, the intensity band, the fund's prorated amount, the cost-of-attendance cap, the eligible amount, the amount the enrolment record does not support, and one verdict from a closed set of five.

And when it cannot

And what it does when it cannot. On the scored run 64 of 64 replies parsed and nothing stopped at the token ceiling, so there is no unparsed row to report. What there IS is over-citation: on 18 of 64 disbursements the arm cited a registration the student really did drop — a row the register got right — and the station then added those hours back, inflating the census load. Every family this kit loses to its own free floor is that error.

Where it fitsWhat did work

Every line below is a measured result from this kit's own runs, with the figure that supports it. The headline above is not softened by any of them.

  • Your late drops all say "dropped" and your no-shows all say "no-show" — the free rules floor, and do not buy a call at all
    The floor beats the paid arm 4 of 5 to 1 on late drops and 4 of 5 to 2 on no-shows here, and across the 29 files where the register itself is wrong the two arms TIE at 12 each. A keyword list over the notes reaches everything a keyword can reach, for $0.00.
  • Your findings live in a verb — an appeal that was heard rather than granted, a note about a drop of a different course — the paid arm
    10 of 12 against 0 of 12 on refused appeals and 14 of 23 against 0 of 23 on the keep-note decoys. A regex reads the status and the date, which every refused appeal states as fully as a granted one.
  • Your finding is a column — an audit basis, a status flag, a date comparison — pure code, and put it in the station rather than in the prompt
    The audit basis is decidable from the BASIS column and free code gets it more often than the call does, 2 of 5 against 1. Everything DER-2026 decides in code — the intensity band, the proration, the cost-of-attendance cap, the payment-period date test — is free on every arm and is published as such.
  • You need to know how much of a term's disbursements are unsupported, in total — something else
    The grain here is ONE disbursement. It answers one question about one payment and stops; there is no ranking, no aggregation and no queue.

And where nothing here is good enough:

  • You want a number you can take to an auditor — neither arm, yet
    DER-2026 is invented. Its intensity bands, proration tables, tolerances and rule order are this kit's own and are not anybody's actual obligations, and nothing produced under it is a compliance finding.

At a glanceHow the whole thing runs

41%all five correct pct
1,968 msp50, end to end
$0.00per 1,000 disbursement file · google/gemini-3-flash

Run once, for real, on 2026-09-09. Every figure on these pages was captured from that run — nothing is written from intent.

14 steps, grouped by the question that sends you to them rather than by build order. Each tile carries the one figure that step is about, and opens the page behind it.

Should you use this?What you bring, where it stops, and when not to use it

Before you commit an afternoon to this, these are the answers that decide it. Each one is rendered from the record it lives in — and links the page that holds it in full.

What do I have to bring?Replace data/corpus/*.txt with your own disbursement files in the same shape and data/students.json with your own award rows, then re-derive the key. ⚠︎ WHAT STOPS BEING TRUE THE MOMENT YOU DO. Corpus lens →
When is this the wrong choice?Avoid: Paying per disbursement for a regex you could write in an afternoon. That is the case against the best-fitting scenario (“Your late drops all say "dropped" and your no-shows all say "no-show"”). 5 scenarios scored in all, each with its own. Eval lens →
Where does it stop working?A register that is not fixed-width columns. src/register.py's row regex is the shape these files print; a CSV or an SIS API export needs a different parser and nothing above it changes. 6 recorded failure modes, each from a run rather than a guess. Corpus lens →
What was never verified?NO SECOND SCORED RUN. One was fired, so the run-to-run spread on this corpus is unknown and unclaimed. 8 items this kit says it could not check. Eval lens →
Can I run this on a model I control?Yes — any OpenAI-compatible endpoint, including one on your own hardware. The shipped adapter takes its host from BASE_URL and its model from MODEL, so nothing in src/ changes. The published figures come from 1 model on the fast tier, one provider, one key. Prompt lens →
And if it fits — what do I stand up?6 artifacts with a stated home and a stated egress, and 3 decisions each with what you provision past its ceiling — plus what was not measured. That is the next page, not this one. step 14 — Run it in your environment →

Not asked of this kit — 2 questions: clone (a fresh clone of this kit runs with nothing fetched); judge (nothing here is graded by a model).

Last verified 2026-09-09 — r001-disburse-recon. Every figure on these pages was captured from that run.

Run itHow this reaches your data

Every result on this page was produced by pure code over checked-in files, with no API key — which is why you can read the numbers before anyone spends anything.

Run this on your own data

  • The pipeline, its eval harness and the runs behind every numberdeployed inside your environment, on your own model endpoints, against your own documents.
  • The corpus above is the shape, not the limitit is a folder swap, and there is no database to migrate.

Talk to us →

Checked before this shipped — A clean checkout with no key configured renders the whole board, all three free floors and every committed run, and both data checks (--check and evals.check_labels) run on a machine with nothing installed.

A living map of modern AI — kept current every morning