Tamper-Evident Ledger
Bills, payments, refunds and voids written as a hash-chained event log. Change, delete or rewrite any row and verification points straight at it.
1. Run a shift
Each action is checked against the current balances, then becomes exactly one event, or is refused with a reason. Refused actions write nothing.
- Nothing yet.
Try a refund yourself
Run the shift first so there are payments to refund.
2. The ledger
Each event stores the hash of the one before it, so every row vouches for all rows above it. An anchor copies the latest hash somewhere the database can't reach, like an end-of-day report.
| # | Event | By | Details | Previous → hash |
|---|---|---|---|---|
| Empty. | ||||
3. Try to cheat
Pretend you have write access to the database and want the $9.00 refund to look like $1.00, or the void to disappear.
Change a number
Edit the refund amount in place.
Delete a row
Remove the void from history.
Rewrite and re-hash
Change the refund, then recompute every hash after it so the chain looks whole.
4. Balances rebuilt from the ledger
Nothing below is stored. Every figure is recomputed from the events, in integer cents, each time the ledger changes.
| Bill | Table | Status | Total | Payment |
|---|
Checks
5. Tests
Money rules and tamper detection, run in your browser against the code on this page.
Where the rules come from
- From the IPOT POS: settlement is one transaction, so the charge, closing the bill, freeing the table and the cash-drawer entry land together or not at all. Refunds only go against captured payments, never beyond what is left including the tip, and record a reason and an approver. A void records who did it and why, and a voided bill can't be settled. Items keep the price the cashier saw when they were ordered. At IPOT these actions are written to an audit log.
- From the governance-platform rebuild: the append-only, hash-chained history and a verifier that walks it; its September 2026 run verified 328 incident events.
- Added here: anchoring. A hash chain alone only proves rows agree with each other; someone who can rewrite the table can recompute every hash (attack 3). Keeping the latest hash outside the database is what makes a rewrite visible.