ReadonlyBudgetTotal budget in cents, or null when uncapped.
Accumulated cost in cents, populated via record().
Sugar for wiring into a reranker. Returns a closure that records cost on
this guard — assignable directly to BaseReRanker.CostReporter.
Pre-call check: does estimatedCents fit in the remaining budget? Returns
true when uncapped or when remaining ≥ estimate.
Negative estimates are treated as zero (defensive — a buggy
EstimateCostCents shouldn't trigger short-circuits prematurely).
Post-call accumulator. Negative or non-finite values are clamped to 0.
Cents remaining in the budget. Returns null when uncapped, else
max(0, Budget - Spent).
Per-run budget tracker. One instance per search invocation; lives only as long as the SearchEngine.search call. Not thread-safe, but Node is single-threaded within a request so that's fine.