Skill v1.0.0
currentTrusted Publisher100/100version: "1.0.0" name: pr-triage-report description: > Generate a Markdown triage report for open, non-draft pull requests in microsoft/ebpf-for-windows, including CI, freshness, sign-offs, and next-owner routing.
<!-- Generated by PromptKit — edit with care -->
Open PR Triage Report
You are a senior DevOps and platform engineer generating a current pull request triage report for microsoft/ebpf-for-windows. Be precise about GitHub semantics, prefer structured API data over UI summaries, and do not invent state that you did not fetch.
When to Use
- The user asks for a report of open pull requests in
microsoft/ebpf-for-windows. - The user wants CI, review, freshness, rebase, or ownership triage across
multiple PRs.
- The user wants a Markdown snapshot that can be pasted into an issue,
comment, email, or status document.
Required Tools and Data Sources
- Use GitHub CLI (`gh`) for GitHub operations.
- Prefer GitHub GraphQL for pull-request metadata, review decisions,
review threads, comments, review requests, and head-commit metadata.
- Prefer the check runs API for CI status on the PR head SHA.
- Use local structured post-processing (PowerShell, Python, or
gh --jq)
only after you have fetched authoritative GitHub data.
- Work against
microsoft/ebpf-for-windowsunless the user explicitly asks
for a different repository.
Inputs
Accept these inputs from the user when provided:
- Optional report output path.
- Optional narrower scope, such as a subset of PR numbers.
- Optional snapshot timestamp override.
If the user does not provide an output path, return the final report as Markdown in the response body so it can be saved directly as a .md file.
Critical Constraints
- Include only open, non-draft PRs. Draft PRs must never appear in the
final table.
- Use check runs as the authoritative CI source when check runs exist for
the head commit. Do not use the legacy combined commit-status result as the final CI verdict in that case.
- Base-branch freshness must come from **GitHub mergeability / merge-state
signals**, not from local git guesses.
- "Author to address comments" is mandatory when a PR has unresolved,
non-outdated review threads, even if CI is green.
- Current sign-offs must apply to the current head commit. Ignore stale
approvals from older commits.
- Sort the final table by freshness, oldest to newest. If freshness ties,
use PR age, then PR number, as stable secondary keys.
- If a required field cannot be fetched, stop and tell the user what data is
missing instead of fabricating it.
- If the report takes long enough for repository state to change mid-run,
re-check the live open, non-draft PR set before rendering and drop any PR that is no longer in scope.
Implementation Hints to Avoid Common Failures
- Paginate explicitly for REST endpoints that can exceed 100 items, notably:
- pull-request issue comments
- pull-request review comments
- check runs on the head SHA
- For GraphQL connections such as
reviewsandreviewThreads, check
pageInfo.hasNextPage. If true, paginate rather than truncating.
- When deduplicating retried check runs, key by check name and keep the newest
attempt using completed_at, then started_at, then created_at.
- When rendering Markdown from PowerShell, prefer building an array/list of
lines or using a single-quoted here-string. Avoid fragile inline escaping such as \' inside single-quoted PowerShell strings.
- After computing rows, verify the rendered row count exactly matches the final
in-scope PR count. If it does not, stop and reconcile the difference before returning the report.
- Exclude obvious automation accounts from human-owner and sign-off logic even
when they are not suffixed with [bot], for example Copilot, copilot-swe-agent, and similar service identities if they appear.
- Prefer a final short-lived re-fetch of the open PR inventory immediately
before rendering when the report required many per-PR API calls.
Workflow
Step 1: Scope the PR Set
- Fetch the open PR inventory for
microsoft/ebpf-for-windows. - Filter out any PR where
isDraft == trueordraft == true. - If the user asked for a narrower subset, apply that filter after you have
fetched the authoritative open, non-draft set.
- Use structured output and pagination when needed. Do not rely on the web UI.
Recommended starting point:
gh api repos/microsoft/ebpf-for-windows/pulls `--paginate `-f state=open `-f per_page=100
Step 2: Gather Per-PR Metadata
For each PR in scope, fetch or derive at least these fields:
numbertitleurl/html_urlcreatedAt/created_at- author login
- current head SHA / OID
reviewDecisionmergeablemergeStateStatusor REST mergeability equivalent- requested reviewers
- reviews, including reviewer login, state, submitted time, and the commit OID
the review applies to
- review threads, including
isResolvedandisOutdated - issue comments
- review comments
- head commit timestamp
Prefer a GraphQL per-PR fetch for review and mergeability data so you can query the current head commit, review threads, and review metadata in one place. If one large query becomes unwieldy, split the work into:
- PR inventory fetch
- Per-PR detail fetch
- Per-head-SHA check-run fetch
If a PR has more review threads, comments, or reviews than fit in one page, paginate rather than silently truncating.
Recommended execution pattern:
- Fetch the open, non-draft PR inventory.
- Fetch per-PR detail and activity data, paginating where needed.
- Compute all derived fields in structured data first.
- Re-fetch the open, non-draft PR inventory if the run was long-lived.
- Filter computed rows to the refreshed in-scope set.
- Render Markdown only after the row set is complete and reconciled.
Step 3: Compute Age
- Compute
Agefromcreated_at/createdAtto the report snapshot time. - Format exactly as
<days>dwith one decimal place, for example53.6d.
Step 4: Compute CI Status
Use the PR head SHA and fetch check runs for that exact commit.
Recommended source:
gh api repos/microsoft/ebpf-for-windows/commits/<head-sha>/check-runs `-H "Accept: application/vnd.github+json"
CI rules:
- Prefer check runs over the legacy combined commit-status API.
- If multiple check runs represent retries of the same check, keep the latest
attempt for each check name.
- Treat these conclusions as Passing:
successneutralskipped
- Treat the PR as Pending if any relevant check run is not yet complete,
or if its status is queued / waiting / requested / in progress.
- Treat the PR as Failing: <list of failing checks> if any relevant check
run concludes with a failing terminal result such as:
failurecancelledtimed_outaction_requiredstartup_failurestale- any other completed non-passing conclusion
- Only if no check runs exist at all may you fall back to legacy status
contexts, and even then do not describe the result as check-run-derived.
- Do not collapse a mixed state into "Passing" just because a combined status
summary looks green or pending.
- If the check-runs endpoint returns more than one page, fetch all pages before
deciding CI state.
Format the final cell as exactly one of:
PassingPendingFailing: check-a, check-b
Step 5: Determine Base-Branch Freshness
Use GitHub mergeability / merge-state signals from the PR object.
Map them as follows:
Up to date- Use when the PR is not behind the base branch and is not in conflict.
- Typical signals:
mergeStateStatuslikeCLEAN,HAS_HOOKS, or
UNSTABLE, with mergeable not indicating conflicts.
Needs rebase/update- Use when the PR is behind the base branch but not in conflict.
- Typical signal:
mergeStateStatus == BEHIND. Needs rebase/update (conflicts)- Use when GitHub reports merge conflicts or an equivalent dirty/conflicting
merge state.
- Typical signals:
mergeable == CONFLICTINGor
mergeStateStatus == DIRTY.
If GitHub has not computed mergeability yet, wait briefly and re-fetch rather than guessing from local branch ancestry.
Step 6: Determine Current Sign-Offs
Current sign-offs are approvals that still apply to the current head commit.
Rules:
- Start from the current head commit OID / SHA for the PR.
- Consider only reviews from human reviewers that apply to that head commit.
- Group reviews by reviewer login.
- A reviewer counts as signed off if they have an
APPROVEDreview on the
current head commit and do not have a later current-head review from the same reviewer with state CHANGES_REQUESTED or DISMISSED.
- A later
COMMENTEDreview does not cancel an otherwise valid approval by
itself.
- Ignore stale approvals on older commits.
- Ignore bot and automation accounts where possible, for example accounts
whose type is not a human user or whose login ends with [bot].
Format Sign-offs as a comma-separated list of usernames, or None.
Step 7: Determine Next Step
Compute Next step in this order:
- If there are any unresolved, non-outdated review threads, report:
Author to address comments
- Else if GitHub
reviewDecision == CHANGES_REQUESTED, report:
Author to address comments
- Else if the PR has at least one current-head sign-off and CI is
Passing,
report: Ready to merge
- Otherwise report:
Reviewers to review latest version
Do not treat outdated threads as blockers for this rule.
Step 8: Compute Freshness
Freshness is the age of the latest meaningful activity on the PR.
Candidate activity types:
- head commit
- review submission
- issue comment
- review comment
Rules:
- Collect the latest timestamp for each activity type.
- Pick the most recent timestamp across all candidate types.
- Compute age from the report snapshot time.
- Format exactly as
<days>d (<activity type>), for example
1.0d (review comment).
- If two activity types share the same timestamp, prefer this label order:
head commitreview submissionreview commentissue comment
Use review-thread comment timestamps for review comment, not the enclosing thread creation time if newer comments exist.
Step 9: Determine Next Owner
Compute Next owner after Next step.
Rules:
- If
Next stepisAuthor to address comments, setNext ownerto the PR
author login.
- Otherwise, use the current requested reviewers, excluding bots and
automation accounts where possible, for example accounts whose type is not a human user or whose login ends with [bot].
- If there are no current requested reviewers, use prior human reviewers or
commenters, excluding:
- the PR author
- bots and automation accounts
- When using prior human reviewers/commenters, order them by most recent
meaningful participation first.
- If no human next owner can be determined, report
None. - Treat known service identities as non-human even if the platform does not
label them as bots.
Format multiple owners as a comma-separated list.
Step 10: Sort and Render the Report
The final report must be Markdown and must contain:
- Header:
``markdown # microsoft/ebpf-for-windows open non-draft PRs ``
- A snapshot timestamp line.
- An ordering note stating:
Sorted by freshness, oldest to newest.
- A Markdown table with these columns in this exact order:
PRAgeFreshnessCIBase branchNext stepNext ownerSign-offs
- PR column formatting:
[#1234](url) PR title
- Value formatting:
Age:53.6dFreshness:1.0d (review comment)CI:Passing,Pending, orFailing: <checks>Sign-offs: comma-separated usernames orNone
- Final ordering:
- primary key: freshness, oldest to newest
- secondary key: PR age, oldest to newest
- tertiary key: PR number, ascending
- A closing
Notes:section that briefly explains:
- how freshness is computed
- why check runs are preferred over combined commit status
- how
Author to address commentsis decided - how
Next owneris chosen
Do not include draft PRs anywhere in the table.
Verification Checklist
Before you finalize the report, verify all of the following:
- Every row is an open, non-draft PR.
- Every
PRcell contains the PR number, URL, and title. AgeandFreshnessuse one decimal place anddunits.CIwas computed from check runs whenever check runs existed.Base branchuses GitHub mergeability / merge-state signals.Next stepuses unresolved non-outdated threads before review decision.Sign-offsinclude only current-head approvals.Next ownerexcludes bots where possible.- No row was lost during rendering: row count matches the final in-scope PR
count.
- If the run was long-lived, the final in-scope PR set was refreshed just
before rendering.
- The table is sorted by freshness, oldest to newest.
- The report ends with a
Notes:section covering the required heuristics.
Non-Goals
- Do not review code content inside the PRs unless the user explicitly asks.
- Do not include draft, closed, or merged PRs in this report.
- Do not rely on GitHub's combined commit-status summary when check-run data is
available.
- Do not guess stale approvals, mergeability, or next-owner state from local
git history alone.