The pull request looked fine: a new process_refund function that Claude Code had written against a legacy payments codebase, a test, a clean two-file diff. It passed review at a glance, and it merged. Then the on-call engineer noticed that refunds were not showing up in the observability dashboard, and that a failed refund returned a generic 500 instead of the structured error the payments gateway expected.
The code was not buggy in the usual sense. It was architecturally wrong. It called logging.getLogger(__name__) instead of the house get_logger() that injects the trace and tenant IDs every other module uses. It queried Payment.objects.get(id=...) directly instead of going through PaymentRepository, bypassing the read-replica routing and the soft-delete filter that every other access path respects. It raised a bare ValueError where the rest of the service raises DomainError(code=...) so the API layer can map it to the right HTTP status. Three decisions, all defensible in isolation, all wrong for this codebase.
The agent did not lack intelligence. It lacked the one thing a new engineer gets on day one and an agent gets never: someone pointing at the existing code and saying "do it like that."
The thesis: on brownfield, the harness is the bottleneck, not the model
Here is the claim this article owns. On an existing codebase, the raw capability of the model is not what limits the quality of what a coding agent produces. The harness is - the context you engineer around the model: what it reads, in what order, under what instructions, with what tools. Teams keep turning to a smarter model to fix architecturally-wrong output. A smarter model does help at the margin, through a larger window and better recall over the context it holds. But it cannot recover conventions that never entered its context in the first place. So it produces output that is more fluent and still architecturally wrong. The failure is structural, not a limit of intelligence.
I want to name the mechanism precisely, because "the model needs more context" is too vague to act on. I call it Convention Inversion.
On a greenfield project, the agent is the convention-author. It picks the logger, the error type, the folder layout, and because it picked them, its later choices are consistent with its earlier ones by construction. Its guesses match because it is guessing against itself.
On a brownfield codebase, that role inverts. The agent becomes a convention-follower. The logger, the error type, the access pattern, and a thousand other decisions were made years ago, by people who have since left, and are recorded nowhere the agent can read them. Every naive-default failure - wrong logger, wrong query path, wrong error type - traces back to this single inversion. The agent is still authoring conventions, confidently, in a codebase that already has them.
One clarification before we go further, because "Convention Inversion" will make some readers reach for the terms next to it. This is not Inversion of Control, where a framework calls your code instead of the reverse. It is not Convention over Configuration, where sensible defaults replace explicit wiring. And it is not "context debt," the useful term others have coined for the accumulated undocumented decisions in a legacy system. Convention Inversion names something narrower and more actionable: the moment the author of a set of conventions and the party bound to follow them come apart. On greenfield they are the same party - the agent authors its own conventions and obeys them by construction. On brownfield they split - the agent must follow conventions authored by others it cannot see. Everything in the harness exists to close that gap. Keep the general form in mind - author and follower coming apart - because it returns near the end, one level up, where the author turns out to be you.
The uncomfortable part, if you were expecting a vendor to disagree: Anthropic already says this. The Claude Code best-practices documentation opens by stating that "most best practices are based on one constraint: Claude's context window fills up fast, and performance degrades as it fills." The "just wait for a smarter model" position is not Anthropic's engineering guidance - it lives in the market, in the demos, in the procurement decks. The people building the tool are telling you the constraint is the harness. Most teams are not listening.
Why Convention Inversion gets worse in production, not just in a demo
The demo works because the demo is greenfield. Someone opens an empty repo, describes an app, and the agent builds something coherent in an afternoon. That is a real capability and it is genuinely impressive. It is also the easy case, because in an empty repo the agent's guesses cannot collide with anything.
Production is the other case. Your codebase is measured in millions of lines; a context window is 200K tokens on the standard configuration, and up to 1M where an extended window is available. Even at a million tokens, you hold only a small fraction of the system at any moment. And the model does not get more reliable as you fill that window. Independent testing by Chroma across 18 frontier models found that every one of them, including the strongest, becomes less reliable at recalling and using information as the input grows, and the degradation shows up well before the window's stated limit. Anthropic frames the same effect as a limited "attention budget." More context does not mean more understanding. Past a point, it is just more noise the model has to hold in working memory. This is why the window is infrastructure to manage, not a bucket to fill.
Now scale that across a team. One developer running an unguided session and producing one architecturally-wrong PR is a code-review problem. Ten developers running unguided sessions, each agent re-inventing the house conventions slightly differently, is an entropy problem. The real enterprise risk of coding agents on legacy code is not the single bad pull request that review catches. It is that the codebase drifts faster than it did before - toward ten subtly different logging patterns, three competing ways to fetch a payment, a slow erosion of the consistency that made the system legible in the first place. Convention Inversion is not a per-session bug. Without a shared harness, it is a per-developer, per-session tax on your architecture. Staying valuable as the engineer in that loop, rather than the person who pastes what the agent produced without understanding it, is the human-side mirror of the same problem.
Why agentic search changes where the setup effort goes
To fix the harness you have to understand how the agent actually finds things, because it is not what most people assume.
Claude Code does not maintain a vector index of your repository. It navigates the way an engineer does: it runs grep, it reads files, it follows a reference from one file to the next, loading context just in time rather than from a pre-built index. This is a deliberate design choice, and Anthropic has been explicit about it. Boris Cherny, who created Claude Code, has said that early versions used a retrieval-augmented generation (RAG) setup with a local vector database, and that they moved away from it because agentic search worked better in their testing. Another engineer on the team put it more bluntly: agentic search outperformed the indexed approach "by a lot," and the margin surprised them.
That result is counterintuitive if you have internalized "an index means better retrieval," so it is worth understanding why it holds. An index is a snapshot; it goes stale the moment the agent edits a file, and it returns fuzzy nearest-neighbor matches that are often almost-right in a way that is worse than a miss. Agentic search reads the current state of the code and reasons about what it finds. It is fresh, precise, and private - nothing has to be embedded and stored.
But the property that makes agentic search work is also the property that makes brownfield hard, and this is the mechanism that earns the rest of this article: with no index, navigation quality is bounded entirely by how legible you have made the codebase. An index can hide bad naming behind vector similarity. Agentic search cannot. If your payment logic lives in a file called utils2.py next to helpers_old.py, and the function is named do_the_thing, the agent has nothing to follow. It greps for "refund," lands on a comment in an unrelated module, and starts building from the wrong place. On a well-named, consistently-structured codebase the same agent walks straight to the right file. The model is identical in both cases. The harness - here, the legibility of the code and the signposts you have placed in it - is the entire difference.
The wrong way: one unbounded Claude Code session that does everything
The default way people use a coding agent on a legacy codebase is a single prompt in a single session:
Investigate the codebase and add refund support to the payments service.Watch what happens. The agent, correctly trying to be thorough, starts investigating. It greps for "payment." It gets forty hits. It reads the models, then the serializers, then the service layer, then the tasks, then the tests, then the three utility modules that came up in the grep, then the API views that import them. It is now two hundred files deep. Anthropic has a name for this failure - "the infinite exploration" - where the agent reads hundreds of files and fills its own context before it has written a line.
By the time it starts implementing, the window is saturated. The early part of the conversation - your actual instruction, the first useful file it found - has decayed under everything that came after. This is context rot in practice: the signal that mattered is now buried in the noise the agent generated while looking for it. The refund code it finally writes is drafted from a degraded, half-remembered picture of the system. It writes logging.getLogger. It writes Payment.objects.get. The one session tried to do discovery and construction at once, and the discovery poisoned the construction.
The tempting fix is the wrong one. You add "use the existing logger and repository pattern" to the prompt. Now you are hand-feeding conventions one incident at a time, forever, and the next developer's session knows none of it. You have treated a symptom of Convention Inversion, in one session, by hand. The disease is untouched.
The right way: split exploration from editing
The fix is to stop asking one session to both understand and change the system. Split it in two: a read-only exploration pass that produces a durable map, and a clean editing pass that works from that map. This is not a fringe technique - it is Anthropic's recommended default working mode, documented as Explore, then Plan, then Implement, then Commit, with the note that "letting Claude jump straight to coding can produce code that solves the wrong problem."
The mechanism that makes it cheap is the subagent. A subagent runs in its own separate context window and reports back a summary, not the raw files it read. Anthropic's own framing: "the subagent explores the codebase, reads relevant files, and reports back with findings, all without cluttering your main conversation." The two hundred files get read in a context you throw away. What survives is the map.
First, the exploration pass. Define a read-only explorer so it physically cannot edit while it investigates:
# .claude/agents/payments-explorer.md---name: payments-explorerdescription: Read-only mapper for the payments subsystem. Produces a findings file; never edits code.tools: Read, Grep, Glob---You are mapping an existing subsystem so a later editing session can workwithout re-reading the whole tree. You do not write or modify code.Produce a findings file with exactly these sections:1. Entry points - where a request enters this subsystem2. The house patterns - logger, data access, error handling, with ONE file:line example of each that the editing session should copy3. The files a refund feature would touch, and why4. Gotchas - anything surprising that a naive change would get wrongRun it, pointed at the task, and have it write the map to a file in the repo:
Use the payments-explorer subagent to map how refunds would be added to thepayments service. Write the result to notes/payments-refund-map.md.The subagent burns its own context reading the forty files. Your main session stays clean. The output is a small, high-signal document:
# notes/payments-refund-map.md## Entry points (existing - what's here now)- API: PaymentView at payments/api/views.py:88 (DRF). RefundView goes beside it.- Async: charges settle in payments/tasks/charges.py:20. No refund task exists yet.## House patterns - copy these exactly- Logger: payments/service/charge.py:14 `log = get_logger(__name__)` from app.observability (NOT logging.getLogger - that skips trace/tenant IDs)- Data: payments/repo/payment_repository.py:40 `PaymentRepository.find_by_id()` - routes reads to the replica and applies the soft-delete filter. Never use Payment.objects.- Errors: payments/errors.py:12 raise DomainError(code="refund_failed") The API layer maps DomainError.code -> HTTP status. Bare exceptions become a 500.## Files a refund touches- payments/service/refund.py (new) - mirror payments/service/charge.py- payments/repo/payment_repository.py - add refund persistence method- payments/api/views.py - add RefundView next to PaymentView- payments/tasks/refunds.py (new) - async settlement, mirror charges.py## Gotchas- Charges and refunds share the ledger; a refund must post a REVERSAL entry, not a negative charge. See ledger/README.md.Now the editing pass, in a fresh session with the window empty. This is the other half of Anthropic's documented pattern - once the specification exists, "start a fresh session to execute it" so the new session "has clean context focused entirely on implementation." You give it the map and point at the one example to copy:
Read notes/payments-refund-map.md. Implement refund support following itexactly. Match the logger, data-access, and error patterns from thefile:line examples in the map. Model payments/service/refund.py on payments/service/charge.py.Do not read the rest of the codebase unless the map is missing something.The editing session never does open-ended discovery. It loads a curated map and one reference file, and it writes code that matches the house patterns because you handed it the house patterns instead of hoping it would find them. Convention Inversion is defeated the same way you would onboard a human: not with a smarter engineer, but by pointing at the existing code and saying "like that."
Convention Inversion and the layers of the harness
The exploration/editing split is the working mode. Underneath it sits the durable part of the harness - the layered instructions and tools that make every session start further ahead. Here is the whole stack, in the order you should invest in it.
Layer 1: The CLAUDE.md instruction hierarchy
The root CLAUDE.md is loaded into every session, so it is the most expensive real estate you own. The discipline is to keep it to pointers and gotchas, not documentation. Anthropic's guidance is explicit and worth internalizing: "Bloated CLAUDE.md files cause Claude to ignore your actual instructions." For each line, ask whether removing it would cause a mistake; if not, cut it. What belongs there: the non-obvious build command, the one architectural decision that trips everyone up, a pointer to where the real conventions live. What does not: anything the agent can infer by reading the code, and file-by-file descriptions that go stale in a week.
The leverage comes from nesting. Claude Code loads CLAUDE.md files from parent directories at startup, and pulls in a child directory's CLAUDE.md on demand when it reads a file in that directory. So the payments module's local conventions live in payments/CLAUDE.md and cost nothing until the agent actually works in payments:
# payments/CLAUDE.md (loads only when the agent touches this directory)- Logger: `get_logger(__name__)` from app.observability. Never logging.getLogger.- Data access: go through PaymentRepository. Never Payment.objects directly.- Errors: raise DomainError(code=...). Bare exceptions become HTTP 500.- Refunds post a ledger REVERSAL, not a negative charge. See ledger/README.md.That is the antidote to Convention Inversion made durable. The conventions load additively as the agent walks the tree, so it reads exactly the rules for the code it is touching and pays no token cost for the rest.
There is a second-order effect worth naming: the root file does not just cost tokens, it sets the ceiling on how closely the agent follows anything you write. When instructions compete for attention the marginal one does not get half-followed - it gets dropped, and you cannot predict which. A 400-line CLAUDE.md that documents every module reads to the model as low-signal noise, and the single line that actually matters (refunds post a ledger reversal, not a negative charge) drowns in it. That is the mechanism behind Anthropic's warning - bloat is not a tidiness problem, it is an instruction-adherence problem. Treat the root file's length as a budget you actively defend, and re-audit it the moment it grows past a screen. The nested files exist precisely so that this discipline costs you no coverage.
Layer 2: Scoped commands and exclusions
Put the local test and lint command in the subdirectory's CLAUDE.md so the agent runs pnpm --filter @repo/api test instead of the whole monorepo suite. For exclusions, one caution that matters: an ignore file keeps generated and vendored files out of the agent's way, but do not treat it as a security boundary. Claude Code has been reported reading .env contents despite a .claudeignore entry meant to block them (The Register reproduced the issue in January 2026). If a path must never be read, enforce it with permissions.deny in .claude/settings.json or a PreToolUse hook - a real gate, not a hint, and the same deterministic-constraint thinking that keeps agent tool calls in scope:
// .claude/settings.json{ "permissions": { "deny": ["Read(./.env)", "Read(./secrets/**)"] }}Both halves of this layer are really about the length of the agent's feedback loop. A scoped command shortens it: an agent that gets a pass or fail in seconds verifies after every edit, while one that waits minutes for the full monorepo suite quietly learns to skip the check and assume its change was fine. Exclusions clean it: generated bundles, vendored trees, and lockfiles that match every search term bury the real hit and burn context on every grep. Put the narrowest command that still proves the change where the agent will look for it, exclude the noise, and every layer above this one runs on a tighter, less polluted loop.
Layer 3: A codebase map
When the directory structure does not carry the load - a legacy tree where names lie about contents - a short map document is worth more than any amount of grep. It says where things live and, more importantly, why. This is also exactly the artifact a coding agent can generate for you as a one-time investment; I have written separately about going from an unknown codebase to an architecture document, and that output is the seed of your map. Keep it alive the way you would keep a system diagram current rather than letting it rot into a stale screenshot in someone's Drive.
A map earns its place only when it answers questions the tree cannot. Three pay off most: where a responsibility actually lives when the directory name lies (the "billing" logic that really sits in core/legacy/txn.py), which of two near-identical modules is the live one and which is the deprecated copy nobody deleted, and the load-bearing indirection - the dependency-injection wiring or dynamic dispatch that grep will never connect for you. Keep it to exactly that. A map that restates the folder layout is worse than none, because it goes stale silently and the agent trusts it anyway. Date it, keep it short, and regenerate it as a cheap, repeatable pass rather than a document you maintain by hand forever.
Layer 4: Symbol-level navigation over grep
This is the highest-value move for a legacy multi-language repo, and it is underused. String matching lands on the wrong symbol constantly: grep for send in a large codebase and you get the mailer, the message queue, the metrics emitter, and a comment. Symbol resolution - go-to-definition, find-references - filters to the actual definition before the agent reads anything, using the same Language Server Protocol (LSP) your IDE uses. This is now available first-party: Anthropic recommends installing a code-intelligence plugin for typed languages to give the agent "precise symbol navigation and automatic error detection after edits." It is also available through Model Context Protocol (MCP) servers such as the open-source Serena, which exposes find_symbol and find_referencing_symbols backed by real language servers across 30+ languages. Either way, symbol navigation turns "read ten files to find the one that defines this" into a single precise jump.
The payoff compounds with codebase age. In a young repo the agent can afford to read broadly; in a legacy tree the cost of reading the wrong ten files is the whole context window, and symbol resolution is what stops it paying that cost on every task. The setup is a one-time install - a plugin for typed languages, or Serena wired as an MCP server - and the return is that "find where this is defined" and "find everything that calls this" stop being read-the-repo operations. One caveat keeps it honest: navigation is only as good as the language server underneath it, so a repo that does not typecheck cleanly, or a dynamically-typed corner with no server support, degrades back to grep. Know where those edges are so you are not surprised when the agent's jumps turn vague there.
Layer 5: The exploration/editing split
This is the working mode from the previous section, promoted to a first-class layer because it is the habit that makes every other layer pay off. The instruction hierarchy, the scoped commands, the symbol navigation - none of them help if the session using them is already drowning in its own discovery. A read-only exploration subagent writes the findings file; a fresh session edits from it. Make it the default, not the exception.
The mechanism that makes this work is the discard. The exploration pass is allowed to be wasteful - open twenty files, chase three dead ends, burn its context - because its only job is to produce the findings file, after which it is thrown away. The editing session then starts from that distilled map with a clean window, so its tokens go to the change instead of the search. Skip the split and you get the failure mode this article opened with: one session that explores and edits in the same window, saturates halfway through, and starts making architectural guesses exactly when it has the least room left to reason. The findings file is the seam that lets you throw away the expensive half and keep the cheap one.
Layer 6: MCP and integrations, wired last
MCP servers and external integrations - issue trackers, databases, design tools - come last, for the reason the checklist makes concrete. They multiply the reach of a working harness, and they multiply the confusion of a broken one. Wired before layers 1 through 5 exist, they give a context-starved agent more ways to act on a codebase it still does not understand.
Concretely this is the issue tracker, the database inspector, the design tool, the internal service the agent can now call instead of being told about - each one widening what a competent agent does without leaving the session. But an integration is a force multiplier, and it multiplies whatever it is attached to. Wire a database MCP server into a harness where layers 1 through 5 already exist and the agent inspects the real schema to write a correct migration; wire the same server into a context-starved agent with no conventions and no map, and you have handed it a faster way to act confidently on a system it has not understood. The ordering rule is not aesthetic. Integrations amplify the harness, so there has to be a harness worth amplifying first.
The two-lane flow: context saturation versus a scoped edit
The whole argument, in one picture: the same task, run two ways.
flowchart TD
T[Task: add refund support<br/>to the payments service]
T --> A1[Single unbounded session]
A1 --> A2["investigate the codebase<br/>and add the feature"]
A2 --> A3[Reads 200+ files<br/>grep wanders, follows every reference]
A3 --> A4[Context window saturates<br/>early instructions decay]
A4 --> A5[Architecturally-wrong PR<br/>wrong logger, wrong ORM, bare errors]
T --> B1[Exploration / editing split]
B1 --> B2[Read-only exploration subagent<br/>maps the subsystem in throwaway context]
B2 --> B3[Writes findings file<br/>payments-refund-map.md]
B3 --> B4[Fresh editing session<br/>loads only the map + one example file]
B4 --> B5[Scoped, convention-correct PR<br/>matches house patterns]
classDef task fill:#FFD93D,color:#2C2C2A,stroke:#D4B02A;
classDef neutral fill:#4A90E2,color:#FFFFFF,stroke:#3A7BC8;
classDef split fill:#7B68EE,color:#FFFFFF,stroke:#6858DE;
classDef fail fill:#E74C3C,color:#FFFFFF,stroke:#B03A2E;
classDef good fill:#6BCF7F,color:#2C2C2A,stroke:#4CAF64;
class T task;
class A1,A2,A3,A4 neutral;
class A5 fail;
class B1 split;
class B2,B3,B4 neutral;
class B5 good;
Same model, same task, same codebase. The only variable is the harness.
The operational reality most guides skip: Convention Inversion, one level up
Here is the part that is counterintuitive enough that almost no one writes it down, and it is where I am giving you my reasoned position rather than a citable fact - I will mark exactly where the evidence ends.
Convention Inversion does not stop at the codebase. It recurs, one level up, in the harness itself. The instructions you write are conventions too, and the moment you commit them, you become the convention-author whose choices a future agent must follow - including a future, stronger agent for whom your choices are wrong.
Consider a rule that a lot of teams add in 2026: "Always refactor one file at a time. Never modify more than one file in a single change." For a weaker model that loses the thread across a multi-file edit, this is a sensible guardrail - it trades capability for reliability. For a stronger model that can hold a coherent five-file refactor in working memory and execute it correctly, the exact same rule holds it back. It forces an artificial, worse split of the work and produces more churn, not less. The instruction that helped your harness a year ago actively degrades it now. Your own convention has inverted on you.
The rule did not change; the model outgrew it. That is the second face of Convention Inversion, and it is the one nobody plans for. The first face is the agent failing to follow your codebase's conventions. The second is your harness conventions no longer deserving to be followed - written for a weakness the model has since shed, still silently steering it. Same inversion, one altitude up: the party that authored the conventions and the party that must live under them have traded places again, except this time the author was you.
This is where I have to be honest about what is proven. The direct evidence is thin: this is a reasoned position, not a benchmarked result. What supports it - short of proving it - is real. An empirical study of AI coding agents (arXiv:2511.04824) found that agents refactor with an inverse motivation profile compared to humans, rarely restructuring for modularity or deduplication the way people do; the shape of an agent's behavior is not fixed and shifts in non-obvious ways between systems. And Anthropic's own warning that a bloated instruction file causes the model to ignore your instructions tells you that harness configuration has real, sometimes negative, weight on behavior. Neither one proves that a rule built for a weak model holds back a strong one. Together, they make it the safer assumption, even though it is not proven.
The practical consequence is a discipline, not a fact: harness configuration is not write-once. Every rule in your CLAUDE.md was written against a specific model's failure modes, and those failure modes move under you with every release. Budget a review cadence for your harness the way you budget one for dependencies. After a major model release, re-audit your instruction files and ask of each rule: is this still protecting me, or is it now protecting me from a weakness the model no longer has? This is the sense in which the harness is the product - not a setup you do once, but a living layer you maintain. It ties back to the thesis directly: if the bottleneck were the model, you would upgrade and move on. Because the bottleneck is the harness, upgrading the model is the moment your harness needs the most attention, not the least. This is the same reason autonomous loops need explicit stopping conditions rather than blind iteration, a point I develop in the Ralph loop and /goal.
The brownfield onboarding checklist
Onboard a coding agent to a legacy codebase in this order. The ordering is the advice; the most common mistake is doing it backward.
- Instruction hierarchy first. A lean root
CLAUDE.md(pointers and gotchas, nothing the agent can infer) plus nestedCLAUDE.mdfiles that carry each module's local conventions - logger, data access, error handling - with afile:lineexample of each. This alone defeats most of Convention Inversion. - Scoped commands and exclusions. Per-directory test and lint commands so the agent runs the right suite. Exclude generated and vendored files. Enforce genuine secrets exclusion with
permissions.denyor a hook, not an ignore file. - Symbol navigation. Install a code-intelligence plugin for your typed languages, or wire up an LSP-backed MCP server. On a multi-language legacy repo this is the single highest-value tool you can add.
- Make the exploration/editing split your default. Read-only exploration subagent writes a findings file; a fresh session edits from it. Stop running discovery and construction in one window.
- MCP and integrations last. This is the "don't do this first" rule. Wiring your issue tracker, your database, and five MCP servers before the instruction hierarchy exists is the most common way teams waste the first month. Integrations multiply what a working harness can do and multiply the confusion of a broken one. Get layers 1 through 4 right, then add reach.
- Schedule a harness re-audit. Put a recurring reminder to review your instruction files after every major model release. Delete the rules that were protecting you from a weaker model's mistakes.
If you take one thing: on brownfield code, stop evaluating models and start engineering the harness. The model you already have is almost certainly not your bottleneck. This is the coding-agent instance of a broader pattern I have argued across the Harness Engineering series - there the harness wraps a production LLM service; here it wraps a coding agent, but the discipline is the same. The intelligence is in the model. The leverage is in the harness.
References
- Anthropic. Best practices for Claude Code. Claude Code Documentation. https://code.claude.com/docs/en/best-practices
- Anthropic. (2025, September 29). Effective context engineering for AI agents. Anthropic Engineering. https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents
- Anthropic. Effective harnesses for long-running agents. Anthropic Engineering. https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents
- Anthropic. Manage Claude's memory (CLAUDE.md). Claude Code Documentation. https://code.claude.com/docs/en/memory
- Anthropic. Context windows. Claude Platform Documentation. https://platform.claude.com/docs/en/build-with-claude/context-windows
- Anthropic. Create custom subagents. Claude Code Documentation. https://code.claude.com/docs/en/sub-agents
- Hong, K., Troynikov, A., & Huber, J. (2025, July 14). Context Rot: How Increasing Input Tokens Impacts LLM Performance. Chroma Technical Report. https://www.trychroma.com/research/context-rot
- Agentic Refactoring: An Empirical Study of AI Coding Agents. (2025). arXiv:2511.04824. https://arxiv.org/abs/2511.04824
- Kravcenko, V. (2026, March 3). Claude Code Doesn't Index Your Codebase. Here's What It Does Instead (quoting Boris Cherny and team; primary sources: Hacker News item 43164253 and Cherny on X). https://vadim.blog/claude-code-no-indexing/
- oraios. Serena - LSP-powered coding agent toolkit / MCP server. GitHub. https://github.com/oraios/serena
- TianPan. (2026, April 19). AI Coding Agents on Legacy Codebases: What Works and What Backfires. https://tianpan.co/blog/2026-04-19-ai-coding-agents-brownfield-legacy-code
- Duman, Y. (2025, December 9). Six Months of Agentic Coding in the Trenches: Lessons from a Brownfield Project. https://www.yduman.dev/posts/six-months-of-agentic-coding/
- Claburn, T. (2026, January 28). Claude Code reads .env files despite ignore rules. The Register. https://www.theregister.com/2026/01/28/claude_code_ai_secrets_files/
Related Articles
- The Ralph Loop and /goal: What Claude Code Actually Automated
- Agent Skills Are Not Prompts. They Are Production Knowledge Infrastructure.
- BMAD vs Spec Kit vs Kiro vs Superpowers: What Transfers
- Claude Code Guide: Build Agentic Workflows with Commands, MCP, and Subagents