ir:triage
Autonomously triage GitHub issues on ingo-eichhorst/Irrlicht. Diagnostic-only: scores each issue against a 6-axis readiness rubric and lands it at ready-for-agent or needs-info, with a one-line justification per label. Triggers: "/ir:triage" (sweep), "/ir:triage #N" (single), "/ir:triage #N #M".
Best use case
ir:triage is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Autonomously triage GitHub issues on ingo-eichhorst/Irrlicht. Diagnostic-only: scores each issue against a 6-axis readiness rubric and lands it at ready-for-agent or needs-info, with a one-line justification per label. Triggers: "/ir:triage" (sweep), "/ir:triage #N" (single), "/ir:triage #N #M".
Teams using ir:triage should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/ir:triage/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How ir:triage Compares
| Feature / Agent | ir:triage | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Autonomously triage GitHub issues on ingo-eichhorst/Irrlicht. Diagnostic-only: scores each issue against a 6-axis readiness rubric and lands it at ready-for-agent or needs-info, with a one-line justification per label. Triggers: "/ir:triage" (sweep), "/ir:triage #N" (single), "/ir:triage #N #M".
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Irrlicht Triage (Autonomous, Diagnostic-Only)
Triage issues on `ingo-eichhorst/Irrlicht` end-to-end without prompting the maintainer. **Triage is diagnostic, not prescriptive.** Score readiness, classify, label, post — never propose solutions, never invent acceptance criteria, never break work into subtasks. If an axis fails, flag it; the implementing agent (or a separate planning step) does the prescribing later.
This contract is borrowed from established practice — Chromium's triage guidance ("triage is assessment, categorization, prioritization — not solutioning"), INVEST (Independent / Negotiable / Valuable / Estimable / Small / Testable), Devin's Agents 101 (strong feedback loops, specified outcome, starting points, checkpoints), and mattpocock's AGENT-BRIEF (concrete testable AC, explicit scope boundaries — authored *before* an agent picks up, not by the triage step).
Every `gh` call passes `--repo ingo-eichhorst/Irrlicht` so the skill works from any worktree.
## Invocation
- `/ir:triage` — triage every open issue missing a state role.
- `/ir:triage #278` — triage one issue.
- `/ir:triage #278 #277 #280` — triage several.
Enumerate the "all" set:
```bash
gh issue list --repo ingo-eichhorst/Irrlicht --state open --limit 200 \
--json number,title,labels \
| jq -r '.[] | select(
[.labels[].name] |
any(. == "needs-triage" or . == "needs-info" or
. == "ready-for-agent" or . == "ready-for-human" or
. == "wontfix") | not
) | .number'
```
`ready-for-human` is in the filter as a defensive guard — the skill no longer applies it, but a stray issue with that label should not be unconditionally re-triaged.
Triage one at a time so a failure on issue N doesn't block N+1.
## Disclaimer
Every comment posted during triage **must** start with:
```
> *This was generated by AI during triage.*
```
## Per-issue workflow
1. **Read.** `gh issue view <N> --repo ingo-eichhorst/Irrlicht --comments`. **Skip-if-triaged rule:** in the bulk sweep (`/ir:triage` with no args), if a prior `*This was generated by AI during triage.*` comment already exists and a state label is already applied, skip — already triaged. **When the maintainer explicitly names an issue (`/ir:triage #N`), always re-triage** — the explicit invocation is the maintainer's signal that they want a fresh assessment (e.g. after a rubric change). Edit the prior comment in place via `gh issue comment <N> --edit-last` rather than appending a new one.
2. **Verify (light).** For bugs, sanity-check that cited code paths still exist. Don't run tests. For enhancements, glance at `core/domain/` / `core/ports/` if proposed interfaces are named.
3. **Score the 6 axes** (Readiness Rubric below). Each axis is ✓ or ✗ with a one-liner. The verdict falls out of the scoring.
4. **Justify every label** — category, priority, scope, flags, milestone. One line each. If you can't justify, don't apply.
5. **Post** the assessment using the template below.
6. **Label and milestone** in a single `gh issue edit` call (one round-trip per issue). Close if `wontfix`.
## Readiness Rubric (6 axes)
Each axis scores ✓ (pass) or ✗ (fail) with a one-line justification grounded in the issue body. Any ✗ → `needs-info`. All ✓ → `ready-for-agent`.
| Axis | ✓ when… | ✗ when… |
|---|---|---|
| **Scope** | The change is bounded — number of files / packages touched is knowable from the issue, no "and also" creep. | "Refactor the codebase", "improve performance", any wording that fans out unboundedly. |
| **Specification** | The desired outcome is stated (what, not how). Edge cases either listed or absent because they don't exist. | Outcome is implied or aspirational; "make it better"; multiple plausible interpretations. |
| **Verifiability** | A concrete signal exists for "done": a unit test, a replay scenario, a CLI command output, a UI behavior, a metric threshold. | No way to mechanically tell if the fix worked; only "looks right" judgment. |
| **Context** | Relevant code paths / docs / prior PRs are cited or trivially findable. The agent has a starting point. | Issue is abstract or implicates code with no obvious entry point. |
| **Independence** | Not blocked on another issue / PR / external decision. No concurrent work that would conflict. | Depends on #N which is open / unresolved / unmerged; depends on a maintainer decision not yet made. |
| **Reversibility** | Local change, easy to revert. No production data, secrets, or one-way doors. | Touches signing keys, prod migrations, irreversible deletions, anything with blast radius beyond the repo. |
**Complexity** is a separate signal that informs the verdict. Score it Low / Medium / High using the calibration below. Complexity does *not* block readiness on its own — but **High complexity with no breakdown filed (no child issues, no ordered phase plan in the body) is a Scope failure** and lands the issue in `needs-info`.
### Complexity calibration
Industry context: agent benchmarks consistently show top models resolving a much lower fraction of real-world / production-like tasks than of curated tasks — the gap is driven by patch size and specification ambiguity, not by raw reasoning ability. Calibrate accordingly:
- **Low** — one file, one concern, no cross-package coordination. Highest agent success rate.
- **Medium** — 2–4 files across one slice (e.g. domain type + adapter + service), all foreseeable from the issue. One coherent change.
- **High** — multi-package coordination, schema evolution, cross-adapter parity, multi-phase work, or any "and also wire it through the UI". Agents fail here without a breakdown.
If complexity is High and the issue body does not contain a phase plan or link to child issues: **fail Scope, route to needs-info, ask the reporter to break it down.** Triage does not propose the breakdown itself.
## Decision rules
### Category (apply with one-liner)
- `bug` — describes broken behavior, regression, or wrong output.
- `enhancement` — proposes new behavior, capability, refactor, or polish.
### State
Two active states (`ready-for-agent`, `needs-info`) plus `wontfix` for closure.
- `ready-for-agent` — all 6 axes pass. Default heavily here. Visual sign-off and final review happen at PR time, not as triage barriers.
- `needs-info` — one or more axes fail. Two flavors:
1. **Reporter-side** — missing repro / outcome / verifiability / scope. Brief addresses `@reporter`.
2. **Maintainer-prereq** — a one-shot setup the agent literally cannot do (cryptographic key custody, account enrollment with identity/wallet). Brief addresses the maintainer and says: "once <prereq> exists, this becomes ready-for-agent."
Things that do **not** qualify as ✗ on any axis: aesthetic judgment ("matches the design system"), "needs a VM at the keyboard", manual hardware testing, Xcode `.pbxproj` edits, scope-commitment for multi-phase arcs *with a phase plan in the body*.
Closure label (separate from active states):
- `wontfix` — out of scope, duplicate, or invalid. Close after commenting.
### Priority (apply with one-liner)
- `Priority-High` — blocking or user-visible regression.
- `Priority-Medium` — should land soon, not blocking.
- `Priority-Low` — nice-to-have / polish.
Apply on every issue except `needs-info` (priority isn't yet meaningful there).
### Scope labels (apply with one-liner each)
If the issue is scoped to a specific adapter, platform, or module, add a `scope:<name>` label so issue lists are filterable. Use the directory name as the canonical scope token:
- Adapters (`core/adapters/inbound/agents/<name>`): `scope:opencode`, `scope:claudecode`, `scope:codex`, `scope:aider`, `scope:pi`.
- Platforms (`platforms/<name>`): `scope:macos`, `scope:web`.
- Other modules: `scope:daemon` (irrlichd), `scope:cli` (irrlicht-ls / irrlicht-focus), `scope:replay`, `scope:tooling`, `scope:site`.
Multiple scopes are fine for cross-cutting issues. Skip scope entirely for shared infra (`core/domain`, `core/application/services`) without a single owner.
Create a missing label on demand:
```bash
gh label create scope:opencode --repo ingo-eichhorst/Irrlicht --color BFD4F2 --description "OpenCode adapter" 2>/dev/null || true
```
### Flags (apply with one-liner each)
Each flag below is **only** applied when the criterion fits. The brief must include a one-liner explaining *why this flag is on this issue* — generic justifications ("looks beginner-friendly") don't count.
- `good first issue` — apply when **all four** hold: scope is one file or one cohesive function, complexity is Low, no domain-specific knowledge of irrlicht's hexagonal architecture or replay system is required, no concurrency / unsafe / FFI / signing code involved. One-liner names which of the four conditions make it newcomer-safe.
- `help wanted` — issue is well-scoped and acceptance is clear, but is **not** in the maintainer's near-term roadmap and external contribution is welcome. One-liner names why it's parked (e.g. "v0.6 milestone, not blocking 0.4").
- `documentation` — the only artifact that changes is documentation (`AGENTS.md`, `CLAUDE.md`, `site/docs/`, `README*`). One-liner names the doc surface.
- `adapter-request` — issue asks for support for a new coding agent or orchestrator. One-liner names the agent. When this lands at `ready-for-agent`, the brief must point at `ir:onboarding-factory` and the canonical scenario matrix rather than enumerating onboarding steps.
- `track:brand` — touches UI / marketing / overlay design that's part of the brand surface. One-liner names the surface.
- `duplicate` — a prior open issue covers the same scope. One-liner names `#N`.
- `invalid` — the report is wrong (works on current main, misunderstands the system). One-liner names the misunderstanding.
### Milestone (apply with one-liner)
Milestones group issues by release cycle. The convention is `vMAJOR.MINOR` (e.g. `v0.5`). Apply on every `ready-for-agent` issue; skip on `needs-info` and `wontfix`.
**If the issue already has a maintainer-set milestone, do not change it.** Note the existing milestone in the brief; the maintainer's choice wins.
**Resolution.** At the start of the run (or first single-issue invocation), enumerate open milestones and compute the three buckets from the latest published release:
```bash
LATEST_MM=$(gh release view --repo ingo-eichhorst/Irrlicht --json tagName --jq .tagName \
| sed -E 's/^v//; s/^([0-9]+\.[0-9]+).*/\1/')
# 0.4 → ACTIVE=0.5, NEXT=0.6, FUTURE=0.7
ACTIVE="v$(awk -v v="$LATEST_MM" 'BEGIN{split(v,a,"."); print a[1]"."a[2]+1}')"
NEXT="v$(awk -v v="$LATEST_MM" 'BEGIN{split(v,a,"."); print a[1]"."a[2]+2}')"
FUTURE="v$(awk -v v="$LATEST_MM" 'BEGIN{split(v,a,"."); print a[1]"."a[2]+3}')"
gh api "repos/ingo-eichhorst/Irrlicht/milestones?state=open" --jq '.[] | .title'
```
**Pick by priority:**
| Priority | Milestone |
|---|---|
| `Priority-High` | `$ACTIVE` (the in-progress release) |
| `Priority-Medium` | `$NEXT` |
| `Priority-Low` | `$FUTURE` |
**Create if missing.** If the chosen milestone doesn't exist in the open set, create it before applying — once per run, not per issue:
```bash
gh api repos/ingo-eichhorst/Irrlicht/milestones \
-f title="$FUTURE" -f state=open \
-f description="Future / longer-horizon work" --silent 2>/dev/null || true
```
Description is optional — only set it for `$FUTURE` since that bucket's intent isn't obvious from the title alone.
## Output: assessment (`ready-for-agent` or `needs-info`)
Single template for both verdicts. The brief is purely diagnostic — short, structured, every line earns its place.
```markdown
> *This was generated by AI during triage.*
## Triage Assessment
**Category:** <bug | enhancement> — <one-liner why>
**Priority:** <High | Medium | Low> — <one-liner why> *(omit if needs-info)*
**Scope:** <scope:X[, scope:Y]> — <one-liner per scope> *(omit if shared infra)*
**Flags:** <flag1, flag2> — <one-liner per flag> *(omit if none)*
**Milestone:** <vMAJ.MIN> — <one-liner why; or "existing — maintainer-set"> *(omit if needs-info or wontfix)*
**Complexity:** <Low | Medium | High> — <one-liner: files/packages touched, judgment calls required>
**Readiness:**
- ✓/✗ **Scope** — <one-liner>
- ✓/✗ **Specification** — <one-liner>
- ✓/✗ **Verifiability** — <one-liner>
- ✓/✗ **Context** — <one-liner>
- ✓/✗ **Independence** — <one-liner>
- ✓/✗ **Reversibility** — <one-liner>
**Verdict:** ready-for-agent | needs-info
<!-- if needs-info: -->
**Blocked on, before this becomes ready-for-agent:**
- <specific, one-shot item> (@reporter | @maintainer)
- <specific, one-shot item> (@reporter | @maintainer)
```
### What to leave out
The brief never contains:
- Invented acceptance criteria. If Verifiability fails, that's the gap; do not paper over it with a checklist.
- Proposed subtasks. If complexity is High without a breakdown, that's a Scope failure; the reporter or maintainer files child issues.
- Implementation suggestions, "watch for" invariants, "key interfaces", "out of scope" lists. The agent reads `AGENTS.md` / `CLAUDE.md` and the codebase before starting.
- Re-narration of current behavior or desired behavior. The issue body has those.
If you find yourself writing any of the above, stop — that's brief-authoring, not triage.
## Output: `wontfix`
One short paragraph naming the reason (out of scope / duplicate of #N / invalid + one-liner why). Close after posting.
## Apply labels and milestone (one call per issue)
```bash
gh issue edit <N> --repo ingo-eichhorst/Irrlicht \
--add-label <category>,<state>,<Priority-X>[,<flag>...][,scope:<area>...] \
--remove-label needs-triage,needs-info \
--milestone "<vMAJ.MIN>"
```
Omit `--milestone` on `needs-info` and `wontfix` issues, and on issues that already have a maintainer-set milestone (don't overwrite). If a `scope:<name>` label is new to the repo, create it first. If the chosen milestone doesn't exist in the open set, create it via the `gh api` call above before this command.
## Worked examples
### Example 1 — `ready-for-agent`
For a localized OpenCode adapter bug (one root cause, three named files, clear acceptance test):
```markdown
> *This was generated by AI during triage.*
## Triage Assessment
**Category:** bug — describes a 2.5s tail latency on a state transition; user-visible regression compared to other adapters.
**Priority:** Medium — UX-visible, OpenCode-only, not data-loss or crash.
**Scope:** scope:opencode — root cause and fix surface localized to OpenCode adapter + a flag on `agent.Event`.
**Milestone:** v0.6 — Priority-Medium → next cycle; bounded refactor, ships independently of v0.5 work.
**Complexity:** Medium — three packages in one slice (`core/domain/agent` flag, OpenCode watcher, session detector short-circuit).
**Readiness:**
- ✓ **Scope** — three named files, all foreseeable from the issue body.
- ✓ **Specification** — root cause identified; fix path stated; reasons against alternatives given.
- ✓ **Verifiability** — unit test for terminal `EventActivity` mid-debounce; replay scenario records `working → ready` within ≤500ms.
- ✓ **Context** — exact code paths and constants cited (and verified extant).
- ✓ **Independence** — no blocking issues; flag defaults false so other adapters are unchanged.
- ✓ **Reversibility** — additive flag + local short-circuit; revertible.
**Verdict:** ready-for-agent
```
### Example 2 — `needs-info` (reporter-side gap)
For an enhancement that lists multiple implementation paths without picking one:
```markdown
> *This was generated by AI during triage.*
## Triage Assessment
**Category:** enhancement — proposes new behavior (smarter notification copy).
**Flags:** help wanted — existing flag preserved; brief was already filed by the maintainer and external contributors are welcome.
**Complexity:** Medium-to-High — depends on chosen approach (heuristic vs bundled small model vs piggyback vs hybrid; each has different scope, dependency surface, and binary-size impact).
**Readiness:**
- ✓ **Scope** — bounded to notification text generation; per-adapter parser hooks named.
- ✗ **Specification** — issue lists four implementation paths without picking one; the path choice changes architecture, not just code.
- ✗ **Verifiability** — no acceptance bar stated for "good enough" generated text quality.
- ✓ **Context** — code paths for transcript reads exist per adapter.
- ✓ **Independence** — no blocking issues.
- ✓ **Reversibility** — local change either way.
**Verdict:** needs-info
**Blocked on, before this becomes ready-for-agent:**
- Pick one path: heuristic-only, bundled small model, piggyback, or hybrid (@reporter / @maintainer). Each has different scope, dependency surface, and binary-size impact.
- State the acceptance bar — manual eyeball on N sessions, fixture-based test suite, or specific quality metric (@reporter).
```
### Example 3 — `needs-info` (maintainer-prereq)
For an enhancement gated on a one-shot cryptographic-identity setup the agent cannot perform:
```markdown
> *This was generated by AI during triage.*
## Triage Assessment
**Category:** enhancement — distribution improvement.
**Scope:** scope:macos, scope:tooling — `tools/build-release.sh`, cask, `site/install.sh`.
**Complexity:** Low — script edits in `tools/build-release.sh` (sign + notarytool + stapler) plus two cleanup edits.
**Readiness:**
- ✓ **Scope** — three named files, no fan-out.
- ✓ **Specification** — exact `codesign` / `notarytool` / `stapler` commands given.
- ✓ **Verifiability** — `spctl -a -t open` and `xcrun stapler validate` plus a clean `brew install --cask`.
- ✓ **Context** — current build-release.sh and cask postflight block both findable.
- ✗ **Independence** — implementation requires Apple Developer Program enrollment + Developer ID cert in keychain + notarytool credentials. The agent has no keychain.
- ✓ **Reversibility** — script edits revertible; the prereq itself is one-time but not destructive.
**Verdict:** needs-info
**Blocked on, before this becomes ready-for-agent:**
- Apple Developer Program enrollment ($99/yr) (@maintainer).
- Developer ID Application certificate generated and installed in the maintainer's macOS keychain (@maintainer).
- App-specific password configured for `notarytool` against the maintainer's Apple ID (@maintainer).
```Related Skills
irrlicht-design
Use this skill to generate well-branded interfaces and assets for Irrlicht, either for production or throwaway prototypes/mocks/etc. Contains essential design guidelines, colors, type, fonts, assets, and UI kit components for prototyping.
ir:test-mac
Build and run a dev irrlicht daemon + macOS Swift app for local testing. Asks whether to run a SEPARATE instance alongside production (isolated state, port 7838 — production keeps running) or to REPLACE the running production versions (production port 7837 + production state, so the statusline quota feed and existing sessions show up). Use when the user says "test mac", "restart mac", "rebuild mac", or "/ir:test-mac".
ir:release
Build and publish an irrlicht release. Bumps version, builds Go daemon + Swift app, creates signed app bundle with icon, packages DMG (branded installer) + PKG, updates docs/changelog/landing page, commits, tags, pushes, and creates GitHub release with assets. Default: patch bump. Use "/ir:release minor" or "/ir:release major".
ir:refresh-aliases
Sync irrlicht's model-name alias map against codeburn's upstream BUILTIN_ALIASES. Fetches codeburn's src/models.ts, diffs entries against core/pkg/capacity/aliases.go, and proposes additions/changes as a PR. Use when user says '/ir:refresh-aliases', 'refresh aliases', 'sync codeburn aliases', 'check alias map', or when a session prices at $0 for a known model.
ir:onboarding-factory/record
Carry one assessed cell to a committed, verified recording: check prerequisites, port any missing driver step, drive the live agent CLI under a recording daemon via `of record run`, verify EVERY websocket observation (state + model + cost + tokens + agent) via `of record verify`, refresh the replay golden, and commit. Backflows a correction into the cell when the live recording disagrees with the assessment. Invoked as `/ir:onboarding-factory record <agent> <scenario>`.
ir:onboarding-factory/create-scenario
Add a brand-new scenario ROW to the matrix: one agent-agnostic `{id, name, description, acceptance_criteria, process}` entry written through `of scenario add`. Researches how the behavior manifests across every onboarded agent (and what the daemon would observe) before synthesizing the agent-agnostic spec. No agent CLI invocation, no recording. Invoked as `/ir:onboarding-factory create-scenario <slug>`.
ir:onboarding-factory/create-agent
Onboard a brand-new agent CLI as a matrix COLUMN: research its identity + recording prerequisites, register it via `of agent add`, scaffold its interactive driver from the template, and predict which step types each scenario's recipe will need (the driver-needs punch-list). No live recording. Invoked as `/ir:onboarding-factory create-agent <slug>`.
ir:onboarding-factory/assess
Judge one (agent, scenario) cell across the three pillars — agent capability, daemon sensor capture, driver capability — on cited evidence, then author the cell's recipe and machine-checkable spec. Writes the cell metadata via `of cell write` and the spec (expected.jsonl) via `of cell spec`. No live recording. Invoked as `/ir:onboarding-factory assess <agent> <scenario>`.
ir:onboarding-factory
Maintain the canonical scenario × agent fixture matrix for irrlicht. A slim dispatcher that routes intent to four focused subagents — `create-scenario` (add a matrix row), `create-agent` (add a matrix column), `assess` (judge one cell across the three pillars and write its spec), and `record` (drive the live agent and verify every websocket observation). Every read and every write goes through the `of` factory CLI (tools/onboarding-factory) — the skill itself never touches `replaydata/`. Each subagent returns a ≤6-line summary so the parent keeps its context for strategic decisions instead of drowning in per-cell tool output. Use when the user says "/ir:onboarding-factory", "onboard agent", "add a scenario", "assess fixtures", "record fixtures", or "regenerate recordings".
ir:agent-landscape
Scan the web for coding agents and agent orchestrators, track GitHub stars and trends, rank by popularity+momentum, and publish a report to the irrlicht site. Shows which agents irrlicht already supports. Use when user says 'agent landscape', 'scan agents', 'coding agent tracker', 'agent popularity', '/ir:agent-landscape', or wants to see the competitive landscape of coding agents.
performing-web-application-vulnerability-triage
Triage web application vulnerability findings from DAST/SAST scanners using OWASP risk rating methodology to separate true positives from false positives and prioritize remediation.
performing-malware-triage-with-yara
Performs rapid malware triage and classification using YARA rules to match file patterns, strings, byte sequences, and structural characteristics against known malware families and suspicious indicators. Covers rule writing, scanning, and integration with analysis pipelines. Activates for requests involving YARA rule creation, malware classification, pattern matching, sample triage, or signature-based detection.