Triggers are conditions, not vibes
"Escalate when it feels serious" is not a policy — it's a mood, and moods degrade with queue depth. The trigger list above is the same judgment, compiled into conditions a script can evaluate and a new hire can apply on day one without asking anyone:
- Emotional language — grief, fury, "I'm begging you," "I'm done with you people." The single best-documented territory where automated support fails, and the first one Klarna named in its reversal. A model reads "where is my order" and sees a status question; a human hears the funeral on Saturday.
- Legal or chargeback threat — "lawsuit," "my bank," "chargeback," "small claims." From the moment this appears, the reply is potential evidence. Nothing templated goes near it.
- Over the refund line — a number, on purpose. $100 here; your team's number is whatever your lead's own approval limit is. Below it, mistakes are cheap and macros may draft. Above it, a mistake is a real ledger event, so the ticket routes to someone whose job title includes eating that risk.
- Third contact on the same issue — by the third email, the issue is no longer whatever the customer's words say it is. The issue is that your process failed twice. That meta-problem has no macro, because its actual intent is "restore trust," and trust is restored by a named human reading the whole thread.
- Regulator or media mention — rare, unmissable, and the cost of missing one is a genre of headline you've read.
Run it: one ticket trips three triggers at once. That's typical — real escalation tickets rarely trip just one, which is also a useful smell test for your trigger list. If most escalations arrive via a single trigger, your conditions are probably too loose or too few.
Notice what the conditions did to the argument
With triggers_hit in the codebase, "should this have escalated?" stops being a debate about judgment and becomes a diff. The ticket had contacts: 3; the trigger list says three contacts escalates; the macro answered anyway — that's a bug, not a performance conversation. And when a ticket should have escalated but no trigger caught it, the fix is equally concrete: add the condition, and every future ticket benefits.
That's the same move as the banned-promises list and the golden evals: take the thing your best agent does by feel, write it as data and conditions, and now the whole team — including the drafter — does it every time.
One more thing the function's shape tells you: it returns all the hits, not the first one. The routing decision only needs "any trigger fired," but the escalating human needs the full list — "third contact + over the line + emotional" is a briefing, not just a flag. Next: drill the routing, then find the hole someone left in the refund check.