MCPInstall

dotnet-inspect-correctness

Judge whether code is sound and safe to call — its exception surface, unsafe operations, interop boundaries, and pooled-resource ownership evidence.

Installs
415
Last 24h
—
Trending rank
—
Security
Not audited

Install

Works with every agent the skills CLI supports.

npx skills add https://github.com/richlander/dotnet-inspect --skill dotnet-inspect-correctness
  1. 01

    Install

    Run the command in your project. The CLI asks which agents to install for.

  2. 02

    Describe the task

    Ask your agent for something this skill covers. It loads dotnet-inspect-correctness automatically when relevant.

  3. 03

    Review the result

    The agent follows the SKILL.md steps, scripts and references bundled with the skill.

SKILL.md

The instructions your agent reads when the skill is triggered.

dotnet-inspect: correctness and safety

Use this skill to judge whether code is sound and safe to call: what it can throw, how it handles errors, and where it steps outside safe, managed execution. This is single-version analysis; for how these signals change between versions, use the compatibility skill.

dnx dotnet-inspect -y -- <command>

What can it throw? (exception surface)

There is no dedicated "Exceptions" section; exception behavior comes from method-body analysis. Exception Regions shows the exact catch/filter/finally layout; graph fields and hidden facts summarize behavior:

dnx dotnet-inspect -y -- member Type Method:1 -S "Exception Regions"
dnx dotnet-inspect -y -- member Type Method:1 -S "Call Graph" --fields "Throws,ThrowSites,ExceptionTypes,ConstructedExceptions,Catch,Finally"
dnx dotnet-inspect -y -- member Type Method:1 -S "Call Graph" --fields "Throws,Catch,Finally"
dnx dotnet-inspect -y -- member Type Method:1 -S Facts --tsv

Throws/ThrowSites count throw sites; ExceptionTypes/ConstructedExceptions name the exception types; Catch/Finally show handling. Exception Regions retains IL ranges and caught types. -S Facts (member, single method) lists the hidden facts in the body and supports --tsv.

Is it memory-safe? (unsafe operations)

dnx dotnet-inspect -y -- member Type Method:1 --library MyLib.dll -S "Unsafe Operations,IL"

-S "Unsafe Operations" shows the unsafe operations in a single method body, with IL evidence. For the library-wide safety surface (unsafe members, P/Invoke methods) and provenance/supply-chain signals, see the signals skill.

For one crash or profiler coordinate, use library coordinate 0x06000001+0x5 --library Foo.dll for the default source-location, member, instruction, exception, callsite, and return-address context. Safety evidence is opt-in: library coordinate 0x06000001+0x5 --library Foo.dll -S "Context: Safety".

To confirm whether one definite unsafe operation appeared at an adjacent version boundary, first correlate caller-selected package cells:

dnx dotnet-inspect -y -- diff --history --package MyLib@1.0.0..2.0.0 \
  -t MyType -m Method \
  --finding analysis.unsafety --at first --at last

Repeat --at for sparse probes or use --at all for an explicitly bounded dense traversal. A gap-spanning Added row locates a candidate boundary; it does not claim the exact introduction version. Confirm the adjacent pair:

dnx dotnet-inspect -y -- diff --package MyLib@1.4.0..1.5.0 \
  -t MyType -m Method \
  --finding analysis.unsafety

PairFinding.Added is the introduction proof. Present and Removed distinguish persistence from disappearance; the command compares only the two supplied endpoints.

Review unsafe code and ownership against .NET guidance

Use the .NET unsafe-code best-practices guide as the policy owner. Its source document currently organizes the review into 26 numbered topics.

dotnet-inspect supplies compiled evidence, not a monolithic compliance verdict. Acquire reusable JSONL row sets, use the agent and jq to slice and join them for each question, then drill only consequential Members. The same rows can answer other safety questions without adding a new aggregate command.

Acquire reusable row sets

Keep each row family separate so its identity, shape, and completion remain visible. Capture every command's status and diagnostics: an empty focused section can be a nonzero result rather than a successful empty census.

capture()
{
  output="$1"
  shift
  status=0
  "$@" > "$output" 2> "$output.stderr" || status=$?
  printf '%s\t%s\n' "$output" "$status" >> inspection-status.tsv
}

