dotnet/runtime

~2,300 distinct XML manifests with structural invariants no per-language linter sees — and the demand source that promotes `xml_path_*` from v0.11+ to a v0.10 ship-target.

Narrative
Adds a structural floor on top of mature tooling
Rules
60
Last revalidated
Engineering reference
README on GitHub · .alint.yml

Why this case study matters

dotnet/runtime is the canonical XML-shape monorepo at scale — Microsoft’s CLR + Mono + NativeAOT runtime, the BCL (Base Class Library: every System.* and Microsoft.Extensions.*), the per-OS native libs, and the cross-arch installer. Built on the MSBuild + Arcade SDK stack, with the actual build matrix orchestrated from 186 yml files under eng/pipelines/ (Azure DevOps), and only 20 yml under .github/workflows/ for GitHub-side automation.

Where apache/spark surfaced the xml_path_* rule-kind candidate via 49 pom.xml files (Maven), dotnet/runtime stress-tests it at one order of magnitude bigger scale with:

Total: ~2,300 distinct XML manifests in the sparse-checkout. The single most XML-heavy repo in the launch-evidence list.

Headline catch

Two v0.10 ship-targets get demand-validated by this case study.

1. xml_path_* is now a v0.10 ship-target

spark proved the shape via 49 pom.xml; dotnet/runtime proves the scale via ~2,300 distinct XML manifests across one repo. The cumulative drift exposure (8 distinct per-csproj invariants × 1,091 csprojs ≈ 8,700 invariant-instances that today are checked via regex fallback or not at all) is large enough to warrant the primitive’s design cost without further demand-source accumulation.

The 8 invariants the structured-query primitive unblocks per csproj:

InvariantToday (regex fallback)With xml_path_*
Root element is <Project>(?m)^<Project(\s|>|/) (with BOM gymnastics)xml_path_exists: $.Project
Sdk attribute is one of {NET.Sdk, NET.Sdk.Web, …}Long alternation regexxml_path_matches: $.Project[@Sdk]
Has either <TargetFramework> or <TargetFrameworks> (mutually exclusive)Counts substring matches; can’t enforce mutual exclusionxml_path_count: ... == 1
TargetFrameworks references only known TFM variables from eng/Versions.propsNot expressibleCross-file xml_path_matches
<EnableNullable>true</EnableNullable> per area-level conventionPer-csproj regex checkxml_path_equals
<RootNamespace> matches the file-system pathNot expressiblexml_path_equals against derived path
<PackageReference Version="..." /> matches eng/Versions.propsNot expressibleCross-file xml_path_equals
Every <ProjectReference Include="..." /> resolves to an existing csprojNot expressiblexml_path_resolves

Promotes xml_path_* from “v0.11+ candidate” to “v0.10 ship-target”: the structured-query family becomes complete (json/yaml/toml/xml) and the two demand-driving repos are both flagship-visibility launches (Apache TLP + Microsoft CLR).

2. dotnet@v1 (or csharp@v1) bundled ruleset is a v0.10 ship-target

alint ships rust@v1, java@v1, python@v1, node@v1, go@v1 — but no C#/.NET equivalent today. dotnet/runtime is the first case study where this gap is the dominant story.

A 12-rule dotnet@v1 ruleset (csproj-uses-net-sdk, csproj-declares-target-framework, root-directory-build-{props,targets}, global-json + NuGet.config + Versions.props triad, the bin/obj/artifacts/.vs hygiene set, msbuild-files-have-project-root) would consolidate the build-system anchor + per-csproj XML-shape + hygiene sections of this case study’s config into one extends: line.

Adopter surface is large: every Microsoft .NET project + every Azure SDK + every dotnet/* repo + microsoft/dapr + microsoft/orleans + the Unity scripting layer + a substantial fraction of enterprise codebases. Composition is mechanical; the 12 rules are already authored in this case study.

Where alint earns its keep here

dotnet/runtime is the flagship “XML-shape monorepo at scale” story for the launch:

The case study also confirms a 9th source for cross_file_value_equals via the dotnet-tools.jsonglobal.json Arcade SDK coherence pattern — already past-saturation, already v0.10.

Future story angles

The factual engineering writeup (tooling inventory, mapping table, gap catalogue, validation status footer) lives in the public alint repo at github.com/asamarts/alint/tree/main/examples/dotnet-runtime/README.md.