Most of us have seen a coding agent fail to complete a task we know it can do. We just don't understand the inconsistency in quality and lazily chalk it up to the "non-deterministic" nature of AI. What you might not realize is that the agent isn't failing because of intelligence, it's failing because its context is cluttered with noise.

To fix this, we need to shift from context maximizing to deterministic pruning. Here is what you will get out of this deep dive to help you build those boundaries:

  • Why feeding an agent your entire repository causes agent reasoning failures.
  • How to navigate brownfield codebases by isolating subsystems for agents.
  • How to dynamically mask dead code before launching an agent turn.
  • The essentials for a reliable pruning harness.
  • Why unconstrained context bloats PRs and burns out reviewers.

In computer architecture, thrashing occurs when an executing process demands more memory than the caches can hold. The processor stops executing useful instructions and spends all its resources swapping pages of memory in and out of RAM.

Coding agents have a similar bottleneck inside their prompt windows. With brownfield development, it might be tempting to dump the whole legacy codebase into context and prompt "refactor this to Next.js" (Read my article How to automate modernization with Antigravity and multi-agent orchestration to learn why this is a bad idea and what to do instead). However, if you do dump the whole codebase into context the agent is more likely to confuse dead code and old library usage as current intent.

You've reached context bankruptcy when the context actively degrades reasoning accuracy.

The visibility trap and why more context breaks reasoning

Some developers treat complete repository ingestion as a headline feature of the large context windows of frontier models. They assume comprehensive visibility equals deep understanding. It doesn't.

In clean greenfield projects, broad context ingestion works but in a multi-million-line legacy codebase, broad context ingestion adversely impacts an agent's ability to reason.

Most of us don't work on greenfield apps and many work inside messy poorly documented legacy codebases they inherited. They typically contain gems like folders named "v1-alpha", temporary helper scripts that are no longer usable or reflect current code, and orphaned feature flags. When an agent sweeps this data into context via naive RAG sweeps or massive context windows, it treats outdated patterns as current engineering truth.

The rule driving this failure is Hyrum's Law applied to AI context windows: with sufficient ingestion breadth, every observable historical implementation detail will eventually be depended upon by an autonomous model.

Give an agent access to 1,000 files and it will reason over your hackiest workarounds. It anchors on deprecated helper scripts and replicates tech debt into new modules.


Selective ignorance and how to enforce the boundary

Selective ignorance and how to enforce the boundary

When I review a legacy monolith I'm not familiar with, I don't read every file.

I practice selective ignorance and deliberately ignore most of the repository when building a mental model around the module I want to modify. I do this by treating the surrounding subsystems as if they were black boxes bounded by strict contracts.

The agent execution environments should model this behavior.

Addy Osmani recently documented context rot (the measurable performance dip models experienced as prompt windows fill) and agentic engine optimization (AEO) (formatting codebase documentation). Our industry remains obsessed with ingestion pipelines and larger token limits. Nobody is building harness infrastructure designed to force strategic forgetting.

To protect agent reasoning we must shift our engineering effort from context maximization to deterministic pruning.

If the agent sees the whole repository, you aren't scaling engineering velocity. You're scaling cognitive debt.


Pruning harnesses versus context bankruptcy

Pruning harnesses versus context bankruptcy

I treat context budget allocation as an architectural constraint because strategic forgetting requires replacing broad ingestion with deterministic pruning.

The contrast between unbound ingestion and strategic forgetting is significant.

Architectural Dimension Unbound Ingestion (Context Bankruptcy) Strategic Forgetting (Pruning Harness)
Ingestion Strategy Global vector RAG sweeps or broad context dumping across **/* Dynamic AST pruning scoped strictly to active dependency graphs
Legacy Conflict Resolution Ingests competing API wrappers; model hallucinates hybrid syntax Hides deprecated subsystems; enforces single active contract
Prompt Capacity 85%+ context budget consumed by historical boilerplate and dead code <15% context budget consumed; working memory preserved for execution
Reasoning Stability High susceptibility to context rot; attention allocation dilutes over noise High attention concentration; deterministic diff generation
Verification Overhead High cognitive load; engineers scrutinize massive diffs for side effects Minimal cognitive load; diffs match expected five-line boundary

Architectural context pruning is not an optimization step. It is a baseline reliability prerequisite. If an autonomous agent can read deprecated internal modules, it will eventually depend on them.

Models are probabilistic which makes them unreliable at deterministic access controls. Simply refining a prompt to instruct the model to ignore sections of a large codebase will fail under complex reasoning loads. This is because models will attend to tokens inside their prompt windows regardless if those tokens are no longer relevant to the project.

To guarantee selective ignorance, implement a muted repo pattern which dynamically manipulates repository visibility before launching an agent turn. Here's how it works…

1. Map active dependency graphs

Run a static Abstract Syntax Tree (AST) parse starting from the target entry file. Generate a strict allowlist containing only immediate upstream imports and downstream consumers.

2. Dynamically create ignore masks

Write an ephemeral .antigravityignore, .geminiignore, .claudesignore or .cursorignore file before the agent turns. Mask out archive/, deprecated helpers, and unrelated domain packages.

3. Use interfaces as substitutes for implementation

Replace complex external database wrappers and legacy integrations with clean interfaces or OpenAPI stubs. Force the model to code against these interfaces.

4. Launch scoped agent turns

Execute the agent prompt inside the pruned sandbox. This enables the model to work with focused attention free of historical distraction.


Essential implementation components

Essential implementation components

Building a deterministic pruning harness relies on three core components.

1. Runtime CLI file gating

Modern agentic IDEs maintain persistent workspace indexes so I avoid editing .antigravityignore, .geminiignore, .claudesignore or .cursorignore dynamically per agent turn because overwriting ignore manifests trigger file-watcher invalidation events. When that happens the machine rebuilds codebase indexes in a race condition against the model's first token.

To avoid editing the ignored files each agent turn, one option is passing file allowlist flags directly into your terminal command when launching the agent (agy --add-dir src/auth/dir). Or, if building a custom harness, pass allowed file arrays into your tool execution APIs in memory.

# .claudesignore .cursorignore .geminiignore .antigravityignore
# Force strategic forgetting in brownfield repositories

**/node_modules/
**/dist/
**/build/

