[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-dotnet-binskim-analysis":3,"mdc-7zg05o-key":36,"related-org-dotnet-binskim-analysis":2133,"related-repo-dotnet-binskim-analysis":2300},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":25,"repoUrl":26,"updatedAt":27,"license":28,"forks":29,"topics":30,"repo":31,"sourceUrl":34,"mdContent":35},"binskim-analysis","investigate BinSkim SDL security findings","Investigate BinSkim SDL findings from official pipelines — understand Guardian filtering, compare raw vs merged SARIF, decode portal results, and determine fix ownership. Use when asked about SDL scan results, portal findings, Guardian filtering, rule meanings, or discrepancies between local and official results. Also use when asked \"why does the portal show X\", \"what's filtered\", \"explain Guardian\", \"investigate SDL findings\", \"portal BA2008\", \"binskim failures in pipeline\", or \"what rules are required\". DO NOT USE FOR: running BinSkim locally (use binskim-scan), source code analysis (use CodeQL), or credential scanning (use CredScan).\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},"dotnet",".NET (Microsoft)","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fdotnet.png",[12,16,19,22],{"name":13,"slug":14,"type":15},"Security","security","tag",{"name":17,"slug":18,"type":15},".NET","net",{"name":20,"slug":21,"type":15},"Audit","audit",{"name":23,"slug":24,"type":15},"Code Analysis","code-analysis",12,"https:\u002F\u002Fgithub.com\u002Fdotnet\u002Farcade-skills","2026-07-12T08:23:11.212231",null,18,[],{"repoUrl":26,"stars":25,"forks":29,"topics":32,"description":33},[],"Reuseable AI skills, plugins, agents for use in the dotnet product repos, such as dotnet\u002Fruntime","https:\u002F\u002Fgithub.com\u002Fdotnet\u002Farcade-skills\u002Ftree\u002FHEAD\u002Fplugins\u002Fdotnet-compliance\u002Fskills\u002Fbinskim-analysis","---\nname: binskim-analysis\ndescription: >\n  Investigate BinSkim SDL findings from official pipelines — understand Guardian filtering,\n  compare raw vs merged SARIF, decode portal results, and determine fix ownership.\n  Use when asked about SDL scan results, portal findings, Guardian filtering, rule meanings,\n  or discrepancies between local and official results. Also use when asked \"why does the portal\n  show X\", \"what's filtered\", \"explain Guardian\", \"investigate SDL findings\", \"portal BA2008\",\n  \"binskim failures in pipeline\", or \"what rules are required\". DO NOT USE FOR: running BinSkim\n  locally (use binskim-scan), source code analysis (use CodeQL), or credential scanning (use CredScan).\n---\n\n# BinSkim Official Results Analysis\n\nInvestigate and interpret BinSkim findings from official 1ES SDL pipelines. This skill helps you understand what the central portal reports, what gets filtered, and how to determine fix ownership.\n\n> For running BinSkim locally against a repo, use the **binskim-scan** skill instead.\n\n## When to Use This Skill\n\n- Investigating BinSkim findings reported in the central SDL portal\n- Understanding why the portal shows (or doesn't show) specific findings\n- Comparing local scan results with official pipeline results\n- Determining whether a finding is fixable in the repo or requires an upstream vendor fix\n- Questions like \"why does the portal show BA2008 on X.dll?\", \"what rules apply to my repo?\"\n\n## How Official SDL Scanning Works\n\nOfficial pipelines run BinSkim via Guardian, not directly. Results go through filtering before reaching the portal:\n\n```text\nBinSkim runs -> raw binskim.sarif (ALL findings)\n     |\nGuardian merges\u002Ffilters -> Results.sarif (subset)\n     |\nResults.sarif uploaded -> Central portal\n```\n\n**Your local scan will find more issues than the portal reports.** This is expected — the portal only shows findings for rules with SDL policy requirement mappings for your org. See [references\u002Fguardian-filtering.md](references\u002Fguardian-filtering.md) for the full filtering pipeline.\n\n## Downloading SDL Artifacts\n\nTo investigate official results, download the SDL artifact from the repo's official build:\n\n```powershell\n# Use AzDO tools or ado-dnceng-pipelines_download_artifact\n# Artifact naming pattern:\n#   Most repos:  drop_build_Windows_x64_sdl_analysis\n#   VMR repos:   drop_VMR_Vertical_Build_Windows_x64_sdl_analysis\n# Some repos have multiple SDL legs — check ALL OS legs (Windows, Linux, macOS)\n# Each OS build produces different native binaries with potentially different findings\n#\n# ⚠️ NON-WINDOWS SDL ARTIFACTS MAY BE EMPTY. Some pipelines may have a bug where\n#    BinSkim only runs on Windows SDL legs. Linux\u002FmacOS SDL artifacts may exist but contain 0-byte\n#    SARIF files. Always check file sizes before parsing — don't assume non-Windows legs\n#    have results.\n#\n# ⚠️ LARGE PIPELINE ARTIFACTS: For large artifacts (>100MB), the AzDO REST API may return\n#    an HTML sign-in page if you use $format=zip directly. Instead:\n#    1. GET the artifact metadata first:\n#       GET ...\u002F_apis\u002Fbuild\u002Fbuilds\u002F{buildId}\u002Fartifacts?artifactName={name}&api-version=7.1\n#    2. Extract the downloadUrl from the response: .resource.downloadUrl\n#    3. GET that URL with a bearer token to download the actual content\n#    This CDN-based download works reliably for any artifact size.\n\n# Key files inside the artifact:\n# - binskim\u002F001\u002Fbinskim.sarif    \u003C- Raw BinSkim output (everything found)\n# - Results.sarif                 \u003C- Guardian-merged output (portal sees this)\n# - break\u002F001\u002Foptions.json        \u003C- Break policy (which tools can fail the build)\n# - .gdnbaselines                 \u003C- Auto-generated baseline suppressions\n```\n\n### Downloading via MCP when the agent host suppresses binary tool output\n\nSome agent CLI hosts run the MCP `pipelines_artifact` `download` action successfully but **silently drop the embedded-resource zip** (you see \"Tool ran without output or errors\" and no file lands anywhere). When that happens, call the MCP HTTP endpoint directly from PowerShell and decode the base64 blob yourself:\n\n1. Find the MCP servers config (the file path is in env, but typically): `Get-ChildItem $env:TEMP -Filter \"copilot-mcp-*.json\" | Sort LastWriteTime -Descending | Select -First 1 | Get-Content -Raw` — locate the `ado-dnceng` (or `ado-dnceng-public`) entry's `url` and capture it in a variable (the port is assigned per session, so it changes every time):\n   ```powershell\n   $mcpUrl = (Get-Content (Get-ChildItem $env:TEMP -Filter 'copilot-mcp-*.json' | Sort LastWriteTime -Descending | Select -First 1) -Raw | ConvertFrom-Json).mcpServers.'ado-dnceng'.url\n   ```\n2. POST a `tools\u002Fcall` JSON-RPC request (uses `$mcpUrl` from step 1 — do not hardcode the port):\n   ```powershell\n   $req = @{ jsonrpc='2.0'; id=2; method='tools\u002Fcall'; params=@{\n     name='pipelines_artifact'\n     arguments=@{ action='download'; buildId=\u003Cid>; project='internal'; artifactName='\u003Cname>' }\n   } } | ConvertTo-Json -Compress -Depth 10\n   $msg = [System.Net.Http.HttpRequestMessage]::new('POST',$mcpUrl)\n   $msg.Headers.Accept.ParseAdd('application\u002Fjson, text\u002Fevent-stream')\n   $msg.Content = [System.Net.Http.StringContent]::new($req,[Text.Encoding]::UTF8,'application\u002Fjson')\n   $client = [System.Net.Http.HttpClient]::new(); $client.Timeout = [TimeSpan]::FromMinutes(15)\n   $body = $client.SendAsync($msg).Result.Content.ReadAsStringAsync().Result\n   ```\n3. Response is **Server-Sent Events**: find the `data: ` line and `ConvertFrom-Json`. The zip is at `result.content[0].resource.blob` (base64). Write with `[IO.File]::WriteAllBytes($path, [Convert]::FromBase64String($blob))` then `Expand-Archive`.\n4. Reusable script template: see `C:\\temp\\Download-AdoArtifact.ps1` if previously generated, or recreate from the snippet above.\n\nNotes:\n- The MCP-served zip is dedup-compressed and is **much smaller** than the `artifactsize` reported by the artifact list call (an 86 MB \"artifactsize\" Windows_x64 SDL artifact downloads as a ~5–6 MB zip but contains the full 40+ MB raw and merged SARIF after extraction). Don't be alarmed by the size delta.\n- `az login` \u002F `Connect-AzAccount` may hang indefinitely in non-interactive agent shells — don't rely on them. The MCP HTTP path above uses the MCP server's existing auth so no extra login is needed.\n\n> **Large SARIF files**: For repos with many binaries (especially the VMR), raw and merged SARIF can be **50-80MB+**. Use `Get-Content -Raw | ConvertFrom-Json` and stream results with `Group-Object`.\n\n> **SDL does NOT run on PR validation builds.** It only runs on official\u002FCI pipelines (gated by `Build.Reason != PullRequest`). Users must manually queue the official pipeline for SDL results before merging.\n\n**Per-repo pipeline names** — see [references\u002Frepo-profiles-index.md](references\u002Frepo-profiles-index.md) for the index of per-repo profile files (one per repo). Load only the file for the repo you're investigating.\n\n## SDL Artifact Structure\n\nThe SDL artifact contains a rich directory structure. Key files and what they tell you:\n\n```text\n\u003CSDL artifact>\u002F\n  binskim\u002F\n    001\u002Fbinskim.sarif         # Raw BinSkim output for scan directory 1 (e.g., bin\u002F)\n    001\u002F.gdntoolinput         # Explicit file list — exactly what was scanned\n    002\u002Fbinskim.sarif         # Raw BinSkim output for scan directory 2 (e.g., symbols\u002F)\n    002\u002F.gdntoolinput         # Explicit file list for directory 2\n  prefast\u002F                    # Native C++ static analysis (separate from BinSkim)\n  roslynanalyzers\u002F            # Managed code analysis\n  break\u002F001\u002Foptions.json      # Break policy — which tools can fail the build\n  Results.sarif               # Guardian-merged & deduplicated (this goes to portal)\n  Results3.sarif              # Cumulative raw output from ALL tool phases\n  .gdnbaselines               # Baselined finding signatures (managed by Guardian portal)\n  .gdnsuppress                # Suppressed findings (same set, filtered from S360)\n```\n\n**Multiple phases**: Most tools run in 4 phases (001-004); BinSkim typically has 2 (one per staging directory). Results3.sarif aggregates all phases — expect hundreds of \"runs\" (e.g., 417 = 310 roslynanalyzers + 100 prefast + 7 binskim). Results.sarif deduplicates these down (e.g., to 42 unique runs).\n\n**`.gdntoolinput` is the source of truth** for what was actually scanned. It's an explicit file list (one quoted path per line), NOT a recursive glob. If a binary isn't in this file, BinSkim didn't see it.\n\n**`.gdnbaselines`** are NOT repo-committed — they're auto-generated pipeline artifacts used for break-on-new-only tracking. **`.gdnsuppress`** files CAN be checked into source to suppress specific findings, but this is rarely done in dotnet repos. Neither can weaken SDL policy — the tenant\u002Forg policy sets the floor.\n\n## Comparing Raw vs Merged SARIF\n\nAlways compare both files to understand what Guardian filtered:\n\n```powershell\n$raw = (Get-Content \"binskim\\001\\binskim.sarif\" -Raw | ConvertFrom-Json).runs[0].results\n# IMPORTANT: Results.sarif contains multiple runs (BinSkim, roslynanalyzers, prefast, etc.)\n# Filter to the BinSkim run — don't assume runs[0] is BinSkim\n$mergedSarif = Get-Content \"Results.sarif\" -Raw | ConvertFrom-Json\n$binskimRun = $mergedSarif.runs | Where-Object { $_.tool.driver.name -like '*BinSkim*' } | Select-Object -First 1\n$merged = if ($binskimRun) { $binskimRun.results } else { $mergedSarif.runs[0].results }\n\nWrite-Host \"Raw BinSkim findings: $($raw.Count)\"\nWrite-Host \"After Guardian filtering: $($merged.Count)\"\nWrite-Host \"`nRaw findings by rule:\"\n$raw | Group-Object ruleId | ForEach-Object {\n    $levels = ($_.Group | ForEach-Object { $_.level } | Sort-Object -Unique) -join \",\"\n    Write-Host \"  $($_.Name): count=$($_.Count) levels=[$levels]\"\n}\n```\n\nThe delta between raw and merged is what Guardian filtered out based on SDL policy. See [references\u002Fguardian-filtering.md](references\u002Fguardian-filtering.md) for why things get filtered and the suppression mechanisms available.\n\n## Service Tree and Org Awareness\n\nWhich rules the portal reports depends on `es-metadata.yml` — the `routing.defaultAreaPath.org` field determines your SDL policy scope. Different orgs surface different rules. For example, the `devdiv` org (most `dotnet\u002F*` repos) treats BA2008\u002FBA2009\u002FBA2021 as SDL-required (10203-mapped), while the `nettel` org surfaces BA2004\u002FBA2027 as informational findings in the portal. **Neither BA2004 nor BA2027 is SDL-required at the company level** (no 10203 mapping) — but informational portal findings still often get triaged like requirements, so they are worth fixing. See [references\u002Frepo-perfview.md](references\u002Frepo-perfview.md) for a worked example.\n\nSee [references\u002Fbinskim-rules.md](references\u002Fbinskim-rules.md) for the full rules tables and the observed portal requirements by org.\n\n## Coverage Gap Detection\n\nAfter examining results, check whether the scan covers everything the repo ships:\n\n1. **List all published artifacts** from the pipeline YAML\n2. **Compare with `.gdntoolinput` file lists** in the SDL artifact — these are the explicit files Guardian scanned. Not a recursive directory walk.\n3. **Report gaps**: \"This repo ships X.dll (native C++ binary) but it's not in the `.gdntoolinput` scan targets — likely because it isn't staged to the bin\u002F or symbols\u002F directories that Guardian scans.\"\n\n**Common gap — unstaged binaries**: Native C++ binaries built by `.vcxproj` often output to project-local `Release\\` directories, not the main `artifacts\\bin\\` staging area. Guardian generates `.gdntoolinput` from the staging directories, so these binaries get Prefast coverage (source analysis) but miss BinSkim (binary analysis). This is a pipeline artifact staging config issue.\n\n**Common gap — missing OS coverage**: Each OS build configuration produces different native binaries (e.g., Linux `.so`, macOS `.dylib`, Windows `.dll`). If the official pipeline only runs BinSkim on Windows SDL legs, Linux and macOS native binaries are not scanned at all. **Flag this clearly as a coverage gap that needs fixing.** Note: this gap is typically caused by the 1ES\u002FGuardian SDL template using Windows-centric glob patterns (matching `.dll`\u002F`.exe`\u002F`.sys`) rather than a BinSkim limitation — BinSkim can scan PE, ELF, and Mach-O binaries on any OS using magic-byte detection. To close the gap, either configure broader glob patterns in the existing SDL legs, or add BinSkim scanning steps that target non-Windows artifacts with appropriate patterns (`*.dylib`, `*.so`, or `**`).\n\n## Classification Framework\n\nWhen analyzing findings, classify each into one of four buckets to determine the right action:\n\n| Bucket | Description | Action |\n|--------|-------------|--------|\n| **First-party shipped** | Binary built from repo source, included in shipping packages | Fix in repo — highest priority |\n| **Foreign shipped** | Third-party binary (from NuGet\u002Fvendored), included in shipping packages | File upstream issue, update package, or request SDL exception |\n| **First-party non-shipped** | Binary built from repo source, in test\u002FNonShipping only | Fix for hygiene (low priority), or exclude from scan scope |\n| **Foreign non-shipped** | Third-party binary, in test\u002FNonShipping only | Suppress — should not appear in official scans if artifact staging is correct |\n\nTo classify: check the SARIF artifact path for `Shipping` vs `NonShipping`, and search the repo for the binary's source project (`.vcxproj`\u002F`.csproj`) vs NuGet package origin.\n\n## Fix Ownership\n\nNot all findings can be fixed in the repo where they're reported:\n\n| Binary origin | Example | Fix approach |\n|---|---|---|\n| **C++ source in repo** (`.vcxproj`) | EtwClrProfiler.dll | Add compiler\u002Flinker flags (e.g., `\u002Fguard:cf` for BA2008) |\n| **Pre-built native from NuGet** | Intel MKL\u002FTBB, WiX winterop.dll | Cannot fix here — update package, file upstream issue, or suppress |\n| **Test framework binaries** | xunit.*.dll | Fix scan scope — exclude from shipped artifacts |\n| **Managed C# assembly** | Most `.dll` from `.csproj` | BA2008 not applicable (BinSkim skips IL-only). BA2004\u002FBA2027 may apply |\n\n**VMR (dotnet\u002Fdotnet)**: Findings map to source sub-repos. Look at the artifact path in the SARIF (e.g., `src\u002Farcade\u002Fartifacts\u002F...` means fix goes to `dotnet\u002Farcade`).\n\n### Common misconception\n\n`\u003CControlFlowGuard>Guard\u003C\u002FControlFlowGuard>` in a `.csproj` does **nothing**. The C# compiler has no `\u002Fguard:cf` support. This MSBuild property only works in `.vcxproj` (MSVC C++). BA2008 only fires on native PE binaries.\n\n## Non-Arcade Repos\n\nSome repos (e.g., microsoft\u002Fperfview) don't use arcade infrastructure:\n- No `eng\u002Fcommon\u002Fsdl\u002F` — BinSkim config is in the 1ES template or pipeline YAML directly\n- Build output may be in `src\\bin\\` instead of `artifacts\\`\n- Look for `.ado.yml` or `.pipelines\u002F` for pipeline config\n- The general analysis approach still works — find the SDL artifact, compare raw vs merged SARIF\n\n## Anti-Patterns\n\n> **Don't trust the central portal as the complete picture.** Download the raw `binskim.sarif` and compare with `Results.sarif`. The portal shows only findings for rules with SDL policy mappings.\n\n> **Don't assume \"not in the portal\" means \"not a problem.\"** Guardian filtering removes findings without SDL policy mappings for your org. These may still be good security practice.\n\n> **Don't confuse break policy with reporting.** Break policy controls whether BinSkim fails the build. It does NOT control what gets reported to the portal. Findings can be reported without breaking the build.\n\n> **Don't assume Windows-only scanning is sufficient.** If the repo ships native binaries for Linux or macOS (`.so`, `.dylib`), those binaries may have different BinSkim findings than their Windows counterparts. If official SDL legs only cover Windows, flag this as a gap — the pipeline should be updated to run BinSkim on all OS configurations that produce shipped native artifacts.\n\n## Comparing Local Scan vs Official Run\n\nWhen the user has run the **binskim-scan** skill locally and wants to validate against official results:\n\n| Aspect | Official run | Local scan |\n|---|---|---|\n| **Scope** | Only staged artifacts (explicit `.gdntoolinput` list) | Everything under build output (`src\\**` or `artifacts\\**`) |\n| **Test\u002Fbenchmark binaries** | Excluded from staging | Included (flagged in summary) |\n| **NuGet package binaries** | Excluded unless staged | Included if in build output |\n| **Native C++ binaries** | Only if staged to bin\u002Fsymbols dirs | Included if built successfully |\n| **PDB availability** | Staged alongside binaries | Present if build output is used |\n| **OS coverage** | Check whether ALL OS legs have SDL scanning — not just Windows | Scan on each OS you build for |\n\n**Key reconciliation questions:**\n1. Do all local errors also appear in official? If not, they may be in test\u002FNuGet paths that official doesn't scan.\n2. Do any official findings NOT appear locally? Could mean the binary wasn't built locally (e.g., missing C++ toolset).\n3. Are there binaries in the official `.gdntoolinput` that the local scan missed? Unlikely with recursive scan — the other direction (local finds more) is expected.\n4. Does official scan native C++ binaries that ship? Check `.gdntoolinput` — this is a known gap for repos where C++ output goes to non-standard directories.\n\n> **Don't report NuGet transitive dependency findings as repo issues.** If `libSkiaSharp.dll` fails BA2008, that's SkiaSharp's issue — unless this repo ships it.\n\n## References\n\n- **BinSkim rules (all platforms)**: [references\u002Fbinskim-rules.md](references\u002Fbinskim-rules.md)\n- **Guardian filtering deep-dive**: [references\u002Fguardian-filtering.md](references\u002Fguardian-filtering.md)\n- **Per-repo profiles**: [references\u002Frepo-profiles-index.md](references\u002Frepo-profiles-index.md) (index — one .md per repo)\n- **Arcade SDL infrastructure**: [references\u002Farcade-sdl.md](references\u002Farcade-sdl.md)\n- **Local scanning**: Use the **binskim-scan** skill\n",{"data":37,"body":38},{"name":4,"description":6},{"type":39,"children":40},"root",[41,50,56,73,80,110,116,121,134,152,158,163,397,404,432,652,657,699,734,755,772,778,783,792,802,818,843,849,854,972,983,989,1048,1060,1066,1071,1118,1159,1246,1252,1257,1374,1409,1415,1420,1560,1585,1591,1630,1636,1641,1702,1708,1737,1750,1763,1789,1795,1806,1980,1988,2025,2046,2052,2127],{"type":42,"tag":43,"props":44,"children":46},"element","h1",{"id":45},"binskim-official-results-analysis",[47],{"type":48,"value":49},"text","BinSkim Official Results Analysis",{"type":42,"tag":51,"props":52,"children":53},"p",{},[54],{"type":48,"value":55},"Investigate and interpret BinSkim findings from official 1ES SDL pipelines. This skill helps you understand what the central portal reports, what gets filtered, and how to determine fix ownership.",{"type":42,"tag":57,"props":58,"children":59},"blockquote",{},[60],{"type":42,"tag":51,"props":61,"children":62},{},[63,65,71],{"type":48,"value":64},"For running BinSkim locally against a repo, use the ",{"type":42,"tag":66,"props":67,"children":68},"strong",{},[69],{"type":48,"value":70},"binskim-scan",{"type":48,"value":72}," skill instead.",{"type":42,"tag":74,"props":75,"children":77},"h2",{"id":76},"when-to-use-this-skill",[78],{"type":48,"value":79},"When to Use This Skill",{"type":42,"tag":81,"props":82,"children":83},"ul",{},[84,90,95,100,105],{"type":42,"tag":85,"props":86,"children":87},"li",{},[88],{"type":48,"value":89},"Investigating BinSkim findings reported in the central SDL portal",{"type":42,"tag":85,"props":91,"children":92},{},[93],{"type":48,"value":94},"Understanding why the portal shows (or doesn't show) specific findings",{"type":42,"tag":85,"props":96,"children":97},{},[98],{"type":48,"value":99},"Comparing local scan results with official pipeline results",{"type":42,"tag":85,"props":101,"children":102},{},[103],{"type":48,"value":104},"Determining whether a finding is fixable in the repo or requires an upstream vendor fix",{"type":42,"tag":85,"props":106,"children":107},{},[108],{"type":48,"value":109},"Questions like \"why does the portal show BA2008 on X.dll?\", \"what rules apply to my repo?\"",{"type":42,"tag":74,"props":111,"children":113},{"id":112},"how-official-sdl-scanning-works",[114],{"type":48,"value":115},"How Official SDL Scanning Works",{"type":42,"tag":51,"props":117,"children":118},{},[119],{"type":48,"value":120},"Official pipelines run BinSkim via Guardian, not directly. Results go through filtering before reaching the portal:",{"type":42,"tag":122,"props":123,"children":128},"pre",{"className":124,"code":126,"language":48,"meta":127},[125],"language-text","BinSkim runs -> raw binskim.sarif (ALL findings)\n     |\nGuardian merges\u002Ffilters -> Results.sarif (subset)\n     |\nResults.sarif uploaded -> Central portal\n","",[129],{"type":42,"tag":130,"props":131,"children":132},"code",{"__ignoreMap":127},[133],{"type":48,"value":126},{"type":42,"tag":51,"props":135,"children":136},{},[137,142,144,150],{"type":42,"tag":66,"props":138,"children":139},{},[140],{"type":48,"value":141},"Your local scan will find more issues than the portal reports.",{"type":48,"value":143}," This is expected — the portal only shows findings for rules with SDL policy requirement mappings for your org. See ",{"type":42,"tag":145,"props":146,"children":148},"a",{"href":147},"references\u002Fguardian-filtering.md",[149],{"type":48,"value":147},{"type":48,"value":151}," for the full filtering pipeline.",{"type":42,"tag":74,"props":153,"children":155},{"id":154},"downloading-sdl-artifacts",[156],{"type":48,"value":157},"Downloading SDL Artifacts",{"type":42,"tag":51,"props":159,"children":160},{},[161],{"type":48,"value":162},"To investigate official results, download the SDL artifact from the repo's official build:",{"type":42,"tag":122,"props":164,"children":168},{"className":165,"code":166,"language":167,"meta":127,"style":127},"language-powershell shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# Use AzDO tools or ado-dnceng-pipelines_download_artifact\n# Artifact naming pattern:\n#   Most repos:  drop_build_Windows_x64_sdl_analysis\n#   VMR repos:   drop_VMR_Vertical_Build_Windows_x64_sdl_analysis\n# Some repos have multiple SDL legs — check ALL OS legs (Windows, Linux, macOS)\n# Each OS build produces different native binaries with potentially different findings\n#\n# ⚠️ NON-WINDOWS SDL ARTIFACTS MAY BE EMPTY. Some pipelines may have a bug where\n#    BinSkim only runs on Windows SDL legs. Linux\u002FmacOS SDL artifacts may exist but contain 0-byte\n#    SARIF files. Always check file sizes before parsing — don't assume non-Windows legs\n#    have results.\n#\n# ⚠️ LARGE PIPELINE ARTIFACTS: For large artifacts (>100MB), the AzDO REST API may return\n#    an HTML sign-in page if you use $format=zip directly. Instead:\n#    1. GET the artifact metadata first:\n#       GET ...\u002F_apis\u002Fbuild\u002Fbuilds\u002F{buildId}\u002Fartifacts?artifactName={name}&api-version=7.1\n#    2. Extract the downloadUrl from the response: .resource.downloadUrl\n#    3. GET that URL with a bearer token to download the actual content\n#    This CDN-based download works reliably for any artifact size.\n\n# Key files inside the artifact:\n# - binskim\u002F001\u002Fbinskim.sarif    \u003C- Raw BinSkim output (everything found)\n# - Results.sarif                 \u003C- Guardian-merged output (portal sees this)\n# - break\u002F001\u002Foptions.json        \u003C- Break policy (which tools can fail the build)\n# - .gdnbaselines                 \u003C- Auto-generated baseline suppressions\n","powershell",[169],{"type":42,"tag":130,"props":170,"children":171},{"__ignoreMap":127},[172,183,192,201,210,219,228,237,246,255,264,273,280,289,298,307,316,325,333,342,352,361,370,379,388],{"type":42,"tag":173,"props":174,"children":177},"span",{"class":175,"line":176},"line",1,[178],{"type":42,"tag":173,"props":179,"children":180},{},[181],{"type":48,"value":182},"# Use AzDO tools or ado-dnceng-pipelines_download_artifact\n",{"type":42,"tag":173,"props":184,"children":186},{"class":175,"line":185},2,[187],{"type":42,"tag":173,"props":188,"children":189},{},[190],{"type":48,"value":191},"# Artifact naming pattern:\n",{"type":42,"tag":173,"props":193,"children":195},{"class":175,"line":194},3,[196],{"type":42,"tag":173,"props":197,"children":198},{},[199],{"type":48,"value":200},"#   Most repos:  drop_build_Windows_x64_sdl_analysis\n",{"type":42,"tag":173,"props":202,"children":204},{"class":175,"line":203},4,[205],{"type":42,"tag":173,"props":206,"children":207},{},[208],{"type":48,"value":209},"#   VMR repos:   drop_VMR_Vertical_Build_Windows_x64_sdl_analysis\n",{"type":42,"tag":173,"props":211,"children":213},{"class":175,"line":212},5,[214],{"type":42,"tag":173,"props":215,"children":216},{},[217],{"type":48,"value":218},"# Some repos have multiple SDL legs — check ALL OS legs (Windows, Linux, macOS)\n",{"type":42,"tag":173,"props":220,"children":222},{"class":175,"line":221},6,[223],{"type":42,"tag":173,"props":224,"children":225},{},[226],{"type":48,"value":227},"# Each OS build produces different native binaries with potentially different findings\n",{"type":42,"tag":173,"props":229,"children":231},{"class":175,"line":230},7,[232],{"type":42,"tag":173,"props":233,"children":234},{},[235],{"type":48,"value":236},"#\n",{"type":42,"tag":173,"props":238,"children":240},{"class":175,"line":239},8,[241],{"type":42,"tag":173,"props":242,"children":243},{},[244],{"type":48,"value":245},"# ⚠️ NON-WINDOWS SDL ARTIFACTS MAY BE EMPTY. Some pipelines may have a bug where\n",{"type":42,"tag":173,"props":247,"children":249},{"class":175,"line":248},9,[250],{"type":42,"tag":173,"props":251,"children":252},{},[253],{"type":48,"value":254},"#    BinSkim only runs on Windows SDL legs. Linux\u002FmacOS SDL artifacts may exist but contain 0-byte\n",{"type":42,"tag":173,"props":256,"children":258},{"class":175,"line":257},10,[259],{"type":42,"tag":173,"props":260,"children":261},{},[262],{"type":48,"value":263},"#    SARIF files. Always check file sizes before parsing — don't assume non-Windows legs\n",{"type":42,"tag":173,"props":265,"children":267},{"class":175,"line":266},11,[268],{"type":42,"tag":173,"props":269,"children":270},{},[271],{"type":48,"value":272},"#    have results.\n",{"type":42,"tag":173,"props":274,"children":275},{"class":175,"line":25},[276],{"type":42,"tag":173,"props":277,"children":278},{},[279],{"type":48,"value":236},{"type":42,"tag":173,"props":281,"children":283},{"class":175,"line":282},13,[284],{"type":42,"tag":173,"props":285,"children":286},{},[287],{"type":48,"value":288},"# ⚠️ LARGE PIPELINE ARTIFACTS: For large artifacts (>100MB), the AzDO REST API may return\n",{"type":42,"tag":173,"props":290,"children":292},{"class":175,"line":291},14,[293],{"type":42,"tag":173,"props":294,"children":295},{},[296],{"type":48,"value":297},"#    an HTML sign-in page if you use $format=zip directly. Instead:\n",{"type":42,"tag":173,"props":299,"children":301},{"class":175,"line":300},15,[302],{"type":42,"tag":173,"props":303,"children":304},{},[305],{"type":48,"value":306},"#    1. GET the artifact metadata first:\n",{"type":42,"tag":173,"props":308,"children":310},{"class":175,"line":309},16,[311],{"type":42,"tag":173,"props":312,"children":313},{},[314],{"type":48,"value":315},"#       GET ...\u002F_apis\u002Fbuild\u002Fbuilds\u002F{buildId}\u002Fartifacts?artifactName={name}&api-version=7.1\n",{"type":42,"tag":173,"props":317,"children":319},{"class":175,"line":318},17,[320],{"type":42,"tag":173,"props":321,"children":322},{},[323],{"type":48,"value":324},"#    2. Extract the downloadUrl from the response: .resource.downloadUrl\n",{"type":42,"tag":173,"props":326,"children":327},{"class":175,"line":29},[328],{"type":42,"tag":173,"props":329,"children":330},{},[331],{"type":48,"value":332},"#    3. GET that URL with a bearer token to download the actual content\n",{"type":42,"tag":173,"props":334,"children":336},{"class":175,"line":335},19,[337],{"type":42,"tag":173,"props":338,"children":339},{},[340],{"type":48,"value":341},"#    This CDN-based download works reliably for any artifact size.\n",{"type":42,"tag":173,"props":343,"children":345},{"class":175,"line":344},20,[346],{"type":42,"tag":173,"props":347,"children":349},{"emptyLinePlaceholder":348},true,[350],{"type":48,"value":351},"\n",{"type":42,"tag":173,"props":353,"children":355},{"class":175,"line":354},21,[356],{"type":42,"tag":173,"props":357,"children":358},{},[359],{"type":48,"value":360},"# Key files inside the artifact:\n",{"type":42,"tag":173,"props":362,"children":364},{"class":175,"line":363},22,[365],{"type":42,"tag":173,"props":366,"children":367},{},[368],{"type":48,"value":369},"# - binskim\u002F001\u002Fbinskim.sarif    \u003C- Raw BinSkim output (everything found)\n",{"type":42,"tag":173,"props":371,"children":373},{"class":175,"line":372},23,[374],{"type":42,"tag":173,"props":375,"children":376},{},[377],{"type":48,"value":378},"# - Results.sarif                 \u003C- Guardian-merged output (portal sees this)\n",{"type":42,"tag":173,"props":380,"children":382},{"class":175,"line":381},24,[383],{"type":42,"tag":173,"props":384,"children":385},{},[386],{"type":48,"value":387},"# - break\u002F001\u002Foptions.json        \u003C- Break policy (which tools can fail the build)\n",{"type":42,"tag":173,"props":389,"children":391},{"class":175,"line":390},25,[392],{"type":42,"tag":173,"props":393,"children":394},{},[395],{"type":48,"value":396},"# - .gdnbaselines                 \u003C- Auto-generated baseline suppressions\n",{"type":42,"tag":398,"props":399,"children":401},"h3",{"id":400},"downloading-via-mcp-when-the-agent-host-suppresses-binary-tool-output",[402],{"type":48,"value":403},"Downloading via MCP when the agent host suppresses binary tool output",{"type":42,"tag":51,"props":405,"children":406},{},[407,409,415,417,423,425,430],{"type":48,"value":408},"Some agent CLI hosts run the MCP ",{"type":42,"tag":130,"props":410,"children":412},{"className":411},[],[413],{"type":48,"value":414},"pipelines_artifact",{"type":48,"value":416}," ",{"type":42,"tag":130,"props":418,"children":420},{"className":419},[],[421],{"type":48,"value":422},"download",{"type":48,"value":424}," action successfully but ",{"type":42,"tag":66,"props":426,"children":427},{},[428],{"type":48,"value":429},"silently drop the embedded-resource zip",{"type":48,"value":431}," (you see \"Tool ran without output or errors\" and no file lands anywhere). When that happens, call the MCP HTTP endpoint directly from PowerShell and decode the base64 blob yourself:",{"type":42,"tag":433,"props":434,"children":435},"ol",{},[436,487,587,639],{"type":42,"tag":85,"props":437,"children":438},{},[439,441,447,449,455,457,463,465,471,473],{"type":48,"value":440},"Find the MCP servers config (the file path is in env, but typically): ",{"type":42,"tag":130,"props":442,"children":444},{"className":443},[],[445],{"type":48,"value":446},"Get-ChildItem $env:TEMP -Filter \"copilot-mcp-*.json\" | Sort LastWriteTime -Descending | Select -First 1 | Get-Content -Raw",{"type":48,"value":448}," — locate the ",{"type":42,"tag":130,"props":450,"children":452},{"className":451},[],[453],{"type":48,"value":454},"ado-dnceng",{"type":48,"value":456}," (or ",{"type":42,"tag":130,"props":458,"children":460},{"className":459},[],[461],{"type":48,"value":462},"ado-dnceng-public",{"type":48,"value":464},") entry's ",{"type":42,"tag":130,"props":466,"children":468},{"className":467},[],[469],{"type":48,"value":470},"url",{"type":48,"value":472}," and capture it in a variable (the port is assigned per session, so it changes every time):\n",{"type":42,"tag":122,"props":474,"children":476},{"className":165,"code":475,"language":167,"meta":127,"style":127},"$mcpUrl = (Get-Content (Get-ChildItem $env:TEMP -Filter 'copilot-mcp-*.json' | Sort LastWriteTime -Descending | Select -First 1) -Raw | ConvertFrom-Json).mcpServers.'ado-dnceng'.url\n",[477],{"type":42,"tag":130,"props":478,"children":479},{"__ignoreMap":127},[480],{"type":42,"tag":173,"props":481,"children":482},{"class":175,"line":176},[483],{"type":42,"tag":173,"props":484,"children":485},{},[486],{"type":48,"value":475},{"type":42,"tag":85,"props":488,"children":489},{},[490,492,498,500,506,508],{"type":48,"value":491},"POST a ",{"type":42,"tag":130,"props":493,"children":495},{"className":494},[],[496],{"type":48,"value":497},"tools\u002Fcall",{"type":48,"value":499}," JSON-RPC request (uses ",{"type":42,"tag":130,"props":501,"children":503},{"className":502},[],[504],{"type":48,"value":505},"$mcpUrl",{"type":48,"value":507}," from step 1 — do not hardcode the port):\n",{"type":42,"tag":122,"props":509,"children":511},{"className":165,"code":510,"language":167,"meta":127,"style":127},"$req = @{ jsonrpc='2.0'; id=2; method='tools\u002Fcall'; params=@{\n  name='pipelines_artifact'\n  arguments=@{ action='download'; buildId=\u003Cid>; project='internal'; artifactName='\u003Cname>' }\n} } | ConvertTo-Json -Compress -Depth 10\n$msg = [System.Net.Http.HttpRequestMessage]::new('POST',$mcpUrl)\n$msg.Headers.Accept.ParseAdd('application\u002Fjson, text\u002Fevent-stream')\n$msg.Content = [System.Net.Http.StringContent]::new($req,[Text.Encoding]::UTF8,'application\u002Fjson')\n$client = [System.Net.Http.HttpClient]::new(); $client.Timeout = [TimeSpan]::FromMinutes(15)\n$body = $client.SendAsync($msg).Result.Content.ReadAsStringAsync().Result\n",[512],{"type":42,"tag":130,"props":513,"children":514},{"__ignoreMap":127},[515,523,531,539,547,555,563,571,579],{"type":42,"tag":173,"props":516,"children":517},{"class":175,"line":176},[518],{"type":42,"tag":173,"props":519,"children":520},{},[521],{"type":48,"value":522},"$req = @{ jsonrpc='2.0'; id=2; method='tools\u002Fcall'; params=@{\n",{"type":42,"tag":173,"props":524,"children":525},{"class":175,"line":185},[526],{"type":42,"tag":173,"props":527,"children":528},{},[529],{"type":48,"value":530},"  name='pipelines_artifact'\n",{"type":42,"tag":173,"props":532,"children":533},{"class":175,"line":194},[534],{"type":42,"tag":173,"props":535,"children":536},{},[537],{"type":48,"value":538},"  arguments=@{ action='download'; buildId=\u003Cid>; project='internal'; artifactName='\u003Cname>' }\n",{"type":42,"tag":173,"props":540,"children":541},{"class":175,"line":203},[542],{"type":42,"tag":173,"props":543,"children":544},{},[545],{"type":48,"value":546},"} } | ConvertTo-Json -Compress -Depth 10\n",{"type":42,"tag":173,"props":548,"children":549},{"class":175,"line":212},[550],{"type":42,"tag":173,"props":551,"children":552},{},[553],{"type":48,"value":554},"$msg = [System.Net.Http.HttpRequestMessage]::new('POST',$mcpUrl)\n",{"type":42,"tag":173,"props":556,"children":557},{"class":175,"line":221},[558],{"type":42,"tag":173,"props":559,"children":560},{},[561],{"type":48,"value":562},"$msg.Headers.Accept.ParseAdd('application\u002Fjson, text\u002Fevent-stream')\n",{"type":42,"tag":173,"props":564,"children":565},{"class":175,"line":230},[566],{"type":42,"tag":173,"props":567,"children":568},{},[569],{"type":48,"value":570},"$msg.Content = [System.Net.Http.StringContent]::new($req,[Text.Encoding]::UTF8,'application\u002Fjson')\n",{"type":42,"tag":173,"props":572,"children":573},{"class":175,"line":239},[574],{"type":42,"tag":173,"props":575,"children":576},{},[577],{"type":48,"value":578},"$client = [System.Net.Http.HttpClient]::new(); $client.Timeout = [TimeSpan]::FromMinutes(15)\n",{"type":42,"tag":173,"props":580,"children":581},{"class":175,"line":248},[582],{"type":42,"tag":173,"props":583,"children":584},{},[585],{"type":48,"value":586},"$body = $client.SendAsync($msg).Result.Content.ReadAsStringAsync().Result\n",{"type":42,"tag":85,"props":588,"children":589},{},[590,592,597,599,605,607,613,615,621,623,629,631,637],{"type":48,"value":591},"Response is ",{"type":42,"tag":66,"props":593,"children":594},{},[595],{"type":48,"value":596},"Server-Sent Events",{"type":48,"value":598},": find the ",{"type":42,"tag":130,"props":600,"children":602},{"className":601},[],[603],{"type":48,"value":604},"data: ",{"type":48,"value":606}," line and ",{"type":42,"tag":130,"props":608,"children":610},{"className":609},[],[611],{"type":48,"value":612},"ConvertFrom-Json",{"type":48,"value":614},". The zip is at ",{"type":42,"tag":130,"props":616,"children":618},{"className":617},[],[619],{"type":48,"value":620},"result.content[0].resource.blob",{"type":48,"value":622}," (base64). Write with ",{"type":42,"tag":130,"props":624,"children":626},{"className":625},[],[627],{"type":48,"value":628},"[IO.File]::WriteAllBytes($path, [Convert]::FromBase64String($blob))",{"type":48,"value":630}," then ",{"type":42,"tag":130,"props":632,"children":634},{"className":633},[],[635],{"type":48,"value":636},"Expand-Archive",{"type":48,"value":638},".",{"type":42,"tag":85,"props":640,"children":641},{},[642,644,650],{"type":48,"value":643},"Reusable script template: see ",{"type":42,"tag":130,"props":645,"children":647},{"className":646},[],[648],{"type":48,"value":649},"C:\\temp\\Download-AdoArtifact.ps1",{"type":48,"value":651}," if previously generated, or recreate from the snippet above.",{"type":42,"tag":51,"props":653,"children":654},{},[655],{"type":48,"value":656},"Notes:",{"type":42,"tag":81,"props":658,"children":659},{},[660,680],{"type":42,"tag":85,"props":661,"children":662},{},[663,665,670,672,678],{"type":48,"value":664},"The MCP-served zip is dedup-compressed and is ",{"type":42,"tag":66,"props":666,"children":667},{},[668],{"type":48,"value":669},"much smaller",{"type":48,"value":671}," than the ",{"type":42,"tag":130,"props":673,"children":675},{"className":674},[],[676],{"type":48,"value":677},"artifactsize",{"type":48,"value":679}," reported by the artifact list call (an 86 MB \"artifactsize\" Windows_x64 SDL artifact downloads as a ~5–6 MB zip but contains the full 40+ MB raw and merged SARIF after extraction). Don't be alarmed by the size delta.",{"type":42,"tag":85,"props":681,"children":682},{},[683,689,691,697],{"type":42,"tag":130,"props":684,"children":686},{"className":685},[],[687],{"type":48,"value":688},"az login",{"type":48,"value":690}," \u002F ",{"type":42,"tag":130,"props":692,"children":694},{"className":693},[],[695],{"type":48,"value":696},"Connect-AzAccount",{"type":48,"value":698}," may hang indefinitely in non-interactive agent shells — don't rely on them. The MCP HTTP path above uses the MCP server's existing auth so no extra login is needed.",{"type":42,"tag":57,"props":700,"children":701},{},[702],{"type":42,"tag":51,"props":703,"children":704},{},[705,710,712,717,719,725,727,733],{"type":42,"tag":66,"props":706,"children":707},{},[708],{"type":48,"value":709},"Large SARIF files",{"type":48,"value":711},": For repos with many binaries (especially the VMR), raw and merged SARIF can be ",{"type":42,"tag":66,"props":713,"children":714},{},[715],{"type":48,"value":716},"50-80MB+",{"type":48,"value":718},". Use ",{"type":42,"tag":130,"props":720,"children":722},{"className":721},[],[723],{"type":48,"value":724},"Get-Content -Raw | ConvertFrom-Json",{"type":48,"value":726}," and stream results with ",{"type":42,"tag":130,"props":728,"children":730},{"className":729},[],[731],{"type":48,"value":732},"Group-Object",{"type":48,"value":638},{"type":42,"tag":57,"props":735,"children":736},{},[737],{"type":42,"tag":51,"props":738,"children":739},{},[740,745,747,753],{"type":42,"tag":66,"props":741,"children":742},{},[743],{"type":48,"value":744},"SDL does NOT run on PR validation builds.",{"type":48,"value":746}," It only runs on official\u002FCI pipelines (gated by ",{"type":42,"tag":130,"props":748,"children":750},{"className":749},[],[751],{"type":48,"value":752},"Build.Reason != PullRequest",{"type":48,"value":754},"). Users must manually queue the official pipeline for SDL results before merging.",{"type":42,"tag":51,"props":756,"children":757},{},[758,763,765,770],{"type":42,"tag":66,"props":759,"children":760},{},[761],{"type":48,"value":762},"Per-repo pipeline names",{"type":48,"value":764}," — see ",{"type":42,"tag":145,"props":766,"children":768},{"href":767},"references\u002Frepo-profiles-index.md",[769],{"type":48,"value":767},{"type":48,"value":771}," for the index of per-repo profile files (one per repo). Load only the file for the repo you're investigating.",{"type":42,"tag":74,"props":773,"children":775},{"id":774},"sdl-artifact-structure",[776],{"type":48,"value":777},"SDL Artifact Structure",{"type":42,"tag":51,"props":779,"children":780},{},[781],{"type":48,"value":782},"The SDL artifact contains a rich directory structure. Key files and what they tell you:",{"type":42,"tag":122,"props":784,"children":787},{"className":785,"code":786,"language":48,"meta":127},[125],"\u003CSDL artifact>\u002F\n  binskim\u002F\n    001\u002Fbinskim.sarif         # Raw BinSkim output for scan directory 1 (e.g., bin\u002F)\n    001\u002F.gdntoolinput         # Explicit file list — exactly what was scanned\n    002\u002Fbinskim.sarif         # Raw BinSkim output for scan directory 2 (e.g., symbols\u002F)\n    002\u002F.gdntoolinput         # Explicit file list for directory 2\n  prefast\u002F                    # Native C++ static analysis (separate from BinSkim)\n  roslynanalyzers\u002F            # Managed code analysis\n  break\u002F001\u002Foptions.json      # Break policy — which tools can fail the build\n  Results.sarif               # Guardian-merged & deduplicated (this goes to portal)\n  Results3.sarif              # Cumulative raw output from ALL tool phases\n  .gdnbaselines               # Baselined finding signatures (managed by Guardian portal)\n  .gdnsuppress                # Suppressed findings (same set, filtered from S360)\n",[788],{"type":42,"tag":130,"props":789,"children":790},{"__ignoreMap":127},[791],{"type":48,"value":786},{"type":42,"tag":51,"props":793,"children":794},{},[795,800],{"type":42,"tag":66,"props":796,"children":797},{},[798],{"type":48,"value":799},"Multiple phases",{"type":48,"value":801},": Most tools run in 4 phases (001-004); BinSkim typically has 2 (one per staging directory). Results3.sarif aggregates all phases — expect hundreds of \"runs\" (e.g., 417 = 310 roslynanalyzers + 100 prefast + 7 binskim). Results.sarif deduplicates these down (e.g., to 42 unique runs).",{"type":42,"tag":51,"props":803,"children":804},{},[805,816],{"type":42,"tag":66,"props":806,"children":807},{},[808,814],{"type":42,"tag":130,"props":809,"children":811},{"className":810},[],[812],{"type":48,"value":813},".gdntoolinput",{"type":48,"value":815}," is the source of truth",{"type":48,"value":817}," for what was actually scanned. It's an explicit file list (one quoted path per line), NOT a recursive glob. If a binary isn't in this file, BinSkim didn't see it.",{"type":42,"tag":51,"props":819,"children":820},{},[821,830,832,841],{"type":42,"tag":66,"props":822,"children":823},{},[824],{"type":42,"tag":130,"props":825,"children":827},{"className":826},[],[828],{"type":48,"value":829},".gdnbaselines",{"type":48,"value":831}," are NOT repo-committed — they're auto-generated pipeline artifacts used for break-on-new-only tracking. ",{"type":42,"tag":66,"props":833,"children":834},{},[835],{"type":42,"tag":130,"props":836,"children":838},{"className":837},[],[839],{"type":48,"value":840},".gdnsuppress",{"type":48,"value":842}," files CAN be checked into source to suppress specific findings, but this is rarely done in dotnet repos. Neither can weaken SDL policy — the tenant\u002Forg policy sets the floor.",{"type":42,"tag":74,"props":844,"children":846},{"id":845},"comparing-raw-vs-merged-sarif",[847],{"type":48,"value":848},"Comparing Raw vs Merged SARIF",{"type":42,"tag":51,"props":850,"children":851},{},[852],{"type":48,"value":853},"Always compare both files to understand what Guardian filtered:",{"type":42,"tag":122,"props":855,"children":857},{"className":165,"code":856,"language":167,"meta":127,"style":127},"$raw = (Get-Content \"binskim\\001\\binskim.sarif\" -Raw | ConvertFrom-Json).runs[0].results\n# IMPORTANT: Results.sarif contains multiple runs (BinSkim, roslynanalyzers, prefast, etc.)\n# Filter to the BinSkim run — don't assume runs[0] is BinSkim\n$mergedSarif = Get-Content \"Results.sarif\" -Raw | ConvertFrom-Json\n$binskimRun = $mergedSarif.runs | Where-Object { $_.tool.driver.name -like '*BinSkim*' } | Select-Object -First 1\n$merged = if ($binskimRun) { $binskimRun.results } else { $mergedSarif.runs[0].results }\n\nWrite-Host \"Raw BinSkim findings: $($raw.Count)\"\nWrite-Host \"After Guardian filtering: $($merged.Count)\"\nWrite-Host \"`nRaw findings by rule:\"\n$raw | Group-Object ruleId | ForEach-Object {\n    $levels = ($_.Group | ForEach-Object { $_.level } | Sort-Object -Unique) -join \",\"\n    Write-Host \"  $($_.Name): count=$($_.Count) levels=[$levels]\"\n}\n",[858],{"type":42,"tag":130,"props":859,"children":860},{"__ignoreMap":127},[861,869,877,885,893,901,909,916,924,932,940,948,956,964],{"type":42,"tag":173,"props":862,"children":863},{"class":175,"line":176},[864],{"type":42,"tag":173,"props":865,"children":866},{},[867],{"type":48,"value":868},"$raw = (Get-Content \"binskim\\001\\binskim.sarif\" -Raw | ConvertFrom-Json).runs[0].results\n",{"type":42,"tag":173,"props":870,"children":871},{"class":175,"line":185},[872],{"type":42,"tag":173,"props":873,"children":874},{},[875],{"type":48,"value":876},"# IMPORTANT: Results.sarif contains multiple runs (BinSkim, roslynanalyzers, prefast, etc.)\n",{"type":42,"tag":173,"props":878,"children":879},{"class":175,"line":194},[880],{"type":42,"tag":173,"props":881,"children":882},{},[883],{"type":48,"value":884},"# Filter to the BinSkim run — don't assume runs[0] is BinSkim\n",{"type":42,"tag":173,"props":886,"children":887},{"class":175,"line":203},[888],{"type":42,"tag":173,"props":889,"children":890},{},[891],{"type":48,"value":892},"$mergedSarif = Get-Content \"Results.sarif\" -Raw | ConvertFrom-Json\n",{"type":42,"tag":173,"props":894,"children":895},{"class":175,"line":212},[896],{"type":42,"tag":173,"props":897,"children":898},{},[899],{"type":48,"value":900},"$binskimRun = $mergedSarif.runs | Where-Object { $_.tool.driver.name -like '*BinSkim*' } | Select-Object -First 1\n",{"type":42,"tag":173,"props":902,"children":903},{"class":175,"line":221},[904],{"type":42,"tag":173,"props":905,"children":906},{},[907],{"type":48,"value":908},"$merged = if ($binskimRun) { $binskimRun.results } else { $mergedSarif.runs[0].results }\n",{"type":42,"tag":173,"props":910,"children":911},{"class":175,"line":230},[912],{"type":42,"tag":173,"props":913,"children":914},{"emptyLinePlaceholder":348},[915],{"type":48,"value":351},{"type":42,"tag":173,"props":917,"children":918},{"class":175,"line":239},[919],{"type":42,"tag":173,"props":920,"children":921},{},[922],{"type":48,"value":923},"Write-Host \"Raw BinSkim findings: $($raw.Count)\"\n",{"type":42,"tag":173,"props":925,"children":926},{"class":175,"line":248},[927],{"type":42,"tag":173,"props":928,"children":929},{},[930],{"type":48,"value":931},"Write-Host \"After Guardian filtering: $($merged.Count)\"\n",{"type":42,"tag":173,"props":933,"children":934},{"class":175,"line":257},[935],{"type":42,"tag":173,"props":936,"children":937},{},[938],{"type":48,"value":939},"Write-Host \"`nRaw findings by rule:\"\n",{"type":42,"tag":173,"props":941,"children":942},{"class":175,"line":266},[943],{"type":42,"tag":173,"props":944,"children":945},{},[946],{"type":48,"value":947},"$raw | Group-Object ruleId | ForEach-Object {\n",{"type":42,"tag":173,"props":949,"children":950},{"class":175,"line":25},[951],{"type":42,"tag":173,"props":952,"children":953},{},[954],{"type":48,"value":955},"    $levels = ($_.Group | ForEach-Object { $_.level } | Sort-Object -Unique) -join \",\"\n",{"type":42,"tag":173,"props":957,"children":958},{"class":175,"line":282},[959],{"type":42,"tag":173,"props":960,"children":961},{},[962],{"type":48,"value":963},"    Write-Host \"  $($_.Name): count=$($_.Count) levels=[$levels]\"\n",{"type":42,"tag":173,"props":965,"children":966},{"class":175,"line":291},[967],{"type":42,"tag":173,"props":968,"children":969},{},[970],{"type":48,"value":971},"}\n",{"type":42,"tag":51,"props":973,"children":974},{},[975,977,981],{"type":48,"value":976},"The delta between raw and merged is what Guardian filtered out based on SDL policy. See ",{"type":42,"tag":145,"props":978,"children":979},{"href":147},[980],{"type":48,"value":147},{"type":48,"value":982}," for why things get filtered and the suppression mechanisms available.",{"type":42,"tag":74,"props":984,"children":986},{"id":985},"service-tree-and-org-awareness",[987],{"type":48,"value":988},"Service Tree and Org Awareness",{"type":42,"tag":51,"props":990,"children":991},{},[992,994,1000,1002,1008,1010,1016,1018,1024,1026,1032,1034,1039,1041,1046],{"type":48,"value":993},"Which rules the portal reports depends on ",{"type":42,"tag":130,"props":995,"children":997},{"className":996},[],[998],{"type":48,"value":999},"es-metadata.yml",{"type":48,"value":1001}," — the ",{"type":42,"tag":130,"props":1003,"children":1005},{"className":1004},[],[1006],{"type":48,"value":1007},"routing.defaultAreaPath.org",{"type":48,"value":1009}," field determines your SDL policy scope. Different orgs surface different rules. For example, the ",{"type":42,"tag":130,"props":1011,"children":1013},{"className":1012},[],[1014],{"type":48,"value":1015},"devdiv",{"type":48,"value":1017}," org (most ",{"type":42,"tag":130,"props":1019,"children":1021},{"className":1020},[],[1022],{"type":48,"value":1023},"dotnet\u002F*",{"type":48,"value":1025}," repos) treats BA2008\u002FBA2009\u002FBA2021 as SDL-required (10203-mapped), while the ",{"type":42,"tag":130,"props":1027,"children":1029},{"className":1028},[],[1030],{"type":48,"value":1031},"nettel",{"type":48,"value":1033}," org surfaces BA2004\u002FBA2027 as informational findings in the portal. ",{"type":42,"tag":66,"props":1035,"children":1036},{},[1037],{"type":48,"value":1038},"Neither BA2004 nor BA2027 is SDL-required at the company level",{"type":48,"value":1040}," (no 10203 mapping) — but informational portal findings still often get triaged like requirements, so they are worth fixing. See ",{"type":42,"tag":145,"props":1042,"children":1044},{"href":1043},"references\u002Frepo-perfview.md",[1045],{"type":48,"value":1043},{"type":48,"value":1047}," for a worked example.",{"type":42,"tag":51,"props":1049,"children":1050},{},[1051,1053,1058],{"type":48,"value":1052},"See ",{"type":42,"tag":145,"props":1054,"children":1056},{"href":1055},"references\u002Fbinskim-rules.md",[1057],{"type":48,"value":1055},{"type":48,"value":1059}," for the full rules tables and the observed portal requirements by org.",{"type":42,"tag":74,"props":1061,"children":1063},{"id":1062},"coverage-gap-detection",[1064],{"type":48,"value":1065},"Coverage Gap Detection",{"type":42,"tag":51,"props":1067,"children":1068},{},[1069],{"type":48,"value":1070},"After examining results, check whether the scan covers everything the repo ships:",{"type":42,"tag":433,"props":1072,"children":1073},{},[1074,1084,1101],{"type":42,"tag":85,"props":1075,"children":1076},{},[1077,1082],{"type":42,"tag":66,"props":1078,"children":1079},{},[1080],{"type":48,"value":1081},"List all published artifacts",{"type":48,"value":1083}," from the pipeline YAML",{"type":42,"tag":85,"props":1085,"children":1086},{},[1087,1099],{"type":42,"tag":66,"props":1088,"children":1089},{},[1090,1092,1097],{"type":48,"value":1091},"Compare with ",{"type":42,"tag":130,"props":1093,"children":1095},{"className":1094},[],[1096],{"type":48,"value":813},{"type":48,"value":1098}," file lists",{"type":48,"value":1100}," in the SDL artifact — these are the explicit files Guardian scanned. Not a recursive directory walk.",{"type":42,"tag":85,"props":1102,"children":1103},{},[1104,1109,1111,1116],{"type":42,"tag":66,"props":1105,"children":1106},{},[1107],{"type":48,"value":1108},"Report gaps",{"type":48,"value":1110},": \"This repo ships X.dll (native C++ binary) but it's not in the ",{"type":42,"tag":130,"props":1112,"children":1114},{"className":1113},[],[1115],{"type":48,"value":813},{"type":48,"value":1117}," scan targets — likely because it isn't staged to the bin\u002F or symbols\u002F directories that Guardian scans.\"",{"type":42,"tag":51,"props":1119,"children":1120},{},[1121,1126,1128,1134,1136,1142,1144,1150,1152,1157],{"type":42,"tag":66,"props":1122,"children":1123},{},[1124],{"type":48,"value":1125},"Common gap — unstaged binaries",{"type":48,"value":1127},": Native C++ binaries built by ",{"type":42,"tag":130,"props":1129,"children":1131},{"className":1130},[],[1132],{"type":48,"value":1133},".vcxproj",{"type":48,"value":1135}," often output to project-local ",{"type":42,"tag":130,"props":1137,"children":1139},{"className":1138},[],[1140],{"type":48,"value":1141},"Release\\",{"type":48,"value":1143}," directories, not the main ",{"type":42,"tag":130,"props":1145,"children":1147},{"className":1146},[],[1148],{"type":48,"value":1149},"artifacts\\bin\\",{"type":48,"value":1151}," staging area. Guardian generates ",{"type":42,"tag":130,"props":1153,"children":1155},{"className":1154},[],[1156],{"type":48,"value":813},{"type":48,"value":1158}," from the staging directories, so these binaries get Prefast coverage (source analysis) but miss BinSkim (binary analysis). This is a pipeline artifact staging config issue.",{"type":42,"tag":51,"props":1160,"children":1161},{},[1162,1167,1169,1175,1177,1183,1185,1191,1193,1198,1200,1205,1207,1213,1214,1220,1222,1228,1230,1236,1238,1244],{"type":42,"tag":66,"props":1163,"children":1164},{},[1165],{"type":48,"value":1166},"Common gap — missing OS coverage",{"type":48,"value":1168},": Each OS build configuration produces different native binaries (e.g., Linux ",{"type":42,"tag":130,"props":1170,"children":1172},{"className":1171},[],[1173],{"type":48,"value":1174},".so",{"type":48,"value":1176},", macOS ",{"type":42,"tag":130,"props":1178,"children":1180},{"className":1179},[],[1181],{"type":48,"value":1182},".dylib",{"type":48,"value":1184},", Windows ",{"type":42,"tag":130,"props":1186,"children":1188},{"className":1187},[],[1189],{"type":48,"value":1190},".dll",{"type":48,"value":1192},"). If the official pipeline only runs BinSkim on Windows SDL legs, Linux and macOS native binaries are not scanned at all. ",{"type":42,"tag":66,"props":1194,"children":1195},{},[1196],{"type":48,"value":1197},"Flag this clearly as a coverage gap that needs fixing.",{"type":48,"value":1199}," Note: this gap is typically caused by the 1ES\u002FGuardian SDL template using Windows-centric glob patterns (matching ",{"type":42,"tag":130,"props":1201,"children":1203},{"className":1202},[],[1204],{"type":48,"value":1190},{"type":48,"value":1206},"\u002F",{"type":42,"tag":130,"props":1208,"children":1210},{"className":1209},[],[1211],{"type":48,"value":1212},".exe",{"type":48,"value":1206},{"type":42,"tag":130,"props":1215,"children":1217},{"className":1216},[],[1218],{"type":48,"value":1219},".sys",{"type":48,"value":1221},") rather than a BinSkim limitation — BinSkim can scan PE, ELF, and Mach-O binaries on any OS using magic-byte detection. To close the gap, either configure broader glob patterns in the existing SDL legs, or add BinSkim scanning steps that target non-Windows artifacts with appropriate patterns (",{"type":42,"tag":130,"props":1223,"children":1225},{"className":1224},[],[1226],{"type":48,"value":1227},"*.dylib",{"type":48,"value":1229},", ",{"type":42,"tag":130,"props":1231,"children":1233},{"className":1232},[],[1234],{"type":48,"value":1235},"*.so",{"type":48,"value":1237},", or ",{"type":42,"tag":130,"props":1239,"children":1241},{"className":1240},[],[1242],{"type":48,"value":1243},"**",{"type":48,"value":1245},").",{"type":42,"tag":74,"props":1247,"children":1249},{"id":1248},"classification-framework",[1250],{"type":48,"value":1251},"Classification Framework",{"type":42,"tag":51,"props":1253,"children":1254},{},[1255],{"type":48,"value":1256},"When analyzing findings, classify each into one of four buckets to determine the right action:",{"type":42,"tag":1258,"props":1259,"children":1260},"table",{},[1261,1285],{"type":42,"tag":1262,"props":1263,"children":1264},"thead",{},[1265],{"type":42,"tag":1266,"props":1267,"children":1268},"tr",{},[1269,1275,1280],{"type":42,"tag":1270,"props":1271,"children":1272},"th",{},[1273],{"type":48,"value":1274},"Bucket",{"type":42,"tag":1270,"props":1276,"children":1277},{},[1278],{"type":48,"value":1279},"Description",{"type":42,"tag":1270,"props":1281,"children":1282},{},[1283],{"type":48,"value":1284},"Action",{"type":42,"tag":1286,"props":1287,"children":1288},"tbody",{},[1289,1311,1332,1353],{"type":42,"tag":1266,"props":1290,"children":1291},{},[1292,1301,1306],{"type":42,"tag":1293,"props":1294,"children":1295},"td",{},[1296],{"type":42,"tag":66,"props":1297,"children":1298},{},[1299],{"type":48,"value":1300},"First-party shipped",{"type":42,"tag":1293,"props":1302,"children":1303},{},[1304],{"type":48,"value":1305},"Binary built from repo source, included in shipping packages",{"type":42,"tag":1293,"props":1307,"children":1308},{},[1309],{"type":48,"value":1310},"Fix in repo — highest priority",{"type":42,"tag":1266,"props":1312,"children":1313},{},[1314,1322,1327],{"type":42,"tag":1293,"props":1315,"children":1316},{},[1317],{"type":42,"tag":66,"props":1318,"children":1319},{},[1320],{"type":48,"value":1321},"Foreign shipped",{"type":42,"tag":1293,"props":1323,"children":1324},{},[1325],{"type":48,"value":1326},"Third-party binary (from NuGet\u002Fvendored), included in shipping packages",{"type":42,"tag":1293,"props":1328,"children":1329},{},[1330],{"type":48,"value":1331},"File upstream issue, update package, or request SDL exception",{"type":42,"tag":1266,"props":1333,"children":1334},{},[1335,1343,1348],{"type":42,"tag":1293,"props":1336,"children":1337},{},[1338],{"type":42,"tag":66,"props":1339,"children":1340},{},[1341],{"type":48,"value":1342},"First-party non-shipped",{"type":42,"tag":1293,"props":1344,"children":1345},{},[1346],{"type":48,"value":1347},"Binary built from repo source, in test\u002FNonShipping only",{"type":42,"tag":1293,"props":1349,"children":1350},{},[1351],{"type":48,"value":1352},"Fix for hygiene (low priority), or exclude from scan scope",{"type":42,"tag":1266,"props":1354,"children":1355},{},[1356,1364,1369],{"type":42,"tag":1293,"props":1357,"children":1358},{},[1359],{"type":42,"tag":66,"props":1360,"children":1361},{},[1362],{"type":48,"value":1363},"Foreign non-shipped",{"type":42,"tag":1293,"props":1365,"children":1366},{},[1367],{"type":48,"value":1368},"Third-party binary, in test\u002FNonShipping only",{"type":42,"tag":1293,"props":1370,"children":1371},{},[1372],{"type":48,"value":1373},"Suppress — should not appear in official scans if artifact staging is correct",{"type":42,"tag":51,"props":1375,"children":1376},{},[1377,1379,1385,1387,1393,1395,1400,1401,1407],{"type":48,"value":1378},"To classify: check the SARIF artifact path for ",{"type":42,"tag":130,"props":1380,"children":1382},{"className":1381},[],[1383],{"type":48,"value":1384},"Shipping",{"type":48,"value":1386}," vs ",{"type":42,"tag":130,"props":1388,"children":1390},{"className":1389},[],[1391],{"type":48,"value":1392},"NonShipping",{"type":48,"value":1394},", and search the repo for the binary's source project (",{"type":42,"tag":130,"props":1396,"children":1398},{"className":1397},[],[1399],{"type":48,"value":1133},{"type":48,"value":1206},{"type":42,"tag":130,"props":1402,"children":1404},{"className":1403},[],[1405],{"type":48,"value":1406},".csproj",{"type":48,"value":1408},") vs NuGet package origin.",{"type":42,"tag":74,"props":1410,"children":1412},{"id":1411},"fix-ownership",[1413],{"type":48,"value":1414},"Fix Ownership",{"type":42,"tag":51,"props":1416,"children":1417},{},[1418],{"type":48,"value":1419},"Not all findings can be fixed in the repo where they're reported:",{"type":42,"tag":1258,"props":1421,"children":1422},{},[1423,1444],{"type":42,"tag":1262,"props":1424,"children":1425},{},[1426],{"type":42,"tag":1266,"props":1427,"children":1428},{},[1429,1434,1439],{"type":42,"tag":1270,"props":1430,"children":1431},{},[1432],{"type":48,"value":1433},"Binary origin",{"type":42,"tag":1270,"props":1435,"children":1436},{},[1437],{"type":48,"value":1438},"Example",{"type":42,"tag":1270,"props":1440,"children":1441},{},[1442],{"type":48,"value":1443},"Fix approach",{"type":42,"tag":1286,"props":1445,"children":1446},{},[1447,1485,1506,1527],{"type":42,"tag":1266,"props":1448,"children":1449},{},[1450,1467,1472],{"type":42,"tag":1293,"props":1451,"children":1452},{},[1453,1458,1460,1465],{"type":42,"tag":66,"props":1454,"children":1455},{},[1456],{"type":48,"value":1457},"C++ source in repo",{"type":48,"value":1459}," (",{"type":42,"tag":130,"props":1461,"children":1463},{"className":1462},[],[1464],{"type":48,"value":1133},{"type":48,"value":1466},")",{"type":42,"tag":1293,"props":1468,"children":1469},{},[1470],{"type":48,"value":1471},"EtwClrProfiler.dll",{"type":42,"tag":1293,"props":1473,"children":1474},{},[1475,1477,1483],{"type":48,"value":1476},"Add compiler\u002Flinker flags (e.g., ",{"type":42,"tag":130,"props":1478,"children":1480},{"className":1479},[],[1481],{"type":48,"value":1482},"\u002Fguard:cf",{"type":48,"value":1484}," for BA2008)",{"type":42,"tag":1266,"props":1486,"children":1487},{},[1488,1496,1501],{"type":42,"tag":1293,"props":1489,"children":1490},{},[1491],{"type":42,"tag":66,"props":1492,"children":1493},{},[1494],{"type":48,"value":1495},"Pre-built native from NuGet",{"type":42,"tag":1293,"props":1497,"children":1498},{},[1499],{"type":48,"value":1500},"Intel MKL\u002FTBB, WiX winterop.dll",{"type":42,"tag":1293,"props":1502,"children":1503},{},[1504],{"type":48,"value":1505},"Cannot fix here — update package, file upstream issue, or suppress",{"type":42,"tag":1266,"props":1507,"children":1508},{},[1509,1517,1522],{"type":42,"tag":1293,"props":1510,"children":1511},{},[1512],{"type":42,"tag":66,"props":1513,"children":1514},{},[1515],{"type":48,"value":1516},"Test framework binaries",{"type":42,"tag":1293,"props":1518,"children":1519},{},[1520],{"type":48,"value":1521},"xunit.*.dll",{"type":42,"tag":1293,"props":1523,"children":1524},{},[1525],{"type":48,"value":1526},"Fix scan scope — exclude from shipped artifacts",{"type":42,"tag":1266,"props":1528,"children":1529},{},[1530,1538,1555],{"type":42,"tag":1293,"props":1531,"children":1532},{},[1533],{"type":42,"tag":66,"props":1534,"children":1535},{},[1536],{"type":48,"value":1537},"Managed C# assembly",{"type":42,"tag":1293,"props":1539,"children":1540},{},[1541,1543,1548,1550],{"type":48,"value":1542},"Most ",{"type":42,"tag":130,"props":1544,"children":1546},{"className":1545},[],[1547],{"type":48,"value":1190},{"type":48,"value":1549}," from ",{"type":42,"tag":130,"props":1551,"children":1553},{"className":1552},[],[1554],{"type":48,"value":1406},{"type":42,"tag":1293,"props":1556,"children":1557},{},[1558],{"type":48,"value":1559},"BA2008 not applicable (BinSkim skips IL-only). BA2004\u002FBA2027 may apply",{"type":42,"tag":51,"props":1561,"children":1562},{},[1563,1568,1570,1576,1578,1584],{"type":42,"tag":66,"props":1564,"children":1565},{},[1566],{"type":48,"value":1567},"VMR (dotnet\u002Fdotnet)",{"type":48,"value":1569},": Findings map to source sub-repos. Look at the artifact path in the SARIF (e.g., ",{"type":42,"tag":130,"props":1571,"children":1573},{"className":1572},[],[1574],{"type":48,"value":1575},"src\u002Farcade\u002Fartifacts\u002F...",{"type":48,"value":1577}," means fix goes to ",{"type":42,"tag":130,"props":1579,"children":1581},{"className":1580},[],[1582],{"type":48,"value":1583},"dotnet\u002Farcade",{"type":48,"value":1245},{"type":42,"tag":398,"props":1586,"children":1588},{"id":1587},"common-misconception",[1589],{"type":48,"value":1590},"Common misconception",{"type":42,"tag":51,"props":1592,"children":1593},{},[1594,1600,1602,1607,1609,1614,1616,1621,1623,1628],{"type":42,"tag":130,"props":1595,"children":1597},{"className":1596},[],[1598],{"type":48,"value":1599},"\u003CControlFlowGuard>Guard\u003C\u002FControlFlowGuard>",{"type":48,"value":1601}," in a ",{"type":42,"tag":130,"props":1603,"children":1605},{"className":1604},[],[1606],{"type":48,"value":1406},{"type":48,"value":1608}," does ",{"type":42,"tag":66,"props":1610,"children":1611},{},[1612],{"type":48,"value":1613},"nothing",{"type":48,"value":1615},". The C# compiler has no ",{"type":42,"tag":130,"props":1617,"children":1619},{"className":1618},[],[1620],{"type":48,"value":1482},{"type":48,"value":1622}," support. This MSBuild property only works in ",{"type":42,"tag":130,"props":1624,"children":1626},{"className":1625},[],[1627],{"type":48,"value":1133},{"type":48,"value":1629}," (MSVC C++). BA2008 only fires on native PE binaries.",{"type":42,"tag":74,"props":1631,"children":1633},{"id":1632},"non-arcade-repos",[1634],{"type":48,"value":1635},"Non-Arcade Repos",{"type":42,"tag":51,"props":1637,"children":1638},{},[1639],{"type":48,"value":1640},"Some repos (e.g., microsoft\u002Fperfview) don't use arcade infrastructure:",{"type":42,"tag":81,"props":1642,"children":1643},{},[1644,1657,1676,1697],{"type":42,"tag":85,"props":1645,"children":1646},{},[1647,1649,1655],{"type":48,"value":1648},"No ",{"type":42,"tag":130,"props":1650,"children":1652},{"className":1651},[],[1653],{"type":48,"value":1654},"eng\u002Fcommon\u002Fsdl\u002F",{"type":48,"value":1656}," — BinSkim config is in the 1ES template or pipeline YAML directly",{"type":42,"tag":85,"props":1658,"children":1659},{},[1660,1662,1668,1670],{"type":48,"value":1661},"Build output may be in ",{"type":42,"tag":130,"props":1663,"children":1665},{"className":1664},[],[1666],{"type":48,"value":1667},"src\\bin\\",{"type":48,"value":1669}," instead of ",{"type":42,"tag":130,"props":1671,"children":1673},{"className":1672},[],[1674],{"type":48,"value":1675},"artifacts\\",{"type":42,"tag":85,"props":1677,"children":1678},{},[1679,1681,1687,1689,1695],{"type":48,"value":1680},"Look for ",{"type":42,"tag":130,"props":1682,"children":1684},{"className":1683},[],[1685],{"type":48,"value":1686},".ado.yml",{"type":48,"value":1688}," or ",{"type":42,"tag":130,"props":1690,"children":1692},{"className":1691},[],[1693],{"type":48,"value":1694},".pipelines\u002F",{"type":48,"value":1696}," for pipeline config",{"type":42,"tag":85,"props":1698,"children":1699},{},[1700],{"type":48,"value":1701},"The general analysis approach still works — find the SDL artifact, compare raw vs merged SARIF",{"type":42,"tag":74,"props":1703,"children":1705},{"id":1704},"anti-patterns",[1706],{"type":48,"value":1707},"Anti-Patterns",{"type":42,"tag":57,"props":1709,"children":1710},{},[1711],{"type":42,"tag":51,"props":1712,"children":1713},{},[1714,1719,1721,1727,1729,1735],{"type":42,"tag":66,"props":1715,"children":1716},{},[1717],{"type":48,"value":1718},"Don't trust the central portal as the complete picture.",{"type":48,"value":1720}," Download the raw ",{"type":42,"tag":130,"props":1722,"children":1724},{"className":1723},[],[1725],{"type":48,"value":1726},"binskim.sarif",{"type":48,"value":1728}," and compare with ",{"type":42,"tag":130,"props":1730,"children":1732},{"className":1731},[],[1733],{"type":48,"value":1734},"Results.sarif",{"type":48,"value":1736},". The portal shows only findings for rules with SDL policy mappings.",{"type":42,"tag":57,"props":1738,"children":1739},{},[1740],{"type":42,"tag":51,"props":1741,"children":1742},{},[1743,1748],{"type":42,"tag":66,"props":1744,"children":1745},{},[1746],{"type":48,"value":1747},"Don't assume \"not in the portal\" means \"not a problem.\"",{"type":48,"value":1749}," Guardian filtering removes findings without SDL policy mappings for your org. These may still be good security practice.",{"type":42,"tag":57,"props":1751,"children":1752},{},[1753],{"type":42,"tag":51,"props":1754,"children":1755},{},[1756,1761],{"type":42,"tag":66,"props":1757,"children":1758},{},[1759],{"type":48,"value":1760},"Don't confuse break policy with reporting.",{"type":48,"value":1762}," Break policy controls whether BinSkim fails the build. It does NOT control what gets reported to the portal. Findings can be reported without breaking the build.",{"type":42,"tag":57,"props":1764,"children":1765},{},[1766],{"type":42,"tag":51,"props":1767,"children":1768},{},[1769,1774,1776,1781,1782,1787],{"type":42,"tag":66,"props":1770,"children":1771},{},[1772],{"type":48,"value":1773},"Don't assume Windows-only scanning is sufficient.",{"type":48,"value":1775}," If the repo ships native binaries for Linux or macOS (",{"type":42,"tag":130,"props":1777,"children":1779},{"className":1778},[],[1780],{"type":48,"value":1174},{"type":48,"value":1229},{"type":42,"tag":130,"props":1783,"children":1785},{"className":1784},[],[1786],{"type":48,"value":1182},{"type":48,"value":1788},"), those binaries may have different BinSkim findings than their Windows counterparts. If official SDL legs only cover Windows, flag this as a gap — the pipeline should be updated to run BinSkim on all OS configurations that produce shipped native artifacts.",{"type":42,"tag":74,"props":1790,"children":1792},{"id":1791},"comparing-local-scan-vs-official-run",[1793],{"type":48,"value":1794},"Comparing Local Scan vs Official Run",{"type":42,"tag":51,"props":1796,"children":1797},{},[1798,1800,1804],{"type":48,"value":1799},"When the user has run the ",{"type":42,"tag":66,"props":1801,"children":1802},{},[1803],{"type":48,"value":70},{"type":48,"value":1805}," skill locally and wants to validate against official results:",{"type":42,"tag":1258,"props":1807,"children":1808},{},[1809,1830],{"type":42,"tag":1262,"props":1810,"children":1811},{},[1812],{"type":42,"tag":1266,"props":1813,"children":1814},{},[1815,1820,1825],{"type":42,"tag":1270,"props":1816,"children":1817},{},[1818],{"type":48,"value":1819},"Aspect",{"type":42,"tag":1270,"props":1821,"children":1822},{},[1823],{"type":48,"value":1824},"Official run",{"type":42,"tag":1270,"props":1826,"children":1827},{},[1828],{"type":48,"value":1829},"Local scan",{"type":42,"tag":1286,"props":1831,"children":1832},{},[1833,1875,1896,1917,1938,1959],{"type":42,"tag":1266,"props":1834,"children":1835},{},[1836,1844,1856],{"type":42,"tag":1293,"props":1837,"children":1838},{},[1839],{"type":42,"tag":66,"props":1840,"children":1841},{},[1842],{"type":48,"value":1843},"Scope",{"type":42,"tag":1293,"props":1845,"children":1846},{},[1847,1849,1854],{"type":48,"value":1848},"Only staged artifacts (explicit ",{"type":42,"tag":130,"props":1850,"children":1852},{"className":1851},[],[1853],{"type":48,"value":813},{"type":48,"value":1855}," list)",{"type":42,"tag":1293,"props":1857,"children":1858},{},[1859,1861,1867,1868,1874],{"type":48,"value":1860},"Everything under build output (",{"type":42,"tag":130,"props":1862,"children":1864},{"className":1863},[],[1865],{"type":48,"value":1866},"src\\**",{"type":48,"value":1688},{"type":42,"tag":130,"props":1869,"children":1871},{"className":1870},[],[1872],{"type":48,"value":1873},"artifacts\\**",{"type":48,"value":1466},{"type":42,"tag":1266,"props":1876,"children":1877},{},[1878,1886,1891],{"type":42,"tag":1293,"props":1879,"children":1880},{},[1881],{"type":42,"tag":66,"props":1882,"children":1883},{},[1884],{"type":48,"value":1885},"Test\u002Fbenchmark binaries",{"type":42,"tag":1293,"props":1887,"children":1888},{},[1889],{"type":48,"value":1890},"Excluded from staging",{"type":42,"tag":1293,"props":1892,"children":1893},{},[1894],{"type":48,"value":1895},"Included (flagged in summary)",{"type":42,"tag":1266,"props":1897,"children":1898},{},[1899,1907,1912],{"type":42,"tag":1293,"props":1900,"children":1901},{},[1902],{"type":42,"tag":66,"props":1903,"children":1904},{},[1905],{"type":48,"value":1906},"NuGet package binaries",{"type":42,"tag":1293,"props":1908,"children":1909},{},[1910],{"type":48,"value":1911},"Excluded unless staged",{"type":42,"tag":1293,"props":1913,"children":1914},{},[1915],{"type":48,"value":1916},"Included if in build output",{"type":42,"tag":1266,"props":1918,"children":1919},{},[1920,1928,1933],{"type":42,"tag":1293,"props":1921,"children":1922},{},[1923],{"type":42,"tag":66,"props":1924,"children":1925},{},[1926],{"type":48,"value":1927},"Native C++ binaries",{"type":42,"tag":1293,"props":1929,"children":1930},{},[1931],{"type":48,"value":1932},"Only if staged to bin\u002Fsymbols dirs",{"type":42,"tag":1293,"props":1934,"children":1935},{},[1936],{"type":48,"value":1937},"Included if built successfully",{"type":42,"tag":1266,"props":1939,"children":1940},{},[1941,1949,1954],{"type":42,"tag":1293,"props":1942,"children":1943},{},[1944],{"type":42,"tag":66,"props":1945,"children":1946},{},[1947],{"type":48,"value":1948},"PDB availability",{"type":42,"tag":1293,"props":1950,"children":1951},{},[1952],{"type":48,"value":1953},"Staged alongside binaries",{"type":42,"tag":1293,"props":1955,"children":1956},{},[1957],{"type":48,"value":1958},"Present if build output is used",{"type":42,"tag":1266,"props":1960,"children":1961},{},[1962,1970,1975],{"type":42,"tag":1293,"props":1963,"children":1964},{},[1965],{"type":42,"tag":66,"props":1966,"children":1967},{},[1968],{"type":48,"value":1969},"OS coverage",{"type":42,"tag":1293,"props":1971,"children":1972},{},[1973],{"type":48,"value":1974},"Check whether ALL OS legs have SDL scanning — not just Windows",{"type":42,"tag":1293,"props":1976,"children":1977},{},[1978],{"type":48,"value":1979},"Scan on each OS you build for",{"type":42,"tag":51,"props":1981,"children":1982},{},[1983],{"type":42,"tag":66,"props":1984,"children":1985},{},[1986],{"type":48,"value":1987},"Key reconciliation questions:",{"type":42,"tag":433,"props":1989,"children":1990},{},[1991,1996,2001,2013],{"type":42,"tag":85,"props":1992,"children":1993},{},[1994],{"type":48,"value":1995},"Do all local errors also appear in official? If not, they may be in test\u002FNuGet paths that official doesn't scan.",{"type":42,"tag":85,"props":1997,"children":1998},{},[1999],{"type":48,"value":2000},"Do any official findings NOT appear locally? Could mean the binary wasn't built locally (e.g., missing C++ toolset).",{"type":42,"tag":85,"props":2002,"children":2003},{},[2004,2006,2011],{"type":48,"value":2005},"Are there binaries in the official ",{"type":42,"tag":130,"props":2007,"children":2009},{"className":2008},[],[2010],{"type":48,"value":813},{"type":48,"value":2012}," that the local scan missed? Unlikely with recursive scan — the other direction (local finds more) is expected.",{"type":42,"tag":85,"props":2014,"children":2015},{},[2016,2018,2023],{"type":48,"value":2017},"Does official scan native C++ binaries that ship? Check ",{"type":42,"tag":130,"props":2019,"children":2021},{"className":2020},[],[2022],{"type":48,"value":813},{"type":48,"value":2024}," — this is a known gap for repos where C++ output goes to non-standard directories.",{"type":42,"tag":57,"props":2026,"children":2027},{},[2028],{"type":42,"tag":51,"props":2029,"children":2030},{},[2031,2036,2038,2044],{"type":42,"tag":66,"props":2032,"children":2033},{},[2034],{"type":48,"value":2035},"Don't report NuGet transitive dependency findings as repo issues.",{"type":48,"value":2037}," If ",{"type":42,"tag":130,"props":2039,"children":2041},{"className":2040},[],[2042],{"type":48,"value":2043},"libSkiaSharp.dll",{"type":48,"value":2045}," fails BA2008, that's SkiaSharp's issue — unless this repo ships it.",{"type":42,"tag":74,"props":2047,"children":2049},{"id":2048},"references",[2050],{"type":48,"value":2051},"References",{"type":42,"tag":81,"props":2053,"children":2054},{},[2055,2069,2082,2097,2111],{"type":42,"tag":85,"props":2056,"children":2057},{},[2058,2063,2065],{"type":42,"tag":66,"props":2059,"children":2060},{},[2061],{"type":48,"value":2062},"BinSkim rules (all platforms)",{"type":48,"value":2064},": ",{"type":42,"tag":145,"props":2066,"children":2067},{"href":1055},[2068],{"type":48,"value":1055},{"type":42,"tag":85,"props":2070,"children":2071},{},[2072,2077,2078],{"type":42,"tag":66,"props":2073,"children":2074},{},[2075],{"type":48,"value":2076},"Guardian filtering deep-dive",{"type":48,"value":2064},{"type":42,"tag":145,"props":2079,"children":2080},{"href":147},[2081],{"type":48,"value":147},{"type":42,"tag":85,"props":2083,"children":2084},{},[2085,2090,2091,2095],{"type":42,"tag":66,"props":2086,"children":2087},{},[2088],{"type":48,"value":2089},"Per-repo profiles",{"type":48,"value":2064},{"type":42,"tag":145,"props":2092,"children":2093},{"href":767},[2094],{"type":48,"value":767},{"type":48,"value":2096}," (index — one .md per repo)",{"type":42,"tag":85,"props":2098,"children":2099},{},[2100,2105,2106],{"type":42,"tag":66,"props":2101,"children":2102},{},[2103],{"type":48,"value":2104},"Arcade SDL infrastructure",{"type":48,"value":2064},{"type":42,"tag":145,"props":2107,"children":2109},{"href":2108},"references\u002Farcade-sdl.md",[2110],{"type":48,"value":2108},{"type":42,"tag":85,"props":2112,"children":2113},{},[2114,2119,2121,2125],{"type":42,"tag":66,"props":2115,"children":2116},{},[2117],{"type":48,"value":2118},"Local scanning",{"type":48,"value":2120},": Use the ",{"type":42,"tag":66,"props":2122,"children":2123},{},[2124],{"type":48,"value":70},{"type":48,"value":2126}," skill",{"type":42,"tag":2128,"props":2129,"children":2130},"style",{},[2131],{"type":48,"value":2132},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":2134,"total":2299},[2135,2151,2166,2181,2199,2213,2233,2243,2255,2265,2278,2289],{"slug":2136,"name":2136,"fn":2137,"description":2138,"org":2139,"tags":2140,"stars":2148,"repoUrl":2149,"updatedAt":2150},"multithreaded-task-migration","migrate MSBuild tasks to multithreaded mode","Guide for migrating MSBuild tasks to multithreaded mode support, including compatibility red-team review. Use this when converting tasks to thread-safe versions, implementing IMultiThreadableTask, adding TaskEnvironment support, or auditing migrations for behavioral compatibility.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2141,2142,2145],{"name":17,"slug":18,"type":15},{"name":2143,"slug":2144,"type":15},"Engineering","engineering",{"name":2146,"slug":2147,"type":15},"Performance","performance",5535,"https:\u002F\u002Fgithub.com\u002Fdotnet\u002Fmsbuild","2026-07-22T05:37:33.965588",{"slug":2152,"name":2152,"fn":2153,"description":2154,"org":2155,"tags":2156,"stars":2163,"repoUrl":2164,"updatedAt":2165},"analyzing-dotnet-performance","analyze .NET code for performance anti-patterns","Scans .NET code for ~50 performance anti-patterns across async, memory, strings, collections, LINQ, regex, serialization, and I\u002FO with tiered severity classification. Use when analyzing .NET code for optimization opportunities, reviewing hot paths, or auditing allocation-heavy patterns.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2157,2158,2159,2162],{"name":17,"slug":18,"type":15},{"name":23,"slug":24,"type":15},{"name":2160,"slug":2161,"type":15},"Debugging","debugging",{"name":2146,"slug":2147,"type":15},4576,"https:\u002F\u002Fgithub.com\u002Fdotnet\u002Fskills","2026-07-12T08:23:25.400375",{"slug":2167,"name":2167,"fn":2168,"description":2169,"org":2170,"tags":2171,"stars":2163,"repoUrl":2164,"updatedAt":2180},"android-tombstone-symbolication","symbolicate .NET runtime frames in Android tombstones","Symbolicate the .NET runtime frames in an Android tombstone file. Extracts BuildIds and PC offsets from the native backtrace, downloads debug symbols from the Microsoft symbol server, and runs llvm-symbolizer to produce function names with source file and line numbers. USE FOR triaging a .NET MAUI or Mono Android app crash from a tombstone, resolving native backtrace frames in libmonosgen-2.0.so or libcoreclr.so to .NET runtime source code, or investigating SIGABRT, SIGSEGV, or other native signals originating from the .NET runtime on Android. DO NOT USE FOR pure Java\u002FKotlin crashes, managed .NET exceptions that are already captured in logcat, or iOS crash logs. INVOKES Symbolicate-Tombstone.ps1 script, llvm-symbolizer, Microsoft symbol server.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2172,2173,2176,2177],{"name":17,"slug":18,"type":15},{"name":2174,"slug":2175,"type":15},"Android","android",{"name":2160,"slug":2161,"type":15},{"name":2178,"slug":2179,"type":15},"Microsoft","microsoft","2026-07-12T08:23:21.595572",{"slug":2182,"name":2182,"fn":2183,"description":2184,"org":2185,"tags":2186,"stars":2163,"repoUrl":2164,"updatedAt":2198},"apple-crash-symbolication","symbolicate .NET runtime frames in crash logs","Symbolicate .NET runtime frames in Apple platform .ips crash logs (iOS, tvOS, Mac Catalyst, macOS). Extracts UUIDs and addresses from the native backtrace, locates dSYM debug symbols, and runs atos to produce function names with source file and line numbers. Automatically downloads .dwarf symbols from the Microsoft symbol server using Mach-O UUIDs. USE FOR triaging a .NET MAUI or Mono app crash from an .ips file on any Apple platform, resolving native backtrace frames in libcoreclr or libmonosgen-2.0 to .NET runtime source code, retrieving .ips crash logs from a connected iOS device or iPhone, or investigating EXC_CRASH, EXC_BAD_ACCESS, SIGABRT, or SIGSEGV originating from the .NET runtime. DO NOT USE FOR pure Swift\u002FObjective-C crashes with no .NET components, or Android tombstone files. INVOKES Symbolicate-Crash.ps1 script, atos, dwarfdump, idevicecrashreport.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2187,2188,2189,2192,2195],{"name":17,"slug":18,"type":15},{"name":2160,"slug":2161,"type":15},{"name":2190,"slug":2191,"type":15},"iOS","ios",{"name":2193,"slug":2194,"type":15},"macOS","macos",{"name":2196,"slug":2197,"type":15},"Observability","observability","2026-07-12T08:23:20.369986",{"slug":2200,"name":2200,"fn":2201,"description":2202,"org":2203,"tags":2204,"stars":2163,"repoUrl":2164,"updatedAt":2212},"assertion-quality","evaluate assertion quality in test suites","Analyzes the variety and depth of assertions across test suites in any language. Use when the user asks to evaluate assertion quality, find shallow tests, identify assertion-free tests (no assertions or only trivial ones like Assert.IsNotNull \u002F toBeTruthy()), flag self-referential or tautological assertions, measure assertion diversity, or audit whether tests verify different facets of behavior. Polyglot: .NET, Python, TS\u002FJS, Java, Go, Ruby, Rust, Swift, Kotlin, PowerShell, C++. DO NOT USE FOR: writing new tests (use code-testing-agent \u002F writing-mstest-tests), mutation reasoning about whether tests would catch a bug (use test-gap-analysis), or a general severity-ranked anti-pattern audit (use test-anti-patterns), fixing or rewriting assertions, or writing, fixing, or modernizing MSTest tests, assertions, or attributes (use writing-mstest-tests).",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2205,2206,2209],{"name":23,"slug":24,"type":15},{"name":2207,"slug":2208,"type":15},"QA","qa",{"name":2210,"slug":2211,"type":15},"Testing","testing","2026-07-12T08:23:51.277743",{"slug":2214,"name":2214,"fn":2215,"description":2216,"org":2217,"tags":2218,"stars":2163,"repoUrl":2164,"updatedAt":2232},"author-component","create and review Blazor components","Create or review Blazor components (.razor files) with correct architecture. USE FOR: writing new Blazor components that do NOT involve JavaScript interop, implementing parameters and EventCallback, RenderFragment slots, component lifecycle (OnInitializedAsync, OnParametersSet), async patterns, IAsyncDisposable, CancellationToken, CSS isolation, code-behind. DO NOT USE FOR: creating new projects (use create-blazor-project), JavaScript interop or calling browser APIs from Blazor (use use-js-interop), forms and validation (use collect-user-input), prerendering issues (use support-prerendering), HTTP data fetching patterns (use fetch-and-send-data), coordinating state between unrelated components (use coordinate-components).\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2219,2220,2223,2226,2229],{"name":17,"slug":18,"type":15},{"name":2221,"slug":2222,"type":15},"Blazor","blazor",{"name":2224,"slug":2225,"type":15},"C#","csharp",{"name":2227,"slug":2228,"type":15},"UI Components","ui-components",{"name":2230,"slug":2231,"type":15},"Web Development","web-development","2026-07-15T06:03:29.216359",{"slug":2234,"name":2234,"fn":2235,"description":2236,"org":2237,"tags":2238,"stars":2163,"repoUrl":2164,"updatedAt":2242},"binlog-failure-analysis","analyze MSBuild binary logs","Analyze MSBuild binary logs to diagnose build failures. USE FOR: build errors that are unclear from console output, diagnosing cascading failures across multi-project builds, tracing MSBuild target execution order, and generally any MSBuild build issues. Requires an existing .binlog file. DO NOT USE FOR: generating binlogs (use binlog-generation), non-MSBuild build systems.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2239,2240,2241],{"name":23,"slug":24,"type":15},{"name":2160,"slug":2161,"type":15},{"name":2178,"slug":2179,"type":15},"2026-07-12T08:21:34.637923",{"slug":2244,"name":2244,"fn":2245,"description":2246,"org":2247,"tags":2248,"stars":2163,"repoUrl":2164,"updatedAt":2254},"binlog-generation","generate MSBuild binary logs for diagnostics","Generate MSBuild binary logs (binlogs) for build diagnostics and analysis. USE FOR: adding \u002Fbl:{} to any dotnet build, test, pack, publish, or restore command to capture a full build execution trace, prerequisite for binlog-failure-analysis and build-perf-diagnostics skills, enabling post-build investigation of errors or performance. Requires MSBuild 17.8+ \u002F .NET 8 SDK+ for {} placeholder; PowerShell needs -bl:{{}}. DO NOT USE FOR: non-MSBuild build systems (npm, Maven, CMake), analyzing an existing binlog (use binlog-failure-analysis instead).",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2249,2252,2253],{"name":2250,"slug":2251,"type":15},"Build","build",{"name":2160,"slug":2161,"type":15},{"name":2143,"slug":2144,"type":15},"2026-07-19T05:38:19.340791",{"slug":2256,"name":2256,"fn":2257,"description":2258,"org":2259,"tags":2260,"stars":2163,"repoUrl":2164,"updatedAt":2264},"build-parallelism","optimize MSBuild build parallelism","Diagnose and fix under-parallelized MSBuild builds. USE WHEN a multi-project solution build is slower than expected, doesn't speed up when you add cores, pegs a single core while others idle, or you want to know why `-m` isn't helping. Note: `\u002Fmaxcpucount` default is 1 (sequential) — always pass `-m` for parallel builds. Covers finding the critical path (longest serial ProjectReference chain), graph build (`\u002Fgraph`), BuildInParallel, and solution filters (`.slnf`). DO NOT USE FOR: single-project builds, incremental issues (use incremental-build), compilation slowness inside one project (use build-perf-diagnostics), non-MSBuild build systems.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2261,2262,2263],{"name":17,"slug":18,"type":15},{"name":2143,"slug":2144,"type":15},{"name":2146,"slug":2147,"type":15},"2026-07-19T05:38:18.364937",{"slug":2266,"name":2266,"fn":2267,"description":2268,"org":2269,"tags":2270,"stars":2163,"repoUrl":2164,"updatedAt":2277},"build-perf-baseline","establish and optimize build performance baselines","Establish build performance baselines and apply systematic optimization techniques. USE FOR: diagnosing slow builds, establishing before\u002Fafter measurements (cold, warm, no-op scenarios), applying optimization strategies like MSBuild Server, static graph builds, artifacts output, and dependency graph trimming. Start here before diving into build-perf-diagnostics, incremental-build, or build-parallelism. DO NOT USE FOR: non-MSBuild build systems, detailed bottleneck analysis (use build-perf-diagnostics after baselining).",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2271,2272,2275,2276],{"name":2143,"slug":2144,"type":15},{"name":2273,"slug":2274,"type":15},"Monitoring","monitoring",{"name":2146,"slug":2147,"type":15},{"name":2210,"slug":2211,"type":15},"2026-07-12T08:21:35.865649",{"slug":2279,"name":2279,"fn":2280,"description":2281,"org":2282,"tags":2283,"stars":2163,"repoUrl":2164,"updatedAt":2288},"build-perf-diagnostics","diagnose MSBuild build performance bottlenecks","Diagnose 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.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2284,2285,2286,2287],{"name":17,"slug":18,"type":15},{"name":2160,"slug":2161,"type":15},{"name":2143,"slug":2144,"type":15},{"name":2146,"slug":2147,"type":15},"2026-07-12T08:21:40.961722",{"slug":2290,"name":2290,"fn":2291,"description":2292,"org":2293,"tags":2294,"stars":2163,"repoUrl":2164,"updatedAt":2298},"check-bin-obj-clash","detect MSBuild output path conflicts","Detects MSBuild projects with conflicting OutputPath or IntermediateOutputPath. USE FOR: builds failing with 'Cannot create a file when that file already exists', 'The process cannot access the file because it is being used by another process', intermittent build failures that succeed on retry, or missing\u002Foverwritten outputs in multi-project or multi-targeting builds where bin\u002Fobj (or project.assets.json) collide. Common causes: shared OutputPath, missing AppendTargetFrameworkToOutputPath, extra global properties (e.g. PublishReadyToRun), or SetTargetFramework on a ProjectReference to a single-targeting project. DO NOT USE FOR: file access errors unrelated to MSBuild (OS-level locking), single-project single-TFM builds, non-MSBuild build systems.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2295,2296,2297],{"name":2160,"slug":2161,"type":15},{"name":2143,"slug":2144,"type":15},{"name":2207,"slug":2208,"type":15},"2026-07-19T05:38:14.336279",144,{"items":2301,"total":25},[2302,2309,2321,2336,2347,2362,2372],{"slug":4,"name":4,"fn":5,"description":6,"org":2303,"tags":2304,"stars":25,"repoUrl":26,"updatedAt":27},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2305,2306,2307,2308],{"name":17,"slug":18,"type":15},{"name":20,"slug":21,"type":15},{"name":23,"slug":24,"type":15},{"name":13,"slug":14,"type":15},{"slug":70,"name":70,"fn":2310,"description":2311,"org":2312,"tags":2313,"stars":25,"repoUrl":26,"updatedAt":2320},"run BinSkim binary security analysis","Run BinSkim binary security analysis locally against a dotnet repository. Use when asked to scan binaries, check BinSkim compliance, verify a fix for a rule violation, or run a local SDL scan. Also use when asked \"run binskim\", \"binary security scan\", \"scan binaries\", \"check binskim\", \"verify my fix\", \"repro BA2008 locally\", or \"verify BA2008 fix\". DO NOT USE FOR: investigating official pipeline results or portal findings (use binskim-analysis), source code analysis (use CodeQL), credential scanning (use CredScan), or general build\u002Ftest failures (use ci-analysis).\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2314,2315,2318,2319],{"name":17,"slug":18,"type":15},{"name":2316,"slug":2317,"type":15},"CLI","cli",{"name":23,"slug":24,"type":15},{"name":13,"slug":14,"type":15},"2026-07-12T08:23:09.911458",{"slug":2322,"name":2322,"fn":2323,"description":2324,"org":2325,"tags":2326,"stars":25,"repoUrl":26,"updatedAt":2335},"ci-analysis","analyze .NET CI build and test status","Analyze CI build and test status from Azure DevOps and Helix for dotnet repository PRs. Use when checking CI status, investigating failures, determining if a PR is ready to merge, or given URLs containing dev.azure.com or helix.dot.net. Also use when asked \"why is CI red\", \"test failures\", \"retry CI\", \"rerun tests\", \"is CI green\", \"build failed\", \"checks failing\", or \"flaky tests\". DO NOT USE FOR: investigating stale codeflow PRs or dependency update health, tracing whether a commit has flowed from one repo to another, reviewing code changes for correctness or style.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2327,2328,2331,2334],{"name":17,"slug":18,"type":15},{"name":2329,"slug":2330,"type":15},"Azure","azure",{"name":2332,"slug":2333,"type":15},"CI\u002FCD","ci-cd",{"name":2160,"slug":2161,"type":15},"2026-07-12T08:21:49.360882",{"slug":2337,"name":2337,"fn":2338,"description":2339,"org":2340,"tags":2341,"stars":25,"repoUrl":26,"updatedAt":2346},"ci-crash-dump","debug CI crash dumps","Download and debug crash dumps from CI test failures in dotnet repositories. Use when a CI test crashed (not just failed), when the user wants to debug a crash dump from a PR or build, or when asked \"debug dump\", \"download dump\", \"crash dump from CI\", \"test crashed\", \"analyze crash in PR\", or \"why did the test crash\". DO NOT USE FOR: test failures that are not crashes (use ci-analysis), build failures, performance analysis, or analyzing dumps you already have locally.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2342,2343,2344,2345],{"name":17,"slug":18,"type":15},{"name":2332,"slug":2333,"type":15},{"name":2160,"slug":2161,"type":15},{"name":2210,"slug":2211,"type":15},"2026-07-12T08:21:56.945844",{"slug":2348,"name":2348,"fn":2349,"description":2350,"org":2351,"tags":2352,"stars":25,"repoUrl":26,"updatedAt":2361},"flow-analysis","analyze VMR codeflow health","Analyze VMR codeflow health using maestro MCP tools and GitHub MCP tools. USE FOR: investigating stale codeflow PRs, checking if fixes have flowed through the VMR pipeline, debugging dependency update issues, checking overall flow status for a repo, diagnosing why backflow PRs are missing or blocked, subscription health, build freshness, URLs containing dotnet-maestro or \"Source code updates from dotnet\u002Fdotnet\". DO NOT USE FOR: CI build failures (use ci-analysis skill), code review (use code-review skill), general PR investigation without codeflow context, tracing whether a specific commit\u002FPR has reached another repo (use flow-tracing skill). INVOKES: maestro and GitHub MCP tools, flow-health.cs script.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2353,2354,2355,2358],{"name":2332,"slug":2333,"type":15},{"name":2143,"slug":2144,"type":15},{"name":2356,"slug":2357,"type":15},"GitHub","github",{"name":2359,"slug":2360,"type":15},"MCP","mcp","2026-07-12T08:21:53.151866",{"slug":2363,"name":2363,"fn":2364,"description":2365,"org":2366,"tags":2367,"stars":25,"repoUrl":26,"updatedAt":2371},"flow-tracing","trace .NET dependency flow in VMR","Trace dependency flow across .NET repos through the VMR pipeline. USE FOR: checking if a PR\u002Fcommit from repo A has reached repo B, finding what runtime SHA is in an SDK build, tracing dependency versions through the VMR, checking if a commit is included in an SDK build, decoding SDK version strings, \"has my fix reached runtime\", \"did roslyn#80873 flow to runtime\", \"what SHA is in SDK version X\", cross-repo dependency tracing, mapping SDK versions to VMR commits. DO NOT USE FOR: codeflow PR health or staleness (use flow-analysis skill), CI build failures (use ci-analysis skill). INVOKES: maestro and GitHub MCP tools, Get-SdkVersionTrace.ps1 script.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2368],{"name":2369,"slug":2370,"type":15},"Data Pipeline","data-pipeline","2026-07-12T08:21:55.689056",{"slug":2373,"name":2373,"fn":2374,"description":2375,"org":2376,"tags":2377,"stars":25,"repoUrl":26,"updatedAt":2381},"helix-investigation","investigate Helix test failures","Deep-dive investigation of Helix test failures starting from AzDO build legs. USE FOR: investigating recurring Helix test failures, downloading and analyzing Helix console logs, comparing passing vs failing runs, identifying machine-specific issues, XHarness timeout analysis, Android emulator DEVICE_NOT_FOUND errors, bulk failure aggregation across legs, \"why does this test fail on some machines\", \"top 5 failing tests in the last 2 days\", \"download helix logs for build X\", \"compare passing and failing helix runs\", \"what are the most common failures\". DO NOT USE FOR: high-level CI status checks (use ci-analysis), codeflow PRs (use flow-analysis). INVOKES: Helix and AzDO MCP tools, curl, gh CLI.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2378,2379,2380],{"name":2160,"slug":2161,"type":15},{"name":2143,"slug":2144,"type":15},{"name":2210,"slug":2211,"type":15},"2026-07-12T08:21:46.445586"]