A router model does one job: given a user request and a catalog of tools, it picks the tool whose description best matches the intent. That is a fit decision. Function calling, as documented by OpenAI, is built around exactly this: you pass a list of tools, the model returns a tool call with a name and JSON arguments, and your application executes it. The model never executes the function itself, and it has no reliable view of whether the calling identity holds the scope that tool requires.
That gap is where authority failures live. Fit and authority are independent dimensions. A tool can be a perfect fit and completely out of scope. A 7B router asked to "issue a refund for order 4471" will happily select a issue_refund tool if that tool is in its list, even when the agent's OAuth grant carries read-only billing scope. The route was correct. The execution will be refused.
Research on small language models in tool systems shows this failure class is structural, not a prompt-tuning bug. A study presented at ACL 2026 found that small models hallucinate plausible but nonexistent tool names because the schemas they receive do not match naming conventions internalized during pretraining, and that adapting the schema to the model cut those schema misalignment errors by 80% (Lee et al., ACL 2026). The same mechanism applies to authority: a name like admin_refund or delete_account is strongly associated in pretraining with capability, so a small model gravitates toward it whether or not the current identity can call it.
The decision rule that follows is simple and worth stating plainly. If a failure is caused by fit, retrying with a better prompt or a larger model can help. If it is caused by authority, no amount of retrying or escalation will help until the permission graph changes. The rest of this article is about costing the second case and engineering it out.