: > inspection-status.tsv
capture unsafe-members.jsonl \
  dnx dotnet-inspect -y -- library MyLib.dll \
    -S "Unsafe Members" --jsonl
capture pinvoke-methods.jsonl \
  dnx dotnet-inspect -y -- library MyLib.dll \
    -S "P/Invoke Methods" --jsonl
capture custom-attributes.jsonl \
  dnx dotnet-inspect -y -- library MyLib.dll \
    -S "Custom Attributes" --jsonl
capture references.jsonl \
  dnx dotnet-inspect -y -- library MyLib.dll \
    -S References --jsonl
capture signals.json \
  dnx dotnet-inspect -y -- library MyLib.dll \
    -S Signals --json

Library Custom Attributes covers a filtered set of assembly- and module-level attributes. It does not discover attributes on Types, fields, or methods, and does not establish SkipLocalsInit coverage. Preserve that scope: use exact-subject attributes only after another row or source evidence selects the Type or Member, and report whole-library attribute discovery as unverified.

Ownership and unsafe code overlap. A pooled buffer can have no pointer opcode yet still fail through use-after-return, missing cleanup, or ownership transfer. Acquire Resource Triage beside unsafe evidence through the same wrapper:

capture resource-triage.jsonl \
  dnx dotnet-inspect -y -- library MyLib.dll \
    -S "Resource Triage" --jsonl

Resource Triage currently has no positive completion receipt and can emit rows while some resource roots remain incomplete. Always describe its ownership coverage as unverified; preserve any more specific diagnostic and never turn zero rows into "no ownership issue."

Slice and combine rows

Slurp unsafe calls by exact operation:

jq -s '
  map(select(.reason == "Unsafe call"))
  | sort_by(.detail)
  | group_by(.detail)
  | map({
      operation: .[0].detail,
      sites: length,
      members: (map(.member) | unique)
    })
' unsafe-members.jsonl

Select API families discussed by the guidance:

jq -s --arg pattern \
  'Unsafe\.(AsPointer|As|BitCast|Add|NullRef|SkipInit|ReadUnaligned|WriteUnaligned|CopyBlock)' '
  map(select(.detail | test($pattern)))
' unsafe-members.jsonl

Select stackalloc (localloc) sites:

jq -s '
  map(select(.detail == "localloc"))
  | group_by(.member)
  | map({member: .[0].member, sites: map(.il)})
' unsafe-members.jsonl

Keep evidence families typed when composing one agent packet:

jq -n \
  --slurpfile unsafe unsafe-members.jsonl \
  --slurpfile ownership resource-triage.jsonl \
  --slurpfile interop pinvoke-methods.jsonl \
  '{
    unsafe: $unsafe,
    ownership: $ownership,
    interop: $interop
  }'

These are slices, not joins by display text. Retain each row's Member, IL, token, Candidate, Finding, Acquire IL, Boundary IL, and boundary fields. Resolve an exact Type and Member selector before drilling; do not invent correspondence from a formatted Member label.

Drill one candidate

Use separate machine outputs for the focused evidence and retain Markdown IL for review. Reuse the capture wrapper so an empty or failed drill remains visible:

capture candidate-unsafe.jsonl \
  dnx dotnet-inspect -y -- member MyType Method:1 --library MyLib.dll \
    -S "Unsafe Operations" --jsonl
capture candidate-exceptions.jsonl \
  dnx dotnet-inspect -y -- member MyType Method:1 --library MyLib.dll \
    -S "Exception Regions" --jsonl
capture candidate-attributes.jsonl \
  dnx dotnet-inspect -y -- member MyType Method:1 --library MyLib.dll \
    -S "Custom Attributes" --jsonl
capture candidate-calls.jsonl \
  dnx dotnet-inspect -y -- member MyType Method:1 --library MyLib.dll \
    -S "Call Graph" --fields "Unsafe,Throw,Catch,Finally,Loop" --jsonl
capture candidate-il.md \
  dnx dotnet-inspect -y -- member MyType Method:1 --library MyLib.dll \
    -S IL

Load skill decompiler only when reconstructed C# helps explain the IL. Use source evidence when the question depends on lexical scope, an authored guard, compiler warnings, or repository test practice.

Route the 26 guidance questions

The routes below name the smallest useful evidence composition. They do not claim that matching evidence proves a violation or that checked-empty rows prove safety.

#Guidance topicEvidence route and boundary
1Untracked managed pointersUnsafe-call slice for AsPointer; drill pointer provenance, pinning, uses, and escape.
2Pointer escape from fixedUnsafe/pinned evidence plus IL stores, returns, and calls; lexical fixed scope may require source.
3Runtime or library internalsUnsafe calls, attributes, references, and nonpublic call evidence; broad reliance remains a review judgment.
4Invalid managed pointersSlice Unsafe.Add and related byref arithmetic; drill range and control-flow evidence.
5Reinterpret castsSlice Unsafe.As and BitCast; join exact source/destination Type metadata before judging compatibility.
6Write barrier and GC-reference atomicitySlice cpblk, initblk, indirect stores, and copy APIs; drill destination provenance and field types.
7Object lifetimeCalls to GC.KeepAlive, SafeHandle, finalizers, callbacks, and interop boundaries; absence usually remains unverified.
8Cross-thread localsCall graph, async/state-machine, pointer/byref, and ownership evidence; thread transfer generally needs source or runtime evidence.
9Unsafe bounds-check removalSlice pointer dereferences and Unsafe.Add; inspect guards and ranges, then require runtime performance evidence.
10Memory access coalescingSlice Unsafe/MemoryMarshal calls and stores; compare safe alternatives with runtime evidence.
11Unaligned memory accessSlice unaligned APIs and indirect operations; target alignment and atomicity remain platform/context questions.
12Binary struct serializationSlice MemoryMarshal/Unsafe reads, writes, copies, and exact Type layouts; open generics remain incomplete.
13Null managed pointersSlice Unsafe.NullRef and pointer-to-byref conversions; drill uses and discarded dereferences.
14stackallocSlice localloc; drill loop membership, length construction, span conversion, and bounds.
15Fixed-size buffersUnsafe declarations can select candidates, but library attributes cannot discover field-level FixedBufferAttribute; whole-library discovery is unverified, so use source or exact-Type decompilation for known candidates.
16Pointer plus length APIsPointer signatures and P/Invoke rows identify candidates; inspect explicit lengths and termination assumptions.
17String mutationPointer stores plus string-origin evidence; source or decompilation usually establishes the target.
18Raw IL generationReferences and calls identify Reflection.Emit or Cecil use; generated-IL validity requires separate evidence.
19Uninitialized localsSlice Unsafe.SkipInit calls. Library attributes cannot establish SkipLocalsInit; that whole-library census is unverified, so use source or inspect exact-Member attributes and IL local initialization, then drill reads, writes, and pooled-buffer initialization.
20ArrayPool<T> and poolingJoin Resource Triage, unsafe calls, exceptions, and returns; current ownership coverage is always unverified.
21bool/integer conversionSlice Unsafe.As, BitCast, and unaligned reads involving Boolean and integral Types.
22InteropP/Invoke rows, signatures, attributes, unsafe operations, and ownership/lifetime evidence.
23Thread safetyCall graph and mutable-resource evidence can select candidates; a general thread-safety verdict is out of scope.
24SIMD/vectorizationCalls and unsafe operations identify loads/stores; bounds, alignment, atomicity, and benefit need context/runtime evidence.
25Fuzz testingAssembly evidence cannot establish repository fuzz coverage; inspect tests and CI separately.
26Compiler warningsWarnings are not retained in ordinary assemblies; require build diagnostics or SARIF.

Report the review

For each applicable question, report:

  1. the guidance topic and exact inspected subject;
  2. owner-issued rows and exact coordinates;
  3. the jq slice or join that produced the bounded candidate set;
  4. the agent's labeled interpretation;
  5. completion or unverified boundaries; and
  6. the next focused probe when evidence cannot decide the question.

Do not report all 26 topics as clean because no matching row appeared. Omit topics that are genuinely inapplicable, and distinguish them from applicable questions whose evidence is unavailable or incomplete.

FAQ

What does the dotnet-inspect-correctness skill do?

Judge whether code is sound and safe to call — its exception surface, unsafe operations, interop boundaries, and pooled-resource ownership evidence.

How do I install dotnet-inspect-correctness?

Run npx skills add https://github.com/richlander/dotnet-inspect --skill dotnet-inspect-correctness in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/dotnet-inspect-correctness/ (personal) or .claude/skills/dotnet-inspect-correctness/ (project).

