Review Azure SDK management-plane pull requests, check naming conventions, API compatibility, and code quality.
60
71%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Fix and improve this skill with Tessl
tessl review fix ./.github/skills/azure-sdk-mgmt-pr-review/SKILL.mdReview Azure SDK for .NET management library PRs in three phases: 1. Versioning, 2. API Review, 3. Breaking Change Detection. Run phases in order. Versioning failures are blocking, but continue into API review unless the baseline cannot be determined reliably.
Check the package .csproj, CHANGELOG.md, and compatibility files. Comment on every violation. Phase 1 violations are blocking; use the Finding Severity policy to determine the final review event across all phases.
Rules:
1.x -> 2.0.0 as Critical.ApiCompatVersion. It enforces compatibility against the last stable release. If removed, recover the prior value from base branch or latest released tag for later phases.WirePathAttribute removal diffs may use targeted entries in eng/apicompatbaselines/<Project>.xml.Continue to Phase 2 unless the versioning issue makes the API-review scope impossible to determine, e.g. ApiCompatVersion was removed and no prior stable baseline can be recovered. In that narrow case, request changes and say API review was skipped because the baseline is unknown.
Review only new or changed public API relative to the latest stable release. Existing shipped API that is unchanged is out of scope.
ApiCompatVersion from .csproj. If absent and never present, treat the whole API surface as new and skip breaking-change checks.<PackageName>_<Version>, e.g. Azure.ResourceManager.Foo_1.0.0, under sdk/<service>/<PackageName>/api/<PackageName>.net10.0.cs or older TFM variants.Fetch existing PR comments and reviews first. Suppress duplicate inline and non-inline findings already raised by humans or earlier automation. Reinforce existing threads by replying instead of opening duplicates.
Run the trusted naming scanner:
pwsh .github/skills/azure-sdk-mgmt-pr-review/Check-MgmtNamingRules.ps1 -ApiFilePath <current-api-file> -BaselineApiFilePath <baseline-api-file>Omit -BaselineApiFilePath when there is no stable baseline. Use -PackagePath only for local/manual trusted reviews. In GitHub Agentic Workflow mode, run the scanner from the base branch against explicit API files fetched from PR/baseline; do not execute PR scripts.
When a baseline is supplied, the scanner also compares required/optional parameter metadata for every matching public method and constructor. Investigate every OPTPARAM001 and OPTPARAM002 finding as a potential blocking source-compatibility issue; ApiCompat may not report them.
Before requesting restoration for OPTPARAM001, inspect the complete overload set and verify the change compiles for representative positional and named calls. A compatibility shim may need to keep parameters required when restoring defaults would introduce CS0121; the text scanner intentionally reports these cases rather than approximating the C# overload-resolution binder. Neither [Obsolete] nor [EditorBrowsable] changes overload resolution, and [OverloadResolutionPriority] only helps consumers compiling with C# 13 or later.
Treat scanner API-file line numbers as symbol identifiers, not final comment targets. Resolve each finding to generated source, customization source, or TypeSpec customization files before commenting.
Run contextual naming exhaustively using inventory mode:
pwsh .github/skills/azure-sdk-mgmt-pr-review/Check-MgmtNamingRules.ps1 -ApiFilePath <current-api-file> -BaselineApiFilePath <baseline-api-file> -ListNewTypesEvaluate every NEW class/struct/enum. Verdicts: OK, Flag, or OK (low confidence). The number of verdicts must equal the number of NEW entries. Report Contextual naming: evaluated N new public types, flagged M.
Review API files, src/Generated/, TypeSpec customizations (client.tsp, main.tsp, tspconfig.yaml), and SDK customizations for issues not covered by the scanner.
Scanner rule families include OPTPARAM001, OPTPARAM002, SUFFIX001-SUFFIX010, RESINFIX001, RESNAME001, ACRONYM001, ACRONYM002, ARMCOMMON001, BOOL001, DATETIME001, and TTL001. Contextual naming is intentionally manual; the scanner only provides the bounded worklist.
Use api/*.cs for analysis only. Do not target API listing files for inline comments; large API files can fail GitHub review-position resolution.
Resolve findings as follows:
src/Generated/Models/<TypeName>.cs.src/Generated/<TypeName>.cs.src/Generated/**/<TypeName>.Serialization.cs.src/Customize/**, src/Customization*/**, src/Customized*/**, or file containing [CodeGenType], [CodeGenSuppress], [CodeGenMember], or the custom member.client.tsp, main.tsp, or tspconfig.yaml when in the PR diff.Only emit inline comments for lines in the PR diff. If the correct source line is not in the diff, put the finding under Non-inline findings in the review body. For generated-source comments, request a TypeSpec/decorator/generator fix; never imply generated code should be hand-edited.
Naming suffixes:
| Avoid suffix | Prefer | Exception |
|---|---|---|
Parameter(s) | Content / Patch | - |
Request | Content | - |
Options | Config | ClientOptions |
Response | Result | - |
Update | Patch / Content | - |
Data | remove | Only if not ResourceData / TrackedResourceData |
Definition | remove | Unless removal conflicts with another resource |
Operation | Data / Info | Operation<T> |
Collection | Group / List | Domain-specific names, e.g. MongoDBCollection |
ARM common types must not be redefined. Reuse framework types, or rename service-specific wire variants with RP context and document why they differ: OperationStatusResult, ManagedServiceIdentity, ManagedServiceIdentityType, ManagedServiceIdentityPatch, UserAssignedIdentity, SystemData, TagsUpdate, TagsPatch, ErrorResponse, ErrorDetail, TrackedResource.
Resource naming:
Resource suffix when the remaining noun is descriptive; keep it when removal makes the name generic, e.g. GenericResource.Data only when deriving from ResourceData / TrackedResourceData; otherwise prefer Info.Resource before Data or Collection: use VirtualMachineData, not VirtualMachineResourceData; use VirtualMachineCollection, not VirtualMachineResourceCollection.*PrivateLinkResourceData / *PrivateLinkResourceCollection are allowed because PrivateLinkResource is the ARM resource name.RESNAME001: after stripping Resource, Data, or Collection, a resource trio inheriting ArmResource, ResourceData / TrackedResourceData, or ArmCollection must still carry RP/domain context. Flag single generic nouns like Drill, Goal, Recovery, Enrollment; recommend renaming the whole trio together. GenericResource is the only built-in exception.Operation/model/property rules:
[Model]Patch.[Model]Content or [Model]Data.Is, Can, Has, Does, Should, Allow, Enable, Disable, Use, Support.DateTimeOffset properties end with On or At.MonitoringIntervalInSeconds.TimeToLiveIn<Unit>.Tls1_0, Ver5_6.@@clientName(Enum.Member, Azure.ClientGenerator.Core.exact("Old_Name"), "csharp") over SDK-side [CodeGenMember].Check[Resource/RP name]NameAvailability; model/response: [Resource/RP name]NameAvailabilityXXX; unavailable reason enum: [Resource/RP name]NameUnavailableReason.abstract.ListOperations methods.Acronyms:
Aes, Tcp, Http.Id and Vm.Contextual type naming:
PublicNetworkAccess, EncryptionStatus, PrivateEndpointConnection, Scope, GroupScope, Sensitivity, ManagedRuleSetException unless sufficiently scoped by RP/resource/domain context.StorageAccountPublicNetworkAccess, CosmosDBEncryptionStatus, KeyVaultPrivateEndpointConnection, FrontDoorRuleScope, FrontDoorSensitivityType.*Properties models.Naming fix recommendation:
@@clientName(..., "csharp") in client.tsp, e.g. @@clientName(PublicNetworkAccess, "DurableTaskPublicNetworkAccess", "csharp");.@@clientName(..., Azure.ClientGenerator.Core.exact("Old_Name"), "csharp").[CodeGenType("OriginalGeneratedName")] on a renamed partial class.TypeSpec-backed rename customization (TSPRENAME001):
tsp-location.yaml, including brand-new packages, feature/refresh PRs, and migrations.[CodeGenType], [CodeGenMember], [CodeGenSuppress], wrapper members, or forwarding methods.TSPRENAME001 as blocking. Require scoped @@clientName(TypeSpecTarget, "CSharpName", "csharp") in the spec repository's client.tsp and regeneration; do not accept SDK custom code as an alternative.Type formatting:
| Property pattern | Expected type |
|---|---|
UUID-valued *Id / *Guid | Guid |
String *Id / *ResourceId holding ARM resource ID | ResourceIdentifier |
ResourceType or *Type for resource types | ResourceType |
etag | ETag |
location / locations | Consider AzureLocation |
size | Consider int / long instead of string |
Only flag *Id / *ResourceId for Guid or ResourceIdentifier when the generated C# type is string. Numeric, Guid, or other non-string IDs are intentional domain identifiers and should not be flagged. In TypeSpec, UUID-valued properties should use the uuid scalar.
Duration/interval TypeSpec format:
P1DT2H59M59S): duration scalar.2.2:59:59.5000000): @encode(DurationConstant).SDK migration method renames:
If ApiCompatVersion exists, check breaking changes after Phase 2. Locally, build the project and inspect ApiCompat errors. In untrusted pull_request_target workflows, do not build PR code; rely on CI/check results and API diffs unless the workflow explicitly runs in a trusted context.
For each ApiCompat error, list the removed/changed API and target the relevant source line when possible. Do not fix it during review; request mitigation through customization code, generator/spec features, or the mitigate-breaking-changes skill. Any unmitigated breaking change is blocking. If no ApiCompatVersion exists, skip this phase.
ApiCompat passing is not sufficient for source compatibility. Before declaring this phase complete, investigate every OPTPARAM001 and OPTPARAM002 finding against the complete overload set. Do not infer that a previously reviewed overload covers its siblings; compare every matching signature against the stable baseline.
Report every finding and recommend resolving it in the current PR. Do not defer findings based on whether the package is beta or stable. Severity controls only the review event.
| Severity | Finding categories | Review event |
|---|---|---|
| Blocking | Phase 1 versioning violations; deterministic scanner findings other than advisory TYPE001 and TYPE003 findings; all contextual naming findings; naming, suffix, acronym, resource-name, and ARM common-type violations; TSPRENAME001; required/optional parameter compatibility findings; unmitigated breaking changes; manual generated-code edits; and migration-specific violations | REQUEST_CHANGES |
| Non-blocking | Advisory type-formatting recommendations, including scanner rules TYPE001 and TYPE003 and recommendations explicitly phrased as Consider, such as using ResourceIdentifier, AzureLocation, or a numeric type instead of string, when they do not also violate a blocking compatibility or API rule | COMMENT |
When a review contains both severities, use REQUEST_CHANGES. Do not label a naming finding as non-blocking.
Submit one PR review. Prefer inline comments on commentable source files; put unattachable findings in Non-inline findings. Do not post findings as general PR comments. Never use APPROVE.
Agentic Workflow mode:
create_pull_request_review_comment per inline finding.submit_pull_request_review.REQUEST_CHANGES or COMMENT.pull_request_target.Outside Agentic Workflow mode, use gh api repos/{owner}/{repo}/pulls/{pull_number}/reviews to submit one review with comments, event, and summary body.
Review body must include:
bc946a1
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.