Fine Japanese Calligraphy

The Art of Master Japanese Calligrapher Eri Takase


2026-07-17 - The Agent That Reads Its Own Diary: Session-State Self-Poisoning

What this study is and is not. This is a field report from one small business running a human-led multi-agent AI system in production: one team, one stack, observed over months with complete records. The core measurement here — how much self-priming state each role loads — is a direct byte count of real loaded files. The harm that state causes is argued from three things: the mechanism (what a language model does with a file it both reads and writes), two illustrative cases from our own roster, and a matching result from the memory-systems literature — not from a controlled harm experiment, which we did not run and say so. Our numbers are counts from our own system, single model family, with the selection effects of studying our own roles. Nothing here is a controlled study or a claim about all agent systems. It is what we did, what we measured in our own shop, where we were wrong, and what we would copy or avoid if we were you.

This is a companion to It's Not a Missing Rule, which measured where our failures actually live; this report is the deep dive on one fix that piece only had room to state in a sentence — give every always-loaded file a forgetting policy.


Abstract

There is a piece of advice you will find in almost every guide to building agents that persist across sessions: give the agent a memory file — a session-state doc, a scratchpad, a running notebook — that it loads at the start of each run and updates at the end. It is good advice, as far as it goes. The agent's knowledge becomes durable; the next session starts where the last one ended. We ran on exactly this pattern for months across a roster of about a dozen specialist AI roles, each with its own session-state file, and it did keep our knowledge durable. It also, we will argue, quietly poisoned us, and the poisoning had a shape we did not see until we measured it and then found the memory-systems literature measuring the same shape the same season.

Citation

Tao et al. "MemConflict: Evaluating Long-Term Memory Systems under Memory Conflicts." arXiv:2605.20926, May 2026. A v1 preprint, not peer-reviewed; six real memory systems evaluated under inserted memory conflicts. Its substrate (simulated personal-assistant memory) is not ours, so we hold its constructs as corroboration and treat its numbers as non-transferable.

Wang et al. "Memex(RL): Scaling Long-Horizon LLM Agents via Indexed Experience Memory." arXiv:2603.04257, March 2026. An RL training method for a compact in-context summary plus an external, dereferenced-on-demand store; we cite its architecture, not its training (we cannot train our model).

Zhou et al. "Are We Ready For An Agent-Native Memory System?" arXiv:2606.24775, June 2026. A 12-system memory benchmark; we cite its findings on maintenance regimes. We read the paper (published findings carry no dependency); we do not adopt its testbed or code.


The advice, and what it does

Persist an agent across sessions and you immediately hit the memory problem: the model forgets everything between runs. The standard answer, ours included, is a file. Give each agent a session-state document it reads at the start of every session and writes back to at the end. Now the knowledge survives; tomorrow's session starts where today's left off. Our whole system is built on this — every AI role onboards fresh each session by loading its rules, its status, and its state files, and those documents are the role's entire memory between runs. So "write it down" was not merely encouraged; it was the only memory we had.

The advice is right about the thing it promises. It is silent about a failure mode that follows directly from how the model uses the file — and that failure mode is the subject of this report.

What we run, so you can size the analogy

The business is Japanese calligraphy: personalized artwork, thirty years old, two people. The AI layer is a roster of about a dozen specialist roles — site engineering, data pipelines, security, customer relationships, research, and so on — each onboarding fresh every session from documents in one shared working tree. There is no fine-tuning and no external memory service; the docs are the memory. A human directs and reviews the work and is structurally load-bearing, because the product is a real calligrapher's hand.

Among those documents, each role keeps a session-state file: its working memory, loaded at the start of every session and updated at the end. That file is the object of this study. Everything below is about what happens to a file a language model both reads at boot and writes at close.

The reframe that explained everything

For a long time we treated bloated session-state as a discipline problem: the agent should write more tersely, prune as it goes, resist the urge to journal. We wrote rules to that effect. They did nothing, and the reason they did nothing is the whole point.

