Skip to content
PaloNexus
Request access Request

Recipe: budget exhaustion

Every authority-bound agent can carry a rolling per-hour budget — a ceiling on calls and on LLM tokens. When it’s exceeded, the egress decision denies with call budget exceeded or token budget exceeded (a hard 403), which the SDK surfaces as PolicyDenied. The budget meter is a live control-plane gate (internal/policy Meter, attributed from the model-broker’s usage reports), so it is not modeled by the offline FakeControlPlane.

The deny-handling shape is identical for any hard refusal, so it can be written and tested offline. Here the seeded no-access negative persona is hard-denied on a sample incident from the temporary-elevation walkthrough; in production call budget exceeded arrives through the very same except PolicyDenied branch:

from palonexus import PaloNexus
from palonexus.errors import PolicyDenied, ApprovalRequired
AGENT = "northstar-devops-incident-agent"
OWNER, APPROVER = "ethan.park@northstar.example", "maya.chen@northstar.example"
NEGATIVE = "claire.evans@northstar.example"
pn = PaloNexus.offline()
pn.agents.register(name=AGENT, owner=OWNER, sponsor=APPROVER, scenario="devops-incident").provision()
with pn.task(subject=NEGATIVE, task_id="INC-4821", scenario="devops-incident", actor=AGENT) as task:
try:
task.authorize(action="runbooks:read", resource="runbooks-api:/runbooks/db-failover")
except PolicyDenied as e:
print("hard deny:", e.reason) # live, this is "call budget exceeded" / "token budget exceeded"
except ApprovalRequired as e:
print("needs approval:", e.reason)
pn.close()
hard deny: claire.evans@northstar.example is not authorized for scenario devops-incident

The ceiling lives on the agent’s registry entry. Register it with a budget (a zero on either dimension means unlimited there):

Terminal window
curl -X POST localhost:8181/v1/registry/services \
-d '{
"name": "northstar-devops-incident-agent",
"kind": "agent",
"owner": "ethan.park@northstar.example",
"egress": ["model-anthropic", "runbooks-operator"],
"budget": { "callsPerHour": 200, "tokensPerHour": 500000 }
}'

The control plane meters each allowed egress call against a rolling one-hour window per agent; the model-broker POSTs token usage to /v1/usage so the token dimension is attributed back to the agent.

Budget burn is visible on the palonexus-overview dashboard:

SignalQuery
Per-agent token usagepalonexus_token_usage_total
Per-agent spend (USD)palonexus_agent_cost_usd_total
Deny rate (incl. budget)palonexus_authz_decisions_total{decision="deny"}

Alert on the deny rate climbing for one agent — it usually means a runaway loop hitting its ceiling, exactly what the budget is there to contain.