Git & GitHubLesson
Issue triage labels
Work an agent can't finish in one session has to wait somewhere a later session will find it. In Terrarium that place is a GitHub issue, and a label on the issue usually says what may happen to it next: wait for more facts, go to an agent, or go to a person.
Know GitHub labels already? Skip to In Terrarium.
Outside the box · General
The concept
A label is a name, a color and a description that you attach to issues, pull requests and discussions. Labels belong to one repository, and once a label exists there, it can go on any issue in that repository. Every new repository starts with a default set, such as bug, enhancement, question and wontfix, which you can edit or delete. Anyone with write access can create, edit or delete a label; anyone with triage access can apply one.
You can filter an issue list by label, so a label can stand for a step in your own workflow, such as "ready to build", and the filter shows the queue for that step. GitHub doesn't know the labels mean that. Nothing stops an issue from carrying two steps at once or none at all, so the rules for moving between steps are yours to write down and keep.
Full referenceGitHub Docs: Managing labels
In Terrarium
Work that has to wait, such as a proposal, a bug or a follow-up, goes in an issue, and the open issues are the work queue. Its states come from the triage of an outside Skill pack (Skill packs), and docs/agents/triage-labels.md maps each to the label string used here and says what it means: needs-triage, for example, means a maintainer must evaluate the issue, ready-for-agent that it is fully specified for an agent working alone, and ready-for-human that it needs a person for a judgment call, a decision or a human merge. The same file says who may set them:
20> **Who sets the state.** Only triage sets `ready-for-agent` and
21> `ready-for-human`: `triage`, `auto-triage`, `clear-backlog` and the guest
22> pipeline. Every other Skill, pack Skills included, files its issues
23> `needs-triage`, however settled they look (`to-spec` and `to-tickets` say
24> `ready-for-agent`; don't apply it), except a spec on hold, which carries no
25> label (`issue-tracker.md`, Specs).
26
27> **Requester-trust gate.** A Public issue reaches `ready-for-agent` only
28> after a Trusted user approves it (ADR-0020), except in the guest pipeline
29> (ADR-0023). What the `auto-triage` sweep may label: ADR-0022.
The triage Skill, in .agents/skills/triage/SKILL.md, also gives each issue one category, bug or enhancement, and expects one category and one state on every triaged issue. Moving an issue to ready-for-agent normally comes with an Agent Brief: a comment that states the behavior wanted and how to tell it is done, without file paths (.agents/skills/triage/AGENT-BRIEF.md).
A person runs triage on the issues they pick. .agents/skills/auto-triage/SKILL.md is the sweep: one unattended pass, started by a person, that applies triage's rules to every open issue and to every open PR from a author, which docs/agents/issue-tracker.md treats as a request. It skips a wayfinder:map, the index issue of a big piece of work that the wayfinder Skill splits into child tickets labelled wayfinder:<type>, and picks the rest by their latest comment:
26For everything else, fetch the **most recent comment** and check who wrote it:
27
28- **No state label, `needs-triage`, or no comments.** Always eligible, whoever
29 filed it or commented last, except an on-hold spec or sub-issue
30 (`docs/agents/issue-tracker.md`'s Specs), which follows the next bullet.
31- **Any other state** (`needs-info`, `ready-for-human`, even `ready-for-agent`)
32 **is eligible when its most recent comment is human-authored.**
33 Every agent comment carries an ADR-0017 mark, so a comment without one is human (`isAiAuthored`). Never go by the author or `author_association`: agents post as the owner.
34
35Skip any other ticket whose most recent comment is already AI's own. That keeps
36repeated sweeps **idempotent**: once an agent answers the human's comment,
37the ticket stays quiet until a human writes again, whatever its label reads.
The mark is the session header every agent post carries (Commit and PR attribution). Run as /auto-triage full-sweep, the sweep drops that skip for one run; the Skill allows that mode only when a person directs it, never on an agent's own choice. The sweep also skips a wayfinder ticket that is claimed or blocked. What it may label and close is in ADR-0022 (docs/adr/0022-autonomous-triage-sweep.md), and Human-in-the-loop agents explains its approvals.
Agents build from the ready-for-agent queue. .agents/skills/clear-backlog/SKILL.md takes the issues a default sweep picks up plus every open ready-for-agent issue. When that set is empty it resolves the set in full-sweep mode instead, counting the owner who started the run as the person directing it. It leaves out any issue with a wayfinder:* label, which the wayfinder Skill drives with the owner, rechecks each ready-for-agent issue before it builds, and carries each to a merged PR, a closed issue or a question for the owner.
Why it's built this way
- The pack's names, unchanged. Pack Skills name the states by role, and each label string here matches its role exactly, so a pack Skill's own wording is already the label to set. The cost: a changed entry in the doc's table is a deliberate divergence, which must not be re-synced from the pack. docs/agents/triage-labels.md
- The label holds the queue, the comment holds the turn. A label says where an issue waits, not whether a person wrote since an agent last answered, and no label query can express that. So the sweep reads every open issue's latest comment and stays quiet once an agent has replied. The cost: each sweep fetches every open issue's comments. .agents/skills/auto-triage/SKILL.md
- The label is the approval. A user approves a build by labelling its issue
ready-for-agent; Human-in-the-loop agents says why, and why a sweep or the guest pipeline may set it without a person per issue. ADR-0003 (docs/adr/0003-agent-operating-model-and-governance.md). - Public issues wait for a person. A Public author's issue goes to
ready-for-humanuntil a Trusted user approves it, since Public text can steer an agent (Author trust gives that reason for Public PRs). The cost: a PR built from it still waits for a person to merge (Protected paths). ADR-0020 (docs/adr/0020-requester-trust-tiers.md).
What to watch for
- A label write replaces the whole set. Setting labels through the GitHub MCP tools sends the full list the issue ends with, so a call that names only the new state drops the category and any
wayfinder:label; docs/agents/github-integration.md lists this trap. - A comment can claim a move that never happened. An agent may write "moved to
ready-for-agent" and fail to change the label. scripts/github/check-triage-drift.ts lists the issues whose most recent agent comment claims a label the issue doesn't carry. It is a command you run yourself. It checks a capped number of open issues, which its argument raises, and knows only a short list of phrasings, so a claim worded another way slips past. - Ready doesn't mean still needed. An issue can wait long enough for other work to solve it, so docs/agents/issue-tracker.md has an agent check for a merged fix before it builds a
ready-for-agentissue. - A missing label doesn't always mean untriaged. An issue with no label is usually one nobody has triaged yet, but a spec on hold carries none either: its body says it is on hold (docs/agents/issue-tracker.md), and the sweep picks it up only when a person wrote its latest comment.
Try it in your project
Create a state label in your repository for each step an issue can wait in, such as needs-triage, needs-info, ready-for-agent and ready-for-human, and write one short doc that says, for each, who may set it and what an agent may do with an issue that carries it. Then tell your agent to take work only from the ready-for-agent filter, and to move an issue it can't finish to needs-info or ready-for-human with a comment that says why.
Where next
- LessonHuman-in-the-loop agents
- LessonAuthor trust
- LessonPull requests
- LessonCommit and PR attribution
- JournalHow Humans & Agents Work
Last updated · Latest source on GitHub ↗