Your AI Agent Has Amnesia: Context Rot Is Why It Forgets Your Swift Codebase by Lunch
Two hours into a refactor, my coding agent tried to fix a bug I’d fixed at 9 a.m. Same file. Same off-by-one. It even wrote a smug little comment: ”// Fix: guard against empty array.” I had guarded against the empty array. It was right there, four lines up, in code the agent itself had written earlier that morning.
I’ve started thinking of it as the Memento problem. You know the movie — the guy who can’t form new memories, so he tattoos the important facts on his own body and takes Polaroids because otherwise every morning he wakes up and re-solves the same mystery from scratch. That’s your AI agent on a big Swift codebase around lunchtime. Brilliant at 9. Confidently re-investigating a closed case by 11. Tattooing “DON’T TRUST isPremium” on its forearm by 2.
There’s finally a name for this, and it’s not “the model is dumb.” It’s context rot. And once you see it, you can’t unsee it.
The study that put a number on it
Chroma ran the experiment everybody had a vibe about but nobody had measured. They took 18 frontier models — Claude 4, GPT-4.1, Gemini 2.5, Qwen3, the whole lineup — and watched what happened to accuracy as the input got longer. Not on hard reasoning. On simple stuff: find this fact, repeat this text.
The results are the kind of thing you want to print out and tape to your monitor:
- Models don’t degrade in a nice, predictable line as context grows. They hit cliffs. Fine, fine, fine, then off a ledge.
- Accuracy dropped 30-plus points when the relevant fact was buried in the middle of a 20-document context instead of near the edges.
- Even with all the distracting junk stripped out, sheer length alone still knocked 7.9% off. Length is not free. It’s never been free.
- The nastiest finding: semantic similarity hurts more than length. When the wrong answers look like the right answer, the model face-plants. And a codebase is nothing but forty things that look like the right answer.
Then the finding that broke my brain a little. Across all 18 models, they performed better on shuffled, incoherent context than on logically organized documents. Structure hurt. Which means the tidy, well-organized Swift project you’re so proud of is, to a language model, a more confusing haystack than a pile of random snippets.
That’s not intuition anymore. That’s a benchmark.
What context rot looks like in a SwiftUI project
Here’s the thing nobody warns you about: the demos never show this, because the demos are twelve files long. Context rot needs room to happen. Real apps have room.
You’ve almost certainly seen these and blamed yourself:
It forgets your architecture. You spent the first prompt explaining that this app uses @Observable, not ObservableObject, because you already did that migration and you have the scar tissue to prove it. Ninety minutes later it hands you a fresh view model with @Published properties and an objectWillChange for good measure. It didn’t disobey you. It genuinely doesn’t remember you ever spoke.
It reinvents code you already have. You have a networking layer. A nice one. The agent, unable to see it through the fog, writes a second one inline with URLSession and a hand-rolled retry loop, blissfully unaware that the exact thing it needs is already in the project.
It reintroduces bugs. My favorite genre. It “fixes” something by undoing a fix, because the reason for the fix rotted out of the window ten thousand tokens ago.
It gets more confident as it gets more wrong. This is the cruel part. A junior dev who’s lost says “wait, I’m confused.” The agent never says that. It writes the smug comment. Context rot doesn’t feel like forgetting from the inside — it feels like certainty about a fact that expired an hour ago. If that sounds familiar, it’s the same shape as StoreKit’s .verified still swearing a subscription is active long after the server knows better. The signature checks out. The information is stale. Nobody told the flag.
The “just give it a bigger window” trap
Every quarter someone announces a million-token context window like it’s the cure. It is not the cure. Chroma’s study is basically a 40-page argument that your 1M-token window is writing checks the attention mechanism can’t cash.
Think of it like RAM versus actually-being-used RAM. Sure, the window holds a million tokens. That doesn’t mean the model is thinking about a million tokens with equal care. The middle of a long context is where facts go to be politely ignored — the model reads the start, skims the end, and treats the vast soft middle like the terms and conditions nobody reads.
Which means the move everyone reaches for — dump the whole repo into the agent “so it has all the context” — is the single most reliable way to cause context rot. You didn’t give it more understanding. You gave it a bigger haystack and hid the needle in the worst possible spot.
More context is not more understanding. Past a point, more context is less.
Context engineering is the actual job now
On Hacker News this month the phrase going around is that the real skill stopped being prompt design and became context engineering — deciding what your agent gets to see, and just as importantly, what it doesn’t. Memory stopped being a nice feature and became infrastructure. This is the part of the “AI made me faster” story that the productivity-paradox research quietly predicted: the tool is only fast if you do the unglamorous work of feeding it right.
Here’s what actually moves the needle, in rough order of payoff:
1. Start fresh, on purpose. The single highest-leverage habit is /clear (or a new session) between unrelated tasks. A three-hour session isn’t a badge of honor — it’s a context landfill. Short, scoped sessions beat one heroic marathon every time. The agent that forgets on purpose, when you tell it to, beats the one drowning in this morning’s dead context.
2. Give it Polaroids — a CLAUDE.md. This is the Memento tattoo, and it’s the highest-ROI file in your repo. A tight house-rules file — “we use @Observable, Swift Testing not XCTest, the networking layer lives in Core/Net, never touch App/” — gets re-read every session and survives the amnesia. Keep it short. A bloated CLAUDE.md is just more haystack. We wrote a whole lesson on getting this file right in the CLAUDE.md playbook.
3. Scope the task, not the codebase. Don’t say “refactor the app.” Say “in BrewDetailView.swift, extract the header into its own view.” Point the agent at three files, not three hundred. Xcode 26’s built-in MCP tools — XcodeGrep, XcodeRead, DocumentationSearch — exist precisely so the agent can pull the exact slice it needs instead of you pushing the whole tree at it. Let it retrieve. Don’t pre-load.
4. Compact, then continue. When a session has to run long, summarize the state — “here’s what we’ve done, here’s what’s left” — and start clean from that summary. You’re deciding what survives the reset instead of letting the model’s attention decide for you.
5. Version your context like code. The prompts and house-rules that work are assets. Retyping them from memory every session is how house rules drift and rot creeps back in. This is genuinely why we built PromptKit — somewhere to keep the prompts and context blocks that actually work, versioned and one tap from the tool you’re using, instead of scattered across twelve Notes files and your short-term memory. Context engineering is a discipline now. Disciplines need tooling.
What I’d tell my 9 a.m. self
If I could tattoo one thing on my own forearm, Memento-style, it’d be this: the agent is not your teammate who remembers yesterday. It’s a brilliant stranger who walked in this second and will walk out when the window fills. Treat it that way and it’s astonishing. Expect it to remember, and it’ll break your heart around 2 p.m.
None of this is a reason to put the tools down. The agent that reinvented my networking layer also wrote 400 lines of correct, tested Swift before lunch. The skill isn’t avoiding these tools — it’s knowing exactly when their memory is about to expire, and having the Polaroids ready.
If you want the deeper version of this — how to structure prompts, house rules, and iteration loops so your agent stays sharp on a real SwiftUI project — that’s the whole spine of our AI-tools course in the Learn section, starting with what actually makes a good prompt. And if you’ve been living inside Xcode 26’s agent for a few months like we have, you already know the feeling this post is describing. Now it’s got a name, a study, and a fix.
Context rot is real. It’s measured. It’s beatable. But only if you stop expecting the machine to remember, and start doing the remembering for it.
Leonard tattooed his facts on his skin for a reason. Write yours in a CLAUDE.md.
Share this post
Comments
Leave a comment
NativeFirst Team
EditorialThe NativeFirst team — engineers and designers building native Apple apps and writing the courses we wish we had when we started.