Shikanime Issue Triage
Triage an issue in shikanime-labs/*/shikanime-studio/*: fill fields empty
on the issue and derivable from its content. English; never invent a
repo-lacking value.
Available script
scripts/discover-metadata.sh REPO — print every triage-relevant value the
repo offers: labels, open milestones, owner projects, assignees, enabled
issue types, custom fields. This is the source of truth for Step 3 — every
value you set must come from its output.
When to Use
- "Triage an existing shikanime org issue."
- "Assign metadata (type, labels, assignee, milestone, project, relationships,
fields)."
- "Close an issue with a rationale if it will not be worked."
- A triaged defect needs root-cause diagnosis → hand off to
sks-investigate
(research-only); do not diagnose inline during triage.
Prerequisites
gh authenticated against the canonical org repo. Always target the org repo
directly.
Inputs
N : issue number.
R : OWNER/REPO. Defaults to cwd origin remote, validated under
shikanime-labs/ or shikanime-studio/; else ask.
Procedure
1. Fetch
gh issue view "$N" --repo "$R" --json number,title,body,labels,assignees,milestone,projectCards,blockedBy,blocking
gh api repos/"$R"/issues/"$N" \
--jq '{type: (.type // ""), parent: (.parent_issue.number // null)}' \
# type/parent (not exposed by `gh issue view`)
2. Discover available metadata (source of truth)
Run from the skill directory — scripts/ resolves against the skill dir,
not the target repo:
bash <skill-dir>/scripts/discover-metadata.sh "$R"
Read the full output before deciding anything: labels, milestones, projects,
assignees, issue types, fields. Missing sections (no milestones, no projects)
mean those fields stay empty.
3. Decide each field (apply only if empty + value exists in repo)
type — if empty and the repo has issue types: map by meaning
(defect/regression→Bug, new capability→Feature,
task/tracking→Task). Set only a name from the step-2 issue-types list —
never invent. Apply with gh issue edit "$N" --repo "$R" --type <name>.
labels — best match by meaning (defect→bug, new
capability→enhancement, doc→documentation); add an area label only if
it exists. Drop any not in the step-2 list — never invent.
assignee — if none: ASSIGNEE=$(gh api user --jq .login).
milestone — if none and milestones exist: bug→highest open patch
on current minor (max Z); enhancement→next minor/major.
project — if a Projects V2 board exists and this is unboarded:
--add-project "<title>" (title, not number). Skip if ambiguous.
relationships — set only when derivable from content/links, never
invent:
- parent:
--parent <number> if the issue is clearly a child of #M.
- sub-issues:
--add-sub-issue <n>,<n> for explicitly listed children.
- blockers:
--add-blocked-by <n> / --add-blocking <n> only when the body
or a linked issue states the dependency. Empty + no textual signal → skip.
fields — custom fields live on the project item, not the issue. After
adding to a project, set them via gh project item-edit / GraphQL
(updateProjectV2ItemFieldValue) — see ceiling below. Skip when the repo
has no project board or no custom fields (step-2 output says "no repo-level
fields").
transfer — if the issue clearly belongs in another shikanime-labs/*
/shikanime-studio/* repo (wrong repo, not merely a wrong label), move it
rather than triaging in place. Transfer preserves comments, labels, and the
cross-link:
gh issue transfer "$N" "$DEST_REPO" # DEST_REPO = OWNER/REPO
Confirm the destination exists and that the transfer is accepted before
proceeding. Do not also edit or close the source issue — transfer
empties it.
4. Apply
gh issue edit "$N" --repo "$R" --type "Bug" # only if empty + enabled
gh issue edit "$N" --repo "$R" \
--add-label "bug" --add-label "area/..."
# --add-label, never --label
gh issue edit "$N" --repo "$R" --add-assignee "$ASSIGNEE"
gh issue edit "$N" --repo "$R" --milestone <num>
gh issue edit "$N" --repo "$R" --add-project "Roadmap" # title, not number
gh issue edit "$N" --repo "$R" --parent <number> # only if derivable
gh issue edit "$N" --repo "$R" --add-blocked-by <n> --add-sub-issue <n>,<n>
# fields: only after --add-project, via `gh project item-edit` / GraphQL
5. Verify
gh issue view "$N" --repo "$R" --json number,title,labels,assignees,milestone,projectCards,blockedBy,blocking
gh api repos/"$R"/issues/"$N" \
--jq '{type: (.type // ""), parent: (.parent_issue.number // null)}' \
# confirm type + parent landed
6. Close issues that will not be worked
See references/close.md for the per-reason close commands. Always close with a
rationale; never silently close. Ask the user for free-text REASON — never
guess or reuse a generic string. Post a comment first, then close.
Verification
gh issue view "$N" --repo "$R" --json number,title,labels,assignees,milestone,projectCards,blockedBy,blocking
gh api repos/"$R"/issues/"$N" \
--jq '{type: (.type // ""), parent: (.parent_issue.number // null)}'
See also
sks-issue — creation conventions (English).
1---2name: sks-issue-triage3description: Use when triaging an existing shikanime org issue: assign type, labels, assignee, milestone, project, relationships, and fields; close with rationale if not workable.4license: Apache-2.05---67# Shikanime Issue Triage89Triage an issue in `shikanime-labs/*`/`shikanime-studio/*`: fill fields **empty10on the issue** and **derivable from its content**. English; never invent a11repo-lacking value.1213## Available script1415- `scripts/discover-metadata.sh REPO` — print every triage-relevant value the16 repo offers: labels, open milestones, owner projects, assignees, enabled17 issue types, custom fields. This is the source of truth for Step 3 — every18 value you set must come from its output.1920## When to Use2122- "Triage an existing shikanime org issue."23- "Assign metadata (type, labels, assignee, milestone, project, relationships,24 fields)."25- "Close an issue with a rationale if it will not be worked."26- A triaged defect needs root-cause diagnosis → hand off to `sks-investigate`27 (research-only); do not diagnose inline during triage.2829## Prerequisites3031- `gh` authenticated against the canonical org repo. Always target the org repo32 directly.3334## Inputs3536- `N` : issue number.37- `R` : `OWNER/REPO`. Defaults to cwd `origin` remote, validated under38 `shikanime-labs/` or `shikanime-studio/`; else ask.3940## Procedure4142### 1. Fetch4344```bash45gh issue view "$N" --repo "$R" --json number,title,body,labels,assignees,milestone,projectCards,blockedBy,blocking46gh api repos/"$R"/issues/"$N" \47 --jq '{type: (.type // ""), parent: (.parent_issue.number // null)}' \48 # type/parent (not exposed by `gh issue view`)49```5051### 2. Discover available metadata (source of truth)5253Run from the skill directory — `scripts/` resolves against the skill dir,54not the target repo:5556```bash57bash <skill-dir>/scripts/discover-metadata.sh "$R"58```5960Read the full output before deciding anything: labels, milestones, projects,61assignees, issue types, fields. Missing sections (no milestones, no projects)62mean those fields stay empty.6364### 3. Decide each field (apply only if empty + value exists in repo)6566- **type** — if empty and the repo has issue types: map by meaning67 (defect/regression→`Bug`, new capability→`Feature`,68 task/tracking→`Task`). Set only a name from the step-2 issue-types list —69 never invent. Apply with `gh issue edit "$N" --repo "$R" --type <name>`.70- **labels** — best match by meaning (defect→`bug`, new71 capability→`enhancement`, doc→`documentation`); add an area label only if72 it exists. Drop any not in the step-2 list — never invent.73- **assignee** — if none: `ASSIGNEE=$(gh api user --jq .login)`.74- **milestone** — if none and milestones exist: bug→highest open **patch**75 on current minor (max `Z`); enhancement→next minor/major.76- **project** — if a Projects V2 board exists and this is unboarded:77 `--add-project "<title>"` (title, not number). Skip if ambiguous.78- **relationships** — set only when derivable from content/links, never79 invent:80 - parent: `--parent <number>` if the issue is clearly a child of `#M`.81 - sub-issues: `--add-sub-issue <n>,<n>` for explicitly listed children.82 - blockers: `--add-blocked-by <n>` / `--add-blocking <n>` only when the body83 or a linked issue states the dependency. Empty + no textual signal → skip.84- **fields** — custom fields live on the _project item_, not the issue. After85 adding to a project, set them via `gh project item-edit` / GraphQL86 (`updateProjectV2ItemFieldValue`) — see ceiling below. Skip when the repo87 has no project board or no custom fields (step-2 output says "no repo-level88 fields").89- **transfer** — if the issue clearly belongs in another `shikanime-labs/*`90 /`shikanime-studio/*` repo (wrong repo, not merely a wrong label), move it91 rather than triaging in place. Transfer preserves comments, labels, and the92 cross-link:9394 ```bash95 gh issue transfer "$N" "$DEST_REPO" # DEST_REPO = OWNER/REPO96 ```9798 Confirm the destination exists and that the transfer is accepted before99 proceeding. Do **not** also edit or close the source issue — transfer100 empties it.101102### 4. Apply103104```bash105gh issue edit "$N" --repo "$R" --type "Bug" # only if empty + enabled106gh issue edit "$N" --repo "$R" \107 --add-label "bug" --add-label "area/..."108# --add-label, never --label109gh issue edit "$N" --repo "$R" --add-assignee "$ASSIGNEE"110gh issue edit "$N" --repo "$R" --milestone <num>111gh issue edit "$N" --repo "$R" --add-project "Roadmap" # title, not number112gh issue edit "$N" --repo "$R" --parent <number> # only if derivable113gh issue edit "$N" --repo "$R" --add-blocked-by <n> --add-sub-issue <n>,<n>114# fields: only after --add-project, via `gh project item-edit` / GraphQL115```116117### 5. Verify118119```bash120gh issue view "$N" --repo "$R" --json number,title,labels,assignees,milestone,projectCards,blockedBy,blocking121gh api repos/"$R"/issues/"$N" \122 --jq '{type: (.type // ""), parent: (.parent_issue.number // null)}' \123 # confirm type + parent landed124```125126### 6. Close issues that will not be worked127128See `references/close.md` for the per-reason close commands. Always close with a129rationale; never silently close. Ask the user for free-text `REASON` — never130guess or reuse a generic string. Post a comment first, then close.131132## Verification133134```bash135gh issue view "$N" --repo "$R" --json number,title,labels,assignees,milestone,projectCards,blockedBy,blocking136gh api repos/"$R"/issues/"$N" \137 --jq '{type: (.type // ""), parent: (.parent_issue.number // null)}'138```139140## See also141142- `sks-issue` — creation conventions (English).