You asked the assistant twenty minutes ago to stop relying on lazy loading in the reporting query. It agreed, explained why eager joins were better here, and rewrote the method. Now you ask it to add a date filter to that same method, and the diff comes back with lazy loading restored. Not as a proposal you can reject. As if the earlier exchange never happened.
That is rarely a reasoning failure. It is the context window running out: the earlier turns have been pushed out of what the model can still see, and it is now answering from the code in front of it plus the last handful of messages. The confidence does not drop when the memory does, which is the part that costs you time. If you want the mechanics, the context window explainer covers how the limit works. What follows is how to notice it while you are still inside the session.
Is it confused, or out of room?
These look identical from the outside and need opposite responses.
A confused assistant gives you an answer that is wrong about the thing you just said. You clarify, it corrects itself, and the correction sticks. That is normal back and forth.
An assistant with no room left gives you an answer that is wrong about something settled earlier, you correct it, and the same mistake reappears two or three turns later. Corrections stop sticking. That is the real signal: not the error itself but whether fixing it holds.
One quick check before you blame the window. Ask it to restate the constraint you set an hour ago, in its own words, without hinting at the answer. "What did we decide about lazy loading in the reporting layer?" If it reconstructs a plausible-sounding decision that is not the one you made, the original exchange is gone and it is filling the gap from the code.
Four tells that the context window is running out
It repeats work it already did. It re-reads a file it read ten minutes ago, re-derives a conclusion it already stated, or asks you for the path to a file you pasted earlier. Re-reading one file is nothing. Re-reading the same three files every other turn means the earlier reads are no longer in the conversation.
It re-opens decisions you closed. The library you ruled out comes back. The abstraction you explicitly said was premature reappears in a refactor. This is the clearest of the context window limit signs because the assistant is not arguing with your decision, it is proposing the option as if for the first time.
It drifts from your instruction file. It starts suggesting npm when CLAUDE.md says pnpm, writes a test in the framework you migrated away from, or uses the default commit message format instead of yours. Instruction files are usually loaded at the start of a session, which means they sit at the oldest end of the conversation and get squeezed out before your recent messages do. If an assistant that followed your rules for an hour suddenly stops, the rules left the window. That is a different problem from the one where it never followed them properly.
It loses the plan it wrote. You agreed on a five-step change. It finishes step two, then jumps to something adjacent, or asks what you want to do next when the next step is written three messages above. Multi-step work is where this hurts most, because the plan was the thing holding the session together.
Some tools soften the fall. Claude Code compacts a long conversation into a summary and keeps going, so you do not hit a hard wall. Compaction keeps the gist and drops the specifics, and specifics are exactly where your decisions lived. A compacted session that remembers "we discussed the query layer" has still forgotten what you concluded.
Why pushing harder produces more confident wrong answers
The instinct is to re-explain. You paste the constraint again, the assistant apologises, and the next answer is correct. Then it drifts again, and you paste more.
Every one of those corrections consumes room. You are feeding context into a window that is already full, which pushes out whatever is now oldest, which is often the part of the conversation you were relying on. The session gets more expensive per useful turn and less reliable at the same time.
There is a second cost that is easy to miss. An assistant working from a partial picture still writes complete-looking code. It does not hedge, it does not say "I may be missing something." You end up reviewing confident output with no visible marker of which parts came from the full context and which came from the remains of it. That is how a rejected approach gets back into main. The case for stopping instead of pushing is laid out in more detail in when to start a new AI coding session.
What to save before you reset
The temptation when a session goes bad is to kill it immediately. Spend two minutes first, because the thing you are about to throw away is the only place some of your reasoning exists.
Write down what was decided, why, and what got ruled out:
### 2026-10-25 — Eager joins in the reporting layer
Decision: explicit joins in ReportQuery, no lazy loading.
Why: the dashboard issued ~40 queries per page under lazy loading.
Rejected: caching the serialized rows. Hides the N+1 instead of fixing it.
Open: the export job still uses the old path.
Add where you actually are: the step you reached, the command that was failing, the file you were halfway through. The assistant's own summary is a useful draft here, but write the decision yourself, because that is the sentence a future session will act on. Turning a session into a decision record goes through the full version of this.
Starting clean without re-explaining the project
A fresh session should start from files, not from memory. Your instruction file carries the rules, a decisions file carries what you have settled, and the saved transcript carries the detail if anyone needs to go back to it. Load the decision you just wrote, state the next step, and you are back where you were in a couple of minutes rather than an hour.
We built PrjLab so that record lives with the project instead of on one laptop: .prjcontext/memory/ for decisions, .prjcontext/instructions/ for the rules, .prjcontext/sessions/ for the conversations worth keeping, pushed with prj push and pulled back wherever you code next. That is also what makes picking up the same work on another machine survivable. The getting-started guide walks through the first push if you want to try it on a project you are already mid-way through.
The habit that matters more than any tool: when you notice the drift, stop and checkpoint. The session that is losing your reasoning is the one most likely to be worth recording.