Skip to content

Add Trim/NativeAOT safety rules to code review skill#34962

Open
PureWeen wants to merge 1 commit into
mainfrom
guidance/trim-aot-code-review-rules
Open

Add Trim/NativeAOT safety rules to code review skill#34962
PureWeen wants to merge 1 commit into
mainfrom
guidance/trim-aot-code-review-rules

Conversation

@PureWeen
Copy link
Copy Markdown
Member

Summary

Add Section 23 (Trim / NativeAOT Safety) to the code review skill's review-rules.md, covering 6 checks for IL2026/IL3050 annotation chain analysis.

Motivation

During investigation of Issue #34867 (HybridWebViewHandler IL3050 warnings), we ran a controlled experiment where multiple AI models were asked to diagnose and fix the issue:

Model Without reading code With reading code
Sonnet 4 [UnconditionalSuppressMessage]
Opus 4.5 ✅ Extract method
Sonnet 4.6 ✅ Extract method
Opus 4.6 ✅ Extract method
GPT-5.4 ✅ Extract method

Models that failed shared a shallow heuristic: feature switch guards the code → warning is false positive → suppress it. They didn't reason about why [FeatureGuard] wasn't working (indirect annotation chain through [DynamicallyAccessedMembers] on generic type params).

The correct fix (PR #34958 by @simonrozsival) extracts the annotated type reference into a separate method with matching [RequiresDynamicCode]/[RequiresUnreferencedCode] attributes, converting the indirect chain into a direct call that the [FeatureGuard] can suppress.

What changed

  • review-rules.md: New Section 23 with 6 review checks:

    1. [UnconditionalSuppressMessage] for IL2026/IL3050 is almost always wrong
    2. [FeatureGuard] does NOT suppress indirect annotation chains
    3. Extract-method pattern for feature-guarded annotated types
    4. Don't reference annotated types from extracted helper attributes
    5. Read the full annotation chain before proposing any fix
    6. #pragma warning disable ILxxxx is equally wrong
  • SKILL.md: Added "Safety" category referencing the new section

Why the code review skill (not just an instruction file)

The existing trim-aot.instructions.md uses applyTo globs (**/RuntimeFeature.cs, **/*Handler*.cs, etc.) that only fire when editing matching files. This means:

  • ❌ Issue triage (commenting on issues) — never fires
  • ❌ PR review where agent reads diffs but doesn't open matching files — may not fire
  • ✅ Code review skill — always invoked explicitly, reliable

The code review skill is the right home because it's always explicitly invoked and will be integrated into the try-fix pipeline.

Add Section 23 to review-rules.md covering IL2026/IL3050 annotation
chain analysis, the extract-method pattern for feature-guarded types,
and why [UnconditionalSuppressMessage] is almost always wrong for
these warnings.

Sourced from the HybridWebViewHandler incident (Issue #34867,
PR #34958) where AI agents consistently recommended suppression
instead of the correct structural fix when they didn't read the
source code first.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 14, 2026 18:42
@github-actions
Copy link
Copy Markdown
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 34962

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 34962"

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the .github/skills/code-review skill documentation to add explicit Trim/NativeAOT safety guidance (focused on IL2026/IL3050 annotation-chain analysis) motivated by the HybridWebViewHandler IL3050 incident.

Changes:

  • Added Section 23 (“Trim / NativeAOT Safety”) to review-rules.md with six concrete review checks to discourage suppression-based “fixes” and encourage correct structural patterns.
  • Updated SKILL.md to reflect the expanded rule set and added a new “Safety” category callout.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
.github/skills/code-review/references/review-rules.md Adds a new Section 23 with reviewer heuristics for Trim/NativeAOT (IL2026/IL3050) issues and recommended fix patterns.
.github/skills/code-review/SKILL.md Updates the skill metadata/description and lists “Safety” as a review category referencing the new section.

|-------|-----------------|
| **`[UnconditionalSuppressMessage]` for IL2026/IL3050 is almost always wrong** | If a PR adds `[UnconditionalSuppressMessage("AOT", "IL3050:...")]` or `[UnconditionalSuppressMessage("Trimming", "IL2026:...")]`, it is very likely hiding a real problem rather than fixing it. The correct response is to restructure the code so the analyzer can prove safety — typically via the extract-method pattern below. Only accept suppression if the PR includes proof that the code path is genuinely unconditionally safe (e.g., the type is explicitly preserved). (Issue #34867 — simonrozsival) |
| **`[FeatureGuard]` does NOT suppress indirect annotation chains** | `[FeatureGuard(typeof(RequiresDynamicCodeAttribute))]` on a `RuntimeFeature` property suppresses IL3050 only for **direct** calls to `[RequiresDynamicCode]` methods inside the guarded block. It does **not** suppress warnings from indirect chains — e.g., generic type parameters with `[DynamicallyAccessedMembers]` that trace back to an annotated type. If a PR claims "the feature guard handles it" but the warning goes through a generic like `AddHandler<T, TRender>()`, the guard is NOT sufficient. (Issue #34867 — simonrozsival) |
| **Extract-method pattern for feature-guarded annotated types** | When registering a type annotated with `[RequiresDynamicCode]` or `[RequiresUnreferencedCode]` inside a `[FeatureGuard]`-protected block, and the registration goes through a generic API with `[DynamicallyAccessedMembers]`, extract the call into a separate method annotated with the same attributes. This converts the indirect chain into a direct call that the `[FeatureGuard]` can suppress. Reference: `AppHostBuilderExtensions.AddHybridWebViewHandler()` in `src/Controls/src/Core/Hosting/AppHostBuilderExtensions.cs`. (PR #34958 — simonrozsival) |
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reference to AppHostBuilderExtensions.AddHybridWebViewHandler() appears to be stale/incorrect: there is no AddHybridWebViewHandler method in src/Controls/src/Core/Hosting/AppHostBuilderExtensions.cs (current code registers HybridWebView inside AddControlsHandlers / SetupDefaults). Please update this reference to the actual helper/method name used in the repo (or link to a stable permalink to the relevant PR/commit) so reviewers can find the example quickly.

Suggested change
| **Extract-method pattern for feature-guarded annotated types** | When registering a type annotated with `[RequiresDynamicCode]` or `[RequiresUnreferencedCode]` inside a `[FeatureGuard]`-protected block, and the registration goes through a generic API with `[DynamicallyAccessedMembers]`, extract the call into a separate method annotated with the same attributes. This converts the indirect chain into a direct call that the `[FeatureGuard]` can suppress. Reference: `AppHostBuilderExtensions.AddHybridWebViewHandler()` in `src/Controls/src/Core/Hosting/AppHostBuilderExtensions.cs`. (PR #34958 — simonrozsival) |
| **Extract-method pattern for feature-guarded annotated types** | When registering a type annotated with `[RequiresDynamicCode]` or `[RequiresUnreferencedCode]` inside a `[FeatureGuard]`-protected block, and the registration goes through a generic API with `[DynamicallyAccessedMembers]`, extract the call into a separate method annotated with the same attributes. This converts the indirect chain into a direct call that the `[FeatureGuard]` can suppress. Reference: `HybridWebView` registration in `AddControlsHandlers` / `SetupDefaults` in `src/Controls/src/Core/Hosting/AppHostBuilderExtensions.cs`. (PR #34958 — simonrozsival) |

Copilot uses AI. Check for mistakes.
description: >-
Deep code review of PR changes for correctness, safety, and MAUI conventions.
Uses independence-first assessment (code before narrative) with 345 lines of
Uses independence-first assessment (code before narrative) with 364 lines of
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SKILL description says the rules file has "364 lines", but references/review-rules.md currently has 365 lines. Consider either updating the number or (more robust) removing the hard-coded line count so it doesn't drift each time rules are edited.

Suggested change
Uses independence-first assessment (code before narrative) with 364 lines of
Uses independence-first assessment (code before narrative) with

Copilot uses AI. Check for mistakes.
@kubaflo
Copy link
Copy Markdown
Contributor

kubaflo commented May 24, 2026

/review -b feature/refactor-copilot-yml

@MauiBot
Copy link
Copy Markdown
Collaborator

MauiBot commented May 24, 2026

⚠️ Merge Conflict Detected — This PR has merge conflicts with its target branch. Please rebase onto the target branch and resolve the conflicts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants