ENGINE 19
SFS-E19-EXP · EXPENSE CONTROLS · REV 2026-07-24 · PRODUCTION
PRODUCTION = runnable end-to-end, CI-backed, full test suite passing. All data fictional and seeded.
Expense & P-Card
Every charge, a receipt
A company does not reimburse a card statement on trust. It issues a purchasing card, the bank issues a statement, and the cardholder owes a matching expense report: one line per charge, each with a receipt on file, a business purpose, a valid general-ledger code and a real project, filed inside the submission window, under the per-charge limit, and approved by somebody other than the person who incurred it. This engine reads the six artifacts a statement cycle emits -- the cardholder register, the programme policy, the project register, the bank statements, the expense reports and the general-ledger positions -- and runs twenty-three deterministic controls over them. Does every charge on the statement reconcile to exactly one report line to the cent, does that line carry a receipt and a stated purpose, is it coded to a GL account the policy allows and a project that exists, is the charge under the limit and inside the window, and did a second person approve it. It re-derives the reconciliation from the statement rather than trusting the report's footed total, compares every amount as integer cents with exact equality, and never writes to a source artifact.
The failures here do not look wrong in a page of small numbers, which is exactly why a footed, receipted report carries them straight through. A charge with no report line does not fail a total -- the report total is simply lower than the bank's -- so it survives to whoever reconciles the statement line by line, if anyone does; it is a company expense nobody coded and nobody has a receipt for. A report can foot to a tidy round number and still be a penny off the statement it is meant to mirror, because summing to a clean total is not the same as tying to the bank. And the charge that should never have been on the card -- one cent over the limit, a bar tab in a disallowed category, a project code that does not exist, a report the cardholder signed off themselves -- walks past every check that only looks at whether the numbers add up. Footing is necessary and not sufficient. The engine re-derives the reconciliation where the penny actually lands, 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
Eight control families run in registry order over each cycle file. The first proves the others had something to read and that the review date is legible, because a control that passes on absent evidence reports assurance it never performed.
Key specifications
at a glanceWhat it does for you
plain termsA company issues a purchasing card, the bank issues a statement, and the cardholder owes a matching expense report -- one line per charge, each with a receipt on file, a business purpose, a valid general-ledger code and a real project, filed inside the submission window, under the per-charge limit, and approved by somebody other than the person who incurred it. Several failures hide inside that, and none of them look wrong in a page of small numbers. A statement line with no report line is a company expense nobody coded and nobody has a receipt for; it does not fail a total -- the report total is simply lower than the bank's -- so it surfaces only when the report is reconciled line by line against the statement. A report can foot to a tidy round number and still be a penny off the statement it is meant to mirror, because summing to a clean total is not the same as tying to the bank. And a charge that should never have been on the card -- one cent over the limit, in a disallowed merchant category, coded to a project that does not exist, or approved by the cardholder themselves -- is a control break a footed, receipted report will still carry straight through. None of these are judgment calls. They are equalities -- a charge against its report line, a report against the statement, an approver against the cardholder -- which a deterministic control settles better than a page of small numbers that already adds up.
The seeded demo runs every control over every cycle file7. The CLI generates 24 fictional cycle files -- one clean baseline and one carrying each of the 23 planted defects -- then runs all 23 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.
A cent on the wrong line still fails, a footed total does not save it8. A test moves one cent onto a report line so it no longer matches its statement charge. rec_every_charge_reported fires at exactly one cent either side of the amount, proving the reconciliation ties to the cent and that summing to a round number is necessary but not sufficient.
The per-charge limit is a hard edge, measured to the cent9. A test sets a charge one cent under, exactly at, and one cent over the per-charge limit. pol_per_charge_limit stays silent at and under the limit and FAILs one cent over -- a control break whether or not the expense itself was legitimate, and a boundary a footed report walks straight past.
Functional block diagram
engineering · each block links to its sourcePlain terms
- Seeded Cycle Files. fictional expense-and-card cycle files enter the control registry
- Structural Precondition. is the cycle file complete and the review date legible
- Cardholder Register. is every cardholder fully described and uniquely identified
- Statement. are the statement lines complete, unique and integer cents
- Report Lines. does every report line carry a receipt, a purpose and its fields
- Reconciliation. does every charge reconcile to one report line, to the cent
- Coding. is every line coded to a valid GL and a real project
- Policy. filed in time, under the limit, approved by someone else
- Duplicate Detection. is any charge a duplicate of another on the same card
- Cardholder, Policy & Project Registers. the registers and policy every rule resolves against
- Verdict and Findings. every finding, with the reason it exists, ends at a person
Engineering
- Seeded Cycle Files. generate_corpus writes one clean baseline plus 23 planted-defect files, one for every registered control, 24 files in total. Only the cardholders, the policy, the projects and the charges are stated; each report line's amount and the general-ledger P-Card total are re-derived from those base facts, so the relationships the engine tests are the same relationships that produced the data.
- Structural Precondition. One control. FAILs a cycle file missing any of the six artifact types or carrying a duplicate, and FAILs an unreadable as_of, so no downstream rule holds vacuously on absent evidence.
- Cardholder Register. Four controls: required fields, a unique cardholder id, a card last four of exactly four digits, and a home entity the programme recognises.
- Statement. Four controls: required fields on every line, unique line ids, integer-cent amounts reported and never coerced, and each charge tagged with its own cardholder's card last four.
- Report Lines. Three controls: header and line fields present, a receipt on file for every line, and a non-blank business purpose that a blank value fails.
- Reconciliation. Four controls: every charge matched to exactly one report line and tied to the cent, no orphan report line, each cardholder's report total tying the statement, and the ledger P-Card total tying the sum of report lines.
- Coding. Three controls: a valid GL code from the policy set, a project in the register, and a FLAG on any charge in a policy-disallowed merchant category.
- Policy. Three controls: filed within the submission window (FLAG if late), every charge under the per-charge limit, and an approver who is not the cardholder.
- Duplicate Detection. One control: every charge keyed on date, merchant, amount and card last four; a collision is a merchant double-post to dispute or a claim submitted twice.
- Cardholder, Policy & Project Registers. The cardholder register carries each cardholder's id, name, card last four and home entity. The policy carries the submission window, the per-charge limit, the disallowed categories and the valid GL set. The project register carries every codeable project and its budget. Cardholder, statement, reconciliation, coding and policy controls are all evaluated against these authorities.
- Verdict and Findings. Findings roll up per cycle 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 or absolute paths, which is what makes the committed report diffable.
Instruction set
every public command| Command | Operation | Output | Exit | Artifacts |
|---|---|---|---|---|
python run.py | regenerate the seeded fictional corpus, run all twenty-three 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 | expense_report.json, expense_report.md, samples/ |
python -m expense_engine samples | analyze an existing folder of cycle 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 expense_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 | run the full test suite for this engine | 10346 passed | 0 when every test passes | none |
Benchmarks
measured demo results| Measure | Result |
|---|---|
| Engine tests10 | 10,346 tests collected live collection from the engine directory |
| Registered controls11 | 23 controls counted from the registry, not from documentation |
| Planted defects12 | 23 defect files every registered control has a 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 charge is reimbursed and posted.
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 cycle into the documented reimbursement and posting review |
| One or more FLAG, no FAIL | REVIEW | a human resolves each flag; a charge in a disallowed category and a report filed after the submission window both land here |
| One or more FAIL | FAIL | the cycle does not go to reimbursement or posting until the failing control is cleared |
- Read-only: cycle files are parsed and never written back, so the engine cannot introduce the break it reports.
- Integer cents throughout, compared with exact equality; there is no tolerance band on the reconciliation or the per-charge limit.
- A value 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 number the engine is meant to audit.
- 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 reimburses a charge, posts an entry, or writes to a source artifact. It reports and stops.14
- It reads the six artifacts a statement cycle emits. It does not connect to a bank feed, a card-issuer portal, a receipt store or the general ledger.15
- It proves a report line carries a receipt and a stated purpose, not whether the receipt is authentic or the purpose is genuine. Whether a charge was a reasonable use of company money is a reviewer's judgment.16
- It flags a charge in a policy-disallowed category for a human rather than deciding it; a cash advance or a bar tab is never routine but not necessarily fraud, so the control raises it as a review signal and stops.17
- All shipped data is fictional and the statement cycle is set in a fictional future. The corpus demonstrates the controls; it is not a record of any real company, cardholder, merchant, card number or charge.18
See it run
control architecture
Integration
how to run itDistribution: public repository, MIT license.
- 1python -m pytest --collect-only -q -o addopts= (expense-report-automation/)
- 2len(expense_engine.engine.REGISTRY)
- 3distinct rule-id prefixes in expense_engine.engine.REGISTRY
- 4samples/*.json after python run.py
- 5len(expense_engine.model.DOC_TYPES)
- 6expense_engine/tests/test_control_semantics.py::test_each_charge_reconciles_to_the_cent
- 7python run.py (expense-report-automation/); expense_engine/tests/test_planted_defects.py::test_defect_fires_its_intended_rule
- 8expense_engine/tests/test_control_semantics.py::test_each_charge_reconciles_to_the_cent
- 9expense_engine/tests/test_control_semantics.py::test_per_charge_limit_is_a_hard_edge
- 10python -m pytest --collect-only -q -o addopts= (expense-report-automation/)
- 11len(expense_engine.engine.REGISTRY)
- 12len(expense_engine.generate.DEFECTS)
- 13expense_engine/tests/test_planted_defects.py::test_every_registered_rule_has_a_planted_defect
- 14expense-report-automation/README.md and expense_engine/tests/test_readonly_and_determinism.py::test_analysis_does_not_touch_the_source
- 15expense_engine/model.py DOC_TYPES
- 16expense_engine/engine.py check_rpt_purpose_present
- 17expense_engine/engine.py check_cod_disallowed_category
- 18expense_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