Context
grid#40 (merged via grid#47) built the Grid-side half of tenant-budget tracking: a budgetPolicy CRD field, a tenant-keyed GCounter, SWIM gossip propagation, and a status.budgetStatus[] signal. #47's own description was explicit that enforcement/reporting is cross-repo:
Enforcement (degrade to a cheaper backend / reject at 100%) is explicitly out of scope here — that's cross-repo, gateway-side praxis-ai policy-filter work.
That's the right call, but checking today, the other half doesn't exist anywhere yet: every call site of GridStateSnapshot::increment_tenant_spend in this repo is inside a #[test] module (swim_runtime.rs, swim/src/node.rs, swim/src/state_broadcast.rs, crdt/src/grid_state.rs). There's no HTTP/gRPC endpoint, no SWIM participation from the gateway side, no anything — a real deployment has no way to actually get spend data into the counter this whole feature is built around.
Why this matters now
The ai-side pieces that would produce this data are in flight in parallel:
ai#658 / ai#121 (Token Rate Limiting) — computes token-denominated costs at the gateway, but doesn't reference Grid or emit a spend report anywhere in its current design.
ai#577 (external_metering filter, PR ai#581) — closest existing candidate; already does pre-request balance checks and post-response usage reporting, just to an external billing service, not Grid.
ai#191 (Agent budget enforcement) — explicitly assumes "gateway-local tracking," consistent with my own design comment on grid#40, but never specifies the wire format to Grid.
Nobody has picked "which filter, which protocol, which payload" for the actual gateway → Grid leg, and no issue currently tracks it.
Scope (proposed, not decided)
- Decide which
ai-side filter is the reporter of record (extend ai#577's external_metering? a new filter? something in ai#658's reconciliation path?).
- Define the wire contract: does the gateway join SWIM directly (heavy), or does Grid expose a lightweight report-spend RPC/HTTP endpoint that increments the local site's
GCounter slot (lighter, more likely)?
- Payload: tenant ID, amount in cents, site ID — mirrors
cost_cents_for_tokens's test shape (operator/src/swim_runtime.rs) which already anticipates scoring::BackendConfig::cost_per_1k_input as the cost basis.
Related
Context
grid#40(merged viagrid#47) built the Grid-side half of tenant-budget tracking: abudgetPolicyCRD field, a tenant-keyedGCounter, SWIM gossip propagation, and astatus.budgetStatus[]signal.#47's own description was explicit that enforcement/reporting is cross-repo:That's the right call, but checking today, the other half doesn't exist anywhere yet: every call site of
GridStateSnapshot::increment_tenant_spendin this repo is inside a#[test]module (swim_runtime.rs,swim/src/node.rs,swim/src/state_broadcast.rs,crdt/src/grid_state.rs). There's no HTTP/gRPC endpoint, no SWIM participation from the gateway side, no anything — a real deployment has no way to actually get spend data into the counter this whole feature is built around.Why this matters now
The
ai-side pieces that would produce this data are in flight in parallel:ai#658/ai#121(Token Rate Limiting) — computes token-denominated costs at the gateway, but doesn't reference Grid or emit a spend report anywhere in its current design.ai#577(external_meteringfilter, PRai#581) — closest existing candidate; already does pre-request balance checks and post-response usage reporting, just to an external billing service, not Grid.ai#191(Agent budget enforcement) — explicitly assumes "gateway-local tracking," consistent with my own design comment ongrid#40, but never specifies the wire format to Grid.Nobody has picked "which filter, which protocol, which payload" for the actual gateway → Grid leg, and no issue currently tracks it.
Scope (proposed, not decided)
ai-side filter is the reporter of record (extendai#577'sexternal_metering? a new filter? something inai#658's reconciliation path?).GCounterslot (lighter, more likely)?cost_cents_for_tokens's test shape (operator/src/swim_runtime.rs) which already anticipatesscoring::BackendConfig::cost_per_1k_inputas the cost basis.Related
grid#40/grid#47— Grid-side plumbing this depends on (merged)grid#48— open RBAC gap on the samebudgetStatussignalgrid#64/grid#52/grid#63— active follow-on design work ontenant_spendepoch/window semanticsai#577,ai#191,ai#658,ai#301— candidate reporters / parent epics on theaiside