<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: agentic.standard.contact</title>
    <description>The latest articles on Forem by agentic.standard.contact (@agentic_standard).</description>
    <link>https://forem.com/agentic_standard</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3943025%2Fb2df42dc-46d5-48a0-9dcf-72470656ff26.jpg</url>
      <title>Forem: agentic.standard.contact</title>
      <link>https://forem.com/agentic_standard</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/agentic_standard"/>
    <language>en</language>
    <item>
      <title>Cursor vs JetBrains Rider for C#/.NET in 2026: which to pay for</title>
      <dc:creator>agentic.standard.contact</dc:creator>
      <pubDate>Mon, 25 May 2026 22:51:00 +0000</pubDate>
      <link>https://forem.com/agentic_standard/cursor-vs-jetbrains-rider-for-cnet-in-2026-which-to-pay-for-79l</link>
      <guid>https://forem.com/agentic_standard/cursor-vs-jetbrains-rider-for-cnet-in-2026-which-to-pay-for-79l</guid>
      <description>&lt;p&gt;**Cursor vs JetBrains Rider for C#/.NET in 2026: which to pay for&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cursor.com/" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://www.jetbrains.com/rider/" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;br&gt;
Senior C#/.NET teams aren't really choosing between Cursor and JetBrains Rider — they're paying for both, configuring them to share state, and refusing to choose. This essay is the honest comparison, the pricing math, and the 90-second setup that stops the two tools from drifting out of sync on the same codebase.&lt;/p&gt;

&lt;p&gt;The wrong question (and the right one)&lt;/p&gt;

&lt;p&gt;Search the .NET subreddit on any given week and you'll find a thread titled something like "Should I drop Rider for Cursor?" The answers split into two camps: "Cursor is the future, Rider is dying" and "Cursor is a glorified VS Code, Rider's debugger alone is worth the licence." Both miss the point.&lt;/p&gt;



&lt;p&gt;Cursor is an AI coder. Rider is an IDE. They overlap on the minimum-viable surface (open file, edit, save, git) and almost nowhere else. Asking which one to pick is like asking whether you should buy a car or a satnav. The right question is: given the way each one breaks first, what configuration lets you keep both for $28 a month?&lt;/p&gt;

&lt;p&gt;What Rider still does that Cursor doesn't (yet)&lt;/p&gt;

&lt;p&gt;These are the things that, as of mid-2026, still take a senior .NET dev twice as long in Cursor as they do in Rider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;************Refactoring across solutions. Rider's Rename, Move type, Extract interface, and Pull members up are still surgically precise on a 200-project solution. Cursor's prompt-driven equivalents work, but they hallucinate references in obscure xUnit fixtures roughly one in twenty times.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;****The debugger. Conditional breakpoints, expression evaluation in mixed managed/native frames, async call-stack reconstruction, decompiled-source stepping into NuGet packages. Cursor relies on VS Code's debugger; for serious .NET debugging you reach for Rider every time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;****Hot Reload + dotnet-watch loops. Better surfaced, better tested, and survives more solution layouts than the VS Code C# Dev Kit equivalent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;****Inspections (R# heritage). Two thousand-plus inspections shipped, scoped per-project, with bulk-fix actions. Cursor will tell you about a code smell when you ask. Rider tells you before you save.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;****Profiling (dotTrace, dotMemory) and database tooling. The integrated tools matter more than they look on paper - they remove the context-switch tax of leaving the IDE.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What Cursor does that Rider can't (yet)&lt;/p&gt;

&lt;p&gt;And the reverse list - things you reach for Cursor for, even if Rider is already open:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;******Multi-file agentic edits. "Add a CancellationToken parameter to every async method in the Application layer and propagate it." Cursor does this in one prompt across 60 files. Rider's R# bulk actions can do the rename; only Cursor can do the cascade and update the call sites.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;****Composer and Background Agents. Long-running tasks ("port this controller to Minimal API endpoints, write the matching xUnit tests, then run them") are Cursor's home turf. Rider has AI Assistant; it doesn't iterate.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;******Semantic codebase search. "Find me the place we authorise admin-only endpoints" returns the right file in Cursor. Rider's Find Usages needs the symbol first.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;``&lt;/strong&gt;MCP servers and .mdc rules. Cursor's directory-scoped rule system and MCP integrations (local databases, custom analysers, vendor APIs) have no Rider equivalent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;****Speed of light for boilerplate. New MediatR command + handler + validator + endpoint + xUnit + Postman example, all consistent with the existing patterns in your repo. Cursor with the right rules ships this in under a minute.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The pricing math&lt;/p&gt;

&lt;p&gt;********Senior .NET developers in the UK and EU bill at £60-£120/hour. Both tools are an irrelevance against that baseline, but for completeness, in 2026 GBP:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      ToolPlanCostWhat you actually get

      CursorPro$20/mo (~£16)Sonnet/Opus access, Composer, MCP, 500 fast requests
      JetBrains RiderPersonal annual$159/yr (~£125)Rider only, all updates
      JetBrains All ProductsPersonal annual$289/yr (~£230)Rider + DataGrip + WebStorm + ReSharper + 9 more
      Both (typical senior)Cursor Pro + Rider~$33/mo (~£26)Single seat, both tools, no compromise
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;£26/month is roughly 13 minutes of senior billing time. The tools save that much before lunch. If your employer doesn't expense both, push back; if you're freelance, both go on Schedule C / your self-assessment as ordinary business expenses. There's no realistic scenario where saving £125/year on Rider makes financial sense.&lt;/p&gt;

&lt;p&gt;**&lt;br&gt;
Heavier tip: if you also use WebStorm or DataGrip, the All Products Pack (£230/year) breaks even at two JetBrains tools and includes Rider. Most senior .NET devs already qualify.&lt;/p&gt;

&lt;p&gt;Why running both is dangerous (without configuration)&lt;/p&gt;



&lt;p&gt;Here is the failure mode nobody warns you about: context drift.&lt;/p&gt;

&lt;p&gt;You refactor a domain entity in Rider. Six minutes later, you ask Cursor to add a new MediatR handler that uses it. Cursor's snapshot of the codebase is from before the refactor, because you haven't reopened the relevant files in the Cursor window. It writes the handler against the old shape. You don't notice until tests fail, or worse, until the analyser inspection fires three commits later in CI.&lt;/p&gt;

&lt;p&gt;The mirror failure: Cursor agentically edits 14 files in one prompt; Rider's local R# inspection cache is stale, so half the new code lights up red until you trigger a solution-wide rebuild. New engineers on the team assume the AI broke something. Trust in the tools erodes.&lt;/p&gt;

&lt;p&gt;Both failures have the same root cause: the two tools share a working tree but not a state model. Fix that and you stop choosing.&lt;/p&gt;

&lt;p&gt;The configuration that makes them play nice&lt;/p&gt;

