## Budgets are enumerated, not named

Pillar 2 asks for "simple visibility into resource use from the beginning". Every
storage primitive already carried the measurement — a name, occupancy, a
capacity, `peak()` and `overflows()`. What none of them could do was be *found*.

The consumer had to name each one. The shell's per-second report read five
accessors off three primitives into one format string, tested two of them for
overflow in one warning branch, tested the third in another worded differently,
and called `reset_stats` on each in turn. Adding storage meant editing four
places in one function, and the failure when you missed one was the worst
available: an unreported budget is indistinguishable from a budget that is fine.

So `budget.rs` inverts it. A `BudgetReport` is six plain numbers; a `Budgeted`
thing hands over one or more; `visit_all` walks a borrowed slice of them. The
shell now holds `&[&dyn Budgeted]` and formats reports, and there is exactly one
line in the codebase that knows what storage exists.

**The registry owns nothing and nothing registers with it.** A report is built
on demand by reading the live primitive, so there is no second copy of the truth
to go stale and no registration call anybody can forget. The "registry" is a
slice literal at the call site — sized by the compiler, so there is no registry
capacity to pick, which matters because a capacity chosen before anything
measures one is exactly the guess `BUDGETS.md` exists to replace.

**Why a visitor and not an iterator.** `Vec<BudgetReport>` allocates, which is
denied in the core. `impl Iterator` does not allocate but is not object-safe, so
`&dyn Budgeted` and therefore the slice above could not exist — and aggregates
make that worse, since a `Graph` holds two budgets and a world will hold an
aggregate of aggregates, so each level of nesting would chain another iterator
type through the signature. A visitor composes across that tree for free, stays
object-safe, and allocates nothing. The cost is that a consumer cannot take the
first two reports and stop, which nothing wants to do.

**An aggregate reports its parts separately.** `Graph` visits its pool and its
`Order` as two lines although they share a name and fill together, because they
are separate storage that can be separately wrong: an ordering that refused a
push while the pool still had slots is a bug in that module, and a report that
had folded them into one line is a report in which that bug is invisible.

**The counts are `u32` and convert by saturating.** Wrapping would turn a 5 GiB
arena into a plausible small number and make the report quietly false;
saturating produces `4294967295`, which is not a number any budget here has and
reads as "go and look". Neither case is expected — this engine measures its
budgets in tens of kilobytes — so the only question is which failure is legible.

### A refusal names the resource and the operation

The other half of pillar 2, and it was already true: `Exhausted` carries the
arena and the `op`, `Overflow<T>` the pool, the `op` and the rejected value, and
`Attach` the graph, the `op` and the reason. What was missing was a check, so
`tests/budgets.rs` drives each primitive to capacity and reads back what it
says. It also asserts that a refused operation leaves occupancy and the
high-water mark byte for byte as they were, and that the overflow count survives
the frame boundary that clears the contents.

**`DrawList::push` is the one deliberate exception.** It is infallible, because
a caller that had to handle a rendering failure at every call site would push
renderer concerns back into gameplay. The guarantee it owes is therefore carried
by the budget report instead — the resource is named there and the refusal is
counted there — and that substitution is a test rather than a comment.

**Unresolved handles are not a budget.** A command whose mesh names nothing
would have been dropped by an instance buffer with room to spare, so counting it
as capacity pressure would send whoever is reading to the wrong place. It keeps
its own counter and its own warning line, outside the report.

