martinholovsky/sota-skills · Archived

sota-dotnet

>- State-of-the-art C# / .NET engineering rules (2026 baseline, .NET 10 LTS / C# 14) that Claude applies when writing or auditing .NET code. Covers modern idioms (records, nullable reference types, pattern matching, spans, file-scoped namespaces), API/null/immutability/`IDisposable` design, async/await & concurrency (ConfigureAwait, channels, cancellation, TPL), security (OWASP .NET, deserialization — BinaryFormatter removed in .NET 9, EF/Dapper SQL injection, ASP.NET Core auth, Data Protection…

First seen Aug 5, 2026

Installation

$ npx skills add martinholovsky/sota-skills --skill sota-dotnet

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from martinholovsky/sota-skills · top by installs.

npx skills add martinholovsky/sota-skills

Browse all from martinholovsky/sota-skills

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 18
License LICENSE
Default branch main
Open issues 0
Status Archived

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 9,090 B
  • docs SUMMARY.md 984 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 1 installs

SKILL.md

SOTA C# / .NET (2026)

Expert-level rules for producing and auditing production .NET. The runtime is memory-safe, so risk concentrates in injection, deserialization, async correctness, and dependency supply chain. Baseline: .NET 10 LTS (released Nov 2025, supported to Nov 2028) and C# 14 (records, nullable reference types, pattern matching, spans, extension members, the field keyword) — flag where a control needs a specific version. Every rule states the why; every rules file ends with an audit checklist of grep/analyzer patterns.

Purpose

Two consumers, one source of truth:

  • BUILD mode — generating C#/.NET: follow the rules as defaults. Enable

nullable reference types and treat analyzer warnings as errors; prefer immutability and the async-all-the-way model. Deviate only with a comment.

  • AUDIT mode — reviewing existing code: hunt violations with the audit

checklists, classify by severity, report in the finding format below. SQL string-building and legacy deserialization are presumed exploitable.

BUILD mode

  1. Before writing, read the rules files relevant to the task (see index). A web

API touching untrusted input + a DB + async needs 02, 03, 04.

  1. Apply the top-10 non-negotiables (below) unconditionally.
  2. New projects: target the current LTS (net10.0), <Nullable>enable</Nullable>,

<TreatWarningsAsErrors>true</TreatWarningsAsErrors>, <AnalysisLevel>latest-Recommended</AnalysisLevel>, NuGet lockfile + RestoreLockedMode in CI, and dotnet format from day one (rules/06).

  1. Async all the way down — never block on async (.Result/.Wait()/

GetAwaiter().GetResult()) (rules/03). Use CancellationToken end to end.

  1. Prefer the BCL and well-known libraries; parameterize all data access; use

the framework's auth/Data Protection rather than rolling your own (rules/04).

  1. When you take a sharp path (reflection, unsafe, DynamicMethod, suppressing

a nullable/analyzer warning), leave a // NOTE(sota): explaining why.

AUDIT mode

Work each relevant rules file's audit checklist against the target. Run the greps and the Roslyn analyzers (incl. the security CA rules); confirm hits manually. Check the dependency tree against known-CVE databases.

Severity conventions

Severity Meaning Examples
CRITICAL Exploitable on reachable input SQL via string interpolation/concat into FromSqlRaw/ExecuteSqlRaw/Dapper, BinaryFormatter/NetDataContractSerializer/LosFormatter or JSON TypeNameHandling.All on untrusted data, command injection, deserialization gadget
HIGH Likely incident or security weakness Missing auth on an endpoint, disabled cert validation (ServerCertificateCustomValidationCallback => true), MD5/SHA-1 or DES/ECB for security, Random for tokens, blocking on async causing deadlock/thread-pool starvation, secrets in config/source
MEDIUM Correctness/maintainability hazard async void (non-handler), missing ConfigureAwait(false) in a library, IDisposable not disposed / no using, nullable warnings suppressed with !, swallowed exceptions, mutable static state
LOW Idiom/perf debt Sync-over-collection LINQ on hot path, needless allocations/boxing, class where a record/struct fits, not using Span/pooling on hot path
INFO Style/doc/hygiene formatting, naming, missing XML docs, nullable annotations absent (not enabled)

Finding format