&lt;p&gt;Three things, in this order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;****&lt;code&gt;&lt;/code&gt;One repo, one solution file, both tools opened on the same root. Don't run them on different working copies. Both honour .gitignore the same way; both index .sln files; neither writes index garbage into version control.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;``&lt;/strong&gt;A shared .cursor/rules/ directory. The rules tell Cursor what your house style is - Result over throw, Scoped over Singleton for repository services, AsNoTracking for read-only EF queries, etc. Rider's R# inspections enforce the same conventions from the IDE side. Both tools read the same source of truth: your code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;``&lt;/strong&gt;``A LEARNING_LOG.md at repo root. Every architectural decision goes here as a one-line ADR. Cursor reads it on session start (via persistence.mdc); humans use it when onboarding a new dev. The Learning Log is the bridge between Rider's static analysis and Cursor's stateless prompt-time context.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://agenticstandardcontact-byte.github.io/agentic-architect/" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;br&gt;
This is not a hypothetical setup. It's the exact pattern the Agentic Architect kit was built to enforce, originally because we kept hitting the context-drift problem on a real client codebase. Senior teams ship the kit, point both tools at the same root, and the drift stops.&lt;/p&gt;

&lt;p&gt;A 90-second setup&lt;/p&gt;

&lt;p&gt;Assuming both tools are installed and licensed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  1. Open the same solution root in both
&lt;/h1&gt;

&lt;p&gt;cd MyDotnetSolution.sln&lt;/p&gt;

&lt;h1&gt;
  
  
  2. Add scoped Cursor rules (or grab arch-core-lite.mdc free)
&lt;/h1&gt;

&lt;p&gt;mkdir -p .cursor/rules&lt;br&gt;
curl -L &lt;a href="https://github.com/agenticstandardcontact-byte/agentic-architect/raw/main/arch-core-lite.mdc" rel="noopener noreferrer"&gt;https://github.com/agenticstandardcontact-byte/agentic-architect/raw/main/arch-core-lite.mdc&lt;/a&gt; \&lt;br&gt;
  -o .cursor/rules/arch-core.mdc&lt;/p&gt;

&lt;h1&gt;
  
  
  3. Seed a Learning Log Cursor will re-read on session start
&lt;/h1&gt;

&lt;p&gt;cat &amp;gt; LEARNING_LOG.md &amp;lt;&amp;lt;EOF&lt;/p&gt;

&lt;h1&gt;
  
  
  Learning Log
&lt;/h1&gt;

&lt;h2&gt;
  
  
  ADR-001 - Result over throw for business failures
&lt;/h2&gt;

&lt;h2&gt;
  
  
  ADR-002 - Scoped lifetime for DbContext, never captured by Singletons
&lt;/h2&gt;

&lt;h2&gt;
  
  
  ADR-003 - AsNoTracking on every read-only IQueryable
&lt;/h2&gt;

&lt;p&gt;EOF&lt;/p&gt;

&lt;h1&gt;
  
  
  4. Commit the conventions
&lt;/h1&gt;

&lt;p&gt;git add .cursor/ LEARNING_LOG.md&lt;br&gt;
git commit -m "chore: align Cursor + Rider on house style"&lt;/p&gt;

&lt;p&gt;**&lt;br&gt;
Open Cursor and ask: "Hydrate the Learning Log from the current codebase." It will scan and propose ADRs for the patterns it detects. Accept the ones you actually use; reject the rest. Now both tools agree.&lt;/p&gt;

&lt;p&gt;Where each one breaks first&lt;/p&gt;

&lt;p&gt;*****************&lt;strong&gt;&lt;em&gt;``&lt;/em&gt;&lt;/strong&gt;*Even with the configuration above, both tools have edges. Use the right one for the job:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      TaskReach forWhy

      Renaming a public type used in 80 filesRiderSymbol-aware refactor, won't miss xUnit fixtures or attribute references
      Adding the same field + constructor + DI registration across 12 servicesCursorAgentic loop with Composer; Rider can't iterate on intent
      Async call-stack debugging into a NuGet packageRiderDecompiled-source stepping; Cursor relies on the VS Code debugger
      Porting a controller to Minimal API + tests + Swagger docCursorMulti-file edit + iterate-until-tests-pass; pure prompt territory
      Inspecting why a Scoped service is captured by a SingletonRiderdotnet-di.mdc in Cursor catches it post-hoc; Rider catches it on hover
      Wiring a new MCP server that queries your local SQLiteCursorRider doesn't speak MCP yet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The honest verdict&lt;/p&gt;

&lt;p&gt;**&lt;br&gt;
If you bill at senior rates and you're staring at the £125/year Rider question: pay for both. If your employer is asking which to expense for a team of 10: expense both. If you're a junior starting your first .NET role: get Rider via the JetBrains free .NET Foundation programme or your employer's seat, and run Cursor Pro on your own card while you're learning. The tools are complementary; the only configuration that fails is having neither.&lt;/p&gt;

&lt;p&gt;Where this article ends and the kit begins: the configuration above is necessary but not sufficient. Without scoped rules and a Learning Log, both tools regress to the public-internet average of a .NET codebase - exceptions for business failures, EF Core in your domain layer, DbContext captured by Singletons. The tools are the engine. The rules are the steering.&lt;/p&gt;

&lt;p&gt;Pair with the rest of the series&lt;/p&gt;

