The budget only works if the runtime knows which tools spend. That is the job of a per-effect classifier: one table, reviewed by a person, that labels every tool the agent can see as read, write or destructive. lookup_customer is read. update_crm_field and issue_refund are write. delete_workspace and rotate_production_key are destructive. Classification lives in code and config, not in the prompt, and it should be stated once and enforced everywhere, because letting the agent decide dependency mode at runtime is exactly the mistake sandbox practitioners warn against in sandbox testing guidance for tool calls and side effects.
Two decisions go into that table. First, destructive calls usually get their own counter, often with a budget of one, because a single bad delete is worse than five duplicate updates. Second, some tools are write-only in theory and read-only in practice: a refund that finds the refund already exists changes nothing. Classify by the worst case, then let idempotent implementations reduce the real risk without changing the count.
If classification is new work, derive it from what the tool actually does. Reads return data; writes change stored state or cause an external effect; destructive calls remove state or widen blast radius. When a tool is ambiguous, label it write. A false write label costs budget, a false read label costs money. Runtime enforcement products draw the same line: a Slack agent that summarizes activity does not need to post to channels, and a finance agent flagging discrepancies does not need to approve them, as governance tooling for runtime agent enforcement puts it.



