| name | github-issues |
| description | File, triage, or label a GitHub issue in this repo the way we do it — apply an issue TYPE (Bug/Feature/Task) and the right LABELS. Use whenever creating, editing, triaging, or bulk-labeling issues, or when adding/renaming/removing a label. Covers the "Bug is a type not a label" gotcha, the gh-can't-set-type gotcha, and the version-controlled label taxonomy in .github/labels.yml. |
Filing & triaging GitHub issues
This repo classifies issues on two independent axes. Set both.
- Issue type —
Bug · Feature · Task. Org-level metadata, exactly
one per issue. This is not a label.
- Labels — the taxonomy in
.github/labels.yml (area, status, kind…).
Zero or more per issue.
The single most common mistake: treating Bug as a label. There is no
bug label — Bug is an issue type. Applying a nonexistent label
silently no-ops, so the issue ends up classified as nothing.
Issue types
| Type | Use for |
|---|
Bug | An unexpected problem or behavior |
Feature | A request, idea, or new functionality |
Task | A specific, scoped piece of work (the default) |
Pick one on every new issue. When unsure between Task and Feature:
user-facing capability → Feature; internal/dev work (refactor, CI, deps,
tests, docs tooling) → Task.
Setting the type
GitHub MCP tools (web / remote sessions — the easiest path).
issue_write takes the type by name in the same call that creates the
issue:
mcp__github__issue_write(
method="create", owner="digitalgroundgame", repo="pragmatic-papers",
title="…", body="…",
type="Bug", # ← by name, no node ID needed
labels=["documentation"], # ← best-guess kind/status label(s) at filing time
)
To set/change the type on an existing issue, call the same tool with
method="update", issue_number=<n>, type="Bug".
gh CLI (local dev). gh issue create on older gh (≤ ~2.45) has
no --type flag — this is the historical reason the agent skipped it.
Handle it by gh version:
-
Modern gh (≈ 2.63+): gh issue create --type Bug --label documentation …
-
Older gh: create first, then set the type with a GraphQL mutation.
Look the type's node ID up by name at runtime (don't paste a stale ID):
ORG=digitalgroundgame
TYPE_ID=$(gh api graphql -f query='
query($org:String!){ organization(login:$org){
issueTypes(first:20){ nodes { id name } } } }' -f org="$ORG" \
--jq '.data.organization.issueTypes.nodes[] | select(.name=="Bug") | .id')
ISSUE_ID=$(gh issue view <number> --json id -q .id)
gh api graphql -f query='mutation($id:ID!,$type:ID!){
updateIssue(input:{id:$id, issueTypeId:$type}){ issue { number issueType { name } } } }' \
-f id="$ISSUE_ID" -f type="$TYPE_ID"
Known node IDs at time of writing (convenience only — prefer the lookup
above, which can't go stale): Task IT_kwDODO7WPM4BogHl ·
Bug IT_kwDODO7WPM4BogHm · Feature IT_kwDODO7WPM4BogHn.
Labels
.github/labels.yml is the source of truth. It is synced to GitHub by
.github/workflows/labels.yml on push to dev. Two rules follow:
- Only apply labels that exist in
labels.yml. Never invent one — an
unknown label silently fails to apply. When in doubt, read the file (or
run gh label list).
- To add / rename / recolor / remove a label, edit
labels.yml in a PR —
do not create it in the GitHub UI. A UI-only label is reverted on the
next sync, and an ad-hoc label bypasses review. Adding the label to the
file is how you add it to the repo.
When to apply which
Apply your best guess at filing time. On every new issue, set the type
and any labels you can reasonably infer from the title and body — a Kind
label if it's clearly docs/deps, plus any status that applies. A filed issue
should land already-classified. If you can't tell whether it's valid or in
scope, still make your best guess (a maintainer can correct a label) and note
the uncertainty in the body.
| Group | Labels | Apply when… |
|---|
| Kind | documentation, dependencies, testing, ci, security, performance, reference | the nature of the work — docs / deps / tests / CI / security / perf / saved-ref PR |
| Discussion | question, discussion | needs an answer or an open design conversation |
| Status | in progress, blocked, stale | tracking workflow state |
| Review (PR) | ready for review, review comments | on pull requests moving through review |
| Design | waiting on design, needs screenshots | backlogged pending design / needs visual baselines |
| Community | good first issue, help wanted | inviting outside contribution |
| Resolution | duplicate, invalid, wontfix | when closing (pair with the matching state_reason) |
Keep the label set minimal — a Kind and/or a Status is usually enough. The
issue type (Bug / Feature / Task) already says what kind of work it
is, so labels only need to add what the type doesn't.
Closing issues
Always set a reason. MCP: issue_write(method="update", state="closed", state_reason="completed" | "not_planned" | "duplicate") (add
duplicate_of=<n> for duplicates). gh: gh issue close <n> --reason ….
For duplicate/invalid/wontfix, add the matching label too.
Quick checklist for a new issue