Review code changes in dotnet/winforms for concrete problems. Always use this skill when GitHub Copilot code review is requested on a pull request, or when a user asks to review, inspect, audit, or check a PR, branch, commit range, staged changes, uncommitted changes, or local changes in this repository. Supports hosted GitHub.com reviews that post findings directly and interactive reviews of local or remote changes. Focus on correctness, compatibility, native resource and handle lifetime, designer serialization, accessibility, DPI/rendering, performance, security, and regression coverage; omit praise, style-only nits, and speculative concerns.
75
94%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Low
Low-risk findings worth noting
Review changes as a skeptical WinForms maintainer. Identify concrete problems that could affect customers, maintainers, or repository health. A review may target a GitHub pull request or changes that exist only on the user's machine.
The repository is a mature Windows desktop framework with strict compatibility requirements. Small changes can affect native window lifetime, message dispatch, layout, accessibility, design-time serialization, binary and source compatibility, high DPI behavior, or applications that depend on legacy quirks. Treat the change description as a claim to verify, not as proof.
If this skill is running inside GitHub Copilot code review on GitHub.com, GitHub Mobile, or another hosted Copilot code review surface, use hosted PR mode. The platform already supplies the pull request identity, head checkout, diff, repository context, and review-comment publishing mechanism.
Use the platform-provided PR context and tools. Do not run gh to rediscover
the PR, fetch pull refs, create a worktree, ask which comments to publish, or
wait for an additional user response. Repository skills are loaded from the
PR's head branch, so apply the version of this skill present in that branch.
Use PR mode when the user supplies a PR number or URL, asks to review the
current branch's PR, or explicitly refers to a pull request. The default
repository is dotnet/winforms.
Outside hosted Copilot code review, if the user asks for a PR review without an identifier, discover a PR for the current branch:
gh pr view --repo dotnet/winforms --json number,title,headRefName,urlIf no PR exists, continue in local mode. Do not create a PR.
Use local mode when the user asks to review local, uncommitted, staged, unstaged, untracked, committed-but-unpushed, or branch changes. Git is the source of truth; do not require a PR.
Honor an explicit scope. Otherwise use these defaults:
| Request | Reviewed change set |
|---|---|
| "review staged changes" | Index only: git diff --staged |
| "review unstaged changes" | Tracked working-tree changes: git diff |
| "review uncommitted changes" | Index + tracked working tree: git diff HEAD, plus untracked files |
| "review this commit/range" | The named commit or range |
| "review this branch against X" | Merge base with the named base through the current working tree |
| "review my local changes" | Current branch changes from the origin/main merge base, plus index, working tree, and untracked files |
For the comprehensive local default, one diff from the merge base to the working tree includes committed branch changes plus staged and unstaged tracked changes:
git status --short --branch
git fetch origin main --quiet
$base = git merge-base HEAD origin/main
git diff --name-status $base
git diff --find-renames --find-copies $base
git ls-files --others --exclude-standardIf origin/main is unavailable, fall back to local main. Never include
ignored build output. Untracked files do not appear in git diff; list and
read them explicitly. Note the exact scope used in the review result.
Use the checkout and PR diff supplied by GitHub Copilot code review. Review the
head commit that the platform selected and use its repository-wide context
gathering and configured MCP tools when relevant. Do not create a second
checkout or temporary worktree, and do not use gh api to publish comments;
return findings through the hosted review mechanism.
Read and follow the
interactive PR review workflow. It
resolves the PR head in an isolated worktree, preserves the user's checkout,
and documents safe cleanup and comment publication. Never use
gh pr checkout, stash, or switch branches in the user's working tree.
For both modes:
PublicAPI files, resources, and
documentation even when they are unchanged.git log, git blame, linked issues, and earlier PRs when they explain
a compatibility constraint or a deliberately unusual implementation.In PR mode, form an independent understanding of the diff before relying on
the PR description. Inspect existing review threads and status checks with the
host-provided context and tools so findings are not duplicated. In an
interactive session, use these gh fallbacks:
gh pr view $pr --repo dotnet/winforms --comments
gh api --paginate "repos/dotnet/winforms/pulls/$pr/comments?per_page=100"
gh pr checks $pr --repo dotnet/winformsDo not duplicate an existing review comment. A green CI run is useful evidence, not proof that the behavior is correct.
Use the classification to choose the relevant review passes and supporting skills.
| Area | Common paths | Primary risks |
|---|---|---|
| Controls and runtime | src\System.Windows.Forms\** | Compatibility, handle creation/recreation, message handling, layout, events, painting, threading |
| Native primitives and interop | src\System.Windows.Forms.Primitives\**, src\System.Private.Windows.Core\** | ABI correctness, marshalling, pointer width, native ownership, last-error handling |
| Drawing and GDI+ | src\System.Drawing.Common\**, src\System.Private.Windows.GdiPlus\**, src\System.Drawing\** | Graphics state, GDI/GDI+ lifetime, geometry, rendering parity, version guards |
| Designer | src\System.Windows.Forms.Design\**, src\System.Drawing.Design\**, src\System.Design\** | CodeDOM serialization, property metadata, services, out-of-process designer behavior |
| Accessibility | src\Accessibility\**, runtime **\Accessibility\**, accessibility tests | UIA/MSAA contracts, roles, control types, navigation, patterns, events, runtime IDs |
| Analyzers and generators | src\System.Windows.Forms.Analyzers*\**, src\System.Windows.Forms.PrivateSourceGenerators\** | C#/VB parity, false positives, generated-code handling, diagnostics/code-fix correctness |
| Visual Basic | src\Microsoft.VisualBasic*\** | Legacy behavior, C#/VB parity where intended, project and runtime compatibility |
| Tests | src\test\**, project-local tests\** | Scenario fidelity, STA/thread isolation, native cleanup, handle-state assertions |
| Build and packaging | eng\**, pkg\**, root props/targets, pipelines | Arcade flow, package contents, source build, architecture/configuration conditions |
| Contributor and AI guidance | docs\**, .github\skills\**, .github\** | Commands or conventions drifting from executable repository behavior |
Read the relevant existing skill when its area appears in the diff:
Repository documentation and the nearest existing implementation take precedence over generic .NET advice.
base calls, relaxed validation, different exceptions,
and changes visible to derived controls.For public or protected surface changes:
PublicAPI.Unshipped.txt; shipped APIs must not disappear or
change incompatibly.PublicAPI nullability, modifiers, parameter
names, and return types.System.Windows.Forms, new APIs are stable by default and are not wrapped
in NETxx_0_OR_GREATER guards. System.Drawing additions follow their
area's current target-version guard. Do not apply one area's rule to another.PropertyStore use where per-instance fields
would increase control size, the default is represented consistently, and
change events are raised only when the effective value changes.DefaultValue,
DesignerSerializationVisibility, Browsable, Bindable, Localizable,
SRCategory, SRDescription, EditorBrowsable, type converters, and
editors.EventArgs/delegate conventions, Events storage, virtual
OnXxx methods, and XML documentation of customer-visible behavior.IsHandleCreated == false.CreateHandle, DestroyHandle, RecreateHandle, CreateParams, and
WndProc changes, trace state across recreation and disposal. Verify window
styles, message results, base/def-window processing, and child/native state.SendMessage, event callbacks, layout,
accessibility queries, handle creation, or user overrides. State must be
valid before calling code that can reenter.GCHandle. Release each resource with its
matching API exactly once, including exceptional paths. Never delete borrowed
or stock objects.DefaultValue against the actual getter default. For complex defaults,
verify private ShouldSerializeXxx and ResetXxx methods.GraphicsPath behavior, version guards, and meaningful pixel/geometry tests.SR.resx resources and that
resource keys/format arguments are correct. Generated localization churn is
not itself evidence of a bug.eng\common unless they are clearly part of the
Arcade code-flow process.Map each changed production path to an observable risk before evaluating tests. Do not accept "tests were added" without checking what they prove.
| Change | Expected evidence |
|---|---|
| Control property/event/API | Default, set/get, idempotency, event lifecycle, no-handle and with-handle behavior in src\test\unit\System.Windows.Forms |
| Handle/message/native state | Tests for pre-handle, created handle, recreation/disposal, native failure, and relevant 32/64-bit or thread behavior |
| Designer metadata/serialization | Designer unit tests and, when behavior crosses the boundary, integration/round-trip coverage |
| Accessibility | Property, role/control type, navigation/pattern, focus/event behavior with the relevant accessibility level/configuration |
| Rendering/layout/DPI | Geometry or bitmap assertions, meaningful DPI/theme variants, and both integer/float overloads where applicable |
| Analyzer/code fix/generator | Positive and negative cases, generated code, language-version edges, and C#/VB parity when both front ends exist |
| Bug fix | A focused test that fails before the fix for the reported scenario |
Use [WinFormsFact]/[WinFormsTheory] for tests requiring controls or a
synchronization context. Tests involving process-wide UI state, clipboard,
drag/drop, or other global state may require sequential isolation. Async tests
must propagate TestContext.Current.CancellationToken.
Do not require tests for documentation-only changes, comments, generated-only updates, or mechanical refactors whose behavior equivalence is demonstrated. When reporting a coverage gap, name the exact regression scenario and where the test belongs.
Run only validation that helps confirm or refute a suspected problem. Prefer
the smallest relevant test project or filtered test. This repository uses
xUnit v3 on Microsoft.Testing.Platform (not the legacy VSTest adapter). Note
that dotnet test --filter does not work; filtering is still available through
dotnet test -- --filter-method/--filter-class ... or by running the built test
executable directly (see the running-tests skill for exact command syntax).
Use .\build.cmd for an authoritative repository build because it enables the
Arcade CI configuration, PublicAPI analyzers, code-style/documentation
analyzers, and warnings-as-errors. A single-project dotnet build is only
inner-loop evidence and must not be presented as equivalent to CI.
Record exactly what was run and the result. Do not claim a scenario was tested when it was only inspected. Do not turn pre-existing or unrelated failures into findings against the change.
In hosted PR mode, use the ephemeral environment and setup supplied by Copilot code review. Do not create another checkout or attempt to access the user's local machine. An environment limitation is not a finding against the PR.
Prioritize:
Do not report:
For moved or rewritten code, compare implementations line by line and treat the new location as reviewed code. Check callers of removed types/members and any state or validation previously supplied by the old owner.
Publish each verified problem directly as an actionable review comment, using the hosted review system's severity labels and comment format. Attach a finding to the smallest relevant changed line or range. If the problem spans files or cannot be attached accurately to a changed line, put it in the review overview.
Keep one root cause per comment. Explain the reachable mechanism, customer or
maintainer impact, and concise fix direction. Do not emit a numbered
"findings for selection" report, ask the user which comments to post, invoke
gh api, or defer comments to a later interactive step.
If no problems meet the evidence threshold, publish no inline comments and let the hosted review overview report that no issues were found. Do not invent a finding to ensure the review has comments.
Order findings by severity, then confidence. Use this format:
## Findings
1. **[P1][High] Preserve native state when recreating the handle**
— `src\System.Windows.Forms\...\Control.cs:123`
`RecreateHandle()` now destroys the native state before it is captured, so
the value is reset after a DPI transition. This is reachable from ...
**Fix direction:** Capture ... before ... and restore it after ...Severity:
Confidence:
Each finding must:
If there are no findings, say:
## Findings
No findings.
**Residual risk:** <untested or unverified area, or "None identified">
**Review scope:** <exact diff/range and whether untracked files were included>
**Validation:** <commands run, or "Not run">Do not invent a finding to avoid an empty review.
This section applies only to PR mode.
The review request itself authorizes publication. Submit all verified findings
through the platform's normal review output without requesting further user
selection or confirmation. Let the hosted product apply its configured review
event and approval policy; do not independently submit another review through
gh or the GitHub API.
Before returning a comment, check the available existing review threads to avoid duplication. Post one root cause once, on a changed line when possible. The Copilot reviewer identity already discloses that the review is AI-generated, so no additional disclosure is required.
Follow the publication procedure in the interactive PR review workflow. Present findings for selection before using a GitHub review API, and never post draft, duplicate, or unselected findings.
Local mode ends after presenting findings; there is no review to post.
a84cf1f
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.