The agent that cannot stop, and the invoice that follows.
A rule counts what each agent calls and spends, and acts when it reaches the limit you set.
You write these as rules. A changed rule goes live when you promote it, without redeploying Swiftward.
The whole control
# Without exists, an undeclared ceiling reads as zero and refuses everyone.
rules:
record_agent_spend:
all:
- path: "event.type"
op: eq
value: "llm.completed"
- path: "event.data.cost_nano"
op: exists
- path: "event.data.agent.id"
op: exists # no agent, no bucket to add it to
effects:
verdict: approved
priority: 1
state_changes:
agent:
change_buckets:
spent_hour: "{{ event.data.cost_nano }}"
spent_day: "{{ event.data.cost_nano }}"
agent_spend_ceiling_day:
all:
- path: "event.type"
op: eq
value: "llm.input"
- path: "event.data.agent"
op: exists
- path: "event.data.agent.ceiling_day"
op: exists
- path: "state.agent.buckets.spent_day"
op: gte
value: "{{ event.data.agent.ceiling_day }}"
effects:
verdict: rejected
priority: 100
response:
reason: "Refused. This agent has reached the ceiling declared for it today." The numbers are not in the rule. The ceiling is set on the agent record, because it differs per agent, changes from week to week, and is set by someone in finance or security. So changing one agent's budget needs no new ruleset version.
The rule is named and versioned. You can backtest it and run it in shadow, and every decision it makes is recorded. The limit can differ for each customer. A hundred lines of gateway code gives you none of that.
What you can count
You choose what is counted, and per what: calls per agent per hour, dollars per tenant per day, tool calls per task, retries against the same failing endpoint.
The limit does not have to be a hard stop: slow the agent down, route the next call to a person, drop to a cheaper model, or refuse. One agent can carry several limits: warn at half, hand to a human at three quarters, stop at the ceiling.
How the accounting works
The counter sits in the path of every call, so a ceiling stops the next one. A call already running completes, and its cost is recorded when it closes.
Where the calling code names its own agent and you do not control that code, this is a spend control over a caller who cooperates, not a security control over a hostile one. For a hostile caller the control is authorization.
Why the loop is the dangerous half
A runaway agent is rarely one expensive call. It is a cheap call repeated faster than anyone is watching, and what usually ends it is the bill, or a downstream service that starts refusing. A counter on a dashboard someone reads on Monday is too late.