triage
Groom the delivery board — refine acceptance criteria, prioritize bugs, weigh tech debt, archive stale items, restock Todo, escalate cross-team blockers.
Files2
View on GitHubSKILL.mdplugin/skills/workflow/triage/SKILL.md
GitHubTriage
Run the delivery board's backlog grooming ceremony. The board is the state machine: columns Backlog → Todo → Blocked → Active → Completed, item types Task, Bug, Tech Debt. Triage moves items Backlog → Todo (or out of the system) and keeps Todo stocked with the next highest-priority work.
Everything triage learns is written onto the items themselves — the board is the record, not the conversation. Write each note with append_note (short_code, text): one call, no version and no anchor text. A note is not part of the content: get_item shows it after the content under a heading with its id, the date and your name, so the notes stay in time order. Every note starts with:
This was generated by AI during triage.
Invocation
The team lead invokes /kairos:triage and describes what they want in natural language. Interpret and act:
- no arguments, or "groom the backlog" — the full ceremony (below)
- "show me what needs attention" — the attention pass only
- "let's look at <short code>" — triage that one item
- "move <short code> to todo" — quick override
Resolve the board with whoami/my_boards (the user's delivery board) unless the user names one. When the session is wired to a repository (the repository in the SessionStart context), groom the tasks of this board that link to it by default — board_items with repository=<slug> — and say so; the lead can widen to the whole board ("groom everything"). A request with no repository is not in the filtered list. Find it on the whole board: board_items marks it [support lane]. Duplicate searches (search) stay board-wide regardless: a duplicate in another repo is still a duplicate.
Show what needs attention
board_items on Backlog and Blocked (column=Backlog, then column=Blocked), with details: true: each card then shows its priority and the other metadata values, the date of its last change, and its claim. You need no get_item for each card. board_items gives 200 items at most in one result. When the result is a part of the board, its first lines say so and give the offset of the next part. Call board_items again with that offset until you have each part. The counts of a bucket are the counts of all the parts. Present buckets, oldest first, with counts and a one-line summary per item:
- Unrefined — Backlog items without acceptance criteria
- Unprioritized bugs — Bugs without a priority value
- Stale — Backlog items untouched 90+ days
- Blocked — items in Blocked, with what each is waiting on
For a bucket, search gives the answer in one call. Send the board by slug (filter.board). Use filter.metadata_missing for a missing value and filter.updated_before for an age. For the unprioritized bugs that are also stale: {"filter": {"board": "<board>", "task_type": ["bug"], "metadata_missing": ["priority"], "updated_before": "<now minus 90 days, RFC 3339>"}}. list_metadata_definitions gives the slugs and the scale of each definition (the values of priority in their order), and list_templates gives the templates.
Call get_events too: your notifications show the P0 bugs that landed on the board of your team, the tasks of yours that someone cancelled, and the mentions of your name. To mention a person, write @<user name>. list_members gives the user names. Put a P0 bug at the top of the attention list. When the lead has seen them, mark_events_read (ids, or all: true with up_to: the newest id that you read). While you have unread notifications, each answer of a Kairos tool ends with the 5 newest.
Let the lead pick where to start.
Name each item by its short code and the title. Take the column names from the board, not from memory, and translate the lead's words ("ticket", "epic", "sprint") to the Kairos item types: the kairos-vocabulary skill and its ITEM-TYPES.md.
Triage a specific item
- Gather context.
get_itemfor content, metadata, relationships and the prior triage notes (they follow the content), so you don't re-ask resolved questions. Note the item's lane andrepository(get_itemprints both). A request from a different team is in the entry column, in the support lane, and needs no repository. Triage it like any other item; its author owes the answers to "needs info" questions. Check redundancy:searchthe boards for a duplicate item, and search the codebase for an existing implementation of the requested behavior by domain concept, not just the request's wording — report where you looked. - Verify the claim. For a Bug, reproduce it from the reported steps before anything else; report confirmed (with code path), failed, or insufficient detail. For a Task or Tech Debt item, confirm the premise still holds in the codebase.
- Recommend. Give the lead your recommendation — refine toward Todo, needs info, cancel, or archive — with reasoning and a brief summary of what you found in the codebase. Wait for direction.
- Grill if needed. If the item needs fleshing out, run the
grillingskill — sharpen it one question at a time, capturing each answer on the item as it lands. - Apply the outcome (on the item, via
edit_item/set_metadata/transition_item). Ifset_work_class,transition_item,move_itemorcancel_itemis refused withAGENT_TRIAGE_OFF, the board lets a person decide the triage of intake: write the proposal (the outcome below, and why) withappend_noteand move on.- Refined — acceptance criteria written (read ACCEPTANCE-CRITERIA.md first), effort and priority set via
set_metadataon the defined scales (list_metadata_definitionsgives them) — ask the lead once for the scale if the organization defines none; moves to Todo when it's next in line. A refined item that needs code links to exactly one repository.set_repository(short_code,repository) sets the link and changes nothing else. An item with no code, such as support work, needs no repository. Work that spans repos is split into one task per repo joined byblocks/parent edges — never one item that "touches both". - Into the plan — a support request that the team takes into its plan changes lane:
set_work_class(short_code,work_class: planned). It needstransition_itemson the board; the task stays in its column. - Wrong team — an item that belongs to another team's board is moved, never recreated there (recreating loses its history, its edges, and its author):
move_itemwithto_boardtheir delivery board. You needmanage_taskson both boards, so if the tool refuses, say which board it belongs on and ask the lead. The task keeps its repository: the move does not look at it. - Needs info —
append_notethe triage notes: what's established so far, and specific, actionable questions naming who owes the answers. Stays in Backlog; on the next pass, re-read the notes and continue rather than restart. - Cancel — when the lead rejects the item outright ("won't do"):
cancel_itemwith the reason. A cancel needs a reason, and the reason stays on the task; the task goes to the done column, marked Cancelled. If the work comes back later, it is a new task.
- Refined — acceptance criteria written (read ACCEPTANCE-CRITERIA.md first), effort and priority set via
The grooming ceremony
Work the backlog through these actions; the ceremony is done only when every one holds:
- Refine. Every item groomed toward Todo carries acceptance criteria (ACCEPTANCE-CRITERIA.md) and an effort estimate.
- Prioritize bugs. Find each Bug on the board that lacks a priority with one
search(task_type: ["bug"],metadata_missing: ["priority"]), andset_metadataa priority on it, on the scale thatlist_metadata_definitionsgives. P0s are pulled immediately — flagged to the lead in the moment and moved straight to Todo ahead of everything, with expedited acceptance criteria (at minimum the verified reproduction and "no longer reproduces") written as they're pulled; P1–P3 ordered within the backlog. - Weigh tech debt. Tech Debt flows on a standing allocation of roughly 20% of team time — as an item check, about 1 in 5 items across Todo and Active. Under the allocation → propose promoting the highest-value debt items, lead confirms, until the ratio holds; over → hold debt in Backlog.
- Archive stale items. For each Backlog item untouched 90+ days (
searchwithfilter.updated_before= now minus 90 days), propose archival to the lead. On confirmation,append_notea short note recording why it's being archived — durable reasoning, so a returning request meets the recorded decision instead of re-litigation — thendelete_itemwithconfirm: true. This archives the item:restore_itembrings it back, and the note and history stay. Never usepurge_taskfor this: a purge removes the task for good (it is in the admin profile of the MCP tools, not the default). If the lead wants it kept,append_notea parked note with the condition that revives it, and it stays in Backlog. - Clear the done column. When the lead asks,
archive_completedon the board archives each task in its done column (finished and cancelled). Each one can be restored. - Restock Todo. Ask the lead once for the target Todo depth (default: one item per team member), then
transition_itemthe next highest-priority refined items Backlog → Todo until Todo is at depth.
Cross-team blockers
When an item waits on another team: link_items with relationship blocks from the blocking item (theirs) to the blocked item (ours), transition_item ours to Blocked, and append_note an escalation note naming exactly what's needed and from whom — on the item and on its parent initiative, so the blocker is visible at the Initiative Board Review, where cross-team blockers are raised publicly. The blocks edge plus the initiative note is the escalation — there is no side channel.
Quick override
"Move <short code> to todo" — trust the lead. Confirm what you're about to do (transition, metadata, note), then act, skipping the ceremony. If the item is headed to Todo without acceptance criteria, ask whether to write them first.