T1 triage bot
Eight scrum teams, a rotating triage duty, and severity calls that depended on who was on shift.
built at team one. metrics are sanitized aggregates; sla rubric described at the shape level only.
Bug triage across the digital org's scrum teams ran on a human rotation: someone watches the channel, someone eyeballs severity, someone chases the SLA. Manual, slow, and inconsistent — the same ticket got a different priority depending on who was on duty that week. The cost wasn't just time; severity, the thing the whole SLA hinges on, was a coin flip weighted by whoever was on shift.
It looked like a staffing problem. It was an information problem. Everything needed for a severity call already lives in the ticket system — the bot just has to read it the way the system intends: programmatically, through the API, with the ticket system as the source of truth. No pasting ticket text into a chat window.
The tempting first build was a chat assistant: copy the ticket, paste it, ask for a severity. It would have demoed well and rotted fast — pasted blobs lose structure, drift out of sync with the ticket, and can't be a system of record. The route taken instead: structured API data is the only input the model ever sees.
The second choice gets missed in most AI-tool conversations: the model is used only where the judgment actually lives. Severity classification — reading a thread plus live ticket data against the SLA rubric and citing which criteria fired — is the LLM call. Everything else (the rotation schedule, notifications, user-group updates, channel topics) is a deterministic engine on cron. No model where a rule will do.
Mention the bot in a thread and it pulls the full conversation, extracts the ticket keys, fetches each ticket from Jira in parallel, and sends thread + structured tickets + the four-level SLA rubric to the model — which returns a severity level with the specific objective criteria cited, posted back in-thread. Conversation memory makes follow-ups work: ask “what if it only affects one region?” and it re-assesses in context. Postgres holds rotation state, Redis caches, cron drives the morning and evening rotation checks.
Runtime is OpenAI; Claude's role in this system is the build chain — the repo is specced and maintained through Claude Code, spec-first, like everything that came after it.
About 90% of manual routing eliminated. Severity recommendations land within ~5 minutes — against up to a full day before — and get accepted roughly 99% of the time. The bot handles hundreds of tickets a month and prevents dozens of SLA breaches monthly.
And it became the canonical internal reference — “see: how the t1 triage bot pulls ticket information” is how we describe the pattern to every tool that came after.
The LLM reads structured API data, not pasted blobs. Every tool we built after this one inherited that rule.
the insight