Your AI Assistant Isn't Getting Dumber Mid-Session — It's Running Out of Context
Why long AI coding sessions quietly degrade, and four concrete practices — repo rule files, short sessions, symbol ingestion, ADRs — that fix it.

Abhishek
Full-Stack & AI Product Engineer
Two hours into a session, your AI coding assistant starts doing things it wasn't doing an hour ago. It reintroduces a bug you already fixed. It suggests Redux after you told it Zustand three prompts ago. It writes an error handler that ignores the pattern the rest of your codebase uses. Nothing crashed, nothing errored — the model just quietly stopped remembering.
That's context window drift, and it's not a bug in the model. It's what happens when you treat a fixed-size, priority-blind buffer like it has infinite memory.
Why it happens
Every model — Claude Code, Cursor, Copilot, a custom agent loop, doesn't matter — runs on a token context window. Even a 1M-token window drifts, because the problem isn't really about size. Three things cause it.
The sliding window mechanism. As a conversation grows, older instructions get pushed out or de-emphasized in favor of recent turns. Your architecture diagram from message four means less by message eighty.
Context dilution. Dump a few thousand lines of raw test output or a full file into the chat, and your system-level instructions don't disappear — they just lose relative weight. It's a needle-in-a-haystack problem: the needle's still there, but so is a lot more hay than before.
Instruction contradiction. You course-correct mid-session ("actually, use Axios instead of fetch"), and now both instructions live in the history. The model doesn't reliably know which one wins.
Put together, this is why a session that started sharp ends up sloppy — not because the model degraded, but because the signal you gave it got buried under everything you gave it afterward.
Four things that actually fix it
1. Put your rules in the repo, not the chat
Stop re-explaining your stack and conventions inside conversation threads. That information rolls off the context window exactly like everything else. Put it in a file instead — .claude.md, .cursorrules, whatever your tool reads on every fresh interaction — so it's re-loaded at the start of each session instead of decaying across one.
# Repository Architecture Guidelines
- Language: TypeScript (Strict mode enabled)
- Framework: Next.js App Router (React Server Components by default)
- State Management: Zustand (No Redux)
- Testing: Vitest for unit tests, Playwright for E2E
- Formatting: Prettier + ESLint strict rules
Be specific about what's prohibited, not just what's preferred. "No Redux" stops a drifted session from reaching for the wrong tool far more reliably than "we use Zustand" does on its own.
2. Stop running mega-threads
This is the single highest-leverage habit change, and it's the one people resist most because closing a session and starting over feels like losing momentum. It's the opposite — momentum was already gone, you just hadn't noticed.
Scope each session to one task: "implement the JWT refresh token endpoint," not "build out auth." Ship it, verify it, commit it, close the thread. Starting fresh doesn't cost you anything, because your actual state lives in the committed code, not in the chat history. A new session reads clean.
3. Feed it interfaces, not files
Pasting a 1,000-line source file into the chat is the fastest way to trigger dilution — you're burying your own instructions under the exact noise that causes drift. Pass function signatures and type definitions instead of full implementations. If your tool supports symbol indexing or workspace search (@filename references, semantic lookup), let it pull the minimal AST fragment it actually needs rather than handing it everything and hoping it finds the relevant part.
4. Write decisions down where they can't roll off
Significant architecture calls shouldn't live only in chat history — that's exactly the kind of thing instruction contradiction eats alive three sessions later. Keep lightweight Architecture Decision Records in docs/adr/, and when you're prompting for a refactor that touches one, reference it directly: @docs/adr/003-database-migration.md. The decision stays grounded in a permanent file instead of depending on the model still remembering a conversation from last week.
The checklist version
| Practice | Problem it solves | What it looks like |
|---|---|---|
.claude.md / .cursorrules |
Forgetting project standards | Root-level markdown rules file |
| Short sessions | Sliding-window token drop | One session per feature/bugfix, then close it |
| Targeted symbol ingestion | Context dilution | Pass signatures/types, not full files |
| ADR documentation | Instruction contradiction | Architectural decisions kept in docs/adr/ |
None of this is exotic tooling. It's treating the context window as a resource you manage on purpose, not a scratchpad you fill until it stops working. Repo files carry the rules, short sessions keep the signal clean, and permanent docs hold the decisions that shouldn't be left to chat history's mercy.
Related Articles
View All Articles ↗The AI Wrote Code That Compiles, Runs, and Is Wrong: A Debugging Workflow
A practical three-tier workflow for catching the subtle bugs, boundary omissions, and security gaps AI coding assistants keep shipping.
Why Your Coding Agent Chokes on Big Repos (And How AST Compression Fixes It)
Raw file dumps blow up token costs and wreck reasoning in agentic coding tools. Here's how AST signature stripping and dependency-aware context loading cut repo context by 90% or more.
AI Reliability Engineer (AIRE) Explained — Salaries, Skills, and How to Break In
What an AI Reliability Engineer actually does, why postings from Anthropic and OpenAI pay $250K-$485K, and the real skill gap between an AIRE and a classic SRE.