Part 5 of 7 · Ticket router series ~5 min read

How a misroute gets corrected

A ticket lands in the support channel at 9:12am. It’s really a billing question; the router read it as a login problem. There’s a Reassign button. What happens when someone taps it? The honest answer is “it depends what they meant to fix.” This post walks through the three things a human can do to a routed ticket — reassign, bump priority, split — and how the ticket, the queue, and the router’s own examples all stay in sync, so the same mistake gets less likely next time.

Key takeaways

  • Three actions on a routed ticket: reassign (move it, teach the router), bump priority (raise or drop urgency), split (one ticket, two topics).
  • Each action updates the ticket, moves it in the queue, and writes an audit row.
  • A reassign records the original tag and the corrected tag side by side.
  • Corrections feed the router’s labelled examples, so the next sort is a little better.
  • The Reassign button is a Slack interactive message backed by a Function URL.

Three actions on a routed ticket

Three actions a human can take on a routed ticket A diagram showing one input on the left flowing through a small interactive Slack card, then branching into three action paths. Far left: a "Ticket in Slack channel" box showing a typical hand-off card — customer, topic, urgency, tone, message — with three button placeholders below: Reassign, Bump, Split. Whoever picks up the ticket taps one button. The middle column shows the three branches. Branch one, Reassign: opens a Slack menu of teams; on pick, a Function URL Lambda moves the ticket to the new team's queue, updates the topic on the ticket, and writes a correction row to the tr-corrections table with the original topic and team, the corrected topic and team, and who changed it. That correction is added to the router's labelled examples so the next similar ticket sorts better. Branch two, Bump: raises or drops the urgency — a calm ticket that turns out to be urgent gets lifted to priority, a false alarm gets dropped to normal; the queue position changes and a row is written to tr-corrections noting the urgency change. Branch three, Split: a single ticket that holds two separate problems is split into two tickets, each re-read and routed on its own; the original is closed with a pointer to the two new ones. The right side shows the convergence: every action writes a row to the tr-audit DynamoDB table with timestamp, ticket id, action, by-user, and before-and-after. A note at the bottom: a correction doesn't just fix this ticket — it teaches the router, so the same kind of misroute gets less likely. Ticket in channel customer, topic, tone [Reassign] [Bump] [Split] Action 1 Reassign • Menu: pick the right team • Ticket moves, topic updated • Correction row written • Added to router examples Action 2 Bump priority • Raise or drop the urgency (normal ↔ priority) • Queue position changes, correction row written Action 3 Split • One ticket, two problems → two tickets • Each re-read and routed — original closed Audit trail DynamoDB tr-audit timestamp · ticket_id action · by-user before · after A correction doesn’t just fix this ticket — it teaches the router, so the same misroute gets less likely.
Fig 5. Three actions on a routed ticket, three different effects. Reassign moves it and teaches the router. Bump raises or drops the urgency. Split turns one ticket into two. Every action writes to the audit trail.

Action 1: reassign (the most common)

Someone in the support channel reads the ticket, sees it’s really a billing question, and taps Reassign. A small Slack menu opens with the list of teams. They pick Finance and confirm.

The confirm submits to a Function URL Lambda. Three things happen, in order. First, the ticket moves: it’s removed from the support queue and placed in the finance queue, and the topic on the ticket is updated from login to billing. Second, a correction row is written to tr-corrections with the original topic and team, the corrected topic and team, the customer, and the person who made the change. Third, an action: reassign row is written to tr-audit with the before-and-after snapshot.

The correction is the part that matters most. That row — “this ticket, which read like login, was actually billing” — gets added to the router’s labelled examples, the same handful of real tickets the read step shows the model in Part 2. The next time a ticket arrives that looks like this one, the model has a closer example to match against. The router doesn’t retrain; it just gets a better set of examples, refreshed from real corrections.

Action 2: bump priority (raise or drop the urgency)

Sometimes the team is wrong — the router read it right — and sometimes the router misjudged how urgent something was. A ticket that read calm turns out to be a customer about to churn; a ticket that read urgent turns out to be someone who writes everything in capitals. Either way, a human can fix the urgency without touching the team.

Bump opens a small choice: raise to priority, or drop to normal. On confirm, the Function URL Lambda changes the urgency on the ticket and moves it in the queue — up to the top and a ping to the lead if raised, down into the normal pile if dropped — and writes a row to tr-corrections noting the urgency change. Like reassigns, repeated urgency corrections on a kind of ticket feed back into the examples, so the router learns that “customers who say X are usually more urgent than they sound.”

Action 3: split (one ticket, two problems)

Customers don’t always send one problem per email. “My login’s broken and also I was double-charged last month” is one ticket with two topics — one for support, one for finance. Routing it to either team leaves the other half stranded.

Split turns the one ticket into two. The Function URL Lambda creates two new tickets from the original, each carrying the relevant part of the message, sends each back through the read step so it gets its own topic, urgency, and tone, and routes each on its own. The original ticket is closed with a note pointing at the two new ones, so the trail is clear. Split is the rarest of the three actions, but it’s the right tool for the ticket that genuinely belongs in two places — far better than forcing it into one queue and trusting two teams to coordinate from a single card.

Every action is logged, every action teaches

The tr-audit table records every reassign, bump, and split with the user, the timestamp, and a snapshot of the ticket before and after. If a reassign was itself a mistake — someone moved it to the wrong team in a hurry — the next person can reassign again; the trail shows the full chain, so nothing is lost. The tr-corrections table is the narrower, teaching record: just the cases where the router’s tag and a human’s tag disagreed. That table is what the weekly digest counts to show the correction rate, and what feeds the examples.

This is the quiet payoff of keeping a human in the loop on every misroute instead of trusting the router blindly. Each correction is cheap — one tap — and each one makes the system a little more right. A router that learns from its mistakes beats one that’s clever on day one and never improves.

Next post: the cost breakdown. The whole pipeline above runs in coffee-money territory at SMB volume; Part 6 explains exactly where the dollars go and why one small model call per ticket is the only real cost.

All posts