Ledger & Integrity
Ledger & Integrity
This is the part the rest of the resource is built around.
Every move is a row
Each transaction writes to aty_ledger: what item, how many, from where, to where, who caused it and why, under its own tx_id. A trade commits all at once — every item crosses or none does — and writes one row per item that crossed.
Creation and destruction are real endpoints. An item that is crafted arrives with no from_inv; an item that is used leaves with no to_inv. Because creation and destruction are recorded like any other move, the totals close: what exists plus what was destroyed equals what was ever created.
Tracing one unit
invtrace <serial>
Prints that ULID's whole life. This is the question a server owner actually gets asked — "where did this gun come from" — and it has an answer.
Rolling back
Every commit has a transaction id, and a move between two containers can be reversed by it:
invrollback <tx_id> shows what the transaction moved
invrollback <tx_id> confirm moves it back
Rows that created or destroyed something are not reversed, and a rollback refuses when the item has since moved on. The rollback is itself a transaction and is itself written to the ledger, with whoever ran it as the actor. There is no un-audited path back.
The integrity auditor
invaudit duplicates only — the cheap check, worth running often
invaudit full also reads the ledger for ghosts and orphaned bags, and prints the census
invaudit sweep removes empty orphaned bag rows
It reports:
| Finding | Meaning |
|---|---|
| Duplicates | The same serial in two places |
| Ghosts | A unit the ledger says exists but no container holds |
| Orphaned bags | A bag whose item is gone while its contents are not |
Nothing is repaired on its own. A ghost is closed with invwriteoff <uid|all> confirm, which records that it left the world; an orphaned bag is printed with the invcheck line that opens it; empty ones are litter that invaudit sweep removes. The panel's Integrity tab shows duplicates and ghosts with counts and a per-row breakdown.
Conservation testing
invstress
Runs the dupe patterns against the real engine in two scratch stashes — a replayed request, thirty rapid clicks on one slot, two actors racing over the same containers, then four hundred timed moves — and checks after each that nothing was created or destroyed. Each stage prints conserved or LEAK, and the run ends with final: n unit(s) vs n seeded CONSERVED; anything else is a bug worth reporting. The scratch containers and their ledger rows are removed afterwards.
Related: invstressdb, invstresstx, invghosttest, invcheck.
Webhooks
Config.Webhook = { enabled = true, url = 'https://discord.com/api/webhooks/…' }
Off by default. Three kinds of line can be mirrored to Discord, each switched in send: what the auditor finds (alarms), admin actions — rollbacks, console moves, admin gives (admin) — and movements of anything worth minValue or more at shop prices (valuable). invwebhook prints the settings; invwebhook test posts one line to prove the URL works.