Triage
Triage a newly opened issue on the project issue tracker, unattended. This skill runs
inside the triage GitHub Action (triggered by issues: opened) — there is no human
in the loop and no interactive turn. You act on exactly one issue, decide, apply the
issue type and one state label with gh, and write a single comment. You never wait for
or ask a maintainer: if a human is needed, mark the issue appropriately
(ready-for-human, needs-info, or needs-triage) and stop — a maintainer will take
it from there.
Applying the decision is mandatory and verified. After this skill runs, the Action
checks that the issue ends up with an issue type set and exactly one state label. If
either is missing, the triage job fails — so you must run the gh commands below,
not just describe your decision in the comment. See Applying the
decision for the exact commands.
Your final assistant message is the issue comment — the Action posts it as-is. It must start with this exact disclaimer line:
> *This was generated by AI during triage.*
and contain only the comment — no preamble, no "done" summary, no narration of the
steps you took. Do not post it yourself with gh issue comment (that duplicates
it). A follow-up step strips any stray text before the disclaimer as a safety net, but
do not rely on that — write it clean.
Reference docs
- AGENT-BRIEF.md — how to write durable agent briefs
- OUT-OF-SCOPE.md — how the
.out-of-scope/knowledge base works
Roles
Set the category as the GitHub issue type (not a label). The org has exactly these issue types — use one of these names exactly:
Bug— something is brokenFeature— a new feature or improvementTask— chore/maintenance work that is neither a bug nor a user-facing feature
Apply exactly one state label:
needs-triage— a maintainer needs to evaluate (use when genuinely ambiguous)needs-info— waiting on the reporter for more informationready-for-agent— fully specified, ready for an AFK agentready-for-human— needs human implementation (judgment calls, external access, design decisions, manual testing)wontfix— will not be actioned (only for obvious, clear-cut cases; see below)
Every issue you triage must end up with exactly one category (issue type) and one state label. The state names above are the actual label strings used on the tracker.
Applying the decision
Run these before (or after) writing your comment. The Action verifies the result and fails the job if the type or state label is missing.
Issue type — issue types are not labels, so set the type via the REST API (this
works regardless of the runner's gh version):
gh api --method PATCH "repos/$GITHUB_REPOSITORY/issues/<number>" -f type='Bug'
Use Bug, Feature, or Task for type. The <number> is this issue's number.
State label — apply exactly one:
gh issue edit <number> --add-label "ready-for-agent"
A freshly opened issue has no state label, so --add-label alone is correct. Only on a
manual re-triage of an issue that already carries a different state label, remove the
old one in the same command, e.g. --remove-label "needs-triage". Never leave two
state labels on an issue.
Procedure
Gather context. Read the full issue (body, comments, labels, author, dates). Explore the codebase using the project's domain glossary, respecting ADRs in the area. Run two checks: (a) redundancy — search for an existing implementation of the requested behavior by domain concept (not just the request's wording). (b) prior rejection — read
.out-of-scope/*.mdand note any that resembles this request.Verify the claim. For a bug, reproduce it from the reporter's steps where cheap. Report what happened: confirmed (with code path), failed to reproduce, or insufficient detail (a strong
needs-infosignal). A confirmed verification makes a much stronger agent brief.Decide, apply, and comment. Pick the category and state, apply them with the
ghcommands from Applying the decision, then write your triage comment as your final assistant message — the triage action posts that message as the single issue comment. Do not callgh issue commentyourself (that duplicates it). Your final message must start with the AI disclaimer and contain only the comment — no preamble, no "I've completed triage" summary, no restating the steps you took. Pick the safest defensible outcome:- Well-specified and actionable →
ready-for-agent; the comment must contain a## Agent Briefsection built from the template in AGENT-BRIEF.md (Category, Summary, Current behavior, Desired behavior, Key interfaces, Acceptance criteria, Out of scope). Describe behavior and interfaces — never cite file paths or line numbers inside the brief; they go stale before an agent picks the issue up. You may cite one code location in a separate verification note (step 2) to prove the repro, but the brief itself stays behavioral. - Actionable but needs human judgment →
ready-for-human; write the same## Agent Briefstructure and note why it can't be delegated. - Underspecified →
needs-info; post the Needs-info template with specific, answerable questions. This is the terminal action — do not attempt a back-and-forth. - Obviously won't be actioned →
wontfix; post your reasoning but do not close the issue — a maintainer reviews and closes. Only use this for clear-cut cases: the behavior already exists in the codebase (point to where it lives), the request matches a documented prior rejection in.out-of-scope/, or it's plainly out of scope / spam. If there's any real doubt, useneeds-triageinstead. - Genuinely ambiguous →
needs-triage, and explain what you were unsure about.
- Well-specified and actionable →
Hard limits
- Never wait for or ask a human. Decide from what's in front of you.
- Always apply the issue type and exactly one state label with the
ghcommands in Applying the decision. The Action verifies this and fails the job if either is missing — describing the decision only in the comment is not enough. - One comment only, and it is your final assistant message. Never call
gh issue comment— the action posts your final message as the comment, so posting it yourself creates a duplicate. No multi-comment threads, and no chatter wrapped around the comment (the whole final message is the comment). The message must start with the disclaimer line. - Never write repo files. Do not modify
CONTEXT.md, ADRs, or.out-of-scope/from the action — those need a human-reviewed commit/PR. Put recommendations in the comment instead. - Never close issues. Closing is always left to a maintainer.
Needs-info template
## Triage Notes
**What we've established so far:**
- point 1
- point 2
**What we still need from you (@reporter):**
- question 1
- question 2
Questions must be specific and actionable, not "please provide more info".