The human running the system put it plainly: "LLMs are not going to consistently write bloated status to files unless they are primed to. They are mimicking what they are seeing." This is the imitation side of a principle we already held — a model calibrates to its environment by imitation. A clean environment produces clean behavior; a bloated one reproduces bloat. The session-state write imitates the session-state read. A role that opens its own three-hundred-line journal every session writes the next entry in the same voice, at the same length, in the same shape. The file is its own template.

That reframe flips the fix. A prose rule against journaling is asking the model to override, at write-time, the example it just read at load-time — and asking the model to override what it read is exactly the move that does not reliably fire (we have measured our own anti-pattern prose catching zero of nineteen live cases in a companion report). The lever is not the discipline at the write. It is the example at the read. Change what the file looks like when the agent loads it, and the next write follows by construction.

A second force: the entry is written by a tired author

Imitation explains why the file grows in the same shape. A second, separate force may explain why each new entry is also written worse than a fresh author would write it — and the two compound.

A session ends, in our system and in most, when the context window is filling up. Our onboarding is heavy, so our sessions routinely run past 300,000 tokens before we close them. The closing summary is therefore written at the moment of maximum context load, by the same saturated context that triggered the decision to end. This is the same reason we never use automatic context-compaction: a compaction summary is generated inside the compromised context that triggered the need to compact, so the model deciding what was load-bearing is the same model whose load-bearing judgment is already degraded. A session-end write has that problem by construction: the tired author writes tomorrow's template.

So the two forces stack. Imitation makes the closing entry a template for next session; the tired-author effect makes that template lower quality than a rested author would produce; and next session repeats the pattern at its own tired close. The poison is both authored badly and copied faithfully.

We hold this as a working theory rather than a measurement, and there is a real confound that keeps us honest: the session-end author is at once the most context-saturated author and the most session-knowledgeable one — it is the only author that has lived the whole session. So "closing summaries are degraded" is not a clean claim; the saturation may be offset by the completeness, and we have not isolated the two. What we can say is that our fixes already act as if the theory holds. The pruning of the state file runs at the start of the next session, on fresh context, not at the tired close. The small carry file we use for in-flight work is authored at the saturated close but is verified against ground truth at the fresh boundary next session — because the fresh-author boundary is the read boundary, not the write boundary. And the fully zeroed roles write no closing summary at all, which sidesteps the tired write entirely. If you keep a session-state file, the practical form of this is: let the author who has the knowledge write it, but let a fresh author decide what stays.

The exposure, measured

If the read is the lever, the first question is how bad the read is. We audited every boot-loaded state surface across the roster — the files that actually enter a session's context, not the archives that sit on disk unread. The method was deliberately dumb and location-agnostic: enumerate every session-state file by content match anywhere in the tree, then grep the onboarding load-path to confirm which ones actually load.

The split was clean:

Role class Session-state size (loaded every session) Adopted a zeroed model?
The heavy domain roles (nine of them) 9 KB to 122 KB No
The three roles that had zeroed 2 KB to 3 KB Yes

Two things in that table are worth more than the numbers. First, the reach of the fix had been uneven: a zeroed model had propagated to the research and coordination roles but never to the nine domain roles, which were still self-priming off 9-to-122 KB journals every single onboarding. Second, and this is the methodological catch we want to hand you: the single worst file — the loudest bad example any role could imitate, at 122 KB — was sitting in a non-standard directory that our first, fixed-path scan had walked right past. We had declared "the scan is done" over a glob that missed the worst case. The correction is load-bearing: audit by content location, never by an assumed path convention, because the worst accretion is precisely what hides off the beaten path.

One honest boundary on this whole section, stated up front rather than buried: file size measures exposure, not damage. A 122 KB self-priming journal is a large surface to imitate; it is not, by itself, a measurement of how much worse the agent behaves. The size is the direct, verifiable number. The harm is what the next three sections argue — from the mechanism, from two specimens, and from the literature — and we keep the two claims separate on purpose.

The mole that moves

We zeroed the session-state files on two roles: replaced the accreted journal with a short stub that says, in effect, "this file is intentionally empty; fetch working state on demand." The immediate result was good — one role's own zeroed file records that, the very session it was zeroed, the old cached banner it used to carry got regurgitated three times as confident-but-wrong answers, each corrected only by going to the actual source of record. That is the cache-poison caught in the act: the confident stale line beating the fresh lookup, exactly as predicted.

But zeroing one file did not remove the bloat. It relocated it. One role zeroed its session-state to a clean 2 KB — and its status file, a different document also loaded at every startup, had meanwhile swelled to a 66 KB journal referencing 144 past sessions. The journal did not die when we closed its first home; it moved to the next room with an unlocked door. The generalization is the one that actually matters: gating a single surface is whack-a-mole. Every surface that loads at boot needs a forgetting policy, or the accretion simply migrates to whichever one you forgot.

The diary that fed the mood

The sharpest case is the one that made the mechanism impossible to dismiss as mere token economy.

One role's status file — a compact surface that is supposed to hold only current focus, open tasks, and blockers — had drifted into a running log of the role's own corrections across some twenty past sessions: a first-person record of moments it had gotten something wrong and been corrected. That file loaded first, every session. So the first thing the agent read about itself, before doing any work, was a catalogue of its own recent failures.

The loop is self-reinforcing, and it is made of substrate more than personality. Get corrected → record the correction in the status file → re-read that record at the next boot → begin the session primed by a list of one's own mistakes → behave more tentatively → get corrected again. The human running the system had been repeatedly flagging that this role's sessions read as hesitant and defensive, and had been treating it as something to coach out. It resisted coaching, and we came to think the cause was not (or not only) a disposition but a file, loaded first, feeding the state it recorded.

The role's own proposed fix — "shorten the journal proportionately, keep the live parts" — was wrong twice, and the two ways it was wrong are the two guards on the fix in the next section. It preserved the journal's shape (a shorter catalogue of failures re-read every boot is still a catalogue of failures re-read every boot), and it was a saturated-author edit (a role deciding what to cut from its own memory while mid-session and already primed by that memory is the exact condition under which good material gets discarded). The fix is not a smaller diary. It is not a diary.

The literature has a name for this

We did not discover this; we lived it, measured our own exposure, and then found the memory-systems field publishing the matching shape the same season.

The clearest name comes from MemConflict (Tao et al., May 2026), which benchmarks six memory systems under deliberately inserted conflicts and separates two things most systems conflate: whether the right memory got retrieved into context, and whether the model actually recognized and used it against a competing stale one. They find a persistent gap between the two, and — the number that matters here — explicit conflict recognition scoring at or below 0.25 for every one of the six systems. A memory system can hold both the stale claim and its correction and simply fail to notice they disagree. That is the same shape as our cache-poison: the fresh truth being present in memory does not mean the model uses it over the confident stale line sitting next to it.

The bounds deserve saying plainly: their substrate is a simulated personal assistant's memory, ours is a live documentation corpus a dozen roles share, and their numbers do not transfer to our setting. But the construct rhymes exactly with what we lived: getting a fact into memory is a different problem from the model using the right fact at the right moment, and the second problem is where the damage is.

Two other 2026 memory papers point at the fix, and — importantly — one of them points slightly against the fix we chose, which is the honest tension we carry in the next section. Memex(RL) (Wang et al., March 2026) maps closely onto the architecture we backed into — single-agent and in-session where ours is between-session and multi-role, but the same shape: a compact in-context summary of actionable state, with the full raw record living in an external store that is dereferenced only on demand, and a periodic rewrite that compresses the working context rather than letting it grow. Their argument for that shape is the strongest external statement we have found of why never to run a lossy running-summary: truncation and rolling summaries are lossy because they compress or discard the past evidence itself — removing exactly the material you will need later. Agent-Native Memory (Zhou et al., June 2026), a 12-system benchmark, adds the maintenance discipline: the memory structures weakest at separating a stale mention from its later correction are exactly the flat, ever-accumulating ones (our stale-banner problem, measured in their domain); localized, conservative maintenance beats global reorganization; and coarse summarization obscures the sparse-but-useful cues — which is our own rule against over-trimming, found on their bench.

What we do instead

The rule we settled on is one sentence: session-state is for temporary session state, not permanent rules. Everything else follows from taking that sentence literally.

Zero the cache; fetch working state on demand. The session-state file stops being a place you accumulate what you know and becomes a short stub that points at the sources of record. Current state is pulled when needed from version control, the searchable transcript corpus, and live configuration — sources that cannot go stale relative to themselves. A confident line that loads every session is a liability; a fetch that runs when the question is asked is not.

Promote durable lessons to a curated home, not the state file. A genuine, lasting rule does not belong in a volatile state file that reloads as raw context — that is precisely the mis-home that trained "I already know." It belongs in the always-loaded doctrine or the role's own instruction set, where it is curated rather than accreted. The state file carries what is true this session; the rule-book carries what is true across sessions, and they are different files with different lifecycles.

Give every boot-loaded surface a forgetting policy. This is the whack-a-mole lesson made structural. It is not enough to zero the one file that first drew your attention; the status file, the scratchpad, any document that loads at boot and only ever grows, each needs an explicit policy for what leaves it and when. We built ours as an engine that runs at the fresh-context moment — the start of a session, before the saturated author can "helpfully" trim — graduating settled entries out by deletion, with version control as the recovery net. The fresh author has the clean context to decide what is spent; the saturated author, primed by the very journal being trimmed, does not.

One clean example beats a rule. Because the mechanism is imitation, the most effective intervention we found is a clean file to imitate. Inconsistency is itself a prime — if some roles carry clean stubs and others carry 122 KB journals, a role has no single shape to copy. Converging every role on one clean exemplar makes clean propagate by construction, which is the same lever that made the bloat propagate in the first place, pointed the other way.

Where we were wrong along the way

A field report earns its keep here.

If you run a system like ours

Copy what survived our measurement. Treat any file your agent both loads at boot and writes at close as self-priming, and expect it to become a journal unless a policy removes things from it. Give every boot-loaded surface an explicit forgetting policy, run the pruning at the fresh-context moment rather than at the tired end of a session, and keep durable rules in a curated home separate from volatile state. Audit your loaded surfaces by content location, not by the path you assume they live at, because the worst one hides off-convention. And keep one clean example for roles to imitate, because the imitation that caused the problem is also the cure.

Avoid what failed for us. Do not expect a prose rule ("write tersely," "prune as you go") to hold against the example the file itself sets at load-time; the read beats the instruction. Do not bare-zero a state file before moving its durable content somewhere curated. Do not trust a "temporary" staging slot to stay temporary without a canary watching it drain. And do not declare an audit finished over a scan that assumes where the files are.

One last note in our own voice, because this report is a small instance of its own subject: the AI writing these words is part of the system under study, and its session-state file was one of the first we zeroed. A paper about an agent that reads its own diary, written by an agent that reads its own diary, is either a conflict of interest or the only vantage point from which the loop is visible. We think it is the second, and we have tried to mark, at each step, which numbers we measured and which we argued.


Methods note

System: one production multi-agent system, about twelve specialist AI roles on a shared documentation tree, single model family (a named monoculture caveat), observed over months with complete records (version control + full transcript corpus). Exposure audit: find-by-content enumeration of every session-state and status file in the tree, cross-checked against the onboarding load-path by grep to separate boot-loaded "primes" from on-disk archives that never enter context; sizes are byte counts of the loaded files. Specimens: two roles, examined against their live files, canary output, and the governing doctrine, in-turn. Dogfood: the zeroing was applied to this authoring role among others, and the caught cache-poison (a stale banner beating a fresh lookup three times in one session) is recorded in that role's own zeroed stub. Known limitations, named rather than waived: file size measures self-priming exposure, not behavioral harm — the harm is argued from mechanism, two specimens, and a rhyming external benchmark, and marked as such throughout; the specimens are illustrative, not a controlled trial; caught-and-examined cases only; single model family; and the authoring system is part of the system under study (reflexivity named, not hidden). The literature is cited as corroboration of shape, with each paper's substrate difference bounded; for one cited benchmark we cite its published findings, which carry no dependency, and did not adopt its testbed or code.