> For the complete documentation index, see [llms.txt](https://atiysus-organization.gitbook.io/aty-scripts/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://atiysus-organization.gitbook.io/aty-scripts/inventory/features/ledger-and-integrity.md).

# 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

```lua
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.