# Gated Legacy Systems - Block the agent from historical noise
/legacy/v1-alpha/
/deprecated-soap-wrappers/
**/*.deprecated.ts

# Large static assets that trigger context thrashing
**/*.json
**/*.csv
package-lock.json
pnpm-lock.yaml

# Block the agent from analyzing un-verifiable dark matter code
/e2e/stale-tests-2022/
Enter fullscreen mode Exit fullscreen mode

2. Hybrid semantic dependency mapping

Do not rely on naive vector embeddings to select codebase context. Vector similarity retrieves semantically similar code which can pick up unwanted legacy code.

Pure static AST tree-shaking would likely fail in brownfield monoliths because legacy systems lie at compile time. I'm thinking about systems that run on Java reflection, dependency injection containers, and runtime module loaders. For example, a shallow AST transversal would miss dynamically injected resources leading to dependency pruning causing runtime exceptions.

Instead, combine shallow AST parsing with recent observability outputs or runtime error logs to discover dynamic runtime dependencies before gating context windows. If runtime telemetry proves verify.ts calls legacy-sql-pool.js via DI reflection, include legacy-sql-pool.js in the allowlist. If static analysis and runtime traces both show zero execution paths to deprecated-auth.ts, keep it out of the allowlist.

3. Differential verification gating

Brownfield architecture is typically handled by isolating complexity behind interfaces. For example, modifying a billing service doesn't require you to read connection pool source code.

We can apply this thinking to agent prompt windows. By replacing deep internal library code with lightweight interface definitions, the model receives the correct contract specifications without ingesting implementation noise.

I do want to point out however, that in legacy systems interfaces may lie. It's the runtime side effects that are the real source of truth. If you do decide to stub code to save tokens during generation, be sure to enforce a differential verification gate. That way, success can be measured by passing tests against the legacy runtime, not the contract stubs.

How Antigravity implements pruning

Since I work at Google on Antigravity, I wanted to share my knowledge of how Antigravity implements isolation natively:

  • Subagent context isolation: Antigravity separates exploration from execution. The main agent has the ability to dynamically generate subagents which will have their own isolated context buffers and instructions from the main agent. The main agent may decide to delegate token-heavy or codebase-wide operations to subagents and keep the primary execution memory clean.

  • Planning mode checkpoints: Enforce explicit planning artifacts (/plan) so reviewers verify implementation design decisions and verification strategy before code generation.


Vigilance fatigue

Vigilance fatigue

Unconstrained context ingestion doesn't just degrade model reasoning, it also has a toll on people. I know when I review lengthy and broad, machine-generated diffs it triggers vigilance fatigue.

Reviewing code submitted by one of my colleagues is different from reviewing AI-generated code because I have less trust that basic architectural boundaries have been honored. I end up scrutinizing every line of code to verify the edit represents intentional business logic and not accidental side effects caused by historical noise.

As reviews grow in size and number, my attention struggles. It becomes increasingly difficult to avoid rubber-stamping bloated pull requests. Strategic forgetting helps protect reviewers by limiting the agent's reach.


Tuesday morning checklist

Tuesday morning checklist

Most engineering organizations measure AI maturity by counting deployed subagents or tracking token consumption volume. In my opinion, both are vanity indicators.

True agentic scaling requires shifting focus from ingestion maxing to isolation discipline. Audit your agent workflows against three deterministic pruning heuristics:

  1. Enforce small diff boundaries: If a localized bug fix generates PRs touching more than two files, halt execution. Your agent isn't being thorough, it's probably distracted by unrelated legacy code..

  2. Treat ignore manifests as dynamic build artifacts: Don't maintain .antigravityignore files manually. Compile ignore manifests dynamically before agent turns combining AST import traversal with runtime trace telemetry (observability/error logs) so dynamic dependency injection paths stay unmasked.

  3. Sandbox dependencies behind contract stubs: If an agent can read implementation source code for external SDKs or shared database wrappers, hide it. Use interface definitions or OpenAPI contract stubs instead.

Your agent headcount matters less than your isolation boundaries.

Additional resources

Here are a few other agentic brownfield development resources:

Help others find this post.

  • Share this post with your friends on socials.
  • Follow me on LinkedIn or X for more content like this.

Thanks for reading!