Most agent teams start with a free text handoff. The agent writes something like "I could not complete this request, a human should look," a support engineer reads it, and the case disappears into a queue. Nothing about that note can be aggregated. You cannot tell whether the agent escalated because a tool returned an empty field, because two documents disagreed, or because a policy blocked the action. Those are different bugs with different owners.
The fix is a closed list. A closed list means the agent may not invent a label. It must pick one of the codes you defined, and if nothing fits, the case is a taxonomy gap you log and fix at the list level, not at the case level. This is the same discipline evaluation frameworks apply when they insist success criteria be specific enough to become measurable metrics: a vague goal like "the agent should be helpful" cannot be scored, while "a factually correct summary fully grounded in known documents" can Google Cloud's agent evaluation guide.
Reason codes do for escalations what graders do for evaluations. Anthropic's write-up on agent evals defines a grader as logic that scores some aspect of the agent's performance, and notes a task can carry several graders with several checks each Anthropic's evaluation guide. A reason code is the coarse grader attached to every escalated trial: it scores why the run stopped.
The decision rule for the list itself: if two codes would route to the same queue and require the same fix, merge them. If one code covers two failure modes that different people would fix, split it. Four codes survive that test for most support and operations agents. Six is the ceiling; beyond that, reviewers start guessing.



