How the triage-issue Skill Uses JQL for Duplicate Bug Detection in Jira

The triage-issue skill dynamically constructs three targeted JQL queries—focusing on error signatures, components, and symptoms—to search for potential duplicates, then scores and merges results from the searchJiraIssuesUsingJql helper to identify existing bugs with high confidence.

The triage-issue skill, part of the atlassian-rovo plugin in the openai/plugins repository, automates duplicate bug detection by leveraging Jira Query Language (JQL) to search across existing issues. Instead of relying on a single static query, the skill extracts keywords from incoming bug reports and injects them into three distinct JQL templates, maximizing recall while maintaining precision through intelligent scoring.

Dynamic JQL Construction Workflow

The skill implements a multi-stage pipeline defined in plugins/atlassian-rovo/skills/triage-issue/SKILL.md. It never hard-codes complete JQL strings, instead using runtime interpolation to adapt queries based on the specific bug report content.

Keyword Extraction from Bug Reports

First, the skill parses the incoming bug report to extract three critical elements:

  • Error signature: The specific error text or stack trace identifiers
  • Component keywords: Subsystem or module references (e.g., "authentication", "database")
  • Symptom description: User-visible problem statements (e.g., "login fails")

According to the skill definition in SKILL.md (lines 29-38), this extraction happens via natural-language parsing before any JQL construction begins.

Three-Angle JQL Templates

The skill prepares three distinct query templates to search from complementary angles, as documented in lines 69-95 of SKILL.md:

  • Error-focused: Targets exact error text even when component phrasing differs
  • Component-focused: Finds issues referencing the same subsystem regardless of error phrasing
  • Symptom-focused: Surfaces tickets describing the same user-visible problem even without matching error codes

Each template uses placeholder tokens like "error signature" or "component keywords" that get replaced at runtime with the extracted keywords.

Executing Searches with searchJiraIssuesUsingJql

For each constructed JQL string, the skill invokes the generic helper function:

searchJiraIssuesUsingJql(
    cloudId=cloud_id,
    jql=interpolated_query,
    fields=["summary", "description", "status", "resolution", 
            "created", "updated", "assignee"],
    maxResults=20
)

This API signature appears throughout the skill definition (lines 69-94), consistently requesting a concise field set to minimize payload size while capturing essential duplicate-detection context.

The Three-Query Strategy Explained

Using multiple queries ensures high recall across different bug description styles:

  • Error-focused queries prioritize created DESC to surface recent instances of the same crash signature
  • Component-focused queries use updated DESC to find actively worked issues in the same subsystem
  • Symptom-focused queries order by priority DESC, updated DESC to highlight severe, recently touched tickets that match the user-reported symptoms

Each query targets type = Bug and restricts results to the specified project, ensuring relevant scope.

Code Implementation: Building and Executing JQL Queries

Below is a Python representation mirroring the skill's runtime logic, showing how extracted keywords populate the JQL templates before calling the Jira search API:

def build_triaging_queries(project_key, error_kw, component_kw, symptom_kw):
    """Construct the three JQL queries used for duplicate detection."""
    
    # Error-focused: Catch exact error text regardless of component wording

    error_jql = (
        f'project = "{project_key}" AND '
        f'(text ~ "{error_kw}" OR summary ~ "{error_kw}") '
        f'AND type = Bug ORDER BY created DESC'
    )
    
    # Component-focused: Find same subsystem, different error phrasing

    component_jql = (
        f'project = "{project_key}" AND '
        f'text ~ "{component_kw}" AND type = Bug '
        f'ORDER BY updated DESC'
    )
    
    # Symptom-focused: Match user-visible problems, flexible on error codes

    symptom_jql = (
        f'project = "{project_key}" AND '
        f'summary ~ "{symptom_kw}" AND type = Bug '
        f'ORDER BY priority DESC, updated DESC'
    )
    
    return error_jql, component_jql, symptom_jql


def detect_duplicates(cloud_id, project_key, extracted_keywords):
    """Execute searches and aggregate results for duplicate detection."""
    queries = build_triaging_queries(
        project_key,
        extracted_keywords["error"],
        extracted_keywords["component"],
        extracted_keywords["symptom"]
    )
    
    all_results = []
    for jql in queries:
        results = searchJiraIssuesUsingJql(
            cloudId=cloud_id,
            jql=jql,
            fields=["summary", "description", "status", "resolution",
                    "created", "updated", "assignee"],
            maxResults=20
        )
        all_results.extend(results)
    
    return all_results

The actual skill executes this logic within the OpenAI function-call flow defined in plugins/atlassian-rovo/skills/triage-issue/agents/openai.yaml.

Result Scoring and Aggregation

After retrieving results from all three queries, the skill merges the datasets and calculates confidence scores based on criteria defined in SKILL.md (lines 20-36):

  • Exact error match: Higher weight when error signatures align
  • Component overlap: Verification that the subsystem matches
  • Recency: Preference for recently created or updated issues
  • Status: Consideration of resolution state (open vs. closed duplicates)

The system categorizes findings as high-confidence duplicates, likely duplicates, related issues, or new problems, then formats the top matches using presentation templates starting at line 64 of SKILL.md.

Key Source Files

The triage-issue skill implementation spans these files in the openai/plugins repository:

Summary

  • The triage-issue skill uses three distinct JQL queries (error, component, and symptom-focused) to maximize duplicate detection recall
  • Keywords are dynamically interpolated into templates at runtime rather than using static queries
  • The searchJiraIssuesUsingJql helper retrieves essential fields (summary, description, status, assignee, timestamps) for comparison
  • Results are merged and scored based on exact matches, component overlap, recency, and status to determine confidence levels
  • All JQL logic and scoring rules are defined in SKILL.md within the openai/plugins repository

Frequently Asked Questions

What specific JQL fields does the triage-issue skill retrieve?

The skill requests seven specific fields via the fields parameter in searchJiraIssuesUsingJql: summary, description, status, resolution, created, updated, and assignee. This minimalist field set, defined in lines 69-94 of SKILL.md, provides sufficient context for duplicate comparison while keeping API payloads efficient.

The scoring system weighs four factors: exact error signature matches carry the highest weight, followed by component overlap, ticket recency (preferring newer issues), and current status. According to lines 20-36 of SKILL.md, results crossing specific confidence thresholds classify as "high-confidence duplicates" or "likely duplicates," while partial matches are flagged as "related issues."

Can developers customize the JQL templates for specific project requirements?

While the templates are embedded in SKILL.md (lines 69-95), the skill architecture supports modification because the JQL strings use placeholder-based interpolation. Developers can adjust the base templates—changing operators like ~ (contains) to = (equals) or modifying ORDER BY clauses—within the skill definition, though the openai.yaml agent configuration must remain synchronized with any new parameters.

Where is the searchJiraIssuesUsingJql function implemented?

The function appears as a callable action in plugins/atlassian-rovo/skills/triage-issue/agents/openai.yaml, where it is mapped to the OpenAI function-call interface. The actual Jira API wrapper implementation resides in the broader atlassian-rovo plugin infrastructure, while the skill itself focuses on JQL construction and result interpretation in SKILL.md.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →