dotnet-inspect-compatibility
Checks if your code works with different versions of the dotnet framework.
Installation
Paste this into Claude Code, Cursor, or any agent that can run commands.
SKILL.mdShow the author's original SKILL.md
--- name: dotnet-inspect-compatibility version: 0.1.0 description: Decide whether a change or upgrade is safe — API-surface diffs, behavioral diffs (allocations, exceptions), feature switches, and version resolution. --- # dotnet-inspect: compatibility and change analysis Use this skill to decide whether a change is safe to adopt: what changed between two versions and what surface a library exposes. The scenario crosses commands — `diff` for change, `library`/`package` for the surface a single version exposes. ```bash dnx dotnet-inspect -y -- <command> ``` ## Did the API surface change? `diff` compares a version range from a package, a platform (in-box) library, or two local builds. Pick the lens for the question you are answering: ```bash dnx dotnet-inspect -y -- diff --package System.Text.Json@9.0.0..10.0.0 --breaking dnx dotnet-inspect -y -- diff --platform System.Runtime@9.0.0..10.0.0 --additive dnx dotnet-inspect -y -- diff --library old/Foo.dll..new/Foo.dll --changed ``` `--breaking` for migration work, `--additive` for release notes, `--changed` for in-place member changes, `--name-only` for a quick list. Narrow with `-t TypeName`; widen with `--all`. ## Did runtime behavior change? (allocations, exceptions) `-S "Analysis Diff"` compares body-level signal *deltas* between the two versions, not just the API shape. Rows are `Member | Signal | Old | New | Delta`, where `Signal` covers `allocations`, `copies`, `reflection`, `throws`, `catches`, `finallys`, `unsafe`, `constructed-exceptions`, and `optimization` shapes. This is how you catch an allocation regression or a change in exception coverage across versions. (For what these signals mean on a single version, see the `performance` and `correctness` skills.) ```bash dnx dotnet-inspect -y -- diff --package Foo@1.0.0..2.0.0 -S "Analysis Diff" dnx dotnet-inspect -y -- diff --library old/Foo.dll..new/Foo.dll -S "Analysis Diff" --changed ``` Use `Analysis Diff` for aggregate regression triage. To confirm whether one allocation occurrence was introduced at a caller-selected boundary, resolve one method and request the native Analysis Finding pairs: ```bash dnx dotnet-inspect -y -- diff --package Foo@1.4.0..1.5.0 \ -t Foo.Parser -m Parse \ --finding analysis.allocation ``` `PairFinding.Added` with `Old=absent` and `New=present` confirms allocation onset. `Present`, `Removed`, and `Changed` remain distinct; do not infer onset from an aggregate allocation-count delta. For a direct-call boundary in one caller method, select the call-site producer: ```bash dnx dotnet-inspect -y -- diff --package Foo@1.4.0..1.5.0 \ -t Foo.Parser -m Parse \ --finding analysis.call-site ``` Rows identify the callees. `PairFinding.Added` confirms a new direct-call occurrence; `Changed` reports retained-call facet changes such as moving into a loop. For a definite unsafe-operation boundary in one method, select the unsafety producer: ```bash dnx dotnet-inspect -y -- diff --package Foo@1.4.0..1.5.0 \ -t Foo.Parser -m Parse \ --finding analysis.unsafety ``` Rows identify unsafe operation kinds and details. `PairFinding.Added` confirms introduction; `Present` and `Removed` distinguish persistence from disappearance without treating endpoint-local IL offsets as identity. ## Did the implementation change? (decompiled C# + IL + PDB Source) `-S "Implementation Diff"` selects Research-composed body evidence instead of the default API compatibility view. Rows identify the member, producer (`C#`, `IL`, or `PDB Source`), change kind, and producer-owned evidence. `C#` is decompiled text; `PDB Source` is Portable-PDB-selected, checksum-verified text acquired locally or through SourceLink. The lanes are peers: PDB-source absence or failure stays visible and never replaces the C# lane. Narrow with `-t` and `-m`; use `--table`, `--tsv`, or `--jsonl` for columnar output. ```bash dnx dotnet-inspect -y -- diff --library old/Foo.dll..new/Foo.dll \ -S "Implementation Diff" --pdb-source --repo /path/to/Foo \ -t MyType -m HotPath ``` `--repo` requires a fully qualified clone path. For `raw.githubusercontent.com` SourceLink URLs, it reads the committed blob at the SourceLink commit and verifies it against the PDB checksum before fetching the source body remotely. Package or PDB acquisition may still use the network; other SourceLink hosts do not use the local-repository path. Treat these rows as implementation evidence, not semantic-equivalence proof. ## What can be configured? (feature switches) `-S Switches` on `library` or `package --library` reports the behavior and trim/AOT knobs: `[FeatureSwitchDefinition]`s, runtime host configuration options, and `AppContext` switches. ```bash dnx dotnet-inspect -y -- library System.Text.Json -S Switches ``` ## Which versions to compare Version resolution is source-scoped. Use `Foo --version` for the best-known listed version: it reuses each source's matching latest entry and queries sources without one. Use `Foo --latest-version` to bypass those caches and refresh the newest version across all eligible configured sources, and `Foo --versions [N]` (add `--preview`) to list published versions. Unlisted versions are hidden unless `--include-unlisted` is explicit. `--versions-with-feed` retains each version/feed pair when source identity matters. Source declaration order is not precedence; load the `private-feeds` skill for source and credential workflows. Pin with `@`: `Foo@9.0.0`, `Foo@latest`. For caller-driven onset or bisect work, resolve an inclusive addressable vector, then probe only the cells you choose: ```bash dnx dotnet-inspect -y -- package Foo@1.0.0..2.0.0 --versions dnx dotnet-inspect -y -- type TargetType --package Foo@1.0.0..2.0.0 --at '#5' dnx dotnet-inspect -y -- member TargetType TargetMember --package Foo@1.0.0..2.0.0 --at 1.6.0 dnx dotnet-inspect -y -- timeline --package Foo@1.0.0..2.0.0 \ --type TargetType --members --at first --at last dnx dotnet-inspect -y -- timeline --package Foo@1.0.0..2.0.0 \ --type TargetType --member TargetMember \ --finding analysis.unsafety --at first --at last ``` `--at` accepts an exact version, one-based `#N`, `first`, or `last`. Vector resolution does not download every package; only the selected probe is acquired. The agent owns the search policy and bound. For recurrence-safe current onset, walk backward from the bad version until the first successful absence; use binary search only for a predicate known to be monotonic. `timeline` renders `Evaluations` and `Transitions` over the same vector. Omit `--at` for a zero-payload address view and midpoint recommendation, repeat `--at` for sparse probes, or pass `--at all` for explicit dense traversal. Choose the type-focused census with `--type-presence`, `--members`, or `--attributes` (aliases for `api.type`, `api.member`, and `api.attribute`). Add `--member` to `api.member` for one exact member identity track. The same member selector scopes `analysis.allocation`, `analysis.call-site`, and `analysis.unsafety` timelines to one method body. Gap-spanning transitions are evidence across the selected probes, not claims about the exact introduction or removal version. The range and point probes identify a candidate boundary. Confirm the adjacent pair with Metadata's real Finding comparison rather than inferring introduction from probe text: ```bash dnx dotnet-inspect -y -- diff \ --package System.Text.Json@8.0.6..9.0.0 \ -t System.Text.Json.Schema.JsonSchemaExporter \ -S "Finding Transitions" ``` An introduction boundary is a row with `PairFinding.Added`, `Old=absent`, and `New=present`. `PairFinding.Present` means the target exists at both endpoints; for a type target, no row means it exists at neither. Use `-m Type.Member:1` for an API member boundary. Use `--finding analysis.allocation`, `--finding analysis.call-site`, or `--finding analysis.unsafety` with exactly one method target for the corresponding Analysis boundary. Use `--finding csharp.line` or `--finding il.op` with exactly one method target to inspect native implementation-census transitions. Those lenses preserve complete, absent, and failed outcomes, including added or removed methods.
Mirrored from the author's public source. Install counts from the open skills registry.