ENGINE 12
SFS-E12-BUP · REVENUE RECOGNITION · REV 2026-07-22 · PRODUCTION
PRODUCTION = runnable end-to-end, CI-backed, full test suite passing. All data fictional and seeded.
Buyer Upgrades
A liability until the unit closes
A buyer pays for a home upgrade months before the home closes. That money is not revenue when it arrives -- it is a liability, and it stays one until the unit actually closes. Between those two dates the same figure has to appear consistently in four places, each maintained by a different person on a different cadence. This engine reads all four and runs twenty deterministic controls over them: does every upgrade belong to a real unit exactly once, is deferred revenue released on close and only on close, does the closing entry balance, is sales tax carried as a liability, and do the four schedules agree. It never posts and never writes to a source artifact.
The failure mode here is almost never a wrong number. It is the same number failing to move everywhere at once -- released in the schedule but not the ledger, repriced in one report and not the next. Those breaks survive review precisely because every individual page still foots. The engine ships one planted defect per registered control, so the benchmark is a command rather than a claim.
Architecture
functional block stack · static overviewSelect a layer
Seven control families run in registry order over each upgrade book. The first proves the others had something to read.
Key specifications
at a glanceWhat it does for you
plain termsAn upgrade programme keeps four schedules of the same money, and the money changes character exactly once: on the day the unit closes it stops being a liability and becomes revenue. Every recurring failure here is that change happening in some schedules and not others. A unit closes and the deferred balance is released in the closings schedule but never posted to the ledger, so the liability account carries a balance for units that no longer exist. An upgrade is repriced and the cost-to-complete is updated while the proforma keeps the old figure, so margin is reported against a price nobody is charging. A change order is executed and the committed cost never lands, so an overrun looks like an overrun rather than an approved increase. None of these makes any individual page fail to foot, which is exactly why they survive review and why a rule finds them and a reviewer does not.
The seeded demo runs every control over every book7. The CLI generates 22 fictional upgrade books -- one clean baseline and one carrying each planted defect -- then runs all 20 controls over each. The clean book returns PASS with no flags; every defect book returns REVIEW or FAIL and names the control it tripped along with the reason that control exists.
Paid, finished and settled is still not revenue8. A test sets buyer-paid, work-complete and invoice-settled on an open unit and asserts the recognition control stays silent, because none of those recognises revenue. A companion test recognises a single cent before close and asserts it fails. There is no immaterial amount of premature recognition.
A flipped sign is caught in both directions9. The cost-to-complete states cost positive and the proforma states it negative, so the tie negates one side. Tests assert that the correct negative line passes and that a positive one fails -- the check that would be inverted by the obvious raw comparison.
Functional block diagram
engineering · each block links to its sourcePlain terms
- Seeded Upgrade Books. fictional upgrade books enter the control registry
- Structural Precondition. is the book complete enough to be worth reading
- Unit Integrity. does every upgrade belong to a real unit, once
- Deferred Revenue. is revenue released on close, and only on close
- Cost of Sales. does the closing entry balance, and follow revenue
- Sales Tax. is tax a liability rather than revenue
- Four-Way Agreement. do the four schedules carry the same number
- Budgeted Versus Actual. is the forecast/fact marker current
- Ledger Balances. the book of record every schedule is tied back to
- Verdict and Findings. every finding, with the reason it exists, ends at a person
Engineering
- Seeded Upgrade Books. generate_corpus writes one clean baseline plus one planted defect per registered control, 22 books in total. Only the units and their orders are stated; every dependent figure is derived, so a planted defect is guaranteed to be the only thing wrong.
- Structural Precondition. Two controls. Fails a book missing any of the five artifact types, so no downstream rule can hold vacuously.
- Unit Integrity. Three controls over orphaned units, duplicate order ids and closed units missing a close date.
- Deferred Revenue. Four controls: the recognition gate, the per-unit split, and both ledger ties.
- Cost of Sales. Four controls over entry balance, timing, committed cost and change order references.
- Sales Tax. Two controls: derivation from the declared rate, and the tie to the liability account.
- Four-Way Agreement. Four controls chaining cost-to-complete, proforma, variance tab and the unit rows beneath them.
- Budgeted Versus Actual. One control, wrong in both directions: stale after close, or premature before it.
- Ledger Balances. Five accounts: unearned revenue, revenue, cost of sales, contra work-in-progress and sales tax payable. A missing balance fails the tie that needed it rather than skipping quietly.
- Verdict and Findings. Findings roll up per book: 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 | generate the seeded fictional corpus, run all twenty controls, write both reports | per-book verdicts and every actionable finding, then the overall verdict | 2 for the bundled corpus, which carries one planted defect per control by design | upgrade_report.md, upgrade_report.json, samples/ |
python -m upgrade_engine samples | analyze an existing folder of upgrade books without regenerating it | per-book verdicts and findings | 0 PASS / 1 REVIEW / 2 FAIL / 3 usage | none unless --json or --md is passed |
python -m upgrade_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 | 10279 passed | 0 when every test passes | none |
Benchmarks
measured demo results| Measure | Result |
|---|---|
| Engine tests10 | 10,279 tests collected live collection from the engine directory |
| Registered controls11 | 20 controls counted from the registry, not from documentation |
| Planted defects12 | 21 defect books every registered control has at least one book that trips it |
| Control coverage13 | 100 percent of controls with a planted defect no control ships without a book 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.
Engineering
Deterministic envelope. seeded fictional inputs, read-only operation, offline default mode.
Demo gate. FAIL on the bundled corpus, by design -- it carries one planted defect per registered control
| Severity | Verdict | Action |
|---|---|---|
| No findings above PASS | PASS | send the mechanically clean book to the documented manual review |
| One or more FLAG, no FAIL | REVIEW | a human resolves each flag; none of them misstates a figure |
| One or more FAIL | FAIL | a schedule disagrees with another or with the ledger; correct it before the close package is relied on |
- Read-only: books are parsed and never written back, so the engine cannot introduce the defect it reports.
- Integer cents throughout, compared with exact equality; there is no tolerance band anywhere in the registry.
- 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.
- Deterministic and byte-stable: same inputs produce the same findings in the same order, with no timestamps or absolute paths in any output.
- A missing ledger balance fails the tie that needed it rather than skipping quietly; all four accounts are covered by parametrized tests.
Operating limits
what it refuses to do- The engine never posts a journal entry, recognises revenue or writes to a source artifact. It reports and stops.14
- It reads the five artifacts an upgrade programme keeps. It does not connect to a sales system, an accounting ledger or an escrow provider.15
- It checks that a commitment change carries a change order reference, not that the change order was properly authorised. That judgment is a reviewer's.16
- Sales tax is derived from the rate the book declares. The engine does not determine which jurisdiction's rate applies or whether an upgrade is taxable.17
- All shipped data is fictional. The corpus demonstrates the controls; it is not a record of any real buyer, unit or project.18
See it run
brand animation
Integration
how to run itDistribution: public repository, MIT license.
- 1python -m pytest --collect-only -q -o addopts= (buyer-upgrade-automation/)
- 2len(upgrade_engine.engine.REGISTRY)
- 3distinct rule-id prefixes in upgrade_engine.engine.REGISTRY
- 4samples/*.json after python run.py
- 5len(upgrade_engine.model.DOC_TYPES)
- 6upgrade_engine/tests/test_control_semantics.py
- 7python run.py (buyer-upgrade-automation/); output re-run on demand
- 8upgrade_engine/tests/test_control_semantics.py::test_paid_and_complete_is_still_not_recognised
- 9upgrade_engine/tests/test_control_semantics.py::test_proforma_cost_sign_is_enforced
- 10python -m pytest --collect-only -q -o addopts= (buyer-upgrade-automation/)
- 11len(upgrade_engine.engine.REGISTRY)
- 12len(upgrade_engine.generate.DEFECTS)
- 13upgrade_engine/tests/test_planted_defects.py::test_every_registered_rule_has_a_planted_defect
- 14buyer-upgrade-automation/README.md and upgrade_engine/tests/test_readonly_and_determinism.py
- 15upgrade_engine/model.py DOC_TYPES
- 16upgrade_engine/engine.py cos_change_order_referenced
- 17upgrade_engine/engine.py tax_derived_from_rate
- 18upgrade_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