You ask an AI agent to fix a bug in your C# solution. It never reads the whole solution. It searches, opens a few files, and decides from those. So when it gets it wrong, the reason is usually a file it never opened.
This post walks through what the agent reads first, how it hunts for the rest, the three places a .NET solution hides code from it, and the one file that fixes most of it. I use Claude Code as the concrete example because its behavior is documented, but the mechanics apply to most agents.
An agent is a model in a loop
An agent works in a loop: gather context, take an action, check the result, then go around again. The Claude Code docs describe exactly these three phases, and they're explicit about who does what: the model reasons, and the harness around it provides the tools and manages the context the model sees.
So the model never touches your disk. It asks for a file, the tool reads it, and the text goes back into the conversation.
Why it doesn't just read everything
Everything the agent reads lands in its context window, which Anthropic's docs call the model's working memory. Current Claude models have a 1M-token window. That sounds like enough for a whole solution.
But more isn't better. The same docs say that as the token count grows, accuracy and recall degrade, and they give it a name: context rot. So a good agent has to be picky about what it loads.
What it reads first
Not your code. An instruction file.
- In Claude Code, that's
CLAUDE.md. - Many other agents (Codex, Copilot's coding agent, Cursor, Gemini CLI and others) read
AGENTS.md, which describes itself as a README for agents.
That file is loaded at the start of every session, before you type a word. Claude Code also sees your git state: the current branch, uncommitted changes and recent commits. Everything else, the agent has to go and find.
How it finds the rest
Pretty much the way you would on a new team:
- File names. Show me every project file in this solution.
-
Text. Where does
OrderServiceappear? - Read. Open the two or three files that look right.
Glob **/*.csproj
Grep "OrderService"
Read Orders.Api/OrderService.cs
Anthropic's engineering team calls this just-in-time context: Claude Code uses glob and grep to pull files in as it needs them, rather than building a big index up front. CLAUDE.md is the exception: it's put into context right away.
Names are most of the clue
The same article points out that folder hierarchies and naming conventions are real signals for an agent. To you, an OrderService in a tests project and one in the API project are obviously different things. To the agent, the folder and the name are most of what it has.
In .NET, you get a free map: the .sln file and the .csproj files, which say which project references which. Good names make the search work. Vague names make it guess.
Where it gets lost in a .NET solution
1. Too many hits
Search for Order in a big solution and you get hundreds of lines: entities, DTOs, tests, migrations. Every file the agent opens costs context, so it opens the first few that look right. If the one that matters was result number forty, it never sees it.
2. Code wired by convention
EF Core lets you move each entity's configuration into its own class and then apply every configuration in an assembly with one line:
public class OrderConfiguration : IEntityTypeConfiguration<Order>
{
public void Configure(EntityTypeBuilder<Order> b)
=> b.HasKey(o => o.Id);
}
// AppDbContext.OnModelCreating
modelBuilder.ApplyConfigurationsFromAssembly(
typeof(AppDbContext).Assembly);
Nothing in that last line says Order. An agent that reads your DbContext to understand how Order is mapped won't see it there, and can decide there's no configuration at all. The link only exists at runtime. The same goes for anything registered by scanning an assembly.
3. Code that isn't on disk
Source generators write C# at compile time and add it to the compilation. .NET itself uses them, for example for System.Text.Json and regular expressions.
By default, that generated code lives only in memory, inside the compiler. So the agent searches your folders for a method the compiler can see, and it isn't there. Setting EmitCompilerGeneratedFiles to true in the project file writes the generated files out under the obj folder, where they can be opened.
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>
The good news: the compiler is on your side
The agent doesn't have to guess for long. It can run dotnet build, and the compiler answers with the exact file, the exact line, and what's wrong:
OrderService.cs(42,17): error CS1061: 'Order' does not contain a definition for 'Total'
A strong type system turns a wrong guess into an error message, fast. That's the "check the result" step of the loop, and C# gives it a lot to work with.
You can take it one step further. Claude Code has a C# code intelligence plugin (csharp-lsp, backed by csharp-ls) that connects it to a language server. With it, the agent finds definitions and references by symbol instead of by text, and sees type errors right after each edit. It isn't on by default; you install it.
The one file that fixes most of it
Write the instruction file the way you'd brief a new teammate:
- A map of the solution: which project does what.
- Build and test, one command each.
- The traps: what's wired by convention, and where generated code comes from.
## Solution map
- Orders.Api: HTTP endpoints, no business logic
- Orders.Core: domain and services
- Orders.Data: EF Core, configs applied from assembly
## Commands
- build: dotnet build Orders.sln
- test: dotnet test Orders.sln
## Watch out
- JSON contracts come from a source generator
- Handlers are registered by assembly scan
It sits in the context for the whole session, so keep it short.
There's one more reason it matters. In a long session the context fills up, and Claude Code compacts the conversation into a summary. The docs warn that detailed instructions from early in the conversation may be lost in that summary, and their advice is to put persistent rules in CLAUDE.md. Rules that must stick go in the file, not in the chat.
Three rules
- Names that search well.
- A file that maps your solution.
- A build that tells the agent, fast, when it's wrong.
An AI agent doesn't know your solution. It searches it, like a new hire on day one. Your job is to make that search easy.
What's in your instruction file right now? Or don't you have one yet? Tell me in the comments.
I make Vlad's Stack: short explainers on how the tools you use every day actually work, for .NET and full-stack developers. The channel is here.
Top comments (0)