Software Engineer

Issue Triage β€” Auto-Label, Auto-Assign, Auto-Prioritize

15 min/day triage eliminatedEngineering & DevOps4 min read

Key Takeaway

Every new GitLab issue gets automatically classified, labeled, assigned to the right agent, and prioritized β€” the moment it's created. Zero human triage time.

The Problem

Issue triage is project manager work that nobody wants to do but everybody needs done.

New issue lands. Someone reads it. "Is this a bug or a feature request?" Label it. "Is this frontend or backend?" Assign it. "Is this blocking anything?" Prioritize it. "Wait, didn't someone report this already?" Check for duplicates.

At PyratzLabs, we have issues coming in from multiple sources β€” internal team, beta testers, automated monitoring alerts. Without triage, the issue board becomes a wall of unlabeled, unassigned noise. Things get lost. Duplicates pile up. Critical bugs sit next to cosmetic requests with no distinction.

I was spending 15 minutes a day just reading issue titles and dragging things into the right columns. Fifteen minutes doesn't sound like much. Over a month, that's 5 hours of reading titles and clicking labels.

The Solution

A GitLab webhook triggers our agent on every new issue. The agent reads the title and description, classifies it, labels it, assigns it to the right sub-agent, scores priority, and checks for duplicates. By the time I see the issue, it's already triaged.

The Process

The webhook fires on issue creation. The agent processes it through four stages:

Stage 1: Classification

pythonShow code
CLASSIFICATION_RULES = {
    "bug": ["error", "broken", "fail", "crash", "doesn't work", "500", "exception"],
    "feature": ["add", "implement", "new", "support for", "ability to", "would be nice"],
    "docs": ["documentation", "readme", "typo", "unclear", "how to"],
    "infra": ["deploy", "CI", "pipeline", "docker", "server", "scaling", "memory"]
}

def classify_issue(title: str, description: str) -> str:
    text = f"{title} {description}".lower()
    scores = {}
    for category, keywords in CLASSIFICATION_RULES.items():
        scores[category] = sum(1 for kw in keywords if kw in text)
    # Agent also uses LLM reasoning for ambiguous cases
    return max(scores, key=scores.get) if max(scores.values()) > 0 else "triage"

Stage 2: Assignment

pythonShow code
ASSIGNMENT_MAP = {
    "frontend": "jack-ui",        # Jack's UI sub-agent
    "backend": "thom-backend",    # Thom's backend sub-agent
    "blockchain": "thom-web3",    # Thom's web3 sub-agent
    "infra": "thom-devops",       # Thom's devops sub-agent
    "docs": "thom",               # Thom handles docs directly
}

def assign_issue(classification: str, changed_areas: list) -> str:
    # Detect area from file paths mentioned, or keywords
    for area, agent in ASSIGNMENT_MAP.items():
        if area in changed_areas or area in classification:
            return agent
    return "thom"  # Default: lead agent triages further

Stage 3: Priority Scoring

pythonShow code
PRIORITY_SIGNALS = {
    "P1_blocking": ["blocking", "production down", "can't login", "data loss", "security"],
    "P2_important": ["regression", "broken since", "affects multiple", "workaround needed"],
    "P3_normal": ["would be nice", "minor", "cosmetic", "enhancement"]
}

def score_priority(title: str, description: str) -> str:
    text = f"{title} {description}".lower()
    for priority, signals in PRIORITY_SIGNALS.items():
        if any(signal in text for signal in signals):
            return priority
    return "P3_normal"  # Default: nice-to-have

Stage 4: Duplicate Detection

bashShow code
# Search existing issues for similar titles
glab issue list --search "$(echo $TITLE | head -c 50)" --state opened -o json

The agent compares the new issue against open issues using title similarity and keyword overlap. If similarity exceeds 70%, it links them:

View details
πŸ”— Possible duplicate: This issue looks similar to #47
   ("Login fails after session timeout")
   Similarity: 78% β€” linked for review.

The full output in Telegram:

View details
πŸ“‹ New Issue Triaged: #52
  Title: "Dashboard charts not loading on Safari"
  🏷 Labels: bug, frontend
  πŸ‘€ Assigned: @jack-ui
  πŸ”΄ Priority: P2 (regression β€” worked before)
  πŸ”— Related: None found

  Auto-applied on GitLab. No action needed.

The GitLab labels and assignment are applied via CLI:

bashShow code
glab issue update 52 \
  --label "bug,frontend,P2" \
  --assignee jack-ui

The Results

MetricBefore (Manual)After (Agent)Improvement
Triage time per issue2-3 minutes0 (instant)100% automated
Daily PM triage time15 min/day0 min/day7.5 hours/month saved
Label accuracy75% (human inconsistency)92% (pattern + LLM)+17%
Assignment accuracy80%95%+15%
Duplicate detection rate~20% (caught manually)~80% (auto-linked)4x improvement
Time to first responseHours (waiting for triage)Seconds (auto-assigned)Near-instant

Try It Yourself

Wire a GitLab webhook to your agent. The classification is basic keyword matching enhanced with LLM reasoning for edge cases. Assignment maps are project-specific β€” define yours based on who owns what. Duplicate detection is the highest-value piece: even a simple title-similarity check catches 60% of duplicates.


The best project manager is the one you don't notice. Because the work is already done.

GitLabIssue TrackingAutomationProject ManagementAI Agents

Want results like these?

Start free with your own AI team. No credit card required.

Issue Triage β€” Auto-Label, Auto-Assign, Auto-Prioritize β€” Mr.Chief