Triage Workflow
Multi-issue/PR triage across one or more repositories.
Invocation Parsing
Parse the user’s request to determine:
MODE: analyze (default) | act (if user says "act", "--act", "with actions")
DEPTH: shallow | medium (default) | deep
REPOS: current repo | explicit list | org sweep
FILTER: issues (default: both) | prs | both
Phase 1: Fetch Open Items
Single Repo
REPO="owner/repo" # detected or explicit
# Issues
gh issue list --repo "$REPO" --state open --limit 200 \
--json number,title,state,createdAt,updatedAt,labels,author,body,comments,assignees
# PRs (if included)
gh pr list --repo "$REPO" --state open --limit 200 \
--json number,title,state,createdAt,updatedAt,labels,author,body,headRefName,baseRefName,isDraft,mergeable,reviewDecision,statusCheckRollup,assignees
Org Sweep
ORG="tektoncd" # from "org:tektoncd"
# Find repos with open issues
gh search issues --owner "$ORG" --state open --limit 500 \
--json repository,number,title,state,createdAt,labels,author \
--jq '[.[].repository.nameWithOwner] | unique'
# Then fetch per-repo as above
If results hit the limit (200/500), warn the user and suggest narrowing scope.
Verify Available Labels
gh label list --repo "$REPO" --json name --jq '.[].name' | sort
Store this list — only suggest labels that actually exist on the repo.
Phase 2: Classify
For each item, determine classification based on title, body, labels, and existing context:
Issues
| Classification | Detection Signals |
|---|---|
kind/bug |
“bug”, error messages, stack traces, “unexpected behavior”, “regression”, “panic”, “crash” |
kind/feature |
“feature request”, “proposal”, “enhancement”, “would be nice”, “support for” |
kind/question |
“how to”, “is it possible”, “why does”, “?”, “help”, “documentation” |
kind/flake |
“flaky”, “intermittent”, “sometimes fails”, “race condition” |
kind/cleanup |
“refactor”, “cleanup”, “tech debt”, “remove deprecated” |
kind/documentation |
“docs”, “README”, “typo”, “documentation” |
Priority Heuristics
| Priority | Signals |
|---|---|
critical-urgent |
Data loss, security vulnerability, complete breakage, production outage |
important-soon |
Regression, broken common workflow, affects many users |
important-longterm |
Valid improvement, not blocking anyone right now |
backlog |
Nice to have, low impact |
awaiting-more-evidence |
Not enough info to determine impact |
PRs
| Classification | Detection |
|---|---|
bugfix |
Branch/title starts with fix, fix:, fix(, labels include bug |
feature |
Branch/title starts with feat, feature/, labels include feature |
cleanup |
refactor, chore, cleanup, docs |
dependency |
deps/, dependabot, renovate, dependency update |
Triage Status
| Status | Signals |
|---|---|
triage/needs-information |
Bug report without reproduction steps, missing version info, vague description |
triage/duplicate |
Very similar to another open issue (note: flag but never auto-close) |
triage/support |
User needs help, not a code change |
Phase 3: Investigate (Parallel Subagents)
For medium and deep depth, delegate investigation to subagents.
Agent Selection
| Depth | Agent | Model | What it does |
|---|---|---|---|
| shallow | None | — | Orchestrator classifies from title/body/labels. One-line summary, no codebase search. |
| medium | github-triage-analyzer |
sonnet | Search codebase for relevant files, error messages, symbols. Identify 2-5 relevant files. Draft response if actionable. |
| deep | github-triage-deep |
opus | Trace code paths, git blame, root cause hypothesis with file:line refs, suggest fix approach. |
Batching Strategy
Default limits: 8 parallel tasks, 4 concurrent (configurable in ~/.pi/agent/extensions/subagent/index.ts). Plan accordingly:
- ≤8 items to investigate: single
subagentparallel call - >8 items: split into batches of 8, run sequentially
- >20 items: present shallow classification summary first, ask user which items to investigate at medium/deep
- Items not needing investigation (already well-labeled, shallow depth) skip the subagent entirely
Subagent Delegation
Use pi’s subagent tool with parallel mode. Select agent based on depth:
For each issue to investigate:
subagent: github-triage-analyzer (medium) OR github-triage-deep (deep)
task: |
REPO: {repo}
ISSUE: #{number}
TITLE: {title}
BODY: {body}
COMMENTS: {comments_summary}
LABELS: {existing_labels}
CLASSIFICATION: {our_classification}
Investigate this issue. Search the codebase for relevant code.
Return structured findings.
Phase 4: Aggregate & Report
Triage Report Format
# Triage Report — {repo(s)}
**Date:** {date}
**Mode:** {analyze|act}
**Depth:** {shallow|medium|deep}
**Items processed:** {total} ({issues} issues, {prs} PRs)
## Priority Queue
### 🔴 Critical / Important-Soon
| # | Type | Title | Classification | Suggested Action |
|---|------|-------|---------------|-----------------|
| #N | bug | Title | kind/bug, priority/important-soon | Needs fix: [brief] |
### 🟡 Important-Longterm
| # | Type | Title | Classification | Suggested Action |
|---|------|-------|---------------|-----------------|
### 🟢 Backlog / Awaiting Evidence
| # | Type | Title | Classification | Suggested Action |
|---|------|-------|---------------|-----------------|
## Needs Information (no action possible yet)
| # | Title | What's Missing |
|---|-------|---------------|
## Questions (can be answered from codebase)
| # | Title | Draft Answer Available |
|---|-------|-----------------------|
## Stale Issues (no activity >90 days)
| # | Title | Last Activity | Recommendation |
|---|-------|--------------|----------------|
## PRs Summary
| # | Title | Type | CI | Review | Recommendation |
|---|-------|------|----|--------|----------------|
Detailed Findings
After the summary table, include per-item details for investigated items:
### #{number}: {title}
**Classification:** kind/bug, priority/important-soon
**Assignees:** none
**Existing labels:** [list]
**Suggested labels:** [list of labels to add]
**Analysis:**
{Summary of findings from subagent — relevant code, root cause if found}
**Suggested Action:**
{What to do — label, comment, close, assign, etc.}
**Draft Comment:** (if applicable)
> {Draft comment text ready for posting}
Phase 5: Act Mode (Interactive Approval)
Only in act mode. Present each proposed action one at a time.
Action Types and Approval Flow
Labeling:
Proposed: Add labels [kind/bug, priority/important-soon] to #9438
Current labels: [none]
Apply? [y/n/skip]
Commenting:
Proposed comment on #9423:
---
{full draft comment}
---
Post this comment? [y/n/edit/skip]
If user says “edit”, let them modify the comment before posting.
Closing:
Proposed: Close #1234 as duplicate of #5678
Reason: {explanation}
Close? [y/n/skip]
Execution Commands
# Label
gh issue edit "$NUMBER" --repo "$REPO" --add-label "kind/bug,priority/important-soon"
# Comment
gh issue comment "$NUMBER" --repo "$REPO" --body "$COMMENT"
# Close
gh issue close "$NUMBER" --repo "$REPO" --reason "not planned"
# or
gh issue close "$NUMBER" --repo "$REPO" --reason "completed"
Batch Approval Shortcut
After showing the first few items individually, offer:
Remaining actions are all label-only changes. Apply all? [y/n/review each]
Only offer batch for low-risk actions (labeling). Never batch comments or closes.
Anti-Patterns
| Violation | Why |
|---|---|
| Posting comments in analyze mode | analyze is strictly read-only |
| Auto-closing without approval in act mode | Every close needs explicit approval |
| Suggesting labels that don’t exist on the repo | Always verify with gh label list first |
| Guessing at root causes without code evidence | Only report findings supported by code |
| Closing duplicates without linking | Always reference the duplicate issue |
| Ignoring existing labels | Check what’s already labeled before suggesting |
| Treating issues as one-size-fits-all | Different types need different handling |