Notes · 14 August 2026 · 5 min
Money in a ledger should never be a floating-point number
An ERP that is approximately right is worse than the spreadsheets it replaced. Three decisions that follow from taking that seriously.
Every developer learns at some point that 0.1 + 0.2 does not equal 0.3 in floating-point arithmetic. Most learn it as a curiosity. If you are building anything that holds a balance, it is not a curiosity — it is the reason the accounts will not reconcile eighteen months from now, in a way nobody can trace back to a cause.
We ran into this properly while building a 24-module business OS: accounting, inventory, CRM, manufacturing and payroll in one system, with a double-entry general ledger underneath. The constraint that shaped everything else was simple to state and unpleasant to satisfy. An ERP that is approximately right is worse than the spreadsheets it replaced, because a spreadsheet is visibly untrustworthy and a system is not.
Store integers, not decimals
Money is held in integer minor units — paise, cents — never in a floating-point type and never in a language-level decimal that a careless query can coerce. A price is 129900, not 1299.00. Formatting happens at the edge, once, on the way to a screen or a document.
This is unglamorous and it removes an entire category of defect permanently. There is no rounding drift, no summing error that appears only above a certain row count, and no difference between what the database holds and what the invoice says. The cost is that every developer touching the code has to know the convention, which is a documentation problem rather than a correctness one.
The related decision is that every calculation — tax, discount, apportionment, currency conversion — runs through a deterministic engine with unit tests behind it, rather than being written inline at the point of use. Not because inline arithmetic is wrong, but because the fifth place it gets written is where it will differ from the other four.
Event-source the things people will argue about
Inventory is event-sourced across warehouses. Stock is not a number you update; it is the sum of movements, and any past moment can be reconstructed rather than inferred.
This matters because inventory disputes are retrospective. Nobody asks what the stock is now — they can see that. They ask what it was on the eleventh, before the stocktake, and why the system disagrees with the shelf. A mutable quantity column cannot answer that. A movement log can, and it answers it the same way twice.
We did not event-source everything, and would advise against it. It carries real complexity, and most tables genuinely are just current state. The test we used: will somebody one day need to argue about what this value was in the past? For inventory and the ledger, yes. For a customer's phone number, no.
Make the audit log append-only, and mean it
Any figure on any screen traces back to the entries that produced it. The log is append-only — there is no code path that edits or deletes an entry, and a correction is a new entry that reverses an old one, exactly as it would be on paper.
The point of double-entry bookkeeping was never the arithmetic. It was that errors become visible instead of silent. Preserving that property in software means resisting the obvious convenience of letting an admin fix a wrong number, because the moment that path exists, the log stops being evidence and becomes a record of what somebody most recently decided it should say.
And keep the model away from the arithmetic
The system has an AI layer. It explains figures — what drove a variance, which entries make up a balance, why a number moved. It never computes them.
This is not caution for its own sake. A language model that hallucinates a plausible number inside a ledger has produced the single worst failure mode available: an error that looks like an answer, arrives with confidence, and is not flagged anywhere. Explanation is a good use of a model, because a wrong explanation of a correct number is recoverable. A wrong number is not.
The general shape of the rule is worth keeping beyond ledgers. Let the model read, summarise and explain. Do not let it be the thing that decides what is true.
This came out of Sentra — CoreOS. The case study says what it does and what it runs on.