| name | triage |
| description | Move todos through a state machine of triage roles — categorise, verify, grill if needed, and write agent-ready briefs. Maps to pi's built-in todo tool; see ../todo-tracker.md for the full tracker → tool mapping. |
| disable-model-invocation | true |
Triage
Move todos through a small state machine of triage roles using pi's todo tool.
All issue-tracker operations use the mapping defined in ../todo-tracker.md.
PR handling is optional and off by default. This is a personal single-user setup; todos
are the primary request surface. If you're also triaging external PRs as issues, see the note
at the bottom of this file.
Every triage note or brief appended to a todo must start with this disclaimer:
> *This was generated by AI during triage.*
Reference docs
Roles
Two category roles — expressed as tags:
bug — something is broken
enhancement — new feature or improvement
Five state roles — expressed as the status field:
needs-triage — maintainer needs to evaluate
needs-info — waiting on reporter for more information
ready-for-agent — fully specified, ready for an AFK agent
ready-for-human — needs human implementation
wontfix — will not be actioned
Every triaged todo should carry exactly one category tag and one state status. If state
conflicts arise, flag it and ask the maintainer before doing anything else.
State transitions: a new todo without a status normally goes to needs-triage first; from
there it moves to needs-info, ready-for-agent, ready-for-human, or wontfix.
needs-info returns to needs-triage once the reporter replies. The maintainer can override
at any time — flag transitions that look unusual and ask before proceeding.
Invocation
The maintainer invokes /triage and describes what they want in natural language. Interpret
the request and act. Examples:
- "Show me anything that needs my attention"
- "Let's look at TODO-abc123"
- "Move TODO-abc123 to ready-for-agent"
- "What's ready for agents to pick up?"
Show what needs attention
Query todos and present three buckets, oldest first:
- Unlabeled — todos with no status set (never triaged).
needs-triage — evaluation requested but not yet completed.
needs-info with reporter activity since the last triage note — needs re-evaluation.
Use todo({ action: "list" }) then filter by status. Show counts and a one-line summary per
item. Let the maintainer pick.
Triage a specific todo
-
Gather context. Read the full todo body and any appended notes. Parse prior triage
notes so you don't re-ask resolved questions. Explore the codebase using the project's
domain glossary, respecting ADRs in the area. Run two checks against the codebase:
(a) redundancy — search for an existing implementation of the requested behavior by
domain concept (not just the request's wording), and report where you looked. If found,
it's an already-implemented wontfix (step 5).
(b) prior rejection — read .out-of-scope/*.md and surface any that resembles this
request.
-
Recommend. Tell the maintainer your category tag and state recommendation with
reasoning, plus a brief codebase summary relevant to the request — including whether it's
already implemented. Wait for direction.
-
Verify the claim. Before any grilling, check that the claim holds up. For a bug,
reproduce it from the reporter's steps. Report what happened: confirmed (with code path),
failed, or insufficient detail (a strong needs-info signal). A confirmed verification
makes a much stronger agent brief.
-
Grill (if needed). If the request needs fleshing out, run the /grill-me and
/domain-modeling skills together — grill it into shape one question at a time, sharpening
domain terms and updating CONTEXT.md/ADRs inline as decisions land.
-
Apply the outcome:
-
ready-for-agent — append an agent brief (AGENT-BRIEF.md):
todo({ action: "append", id: "TODO-xxxx", body: "> *This was generated by AI during triage.*\n\n## Agent Brief\n..." })
todo({ action: "update", id: "TODO-xxxx", status: "ready-for-agent", tags: ["enhancement"] })
-
ready-for-human — same structure as an agent brief, but note why it can't be delegated
(judgment calls, external access, design decisions, manual testing).
-
needs-info — append triage notes (template below):
todo({ action: "append", id: "TODO-xxxx", body: "> *This was generated by AI during triage.*\n\n## Triage Notes\n..." })
todo({ action: "update", id: "TODO-xxxx", status: "needs-info" })
-
wontfix — set status, with the comment depending on why:
- Already implemented — append a note pointing to where it lives; do not write
to
.out-of-scope/ (that KB is for rejected requests, not built ones).
- Rejected (bug) — append a polite explanation.
- Rejected (enhancement) — write to
.out-of-scope/, append a link to it
(OUT-OF-SCOPE.md).
todo({ action: "append", id: "TODO-xxxx", body: "> *This was generated by AI during triage.*\n\n..." })
todo({ action: "update", id: "TODO-xxxx", status: "wontfix" })
-
needs-triage — set status. Append an optional comment if there's partial progress.
Use todo({ action: "update", id: "TODO-xxxx", status: "...", tags: ["bug"] }) to apply
status and tags. Use todo({ action: "append", ... }) for all notes — never use update
for comments, as it overwrites body history.
Quick state override
If the maintainer says "move TODO-abc123 to ready-for-agent", trust them and apply directly.
Confirm what you're about to do (status change, append, etc.), then act. Skip grilling. If
moving to ready-for-agent without a grilling session, ask whether they want to write an
agent brief.
Needs-info template
## Triage Notes
**What we've established so far:**
- point 1
- point 2
**What we still need from you:**
- question 1
- question 2
Capture everything resolved during grilling under "established so far" so the work isn't
lost. Questions must be specific and actionable, not "please provide more info".
Resuming a previous session
Prior triage notes are appended to the todo body. Read them, check whether the reporter has
answered any outstanding questions, and present an updated picture before continuing. Don't
re-ask resolved questions.
Optional: PR handling
If the project treats external PRs as a request surface, a PR is an issue with attached code
— same roles, same states, same machine, with a few deltas:
- For
ready-for-agent, the brief describes what's left to do on the existing diff.
- For
ready-for-human, note why it can't be delegated (e.g. human merge required).
- Discovery surfaces only external PRs; a collaborator's in-flight PR is not triage work.
This filter is discovery-only — an explicitly named PR is always triaged regardless of author.
This mode is off by default. Enable it only if you're explicitly tracking PRs as todos.