Automated bug triage from GitHub to prioritized Jira backlog using specialized AI agents.
Transform unstructured GitHub issues into a prioritized Jira backlog in seconds. This system uses three specialized AI agents to analyze, classify, score, and rank bugs automatically.
This system automatically:
- β Fetches bugs from GitHub (canonical/lxd)
- π€ Analyzes each issue using AI agents that read source code
- π·οΈ Classifies component, severity (1-10), and priority (P0-P4)
- π¦ Applies policy gates to determine Jira eligibility
- π Generates properly formatted Jira tickets
- π Ranks issues by criticality for backlog ordering
- π― Creates Jira issues automatically with proper linking
Result: Developers see a prioritized backlog where the first issue is always the most critical.
# In OpenCode, run:
/triage-bugs --limit 10 --epic-key LXD-100That's it! The skill orchestrates everything automatically.
bug-triaging-dev/
βββ agents/ # AI agent definitions
β βββ unified-triage/
β β βββ agent.md # Agent 1: Technical analysis
β βββ jira-decision-gate/
β β βββ agent.md # Agent 2: Policy & ranking
β βββ jira-writer/
β βββ agent.md # Agent 3: Jira payload generation
β
βββ skills/ # OpenCode skills
β βββ bug-triage-workflow/
β βββ skill.md # Orchestrator skill (ONE COMMAND)
β
βββ scripts/
β βββ fetch-lxd-issues.sh # GitHub issue fetcher
β βββ run-pipeline.sh # Pipeline orchestrator
β βββ jira-auth.sh # Jira authentication setup
β βββ jira-create-issue.sh # Jira issue creator (idempotent)
β βββ testdata/issues/lxd-real/ # Downloaded GitHub issues
β
βββ TRIAGE_RESULTS.md # Example triage outputs
βββ SAMPLE_OUTPUTS.md # Agent JSON examples
βββ VIDEO_SCRIPT.md # Video recording guide
βββ README.md # This file
Responsibility: Technical analysis and classification
What it does:
- Reads issue description, logs, and comments
- Searches LXD source code at
/project/git/lxd - Classifies component (storage, networking, compute, etc.)
- Scores severity using 14 dimensions:
- Data loss, system stability, accessibility
- Blocked operations, information integrity
- Networking, storage, security vulnerabilities
- Regressions, upgrade issues, system impact
- Cluster-wide blast radius, workarounds
- Assigns priority (P0-P4)
- Checks issue completeness
Output: JSON with classification, severity score, priority, readiness
Responsibility: Policy enforcement and ranking
What it does:
- Consumes Agent 1 output (never re-reads raw issue)
- Applies hard eligibility rules:
- Must have reproducer
- Must have complete information
- Determines Jira creation requirement:
- All issues with complete information are created in Jira
- Calculates deterministic rank score:
rank_score = 0.60*severity + 0.30*priority + 0.10*confidence
- Provides machine-readable blocking reasons if not eligible
Output: JSON with eligibility decision, rank score, next steps
Responsibility: Jira payload generation
What it does:
- Consumes Agent 1 + Agent 2 outputs
- If
jira_required = false, returns skip with reason - If
jira_required = true, generates complete Jira payload:- Summary: Clean title without prefixes
- Structured description with original GitHub issue + triage analysis table
- Labels:
lxd,triage-bot,automated-triage,priority-p1,severity-7 - Links to Epic
- GitHub link formatted in description with emoji and clickable URL
- Custom fields: component, severity, priority, rank score
Output: JSON with Jira-ready payload (or skip reason)
GitHub Issue (JSON)
β
ββββββββββββββββββββββββββββββββββββββββ
β Agent 1: unified-triage β
β - Reads source code β
β - Classifies component β
β - Scores severity (14 dimensions) β
β - Assigns priority β
ββββββββββββββββββββββββββββββββββββββββ
β (JSON: classification, severity, priority)
ββββββββββββββββββββββββββββββββββββββββ
β Agent 2: jira-decision-gate β
β - Applies eligibility rules β
β - Calculates rank score β
β - Decides: create-jira or need-info β
ββββββββββββββββββββββββββββββββββββββββ
β (JSON: eligibility, rank_score)
ββββββββββββββββββββββββββββββββββββββββ
β Agent 3: jira-writer β
β - Generates Jira payload β
β - Formats description β
β - Sets labels and custom fields β
ββββββββββββββββββββββββββββββββββββββββ
β (JSON: Jira-ready payload)
ββββββββββββββββββββββββββββββββββββββββ
β scripts/jira-create-issue.sh β
β - Idempotent creation β
β - Links to Epic β
β - Returns Jira issue key β
ββββββββββββββββββββββββββββββββββββββββ
β
Jira Backlog (ranked by score)
# In OpenCode terminal
/triage-bugs --limit 20 --bugs-only --epic-key LXD-100What happens:
- Fetches 20 bug issues from GitHub
- Processes each through agents 1β2β3
- Creates Jira issues for eligible bugs
- Shows summary report with ranking
/triage-bugs --limit 10 --dry-runShows what would be created without actually calling Jira API.
# 1. Fetch issues
./scripts/fetch-lxd-issues.sh --limit 5 --bugs-only
# 2. Run agents manually (in OpenCode)
/agent unified-triage
# (provide issue JSON, get triage output)
/agent jira-decision-gate
# (provide triage JSON, get gate decision)
/agent jira-writer
# (provide gate JSON, get Jira payload)
# 3. Create in Jira
./scripts/jira-create-issue.sh --payload output.json --epic-key LXD-100 --confirm# Process all issues in a directory
./scripts/run-pipeline.sh --limit 50 --epic-key LXD-100{
"issue_id": "18150",
"classification": {
"component": "storage",
"confidence": 0.98,
"evidence": [
"lxd/storage/drivers/driver_lvm_utils.go:742"
],
"reasoning": "Bug in LVM driver's thinPoolVolumeUsage() function"
},
"severity": {
"score": 7,
"confidence": 0.90,
"dimensions": {
"data_loss": {"applies": false},
"information_integrity": {"applies": true, "evidence": "Reports 4.85 TiB vs actual 2.87 TiB"},
"storage": {"applies": true, "evidence": "Storage pool reporting affected"},
"no_workaround": {"applies": true}
}
},
"priority": {
"level": "P1",
"points": 4,
"reasoning": "High severity (7) affecting monitoring"
}
}{
"issue_id": "18150",
"jira_gate": {
"jira_eligible": true,
"jira_required": true,
"triage_action": "create-jira",
"blocked_by": []
},
"ranking": {
"rank_score": 0.57,
"severity_norm": 0.50,
"priority_norm": 0.40
}
}ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Bug Triage Workflow Complete β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π Summary:
Total issues processed: 20
Jira created: 12
Skipped/Need info: 8
π·οΈ Component Distribution:
compute: 2
clustering: 2
Storage: 2
api-server: 2
networking: 1
Images: 1
Packaging: 1
projects: 1
π― Priority Distribution:
P1 (High): 3
P2 (Medium): 5
P3 (Low): 2
P4 (Lowest): 2
π Top Priority Issues (by rank_score):
1. #18205 - Replicator fails second run [P1, score: 0.75] β LXD-3918
2. #18187 - EDK2 NX protection breaks guests [P1, score: 0.75] β LXD-3915
3. #18194 - DevLXD socket removed on snap refresh [P1, score: 0.74] β LXD-3916
4. #18204 - Replicator fails remote instances [P2, score: 0.63] β LXD-3917
5. #18132 - OVN ACL selectors fail cross-host [P2, score: 0.62] β LXD-3911
β
Jira backlog ready!
gh auth login
# Follow prompts to authenticatecd /project/git/bug-triaging-dev
./scripts/jira-auth.shYou'll be prompted for:
- Jira base URL (e.g.,
https://your-org.atlassian.net) - Project key (e.g.,
LXD) - User email
- API token (generate at https://id.atlassian.com/manage/api-tokens)
Credentials saved to ~/.config/jira/credentials
./scripts/fetch-lxd-issues.sh \
--limit 50 \
--state all \
--label kind/bug \
--since 2026-05-01 \
--until 2026-05-13 \
--bugs-only \
--out-dir custom/path./scripts/run-pipeline.sh \
--limit 20 \
--bugs-only \
--since 2026-05-01 \
--dry-run \
--epic-key LXD-100/triage-bugs --limit 10 --bugs-only --since 2026-05-01 --epic-key LXD-100 --dry-run
# Ubuntu/Debian
sudo apt install gh
# macOS
brew install gh# Ubuntu/Debian
sudo apt install jq
# macOS
brew install jqgh auth status
gh auth login./scripts/jira-auth.sh- Check filters aren't too restrictive
- Try without
--bugs-only - Widen date range
- Verify GitHub token has repo access
- Check LXD repo exists at
/project/git/lxd - Verify agent definitions in
agents/*/agent.md - Try running single agent manually
Separation of Concerns:
- Agent 1: Technical analysis (reads code, understands bugs)
- Agent 2: Business policy (enforces rules, no technical interpretation)
- Agent 3: Output formatting (generates Jira payloads)
Benefits:
- Each agent has a single responsibility
- Easy to debug (clear JSON contracts)
- Modular (swap agents independently)
- Auditable (see each decision point)
- Deterministic: Same input = same output
- Testable: Can create regression fixtures
- Parseable: Easy to validate and debug
- Portable: Works with any tool/language
Formula: rank_score = 0.60*severity + 0.30*priority + 0.10*confidence
Rationale:
- 60% weight on severity: Technical impact matters most
- 30% weight on priority: Operational urgency matters
- 10% weight on confidence: Penalize uncertain classifications
- Deterministic: Same scores always rank the same
- Explainable: Can show why issue X ranks above Y
TRIAGE_RESULTS.md- Real triage results from 8 issuesSAMPLE_OUTPUTS.md- Agent JSON examples
agents/unified-triage/agent.md- Component taxonomy, severity rubricagents/jira-decision-gate/agent.md- Policy rules, ranking formulaagents/jira-writer/agent.md- Jira formatting standards
scripts/fetch-lxd-issues.sh- GitHub API integrationscripts/jira-create-issue.sh- Jira REST API v3 usagescripts/run-pipeline.sh- Orchestration pattern
- Better formatting of the issues
- Link to the GH bug link
- Go implementation
- Autoassign issues
- CI/CD integration (auto-triage on new issues)
- Jira backlog auto-reordering via API
- Mattermost notifications for P0/P1 bugs
- Dashboard with triage metrics
Built for AI Agents Hackathon 2026
Technologies:
- OpenCode (AI agent orchestration)
- Claude Sonnet 4.5 (LLM)
- GitHub CLI (issue fetching)
- Jira REST API v3 (ticket creation)
Ready to triage some bugs? Run /triage-bugs --help in OpenCode! π