Playbooks · Coding agents
Triage a backlog of issues with an agent
A small team works through a pile of open issues with Copilot Chat and the GitHub CLI: every issue ends labelled, assigned, or closed with a reason.
Audience: Small team · Stack: A GitHub repo with a backlog of open issues, GitHub CLI installed and authenticated · Tool: GitHub CLI plus GitHub Copilot Chat for drafting triage notes
Before you start
- A shared triage bar, written down: what counts as a bug, what counts as a request, what gets closed as out of scope, and which labels your repo actually uses. Triage without a bar is just relabelling at random.
- The GitHub CLI installed and authenticated, and Copilot Chat available for drafting notes. No other tooling is required for this playbook.
- A time box for the session and a batch size — for example, twenty issues — so triage ends with a done batch rather than an endless scroll.
- One person deciding, even if the agent drafts. Two triagers applying different bars recreate the backlog in labelled form.
Steps
- List the open backlog with
gh issue list --state open, and narrow it with the filters the CLI supports, for examplegh issue list --label bugorgh issue list --assignee @me. Work from the list, oldest first, not from memory of which issues feel urgent. - For each issue, read it in full with
gh issue view NUMBERbefore judging it. Skimmed triage is how real bugs get closed and vague requests get prioritised. - Draft a triage note for the issue in Copilot Chat, grounded in the issue text: what the reporter actually describes, what is missing for anyone to act on it, and which of your labels fits. Treat the draft as a suggestion — check it against the issue before using any of it.
- Apply the decision with the CLI. Add a label with
gh issue edit NUMBER --add-label "label-name", assign it withgh issue edit NUMBER --add-assignee @me, or hand a well-specified bug to Copilot as a coding agent withgh issue edit NUMBER --add-assignee "@copilot", both forms documented in the GitHub CLI manual. Several issue numbers can be passed to one edit command when the same change applies to all of them. - If an issue is a duplicate, link it to the original in a comment with
gh issue comment NUMBER --body "Duplicate of #ORIGINAL", then close it withgh issue close NUMBER --comment "Closing as a duplicate of #ORIGINAL". The comment forms are documented in the CLI manual; the duplicate judgement itself is yours. - If an issue cannot be acted on, comment asking for the one missing piece — a reproduction, a version, an example — and label it as waiting. Do not close an issue for missing information without saying what is missing.
- At the end of the batch, re-run
gh issue list --state openand count what changed: how many labelled, assigned, closed, and left waiting. Record those four numbers. A triage session that cannot report them did not finish.
Worked example
A small team faces sixty open issues and time-boxes a session to the twenty oldest. The list shows a crash report with steps to reproduce, a feature request with no use case, and three reports of the same login error. The crash report is labelled as a bug and assigned to a teammate; the feature request gets a comment asking for the use case and a waiting label; the three login reports are linked to the earliest one, and the two later ones are closed as duplicates with a comment naming the original. One well-specified crash is assigned to @copilot for a fix attempt. The session ends with the four numbers: twelve labelled, four assigned, three closed, one waiting — and forty issues still open, honestly counted, for the next session.
What can go wrong
- The agent's draft misreads the issue and you apply its label anyway. Fix: read the issue first, every time. The draft is a starting point, and the list order exists so nothing is judged from its title alone.
- Labels multiply because each issue gets a new one. Fix: stop and use only labels that already exist, or agree the new label with the team first. A label used once is not a category.
- Issues are closed to make the numbers look good. Fix: reopen them. A closed issue with no reason recorded is a lost report, and the count of closed issues is not a quality measure.
- The batch never ends because new issues arrive during triage. Fix: triage the frozen list from the start of the session. New arrivals belong to the next batch.
Limits
- An agent can draft a triage note; it cannot decide your priorities, your scope, or whether a report is real. Those judgements are the team's, and this playbook keeps them there.
- Assigning an issue to Copilot starts a fix attempt; it does not guarantee a fix, and the resulting work still needs human review before it merges.
- Triage sorts a backlog; it does not shrink the work in it. A well-triaged backlog with no one to do the work is still a backlog, just a tidier one.
Time and cost: NOT_MEASURED. This page gives no time or cost figure because the tool docs fetched for it state none that applies to this task.
Verification
Checked 2026-10-23 against the author's own docs. The workflow on this page was not run end to end; every command, flag, and capability claim was checked against an author doc or repo fetched that day.
- https://cli.github.com/manual/gh_issue_edit
- https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/editing-an-issue
- https://docs.github.com/en/copilot/reference/chat-cheat-sheet
Cut from this page, with reason:
- No automation or scheduled triage: the CLI commands used are one-shot commands from the author manual, and no scheduled workflow is claimed.
- No claim that Copilot reads issues directly in this flow: the drafting step uses Copilot Chat on issue text the human supplies.
- No time or cost figure: NOT_MEASURED.
If a step here does not match what your installed tool shows, trust the tool's own docs for your version and stop before approving a change you cannot read.
Back to: Coding playbooks hub · Skills index
Also: Small-team hub