[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M699CQ5WWNT5GX98FM50NSEE":3,"skill-same:01M699CQ5WWNT5GX98FM50NSEE":60},{"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":18,"publishedAt":32,"linkOnly":33,"markdownContent":34,"markdownBody":35,"frontMatter":36,"refName":37,"commitSha":38,"skillDirectory":39,"forksCount":40,"repositoryHtmlUrl":41,"repositoryHomepageUrl":6,"ownerHtmlUrl":42,"ownerBlogUrl":43,"ownerDescription":44,"updatedAt":45,"install":46,"resources":59},"01M699CQ5WWNT5GX98FM50NSEE","build-perf-diagnostics",null,"Diagnose MSBuild target\u002Ftask\u002Fanalyzer bottlenecks from binlogs after baselining; not baseline setup, incremental correctness or parallelism tuning.","microsoft\u002Ftestfx","microsoft","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F6154722?v=4","01M698VYDXZ6JW5WH3CRV650R8","Microsoft","01M699C71CJ91B5WZ3AXG3GG2M",1059,"MIT","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Ftestfx\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fbuild-perf-diagnostics\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31],"build perf diagnostics","diagnostics","perf","build","msbuild","setup","diagnose","tuning","baseline","baselining","task","correctness","analyzer","2026-11-10 10:12:30",false,"---\nname: build-perf-diagnostics\ndescription: \"Diagnose MSBuild target\u002Ftask\u002Fanalyzer bottlenecks from binlogs after baselining; not baseline setup, incremental correctness or parallelism tuning.\"\nlicense: MIT\n---\n\n## Scope and routing\n\nDiagnose MSBuild build performance bottlenecks using binary log analysis. USE FOR: identifying why builds are slow by analyzing binlog performance summaries, detecting ResolveAssemblyReference (RAR) taking >5s, Roslyn analyzers consuming >30% of Csc time, single targets dominating >50% of build time, node utilization below 80%, excessive Copy tasks, NuGet restore running every build. Covers timeline analysis, Target\u002FTask Performance Summary interpretation, and 7 common bottleneck categories. Use after build-perf-baseline has established measurements. DO NOT USE FOR: establishing initial baselines (use build-perf-baseline first), fixing incremental build issues (use incremental-build), parallelism tuning (use build-parallelism), non-MSBuild build systems.\n\n## Performance Analysis Methodology\n\n1. **Generate a binlog**: `dotnet build \u002Fbl:{} -m`\n2. Use the **binlog MCP server** (`Microsoft.AITools.BinlogMcp`, exposed under the `binlog` MCP namespace) which is bundled with this plugin\n\n### Alternate flow when MCP is unavailable: binlog replay to text logs\n\n1. **Generate a binlog**: `dotnet build \u002Fbl:{} -m`\n2. **Replay to diagnostic log with performance summary**:\n   ```bash\n   dotnet msbuild build.binlog -noconlog -fl \"-flp:v=diag;logfile=full.log;performancesummary\"\n   ```\n3. **Read the performance summary** (at the end of `full.log`):\n   ```bash\n   grep \"Target Performance Summary\\|Task Performance Summary\" -A 50 full.log\n   ```\n4. **Find expensive targets and tasks**: The PerformanceSummary section lists all targets\u002Ftasks sorted by cumulative time\n5. **Check for node utilization**: grep for scheduling and node messages\n   ```bash\n   grep -i \"node.*assigned\\|building with\\|scheduler\" full.log | head -30\n   ```\n6. **Check analyzers**: grep for analyzer timing\n   ```bash\n   grep -i \"analyzer.*elapsed\\|Total analyzer execution time\\|CompilerAnalyzerDriver\" full.log\n   ```\n\n## Key Metrics and Thresholds\n\n- **Build duration**: what's \"normal\" — small project \u003C10s, medium \u003C60s, large \u003C5min\n- **Node utilization**: ideal is >80% active time across nodes. Low utilization = serialization bottleneck\n- **Single target domination**: if one target is >50% of build time, investigate\n- **Analyzer time vs compile time**: analyzers should be \u003C30% of Csc task time. If higher, consider removing expensive analyzers\n- **RAR time**: ResolveAssemblyReference >5s is concerning. >15s is pathological\n\n## Common Bottlenecks\n\n### 1. ResolveAssemblyReference (RAR) Slowness\n\n- **Symptoms**: RAR taking >5s per project\n- **Root causes**: too many assembly references, network-based reference paths, large assembly search paths\n- **Fixes**: reduce reference count, use `\u003CDesignTimeBuild>false\u003C\u002FDesignTimeBuild>` for RAR-heavy analysis, set `\u003CResolveAssemblyReferencesSilent>true\u003C\u002FResolveAssemblyReferencesSilent>` for diagnostic\n- **Advanced**: `\u003CDesignTimeBuild>` and `\u003CResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>`\n- **Key insight**: RAR runs unconditionally even on incremental builds because users may have installed targeting packs or GACed assemblies (see dotnet\u002Fmsbuild#2015). With .NET Core micro-assemblies, the reference count is often very high.\n- **Reduce transitive references**: Set `\u003CDisableTransitiveProjectReferences>true\u003C\u002FDisableTransitiveProjectReferences>` to avoid pulling in the full transitive closure (note: projects may need to add direct references for any types they consume). Use `ReferenceOutputAssembly=\"false\"` on ProjectReferences that are only needed at build time (not API surface). Trim unused PackageReferences.\n\n### 2. Roslyn Analyzers and Source Generators\n\n- **Symptoms**: Csc task takes much longer than expected for file count (>2× clean compile time)\n- **Diagnosis**: Check the Task Performance Summary in the replayed log for Csc task time; grep for analyzer timing messages; compare Csc duration with and without analyzers (`\u002Fp:RunAnalyzers=false`)\n- **Fixes**:\n  - Conditionally disable in dev: `\u003CRunAnalyzers Condition=\"'$(ContinuousIntegrationBuild)' != 'true'\">false\u003C\u002FRunAnalyzers>`\n  - Per-configuration: `\u003CRunAnalyzers Condition=\"'$(Configuration)' == 'Debug'\">false\u003C\u002FRunAnalyzers>`\n  - Code-style only: `\u003CEnforceCodeStyleInBuild Condition=\"'$(ContinuousIntegrationBuild)' == 'true'\">true\u003C\u002FEnforceCodeStyleInBuild>`\n  - Remove genuinely redundant analyzers from inner loop\n  - Severity config in .editorconfig for less critical rules\n- **Key principle**: Preserve analyzer enforcement in CI. Never just \"remove\" analyzers — configure them conditionally.\n- **GlobalPackageReference**: Analyzers added via `GlobalPackageReference` in `Directory.Packages.props` apply to ALL projects. Consider if test projects need the same analyzer set as production code.\n- **EnforceCodeStyleInBuild**: When set to `true` in `Directory.Build.props`, forces code-style analysis on every build. Should be conditional on CI environment (`ContinuousIntegrationBuild`) to avoid slowing dev inner loop.\n\n### 3. Serialization Bottlenecks (Single-threaded targets)\n\n- **Symptoms**: Performance summary shows most build time concentrated in a single project; diagnostic log shows idle nodes while one works\n- **Common culprits**: targets without proper dependency declaration, single project on critical path\n- **Fixes**: split large projects, optimize the critical path project, ensure proper `BuildInParallel`\n\n### 4. Excessive File I\u002FO (Copy tasks)\n\n- **Symptoms**: Copy task shows high aggregate time\n- **Root causes**: copying thousands of files, copying across network drives, Copy task unintentionally running once per item (per-file) instead of as a single batch (see dotnet\u002Fmsbuild#12884)\n- **Fixes**: use hardlinks (`\u003CCreateHardLinksForCopyFilesToOutputDirectoryIfPossible>true\u003C\u002FCreateHardLinksForCopyFilesToOutputDirectoryIfPossible>`), reduce CopyToOutputDirectory items, use `\u003CUseCommonOutputDirectory>true\u003C\u002FUseCommonOutputDirectory>` when appropriate, set `\u003CSkipCopyUnchangedFiles>true\u003C\u002FSkipCopyUnchangedFiles>`, consider `--artifacts-path` (.NET 8+) for centralized output layout\n- **Dev Drive**: On Windows, switching to a Dev Drive (ReFS with copy-on-write and reduced Defender scans) can significantly reduce file I\u002FO overhead for Copy-heavy builds. Recommend for both dev machines and self-hosted CI agents.\n\n### 5. Evaluation Overhead\n\n- **Symptoms**: build starts slow before any compilation\n- **Root causes**: complex Directory.Build.props, wildcard globs scanning large directories, NuGetSdkResolver overhead (adds 180-400ms per project evaluation even when restored — see dotnet\u002Fmsbuild#4025)\n- **Fixes**: reduce Directory.Build.props complexity, use `\u003CEnableDefaultItems>false\u003C\u002FEnableDefaultItems>` for legacy projects with explicit file lists, avoid NuGet-based SDK resolvers if possible\n- See: `eval-performance` skill for detailed guidance\n\n### 6. NuGet Restore in Build\n\n- **Symptoms**: restore runs every build even when unnecessary\n- **Fixes**:\n  - Separate restore from build: `dotnet restore` then `dotnet build --no-restore`\n  - Enable static graph evaluation: `\u003CRestoreUseStaticGraphEvaluation>true\u003C\u002FRestoreUseStaticGraphEvaluation>` in Directory.Build.props — can save significant time in large builds (results are workload-dependent)\n\n### 7. Large Project Count and Graph Shape\n\n- **Symptoms**: many small projects, each takes minimal time but overhead adds up; deep dependency chains serialize the build\n- **Consider**: project consolidation, or use `\u002Fgraph` mode for better scheduling\n- **Graph shape matters**: a wide dependency graph (few levels, many parallel branches) builds faster than a deep one (many levels, serialized). Refactoring from deep to wide can yield significant improvements in both clean and incremental build times.\n- **Actions**: look for unnecessary project dependencies, consider splitting a bottleneck project into two, or merging small leaf projects\n\n## Using Binlog Replay for Performance Analysis\n\nStep-by-step workflow using text log replay:\n\n1. **Replay with performance summary**:\n   ```bash\n   dotnet msbuild build.binlog -noconlog -fl \"-flp:v=diag;logfile=full.log;performancesummary\"\n   ```\n2. **Read target\u002Ftask performance summaries** (at the end of `full.log`):\n   ```bash\n   grep \"Target Performance Summary\\|Task Performance Summary\" -A 50 full.log\n   ```\n   This shows all targets and tasks sorted by cumulative time — equivalent to finding expensive targets\u002Ftasks.\n3. **Find per-project build times**:\n   ```bash\n   grep \"done building project\\|Project Performance Summary\" full.log\n   ```\n4. **Check parallelism** (multi-node scheduling):\n   ```bash\n   grep -i \"node.*assigned\\|RequiresLeadingNewline\\|Building with\" full.log | head -30\n   ```\n5. **Check analyzer overhead**:\n   ```bash\n   grep -i \"Total analyzer execution time\\|analyzer.*elapsed\\|CompilerAnalyzerDriver\" full.log\n   ```\n6. **Drill into a specific slow target**:\n   ```bash\n   grep 'Target \"CoreCompile\"\\|Target \"ResolveAssemblyReferences\"' full.log\n   ```\n\n## Quick Wins Checklist\n\n- [ ] Use `\u002Fmaxcpucount` (or `-m`) for parallel builds\n- [ ] Separate restore from build (`dotnet restore` then `dotnet build --no-restore`)\n- [ ] Enable static graph restore (`\u003CRestoreUseStaticGraphEvaluation>true\u003C\u002FRestoreUseStaticGraphEvaluation>`)\n- [ ] Enable hardlinks for Copy (`\u003CCreateHardLinksForCopyFilesToOutputDirectoryIfPossible>true\u003C\u002FCreateHardLinksForCopyFilesToOutputDirectoryIfPossible>`)\n- [ ] Disable analyzers conditionally in dev inner loop: `\u003CRunAnalyzers Condition=\"'$(ContinuousIntegrationBuild)' != 'true'\">false\u003C\u002FRunAnalyzers>`\n- [ ] Enable reference assemblies (`\u003CProduceReferenceAssembly>true\u003C\u002FProduceReferenceAssembly>`)\n- [ ] Check for broken incremental builds (see `incremental-build` skill)\n- [ ] Check for bin\u002Fobj clashes (see `check-bin-obj-clash` skill)\n- [ ] Use graph build (`\u002Fgraph`) for multi-project solutions\n- [ ] Use `--artifacts-path` (.NET 8+) for centralized output layout\n- [ ] Enable Dev Drive (ReFS) on Windows dev machines and self-hosted CI\n\n## Impact Categorization\n\nWhen reporting findings, categorize by impact to help prioritize fixes:\n\n- ? **HIGH IMPACT** (do first): Items consuming >10% of total build time, or a single target >50% of build time\n- ? **MEDIUM IMPACT**: Items consuming 2-10% of build time\n- ? **QUICK WINS**: Easy changes with modest impact (e.g., property flags in Directory.Build.props)\n","## Scope and routing\n\nDiagnose MSBuild build performance bottlenecks using binary log analysis. USE FOR: identifying why builds are slow by analyzing binlog performance summaries, detecting ResolveAssemblyReference (RAR) taking >5s, Roslyn analyzers consuming >30% of Csc time, single targets dominating >50% of build time, node utilization below 80%, excessive Copy tasks, NuGet restore running every build. Covers timeline analysis, Target\u002FTask Performance Summary interpretation, and 7 common bottleneck categories. Use after build-perf-baseline has established measurements. DO NOT USE FOR: establishing initial baselines (use build-perf-baseline first), fixing incremental build issues (use incremental-build), parallelism tuning (use build-parallelism), non-MSBuild build systems.\n\n## Performance Analysis Methodology\n\n1. **Generate a binlog**: `dotnet build \u002Fbl:{} -m`\n2. Use the **binlog MCP server** (`Microsoft.AITools.BinlogMcp`, exposed under the `binlog` MCP namespace) which is bundled with this plugin\n\n### Alternate flow when MCP is unavailable: binlog replay to text logs\n\n1. **Generate a binlog**: `dotnet build \u002Fbl:{} -m`\n2. **Replay to diagnostic log with performance summary**:\n   ```bash\n   dotnet msbuild build.binlog -noconlog -fl \"-flp:v=diag;logfile=full.log;performancesummary\"\n   ```\n3. **Read the performance summary** (at the end of `full.log`):\n   ```bash\n   grep \"Target Performance Summary\\|Task Performance Summary\" -A 50 full.log\n   ```\n4. **Find expensive targets and tasks**: The PerformanceSummary section lists all targets\u002Ftasks sorted by cumulative time\n5. **Check for node utilization**: grep for scheduling and node messages\n   ```bash\n   grep -i \"node.*assigned\\|building with\\|scheduler\" full.log | head -30\n   ```\n6. **Check analyzers**: grep for analyzer timing\n   ```bash\n   grep -i \"analyzer.*elapsed\\|Total analyzer execution time\\|CompilerAnalyzerDriver\" full.log\n   ```\n\n## Key Metrics and Thresholds\n\n- **Build duration**: what's \"normal\" — small project \u003C10s, medium \u003C60s, large \u003C5min\n- **Node utilization**: ideal is >80% active time across nodes. Low utilization = serialization bottleneck\n- **Single target domination**: if one target is >50% of build time, investigate\n- **Analyzer time vs compile time**: analyzers should be \u003C30% of Csc task time. If higher, consider removing expensive analyzers\n- **RAR time**: ResolveAssemblyReference >5s is concerning. >15s is pathological\n\n## Common Bottlenecks\n\n### 1. ResolveAssemblyReference (RAR) Slowness\n\n- **Symptoms**: RAR taking >5s per project\n- **Root causes**: too many assembly references, network-based reference paths, large assembly search paths\n- **Fixes**: reduce reference count, use `\u003CDesignTimeBuild>false\u003C\u002FDesignTimeBuild>` for RAR-heavy analysis, set `\u003CResolveAssemblyReferencesSilent>true\u003C\u002FResolveAssemblyReferencesSilent>` for diagnostic\n- **Advanced**: `\u003CDesignTimeBuild>` and `\u003CResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>`\n- **Key insight**: RAR runs unconditionally even on incremental builds because users may have installed targeting packs or GACed assemblies (see dotnet\u002Fmsbuild#2015). With .NET Core micro-assemblies, the reference count is often very high.\n- **Reduce transitive references**: Set `\u003CDisableTransitiveProjectReferences>true\u003C\u002FDisableTransitiveProjectReferences>` to avoid pulling in the full transitive closure (note: projects may need to add direct references for any types they consume). Use `ReferenceOutputAssembly=\"false\"` on ProjectReferences that are only needed at build time (not API surface). Trim unused PackageReferences.\n\n### 2. Roslyn Analyzers and Source Generators\n\n- **Symptoms**: Csc task takes much longer than expected for file count (>2× clean compile time)\n- **Diagnosis**: Check the Task Performance Summary in the replayed log for Csc task time; grep for analyzer timing messages; compare Csc duration with and without analyzers (`\u002Fp:RunAnalyzers=false`)\n- **Fixes**:\n  - Conditionally disable in dev: `\u003CRunAnalyzers Condition=\"'$(ContinuousIntegrationBuild)' != 'true'\">false\u003C\u002FRunAnalyzers>`\n  - Per-configuration: `\u003CRunAnalyzers Condition=\"'$(Configuration)' == 'Debug'\">false\u003C\u002FRunAnalyzers>`\n  - Code-style only: `\u003CEnforceCodeStyleInBuild Condition=\"'$(ContinuousIntegrationBuild)' == 'true'\">true\u003C\u002FEnforceCodeStyleInBuild>`\n  - Remove genuinely redundant analyzers from inner loop\n  - Severity config in .editorconfig for less critical rules\n- **Key principle**: Preserve analyzer enforcement in CI. Never just \"remove\" analyzers — configure them conditionally.\n- **GlobalPackageReference**: Analyzers added via `GlobalPackageReference` in `Directory.Packages.props` apply to ALL projects. Consider if test projects need the same analyzer set as production code.\n- **EnforceCodeStyleInBuild**: When set to `true` in `Directory.Build.props`, forces code-style analysis on every build. Should be conditional on CI environment (`ContinuousIntegrationBuild`) to avoid slowing dev inner loop.\n\n### 3. Serialization Bottlenecks (Single-threaded targets)\n\n- **Symptoms**: Performance summary shows most build time concentrated in a single project; diagnostic log shows idle nodes while one works\n- **Common culprits**: targets without proper dependency declaration, single project on critical path\n- **Fixes**: split large projects, optimize the critical path project, ensure proper `BuildInParallel`\n\n### 4. Excessive File I\u002FO (Copy tasks)\n\n- **Symptoms**: Copy task shows high aggregate time\n- **Root causes**: copying thousands of files, copying across network drives, Copy task unintentionally running once per item (per-file) instead of as a single batch (see dotnet\u002Fmsbuild#12884)\n- **Fixes**: use hardlinks (`\u003CCreateHardLinksForCopyFilesToOutputDirectoryIfPossible>true\u003C\u002FCreateHardLinksForCopyFilesToOutputDirectoryIfPossible>`), reduce CopyToOutputDirectory items, use `\u003CUseCommonOutputDirectory>true\u003C\u002FUseCommonOutputDirectory>` when appropriate, set `\u003CSkipCopyUnchangedFiles>true\u003C\u002FSkipCopyUnchangedFiles>`, consider `--artifacts-path` (.NET 8+) for centralized output layout\n- **Dev Drive**: On Windows, switching to a Dev Drive (ReFS with copy-on-write and reduced Defender scans) can significantly reduce file I\u002FO overhead for Copy-heavy builds. Recommend for both dev machines and self-hosted CI agents.\n\n### 5. Evaluation Overhead\n\n- **Symptoms**: build starts slow before any compilation\n- **Root causes**: complex Directory.Build.props, wildcard globs scanning large directories, NuGetSdkResolver overhead (adds 180-400ms per project evaluation even when restored — see dotnet\u002Fmsbuild#4025)\n- **Fixes**: reduce Directory.Build.props complexity, use `\u003CEnableDefaultItems>false\u003C\u002FEnableDefaultItems>` for legacy projects with explicit file lists, avoid NuGet-based SDK resolvers if possible\n- See: `eval-performance` skill for detailed guidance\n\n### 6. NuGet Restore in Build\n\n- **Symptoms**: restore runs every build even when unnecessary\n- **Fixes**:\n  - Separate restore from build: `dotnet restore` then `dotnet build --no-restore`\n  - Enable static graph evaluation: `\u003CRestoreUseStaticGraphEvaluation>true\u003C\u002FRestoreUseStaticGraphEvaluation>` in Directory.Build.props — can save significant time in large builds (results are workload-dependent)\n\n### 7. Large Project Count and Graph Shape\n\n- **Symptoms**: many small projects, each takes minimal time but overhead adds up; deep dependency chains serialize the build\n- **Consider**: project consolidation, or use `\u002Fgraph` mode for better scheduling\n- **Graph shape matters**: a wide dependency graph (few levels, many parallel branches) builds faster than a deep one (many levels, serialized). Refactoring from deep to wide can yield significant improvements in both clean and incremental build times.\n- **Actions**: look for unnecessary project dependencies, consider splitting a bottleneck project into two, or merging small leaf projects\n\n## Using Binlog Replay for Performance Analysis\n\nStep-by-step workflow using text log replay:\n\n1. **Replay with performance summary**:\n   ```bash\n   dotnet msbuild build.binlog -noconlog -fl \"-flp:v=diag;logfile=full.log;performancesummary\"\n   ```\n2. **Read target\u002Ftask performance summaries** (at the end of `full.log`):\n   ```bash\n   grep \"Target Performance Summary\\|Task Performance Summary\" -A 50 full.log\n   ```\n   This shows all targets and tasks sorted by cumulative time — equivalent to finding expensive targets\u002Ftasks.\n3. **Find per-project build times**:\n   ```bash\n   grep \"done building project\\|Project Performance Summary\" full.log\n   ```\n4. **Check parallelism** (multi-node scheduling):\n   ```bash\n   grep -i \"node.*assigned\\|RequiresLeadingNewline\\|Building with\" full.log | head -30\n   ```\n5. **Check analyzer overhead**:\n   ```bash\n   grep -i \"Total analyzer execution time\\|analyzer.*elapsed\\|CompilerAnalyzerDriver\" full.log\n   ```\n6. **Drill into a specific slow target**:\n   ```bash\n   grep 'Target \"CoreCompile\"\\|Target \"ResolveAssemblyReferences\"' full.log\n   ```\n\n## Quick Wins Checklist\n\n- [ ] Use `\u002Fmaxcpucount` (or `-m`) for parallel builds\n- [ ] Separate restore from build (`dotnet restore` then `dotnet build --no-restore`)\n- [ ] Enable static graph restore (`\u003CRestoreUseStaticGraphEvaluation>true\u003C\u002FRestoreUseStaticGraphEvaluation>`)\n- [ ] Enable hardlinks for Copy (`\u003CCreateHardLinksForCopyFilesToOutputDirectoryIfPossible>true\u003C\u002FCreateHardLinksForCopyFilesToOutputDirectoryIfPossible>`)\n- [ ] Disable analyzers conditionally in dev inner loop: `\u003CRunAnalyzers Condition=\"'$(ContinuousIntegrationBuild)' != 'true'\">false\u003C\u002FRunAnalyzers>`\n- [ ] Enable reference assemblies (`\u003CProduceReferenceAssembly>true\u003C\u002FProduceReferenceAssembly>`)\n- [ ] Check for broken incremental builds (see `incremental-build` skill)\n- [ ] Check for bin\u002Fobj clashes (see `check-bin-obj-clash` skill)\n- [ ] Use graph build (`\u002Fgraph`) for multi-project solutions\n- [ ] Use `--artifacts-path` (.NET 8+) for centralized output layout\n- [ ] Enable Dev Drive (ReFS) on Windows dev machines and self-hosted CI\n\n## Impact Categorization\n\nWhen reporting findings, categorize by impact to help prioritize fixes:\n\n- ? **HIGH IMPACT** (do first): Items consuming >10% of total build time, or a single target >50% of build time\n- ? **MEDIUM IMPACT**: Items consuming 2-10% of build time\n- ? **QUICK WINS**: Easy changes with modest impact (e.g., property flags in Directory.Build.props)\n",{"name":5,"license":15,"description":7},"main","f8f2bfd77819bb789d4736ce7db4a567a37fcf7e",".agents\u002Fskills\u002Fbuild-perf-diagnostics",315,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Ftestfx","https:\u002F\u002Fgithub.com\u002Fmicrosoft","https:\u002F\u002Fopensource.microsoft.com","Open source projects and samples from Microsoft","2026-11-12 02:10:33",{"source":8,"skillName":5,"commands":47,"prompt":57,"zipAvailable":58},[48,51,54],{"tool":49,"command":50},"npx","npx skills add microsoft\u002Ftestfx --skill build-perf-diagnostics",{"tool":52,"command":53},"bunx","bunx skills add microsoft\u002Ftestfx --skill build-perf-diagnostics",{"tool":55,"command":56},"pnpm","pnpm dlx skills add microsoft\u002Ftestfx --skill build-perf-diagnostics","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Ftestfx\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fbuild-perf-diagnostics\u002FSKILL.md",true,[],[61,88,119,140,159,183],{"skillNo":62,"name":63,"nameZh":6,"description":64,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":65,"categories":66,"keywords":67,"publishedAt":32},"01M70GYY0AV0JGMTHE2CN6TNYK","dotnet-breaking-changes","Use before changing .NET\u002FC# code whose callers you do not control: a NuGet library, or a repo with PublicAPI.Shipped\u002FUnshipped.txt, ApiCompat, multiple TargetFrameworks, InternalsVisibleTo, or generated (.g.cs) partials. Green builds miss silent breaks from optional parameters, parameter names, sealing, const values, nullability, and #if. USE FOR: \"without breaking existing callers\"; adding a public method, overload, optional parameter, or interface member to a shipped library; renaming a public method or an internal helper a friend assembly uses; consolidating duplicated logic; changing a signature, nullability, default, or attribute; adding a target framework; RS0016\u002FRS0017 or ApiCompat errors; \"is this PR breaking?\". For a rename, extract, or merge, also invoke csharp-refactoring. DO NOT USE FOR: an executable whose callers all live in one project; renaming a local variable or private member, even in a shipped library; formatting; framework\u002FSDK\u002FNuGet upgrades (use dotnet-upgrade).","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Ftestfx\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fdotnet-breaking-changes\u002FSKILL.md",[],[68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87],"dotnet","dotnet breaking changes","changes","green","project","default","local","errors","interface","generated","upgrade","invoke","you","code","refactoring","merge","rename","library","live","assembly",{"skillNo":89,"name":90,"nameZh":6,"description":91,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":92,"categories":93,"keywords":99,"publishedAt":32},"01M699HHE9DTZWAMPB1ZR7ZKSW","testfx-test-value-evidence","Apply the vendored test-value-evidence skill with TestFx toolchain, assertion, parallel-safety, packed-consumer, and review conventions. Use when implementing or reviewing behavior-changing TestFx PRs or commits, including source-only changes.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Ftestfx\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Ftestfx-test-value-evidence\u002FSKILL.md",[94],{"categoryNo":95,"categoryName":96,"taxonomyType":97,"taxonomyTypeDesc":98},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",[100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,70,116,117,118],"test","testfx test value evidence","test value evidence","evidence","value","review","parallel","toolchain","commits","implementing","prs","only","use","when","apply","with","behavior","Safety","conventions",{"skillNo":120,"name":121,"nameZh":6,"description":122,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":123,"categories":124,"keywords":125,"publishedAt":32},"01M699HEYWH1B9XGNBFY8J2FZS","testfx-parallel-safety-preflight","Check concurrency and isolation before implementing or refactoring TestFx tests, lifecycle code, helpers, shared-state declarations, or production paths those tests exercise. Use before narrowing DoNotParallelize or ResourceLock, changing parallelization settings, or introducing asynchronous workers; repeat against the final diff.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Ftestfx\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Ftestfx-parallel-safety-preflight\u002FSKILL.md",[],[126,117,127,106,128,129,109,130,81,131,82,132,133,134,135,136,137,138,112,139],"testfx parallel safety preflight","preflight","shared","asynchronous","exercise","concurrency","paths","isolation","helpers","diff","parallelization","lifecycle","tests","workers",{"skillNo":141,"name":142,"nameZh":6,"description":143,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":144,"categories":145,"keywords":146,"publishedAt":32},"01M699HC61ZV9GJ2C8JV03951G","testfx-localization-validation","Validate generated TestFx localization catalogs, resource IDs, placeholders and locked tokens. Use for RESX\u002FXLF changes, OneLoc PRs, localization build failures, duplicate targets or units, and orphaned translation entries.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Ftestfx\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Ftestfx-localization-validation\u002FSKILL.md",[],[147,148,149,150,151,152,153,154,155,110,77,112,156,157,70,158,22],"testfx localization validation","validation","localization","validate","translation","ids","for","tokens","entries","units","duplicate","targets",{"skillNo":160,"name":161,"nameZh":6,"description":162,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":163,"categories":164,"keywords":166,"publishedAt":32},"01M699H9J2NWQXE4BDT6R0FH7S","testfx-acceptance-validation","Validate TestFx shipping paths and capable CI execution using packed consumers, package\u002Fcache provenance, exact exits and artifacts, and selected-versus-executed test evidence. Use for acceptance regressions, package\u002FMSBuild\u002Flauncher\u002Fprotocol changes, or skipped-only CI results; not for unrelated unit-only or documentation changes.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Ftestfx\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Ftestfx-acceptance-validation\u002FSKILL.md",[165],{"categoryNo":95,"categoryName":96,"taxonomyType":97,"taxonomyTypeDesc":98},[167,168,148,100,23,103,169,170,171,111,172,112,173,174,175,176,177,178,179,180,181,182,132,153],"testfx acceptance validation","acceptance","launcher","ci","execution","package","cache","artifacts","provenance","documentation","unrelated","shipping","results","protocol","unit","ci results",{"skillNo":184,"name":185,"nameZh":6,"description":186,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":187,"categories":188,"keywords":189,"publishedAt":32},"01M699H70BB999BT4F627T1PHE","session-delivery-hygiene","Gate local-session scope, persistent delivery, live PR state, integration provenance, and owned cleanup. Use before implementing guidance changes, changing or pushing PR work, diagnosing package\u002Foutput mismatches, or handing off implementation.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Ftestfx\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fsession-delivery-hygiene\u002FSKILL.md",[],[190,191,192,193,194,109,74,195,196,86,197,172,112,175,198,199,70,200,201,202],"session delivery hygiene","delivery","session","hygiene","scope","cleanup","work","pr","output","state","integration","guidance","gate"]