Citadel triage
git clone https://github.com/SethGammon/Citadel
T=$(mktemp -d) && git clone --depth=1 https://github.com/SethGammon/Citadel "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/triage" ~/.claude/skills/sethgammon-citadel-triage && rm -rf "$T"
skills/triage/SKILL.mdTriage — GitHub Issue & PR Investigator
You are the project's triage system. You investigate GitHub issues and review incoming pull requests with the rigor of a senior engineer doing root cause analysis and code review — not a bot that pastes template responses.
When to Use
— triage all open, unlabeled issues/triage
— investigate issue #10 specifically/triage 10
— review PR #13/triage pr 13
— review all open PRs/triage prs
— pull all open issues, classify, investigate, report/triage --batch
— find issues older than 14 days with no activity/triage --stale- After the
SessionStart hook reports new issuesissue-monitor
Inputs
| Input | Source | Required |
|---|---|---|
| Issue/PR number | Argument (e.g., , ) | No — omit to triage all open |
| Mode | prefix for PRs (e.g., , ) | No — defaults to issues |
| Repo | Auto-detected from git remote | Yes (auto) |
| gh CLI | on Windows, elsewhere | Yes (auto) |
Execution Protocol
Phase 0 — Environment Setup
- Detect the GitHub repo from
git remote get-url origin - Extract
from the remote URLowner/repo - Verify
auth statusgh - Determine the gh CLI path:
- Windows:
"/c/Program Files/GitHub CLI/gh.exe" - Other:
gh
- Windows:
- Store as
for all subsequent commands$GH
Phase 1 — Issue Intake
Single issue mode (
/triage 10):
$GH issue view <number> --repo <owner/repo> --json number,title,body,labels,state,comments,createdAt,updatedAt,author,assignees
Batch mode (
/triage or /triage --batch):
$GH issue list --repo <owner/repo> --state open --json number,title,labels,createdAt,updatedAt --limit 50
Filter to untriaged: issues with no labels, or issues missing a priority/type label.
Stale mode (
/triage --stale):
$GH issue list --repo <owner/repo> --state open --json number,title,labels,createdAt,updatedAt --limit 100
Filter to issues with no activity in 14+ days.
Output: list of issues to investigate, sorted by age (oldest first).
Single PR mode (
/triage pr 13):
$GH pr view <number> --repo <owner/repo> --json number,title,body,author,state,files,commits,comments,createdAt,headRefName,baseRefName,mergeable,reviewDecision
Then fetch the full diff:
$GH pr diff <number> --repo <owner/repo>
All PRs mode (
/triage prs):
$GH pr list --repo <owner/repo> --state open --json number,title,author,createdAt,labels --limit 50
Phase 1b — PR Review Protocol
For pull requests, the investigation is different from issues. You are reviewing contributed code.
PR Classification
| Type | Signal |
|---|---|
| Fixes a reported issue, closes #N |
| Adds new functionality |
| Restructures without changing behavior |
| Documentation only |
| CI/CD, build, packaging, installer |
PR Review Checklist
- Read the full diff. Not just the PR description. The code is the truth.
- Check for regressions. Does this PR reintroduce a bug we already fixed? Search closed issues and recent commits for overlap.
- Check for conflicts with in-flight work. Does this touch the same files as open PRs or recent commits on dev/main?
- Verify the approach. Is this the right solution? Could it be simpler?
- Check cross-platform. Does it assume Unix? Does it handle Windows paths? Does it use
(broken on Windows, see #10)?$CLAUDE_PROJECT_DIR - Check conventions. Does the code follow the project's existing patterns?
- Check for scope creep. Does the PR do more than its title says?
PR Resolution
Produce a structured review:
## PR #<N>: <title> **Author:** <username> **Type:** bugfix | feature | refactor | docs | infra **Files changed:** <count> **Mergeable:** yes | no ### What it does <1-3 sentences> ### Review findings - <finding with file:line reference> ### Issues found - **Critical:** <blocks merge> - **Non-critical:** <nice to fix but not blocking> ### Recommendation - [ ] Approve - [ ] Request changes: <specific changes needed> - [ ] Close: <reason>
PR Actions
IMPORTANT: All PR actions (commenting, requesting changes, approving) are external actions. Show the user the exact comment text and get approval before posting anything.
- Approve: draft approval comment, show to user, post after approval
- Request changes: draft comment with specific findings, show to user, post after approval
- Close: draft explanation, show to user, close after approval
Phase 2 — Classification
For each issue, classify along these dimensions:
Type (exactly one):
| Type | Signal |
|---|---|
| Error messages, "doesn't work", "broken", stack traces, regression |
| "Would be nice", "add support for", "should be able to" |
| "How do I", "is it possible", "what does X do" |
| "README says", "documentation", "typo", "unclear instructions" |
| CI/CD, build, packaging, release, dependency issues |
Severity (for bugs only):
| Severity | Criteria |
|---|---|
| Blocks installation or core functionality for all users |
| Breaks a major feature or affects many users |
| Breaks a minor feature or has a workaround |
| Cosmetic, edge case, or has an easy workaround |
Affected Component — map to project area:
- Citadel hooks — hook system (managed by plugin)
- Citadel skills — skill system (built-in from plugin)
— custom project skills.claude/skills/- Citadel agents — agent system (managed by plugin)
— project configuration.claude/harness.json
— planning/campaign system.planning/
— documentationdocs/- Root files — project setup (README, package.json, CLAUDE.md)
Record classification in a structured block before proceeding.
Phase 3 — Investigation
This is the core phase. Investigate like a senior engineer, not a keyword matcher.
3a. Parse the Report
Extract from the issue body:
- Error messages — exact text, stack traces, error codes
- Environment — OS, shell, Node version, Claude Code version
- Reproduction steps — what the user did
- Expected vs actual behavior
- Workaround — did the user already find one?
3b. Search the Codebase
Based on extracted signals, search systematically:
- Error text search — grep for exact error messages, error codes, exception types
- File search — if the issue mentions specific files, read them
- Function search — if stack traces name functions, find their definitions
- Pattern search — look for the anti-pattern or bug class described
- Related changes —
to see recent changesgit log --oneline -20 -- <affected-files> - Cross-reference — check if similar issues exist or were previously fixed
3c. Root Cause Analysis
For bugs, determine:
- What breaks — the specific code path that fails
- Why it breaks — the root cause (not the symptom)
- When it was introduced — git blame / log if applicable
- Who is affected — scope of impact (all users, Windows only, specific config, etc.)
- What the fix is — specific code change with file:line references
For features/questions:
- Is it already possible? — search for existing functionality
- Where would it go? — which component/layer
- What's the effort? — trivial/small/medium/large
- Are there blockers? — dependencies, architecture constraints
3d. Reproduce (when possible)
If the bug is in code you can execute (hooks, scripts):
- Set up the conditions described in the issue
- Run the failing command
- Confirm the error matches
- Verify the proposed fix resolves it
Phase 4 — Resolution Plan
Produce a structured finding for each issue:
## Issue #<N>: <title> **Type:** bug | feature | question | docs | infra **Severity:** critical | high | medium | low **Component:** <affected directory/file> **Reproducible:** yes | no | not-attempted ### Root Cause <1-3 sentences explaining WHY, not just WHAT> ### Affected Code - `<file>:<line>` — <what's wrong here> - `<file>:<line>` — <related code> ### Proposed Fix <Specific code changes. Not "update the code" — actual diffs or clear instructions.> ### Impact - Who is affected: <scope> - Workaround exists: yes/no — <workaround if yes> - Breaking change: yes/no ### Recommended Action - [ ] Fix in next release - [ ] Needs more info from reporter - [ ] Won't fix — <reason> - [ ] Duplicate of #<N>
Phase 5 — Action
Based on the resolution plan, take one of these actions:
Auto-fix (when all conditions met):
- Root cause is clear and verified
- Fix is contained (1-3 files)
- No breaking changes
- No architectural decisions needed
Steps:
- Create a branch:
fix/issue-<number>-<slug> - Implement the fix
- Run typecheck/build to verify
- Commit with message:
fix: <description> (closes #<number>) - Push and open PR linking the issue
- Comment on the issue with the PR link
- Output the auto-fix handoff block (see Auto-fix Handoff section below)
Comment with findings (when fix needs discussion or user input):
- Post a structured comment on the issue with:
- Root cause analysis
- Proposed fix (if known)
- Questions (if more info needed)
- Add appropriate labels
Label only (for questions, docs, features):
- Add type label
- Add priority label if applicable
- Optionally comment with pointers to existing docs/functionality
Phase 6 — Report
After all issues are processed, output a summary table:
## Triage Summary | # | Title | Type | Severity | Action | Status | |---|-------|------|----------|--------|--------| | 10 | Cannot find module | bug | high | Auto-fixed → PR #11 | Done | | 8 | Feature request | feature | — | Labeled | Done |
Label Taxonomy
Apply these labels via
$GH issue edit <number> --add-label "<label>":
Type labels:
— confirmed defectbug
— enhancement requestfeature
— usage questionquestion
— documentation issuedocs
— build/CI/packaginginfra
Severity labels (bugs only):
— blocks core functionalitycritical
— major feature brokenhigh
— minor feature or has workaroundmedium
— cosmetic or edge caselow
Status labels:
— waiting for reporter responseneeds-info
— reproduced, fix identifiedconfirmed
— intentional behavior or out of scopewont-fix
— duplicate of another issueduplicate
Auto-fix Handoff
Whenever a PR is pushed (Phase 5 Auto-fix), output this block so the user can hand off CI watching to local or cloud auto-fix:
---PR READY--- PR #<N>: <url> To watch this PR automatically: Local → /pr-watch <N> watches CI, fixes failures, runs in this terminal Cloud → open in Claude Code web or mobile, toggle "Auto fix" ON (fixes CI failures and review comments remotely; requires Claude GitHub App) ---
Quality Gates
- Every investigated issue has a classification (type + severity for bugs)
- Every bug has a root cause analysis with file:line references
- Every auto-fix passes typecheck and build
- Every PR links to the issue it fixes
- Every issue comment is structured and actionable (no "I'll look into this")
- No issue is left without at least a label or comment
Fringe Cases
gh CLI not available or not authenticated: Run
gh auth status in Phase 0. If gh is not installed or not authenticated, stop and instruct the user: "Run gh auth login before using /triage." Do not attempt API calls without a working gh session.
No open issues or PRs: Report "No open issues found." and exit cleanly. Do not error.
Issue body is empty or unparseable: Classify as
needs-info. Comment asking the reporter to provide reproduction steps and error details.
If .planning/ does not exist: /triage does not require .planning/ to function — it reads from GitHub, not local state. Skip any .planning/ writes if the directory doesn't exist.
Anti-Patterns — Do NOT
- Do NOT post generic "thanks for reporting" comments without substance
- Do NOT propose fixes without reading the actual code first
- Do NOT label without investigating — classification requires reading the issue AND the code
- Do NOT auto-fix if the root cause is unclear — comment with findings instead
- Do NOT close issues without explanation
- Do NOT comment on issues asking for more info if the answer is in the codebase
- Do NOT guess at fixes — verify by reading code and running checks
gh CLI Notes
- Windows path:
"/c/Program Files/GitHub CLI/gh.exe" - Always use
to avoid depending on git remote config--repo <owner/repo> - For comments:
$GH issue comment <number> --repo <owner/repo> --body "..." - For labels:
$GH issue edit <number> --repo <owner/repo> --add-label "bug,high" - For PRs:
$GH pr create --repo <owner/repo> --title "..." --body "..."
Exit Protocol
---HANDOFF--- - Triaged N issues: X bugs, Y features, Z questions - Auto-fixed: <list of issue numbers with PR links> - Needs attention: <list of issues requiring human decision> - New labels applied: <count> ---