KognitaKognita.

Blog

Your AI Triage Routes to the Wrong Jira Project. Again.

8 min read

The ticket says "billing export is failing." The AI triage sees "billing" and routes to the payments team. The payments team looks at it for a few hours, determines it's not theirs, and re-routes to the data pipeline team. The data pipeline team says check CODEOWNERS. CODEOWNERS says the export service is owned by the reports team. The reports team finally sees the ticket — six hours in, on a four-hour SLA.

This is not unusual. Atlassian's own community has documented this exact pattern: tickets that have an assignee but sit in "waiting for review" status for hours because the receiving team has no alert, or because the routing rules pointed to a team restructuring that happened eight months ago. The SLA breach wasn't caused by workload. It was caused by routing latency.

Why keyword routing fails at the edge cases

AI triage trained on ticket text does a reasonable job of routing obvious cases. "Login failure" goes to authentication. "Payment declined" goes to billing. The problem is that interesting bugs rarely arrive with obvious routing signals. A billing export failure could be owned by the billing service, the export service, the data pipeline, or the reporting service — depending on where in the flow the failure occurs. AI trained on ticket language can't distinguish these without understanding service architecture.

The deeper problem is that service ownership changes faster than triage rules are updated. Teams restructure. Ownership transfers. A service that used to be owned by Platform is now owned by the product team that adopted it. The routing rules that were configured at implementation don't reflect the current CODEOWNERS file. The triage AI routes to the old owner, and the ticket bounces.

How a single routing failure cascades through the SLA window
Routing failure on a single ticket:
  Ticket: "Billing export to CSV is failing for our enterprise account"
  AI routes to: Payments team (keyword: billing)
  Payments: "This isn't ours — try Data Pipeline"  (+2h)
  Data Pipeline: "Check CODEOWNERS — export is owned by Reports team"  (+3h)
  Reports team: picks it up  (+1h)
  SLA window: 4 hours. Time elapsed before correct team sees it: 6 hours.

  What was needed: know that csv-export-service is in CODEOWNERS → @reports-team

What accurate routing requires

Accurate service ownership routing requires two things: understanding which service is involved in the reported behavior, and knowing who currently owns that service. Both of these are codebase questions. The service responsible for an export failure is identifiable from the service architecture. The current owner is in CODEOWNERS. Neither source requires manual maintenance — they update automatically when engineers push code.

Jira ticket triage without service ownership context routes by surface language rather than system reality. The same ticket text maps to different correct teams depending on where in the codebase the problem actually lives — and you can only know that by reading the codebase.

Why keyword routing fails on ambiguous tickets
Why keyword-based AI triage fails:
  "Billing export" → could be Billing, Data Pipeline, or Reports
  "Can't log in" → could be Auth, Permissions, SSO, or Account
  "API returns 500" → could be any service
  "Slow performance" → could be any service with a database query
  "Feature not showing" → could be feature flags, permissions, or the feature team

  Keyword routing classifies by surface language, not by system reality.
  The codebase knows exactly who owns what. AI triage doesn't.

A webhook agent that reads CODEOWNERS

Kognita provisions a webhook that fires when a ticket is created in Jira Service Management or your support platform. The managed agent receives the ticket, identifies the services or features referenced in the description, queries the live codebase to determine service ownership from CODEOWNERS, and routes the ticket directly to the correct team — without keyword matching, without static routing rules, and without the teams in between.

How a codebase-grounded webhook agent routes the same ticket instantly
What a Kognita webhook agent routes on the same ticket:
  Ticket: "Billing export to CSV is failing for enterprise account"
  Agent queries CODEOWNERS for export-service → @reports-team
  Agent checks recent commits to csv-export — last changed 3 days ago by @reports-team
  Routes directly to: Reports team Jira project
  Time to correct owner: seconds, not hours.

The routing is accurate because it's derived from the same source that defines ownership: the codebase. When a team takes ownership of a service and updates CODEOWNERS, the routing updates automatically. No triage rule maintenance, no re-training, no support team manually updating routing tables after a reorg.

The SLA impact of instant correct routing

Every minute between ticket creation and the right engineer seeing the ticket is SLA time consumed without progress. When tickets route correctly on creation, the window from "ticket created" to "right person sees it" collapses from hours to seconds. The SLA window that was previously spent on inter-team routing is now available for actual resolution.

For teams with P1 SLAs measured in minutes or hours, the routing step is the difference between meeting and breaching. A four-hour SLA with a six-hour routing path is breached before work begins. Instant correct routing means the clock starts when work actually starts.

Final take

AI triage routes by what the ticket says. CODEOWNERS knows who actually owns the affected service. The gap between those two sources is where SLA time disappears. A webhook-triggered agent that queries the live codebase on every ticket creation routes by system reality — and the SLA window is spent on resolution, not on bouncing between teams.

The ticket arrives. The agent checks CODEOWNERS. The right team sees it in seconds. That's the difference between routing by keywords and routing by codebase.