mir-backend-dotnetlisted
Install: claude install-skill anantbhandarkar/make-it-right
# /mir-backend-dotnet · Make It Right (.NET runtime)
The middle tier. `mir-backend` decides **what is correct** (any language). The framework module (e.g. `mir-backend-dotnet-aspnetcore`) knows the **library's mechanics**. This tier owns what's true for **all .NET backends because they run on the CLR** — the async model, thread pool, DI container, and object lifetime rules that ASP.NET Core, gRPC services, background workers, and SignalR hubs all inherit.
**Runtime assumed:** .NET 8+ (LTS). Notes apply to .NET 6/7 unless stated. Load order: `mir-backend` → `mir-backend-dotnet` → `<framework module>`.
## The CLR footguns AI walks into (framework-agnostic)
### 1. Sync-over-async — the classic deadlock and thread-pool starvation trap
Calling `.Result`, `.Wait()`, or `.GetAwaiter().GetResult()` on a `Task` or `ValueTask` from synchronous code is the #1 async bug on .NET. In runtimes that have a `SynchronizationContext` (old ASP.NET, WinForms, WPF, Blazor Server), the awaited continuation is posted back to the same context — but the calling thread is blocking that context, so you deadlock. In ASP.NET Core (no sync context) you dodge the deadlock but still **consume a thread-pool thread for the full duration of the I/O wait**, which starves the pool under concurrent load and produces the latency cliff that looks identical to "the server slows down after 30 concurrent users."
```csharp
// WRONG — blocks a thread-pool thread; deadlocks in sync-context runtimes
var result = GetD