ENGINE 44
SFS-E44-OCA · DISBURSEMENT CONTROLS · REV 2026-07-24 · PRODUCTION
PRODUCTION = runnable end-to-end, CI-backed, full test suite passing. All data fictional and seeded.
Outstanding Check Aging & Escheatment
Of everything issued, what has never cleared, and how old is it now?
A check register is a list of promises the bank has not yet been asked to keep. This engine starts after the check has left the building -- whether the payment was approved, coded and released is somebody else's control -- and asks the narrower question: of everything issued, what has never cleared, how old is it against the file's own as-of date, and what has to happen to it now. It reads the six artifacts an outstanding-check process emits -- the bank account register, the check register, the void register, the stated outstanding schedule, the stated escheatment schedule and the bank reconciliation -- and runs twenty deterministic controls over them in registry order. Is the aging file complete and the as-of date readable, are the bank account ids unique and does each declare the escheat jurisdiction it reports to, is every check row complete, uniquely numbered within its own account, drawn on a real account, typed, dated on or before the as-of date, paired on its clearing and cleared for exactly the amount it was issued for, are the withdrawn checks classified, off the outstanding schedule and netted to zero, does the outstanding set re-derive from the register key by key and amount by amount, do each item's age and aging band re-derive from its check date, is every stale-dated item marked for follow-up, is the escheatment schedule exactly the items past the dormancy period and each addressed to its own account's jurisdiction, and does the bank reconciliation's outstanding-checks line tie the re-derived evidence rather than the stated schedule. Every amount is integer cents compared with exact ==, every age is measured to the as_of date the file carries rather than the system clock, and no source artifact is ever written back.
Nothing in an outstanding-check register looks wrong, and three things go wrong in it anyway. The outstanding schedule is a filtered view of the register -- nothing cleared, no cleared date, not withdrawn -- and the moment somebody maintains it beside the register instead of deriving it from the register, it drifts: a check that cleared last month stays on it, a check issued this month never reaches it, and the bank reconciliation ties to the drift rather than to the evidence. A withdrawn check keeps living: a voided, zero-dollar or stop-payment item still occupies a row, and if the void never nets the amount to zero, or the item is still counted as outstanding, a cancelled promise sits on the reconciliation and ages -- far enough, eventually, to be handed to a state that was never owed it. And the clock runs where nobody hears it: past the stale-dating threshold the bank may refuse the item and a human has to chase, re-issue or re-void it; past the dormancy period it stops being the entity's money at all and becomes unclaimed property owed to the escheat jurisdiction of the account it was drawn on. The register looks identical the day before and the day after. This engine rebuilds the outstanding set, its ages, its bands, its follow-up markers and the escheatment schedule from the register through one shared aging kernel, ties the reconciliation to that re-derivation rather than to the stated schedule, ships a planted-defect file for every registered control, and states its benchmark as a command rather than a claim.
Architecture
functional block stack · static overviewSelect a layer
Seven control families run in registry order over each aging file. The first proves the others had something to read and that the as-of date is legible, because every age, stale-dating and dormancy test is measured to it and a control that passes on absent evidence reports assurance it never performed.
Key specifications
at a glanceWhat it does for you
plain termsA check register is a list of promises the bank has not yet been asked to keep. Each row carries a check number, a check date, a check type, a payee, the amount issued, the amount cleared and the date it cleared; beside it sit the withdrawn promises -- voided, zero-dollar and stop-payment checks. Whether the payment should have been made at all is somebody else's control. This one starts once the check has left the building. Three failures hide in that register and none of them look wrong in it. The outstanding schedule is a filtered view -- nothing cleared, no cleared date, not withdrawn -- and the moment it is maintained beside the register rather than derived from it, it drifts, and the bank reconciliation's outstanding-checks line ties to the drift instead of to the evidence. A withdrawn check keeps living: still counted as outstanding, or with a void that never nets the amount to zero, so a cancelled obligation sits on the reconciliation and ages. And the clock runs. Past the stale-dating threshold the bank may refuse the item and a person has to chase the payee, re-issue or re-void it; past the dormancy period it is no longer the entity's money at all but unclaimed property owed to the escheat jurisdiction of the account it was drawn on -- and the register looks exactly the same the day before and the day after. None of these are judgment calls. They are set comparisons and date arithmetic -- an outstanding set rebuilt from the register and compared key by key, a void reversal that must net to zero with exact ==, an age that is whole days from the check date to the file's own as-of date, and two thresholds crossed strictly -- which a deterministic control settles better than a schedule inherited by whoever maintains it this quarter.
The seeded demo runs every control over every aging file7. The CLI generates twenty-two fictional aging files -- one clean baseline and one carrying each of the twenty-one planted defects -- then runs all twenty controls over each. The clean file returns PASS with no flags; every defect file returns REVIEW or FAIL and names the control it tripped along with the reason that control exists.
The outstanding set is re-derived, not read back8. One defect file simply deletes a row from the stated outstanding schedule -- a check that has not cleared and was never withdrawn. Nothing in the schedule itself is inconsistent. age_outstanding_set_recomputes rebuilds the set from the check register through the shared aging kernel, finds the item missing, and fails; rpt_outstanding_total_ties independently reports the reconciliation against the same re-derivation rather than against the schedule that lost the row.
A withdrawn check put back on the schedule would have aged into an escheatment9. Another defect file returns a stop-payment check to the outstanding schedule with an otherwise correct age and aging band, so every arithmetic control still holds. void_not_outstanding is the only rule that sees it, and it is the rule that matters: a cancelled promise left on the schedule keeps aging, and far enough out it would be remitted to a jurisdiction as unclaimed property that was never owed.
Functional block diagram
engineering · each block links to its sourcePlain terms
- Seeded Aging Files. fictional outstanding-check aging files enter the control registry
- Structural Precondition. is the aging file complete and the as-of date readable
- Bank Account Register. are the accounts uniquely identified and jurisdictioned
- Check Register. is every check row well-formed, attributable and reconciled
- Withdrawn Checks. are the withdrawn checks really withdrawn
- Outstanding Set & Aging. does the outstanding set re-derive from the register
- Escheatment. is the escheatment schedule exactly the dormant items
- Bank Reconciliation Tie-Out. does the reconciliation tie the re-derived evidence
- Registers & Aging Kernel. the artifacts and predicates every rule resolves against
- Verdict and Findings. every finding, with the reason it exists, ends at a person
Engineering
- Seeded Aging Files. generate_corpus writes one clean baseline plus one planted-defect file for every registered control, twenty-two files in total, at a fictional-future as-of date. Only the bank accounts, the check register and the void register are stated as base facts; the outstanding schedule with its ages, aging bands and follow-up markers, the escheatment schedule and the reconciliation's outstanding line and aging subtotals are all re-derived through the same aging kernel the engine later recomputes with, so the relationships the engine tests are the relationships that produced the data.
- Structural Precondition. One control. FAILs a file missing any of the six artifact types or carrying a duplicate, and FAILs an unreadable as_of date, so no downstream rule holds vacuously on absent evidence and no age is measured to nothing.
- Bank Account Register. Two controls: no bank account id appears twice, and every account declares the escheat jurisdiction its unclaimed property reports to.
- Check Register. Seven controls: the required fields present, the number unique within its own account, the account real, the type known, the date on or before the as-of date, the cleared amount and cleared date paired, and a cleared check cleared for exactly the amount it was issued for.
- Withdrawn Checks. Three controls: every entry carries a known disposition and names a real check, no withdrawn check appears on the outstanding schedule, and every reversal nets its check to exactly zero.
- Outstanding Set & Aging. Three controls: the schedule is exactly the set the register re-derives, every age and aging band recomputes from the check date to the as-of date, and every follow-up marker agrees with the file's stale-dating threshold.
- Escheatment. Two controls: the schedule is exactly the outstanding items strictly past the dormancy period, re-derived on key, amount and age, and each names the jurisdiction its own account declares.
- Bank Reconciliation Tie-Out. Two controls: the outstanding-checks line and count tie the set re-derived from the register rather than the stated schedule, and the six aging subtotals tie the re-derived bands.
- Registers & Aging Kernel. The bank account register carries each disbursement account and its escheat jurisdiction; the check register carries the number, account, date, type, payee, amount issued, amount cleared and cleared date of every check; the void register carries the withdrawn promises and their reversals; and the outstanding schedule, escheatment schedule and bank reconciliation carry the derived population, its aging profile and the line that leaves the department. Every re-derivation resolves against these through one shared kernel: outstanding means a cleared amount of exactly zero and no cleared date and no void entry, age is whole days from the check date to the file's as_of, the band is a lookup on that age, and stale-dated and dormant are both strictly past their thresholds.
- Verdict and Findings. Findings roll up per aging file: any FAIL is FAIL, FLAGs without FAILs are REVIEW, clean is PASS. The CLI exit code is the verdict, so a pipeline can gate on it. Reports carry no timestamps and no absolute paths, which is what makes the committed report diffable -- a change in the diff is a change in the controls, not a change in when the report was run.
Instruction set
every public command| Command | Operation | Output | Exit | Artifacts |
|---|---|---|---|---|
python run.py | regenerate the seeded fictional corpus, run all twenty controls, write both reports | per-file verdicts and every actionable finding, then the overall verdict | 2 for the bundled corpus, which carries a planted defect for every control by design | checkage_report.json, checkage_report.md, samples/ |
python -m checkage_engine samples | analyze an existing folder of aging files without regenerating it | per-file verdicts and findings | 0 PASS / 1 REVIEW / 2 FAIL / 3 usage | none unless --json or --md is passed |
python -m checkage_engine samples --generate --quiet | regenerate the corpus and print only the overall verdict | a single verdict line | 0 PASS / 1 REVIEW / 2 FAIL / 3 usage | samples/ |
python -m pytest checkage_engine/tests -q | run the full test suite for this engine | 10361 passed | 0 when every test passes | none |
Benchmarks
measured demo results| Measure | Result |
|---|---|
| Engine tests10 | 10,361 tests collected live collection from the engine directory |
| Registered controls11 | 20 controls counted from the registry, not from documentation |
| Planted defects12 | 21 defect files every registered control has at least one file that trips it |
| Control coverage13 | 100 percent of controls with a planted defect no control ships without a file demonstrating it firing |
Control characteristics
engineeringPlain terms
The engine has no write path and therefore no autonomy to gate. It produces findings; a person decides whether a check is chased, re-issued, re-voided or reported as unclaimed property.
Engineering
Deterministic envelope. seeded fictional inputs, read-only operation, offline default mode.
Demo gate. FAIL on the bundled corpus, by design -- it carries a planted defect for every registered control
| Severity | Verdict | Action |
|---|---|---|
| No findings above PASS | PASS | carry the mechanically clean aging file into the documented outstanding-check review and bank reconciliation sign-off |
| One or more FLAG, no FAIL | REVIEW | a person resolves each flag; a stale-dating follow-up marker that disagrees with the item's age and an aging subtotal that does not tie the re-derived band both land here |
| One or more FAIL | FAIL | the item or figure is not carried into the reconciliation or the unclaimed-property filing until the failing control is cleared -- an outstanding set that does not recompute, a void still on the schedule or short of netting to zero, an escheatment schedule that does not tie, or a misdirected jurisdiction |
- Read-only: aging files are parsed and never written back, and the engine never voids, re-issues, stops a payment, escheats or pays anything.
- Integer cents throughout, compared with exact ==; there is no tolerance band on an outstanding total, a void reversal or a bucket subtotal.
- An amount that should be integer cents but is not produces an AMOUNT_INVALID finding contained to the one row it was read on, rather than being coerced into the figure the engine is meant to audit.
- One aging kernel: the controls and the generator share the predicates in checkage_engine.aging, so a schedule cannot disagree with the data that produced it.
- Every age, stale-dating and dormancy test is measured to the as_of date carried in the file, never to the system clock, so no finding changes because a day passed on the build machine.
- A check's identity is its number within the account it was drawn on, because two disbursement accounts legitimately run overlapping number series.
- Both thresholds are crossed strictly: an item sitting exactly on the stale-dating day or the dormancy day has not passed it.
- The bank reconciliation is tied to the set re-derived from the check register, not to the stated outstanding schedule, so a schedule and a reconciliation that drifted together still break.
- Deterministic and byte-stable: same inputs produce the same findings in the same order, with no timestamps or absolute paths in any output.
- Absent evidence is never a passing control; a missing artifact fails completeness rather than letting the controls that read it pass unread.
Operating limits
what it refuses to do- The engine never voids, re-issues, stops a payment, escheats, pays, files an unclaimed-property report, or writes to a source artifact. It reads, re-derives and reports.14
- It reads the six artifacts the outstanding-check process emits. It does not connect to a bank, a positive-pay file, a disbursement system, a general ledger or a state unclaimed-property portal.15
- It is the back half of the disbursement story: whether the payment was authorised, coded and released is outside its scope, and it does not opine on whether the payee is owed the money.16
- It applies the stale-dating threshold and dormancy period the file itself carries, defaulting to 180 and 1095 days; it does not decide which threshold or which dormancy period the property type and jurisdiction actually require, nor whether the declared escheat jurisdiction is the correct one.17
- It takes the register at face value: it confirms the outstanding set, the aging and the reconciliation re-derive, not that a check was physically issued or that a clearing actually occurred. All shipped data is fictional -- the entities, bank accounts, payees, check numbers, amounts, dates and escheat jurisdictions are invented and the as-of date is set in a fictional future.18
See it run
control architecture
Integration
how to run itDistribution: public repository, MIT license.
- 1python -m pytest --collect-only -q -o addopts= (check-aging-automation/)
- 2len(checkage_engine.engine.REGISTRY)
- 3distinct rule-id prefixes in checkage_engine.engine.REGISTRY
- 4samples/*.json after python run.py
- 5len(checkage_engine.model.DOC_TYPES)
- 6checkage_engine/tests boundary tests on the cent and on the stale-dating and dormancy days
- 7python run.py (check-aging-automation/); checkage_engine/tests planted-defect suite
- 8checkage_engine/generate.py DEFECTS outstanding_row_missing -> age_outstanding_set_recomputes
- 9checkage_engine/generate.py DEFECTS void_listed_outstanding -> void_not_outstanding
- 10python -m pytest --collect-only -q -o addopts= (check-aging-automation/)
- 11len(checkage_engine.engine.REGISTRY)
- 12len(checkage_engine.generate.DEFECTS)
- 13checkage_engine/tests: every registered rule has a planted defect
- 14check-aging-automation/README.md and checkage_engine read-only / determinism tests
- 15checkage_engine/model.py DOC_TYPES
- 16checkage_engine/engine.py module scope and the chk_ family
- 17checkage_engine/model.py DEFAULT_STALE_DATED_DAYS, DEFAULT_DORMANCY_DAYS and the esc_ family
- 18checkage_engine/generate.py
Show us where the hours go.
One conversation: you describe the work that consumes your team's month; we tell you plainly what this engine can take over, what it can't, and what a scoped first phase would cost. Your people keep approval authority.
Book a free consultation