Which AI agents can use dotnet-inspect-correctness?

Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.

Is dotnet-inspect-correctness safe to install?

No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.

Who maintains dotnet-inspect-correctness?

It is published by richlander in richlander/dotnet-inspect. It has 415 recorded installs.

More from richlander/dotnet-inspect

View all →

dotnet-inspect

richlander/dotnet-inspect

Find and share evidence instead of guessing about .NET packages, libraries, APIs, dependencies, source, performance, and version changes.

Backend & APIs509 installs

dotnet-inspect-decompiler

richlander/dotnet-inspect

Open the skill to read its SKILL.md instructions.

Backend & APIs417 installs

dotnet-inspect-compatibility

richlander/dotnet-inspect

Open the skill to read its SKILL.md instructions.

Backend & APIs412 installs

dotnet-inspect-performance

richlander/dotnet-inspect

Whole-assembly call-graph leverage ranking and performance triage for libraries (experimental).

Backend & APIs411 installs

Popular backend & apis skills

View category →

find-skills

vercel-labs/skills

Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.

OfficialBackend & APIs4.1M installs

entra-app-registration

microsoft/azure-skills

Guides Microsoft Entra ID app registration, OAuth 2.0 authentication, and MSAL integration. USE FOR: create app registration, register Azure AD app, configure OAuth, set up authentication, add API permissions, generate service principal, MSAL example, console app auth, Entra ID setup, Azure AD authentication. DO NOT USE FOR: Key Vault secrets (use azure-keyvault-expiration-audit), general Azure resource security guidance.

OfficialBackend & APIs566.7K installs

This skill should be used when the user wants to "write agent code", "build an agent with ADK", "add a tool", "create a callback", "define an agent", "use state management" — in a project that needs ADK (Agent Development Kit) API patterns and code examples. It provides a quick reference for agent types, tool definitions, orchestration patterns, callbacks, state management, the graph Workflow API, and reference recipes to study. Do NOT use for scaffolding (use google-agents-cli-scaffold) or deployment (use google-agents-cli-deploy).

Backend & APIs514.8K installs

embedded-captions

heygen-com/hyperframes

Add captions or subtitles to an existing single-subject talking-head video without editing the footage. Use for plain verbatim captions, cinematic captions embedded behind the subject, VFX captions, “炸/特效/酷炫字幕,” or a named identity from the 35-style catalog. Route by visual identity, not by backend engine. The quiet anchor rail is the default; embed every word only when the user explicitly wants a fully cinematic treatment. The workflow runs locally end to end, including transcription and subject matting; split multi-shot footage before applying it.

Backend & APIs453.3K installs

entra-agent-id

microsoft/azure-skills

Provision Microsoft Entra Agent Identity Blueprints, BlueprintPrincipals, and per-instance Agent Identities via Microsoft Graph, and configure OAuth 2.0 token exchange (fmipath, OBO, cross-tenant) including the Microsoft Entra SDK for AgentID sidecar. USE FOR: Agent Identity Blueprint, BlueprintPrincipal, agent OAuth, fmipath token exchange, agent OBO, Workload Identity Federation for agents, polyglot agent auth, Microsoft.Identity.Web.AgentIdentities. DO NOT USE FOR: standard Entra app registration (use entra-app-registration), Microsoft Foundry agent authoring (use microsoft-foundry).

OfficialBackend & APIs336.6K installs

neon

neondatabase/agent-skills

Overview of Neon, a complete set of cloud backend primitives around Lakebase Postgres: Auth, Object Storage, Functions, the AI Gateway, and Realtime. Start here to choose Neon for undecided login, files, APIs, and LLM calls, set up the CLI or MCP server, and follow the branch-first workflow. Use when building an app or backend on Neon, or when "Neon" or "Lakebase Postgres" is mentioned. Child skill neon-postgres wins for an existing DATABASEURL, SQL, schema, inspect, or search. Child skill neon-auth wins for login, users, sessions, identity routing, and Managed Better Auth setup. Child skill neon-realtime wins for live queries in reactive apps and agents. Also use for object storage, S3, buckets, serverless functions, function triggers, cron, AI gateway, LLM calls, realtime, logs, Loki, Grafana, observability, postgres, database, backend, Claimable Neon, neon.new, or a no-signup database.

Backend & APIs237.1K installs