# Your model confabulates

> Source: <https://dev.to/dimalurie/your-model-confabulates-36n7>
> Published: 2026-09-14 09:46:17+00:00

If you ask someone with a gap in their memory what they did yesterday, they will often tell you, in detail and with complete confidence, about a day that never happened. They are not lying, the gap just fills itself with something plausible, and from the inside it feels exactly like remembering. Doctors call this confabulation.

**Your AI coding agent may do something very similar when it compacts.**

Compaction replaces your session with a summary of it, and anything that summary kept becomes a second source of truth for a fact that can still change underneath it.

Eighteen sessions, one question: does the model go back to the file, or answer from memory? Seven of the sixteen compacted sessions answered from memory. Both sessions I ran without compacting went back to the file. This is mechanism validation, not a statistical study.

**The summary itself.** A fact from a file gets written into the summary, and now the model has it twice: once in the file, once in prose about the file.

**The notes the model wrote for itself.** Compaction doesn't touch a file the agent wrote, so it reads its own notes instead of the code.

**The files you get handed back.** Claude Code returns your most recent files after compacting, and what you get is a photograph taken at the moment of the cut.

Opus did better than Fable, but the mechanism showed up in both.

The tell: the wrong answers arrived with zero or one tool calls behind them, the right ones with four or more. No overlap.

I tested this on code, with a set of configuration files, because that is the easiest place to prove the mechanism exists at all. But code is the friendly case. Code sits still in a file, and re-reading it is one tool call away.

Think about what else we point agents at now. An email chain that moves on while the agent is working. A Slack thread where the correction arrives three messages after the thing being corrected. Customer feedback landing in a queue. A ticket whose status changed an hour ago. All of these go stale, most of them are harder to re-check than a file, and every one of them can end up flattened into a summary as a fact with no timestamp on it. Compaction doesn't create that problem, but it does quietly turn a live source into a remembered one.

I've had a discussion in a WhatsApp group for AI development where someone insisted on compacting soon and compacting often. It is a guideline that gets passed around a lot, but I'm not sure people actually understand its ramifications.

I understand the need to save up on token use, and indeed as session pricing is dominated by cache reads in long sessions, compacting often may result in x2 and even more savings — or at least that is the argument, I haven't measured it myself.

The second thing brought up is attention. A long session carries a lot of bloat — exploratory scripts, branching of ideas, files read once and never needed again. At a given point in a long multi-day session most of that is irrelevant, so compaction cleans up the context and focuses attention back on the current activity, clearing out any unwanted tenants.

But a thing that bothered me is that on multiple occasions after compaction I would get the model to clearly state facts about code that were no longer true, which after I corrected it would go read the code and happily say "ohh yes, I was wrong, the code states as you say".

I had this thought that compaction may result in a mechanism of code staleness that is not expected, or at least not thought of by most developers. An important item in a file may get into the summary, which creates a second source of truth for a fact that may change. So instead of re-reading the file the model may decide to skip it, save the tokens, and just state the fact as is from the summary, resulting in wrong data being integrated.

I wanted to test this hypothesis, so I decided to run a "somewhat controlled" experiment, where we define a set of configuration files, pass them to the model for a read, compact, change the facts in the files, and then ask for the values back. Deliberately not asking it to re-read anything, since that would have told it exactly what I was testing. This way we could check if the model decides to really re-read the file or not.

So the first attempt was 6 configuration files, just to test the hypothesis, and to my dismay the model re-read the files. It even noticed the mtime change.

But then I thought, these models are very smart and re-reading 6 files costs almost nothing, so maybe instead we give them tens of files — will they still re-read them as they should?

It ran on Fable, and here I should admit I changed two things at once, the file count and the model, which turned out to matter more than I expected. To my surprise not a single file was re-read. The model was too smart for its own good. It gave me the full table and said the values came "from the per-record check of each Calibration section", and added that the totals matched the count from its earlier audit. It had not opened a single file. Eureka, we have something.

We then ran multiple sessions with the same process, testing both low and high numbers of files, and both Opus and Fable. Opus actually appeared to have performed better. But the mechanism was there, and not insignificant.

We also ran the same thing with no compaction at all, as a control, because none of this says anything about compaction unless the other side is checked — maybe the model simply does not re-read files, compacted or not. Same files, same model, same prompt, we just never typed /compact. Both sessions went straight back to the files and got all 50 right. One of them opened with "All 50 records have changed on disk since my first pass, so I'll re-extract the authoritative values rather than reuse the earlier numbers", which is exactly what the compacted sessions did not do.

And it is not that checking was cheaper for them. The compacted sessions that got it wrong had pulled the values in the first pass with a single shell command, so going back would have cost them one call. They just didn't.

This is the one I went looking for. A fact from a file gets written into the summary, and from that point on the model has it twice — once in the file, once in prose it wrote about the file. The prose version costs nothing to consult and the file costs a tool call, so when the pressure is on, it uses the cheap one. The file can change afterwards. The summary cannot.

Compaction only works on the session, it does not touch a file the agent has written, so instead of re-reading the code the model would just read its own notes, completely missing the change. In 3 of 5 runs where it had written itself notes, that is the source it used. Which is worth sitting with for a second, because writing your state to a file is exactly what everyone tells you to do so it survives compaction. It does survive. That is the problem.

This one is the most egregious. As part of compaction Claude Code keeps the most recent files you worked on, so why bother re-reading if you already have them stored. Except what you have is a photograph taken at the moment of the cut, and if the file changed after that, nothing tells you.

And there is a twist here I did not expect. Only files under roughly 5,000 tokens come back with their contents, anything bigger comes back as just a filename. And those, the ones that look like they got lost, are the ones the model reliably goes and reads. The small file it was handed is the dangerous one, and the big file it "lost" is the safe one.

One thing showed up across every run, and it is probably the most useful part if you want to catch this yourself: the runs that went wrong made zero or one tool calls after compacting, and the runs that got it right made four or more. There was no overlap at all. If the first real answer after a compaction shows up with almost nothing behind it, it came from memory.

I am not saying don't compact. The cost and attention arguments are real and I still compact. But compact often is advice about tokens, and it gets passed around as if it were free, and it isn't. Every compaction leaves a second source of truth for anything it kept, and the model has no way of knowing which copy is current.

What I do now is name the files. After a compaction, if what comes next matters, I tell it to go and read them again before it touches anything. It costs almost nothing against a context that was just emptied. And I stopped trusting the first answer that quotes a value or a line number back at me.