&lt;p&gt;&lt;a href="//01-the-context-tax.html"&gt;&lt;/a&gt;&lt;a href="//02-scoped-singleton-di-bug.html"&gt;&lt;/a&gt;&lt;a href="//04-cursor-result-not-throw.html"&gt;&lt;/a&gt;&lt;br&gt;
If this is the first essay you've read here, the three foundational ones are: The Context Tax (why Cursor forgets your architecture every morning), The Scoped→Singleton DI bug (the .NET-specific failure mode that ships silently), and Teach Cursor Result instead of throwing (stop the AI from regressing your error model on every prompt). All three apply equally whether you run Cursor solo or alongside Rider.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://agenticstandardcontact-byte.github.io/agentic-architect/blog/05-cursor-vs-rider-dotnet.html" rel="noopener noreferrer"&gt;https://agenticstandardcontact-byte.github.io/agentic-architect/blog/05-cursor-vs-rider-dotnet.html&lt;/a&gt;. Part of the &lt;a href="https://agenticstandardcontact-byte.github.io/agentic-architect/" rel="noopener noreferrer"&gt;Agentic Architect&lt;/a&gt; persistence kit for Cursor + .NET.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>ai</category>
      <category>cursor</category>
    </item>
    <item>
      <title>This week in Cursor + .NET — 5 rules + 4 essays (week ending May 24, 2026)</title>
      <dc:creator>agentic.standard.contact</dc:creator>
      <pubDate>Sun, 24 May 2026 11:43:24 +0000</pubDate>
      <link>https://forem.com/agentic_standard/this-week-in-cursor-net-5-rules-4-essays-week-ending-may-24-2026-3fn5</link>
      <guid>https://forem.com/agentic_standard/this-week-in-cursor-net-5-rules-4-essays-week-ending-may-24-2026-3fn5</guid>
      <description>&lt;p&gt;&lt;em&gt;Every weekday a single, opinionated rule for senior C#/.NET engineers using Cursor. Here's the full week in one read — canonical posts live on &lt;a href="https://agenticstandardcontact-byte.github.io/agentic-architect/blog/" rel="noopener noreferrer"&gt;the Agentic Architect blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  New essays this week
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://agenticstandardcontact-byte.github.io/agentic-architect/blog/04-cursor-result-not-throw.html" rel="noopener noreferrer"&gt;Teach Cursor Result&amp;lt;T&amp;gt; instead of throwing&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Thu 21 May · C# patterns&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Stop the AI from undoing your Result/ErrorOr error model with throw and null on every new prompt.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://agenticstandardcontact-byte.github.io/agentic-architect/blog/03-cursor-hallucination-loop-breaker.html" rel="noopener noreferrer"&gt;Seven words that stop Cursor hallucination loops&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Wed 20 May · Cursor rules&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The correction spiral — and the circuit-breaker rule that ends it before you type the stop phrase.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://agenticstandardcontact-byte.github.io/agentic-architect/blog/02-scoped-singleton-di-bug.html" rel="noopener noreferrer"&gt;The Scoped→Singleton DI bug your AI just suggested (and how to catch it)&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Tue 19 May · .NET DI&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The .NET lifetime bug that ships to production silently — and the one Cursor rule that catches it before merge.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://agenticstandardcontact-byte.github.io/agentic-architect/blog/01-the-context-tax.html" rel="noopener noreferrer"&gt;The Context Tax: Why every Cursor session costs you 15 minutes&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Mon 18 May · Architecture&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The hidden cost senior engineers pay every morning — and a four-rule architecture for eliminating it.&lt;/p&gt;

&lt;h2&gt;
  
  
  5 daily senior rules
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Rule 11: Rethrow, Don't throw ex
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Sun 24 May&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;throw ex resets the stack trace. throw preserves it. Cursor gets this wrong about 40 percent of the time when generating catch blocks. Rewrite any naked throw ex to throw unless the exception has been explicitly wrapped.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://agenticstandardcontact-byte.github.io/agentic-architect/blog/#2026-05-24" rel="noopener noreferrer"&gt;→ Permalink on the blog&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Rule 10: AsNoTracking for Reads
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Sat 23 May&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Every read-only EF Core query should call AsNoTracking. Add a rule that recognises query methods returning DTOs (not entities) and inserts the call. Cursor never does this by default and your read perf degrades silently across releases.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://agenticstandardcontact-byte.github.io/agentic-architect/blog/#2026-05-23" rel="noopener noreferrer"&gt;→ Permalink on the blog&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Rule 9: Scoped Capture in Singleton
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Fri 22 May&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The single most expensive .NET runtime bug: a Singleton holding a Scoped service. Cursor cheerfully writes this without warning. Audit constructor parameters of any class registered as Singleton — if any are typically Scoped (DbContext, repositories, MediatR sender), flag it before merge.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://agenticstandardcontact-byte.github.io/agentic-architect/blog/#2026-05-22" rel="noopener noreferrer"&gt;→ Permalink on the blog&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Rule 8: CancellationToken Propagation
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Thu 21 May&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Every async method in your codebase should accept and forward a CancellationToken. Make it a rule that any new async signature without one is flagged. Stops the AI from quietly losing cancellation half-way down a call chain.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://agenticstandardcontact-byte.github.io/agentic-architect/blog/#2026-05-21" rel="noopener noreferrer"&gt;→ Permalink on the blog&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Rule 2: Persistence Boundaries
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Wed 20 May&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Never let the AI write database logic in your Controllers. Enforce a strict boundary where all IQueryable access stays in the Infrastructure layer. This keeps your business logic "pure" and readable for the LLM.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://agenticstandardcontact-byte.github.io/agentic-architect/blog/#2026-05-20" rel="noopener noreferrer"&gt;→ Permalink on the blog&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Try one rule before you trust the whole kit
&lt;/h2&gt;

&lt;p&gt;The free &lt;strong&gt;&lt;a href="https://github.com/agenticstandardcontact-byte/agentic-architect/blob/main/arch-core-lite.mdc?utm_source=devto&amp;amp;utm_medium=weekly_digest&amp;amp;utm_campaign=free_sample" rel="noopener noreferrer"&gt;&lt;code&gt;arch-core-lite.mdc&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt; is one drop-in Cursor rule that ends the morning re-explanation ritual. Install in 60 seconds, see whether Cursor actually remembers your DI lifetimes, and decide for yourself whether the full kit is worth £19.99.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Free sample:&lt;/strong&gt; &lt;a href="https://github.com/agenticstandardcontact-byte/agentic-architect/blob/main/arch-core-lite.mdc?utm_source=devto&amp;amp;utm_medium=weekly_digest&amp;amp;utm_campaign=free_sample" rel="noopener noreferrer"&gt;&lt;code&gt;arch-core-lite.mdc&lt;/code&gt; on GitHub&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full kit (£19.99, one-time):&lt;/strong&gt; &lt;a href="https://agenticarchitect.gumroad.com/l/dotnet-persistence-kit?utm_source=devto&amp;amp;utm_medium=weekly_digest&amp;amp;utm_campaign=paid_kit" rel="noopener noreferrer"&gt;Agentic Architect on Gumroad&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Daily rules feed:&lt;/strong&gt; &lt;a href="https://agenticstandardcontact-byte.github.io/agentic-architect/blog/?utm_source=devto&amp;amp;utm_medium=weekly_digest&amp;amp;utm_campaign=blog_index" rel="noopener noreferrer"&gt;https://agenticstandardcontact-byte.github.io/agentic-architect/blog/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Canonical home for everything in this digest: &lt;a href="https://agenticstandardcontact-byte.github.io/agentic-architect/blog/" rel="noopener noreferrer"&gt;https://agenticstandardcontact-byte.github.io/agentic-architect/blog/&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>ai</category>
      <category>cursor</category>
    </item>
    <item>
      <title>This week in Cursor + .NET — 3 rules + 4 essays (week ending May 22, 2026)</title>
      <dc:creator>agentic.standard.contact</dc:creator>
      <pubDate>Fri, 22 May 2026 21:32:35 +0000</pubDate>
      <link>https://forem.com/agentic_standard/this-week-in-cursor-net-3-rules-4-essays-week-ending-may-22-2026-29i5</link>
      <guid>https://forem.com/agentic_standard/this-week-in-cursor-net-3-rules-4-essays-week-ending-may-22-2026-29i5</guid>
      <description>&lt;p&gt;&lt;em&gt;Every weekday a single, opinionated rule for senior C#/.NET engineers using Cursor. Here's the full week in one read — canonical posts live on &lt;a href="https://agenticstandardcontact-byte.github.io/agentic-architect/blog/" rel="noopener noreferrer"&gt;the Agentic Architect blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  New essays this week
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://agenticstandardcontact-byte.github.io/agentic-architect/blog/04-cursor-result-not-throw.html" rel="noopener noreferrer"&gt;Teach Cursor Result&amp;lt;T&amp;gt; instead of throwing&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Thu 21 May · C# patterns&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Stop the AI from undoing your Result/ErrorOr error model with throw and null on every new prompt.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://agenticstandardcontact-byte.github.io/agentic-architect/blog/03-cursor-hallucination-loop-breaker.html" rel="noopener noreferrer"&gt;Seven words that stop Cursor hallucination loops&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Wed 20 May · Cursor rules&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The correction spiral — and the circuit-breaker rule that ends it before you type the stop phrase.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://agenticstandardcontact-byte.github.io/agentic-architect/blog/02-scoped-singleton-di-bug.html" rel="noopener noreferrer"&gt;The Scoped→Singleton DI bug your AI just suggested (and how to catch it)&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Tue 19 May · .NET DI&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The .NET lifetime bug that ships to production silently — and the one Cursor rule that catches it before merge.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://agenticstandardcontact-byte.github.io/agentic-architect/blog/01-the-context-tax.html" rel="noopener noreferrer"&gt;The Context Tax: Why every Cursor session costs you 15 minutes&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Mon 18 May · Architecture&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The hidden cost senior engineers pay every morning — and a four-rule architecture for eliminating it.&lt;/p&gt;

