The Close checksums
A Close checksum is a reconciliation. It runs after the fact and it reports. AP control against the AP sub-ledger, cross-foot, per-rail reconciliation against external bank evidence. It is a property of the whole book across seven sub-ledgers.Most of them no longer wait for the close.
78 of the 104 hold at every instant, and the Auditor runs those every night.
The name is historical: it is the v12 workbook’s Close list, not a statement that these can only be asked at month-end.
Two kinds of row
Exactly as in the workbook:
The distinction is not cosmetic.
A deposit held on behalf of a customer is supposed to be a non-zero liability; reporting it as a break would train people to ignore breaks.
summary.ok is true when every must-be-zero checksum passes, and the explainable balances are printed alongside.
The size of the surface
close_checks.py declares 104 checksum templates: 82 must-be-zero and 22 explainable balances.
One hundred and one cover the seven authoritative Books families; three Wave E KETCHUYEN-* controls cover the cross-book close procedure.
That number is no longer an estimate.
Every one of the 104 carries a machine-readable phase and layer tag, generated from the code and diffable:
The two tags
Phase answers when is the expected value reachable? A check is continuous when its expected value holds at every instant, which in practice is one of four shapes: a tie between two representations of one fact written in the same transaction, a referential-integrity or catalog check, an arithmetic identity inside a row, or a bound. A check is close-gated when its expected value is only reached after a period-end procedure: a drain-to-zero pool whose non-zero state is a normal in-flight condition, a tie against evidence that arrives with a lag, or a completeness assertion about a period. The 78 continuous ones are what the Auditor’s nightly continuous sweep runs, so most of this surface no longer waits for month-end to be asked. Layer answers whose work is a failure? The test is the one on the two-layers page: if the fix is “find the missing or mismatched document, or correct what it says” it is the bookkeeping layer; if the fix is “decide what this belongs to, or what the period needs” it is the accounting layer. That tag is what routes an exception to one of the two lanes in Audit → Actions.The layer rule moves eight checks and changes neither total, which is the useful evidence that it is the right axis.Four leave the bookkeeping layer (
PO-ADVANCE-POOL, SO-ADVANCE-POOL, PAYMENT-CROSSFOOT, RECEIPT-CROSSFOOT, all allocation) and four arrive (NEG-STOCK-QTY, CONTRACT-ASOF, FLOAT-FACILITY-TIE, ADJ-STOCK-LEG, all matching or movement).A naive by-sub-ledger reading would have put every one of those eight on the wrong worklist.What actually executes
The number of checks that runs on a given book is data-dependent, and expands or contracts around those 104 definitions:
Nine of the 104 expand at run time and 16 are conditional.
Two related numbers, and the difference matters.
The v12 workbook carries roughly 91 Close-list rows.
close_checks.py declares 104 checksum templates.
A live run executes however many those 104 expand to against that book’s data.These are related but not identical quantities: some workbook rows became structural rather than checks (see below), and GreatBook added checksums the workbook never had, such as the output-VAT per-line twin and the split of NEG-STOCK.
The generated inventory is what makes the middle number countable, and it is the one to cite when you mean “the checks that exist”.The Books families and Wave E close group
Settlement · AP/AR spine · rails · 15
Settlement · AP/AR spine · rails · 15
4 continuous must-be-zero, 6 close-gated, 5 report-only.
11 on the bookkeeping layer, 4 on the accounting layer.
AP-CONTROL compares GL 2000 outstanding against the sum of bill dues.
It catches a posting to the control account that bypassed the AP sub-ledger, which is exactly the defect the single obligation writer closes.The four allocation checks sit on the accounting layer under the layered rule: the advance pool is allocations minus applications, and cross-foot is the sum of a settlement’s allocations against the settlement itself.
Both are attribution failures, not matching failures.The two bank-rail ties are close-gated only because the bank statement arrives with a lag.
If an organisation loads statements daily they are continuous, and they then become the single most valuable nightly check in the whole list.Inventory and costing · 26
Inventory and costing · 26
17 continuous must-be-zero, 7 close-gated, 2 report-only.
7 on the bookkeeping layer, 19 on the accounting layer.
NEG-STOCK used to be one check counting items where quantity or value was negative.
It is now split, because negative quantity is a movement error the bookkeeping layer fixes and negative value is a valuation error the accounting layer fixes.
That split is the only change the layer tagging made to the Close oracle, and it is worth it: the alternative routes every valuation error to the wrong worklist.GRNI stays on the bookkeeping layer even though it lives in the costing runner.
The missing thing is a supplier bill, so the fix is “find the document”.Payroll · 22
Payroll · 22
10 continuous must-be-zero, 9 close-gated, 3 report-only.
3 on the bookkeeping layer, 19 on the accounting layer.
This family needs a
period.
Without one it is skipped rather than run against an undefined scope, which is why the continuous sweep resolves the open periods itself and runs this subset once per open period.Five of these were already gated in code behind “only meaningful once the period’s bills are raised”, long before the phase tag had a name.
CONTRACT-ASOF is on the bookkeeping layer: matching every payroll line to a covering contract is matching.Loans and treasury · 10
Loans and treasury · 10
7 continuous must-be-zero, 0 close-gated, 3 report-only.
1 on the bookkeeping layer, 9 on the accounting layer.
Financing is judgment, so this family sits almost entirely on the accounting layer.
The float-to-facility tie is the exception, because it is a reconciliation.
VN VAT and statutory · 11
VN VAT and statutory · 11
6 continuous must-be-zero, 0 close-gated, 5 report-only.
5 on the bookkeeping layer, 6 on the accounting layer.
VAT-INTEGRITY-OUT is a GreatBook addition.
The workbook’s per-line integrity check only covered input VAT.VAT-133-TIE and VAT-3331-TIE compare exact register base evidence with GL base.
New register rows bind to one immutable journal line; historical rows without exact, unambiguous same-organization evidence make the result partial or inconclusive rather than producing a false pass.Adjustment notes · 12
Adjustment notes · 12
10 continuous must-be-zero, 0 close-gated, 2 report-only.
12 on the bookkeeping layer, 0 on the accounting layer.
Every check here is on the bookkeeping layer.
An adjustment note is matched to the original document it adjusts, and the judgment behind raising one is recorded elsewhere.
Consolidation · 5
Consolidation · 5
2 continuous must-be-zero, 1 close-gated, 2 report-only.
0 on the bookkeeping layer, 5 on the accounting layer.
GROUP-TB is intentionally absent.
Adding balanced journal lines across a group would restate the GL’s structural debit/credit rule without proving membership, translation, completeness, or eliminations, so the former tautology is not counted as a green control.Wave E kết chuyển · 3
Wave E kết chuyển · 3
Three close-gated must-be-zero controls, all on the accounting layer.
These controls verify the period-end carry-forward and result transfer after the procedure has run.
Asking them mid-period would turn ordinary in-flight balances into false findings, so they belong only to the explicit close-gated family.
The most credible decision in the finance layer
Where a workbook check is true by construction in a relational model, it was not reproduced as a fake zero-check. The workbook has rows that compare a stored derived column to its own derivation. In a spreadsheet that catches a pasted value. In GreatBook there is no stored derived column, so the same check compares a value to itself and passes unconditionally. Reproducing it would have produced a green row that tests nothing. Instead the value became structural - the derived value cannot drift - and the version with real teeth was implemented in its place:
The same reasoning produced the
WIP-154 checksum with teeth: the workbook’s WIP nets to zero because a live unit-cost formula moves both legs together, and GreatBook stamps the cost immutably on the movement so it cannot.
Running it
live_acceptance reads on a read_only=True session and rolls back the single insert the FX assertion needs, then asserts the table count is unchanged afterwards.
The floor’s own pytest suite proves the engine on a throwaway database and says nothing about live.
Where it is enforced
The test that would fail if it broke
The capstone istest_close_list, which runs a single close touching six families with live worked data and asserts the whole surface is green.
Each family also has its own suite: test_settlement.py, test_costing.py, test_payroll.py, test_loans.py, test_vat.py, test_adjustments.py, test_consolidation.py.
What is deliberately not built yet
Recorded honestly rather than omitted:- the sample-cost pool and the asset-register independent re-derivation, which need an asset and sample sub-ledger of their own;
- per-tenant
authenticatedRLS policies, waiting on the JWT organisation claim.
Related
- The exception system - the nightly sweep that runs 78 of these, and the register it files into
- Two layers on the same documents - the rule behind the layer column
- What guards the engine - why a Close break is reported rather than refused
- The 18 GL invariants - the other set of checks, and the distinction
- The seven sub-ledgers - the families this surface spans
- Nothing stored that can be derived - why the tautologies were replaced
- Fiscal periods and closing - step 4 of the close checklist