[SEVERITY] File.cs:LINE — short title
  Rule: rules/NN-name.md § section
  Evidence: the offending line(s), verbatim
  Impact: one sentence — what executes/leaks/deadlocks, under what input
  Fix: concrete replacement code or action
  Effort: trivial | small | medium | large

Group findings by severity, CRITICAL first. End with: counts per severity, the three highest-leverage fixes, and which checklists/analyzers were run.

Rules index

File Read this when...
rules/01-idioms.md Writing/reviewing any C#: records & record struct, nullable reference types, pattern matching/switch expressions, spans, LINQ discipline, var, expression vs statement, file-scoped namespaces, error handling, modern C# 12–14 features
rules/02-design-api.md Designing types/APIs: nullable reference type discipline, int? over a magic int and using TryParse's bool (its out is 0 on failure), immutability, IDisposable/IAsyncDisposable and using, exceptions, value vs reference types, internal/visibility, DI (the built-in container), options pattern
rules/03-async-concurrency.md Anything async/Task/threads: async-all-the-way, never block (.Result/.Wait()), ConfigureAwait(false) in libraries, CancellationToken flow, async void, Channel<T>, IAsyncEnumerable, TPL/Parallel, thread-safety, ValueTask
rules/04-security.md Any input crossing a trust boundary: SQL (EF Core/Dapper parameterization), legacy serializers (BinaryFormatter removed .NET 9) + JSON TypeNameHandling, command/path injection, ASP.NET Core authn/authz, antiforgery/CORS, Data Protection, crypto (RandomNumberGenerator, AES-GCM), secrets; OWASP .NET
rules/05-performance.md Latency/throughput/memory work: GC (gen/SOH/LOH, server vs workstation), allocation reduction, Span<T>/Memory<T>/ArrayPool, struct/record struct, BenchmarkDotNet, async overhead, Native AOT / trimming, string handling
rules/06-build-tooling-ci.md Setting up or auditing build/CI: SDK/TFM targeting, Directory.Build.props, nullable + warnings-as-errors, Roslyn analyzers (incl. security CA rules), dotnet format, NuGet lockfiles + supply chain (lock mode, source mapping, signed packages, CVE scan), SBOM. **Test strategy lives in sota-testing; this owns .NET build/test mechanics (xUnit/NUnit, Testcontainers).**

Top-10 non-negotiables

  1. No string-built SQL. Parameterize: EF Core LINQ or parameters

(FromSql/interpolated FromSql, never FromSqlRaw/ExecuteSqlRaw with concatenation); Dapper with parameters. Interpolated/concatenated SQL is CRITICAL. (rules/04)

  1. No unsafe deserialization. BinaryFormatter is removed in .NET 9+ (throws);

never reintroduce it or NetDataContractSerializer/LosFormatter/SoapFormatter, and never use Json.NET TypeNameHandling.Auto/All or JsonSerializer with an unrestricted type resolver on untrusted data. Use System.Text.Json with known types. (rules/04)

  1. Async all the way; never block on async. No .Result, .Wait(),

.GetAwaiter().GetResult() on a hot/request path (deadlock + thread-pool starvation). async void only for event handlers. (rules/03)

  1. Flow CancellationToken end to end through async APIs and honor it.

(rules/03)

  1. ConfigureAwait(false) in library code (code with no sync context that

doesn't need to resume on the original context). (rules/03)

  1. Nullable reference types enabled and honored. <Nullable>enable</Nullable>;

don't paper over warnings with the null-forgiving !. (rules/01, rules/02)

  1. Deterministic disposal. Everything IDisposable/IAsyncDisposable is in a

using/await using or owned by a DI-managed lifetime — HttpClient via IHttpClientFactory, not new-per-call. (rules/02)

  1. Crypto uses the right primitives. RandomNumberGenerator (never Random)

for tokens/keys/IVs; AES-GCM (not ECB); no MD5/SHA-1 for security; ASP.NET Core Data Protection for at-rest tokens; never disable TLS cert validation. (rules/04)

  1. AuthN/AuthZ enforced server-side on every non-public endpoint

([Authorize]/policies/endpoint auth), antiforgery for cookie-auth POSTs, CORS locked to known origins. (rules/04)

  1. Analyzers + nullable + lockfile gate CI. TreatWarningsAsErrors,

Roslyn analyzers (incl. security CA rules), dotnet format --verify-no-changes, NuGet locked-mode restore + CVE scan. (rules/06)