&lt;h2&gt;
  
  
  3 daily senior rules
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Rule 9: Scoped Capture in Singleton
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Fri 22 May&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The single most expensive .NET runtime bug: a Singleton holding a Scoped service. Cursor cheerfully writes this without warning. Audit constructor parameters of any class registered as Singleton — if any are typically Scoped (DbContext, repositories, MediatR sender), flag it before merge.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://agenticstandardcontact-byte.github.io/agentic-architect/blog/#2026-05-22" rel="noopener noreferrer"&gt;→ Permalink on the blog&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Rule 8: CancellationToken Propagation
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Thu 21 May&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Every async method in your codebase should accept and forward a CancellationToken. Make it a rule that any new async signature without one is flagged. Stops the AI from quietly losing cancellation half-way down a call chain.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://agenticstandardcontact-byte.github.io/agentic-architect/blog/#2026-05-21" rel="noopener noreferrer"&gt;→ Permalink on the blog&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Rule 2: Persistence Boundaries
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Wed 20 May&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Never let the AI write database logic in your Controllers. Enforce a strict boundary where all IQueryable access stays in the Infrastructure layer. This keeps your business logic "pure" and readable for the LLM.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://agenticstandardcontact-byte.github.io/agentic-architect/blog/#2026-05-20" rel="noopener noreferrer"&gt;→ Permalink on the blog&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Try one rule before you trust the whole kit
&lt;/h2&gt;

&lt;p&gt;The free &lt;strong&gt;&lt;a href="https://github.com/agenticstandardcontact-byte/agentic-architect/blob/main/arch-core-lite.mdc?utm_source=devto&amp;amp;utm_medium=weekly_digest&amp;amp;utm_campaign=free_sample" rel="noopener noreferrer"&gt;&lt;code&gt;arch-core-lite.mdc&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt; is one drop-in Cursor rule that ends the morning re-explanation ritual. Install in 60 seconds, see whether Cursor actually remembers your DI lifetimes, and decide for yourself whether the full kit is worth £19.99.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Free sample:&lt;/strong&gt; &lt;a href="https://github.com/agenticstandardcontact-byte/agentic-architect/blob/main/arch-core-lite.mdc?utm_source=devto&amp;amp;utm_medium=weekly_digest&amp;amp;utm_campaign=free_sample" rel="noopener noreferrer"&gt;&lt;code&gt;arch-core-lite.mdc&lt;/code&gt; on GitHub&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full kit (£19.99, one-time):&lt;/strong&gt; &lt;a href="https://agenticarchitect.gumroad.com/l/dotnet-persistence-kit?utm_source=devto&amp;amp;utm_medium=weekly_digest&amp;amp;utm_campaign=paid_kit" rel="noopener noreferrer"&gt;Agentic Architect on Gumroad&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Daily rules feed:&lt;/strong&gt; &lt;a href="https://agenticstandardcontact-byte.github.io/agentic-architect/blog/?utm_source=devto&amp;amp;utm_medium=weekly_digest&amp;amp;utm_campaign=blog_index" rel="noopener noreferrer"&gt;https://agenticstandardcontact-byte.github.io/agentic-architect/blog/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Canonical home for everything in this digest: &lt;a href="https://agenticstandardcontact-byte.github.io/agentic-architect/blog/" rel="noopener noreferrer"&gt;https://agenticstandardcontact-byte.github.io/agentic-architect/blog/&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>ai</category>
      <category>cursor</category>
    </item>
    <item>
      <title>Teach Cursor Result&lt;T&gt; Instead of Throwing</title>
      <dc:creator>agentic.standard.contact</dc:creator>
      <pubDate>Thu, 21 May 2026 22:35:25 +0000</pubDate>
      <link>https://forem.com/agentic_standard/teach-cursor-result-instead-of-throwing-5f82</link>
      <guid>https://forem.com/agentic_standard/teach-cursor-result-instead-of-throwing-5f82</guid>
      <description>&lt;p&gt;Teach Cursor Result instead of throwing&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;If your team already models failures as Result&amp;lt;T&amp;gt;, ErrorOr&amp;lt;T&amp;gt;, or railway-style responses, Cursor will still reach for throw and null on the next prompt. That is not malice — it is training bias. Here is why it happens, what it costs, and how scoped rules teach the AI to match the error model you already paid for.


## 
The default the model learned


``
Most C# examples on the public internet — tutorials, StackOverflow, even Microsoft docs samples — use exceptions for business failures and null for "not found". Ask Cursor to add an endpoint that rejects duplicate orders and you will get something like:


```

```
public async Task&amp;lt;OrderDto&amp;gt; CreateAsync(CreateOrderRequest request, CancellationToken ct)
{
    var existing = await _db.Orders.FirstOrDefaultAsync(o =&amp;gt; o.Reference == request.Reference, ct);
    if (existing is not null)
        throw new ConflictException("Order reference already exists");

    var order = Order.Create(request);
    await _db.SaveChangesAsync(ct);
    return order.ToDto();
}


``
Readable. Familiar. Architecturally wrong if your Application layer already returns Result&amp;lt;OrderDto&amp;gt; and your API maps errors to ProblemDetails without catching domain exceptions in every controller.


## 
What breaks when the AI throws anyway


- ****Inconsistent HTTP semantics. Some endpoints return 409 from a mapper; others leak 500s because an exception bubbled past the pipeline you thought was uniform.

