[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6AE5PCFTF38MCSE9V7DK0Q5":3,"skill-same:01M6AE5PCFTF38MCSE9V7DK0Q5":83},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":49,"commitSha":50,"skillDirectory":51,"forksCount":52,"repositoryHtmlUrl":53,"repositoryHomepageUrl":54,"ownerHtmlUrl":55,"ownerBlogUrl":56,"ownerDescription":57,"updatedAt":58,"install":59,"resources":72},"01M6AE5PCFTF38MCSE9V7DK0Q5","roslyn-analyzers",null,"Build, review, debug, package, and test Roslyn diagnostic analyzers, code fix providers, and incremental source generators. Use for DiagnosticAnalyzer, CodeFixProvider, IIncrementalGenerator, IOperation analysis, Microsoft.CodeAnalysis dependency pinning, Roslyn test harnesses, C#\u002FVB tests, and analyzer NuGet packaging.","github\u002Fawesome-copilot","github","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F9919?v=4","01M6AC83DS133TPXFSP1DHNCC6","GitHub","01M6AD3PBDYPK7NVFJNJ66Y8RS",41046,"MIT","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Froslyn-analyzers\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"roslyn analyzers","fix","for","harnesses","analyzer","C#","tests","build","dependency","use","packaging","review","analysis","dependency pinning","package","nuget","code","debug","microsoft","test","2026-11-10 10:12:30",false,"---\nname: roslyn-analyzers\ndescription: 'Build, review, debug, package, and test Roslyn diagnostic analyzers, code fix providers, and incremental source generators. Use for DiagnosticAnalyzer, CodeFixProvider, IIncrementalGenerator, IOperation analysis, Microsoft.CodeAnalysis dependency pinning, Roslyn test harnesses, C#\u002FVB tests, and analyzer NuGet packaging.'\n---\n\n# Roslyn Analyzers and Source Generators\n\nUse this workflow when adding or changing a Roslyn analyzer, code fix, source generator, tests, dependencies, or package layout. First inspect the repository's target frameworks, central package management, test framework, analyzer and generator conventions, diagnostic ID allocation, localization, and packaging. Preserve established conventions unless they conflict with the compatibility rules below.\n\n## Non-negotiable design rules\n\n- Prefer `IOperation`-based analysis wherever possible. Register the narrowest applicable `OperationKind` and inspect typed operations such as `IInvocationOperation`, `IAwaitOperation`, or `IObjectCreationOperation`. This usually supports C# and VB with one analyzer and gives direct access to symbols and conversions.\n- Use syntax analysis only for inherently syntactic rules or syntax not represented adequately by `IOperation`. A syntax-node callback already has a `SemanticModel`; do not call `Compilation.GetSemanticModel` or fetch another semantic model from it. Repeated semantic-model creation is expensive and often indicates that an operation or symbol action is the better abstraction.\n- Every analyzer must support C#. VB.NET support is optional until requested or established repository precedent requires it. A language-neutral operation analyzer may declare both languages. If VB support is promised, include equivalent C# and VB snippets in tests; do not infer VB correctness from shared implementation alone.\n- Keep analyzer and code-fix providers in distinct assemblies. The analyzer project must never reference Roslyn Workspaces packages. Workspaces dependencies belong only in the code-fix and test projects.\n- Analyzer callbacks must be stateless or concurrency-safe. Call `EnableConcurrentExecution()`. Make an explicit generated-code choice with `ConfigureGeneratedCodeAnalysis(...)`; follow repository policy rather than silently accepting the default.\n- Respect cancellation where APIs expose a token. Do not retain compilations, operations, syntax trees, symbols, or semantic models in static state.\n- Avoid `InternalsVisibleTo`. Test analyzers through their public `DiagnosticAnalyzer` and `CodeFixProvider` APIs and the Roslyn test harness. A small analyzer helper may be public when direct testing is genuinely useful, but most behavior should be tested end to end.\n- Centralize metadata names and member names instead of propagating magic strings. Use one shared static catalog for fully qualified type names, namespaces, and API member names.\n- Never identify a symbol, including an attribute class, by calling `ToDisplayString()` and comparing the result with a string literal. Resolve an expected named type from the `Compilation` once by metadata name. To resolve a method, property, field, or event, first resolve its containing type, then select the expected member by name and signature. Compare encountered symbols with `SymbolEqualityComparer.Default.Equals(actual, expected)`. When generic substitutions are irrelevant, compare named types, properties, fields, and events by `OriginalDefinition`; compare methods after replacing a reduced extension method with `ReducedFrom ?? method` and then taking `OriginalDefinition`. Normalize both expected and encountered symbols, and inspect type arguments separately when they are part of the match. Display strings are for presentation, not identity, and can vary with formatting, aliases, qualification, nullability, and other context.\n- Document every diagnostic ID. When the repository uses Docfx, put analyzer documentation under its Docfx tree, typically `docfx\u002Fanalyzers`, and include each page in the relevant table of contents.\n- Set every analyzer assembly's version precisely enough that each commit produces a unique assembly version. When using Nerdbank.GitVersioning, give each analyzer project its own `version.json` with `assemblyVersion.precision` set to `revision` and ensure that repository-wide MSBuild properties do not prevent that file from being discovered.\n- Source generators must implement `IIncrementalGenerator`, not `ISourceGenerator`. Design the provider graph so unchanged inputs remain cached and do not regenerate output.\n- Source generators must use a small `SourceWriter` abstraction for deterministic newlines, indentation, encoding, and balanced output. Start from [SourceWriter.cs](.\u002Freferences\u002FSourceWriter.cs) and tailor its namespace and target-framework details to the receiving repository.\n\n## Implementation workflow\n\n1. Write down examples that must report and near-misses that must not report. Decide the exact diagnostic span and message arguments before implementation.\n2. Determine whether the rule is semantic. Prefer, in order, operation actions, operation-block actions, symbol actions, compilation-start actions that register one of those actions, and finally syntax actions.\n3. Resolve well-known named types once in a compilation-start action with `Compilation.GetTypeByMetadataName` when needed. Resolve expected members from the resulting containing type by name and full signature; `GetTypeByMetadataName` does not resolve methods, properties, fields, or events. If a required type or member is absent, register no inner action. Capture the resolved `ISymbol` in the registered callback and compare encountered symbols with `SymbolEqualityComparer.Default.Equals`. When generic substitutions are irrelevant, normalize both expected and encountered named types, properties, fields, and events with `OriginalDefinition` before comparing them; this includes comparing `AttributeData.AttributeClass` with a resolved generic attribute definition. For methods, normalize each `IMethodSymbol` with `(method.ReducedFrom ?? method).OriginalDefinition` so constructed generic and reduced extension methods match their declaration. Inspect type arguments separately when they matter. Never use `ToDisplayString()` plus a string literal as a substitute for symbol identity. Check metadata names, arity, containing type, and signature as appropriate when selecting members; do not identify APIs by simple method name alone.\n4. Define a stable diagnostic ID and descriptor. Follow repository practices for category, severity, localization, help links, telemetry tags, and release tracking.\n5. Add or update the diagnostic's documentation page and wire the descriptor's `HelpLinkUri` to its published URL.\n6. Report the smallest useful source location. Avoid diagnostics on generated code unless that is intentional.\n7. Add or update the code fix in the separate code-fix assembly. Preserve trivia, use syntax generators or typed syntax APIs, annotate simplifiable\u002Fformattable nodes where appropriate, provide stable equivalence keys for distinct actions, and offer `FixAllProvider` only when batch application is correct.\n8. Add positive, negative, edge, and code-fix tests in one test class for the rule.\n9. Verify that every analyzer project has per-commit assembly versioning and that its project-local version configuration is actually honored.\n10. Run the narrow test class or method first, then the test project, then the repository's normal build or analyzer validation. Honor the repository's test-runner syntax; do not assume VSTest `--filter` is supported.\n\nFor a source generator, replace steps 1-8 with: define generated API examples and invalid-input diagnostics; model each independent input; build an incremental provider graph; render with `SourceWriter`; and test output, diagnostics, determinism, and incremental caching before continuing with versioning, packaging, and repository validation.\n\n## Analyzer pattern\n\nThis is the preferred shape for a semantic rule. Adapt descriptor construction and generated-code policy to local conventions.\n\n```csharp\nusing System.Collections.Immutable;\nusing Microsoft.CodeAnalysis;\nusing Microsoft.CodeAnalysis.Diagnostics;\nusing Microsoft.CodeAnalysis.Operations;\n\n[DiagnosticAnalyzer(LanguageNames.CSharp)]\npublic sealed class AvoidBlockingAnalyzer : DiagnosticAnalyzer\n{\n    public const string DiagnosticId = \"LIB0001\";\n\n    private static readonly DiagnosticDescriptor Rule = new(\n        DiagnosticId,\n        \"Avoid blocking calls\",\n        \"Do not call '{0}'\",\n        \"Usage\",\n        DiagnosticSeverity.Warning,\n        isEnabledByDefault: true);\n\n    public override ImmutableArray\u003CDiagnosticDescriptor> SupportedDiagnostics => [Rule];\n\n    public override void Initialize(AnalysisContext context)\n    {\n        context.EnableConcurrentExecution();\n        context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);\n        context.RegisterCompilationStartAction(static context =>\n        {\n            INamedTypeSymbol? taskType = context.Compilation.GetTypeByMetadataName(KnownApis.Task.FullName);\n            if (taskType is null)\n            {\n                return;\n            }\n\n            context.RegisterOperationAction(\n                operationContext => AnalyzeInvocation(operationContext, taskType),\n                OperationKind.Invocation);\n        });\n    }\n\n    private static void AnalyzeInvocation(OperationAnalysisContext context, INamedTypeSymbol taskType)\n    {\n        var invocation = (IInvocationOperation)context.Operation;\n        IMethodSymbol method = invocation.TargetMethod;\n        if (method.Name == KnownApis.Task.Wait &&\n            SymbolEqualityComparer.Default.Equals(method.ContainingType, taskType))\n        {\n            context.ReportDiagnostic(Diagnostic.Create(\n                Rule,\n                invocation.Syntax.GetLocation(),\n                method.Name));\n        }\n    }\n}\n\npublic static class KnownApis\n{\n    public static class Task\n    {\n        public const string FullName = \"System.Threading.Tasks.Task\";\n        public const string Wait = \"Wait\";\n    }\n}\n```\n\nWhen supporting both languages, use `[DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)]` only if all analysis and diagnostic locations are actually language-neutral or both languages are separately handled and tested.\n\n## Syntax-analysis exception\n\nUse syntax callbacks only when syntax itself controls the rule. Use the callback's existing semantic model if semantic information is unavoidable:\n\n```csharp\nprivate static void AnalyzeNode(SyntaxNodeAnalysisContext context)\n{\n    var invocation = (InvocationExpressionSyntax)context.Node;\n    ISymbol? symbol = context.SemanticModel.GetSymbolInfo(invocation, context.CancellationToken).Symbol;\n    \u002F\u002F Do not call context.Compilation.GetSemanticModel(invocation.SyntaxTree).\n}\n```\n\nBefore choosing this pattern, check whether `IInvocationOperation.TargetMethod`, `IArgumentOperation.Parameter`, `IConversionOperation`, or another operation supplies the same information.\n\n## Incremental source generators\n\nAlways implement `IIncrementalGenerator`. Do not wrap an `ISourceGenerator` with `AsSourceGenerator`; that preserves the old execution model rather than designing for incrementality.\n\nBuild a pipeline with these properties:\n\n- Use `SyntaxProvider.ForAttributeWithMetadataName` for attribute-driven discovery. Otherwise, use `CreateSyntaxProvider` with a very cheap syntactic predicate and perform semantic work only in its transform.\n- Transform syntax and symbols immediately into small immutable, value-equatable models containing only information needed for generation. Do not carry `SyntaxNode`, `ISymbol`, `SemanticModel`, or `Compilation` into later stages because their identity changes defeat caching.\n- Keep independent inputs in independent providers. Combine providers as late as possible. Avoid combining every item with `CompilationProvider` merely for convenience.\n- Avoid `Collect()` unless one output truly depends on the complete set. Prefer one output per model so editing one declaration invalidates only that output.\n- Use stable equality. Records and immutable value types are good models; add `WithComparer` when normal equality does not represent semantic equivalence.\n- Keep transforms and output callbacks static, pure, deterministic, and cancellation-aware. Do not read ambient files, clocks, environment state, or mutable static state. Model configuration, additional files, analyzer config options, and parse options as explicit providers.\n- Give providers `WithTrackingName` labels while developing or testing incremental behavior.\n- Generate stable, collision-resistant hint names. Sort any aggregated inputs explicitly before emitting output.\n- Report invalid user input with generator diagnostics instead of throwing. Generator exceptions surface as compiler failures.\n- Use `SourceText` with an explicit encoding when calling `AddSource`.\n\nA compact pipeline should look like this:\n\n```csharp\n[Generator(LanguageNames.CSharp)]\npublic sealed class FactoryGenerator : IIncrementalGenerator\n{\n    public void Initialize(IncrementalGeneratorInitializationContext context)\n    {\n        IncrementalValuesProvider\u003CTypeModel> models = context.SyntaxProvider\n            .ForAttributeWithMetadataName(\n                \"Product.GenerateFactoryAttribute\",\n                static (node, _) => node is TypeDeclarationSyntax,\n                static (attributeContext, cancellationToken) =>\n                    TypeModel.Create(attributeContext, cancellationToken))\n            .WithTrackingName(\"FactoryModels\");\n\n        context.RegisterSourceOutput(models, static (productionContext, model) =>\n        {\n            var writer = new SourceWriter();\n            writer.WriteLine(\"\u002F\u002F \u003Cauto-generated\u002F>\");\n            writer.WriteLine($\"namespace {model.Namespace};\");\n            writer.WriteLine();\n            writer.WriteLine($\"partial class {model.TypeName}\");\n            writer.WriteLine('{');\n            writer.Indentation++;\n            writer.WriteLine($\"public static {model.TypeName} Create() => new();\");\n            writer.Indentation--;\n            writer.WriteLine('}');\n            productionContext.AddSource(model.HintName, writer.ToSourceText());\n        });\n    }\n}\n```\n\nThe model creation step must normalize symbol data into strings, booleans, enums, and other immutable values, validate unsupported declarations, escape identifiers, and derive a stable hint name. The output callback should only render the model. Use the complete [SourceWriter.cs](.\u002Freferences\u002FSourceWriter.cs) example rather than ad hoc `StringBuilder` concatenation, then adapt indentation style and framework compatibility to the repository.\n\n### Generator tests\n\nTest source generators with `GeneratorDriver` or the repository's generator test harness. Cover:\n\n- exact generated hint names and source text;\n- multiple and nested declarations, namespaces, generics, escaped identifiers, and partial types;\n- malformed or unsupported inputs and their diagnostic locations;\n- additional files, analyzer config options, and parse options when consumed;\n- deterministic output independent of input enumeration and operating-system newlines;\n- a second driver run with identical inputs that caches all expected tracked steps;\n- a narrowly changed input that reruns only the affected pipeline and output;\n- compilation of generated output without unexpected diagnostics.\n\nEnable incremental step tracking in tests and assert run reasons such as cached, unchanged, modified, or newly produced according to the Roslyn version in use. Do not settle for snapshot-only tests: identical generated text can hide a pipeline that recomputes everything.\n\n## Diagnostic documentation and help links\n\nCreate one discoverable documentation page for every diagnostic code. A useful page includes:\n\n- the diagnostic ID, title, category, and default severity;\n- the exact condition that triggers the diagnostic;\n- why the reported pattern is problematic;\n- bad and corrected C# examples;\n- VB examples when VB support is promised;\n- exceptions, configuration, suppression guidance, and code-fix behavior when relevant.\n\nIf the repository has a Docfx site, place these pages under its existing analyzer documentation area, typically:\n\n```text\ndocfx\u002F\n    analyzers\u002F\n        LIB0001.md\n    toc.yml\n```\n\nFollow the site's existing URL and navigation conventions. Add each page to the applicable `toc.yml` so it is rendered and discoverable. The descriptor's help link must be the public GitHub Pages URL that Docfx will produce, not a source-tree path. Centralize construction when all diagnostics share a route:\n\n```csharp\nprivate static string GetHelpLink(string diagnosticId)\n        => $\"https:\u002F\u002Fexample.github.io\u002Fproduct\u002Fanalyzers\u002F{diagnosticId}.html\";\n\nprivate static readonly DiagnosticDescriptor Rule = new(\n        id: DiagnosticId,\n        title: \"Avoid blocking calls\",\n        messageFormat: \"Do not call '{0}'\",\n        category: \"Usage\",\n        defaultSeverity: DiagnosticSeverity.Warning,\n        isEnabledByDefault: true,\n        helpLinkUri: GetHelpLink(DiagnosticId));\n```\n\nDerive the exact hostname, base path, output extension, casing, and route from the repository's Docfx configuration and deployment setup. Confirm that the generated site's route matches `HelpLinkUri`; do not merely assume that a Markdown path maps to the expected URL. When no Docfx folder exists, follow the repository's established documentation system or create an equivalent durable page and public help URL.\n\n## Project and dependency boundaries\n\nA typical solution has three projects:\n\n```text\nProduct.Analyzers          -> Microsoft.CodeAnalysis.Common\u002FCSharp only\nProduct.CodeFixes          -> Product.Analyzers + Roslyn Workspaces\u002FFeatures APIs\nProduct.Analyzers.Tests    -> analyzer + code-fix projects + current testing packages\n```\n\nTarget analyzer assemblies conservatively, commonly `netstandard2.0`, unless host requirements dictate otherwise. Treat the analyzer's Roslyn version as a host-compatibility floor, not a routine dependency to float.\n\nChoose exactly one Roslyn reference-assembly version for shipping analyzer projects. Pin it independently from the latest Roslyn version used by code-fix tests or the rest of the repository. Pin the analyzer dependency's entire transitive closure to mutually compatible versions, including packages such as `System.Collections.Immutable`, `System.Memory`, `System.Reflection.Metadata`, `System.Runtime.CompilerServices.Unsafe`, and `System.Threading.Tasks.Extensions` when they appear in restore. Directly pinning only `Microsoft.CodeAnalysis.*` is insufficient: a newer centrally managed transitive dependency can make the analyzer fail in an older compiler host.\n\nWith central package management, create a dedicated `Directory.Packages.Analyzers.props` at the repository root and import it only for shipping analyzer, source-generator, and code-fix projects. Do not fold these overrides into the general `Directory.Packages.props`: the separate file makes the compatibility boundary visible and lets dependency automation treat it specially.\n\nUse this three-part pattern.\n\nFirst, have every shipping analyzer, source-generator, and code-fix project import one shared props file such as `src\u002FAnalyzerCompatibility.props`. That file should identify the project:\n\n```xml\n\u003CProject>\n    \u003CPropertyGroup>\n        \u003C!-- This is set so that Directory.Packages.Analyzers.props can apply version overrides specific to analyzer projects. -->\n        \u003CIsAnalyzerCompatibilityProject>true\u003C\u002FIsAnalyzerCompatibilityProject>\n    \u003C\u002FPropertyGroup>\n\u003C\u002FProject>\n```\n\nSecond, conditionally import the dedicated package file from a repository-wide props or targets file after central package versions are available:\n\n```xml\n\u003CImport Project=\"$(MSBuildThisFileDirectory)Directory.Packages.Analyzers.props\"\n                Condition=\"'$(IsAnalyzerCompatibilityProject)' == 'true'\" \u002F>\n```\n\nThird, copy this `Directory.Packages.Analyzers.props` structure and tailor the baseline comment, Roslyn version, and transitive versions to the oldest supported compiler or SDK host. Use `Update` only for a package already declared by the repository's central package file; use `Include` to add a pin for a package that is otherwise transitive-only. The example assumes the Roslyn packages are already declared and the listed runtime dependencies are new pins:\n\n```xml\n\u003CProject>\n    \u003C!-- These versions are chosen to support the oldest compiler\u002FSDK host named here. -->\n  \u003CPropertyGroup>\n        \u003CCodeAnalysisVersionForAnalyzers>4.11.0\u003C\u002FCodeAnalysisVersionForAnalyzers>\n      \u003C!-- Apply analyzer compatibility pins to packages referenced only transitively. -->\n      \u003CCentralPackageTransitivePinningEnabled>true\u003C\u002FCentralPackageTransitivePinningEnabled>\n  \u003C\u002FPropertyGroup>\n  \u003CItemGroup>\n        \u003CPackageVersion Update=\"Microsoft.CodeAnalysis\" Version=\"$(CodeAnalysisVersionForAnalyzers)\" \u002F>\n        \u003CPackageVersion Update=\"Microsoft.CodeAnalysis.Common\" Version=\"$(CodeAnalysisVersionForAnalyzers)\" \u002F>\n        \u003CPackageVersion Update=\"Microsoft.CodeAnalysis.CSharp\" Version=\"$(CodeAnalysisVersionForAnalyzers)\" \u002F>\n        \u003CPackageVersion Include=\"Microsoft.CodeAnalysis.CSharp.Workspaces\" Version=\"$(CodeAnalysisVersionForAnalyzers)\" \u002F>\n        \u003CPackageVersion Update=\"Microsoft.CodeAnalysis.VisualBasic\" Version=\"$(CodeAnalysisVersionForAnalyzers)\" \u002F>\n        \u003CPackageVersion Include=\"Microsoft.CodeAnalysis.VisualBasic.Workspaces\" Version=\"$(CodeAnalysisVersionForAnalyzers)\" \u002F>\n        \u003CPackageVersion Include=\"Microsoft.Bcl.AsyncInterfaces\" Version=\"8.0.0\" \u002F>\n        \u003CPackageVersion Include=\"System.Collections.Immutable\" Version=\"8.0.0\" \u002F>\n        \u003CPackageVersion Include=\"System.Memory\" Version=\"4.5.5\" \u002F>\n        \u003CPackageVersion Include=\"System.Reflection.Metadata\" Version=\"8.0.0\" \u002F>\n        \u003CPackageVersion Include=\"System.Runtime.CompilerServices.Unsafe\" Version=\"6.0.0\" \u002F>\n        \u003CPackageVersion Include=\"System.Text.Json\" Version=\"8.0.0\" \u002F>\n        \u003CPackageVersion Include=\"System.Threading.Tasks.Extensions\" Version=\"4.5.4\" \u002F>\n  \u003C\u002FItemGroup>\n\u003C\u002FProject>\n```\n\nThe XML comments in these samples are required, not decorative. Keep equivalent comments in the receiving repository explaining why `IsAnalyzerCompatibilityProject` exists, why the conditional import exists when its purpose is not obvious, which oldest host the pinned versions support, and why these versions intentionally differ from the repository defaults. Include the Roslyn version-support documentation URL in or next to the baseline comment when it helps maintainers choose the correct compiler baseline. Future dependency updates must preserve or update these comments so users do not mistake deliberate compatibility pins for stale packages.\n\nThe versions above are a structural example, not universal recommendations. Recalculate the complete package set for the selected oldest host by inspecting the resolved dependency graph. Retain each package that Roslyn or the generator loads in the compiler process, even when the repository does not reference it directly. `Workspaces` entries centrally pin versions for code-fix projects but must not be referenced by analyzer or source-generator projects. The test project should remain outside `IsAnalyzerCompatibilityProject` and use the latest repository-approved Roslyn and analyzer-testing packages so tests also catch compatibility with current APIs and compilers.\n\nAlways prefer the latest available version of `Microsoft.CodeAnalysis.Analyzers`. It is a development-time analyzer package, not a compiler-host runtime dependency, so it does not need to match `Microsoft.CodeAnalysis`, `Microsoft.CodeAnalysis.Common`, C#\u002FVB, or Workspaces package versions and must not be held back to the analyzer compatibility baseline. Keep it on the repository's normal latest-version update path and reference it without flowing it to consumers:\n\n```xml\n\u003CPackageReference Include=\"Microsoft.CodeAnalysis.Analyzers\" PrivateAssets=\"all\" \u002F>\n```\n\nDo not set its central version to `$(CodeAnalysisVersionForAnalyzers)` and do not include it among packages excluded from minor or major dependency updates. This exception applies specifically to `Microsoft.CodeAnalysis.Analyzers`; packages loaded with the shipping analyzer or generator still belong to the carefully pinned compatibility closure.\n\nConfigure dependency automation so the analyzer baseline is not upgraded across Roslyn versions. For Renovate, isolate the analyzer version file or package group and disallow updates:\n\n```json\n{\n  \"packageRules\": [\n    {\n      \"matchFileNames\": [\"Directory.Packages.Analyzers.props\"],\n      \"enabled\": false\n    }\n  ]\n}\n```\n\nFor Dependabot, use an `ignore` entry for each analyzer-baseline package with `update-types` containing `version-update:semver-major`, `version-update:semver-minor`, and `version-update:semver-patch`. Include the pinned transitive packages, not only `Microsoft.CodeAnalysis.*`. If the tool cannot distinguish analyzer-only central versions from repository-wide versions, place the analyzer pins in a dedicated file\u002Fdirectory or make those upgrades manual.\n\nVerify dependency isolation with a restore graph or assets file and, when practical, load the built analyzer in the oldest supported compiler\u002FIDE host. A successful build on the newest SDK does not prove host compatibility.\n\n## Code-fix boundaries\n\nThe code-fix project may reference packages such as `Microsoft.CodeAnalysis.CSharp.Workspaces` or `Microsoft.CodeAnalysis.VisualBasic.Workspaces`; the analyzer project may not. Keep the code fix optional from the analyzer's perspective. A fix should:\n\n- register only when the diagnostic can be fixed safely;\n- find the target node from the diagnostic span defensively;\n- preserve leading\u002Ftrailing trivia and imports;\n- use `Simplifier.Annotation` and `Formatter.Annotation` where appropriate;\n- return a new document or solution without mutating shared state;\n- support cancellation and avoid blocking async Roslyn APIs;\n- use a meaningful, stable equivalence key, especially when multiple fixes share a title;\n- return the batch fixer only when fixes do not conflict or depend on application order.\n\n## Unique assembly versions\n\nAnalyzer hosts cache and identify assemblies by assembly identity. Every commit that can change an analyzer should therefore produce a unique, precise assembly version; relying only on package version or file version is insufficient.\n\nWith Nerdbank.GitVersioning, put a `version.json` directly in every analyzer project directory, including each language-specific analyzer assembly when those are separate:\n\n```json\n{\n    \"$schema\": \"https:\u002F\u002Fraw.githubusercontent.com\u002Fdotnet\u002FNerdbank.GitVersioning\u002Fmain\u002Fsrc\u002FNerdBank.GitVersioning\u002Fversion.schema.json\",\n    \"inherit\": true,\n    \"assemblyVersion\": {\n        \"precision\": \"revision\"\n    }\n}\n```\n\nThen inspect all imported `Directory.Build.props`, `Directory.Build.targets`, and project SDK props for `GitVersionBaseDirectory`. A repository may set that property to a shared root so version calculation happens once; that can cause a project-local `version.json` to be ignored. In each analyzer project file, reset it to the analyzer project's own directory:\n\n```xml\n\u003CPropertyGroup>\n    \u003C!-- Honor this analyzer project's version.json and produce a unique assembly identity per commit. -->\n    \u003CGitVersionBaseDirectory>$(MSBuildProjectDirectory)\u003C\u002FGitVersionBaseDirectory>\n\u003C\u002FPropertyGroup>\n```\n\nApply this override after any shared property import that sets the value, or otherwise ensure normal MSBuild precedence leaves the project-local value effective. Do not add the override blindly: first locate the controlling assignment and confirm which `version.json` the evaluated analyzer project uses.\n\nValidate the built assembly rather than only inspecting MSBuild source. Build the same analyzer from two distinct commits when practical and confirm that `AssemblyName.Version` differs. At minimum, inspect the evaluated `GitVersionBaseDirectory`, the selected version file, and the resulting assembly version. Repeat this for every analyzer assembly, not merely the packaging or code-fix project.\n\n## Test structure\n\nUse `Microsoft.CodeAnalysis.Testing` or the repository's established equivalent. Keep one test class per diagnostic rule for analyzer and code-fix behavior together. Do not create a separate code-fix test class. Even when a diagnostic intentionally has no fix, instantiate the same analyzer-plus-code-fix harness with `EmptyCodeFixProvider`; this keeps all cases and configuration for the rule together.\n\nAnnotate every verifier\u002Fhelper parameter that accepts C# source with `[StringSyntax(\"c#-test\")]` from `System.Diagnostics.CodeAnalysis`. This enables syntax highlighting and language services at test call sites. Start from [CSharpCodeFixVerifier.cs](.\u002Freferences\u002FCSharpCodeFixVerifier.cs) for a complete example and apply the attribute to analyzer-only and generator test helpers as well. If the target framework does not define `StringSyntaxAttribute`, use the repository's compatibility\u002Fpolyfill pattern.\n\nWhen C# source is assigned to a local variable instead of passed directly to an annotated parameter, add a language comment before the literal:\n\n```csharp\nconst string source = \u002F* lang=c#-test *\u002F \"\"\"\n    \u002F\u002F C# code here\n    \"\"\";\n```\n\nPrefer inline markup to hard-coded line\u002Fcolumn spans:\n\n```csharp\nusing Verify = CSharpCodeFixVerifier\u003CAvoidBlockingAnalyzer, AvoidBlockingCodeFix>;\n\npublic class AvoidBlockingTests\n{\n    [Fact]\n    public async Task ReportsBlockingCallAndFixesIt()\n    {\n        const string source = \u002F* lang=c#-test *\u002F \"\"\"\n            using System.Threading.Tasks;\n            class C\n            {\n                void M(Task task) => [|task.Wait()|];\n            }\n            \"\"\";\n        const string fixedSource = \u002F* lang=c#-test *\u002F \"\"\"\n            using System.Threading.Tasks;\n            class C\n            {\n                async Task M(Task task) => await task;\n            }\n            \"\"\";\n\n        await Verify.VerifyCodeFixAsync(source, fixedSource);\n    }\n\n    [Fact]\n    public async Task DoesNotReportAwaitedTask()\n    {\n        const string source = \u002F* lang=c#-test *\u002F \"\"\"\n            using System.Threading.Tasks;\n            class C\n            {\n                async Task M(Task task) => await task;\n            }\n            \"\"\";\n\n        await Verify.VerifyAnalyzerAsync(source);\n    }\n}\n```\n\nUse `[|bad code|]` for one diagnostic and named markup such as `{|#0:bad code|}` when diagnostics need distinct descriptors, arguments, or locations. Use explicit `DiagnosticResult` objects for IDs, severities, arguments, and additional locations, but attach them to markup locations where the harness supports it. Hard-coded `WithSpan(line, column, ...)` is a last resort for locations that markup cannot express.\n\nIf there is no code fix:\n\n```csharp\nusing Verify = CSharpCodeFixVerifier\u003CAvoidBlockingAnalyzer, EmptyCodeFixProvider>;\n```\n\nWhen VB support is required, use the corresponding Visual Basic verifier and include VB source, fixed source, and negative snippets. Keep shared behavioral cases aligned across languages while retaining language-specific parser\u002Freference configuration.\n\nTest at least:\n\n- a straightforward positive case with the exact diagnostic span;\n- a straightforward negative case;\n- qualified, aliased, generic, inherited, overloaded, and extension-method forms relevant to symbol matching;\n- nullability, implicit conversions, conditional access, lambdas\u002Flocal functions, and malformed code when relevant;\n- absence of an optional referenced type or assembly;\n- generated code according to declared policy;\n- every offered code action and equivalence key;\n- fix-all behavior when advertised;\n- preservation of trivia, imports, and formatting;\n- both C# and VB for every promised cross-language behavior.\n\nPrefer reference-assembly definitions supplied by the test framework over references copied from the executing runtime. Add only the metadata references and additional files needed by the scenario. Keep test parse options explicit when testing language-version-sensitive syntax.\n\n## Packaging\n\nPrefer bundling analyzer assemblies in the same NuGet package as the library they serve so consumers receive diagnostics automatically. Put analyzer DLLs under language-appropriate analyzer paths such as `analyzers\u002Fdotnet\u002Fcs` and `analyzers\u002Fdotnet\u002Fvb`; do not place them under `lib`. Include code-fix assemblies and their required dependencies according to the target host\u002Fpackage convention.\n\nPackage source generators as analyzer assets as well, commonly under `analyzers\u002Fdotnet\u002Fcs`. Keep generator runtime dependencies self-contained and minimal because compiler hosts do not resolve dependencies like ordinary application projects. Validate generator loading and generated output from a packed consumer project.\n\nA separate `Product.Analyzers` package is also valid. In that model, the main library package should depend on it with appropriate asset metadata so analyzers flow to consumers without becoming runtime dependencies. Validate the packed `.nupkg`, not merely the build output: inspect paths, dependencies, satellite resources, build\u002FbuildTransitive assets, and verify the analyzer loads from a sample consumer project.\n\n## Review checklist\n\n- The implementation uses the narrowest suitable `IOperation` or symbol action.\n- Every source generator implements `IIncrementalGenerator`, uses immutable equatable pipeline models, and has tests proving cached and selective recomputation.\n- Generated code uses the shared `SourceWriter` for deterministic formatting and encoding.\n- No syntax callback fetches another semantic model.\n- C# behavior is implemented and tested; promised VB behavior has equivalent VB tests.\n- Analyzer and code-fix assemblies are separate, and the analyzer has no Workspaces dependency.\n- Shipping Roslyn references and their transitive dependency closure are coherently pinned to one compatibility baseline.\n- `Microsoft.CodeAnalysis.Analyzers` uses the latest available version as a private development dependency and is not tied to the shipping Roslyn baseline.\n- Shipping analyzer, source-generator, and code-fix projects set `IsAnalyzerCompatibilityProject`, conditionally import a dedicated `Directory.Packages.Analyzers.props`, and retain XML comments explaining the compatibility baseline and override mechanism.\n- Renovate or Dependabot cannot automatically advance that baseline at any SemVer level: patch, minor, or major.\n- API\u002Ftype\u002Fmember names come from a shared catalog rather than scattered literals.\n- Symbol and attribute matching resolves expected named types from the compilation and expected members from their containing types by name and signature. When generic substitutions are irrelevant, it normalizes both expected and encountered named types, properties, fields, and events with `OriginalDefinition`, and methods with `(method.ReducedFrom ?? method).OriginalDefinition`, then uses `SymbolEqualityComparer.Default`; it inspects relevant type arguments separately and never compares `ToDisplayString()` output with a literal.\n- Every diagnostic ID has a documentation page, is present in site navigation, and has a `HelpLinkUri` matching the published URL.\n- Every analyzer project produces a unique assembly version per commit; with Nerdbank.GitVersioning, its local `version.json` uses revision precision and any shared `GitVersionBaseDirectory` is overridden correctly.\n- Tests use inline markup where possible and cover positive and negative behavior.\n- C# verifier parameters use `[StringSyntax(\"c#-test\")]`, and local C# source literals use `\u002F* lang=c#-test *\u002F` where useful.\n- One rule-focused test class contains analyzer and code-fix cases, using `EmptyCodeFixProvider` when needed.\n- Tests exercise public APIs without `InternalsVisibleTo`.\n- The packed package places analyzer assets correctly and has been tested from a consumer project.\n- Focused tests, the full test project, and the repository build pass without new analyzer warnings.\n","# Roslyn Analyzers and Source Generators\n\nUse this workflow when adding or changing a Roslyn analyzer, code fix, source generator, tests, dependencies, or package layout. First inspect the repository's target frameworks, central package management, test framework, analyzer and generator conventions, diagnostic ID allocation, localization, and packaging. Preserve established conventions unless they conflict with the compatibility rules below.\n\n## Non-negotiable design rules\n\n- Prefer `IOperation`-based analysis wherever possible. Register the narrowest applicable `OperationKind` and inspect typed operations such as `IInvocationOperation`, `IAwaitOperation`, or `IObjectCreationOperation`. This usually supports C# and VB with one analyzer and gives direct access to symbols and conversions.\n- Use syntax analysis only for inherently syntactic rules or syntax not represented adequately by `IOperation`. A syntax-node callback already has a `SemanticModel`; do not call `Compilation.GetSemanticModel` or fetch another semantic model from it. Repeated semantic-model creation is expensive and often indicates that an operation or symbol action is the better abstraction.\n- Every analyzer must support C#. VB.NET support is optional until requested or established repository precedent requires it. A language-neutral operation analyzer may declare both languages. If VB support is promised, include equivalent C# and VB snippets in tests; do not infer VB correctness from shared implementation alone.\n- Keep analyzer and code-fix providers in distinct assemblies. The analyzer project must never reference Roslyn Workspaces packages. Workspaces dependencies belong only in the code-fix and test projects.\n- Analyzer callbacks must be stateless or concurrency-safe. Call `EnableConcurrentExecution()`. Make an explicit generated-code choice with `ConfigureGeneratedCodeAnalysis(...)`; follow repository policy rather than silently accepting the default.\n- Respect cancellation where APIs expose a token. Do not retain compilations, operations, syntax trees, symbols, or semantic models in static state.\n- Avoid `InternalsVisibleTo`. Test analyzers through their public `DiagnosticAnalyzer` and `CodeFixProvider` APIs and the Roslyn test harness. A small analyzer helper may be public when direct testing is genuinely useful, but most behavior should be tested end to end.\n- Centralize metadata names and member names instead of propagating magic strings. Use one shared static catalog for fully qualified type names, namespaces, and API member names.\n- Never identify a symbol, including an attribute class, by calling `ToDisplayString()` and comparing the result with a string literal. Resolve an expected named type from the `Compilation` once by metadata name. To resolve a method, property, field, or event, first resolve its containing type, then select the expected member by name and signature. Compare encountered symbols with `SymbolEqualityComparer.Default.Equals(actual, expected)`. When generic substitutions are irrelevant, compare named types, properties, fields, and events by `OriginalDefinition`; compare methods after replacing a reduced extension method with `ReducedFrom ?? method` and then taking `OriginalDefinition`. Normalize both expected and encountered symbols, and inspect type arguments separately when they are part of the match. Display strings are for presentation, not identity, and can vary with formatting, aliases, qualification, nullability, and other context.\n- Document every diagnostic ID. When the repository uses Docfx, put analyzer documentation under its Docfx tree, typically `docfx\u002Fanalyzers`, and include each page in the relevant table of contents.\n- Set every analyzer assembly's version precisely enough that each commit produces a unique assembly version. When using Nerdbank.GitVersioning, give each analyzer project its own `version.json` with `assemblyVersion.precision` set to `revision` and ensure that repository-wide MSBuild properties do not prevent that file from being discovered.\n- Source generators must implement `IIncrementalGenerator`, not `ISourceGenerator`. Design the provider graph so unchanged inputs remain cached and do not regenerate output.\n- Source generators must use a small `SourceWriter` abstraction for deterministic newlines, indentation, encoding, and balanced output. Start from [SourceWriter.cs](.\u002Freferences\u002FSourceWriter.cs) and tailor its namespace and target-framework details to the receiving repository.\n\n## Implementation workflow\n\n1. Write down examples that must report and near-misses that must not report. Decide the exact diagnostic span and message arguments before implementation.\n2. Determine whether the rule is semantic. Prefer, in order, operation actions, operation-block actions, symbol actions, compilation-start actions that register one of those actions, and finally syntax actions.\n3. Resolve well-known named types once in a compilation-start action with `Compilation.GetTypeByMetadataName` when needed. Resolve expected members from the resulting containing type by name and full signature; `GetTypeByMetadataName` does not resolve methods, properties, fields, or events. If a required type or member is absent, register no inner action. Capture the resolved `ISymbol` in the registered callback and compare encountered symbols with `SymbolEqualityComparer.Default.Equals`. When generic substitutions are irrelevant, normalize both expected and encountered named types, properties, fields, and events with `OriginalDefinition` before comparing them; this includes comparing `AttributeData.AttributeClass` with a resolved generic attribute definition. For methods, normalize each `IMethodSymbol` with `(method.ReducedFrom ?? method).OriginalDefinition` so constructed generic and reduced extension methods match their declaration. Inspect type arguments separately when they matter. Never use `ToDisplayString()` plus a string literal as a substitute for symbol identity. Check metadata names, arity, containing type, and signature as appropriate when selecting members; do not identify APIs by simple method name alone.\n4. Define a stable diagnostic ID and descriptor. Follow repository practices for category, severity, localization, help links, telemetry tags, and release tracking.\n5. Add or update the diagnostic's documentation page and wire the descriptor's `HelpLinkUri` to its published URL.\n6. Report the smallest useful source location. Avoid diagnostics on generated code unless that is intentional.\n7. Add or update the code fix in the separate code-fix assembly. Preserve trivia, use syntax generators or typed syntax APIs, annotate simplifiable\u002Fformattable nodes where appropriate, provide stable equivalence keys for distinct actions, and offer `FixAllProvider` only when batch application is correct.\n8. Add positive, negative, edge, and code-fix tests in one test class for the rule.\n9. Verify that every analyzer project has per-commit assembly versioning and that its project-local version configuration is actually honored.\n10. Run the narrow test class or method first, then the test project, then the repository's normal build or analyzer validation. Honor the repository's test-runner syntax; do not assume VSTest `--filter` is supported.\n\nFor a source generator, replace steps 1-8 with: define generated API examples and invalid-input diagnostics; model each independent input; build an incremental provider graph; render with `SourceWriter`; and test output, diagnostics, determinism, and incremental caching before continuing with versioning, packaging, and repository validation.\n\n## Analyzer pattern\n\nThis is the preferred shape for a semantic rule. Adapt descriptor construction and generated-code policy to local conventions.\n\n```csharp\nusing System.Collections.Immutable;\nusing Microsoft.CodeAnalysis;\nusing Microsoft.CodeAnalysis.Diagnostics;\nusing Microsoft.CodeAnalysis.Operations;\n\n[DiagnosticAnalyzer(LanguageNames.CSharp)]\npublic sealed class AvoidBlockingAnalyzer : DiagnosticAnalyzer\n{\n    public const string DiagnosticId = \"LIB0001\";\n\n    private static readonly DiagnosticDescriptor Rule = new(\n        DiagnosticId,\n        \"Avoid blocking calls\",\n        \"Do not call '{0}'\",\n        \"Usage\",\n        DiagnosticSeverity.Warning,\n        isEnabledByDefault: true);\n\n    public override ImmutableArray\u003CDiagnosticDescriptor> SupportedDiagnostics => [Rule];\n\n    public override void Initialize(AnalysisContext context)\n    {\n        context.EnableConcurrentExecution();\n        context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);\n        context.RegisterCompilationStartAction(static context =>\n        {\n            INamedTypeSymbol? taskType = context.Compilation.GetTypeByMetadataName(KnownApis.Task.FullName);\n            if (taskType is null)\n            {\n                return;\n            }\n\n            context.RegisterOperationAction(\n                operationContext => AnalyzeInvocation(operationContext, taskType),\n                OperationKind.Invocation);\n        });\n    }\n\n    private static void AnalyzeInvocation(OperationAnalysisContext context, INamedTypeSymbol taskType)\n    {\n        var invocation = (IInvocationOperation)context.Operation;\n        IMethodSymbol method = invocation.TargetMethod;\n        if (method.Name == KnownApis.Task.Wait &&\n            SymbolEqualityComparer.Default.Equals(method.ContainingType, taskType))\n        {\n            context.ReportDiagnostic(Diagnostic.Create(\n                Rule,\n                invocation.Syntax.GetLocation(),\n                method.Name));\n        }\n    }\n}\n\npublic static class KnownApis\n{\n    public static class Task\n    {\n        public const string FullName = \"System.Threading.Tasks.Task\";\n        public const string Wait = \"Wait\";\n    }\n}\n```\n\nWhen supporting both languages, use `[DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)]` only if all analysis and diagnostic locations are actually language-neutral or both languages are separately handled and tested.\n\n## Syntax-analysis exception\n\nUse syntax callbacks only when syntax itself controls the rule. Use the callback's existing semantic model if semantic information is unavoidable:\n\n```csharp\nprivate static void AnalyzeNode(SyntaxNodeAnalysisContext context)\n{\n    var invocation = (InvocationExpressionSyntax)context.Node;\n    ISymbol? symbol = context.SemanticModel.GetSymbolInfo(invocation, context.CancellationToken).Symbol;\n    \u002F\u002F Do not call context.Compilation.GetSemanticModel(invocation.SyntaxTree).\n}\n```\n\nBefore choosing this pattern, check whether `IInvocationOperation.TargetMethod`, `IArgumentOperation.Parameter`, `IConversionOperation`, or another operation supplies the same information.\n\n## Incremental source generators\n\nAlways implement `IIncrementalGenerator`. Do not wrap an `ISourceGenerator` with `AsSourceGenerator`; that preserves the old execution model rather than designing for incrementality.\n\nBuild a pipeline with these properties:\n\n- Use `SyntaxProvider.ForAttributeWithMetadataName` for attribute-driven discovery. Otherwise, use `CreateSyntaxProvider` with a very cheap syntactic predicate and perform semantic work only in its transform.\n- Transform syntax and symbols immediately into small immutable, value-equatable models containing only information needed for generation. Do not carry `SyntaxNode`, `ISymbol`, `SemanticModel`, or `Compilation` into later stages because their identity changes defeat caching.\n- Keep independent inputs in independent providers. Combine providers as late as possible. Avoid combining every item with `CompilationProvider` merely for convenience.\n- Avoid `Collect()` unless one output truly depends on the complete set. Prefer one output per model so editing one declaration invalidates only that output.\n- Use stable equality. Records and immutable value types are good models; add `WithComparer` when normal equality does not represent semantic equivalence.\n- Keep transforms and output callbacks static, pure, deterministic, and cancellation-aware. Do not read ambient files, clocks, environment state, or mutable static state. Model configuration, additional files, analyzer config options, and parse options as explicit providers.\n- Give providers `WithTrackingName` labels while developing or testing incremental behavior.\n- Generate stable, collision-resistant hint names. Sort any aggregated inputs explicitly before emitting output.\n- Report invalid user input with generator diagnostics instead of throwing. Generator exceptions surface as compiler failures.\n- Use `SourceText` with an explicit encoding when calling `AddSource`.\n\nA compact pipeline should look like this:\n\n```csharp\n[Generator(LanguageNames.CSharp)]\npublic sealed class FactoryGenerator : IIncrementalGenerator\n{\n    public void Initialize(IncrementalGeneratorInitializationContext context)\n    {\n        IncrementalValuesProvider\u003CTypeModel> models = context.SyntaxProvider\n            .ForAttributeWithMetadataName(\n                \"Product.GenerateFactoryAttribute\",\n                static (node, _) => node is TypeDeclarationSyntax,\n                static (attributeContext, cancellationToken) =>\n                    TypeModel.Create(attributeContext, cancellationToken))\n            .WithTrackingName(\"FactoryModels\");\n\n        context.RegisterSourceOutput(models, static (productionContext, model) =>\n        {\n            var writer = new SourceWriter();\n            writer.WriteLine(\"\u002F\u002F \u003Cauto-generated\u002F>\");\n            writer.WriteLine($\"namespace {model.Namespace};\");\n            writer.WriteLine();\n            writer.WriteLine($\"partial class {model.TypeName}\");\n            writer.WriteLine('{');\n            writer.Indentation++;\n            writer.WriteLine($\"public static {model.TypeName} Create() => new();\");\n            writer.Indentation--;\n            writer.WriteLine('}');\n            productionContext.AddSource(model.HintName, writer.ToSourceText());\n        });\n    }\n}\n```\n\nThe model creation step must normalize symbol data into strings, booleans, enums, and other immutable values, validate unsupported declarations, escape identifiers, and derive a stable hint name. The output callback should only render the model. Use the complete [SourceWriter.cs](.\u002Freferences\u002FSourceWriter.cs) example rather than ad hoc `StringBuilder` concatenation, then adapt indentation style and framework compatibility to the repository.\n\n### Generator tests\n\nTest source generators with `GeneratorDriver` or the repository's generator test harness. Cover:\n\n- exact generated hint names and source text;\n- multiple and nested declarations, namespaces, generics, escaped identifiers, and partial types;\n- malformed or unsupported inputs and their diagnostic locations;\n- additional files, analyzer config options, and parse options when consumed;\n- deterministic output independent of input enumeration and operating-system newlines;\n- a second driver run with identical inputs that caches all expected tracked steps;\n- a narrowly changed input that reruns only the affected pipeline and output;\n- compilation of generated output without unexpected diagnostics.\n\nEnable incremental step tracking in tests and assert run reasons such as cached, unchanged, modified, or newly produced according to the Roslyn version in use. Do not settle for snapshot-only tests: identical generated text can hide a pipeline that recomputes everything.\n\n## Diagnostic documentation and help links\n\nCreate one discoverable documentation page for every diagnostic code. A useful page includes:\n\n- the diagnostic ID, title, category, and default severity;\n- the exact condition that triggers the diagnostic;\n- why the reported pattern is problematic;\n- bad and corrected C# examples;\n- VB examples when VB support is promised;\n- exceptions, configuration, suppression guidance, and code-fix behavior when relevant.\n\nIf the repository has a Docfx site, place these pages under its existing analyzer documentation area, typically:\n\n```text\ndocfx\u002F\n    analyzers\u002F\n        LIB0001.md\n    toc.yml\n```\n\nFollow the site's existing URL and navigation conventions. Add each page to the applicable `toc.yml` so it is rendered and discoverable. The descriptor's help link must be the public GitHub Pages URL that Docfx will produce, not a source-tree path. Centralize construction when all diagnostics share a route:\n\n```csharp\nprivate static string GetHelpLink(string diagnosticId)\n        => $\"https:\u002F\u002Fexample.github.io\u002Fproduct\u002Fanalyzers\u002F{diagnosticId}.html\";\n\nprivate static readonly DiagnosticDescriptor Rule = new(\n        id: DiagnosticId,\n        title: \"Avoid blocking calls\",\n        messageFormat: \"Do not call '{0}'\",\n        category: \"Usage\",\n        defaultSeverity: DiagnosticSeverity.Warning,\n        isEnabledByDefault: true,\n        helpLinkUri: GetHelpLink(DiagnosticId));\n```\n\nDerive the exact hostname, base path, output extension, casing, and route from the repository's Docfx configuration and deployment setup. Confirm that the generated site's route matches `HelpLinkUri`; do not merely assume that a Markdown path maps to the expected URL. When no Docfx folder exists, follow the repository's established documentation system or create an equivalent durable page and public help URL.\n\n## Project and dependency boundaries\n\nA typical solution has three projects:\n\n```text\nProduct.Analyzers          -> Microsoft.CodeAnalysis.Common\u002FCSharp only\nProduct.CodeFixes          -> Product.Analyzers + Roslyn Workspaces\u002FFeatures APIs\nProduct.Analyzers.Tests    -> analyzer + code-fix projects + current testing packages\n```\n\nTarget analyzer assemblies conservatively, commonly `netstandard2.0`, unless host requirements dictate otherwise. Treat the analyzer's Roslyn version as a host-compatibility floor, not a routine dependency to float.\n\nChoose exactly one Roslyn reference-assembly version for shipping analyzer projects. Pin it independently from the latest Roslyn version used by code-fix tests or the rest of the repository. Pin the analyzer dependency's entire transitive closure to mutually compatible versions, including packages such as `System.Collections.Immutable`, `System.Memory`, `System.Reflection.Metadata`, `System.Runtime.CompilerServices.Unsafe`, and `System.Threading.Tasks.Extensions` when they appear in restore. Directly pinning only `Microsoft.CodeAnalysis.*` is insufficient: a newer centrally managed transitive dependency can make the analyzer fail in an older compiler host.\n\nWith central package management, create a dedicated `Directory.Packages.Analyzers.props` at the repository root and import it only for shipping analyzer, source-generator, and code-fix projects. Do not fold these overrides into the general `Directory.Packages.props`: the separate file makes the compatibility boundary visible and lets dependency automation treat it specially.\n\nUse this three-part pattern.\n\nFirst, have every shipping analyzer, source-generator, and code-fix project import one shared props file such as `src\u002FAnalyzerCompatibility.props`. That file should identify the project:\n\n```xml\n\u003CProject>\n    \u003CPropertyGroup>\n        \u003C!-- This is set so that Directory.Packages.Analyzers.props can apply version overrides specific to analyzer projects. -->\n        \u003CIsAnalyzerCompatibilityProject>true\u003C\u002FIsAnalyzerCompatibilityProject>\n    \u003C\u002FPropertyGroup>\n\u003C\u002FProject>\n```\n\nSecond, conditionally import the dedicated package file from a repository-wide props or targets file after central package versions are available:\n\n```xml\n\u003CImport Project=\"$(MSBuildThisFileDirectory)Directory.Packages.Analyzers.props\"\n                Condition=\"'$(IsAnalyzerCompatibilityProject)' == 'true'\" \u002F>\n```\n\nThird, copy this `Directory.Packages.Analyzers.props` structure and tailor the baseline comment, Roslyn version, and transitive versions to the oldest supported compiler or SDK host. Use `Update` only for a package already declared by the repository's central package file; use `Include` to add a pin for a package that is otherwise transitive-only. The example assumes the Roslyn packages are already declared and the listed runtime dependencies are new pins:\n\n```xml\n\u003CProject>\n    \u003C!-- These versions are chosen to support the oldest compiler\u002FSDK host named here. -->\n  \u003CPropertyGroup>\n        \u003CCodeAnalysisVersionForAnalyzers>4.11.0\u003C\u002FCodeAnalysisVersionForAnalyzers>\n      \u003C!-- Apply analyzer compatibility pins to packages referenced only transitively. -->\n      \u003CCentralPackageTransitivePinningEnabled>true\u003C\u002FCentralPackageTransitivePinningEnabled>\n  \u003C\u002FPropertyGroup>\n  \u003CItemGroup>\n        \u003CPackageVersion Update=\"Microsoft.CodeAnalysis\" Version=\"$(CodeAnalysisVersionForAnalyzers)\" \u002F>\n        \u003CPackageVersion Update=\"Microsoft.CodeAnalysis.Common\" Version=\"$(CodeAnalysisVersionForAnalyzers)\" \u002F>\n        \u003CPackageVersion Update=\"Microsoft.CodeAnalysis.CSharp\" Version=\"$(CodeAnalysisVersionForAnalyzers)\" \u002F>\n        \u003CPackageVersion Include=\"Microsoft.CodeAnalysis.CSharp.Workspaces\" Version=\"$(CodeAnalysisVersionForAnalyzers)\" \u002F>\n        \u003CPackageVersion Update=\"Microsoft.CodeAnalysis.VisualBasic\" Version=\"$(CodeAnalysisVersionForAnalyzers)\" \u002F>\n        \u003CPackageVersion Include=\"Microsoft.CodeAnalysis.VisualBasic.Workspaces\" Version=\"$(CodeAnalysisVersionForAnalyzers)\" \u002F>\n        \u003CPackageVersion Include=\"Microsoft.Bcl.AsyncInterfaces\" Version=\"8.0.0\" \u002F>\n        \u003CPackageVersion Include=\"System.Collections.Immutable\" Version=\"8.0.0\" \u002F>\n        \u003CPackageVersion Include=\"System.Memory\" Version=\"4.5.5\" \u002F>\n        \u003CPackageVersion Include=\"System.Reflection.Metadata\" Version=\"8.0.0\" \u002F>\n        \u003CPackageVersion Include=\"System.Runtime.CompilerServices.Unsafe\" Version=\"6.0.0\" \u002F>\n        \u003CPackageVersion Include=\"System.Text.Json\" Version=\"8.0.0\" \u002F>\n        \u003CPackageVersion Include=\"System.Threading.Tasks.Extensions\" Version=\"4.5.4\" \u002F>\n  \u003C\u002FItemGroup>\n\u003C\u002FProject>\n```\n\nThe XML comments in these samples are required, not decorative. Keep equivalent comments in the receiving repository explaining why `IsAnalyzerCompatibilityProject` exists, why the conditional import exists when its purpose is not obvious, which oldest host the pinned versions support, and why these versions intentionally differ from the repository defaults. Include the Roslyn version-support documentation URL in or next to the baseline comment when it helps maintainers choose the correct compiler baseline. Future dependency updates must preserve or update these comments so users do not mistake deliberate compatibility pins for stale packages.\n\nThe versions above are a structural example, not universal recommendations. Recalculate the complete package set for the selected oldest host by inspecting the resolved dependency graph. Retain each package that Roslyn or the generator loads in the compiler process, even when the repository does not reference it directly. `Workspaces` entries centrally pin versions for code-fix projects but must not be referenced by analyzer or source-generator projects. The test project should remain outside `IsAnalyzerCompatibilityProject` and use the latest repository-approved Roslyn and analyzer-testing packages so tests also catch compatibility with current APIs and compilers.\n\nAlways prefer the latest available version of `Microsoft.CodeAnalysis.Analyzers`. It is a development-time analyzer package, not a compiler-host runtime dependency, so it does not need to match `Microsoft.CodeAnalysis`, `Microsoft.CodeAnalysis.Common`, C#\u002FVB, or Workspaces package versions and must not be held back to the analyzer compatibility baseline. Keep it on the repository's normal latest-version update path and reference it without flowing it to consumers:\n\n```xml\n\u003CPackageReference Include=\"Microsoft.CodeAnalysis.Analyzers\" PrivateAssets=\"all\" \u002F>\n```\n\nDo not set its central version to `$(CodeAnalysisVersionForAnalyzers)` and do not include it among packages excluded from minor or major dependency updates. This exception applies specifically to `Microsoft.CodeAnalysis.Analyzers`; packages loaded with the shipping analyzer or generator still belong to the carefully pinned compatibility closure.\n\nConfigure dependency automation so the analyzer baseline is not upgraded across Roslyn versions. For Renovate, isolate the analyzer version file or package group and disallow updates:\n\n```json\n{\n  \"packageRules\": [\n    {\n      \"matchFileNames\": [\"Directory.Packages.Analyzers.props\"],\n      \"enabled\": false\n    }\n  ]\n}\n```\n\nFor Dependabot, use an `ignore` entry for each analyzer-baseline package with `update-types` containing `version-update:semver-major`, `version-update:semver-minor`, and `version-update:semver-patch`. Include the pinned transitive packages, not only `Microsoft.CodeAnalysis.*`. If the tool cannot distinguish analyzer-only central versions from repository-wide versions, place the analyzer pins in a dedicated file\u002Fdirectory or make those upgrades manual.\n\nVerify dependency isolation with a restore graph or assets file and, when practical, load the built analyzer in the oldest supported compiler\u002FIDE host. A successful build on the newest SDK does not prove host compatibility.\n\n## Code-fix boundaries\n\nThe code-fix project may reference packages such as `Microsoft.CodeAnalysis.CSharp.Workspaces` or `Microsoft.CodeAnalysis.VisualBasic.Workspaces`; the analyzer project may not. Keep the code fix optional from the analyzer's perspective. A fix should:\n\n- register only when the diagnostic can be fixed safely;\n- find the target node from the diagnostic span defensively;\n- preserve leading\u002Ftrailing trivia and imports;\n- use `Simplifier.Annotation` and `Formatter.Annotation` where appropriate;\n- return a new document or solution without mutating shared state;\n- support cancellation and avoid blocking async Roslyn APIs;\n- use a meaningful, stable equivalence key, especially when multiple fixes share a title;\n- return the batch fixer only when fixes do not conflict or depend on application order.\n\n## Unique assembly versions\n\nAnalyzer hosts cache and identify assemblies by assembly identity. Every commit that can change an analyzer should therefore produce a unique, precise assembly version; relying only on package version or file version is insufficient.\n\nWith Nerdbank.GitVersioning, put a `version.json` directly in every analyzer project directory, including each language-specific analyzer assembly when those are separate:\n\n```json\n{\n    \"$schema\": \"https:\u002F\u002Fraw.githubusercontent.com\u002Fdotnet\u002FNerdbank.GitVersioning\u002Fmain\u002Fsrc\u002FNerdBank.GitVersioning\u002Fversion.schema.json\",\n    \"inherit\": true,\n    \"assemblyVersion\": {\n        \"precision\": \"revision\"\n    }\n}\n```\n\nThen inspect all imported `Directory.Build.props`, `Directory.Build.targets`, and project SDK props for `GitVersionBaseDirectory`. A repository may set that property to a shared root so version calculation happens once; that can cause a project-local `version.json` to be ignored. In each analyzer project file, reset it to the analyzer project's own directory:\n\n```xml\n\u003CPropertyGroup>\n    \u003C!-- Honor this analyzer project's version.json and produce a unique assembly identity per commit. -->\n    \u003CGitVersionBaseDirectory>$(MSBuildProjectDirectory)\u003C\u002FGitVersionBaseDirectory>\n\u003C\u002FPropertyGroup>\n```\n\nApply this override after any shared property import that sets the value, or otherwise ensure normal MSBuild precedence leaves the project-local value effective. Do not add the override blindly: first locate the controlling assignment and confirm which `version.json` the evaluated analyzer project uses.\n\nValidate the built assembly rather than only inspecting MSBuild source. Build the same analyzer from two distinct commits when practical and confirm that `AssemblyName.Version` differs. At minimum, inspect the evaluated `GitVersionBaseDirectory`, the selected version file, and the resulting assembly version. Repeat this for every analyzer assembly, not merely the packaging or code-fix project.\n\n## Test structure\n\nUse `Microsoft.CodeAnalysis.Testing` or the repository's established equivalent. Keep one test class per diagnostic rule for analyzer and code-fix behavior together. Do not create a separate code-fix test class. Even when a diagnostic intentionally has no fix, instantiate the same analyzer-plus-code-fix harness with `EmptyCodeFixProvider`; this keeps all cases and configuration for the rule together.\n\nAnnotate every verifier\u002Fhelper parameter that accepts C# source with `[StringSyntax(\"c#-test\")]` from `System.Diagnostics.CodeAnalysis`. This enables syntax highlighting and language services at test call sites. Start from [CSharpCodeFixVerifier.cs](.\u002Freferences\u002FCSharpCodeFixVerifier.cs) for a complete example and apply the attribute to analyzer-only and generator test helpers as well. If the target framework does not define `StringSyntaxAttribute`, use the repository's compatibility\u002Fpolyfill pattern.\n\nWhen C# source is assigned to a local variable instead of passed directly to an annotated parameter, add a language comment before the literal:\n\n```csharp\nconst string source = \u002F* lang=c#-test *\u002F \"\"\"\n    \u002F\u002F C# code here\n    \"\"\";\n```\n\nPrefer inline markup to hard-coded line\u002Fcolumn spans:\n\n```csharp\nusing Verify = CSharpCodeFixVerifier\u003CAvoidBlockingAnalyzer, AvoidBlockingCodeFix>;\n\npublic class AvoidBlockingTests\n{\n    [Fact]\n    public async Task ReportsBlockingCallAndFixesIt()\n    {\n        const string source = \u002F* lang=c#-test *\u002F \"\"\"\n            using System.Threading.Tasks;\n            class C\n            {\n                void M(Task task) => [|task.Wait()|];\n            }\n            \"\"\";\n        const string fixedSource = \u002F* lang=c#-test *\u002F \"\"\"\n            using System.Threading.Tasks;\n            class C\n            {\n                async Task M(Task task) => await task;\n            }\n            \"\"\";\n\n        await Verify.VerifyCodeFixAsync(source, fixedSource);\n    }\n\n    [Fact]\n    public async Task DoesNotReportAwaitedTask()\n    {\n        const string source = \u002F* lang=c#-test *\u002F \"\"\"\n            using System.Threading.Tasks;\n            class C\n            {\n                async Task M(Task task) => await task;\n            }\n            \"\"\";\n\n        await Verify.VerifyAnalyzerAsync(source);\n    }\n}\n```\n\nUse `[|bad code|]` for one diagnostic and named markup such as `{|#0:bad code|}` when diagnostics need distinct descriptors, arguments, or locations. Use explicit `DiagnosticResult` objects for IDs, severities, arguments, and additional locations, but attach them to markup locations where the harness supports it. Hard-coded `WithSpan(line, column, ...)` is a last resort for locations that markup cannot express.\n\nIf there is no code fix:\n\n```csharp\nusing Verify = CSharpCodeFixVerifier\u003CAvoidBlockingAnalyzer, EmptyCodeFixProvider>;\n```\n\nWhen VB support is required, use the corresponding Visual Basic verifier and include VB source, fixed source, and negative snippets. Keep shared behavioral cases aligned across languages while retaining language-specific parser\u002Freference configuration.\n\nTest at least:\n\n- a straightforward positive case with the exact diagnostic span;\n- a straightforward negative case;\n- qualified, aliased, generic, inherited, overloaded, and extension-method forms relevant to symbol matching;\n- nullability, implicit conversions, conditional access, lambdas\u002Flocal functions, and malformed code when relevant;\n- absence of an optional referenced type or assembly;\n- generated code according to declared policy;\n- every offered code action and equivalence key;\n- fix-all behavior when advertised;\n- preservation of trivia, imports, and formatting;\n- both C# and VB for every promised cross-language behavior.\n\nPrefer reference-assembly definitions supplied by the test framework over references copied from the executing runtime. Add only the metadata references and additional files needed by the scenario. Keep test parse options explicit when testing language-version-sensitive syntax.\n\n## Packaging\n\nPrefer bundling analyzer assemblies in the same NuGet package as the library they serve so consumers receive diagnostics automatically. Put analyzer DLLs under language-appropriate analyzer paths such as `analyzers\u002Fdotnet\u002Fcs` and `analyzers\u002Fdotnet\u002Fvb`; do not place them under `lib`. Include code-fix assemblies and their required dependencies according to the target host\u002Fpackage convention.\n\nPackage source generators as analyzer assets as well, commonly under `analyzers\u002Fdotnet\u002Fcs`. Keep generator runtime dependencies self-contained and minimal because compiler hosts do not resolve dependencies like ordinary application projects. Validate generator loading and generated output from a packed consumer project.\n\nA separate `Product.Analyzers` package is also valid. In that model, the main library package should depend on it with appropriate asset metadata so analyzers flow to consumers without becoming runtime dependencies. Validate the packed `.nupkg`, not merely the build output: inspect paths, dependencies, satellite resources, build\u002FbuildTransitive assets, and verify the analyzer loads from a sample consumer project.\n\n## Review checklist\n\n- The implementation uses the narrowest suitable `IOperation` or symbol action.\n- Every source generator implements `IIncrementalGenerator`, uses immutable equatable pipeline models, and has tests proving cached and selective recomputation.\n- Generated code uses the shared `SourceWriter` for deterministic formatting and encoding.\n- No syntax callback fetches another semantic model.\n- C# behavior is implemented and tested; promised VB behavior has equivalent VB tests.\n- Analyzer and code-fix assemblies are separate, and the analyzer has no Workspaces dependency.\n- Shipping Roslyn references and their transitive dependency closure are coherently pinned to one compatibility baseline.\n- `Microsoft.CodeAnalysis.Analyzers` uses the latest available version as a private development dependency and is not tied to the shipping Roslyn baseline.\n- Shipping analyzer, source-generator, and code-fix projects set `IsAnalyzerCompatibilityProject`, conditionally import a dedicated `Directory.Packages.Analyzers.props`, and retain XML comments explaining the compatibility baseline and override mechanism.\n- Renovate or Dependabot cannot automatically advance that baseline at any SemVer level: patch, minor, or major.\n- API\u002Ftype\u002Fmember names come from a shared catalog rather than scattered literals.\n- Symbol and attribute matching resolves expected named types from the compilation and expected members from their containing types by name and signature. When generic substitutions are irrelevant, it normalizes both expected and encountered named types, properties, fields, and events with `OriginalDefinition`, and methods with `(method.ReducedFrom ?? method).OriginalDefinition`, then uses `SymbolEqualityComparer.Default`; it inspects relevant type arguments separately and never compares `ToDisplayString()` output with a literal.\n- Every diagnostic ID has a documentation page, is present in site navigation, and has a `HelpLinkUri` matching the published URL.\n- Every analyzer project produces a unique assembly version per commit; with Nerdbank.GitVersioning, its local `version.json` uses revision precision and any shared `GitVersionBaseDirectory` is overridden correctly.\n- Tests use inline markup where possible and cover positive and negative behavior.\n- C# verifier parameters use `[StringSyntax(\"c#-test\")]`, and local C# source literals use `\u002F* lang=c#-test *\u002F` where useful.\n- One rule-focused test class contains analyzer and code-fix cases, using `EmptyCodeFixProvider` when needed.\n- Tests exercise public APIs without `InternalsVisibleTo`.\n- The packed package places analyzer assets correctly and has been tested from a consumer project.\n- Focused tests, the full test project, and the repository build pass without new analyzer warnings.\n",{"name":5,"description":7},"main","5269f7ea2d6c3a9bfda5ed878b6726cf509121fd","skills\u002Froslyn-analyzers",5340,"https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot","https:\u002F\u002Fawesome-copilot.github.com\u002F","https:\u002F\u002Fgithub.com\u002Fgithub","https:\u002F\u002Fgithub.com\u002Fabout","How people build software.","2026-11-11 13:41:32",{"source":8,"skillName":5,"commands":60,"prompt":70,"zipAvailable":71},[61,64,67],{"tool":62,"command":63},"npx","npx skills add github\u002Fawesome-copilot --skill roslyn-analyzers",{"tool":65,"command":66},"bunx","bunx skills add github\u002Fawesome-copilot --skill roslyn-analyzers",{"tool":68,"command":69},"pnpm","pnpm dlx skills add github\u002Fawesome-copilot --skill roslyn-analyzers","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Froslyn-analyzers\u002FSKILL.md",true,[73,79],{"path":74,"resourceType":75,"resourceTypeDesc":76,"sizeBytes":77,"sourceHtmlUrl":78},"references\u002FCSharpCodeFixVerifier.cs","REFERENCE","参考文档",2548,"https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Froslyn-analyzers\u002Freferences\u002FCSharpCodeFixVerifier.cs",{"path":80,"resourceType":75,"resourceTypeDesc":76,"sizeBytes":81,"sourceHtmlUrl":82},"references\u002FSourceWriter.cs",11760,"https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Froslyn-analyzers\u002Freferences\u002FSourceWriter.cs",[84,116,143,167,201,218],{"skillNo":85,"name":86,"nameZh":6,"description":87,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":88,"categories":89,"keywords":98,"publishedAt":44},"01M70KXZNX9ES38N2A8M58ZZMZ","supabase-rls-policies","Write, review, and test Supabase Row Level Security (RLS) policies so that one user cannot read or change another user's rows. Use when creating or changing tables, policies, views, or security definer functions in a Supabase project, when reviewing a migration that touches RLS, or when asked to prove user isolation with pgTAP tests that sign in as two users.","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fsupabase-rls-policies\u002FSKILL.md",[90,95],{"categoryNo":91,"categoryName":92,"taxonomyType":93,"taxonomyTypeDesc":94},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",{"categoryNo":96,"categoryName":97,"taxonomyType":93,"taxonomyTypeDesc":94},"01JBSEEDCAT000000000000023","Skill与智能体开发",[99,100,101,102,103,104,35,105,106,107,108,109,110,111,30,112,33,113,114,115],"supabase","rls","supabase rls","supabase rls policies","project","when","change","read","write","security","isolation","tables","as","prove","users","functions","with",{"skillNo":117,"name":118,"nameZh":6,"description":119,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":120,"categories":121,"keywords":123,"publishedAt":44},"01M70KWA5YWXDV6V8DZ19E3T2Y","skill-distribution-audit","Audit a skill collection before release or investigate installer omissions, archived\u002Ftemplate leakage, duplicate identities, and manifest drift. Reconcile the intended public source set, distribution manifest, and actual discovery output for a specified consumer version. Includes a deterministic set-comparison helper.","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fskill-distribution-audit\u002FSKILL.md",[122],{"categoryNo":96,"categoryName":97,"taxonomyType":93,"taxonomyTypeDesc":94},[124,125,126,127,128,129,26,130,131,132,133,134,135,136,137,138,139,140,141,142],"distribution","skill distribution audit","audit","SET","deterministic","installer","discovery","comparison","helper","manifest","version","collection","drift","output","investigate","duplicate","template","release","reconcile",{"skillNo":144,"name":145,"nameZh":6,"description":146,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":147,"sourceHtmlUrl":148,"categories":149,"keywords":151,"publishedAt":44},"01M70KCJPFVW7PPQ49CC5R8JGK","logicapps-custom-code-net10-migration","Migrate Azure Logic Apps Standard local-function custom-code projects from .NET 8 to .NET 10. Use for legacy Logic Apps custom-code workspace upgrades, project\u002Fpackage configuration, custom-worker settings, publication, and integrated VS Code debugging. Not for ordinary .NET applications, standalone Azure Functions, Consumption workflows, or cloud deployment.","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Flogicapps-custom-code-net10-migration\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Flogicapps-custom-code-net10-migration\u002FSKILL.md",[150],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[152,40,153,154,155,156,26,103,157,158,159,160,161,162,38,33,163,164,165,166],"custom","logicapps custom code net10 migration","migration","projects","standalone","deployment","applications","local","azure","worker","upgrades","apps","Legacy","debugging","workflows",{"skillNo":168,"name":169,"nameZh":6,"description":170,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":171,"sourceHtmlUrl":172,"categories":173,"keywords":178,"publishedAt":44},"01M6AEBN37RQMXJ3298PEY7PG1","winmd-api-search","Find and explore Windows desktop APIs. Use when building features that need platform capabilities — camera, file access, notifications, UI controls, AI\u002FML, sensors, networking, etc. Discovers the right API for a task and retrieves full type details (methods, properties, events, enumeration values).","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fwinmd-api-search\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fwinmd-api-search\u002FSKILL.md",[174,177],{"categoryNo":175,"categoryName":176,"taxonomyType":93,"taxonomyTypeDesc":94},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,104,194,195,196,197,198,26,199,200],"winmd api search","search","api","windows","desktop","file access","enumeration","ui","ml","file","networking","capabilities","notifications","explore","access","features","full","camera","events","platform","methods","controls",{"skillNo":202,"name":203,"nameZh":6,"description":204,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":205,"licenseFileUrl":206,"sourceHtmlUrl":207,"categories":208,"keywords":214,"publishedAt":44},"01M6AE571R3SC1ZGE202B3NB5S","resemble-detect","Deepfake detection and media safety — detect AI-generated audio, images, video, and text, trace synthesis sources, apply watermarks, verify speaker identity, and analyze media intelligence using Resemble AI","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fresemble-detect\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fresemble-detect\u002FSKILL.md",[209,210,213],{"categoryNo":175,"categoryName":176,"taxonomyType":93,"taxonomyTypeDesc":94},{"categoryNo":211,"categoryName":212,"taxonomyType":93,"taxonomyTypeDesc":94},"01JBSEEDCAT000000000000016","图像与多媒体",{"categoryNo":96,"categoryName":97,"taxonomyType":93,"taxonomyTypeDesc":94},[215,127,188,216,217],"resemble detect","https","identity",{"skillNo":219,"name":220,"nameZh":6,"description":221,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":205,"licenseFileUrl":222,"sourceHtmlUrl":223,"categories":224,"keywords":229,"publishedAt":44},"01M6AE30BSK2HCY4TQQ22Z8JRD","quality-playbook","Run a complete quality engineering audit on any codebase. Derives behavioral requirements from the code, generates spec-traced functional tests, runs a three-pass code review with regression tests, executes a multi-model spec audit (Council of Three), and produces a consolidated bug report with TDD-verified patches. Finds the 35% of real defects that structural code review alone cannot catch. Works with any language. Trigger on 'quality playbook', 'spec audit', 'Council of Three', 'fitness-to-purpose', or 'coverage theater'.","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fquality-playbook\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot\u002Fblob\u002Fmain\u002Fskills\u002Fquality-playbook\u002FSKILL.md",[225,228],{"categoryNo":226,"categoryName":227,"taxonomyType":93,"taxonomyTypeDesc":94},"01JBSEEDCAT000000000000007","代码审查",{"categoryNo":96,"categoryName":97,"taxonomyType":93,"taxonomyTypeDesc":94},[230,231,232,233,40,35,9,126,234,235,216,236,237,238,239,240,241,242,243,244,245,246,30,247,248,249,250],"playbook","quality playbook","quality","code review","tdd","run","report","spec","bug report","council","engineering","functional","spec audit","bug","verified","multi-model","three","coverage","model","regression","structural"]