microsoft/issue-triage-report
Generate comprehensive GitHub Feature Area Status reports for the Windows App SDK repository. Use when asked to create triage reports, identify high-priority issues, analyze feature area health, find issues needing attention, or generate status dashboards. Triggers on requests involving issue triage, area status, priority analysis, bug tracking reports, or engineering team focus areas.
npx skills add https://github.com/microsoft/WindowsAppSDK --skill issue-triage-report
This skill generates comprehensive GitHub Feature Area Status reports that help engineering teams identify high-priority issues, track triage status, and highlight items needing immediate attention.
Primary triggers — Generate a report when:
Anti-patterns — Do NOT use this skill when:
gh) installed and authenticatedThe area contacts file maps feature areas to team members. This file is required for contact lookups and is stored in your local .user/ folder (not committed to the repository).
mkdir -p .user/issue-triage-report
cp .github/skills/issue-triage-report/references/area-contacts.json .user/issue-triage-report/area-contacts.json
.user/issue-triage-report/area-contacts.json with your team's actual contacts> Note: The .user/ folder is gitignored, so your team contacts remain private.
Generate the full feature area status report with highlight scoring.
Location: ./scripts/Generate-FeatureAreaReport.ps1
./scripts/Generate-FeatureAreaReport.ps1 [-Repo <owner/repo>] [-OutputFormat <markdown|csv|json>] [-HighlightCount <n>]
| Parameter | Required | Default | Description |
|-----------|----------|---------|-------------|
| -Repo | No | microsoft/WindowsAppSDK | Repository in owner/repo format |
| -OutputFormat | No | markdown | Output format: markdown, csv, or json |
| -HighlightCount | No | 3 | Max highlighted issues per area |
| -IncludeClosed | No | $false | Include recently closed issues count |
Example:
./scripts/Generate-FeatureAreaReport.ps1 -OutputFormat markdown -HighlightCount 3
Calculate the highlight score for a specific issue to determine priority.
Location: ./scripts/Get-HighlightScore.ps1
./scripts/Get-HighlightScore.ps1 -IssueNumber <number> [-Repo <owner/repo>] [-Verbose]
| Parameter | Required | Default | Description |
|-----------|----------|---------|-------------|
| -IssueNumber | Yes | - | GitHub issue number to analyze |
| -Repo | No | microsoft/WindowsAppSDK | Repository in owner/repo format |
| -Verbose | No | $false | Show detailed scoring breakdown |
Example:
./scripts/Get-HighlightScore.ps1 -IssueNumber 4651 -Verbose
Retrieve or update the area-to-contact mapping configuration.
Location: ./scripts/Get-AreaContacts.ps1
./scripts/Get-AreaContacts.ps1 [-Area <area-name>] [-Update]
| Parameter | Required | Default | Description |
|-----------|----------|---------|-------------|
| -Area | No | - | Specific area to look up (returns all if omitted) |
| -Update | No | $false | Interactively update contact mapping |
gh auth status
./scripts/Generate-FeatureAreaReport.ps1 -OutputFormat markdown -HighlightCount 3
Before running the command above, have the agent save runtime assessments to:
./references/AgentAssessments.jsonThis file is loaded automatically at script start and applied as per-run overrides.
Every assessed issue entry must include agent reasoning in the reasoning field.
Required per-issue schema in assessments:
severityTier: critical|high|medium|low|noneisBlocker: true|falsereasoning: short rationale explaining severity/blocker judgmentExample:
{
"assessments": {
"2894": {
"severityTier": "high",
"isBlocker": false,
"reasoning": "Frequent user impact in notifications flow; clear repro in comments; no confirmed workaround."
}
}
}
[severity:critical|high|medium|low|none], [blocker:yes|no], and optional [confidence:XX]. gh issue list --repo microsoft/WindowsAppSDK --label "area-Notifications" --state open --json number,title,body,labels,reactionGroups,createdAt,comments
./scripts/Get-HighlightScore.ps1 -IssueNumber 2894 -Verbose
./scripts/Get-AreaContacts.ps1
./scripts/Get-AreaContacts.ps1 -Area "area-Notifications" -Update
Issues are scored with a normalized composite on a 0..100 scale. See scoring-algorithm.md for complete details.
PowerShell computes deterministic score factors and highlight labels. Severity and blocker are assessment-driven inputs.
Scripts load baseline assessments from:
./references/IssueAssessments.jsonThey also load runtime agent assessments from:
./references/AgentAssessments.jsonIf both files include the same issue number, IssueAssessments.json takes precedence.
If either file is missing or malformed, scripts emit status/warning output and continue with fallback behavior.
Implementation note: scripts load these files through a single Read-Assessments function in ./scripts/ReportLib.ps1 using -AssessmentType Issue or -AssessmentType Agent.
After generating scores, review each highlighted issue and assign these annotations based on title, body, labels, and comments:
[severity:critical|high|medium|low|none][blocker:yes|no][confidence:XX]After assigning annotations, persist the same decision to ./references/AgentAssessments.json and include reasoning for every updated issue entry.
Use this severity rubric:
| Tier | Meaning |
|------|---------|
| critical | Crash, data loss, severe regression, or broad user/system impact |
| high | Serious functional break affecting key workflows |
| medium | User-visible defect or limitation with practical workaround |
| low | Minor issue, edge case, docs/polish impact |
| none | No clear severity signal from issue content |
Mark [blocker:yes] only when issue content explicitly indicates dependency blocking (for example: "blocked by", "blocking release", "must be fixed before") and no workaround has been provided. Otherwise use [blocker:no].
Use this confidence rubric:
| Score | Level | Meaning |
|-------|-------|---------|
| 80-100 | High | Multiple strong signals agree: issue content, labels, reactions, age, comments, and recent discussion all support highlighting it |
| 60-79 | Medium-High | Strong support from the score breakdown and issue details, with only minor ambiguity |
| 40-59 | Medium | Reasonable highlight candidate, but some evidence is weak, stale, or mixed |
| 20-39 | Low | The numeric score is carrying most of the case; supporting context is limited or ambiguous |
| 0-19 | Very Low | The issue surfaced mechanically, but the agent cannot defend highlighting it with the available evidence |
Confidence should consider:
| Factor | Weight (between 0 and 1) | Description |
|--------|--------|-------------|
| Reactions | weights.reactions | round(min(1, totalReactions / rankingCeilings.reactions) * weight * 100, 1) |
| Age | weights.age | round(min(1, issueAgeDays / rankingCeilings.ageDays) * weight * 100, 1) |
| Comments | weights.comments | round(min(1, commentCount / rankingCeilings.comments) * weight * 100, 1) |
| Severity | weights.severity | round(weight * severityMultipliers[tier] * 100, 1) from assessments (critical/high/medium/low/none) |
| Blockers | weights.blockers | Adds round(weight * 100, 1) when assessed isBlocker=true |
Total = min(100, round(sum of factor points, 1)).
rankingCeilings are independent per-factor scales and do not need to sum to any target.
recommendationBands are fixed score-ratio boundaries (high, medium, normal) used to classify recommendations. They are ratio cutoffs, not statistical percentiles.
The report adds reason labels to highlighted issues:
| Label | Meaning |
|-------|---------|
| 🌟 Popular | High reaction count (≥5 reactions) |
| ⏰ Aging | Open > 90 days without triage |
| 📈 Trending | High comment activity (≥10 comments) |
| Feature Area | Area Contact | Open | Triage | Proposals | Closed | Highlights |
|--------------|--------------|------|--------|-----------|--------|------------|
| area-Notification | Contact Name | 34 | 8 | 11 | 0 | 🌟 [#2894](link), ⏰ [#3001](link) |
| area-Widgets | Contact Name | 21 | 10 | 4 | 0 | 📈 [#3958](link) |
When producing the final narrative report, the agent should append content-review annotations:
| Feature Area | Area Contact | Open | Triage | Proposals | Closed | Highlights |
|--------------|--------------|------|--------|-----------|--------|------------|
| area-Notification | Contact Name | 34 | 8 | 11 | 0 | 🌟 [#2894](link) [severity:high] [blocker:no] [confidence:85], ⏰ [#3001](link) [severity:medium] [blocker:no] [confidence:72] |
| area-Widgets | Contact Name | 21 | 10 | 4 | 0 | 📈 [#3958](link) [severity:low] [blocker:no] [confidence:68] |
| Indicator | Meaning |
|-----------|---------|
| 0️⃣🐛🥳 | Zero bugs — celebrate! |
| - | Data not applicable or unavailable |
Contact mappings are stored in area-contacts.json. Update this file when team assignments change.
Modify scoring weights in ./scripts/ScoringConfig.json.
severityMultipliers maps assessment tiers to the percentage of weights.severity that is applied.
| Symptom | Solution |
|---------|----------|
| gh: command not found | Install GitHub CLI: winget install GitHub.cli |
| authentication required | Run gh auth login and follow prompts |
| Rate limit exceeded | Wait or use --limit to reduce API calls |
| Missing area label | Issue may use non-standard label; check label list |
| Contact not found | Update area-contacts.json |
# List all area labels (uses Get-RepositoryLabels.ps1 as the single source of truth)
./.github/skills/triage-meeting-prep/scripts/Get-RepositoryLabels.ps1 -Filter "area-*" -OutputFormat table
# Get issue details with reactions
gh issue view 4651 --repo microsoft/WindowsAppSDK --json number,title,labels,reactionGroups,createdAt,comments,author
# List issues needing triage
gh issue list --repo microsoft/WindowsAppSDK --label "needs-triage" --state open --json number,title,labels
# Export all open issues to JSON
gh issue list --repo microsoft/WindowsAppSDK --state open --limit 1000 --json number,title,labels,reactionGroups,createdAt,comments,author
Take microsoft/issue-triage-report from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.