- ****````Untestable handlers. Unit tests for MediatR handlers should assert on result.IsError, not Assert.ThrowsAsync for business cases.

- ****``Hidden control flow. null checks and thrown exceptions are invisible in signatures. The AI (and the next human) cannot see failure modes without reading the body.

- ****Retry poison. Transient infrastructure failures belong in exceptions; business rule violations do not. Mixing them trains operators to retry non-retryable faults.



Senior teams moved to explicit results precisely to make failure visible. The AI undoing that in one autocomplete is expensive.


## 
What good looks like in a MediatR codebase


Same feature, result-shaped:


```

```
public async Task&amp;lt;Result&amp;lt;OrderDto&amp;gt;&amp;gt; Handle(CreateOrderCommand cmd, CancellationToken ct)
{
    var exists = await _orders.ExistsByReferenceAsync(cmd.Reference, ct);
    if (exists)
        return Result.Conflict&amp;lt;OrderDto&amp;gt;("Order reference already exists");

    var create = Order.Create(cmd);
    if (create.IsError)
        return create.Errors;

    await _orders.AddAsync(create.Value, ct);
    return create.Value.ToDto();
}


The endpoint stays thin:


```

```
app.MapPost("/orders", async (CreateOrderCommand cmd, ISender sender, CancellationToken ct) =&amp;gt;
{
    var result = await sender.Send(cmd, ct);
    return result.Match(Results.Created, Results.Problem);
});


No try/catch for "customer not found". No null return that the caller forgets to check. The signature documents the contract.


## 
Why telling it once does not stick


``
You paste "we use Result pattern, do not throw for business errors" into chat. It complies for that file. Three prompts later, on a validator or a repository method, it throws NotFoundException again because:


1. ****The local context is a file that still has legacy throws from 2019.

1. ****The prompt did not mention ErrorOr vs Result vs FluentResults — so it picks whichever type name it saw most recently in training.

1. ****There is no enforced rule on Application-layer files — only a memory in a chat you closed yesterday.



[](01-the-context-tax.html)
This is the same persistence problem as the Context Tax, applied to error modelling. You need the convention to reload when the relevant layer opens — not when you remember to lecture the model.


## 
The rule contract (what to encode)


A useful Cursor rule for result-shaped codebases does not need to mandate a specific NuGet package. It should:


- ****``````

Detect the house style — if the project already references FluentResults, ErrorOr, or an internal Result&amp;lt;T&amp;gt;, match that type exactly.

- ****

````Forbid null-as-missing on public Application APIs when Results are in use — return NotFound errors instead of null.

- ****Reserve exceptions for truly exceptional cases: programmer errors, cancelled operations, infrastructure timeouts — not "email already taken".

- ****Require mapping at the edge — handlers return Results; endpoints map them. No throws in Minimal API lambdas for domain failures.

- ****Keep validators ahead of handlers — FluentValidation failures should become Results before handler logic runs (pairs well with MediatR pipelines).



