.agents/skills/issue-triage/SKILL.md
Issue pipeline: Step 1 of 3 (Triage). See documentation/dev/issue-pipeline.md.
Analyze a SkiaSharp GitHub issue and produce a structured, schema-validated triage JSON.
These 3 reads are REQUIRED. Do not proceed to Phase 1 until all three are loaded.
Quick flow:
- Load issue data from GitHub (prefer
gh, or GitHub MCP when available)- Read references: schema-cheatsheet, labels, triage-examples, anti-patterns
- Create brief plan (5-10 lines)
- Investigate code — READ-ONLY, never edit source files
- Generate JSON
- Validate with script
- Persist JSON + Markdown + HTML reports
Primary source: GitHub itself. Prefer gh CLI for repeatable issue/PR fetches and searches. If the environment exposes GitHub MCP issue/PR lookup tools, those are also valid. Do not set up or depend on a cache worktree or cache branch for this skill.
Phase 1 (Setup) → Phase 2 (Investigate) → Phase 3 (Analyze) → Phase 4 (Workarounds) → Phase 5 (Validate) → Phase 6 (Persist & Render)
Run once per session:
pip3 install -r .agents/skills/issue-triage/scripts/requirements.txt --quiet
python3 --version # Requires 3.9+
python3 -c "import jinja2; print('jinja2', jinja2.__version__)" # pip3 install jinja2
gh --version
gh auth status
If gh is unavailable or unauthenticated, use the GitHub MCP issue/PR retrieval and search tools available in the environment.
gh issue view {number} --repo mono/SkiaSharp \
--json number,title,body,labels,comments,state,createdAt,updatedAt,closedAt,author,milestone \
> /tmp/{number}.issue.json
GitHub MCP issue/PR retrieval tools are equally valid if the environment exposes them.
Scope: READ code, don't WRITE code. Grep, read files, trace call chains. Never create files, compile, or execute.
Before ANY classification, search the source code for the types, methods, APIs, or behaviors mentioned in the issue. Read the relevant files. Record every finding in analysis.codeInvestigation as {file, finding, relevance} (with optional lines).
Do NOT classify until you have examined source code. For bugs, include at least one codeInvestigation entry. Close-* actions should include at least two.
Steps:
gh CLI or GitHub MCP directly:
# Search issues (finds duplicates, prior reports, related discussions)
gh search issues "{keywords from issue}" --repo mono/SkiaSharp --limit 10 \
--json number,title,state,url
# Search PRs (finds fixes, prior attempts, reverted changes)
gh pr list --search '{keywords from issue}' --state all --repo mono/SkiaSharp --limit 10 --json number,title,state,mergedAt
evidence.reproEvidence.repoLinks — both duplicate/related issues AND closed/unmerged PRs, as they reveal prior reports and maintainer decisions. Duplicate issues are especially important for close-as-duplicate classification.| Signal in issue | Source to consult |
|---|---|
| NativeAssets, DllNotFoundException, container, WASM | documentation/dev/packages.md |
| Platform quirks, common traps | references/skia-patterns.md |
| Specific SkiaSharp types or methods | docs/SkiaSharpAPI/*.xml |
| How-to about drawing, paths, bitmaps | .docs/docs/docs/ |
| Non-SkiaSharp tech (MAUI, Blazor, WPF) | mslearn/microsoft_docs_search MCP tool |
Pre-flight — confirm before analyzing:
- Issue data loaded from
ghCLI or GitHub MCP- Read references/schema-cheatsheet.md for required fields and enums
- Read references/labels.md for valid label values
- Read references/triage-examples.md for calibration
- Read references/anti-patterns.md — at least the critical rules
- Created a brief plan (5-10 lines: what to investigate, what type you suspect)
Reminder: Triage is READ-ONLY. Do NOT edit any source files (.cs, .cpp, .csproj, .json).
Read references/labels.md for valid label values and cardinality, references/triage-examples.md for calibration, and references/schema-cheatsheet.md for required fields.
Write brief internal analysis (3–5 sentences), classify the type, then read references/research-by-type.md for type-specific research. Conduct the research, then generate the JSON. Write to /tmp/{number}.json. Use this exact literal path structure, do NOT substitute $TMPDIR or any other variable. Do NOT use mkdir — write directly to /tmp/.
⚠️ Schema Compliance:
- Read references/schema-cheatsheet.md — This is the authoritative source for structure, fields, and enums.
- Review references/labels.md — Use only valid label values.
- Follow these critical constraints:
meta.schemaVersionmust be"1.0"- Optional fields: OMIT entirely if not applicable. Do NOT set to
null.- String Arrays:
platforms,backends,tenetsare simple string arrays (no confidence wrapper).- Investigation:
analysis.codeInvestigationis MANDATORY. At least one entry for bugs, two for close-* actions.- Rationale:
analysis.rationaleis a single summary string (not per-field).- Validation: No extra properties allowed (
additionalProperties: false).
| Group | Content |
|---|---|
summary | One-sentence description of the issue (top-level string, required). |
meta | Version "1.0", issue number, repo, analyzedAt (ISO 8601). |
classification | type and area (required objects with confidence). platforms, backends (optional string arrays). |
evidence | bugSignals (for bugs), reproEvidence (all attachments/links), regression (if claimed), fixStatus (if fixed). |
analysis | summary (required), codeInvestigation (findings from Phase 2), keySignals (quotes), rationale (decision summary), resolution (proposals). |
output | actionability (suggested action + suggestedReproPlatform) and actions (automatable tasks). |
Refer to the cheatsheet for the exact field structure and enum values.
For bugs, questions, and feature requests: actively search for workarounds the reporter can use now. Follow references/workaround-search.md — 9 sources in priority order (existing triages → closed issues → known patterns → source code → docs → web).
category to "workaround" / "fix" / "alternative" / "investigation"codeSnippet on any proposal with copy-paste-ready codeSkip this phase for duplicates and abandoned issues (omit analysis.resolution).
If any proposal includes a codeSnippet or the add-comment comment contains code: you must validate it with 3 parallel agents per references/workaround-validation.md. Do not suggest code that has not been checked.
Agents (parallel explore type, Haiku model):
Synthesis: All pass → validated: "yes". Any warn → add caveats to comment, reduce confidence. Any fail → fix or strip code, set validated: "no".
If no proposals contain code, set validated: "untested".
🛑 PHASE GATE: You CANNOT proceed to Phase 6 without passing validation. Skipping validation = INVALID triage. The task is incomplete.
python3 .agents/skills/issue-triage/scripts/validate-triage.py /tmp/{number}.json
⚠️ NEVER hand-roll your own validation. NEVER assume it passes. RUN THE SCRIPT.
🛑 PHASE GATE: Phase 5 validator MUST have printed ✅ before you reach this step. If you have not run the validation script, GO BACK and run it now.
Copy the validated JSON to output/ai-triage/ for collection, then render companion Markdown and HTML reports that wrap the same JSON data.
python3 .agents/skills/issue-triage/scripts/persist-triage.py /tmp/{number}.json
This produces:
output/ai-triage/{number}/triage.jsonoutput/ai-triage/{number}/triage.mdoutput/ai-triage/{number}/triage.html✅ Triage: ai-triage/{number}/triage.json
✅ Report: ai-triage/{number}/triage.md
✅ Viewer: ai-triage/{number}/triage.html
Type: type/bug (0.98) Area: area/SkiaSharp
Severity: critical Action: needs-investigation
Actions:
labels-1 update-labels [low] Add type/bug, area/SkiaSharp
comment-1 add-comment [high] ⚠️ requires human edit
link-1 link-related [low] Cross-ref #1234
Pipeline hint:
classification.type.value == "type/bug" and output.actionability.suggestedAction == "needs-investigation": next step is issue-repro (ai-repro/{number}/repro.json).classification.type.value is type/enhancement or type/feature-request and suggestedAction == "needs-investigation": next step is also issue-repro, but repro will use confirmed/not-confirmed instead of reproduced/not-reproduced.output.actionability.suggestedReproPlatform tells CI which runner to use for reproduction:
macos — for os/iOS, os/macOS, os/tvOS, os/watchOS issueswindows — for os/Windows-Classic, os/Windows-WinUI, os/Windows-Universal-UWP, os/Windows-Nano-Server issueslinux — for everything else (os/Linux, os/WASM, os/Android, os/Tizen, or no platform specified)linux even if the reporter tests on other platforms.If add-comment exists, show comment in a copy-paste block. ⚠️ NEVER post via GitHub API.
See references/anti-patterns.md — read this file on first triage in session.
#0 (CRITICAL): Triage is READ-ONLY. If you edit a source file during triage, you have FAILED. See the anti-patterns reference for the full list.
#1 (CRITICAL): NEVER use store_memory during triage. Triage produces JSON artifacts, not memories. Storing unverified facts pollutes all future sessions.
#2 (CRITICAL): NEVER skip the validation script. You MUST run validate-triage.py and see ✅ before persisting. Mentally checking fields is not validation. If the script isn't run, the triage is invalid.
scripts/validate-triage.py <triage.json> — Validate against schema + rationale coverage + action integrityscripts/persist-triage.py <triage.json> — Copy validated JSON to output/ai-triage/{number}/ and invoke rendererscripts/render-triage-report.py <triage.json> — Render validated triage JSON → .md + .html (uses Jinja2 template for markdown)scripts/triage-report.md.jinja2 — Jinja2 template for the Markdown reportscripts/viewer.html — Bootstrap 5 HTML template for the interactive viewer