``[](https://agenticstandardcontact-byte.github.io/agentic-architect/)
arch-core.mdc in the Agentic Architect kit encodes the "match existing Result / ErrorOr / OneOf patterns" clause on Application and API-adjacent files. It is the boundary guardian applied to control flow — not just folder placement.


## 
A prompt you can use today (before the full kit)


Until rules are committed, pin this at the top of any handler or endpoint edit:


&amp;gt; Business failures are Result errors, not exceptions. Match the Result/ErrorOr type already used in this project. Map to HTTP at the API boundary only.


````


Short. Boring. Repeatable. It cuts throw regressions roughly in half in my experience — but discipline still decays without scoped .mdc files and a LEARNING_LOG.md entry the model reads on session start.


## 
Log the decision once, enforce it forever


When you adopt Results team-wide, add one Learning Log line the persistence engine can re-hydrate:




```plaintext

```


## ADR-014 — Application errors are Results
- Handlers return Result&amp;lt;T&amp;gt; / ErrorOr&amp;lt;T&amp;gt;; no throw for business rules.
- API maps via Match / ToProblemDetails; controllers stay thin.
- Exceptions: infrastructure only (timeouts, corruption).


``
Next Monday, the model sees the ADR before it suggests throw new InvalidOperationException("duplicate") in a handler that has returned Results for six months.


## 
Pair with the other failure modes


[](02-scoped-singleton-di-bug.html)[](03-cursor-hallucination-loop-breaker.html)****
Result discipline does not replace DI lifetime audits (Scoped→Singleton capture) or hallucination breakers (seven-word stop phrase). It addresses a third failure mode: silent style regression — code that compiles, looks professional, and slowly erodes the conventions your team chose on purpose.

---

*Originally published at [https://agenticstandardcontact-byte.github.io/agentic-architect/blog/04-cursor-result-not-throw.html](https://agenticstandardcontact-byte.github.io/agentic-architect/blog/04-cursor-result-not-throw.html). Part of the [Agentic Architect](https://agenticstandardcontact-byte.github.io/agentic-architect/) persistence kit for Cursor + .NET.*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>ai</category>
      <category>cursor</category>
    </item>
    <item>
      <title>Seven Words That Stop Cursor Hallucination Loops</title>
      <dc:creator>agentic.standard.contact</dc:creator>
      <pubDate>Thu, 21 May 2026 22:25:22 +0000</pubDate>
      <link>https://forem.com/agentic_standard/seven-words-that-stop-cursor-hallucination-loops-1mf5</link>
      <guid>https://forem.com/agentic_standard/seven-words-that-stop-cursor-hallucination-loops-1mf5</guid>
      <description>&lt;p&gt;Seven words that stop Cursor hallucination loops&lt;/p&gt;

&lt;p&gt;**&lt;br&gt;
You have seen this spiral: the AI invents an API that does not exist, you correct it, it apologises and invents a different wrong API, you correct it again, and twenty minutes later you are debugging the assistant instead of your code. The fix is not a longer system prompt. It is a hard stop — seven words — and optionally a rule that enforces the same behaviour before you have to type them.&lt;/p&gt;

&lt;p&gt;What a hallucination loop looks like&lt;/p&gt;

&lt;p&gt;It usually starts on a method the model half-remembers. You ask Cursor to wire up a handler against an interface you know exists. It returns something plausible:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;await _mediator.Send(new ProcessOrderCommand(id), cancellationToken);&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

Clean. Confident. Wrong — ProcessOrderCommand takes a Guid and a CustomerContext, not an int. You point that out. The model agrees, rewrites the call, and quietly changes the command constructor to match its mistake. You correct the constructor. It moves the validation into a private method that calls _db.ValidateOrderAsync — a method that does not exist and never will.


****
Each turn sounds cooperative. Each turn drifts further from the file on disk. That is a hallucination loop: high confidence, low grounding, escalating wrongness.


## 
Why "be more careful" never works


**********
Generic instructions — think step by step, double-check your work, do not hallucinate — do not change the failure mode. The model is already trying to satisfy your last correction. The problem is not effort; it is missing evidence. It is answering from pattern completion instead of re-opening the source.


****
Longer preambles make it worse. You burn tokens on politeness while the model still has not re-read the interface definition three files away. What you need is not encouragement. You need a circuit breaker — the same pattern you use when a retry policy should stop calling a failing downstream service.


## 
The seven words


When you recognise the loop — two failed fixes on the same symbol, invented members, or repeated apologies without a file quote — paste this and nothing else:


&amp;gt; Stop. Re-read the file. Ask me.


Seven words. No preamble. No new requirements. The phrase does three things:


1. ****Stop — halts the current generation strategy (more code is the wrong move).

1. ****Re-read the file — forces grounding in the actual AST, not the last assistant message.

1. ****Ask me — moves uncertainty to a targeted question instead of another guess.





````
In practice the next reply is slower and shorter. It quotes real members. It asks whether you meant ProcessOrderCommand or the older SubmitOrderCommand before touching DI registration. That is the behaviour you want from a senior pair — not another speculative patch.


## 
When to trip the breaker


Use it when any of these are true:


- ****The same error message or missing member appears twice after you corrected it once.

- The model cites APIs, packages, or config keys you cannot find with ripgrep.

- It refactors unrelated files to "fix" a local compile error.

- It agrees with you, then contradicts its own fix in the next message.



******
Do not use it for slow but steady progress — one wrong import fixed on the second try is normal. The breaker is for spirals, not single mistakes.


## 
From manual phrase to automatic rule


``[](https://agenticstandardcontact-byte.github.io/agentic-architect/)
Typing the seven words works, but you should not have to remember them at 17:30 on a Thursday. That is what bug-breaker.mdc is for in the Agentic Architect kit: a scoped rule that loads on code files and encodes the same contract:


- ****After two failed attempts on the same problem in one session, stop proposing code.

- Re-read the current file and any directly imported types before continuing.

- Surface one specific question — with line references — instead of guessing.



Because it is directory-scoped like the other kit rules, it does not inflate every prompt. It sits quiet until you are actually editing implementation code — exactly where loops hurt.


## 
How it pairs with persistence


Hallucination loops are worse when the model has no memory of yesterday's decision. You explain that orders flow through Mediator, not direct repository calls. It forgets by Friday and loops on a repository shortcut again.


**````

**
The circuit breaker stops the session spiral. persistence.mdc plus LEARNING_LOG.md stops the week-over-week spiral by writing decisions the model re-hydrates on session start. Together they address two different half-lives of the same problem — which is why the kit ships four rules, not one mega-prompt.


## 
What this does not fix


[](01-the-context-tax.html)
Honest limits: the breaker will not save a prompt that contradicts your architecture, and it will not replace code review. It also cannot fix context rot at Monday stand-up — that is the Context Tax problem, solved with persistence and scoped boundaries, not a stop phrase.


**
What it does fix is the most expensive hour in AI-assisted development: the hour you spend as the human circuit breaker while the model confidently ships fiction.

---

*Originally published at [https://agenticstandardcontact-byte.github.io/agentic-architect/blog/03-cursor-hallucination-loop-breaker.html](https://agenticstandardcontact-byte.github.io/agentic-architect/blog/03-cursor-hallucination-loop-breaker.html). Part of the [Agentic Architect](https://agenticstandardcontact-byte.github.io/agentic-architect/) persistence kit for Cursor + .NET.*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>ai</category>
      <category>cursor</category>
    </item>
    <item>
      <title>The Scoped Singleton DI Bug Your AI Just Suggested</title>
      <dc:creator>agentic.standard.contact</dc:creator>
      <pubDate>Thu, 21 May 2026 22:23:27 +0000</pubDate>
      <link>https://forem.com/agentic_standard/the-scoped-singleton-di-bug-your-ai-just-suggested-jo0</link>
      <guid>https://forem.com/agentic_standard/the-scoped-singleton-di-bug-your-ai-just-suggested-jo0</guid>
      <description>&lt;p&gt;The Scoped→Singleton DI bug your AI just suggested (and how to catch it)&lt;/p&gt;

&lt;p&gt;Of all the bugs that ship to production silently, the captured-dependency lifetime bug is one of the most expensive. It compiles. It passes your tests. It runs fine in dev. Then in production, under load, it starts corrupting data across requests. And AI assistants suggest it constantly. Here's why — and the one Cursor rule that catches it before merge.&lt;/p&gt;

&lt;p&gt;The bug, in 30 lines&lt;/p&gt;

&lt;p&gt;``&lt;br&gt;
You ask Cursor to add caching to OrderService. It gives you this:&lt;/p&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;plaintext&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;br&gt;
// OrderService.cs&lt;br&gt;
public class OrderService : IOrderService&lt;br&gt;
{&lt;br&gt;
    private readonly IMemoryCache _cache;&lt;br&gt;
    private readonly OrderDbContext _db;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public OrderService(IMemoryCache cache, OrderDbContext db)
{
    _cache = cache;
    _db = db;
}

public async Task&amp;lt;Order?&amp;gt; GetAsync(int id, CancellationToken ct)
{
    if (_cache.TryGetValue(id, out Order? cached)) return cached;

    var order = await _db.Orders.FindAsync(new object[] { id }, ct);
    if (order is not null) _cache.Set(id, order, TimeSpan.FromMinutes(5));
    return order;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;// Program.cs&lt;br&gt;
builder.Services.AddDbContext(...);&lt;br&gt;
builder.Services.AddScoped();&lt;br&gt;
builder.Services.AddMemoryCache(); // ← registers IMemoryCache as Singleton&lt;/p&gt;

&lt;p&gt;Looks correct. Compiles. Tests pass. Shipped.&lt;/p&gt;

&lt;p&gt;What actually happens at runtime&lt;/p&gt;

&lt;p&gt;&lt;code&gt;****&lt;/code&gt;****&lt;br&gt;
IMemoryCache is registered as Singleton — one instance for the entire app's lifetime. OrderService is registered as Scoped — one instance per HTTP request.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;plaintext&lt;br&gt;
On its own, that's fine. The problem is what you cached: an Order entity, which is in turn attached to OrderDbContext — also Scoped. The cache, alive for the lifetime of the application, now holds a reference to an entity attached to a DbContext that was disposed when the original request ended.&lt;/p&gt;

&lt;p&gt;``&lt;br&gt;
Now request #2 comes in. It hits the cache, gets the order, mutates a property. Then request #3 hits the cache, sees the mutation, and decides to write something else based on it. Then request #4 wakes up the entity's dispose-tracking and explodes with ObjectDisposedException — but only sometimes, depending on the GC pressure that day.&lt;/p&gt;

&lt;p&gt;Welcome to the longest debugging session of your year.&lt;/p&gt;

&lt;p&gt;Why AI assistants suggest this constantly&lt;/p&gt;

&lt;p&gt;The patterns the AI has seen most often in its training data — short examples, blog tutorials, StackOverflow answers — almost always omit DI registration. A typical "caching with IMemoryCache" snippet looks like ten lines, with no reference to where the service is registered or with what lifetime.&lt;/p&gt;




&lt;p&gt;The AI learned the surface pattern ("inject IMemoryCache, call .Set") without the surrounding constraint ("…unless the consumer is Scoped and the cached value graph reaches into Scoped infrastructure"). When you ask it to add caching to your codebase, it pattern-matches against the surface form. The constraint is invisible to it.&lt;/p&gt;




&lt;p&gt;This isn't a "the AI is dumb" critique. Most senior developers ship this exact bug at least once. The patterns in the wild teach the wrong lesson.&lt;/p&gt;

&lt;p&gt;The five lifetime traps to teach the AI&lt;/p&gt;

&lt;p&gt;If you're going to enforce one set of rules on AI-suggested .NET code, make it these:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Scoped or Transient injected into Singleton&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;``&lt;br&gt;
The classic. A Singleton constructor takes IRepository (Scoped). The Singleton captures it forever. Requests share state. Data corrupts.&lt;/p&gt;




&lt;p&gt;The rule: when adding a constructor parameter, check the parameter type's registered lifetime. If the consumer is Singleton and the parameter is Scoped/Transient, refuse and surface the issue.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;DbContext captured by anything Singleton&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;****&lt;/code&gt;&lt;br&gt;
Special case of #1 but worth its own callout. DbContext is always Scoped — it has to be, it tracks per-request state. Any Singleton that captures a DbContext is a bug. If you need DB access from a Singleton, inject IServiceScopeFactory and create a scope per operation.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Cached entities still attached to a DbContext&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The bug from the example. The cache outlives the DbContext, but holds a graph that depends on it.&lt;/p&gt;

&lt;p&gt;****``&lt;br&gt;
The rule: what goes into long-lived caches must be either (a) AsNoTracking()'d, (b) projected to a DTO, or (c) detached explicitly.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;4. HttpClient instantiated with new


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A long-running app that does new HttpClient() on every call leaks sockets — eventually exhausting the connection pool. Even worse: a Singleton that captures a single HttpClient reuses DNS forever.&lt;/p&gt;






&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The rule: always inject IHttpClientFactory and call CreateClient(name). Never new HttpClient() outside of one-shot scripts.


### 
5. Hosted services touching Scoped dependencies directly


``
IHostedService is Singleton-by-construction. Inject a Scoped repo into one and it'll be alive for the lifetime of the process — every "scoped" operation will share state. Worse, the DbContext will leak.


****``````


The rule: in any BackgroundService or IHostedService, never inject Scoped dependencies directly. Inject IServiceScopeFactory and create a scope per unit of work.


## 
The Cursor rule that catches all five


``[](https://agenticstandardcontact-byte.github.io/agentic-architect/)``

````
The dotnet-di.mdc rule in Agentic Architect codifies the above. When Cursor is editing a file where DI is happening — Program.cs, Startup.cs, ServiceCollectionExtensions.cs, any class constructor — the rule activates and audits suggestions for:


- Lifetime mismatches between consumer and constructor parameters

- Captured Scoped dependencies inside hosted services or background workers

- ``

Direct HttpClient instantiation

- Captured tracked entities in long-lived caches

- Static helpers reaching into scoped infrastructure



**
The trick is the scoping: it loads only on files where DI is actually happening — not on every prompt. Your token budget stays sane. The AI stays sharp on the file you're actually in.


## 
The bigger pattern: enforce, don't suggest


********
The reframe that took me a year of using AI assistants to internalize is this: generic prompts ask the AI to suggest good patterns. Scoped rules force it to enforce them.


"Be careful with DI lifetimes" is a suggestion. The AI will agree, nod sagely, then ship the captured-Scoped bug an hour later when you're tired.


"Before suggesting any constructor change, audit the lifetime contract" is a rule. The AI now has a checklist. It pauses, runs the check, and either suggests a boundary-respecting alternative or asks you a targeted question — instead of confidently shipping the bug.


**
The first time the AI catches a Scoped-into-Singleton in code you wrote, the kit pays for itself.

---

*Originally published at [https://agenticstandardcontact-byte.github.io/agentic-architect/blog/02-scoped-singleton-di-bug.html](https://agenticstandardcontact-byte.github.io/agentic-architect/blog/02-scoped-singleton-di-bug.html). Part of the [Agentic Architect](https://agenticstandardcontact-byte.github.io/agentic-architect/) persistence kit for Cursor + .NET.*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>ai</category>
      <category>cursor</category>
    </item>
    <item>
      <title>The Context Tax: Why Every Cursor Session Costs You 15 Minutes</title>
      <dc:creator>agentic.standard.contact</dc:creator>
      <pubDate>Wed, 20 May 2026 22:54:58 +0000</pubDate>
      <link>https://forem.com/agentic_standard/the-context-tax-why-every-cursor-session-costs-you-15-minutes-cl1</link>
      <guid>https://forem.com/agentic_standard/the-context-tax-why-every-cursor-session-costs-you-15-minutes-cl1</guid>
      <description>&lt;p&gt;There's a hidden cost senior engineers pay every morning when they open Cursor. It compounds quietly, it doesn't show up on any dashboard, and at a typical senior billing rate it's worth thousands of pounds a year. I call it the &lt;strong&gt;Context Tax&lt;/strong&gt;. Here's why it happens, what it actually costs, and the four-rule architecture I built to eliminate it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 15-minute problem
&lt;/h2&gt;

&lt;p&gt;Open Cursor on Monday morning. New chat. You're picking up where you left off Friday — adding a caching layer to &lt;code&gt;OrderService&lt;/code&gt;. You type:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Add Redis caching to this method."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And the AI returns something technically correct, but architecturally wrong. It instantiates &lt;code&gt;ConnectionMultiplexer&lt;/code&gt; directly in the service constructor. It uses &lt;code&gt;IMemoryCache&lt;/code&gt; as if your project doesn't already register &lt;code&gt;IDistributedCache&lt;/code&gt;. It writes a synchronous wrapper around an async call.&lt;/p&gt;

&lt;p&gt;You sigh. You type the preamble. &lt;em&gt;Again.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"This project uses Mediator and Result&amp;lt;T&amp;gt;. We register caching through IDistributedCache in /Infrastructure/Caching. Don't reach into ConnectionMultiplexer directly. Don't put any caching logic in the Service layer — wrap it via a decorator in Infrastructure. And we never instantiate dependencies, we inject them via constructor."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Three paragraphs. Maybe four. By the time the AI has the context it needs to actually be useful, you've spent fifteen minutes typing what your codebase has already shown it dozens of times before.&lt;/p&gt;

&lt;p&gt;That's the Context Tax.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it happens
&lt;/h2&gt;

&lt;p&gt;Cursor — like every other AI coding tool right now — has no persistent memory between sessions. Each new chat starts fresh. Every architectural decision your team has ever made, every refactor your codebase has ever absorbed, every "we tried that, it doesn't work for us" — gone the moment you close the window.&lt;/p&gt;

&lt;p&gt;The AI isn't stupid. It's amnesiac.&lt;/p&gt;

&lt;p&gt;Worse: even &lt;em&gt;within&lt;/em&gt; a session, the AI's understanding of your architecture is a fragile probability cloud. By Wednesday afternoon it has "forgotten" the convention it followed on Monday. It starts suggesting patterns that violate your boundaries. You correct it. It double-downs. You correct it again. It loops on the same hallucination, burning tokens, burning your time.&lt;/p&gt;

&lt;p&gt;This is what I call &lt;strong&gt;AI drift&lt;/strong&gt;, and on a long project it's the single biggest reason senior engineers go from "Cursor is incredible" to "I've turned the autocomplete off."&lt;/p&gt;

&lt;h2&gt;
  
  
  The cost
&lt;/h2&gt;

&lt;p&gt;Let's do the uncomfortable math.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;15 minutes per day&lt;/strong&gt; spent on re-context and correcting drift.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;~250 working days per year.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;That's &lt;strong&gt;62.5 hours&lt;/strong&gt;. Nearly &lt;strong&gt;eight full working days&lt;/strong&gt; annually.&lt;/li&gt;
&lt;li&gt;At a UK senior dev billing rate of around &lt;strong&gt;£75/hour&lt;/strong&gt;, that's &lt;strong&gt;£4,687.50&lt;/strong&gt; of senior time, per engineer, per year — bleeding out invisibly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On a five-engineer team that's the cost of a junior hire.&lt;/p&gt;

&lt;h2&gt;
  
  
  The instinct that doesn't work
&lt;/h2&gt;

&lt;p&gt;The obvious response is to write a long system prompt with all your conventions and paste it at the top of every new chat. Most senior engineers I know have tried this. It fails for three reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Token bloat.&lt;/strong&gt; A 2,000-token preamble at the start of every prompt is expensive and slow. Worse, the AI's attention to &lt;em&gt;specific&lt;/em&gt; rules degrades as the preamble grows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Discipline decay.&lt;/strong&gt; You'll do it for a week. By week two you'll start skipping it for "quick" prompts. The drift returns.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Static knowledge.&lt;/strong&gt; Your architecture evolves. The preamble doesn't. It's a snapshot from whenever you last bothered to update it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You don't need a longer prompt. You need &lt;em&gt;persistence&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What persistence actually looks like
&lt;/h2&gt;

&lt;p&gt;The breakthrough — once you stop thinking of Cursor as a chat-bot and start thinking of it as a stateful pair-programmer — is that the AI needs three things to behave like a senior:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;A long-term memory file&lt;/strong&gt; that lives in the repo, that the AI reads on every session start, and that the AI itself updates whenever it learns something new. Architectural Decision Records (ADRs) for the AI, by the AI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scoped, directory-aware rules&lt;/strong&gt; that load only when relevant — a DI rule fires on &lt;code&gt;Startup.cs&lt;/code&gt; and &lt;code&gt;ServiceCollectionExtensions.cs&lt;/code&gt;, not on every controller. Token budget preserved.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A circuit breaker&lt;/strong&gt; that detects when the AI is in a hallucination loop and forces it to stop, re-read the file, and ask a question rather than double down.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;None of these are exotic. They're standard senior-engineering moves applied to the AI itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  The four-rule architecture
&lt;/h2&gt;

&lt;p&gt;I packaged the pattern I've been using on real .NET codebases into four &lt;code&gt;.mdc&lt;/code&gt; files Cursor reads natively:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;arch-core.mdc&lt;/code&gt;&lt;/strong&gt; — boundary enforcement. Detects which layer the current file lives in and refuses suggestions that cross it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;dotnet-di.mdc&lt;/code&gt;&lt;/strong&gt; — DI auditor. Catches &lt;code&gt;Scoped → Singleton&lt;/code&gt; capture, &lt;code&gt;HttpClient&lt;/code&gt; instantiation, &lt;code&gt;IConfiguration&lt;/code&gt; leaks into business logic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;bug-breaker.mdc&lt;/code&gt;&lt;/strong&gt; — the circuit breaker. Watches for repeated failed attempts on the same problem and forces re-reading instead of doubling down.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;persistence.mdc&lt;/code&gt;&lt;/strong&gt; — the engine. Maintains &lt;code&gt;LEARNING_LOG.md&lt;/code&gt; across sessions. Auto-appends decisions in an ADR-style format. Hydrates the AI on session start.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The whole thing lives in &lt;code&gt;.cursor/rules/&lt;/code&gt; and a single root-level &lt;code&gt;LEARNING_LOG.md&lt;/code&gt;. Zero config. Zero build step. Commit it to your repo, your whole team gets the same baseline.&lt;/p&gt;

&lt;h2&gt;
  
  
  What "after" looks like
&lt;/h2&gt;

&lt;p&gt;Monday morning, two months in. New chat:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Add Redis caching to OrderService."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The AI responds:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Detected Scoped lifetime conflict with &lt;code&gt;IMemoryCache&lt;/code&gt; (Singleton). Following Log Entry #27: 'Prefer &lt;code&gt;IDistributedCache&lt;/code&gt; abstraction in &lt;code&gt;/Infrastructure/Caching&lt;/code&gt;.' Applying decorator pattern via Scrutor per &lt;code&gt;arch-core.mdc §3&lt;/code&gt;..."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No preamble. No correction loop. The AI already knows.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try one rule for free
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;arch-core-lite.mdc&lt;/code&gt; rule is a stripped-down version of the kit's boundary guardian. Drop it in your &lt;code&gt;.cursor/rules/&lt;/code&gt; folder and watch your AI start respecting your layers today. Free download, no signup:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/agenticstandardcontact-byte/agentic-architect/blob/main/arch-core-lite.mdc" rel="noopener noreferrer"&gt;&lt;strong&gt;Download arch-core-lite.mdc&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Or just stop the Context Tax today
&lt;/h2&gt;

&lt;p&gt;The full &lt;strong&gt;Agentic Architect&lt;/strong&gt; kit — 4 specialist rules + the persistence engine + Learning Log template — is &lt;strong&gt;£19.99 one-time&lt;/strong&gt;. Lifetime updates. MIT-licensed. 14-day no-questions refund.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://agenticarchitect.gumroad.com/l/dotnet-persistence-kit" rel="noopener noreferrer"&gt;&lt;strong&gt;Get the full framework — £19.99&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://agenticstandardcontact-byte.github.io/agentic-architect/blog/01-the-context-tax.html" rel="noopener noreferrer"&gt;agenticstandardcontact-byte.github.io/agentic-architect/blog&lt;/a&gt;. Canonical URL is set so the original gets the SEO juice.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>ai</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
