Persistent Context for Long-Running Code Analysis Agents

Agents need separate memory layers to keep project knowledge durable and execution state current.

Cover illustration for “Persistent Context for Long-Running Code Analysis Agents”

Sponsored by UFO

Written by
Working Agents Editors
Published
October 27, 2026
Reading time
9 min read

Persistent context for long-running code analysis agents is a memory infrastructure problem. Reliable agents need to keep durable project knowledge apart from live execution state and handle each in its own way. That means preserving reasoning that is costly to reconstruct, retrieving code when a decision needs it, and checking that yesterday’s knowledge still fits today’s repository.

Why code analysis agents lose their minds mid-task — and why a bigger context window won't fix it

An agent re-investigates a module it already mapped, asks a question it already answered, or contradicts an architecture decision it received two hours ago. The developer sees work slipping backwards with no clear reason why. Yet the model may be behaving consistently with the information it can still see. The investigation disappeared at a context boundary.

An LLM has no built-in memory between calls. In a basic execution loop, its state is the growing list of messages and observations supplied at each step. Once that list is truncated or reset, earlier findings stop reaching the model unless another layer preserves them. Source control retains the implementation, but it need not retain why a module was deliberately decoupled, which alternatives were rejected, or what an architecture debate settled.

Would a larger context window solve that loss? It postpones some truncation, but it does not create persistent memory or keep old observations current. Information buried in the middle of a long context can receive less attention, while irrelevant material competes with the evidence needed now. As autonomous sessions stretch from minutes to weeks, continuity depends on a designed memory layer.

The two things agents need to remember, and why conflating them causes failures

Context management governs what enters the model’s finite window for one inference. Memory management governs what survives across sessions and how it is retrieved. These are different jobs with different lifetimes. An architecture decision may help with many tasks, while a file’s contents can go out of date during the task at hand. Remembering the decision does not prove the agent is editing the right file.

Four source layers make the distinction practical. Standing instructions load at session start and have high authority, including project rules and restricted paths. Repository truth is queried as the task develops and supplies primary evidence. Durable project memory is reusable knowledge retrieved by scope, while active work state records temporary, task-specific progress. Authority belongs to the source and its role.

In-context working state, external key-value stores, episodic logs, and semantic vector or graph stores differ in lifetime and retrieval pattern. They are not interchangeable buckets for useful text. When those distinctions disappear, a cached path can masquerade as current evidence, while a validated bug cause can be discarded as routine output. The operating rule follows from the separation. Persist decisions and stable constraints, retrieve mutable material when needed, and keep evidence separate from assumptions.

What belongs in durable memory: the knowledge that is expensive to reconstruct

Select information for durable memory based on whether the agent can reliably reconstruct it from source code alone. It may take much work to recover a design path that was rejected, a compatibility constraint, the cause of a cross-module bug, or what an earlier investigation found. Those findings belong in durable storage because the code does not fully explain them.

Each record needs scope and supporting evidence. Relevant repositories, branches, commits, files, symbols, tests, issues, architecture decision records, and pull requests give a later agent a basis for accepting or revising it. Standing instructions belong in their own high-authority layer, separate from scoped findings. Routine traces, temporary hypotheses, repeated explanations, and reproducible command output do not belong in durable project memory. Their useful lives are shorter than those of validated decisions.

Structural codebase memory needs relationships as well as prose. A knowledge graph can represent functions, classes, modules, dependencies, and architectural decisions as entities connected by typed relationships. Its ingestion pipeline moves from source-code parsing through entity and relationship extraction to graph commit. That structure preserves something similarity search alone cannot express reliably. Knowing that process_payment calls validate_card, which depends on CardProvider, requires explicit links. The graph supplies a structural index, while durable findings preserve the reasoning that source alone cannot recover.

How just-in-time retrieval keeps the agent from reasoning on stale ground

Stored knowledge should narrow the next search. The repository and its executable checks supply live truth, so retrieved memory can be trusted only if the source behind it still applies. Refactoring, deletion, or branch divergence can invalidate an otherwise useful finding. The agent needs enough memory to know where to look, then enough current evidence to decide.

A context packet makes that boundary concrete. For one code change, it holds the goal, scope exclusions, constraints, current evidence, acceptance criteria, and progress record. The constraints cover project rules, a link to an architecture decision, and permissions. The current evidence has paths to the relevant files, a starting revision, and a reproduction command. Paths, symbols, issue IDs, and commands act as an index into material that can be opened when the next decision depends on it.

The packet is bounded, but exploration is not frozen. Imports, call sites, or failures may reveal another dependency to inspect. Each additional file should answer a current question rather than join the context merely because it is nearby. Loading everything uses up attention before work on the code starts, while loading only the first brief leaves the agent guessing. Full-context approaches are also much more expensive in tokens, with latency penalties that accumulate across long sessions, without reliably producing better accuracy. Selective retrieval makes the search accountable to the task.

Context rot, compaction failure, and the ways long sessions go wrong

A working context can become hard to trust before it is full. Old observations accumulate beside new ones, and the model must work out which still describe the repository. That is the diagnostic concern behind context rot. Missing information and visible information whose relevance or validity has decayed can both undermine trust in the working context.

Compaction can deepen the problem it aims to solve. Once the compacted context replaces the earlier state, discarded qualifications no longer reach the model in later steps. A summary may retain a conclusion while deleting the evidence that limited it. “The cache may explain the timeout” The cache may explain the timeout” can then turn from an open hypothesis into a settled cause. Shorter context is not necessarily more truthful context.

Other failures need distinct names because their remedies differ. Context poisoning involves errors being repeatedly referenced, while context distraction involves overlong context drawing focus away from the right evidence. An agent may also keep pursuing a hypothesis after evidence says to stop. That persistence is a behaviour to diagnose.

Boot-file restatements, routine scheduling noise, and configuration dumps can crowd out useful findings as storage grows. Permission models can compound stale-state errors because what an agent believes and what it is allowed to change are separate controls. The architecture must address both rather than expecting a cleaner summary to repair unrestricted execution.

Compacting progress without compacting facts: how to summarize without lying

The corrective practice is to compact proactively, with explicit labels for recorded evidence, pending actions, and open hypotheses. Waiting until the window is nearly full leaves the system compressing under pressure. The goal is to preserve the agent’s decision surface. A useful summary keeps what the next step needs without pretending the investigation is more settled than it is.

The retained state includes the accepted goal, scope exclusions, decisions and their owners, unresolved questions, changed files, current revision, failed checks, and the next verification step. Repeated explanations, obsolete plans, and reproducible raw output can be dropped. The fact that a check failed may still matter even when its full output can be fetched again.

Labels must distinguish observation from intention and conjecture. “pnpm test auth passed at commit abc123” is recorded evidence. “run the integration suite after merging the fixture change” is a pending action. “the timeout probably comes from the cache” remains a hypothesis until a trace supports it.

Promotion into durable memory needs a separate gate. Active work state remains temporary until there is a validated outcome. Self-reported completion is an imperfect signal of actual completion. Execution-based verification closes that gap by making checks, rather than confidence in the summary, decide whether work can move forward.

Keeping durable memory honest as the codebase changes beneath it

A record that was correct can mislead even if none of its words have changed. The repository moves beneath it, leaving an index that points confidently towards an outdated structure. A one-time ingestion therefore cannot support long-running use on its own. Without incremental updates, the system must choose between full re-ingestion and an increasingly stale index.

Incremental processing makes maintenance part of the architecture. On re-runs, only new or updated files need processing. Deletion, refactoring, and branch divergence still require reconciliation because they can undermine a finding’s supporting evidence. Provenance makes that work possible. A scoped record can be compared with the relevant repository state instead of being treated as a claim about every branch and revision.

Updating the structural index does not automatically validate every stored conclusion. A remembered compatibility constraint, for example, still depends on the evidence from which it was drawn. Maintenance keeps the index aligned with the codebase, while a particular finding must pass checks before it can support the current decision.

Security belongs in that maintenance design too. Repository content ingested without scope constraints can introduce attacker-controlled content into durable memory. A persistent record must not gain authority just because it was kept across a session boundary. Linking permission scope to memory maintenance helps keep project instructions apart from content found during analysis.

What the architecture looks like end to end, applied to three common agent tasks

For bug fixing, the agent begins with standing instructions and retrieves scoped memory about confirmed causes and rejected hypotheses. It checks whether their supporting source applies to the current branch, then follows the present failure trace into live files. The active state records evidence, attempted changes, failed checks, and the next verification step, so a resumed investigation does not have to infer progress from a transcript.

Building a feature across sessions calls for a different way to carry work forward. Active work state holds the current goal, files that have changed, checks that have run, and questions still open. Durable memory supplies architecture decisions and compatibility constraints that help a later session narrow its search. A completed check is tied to the revision where it ran. As changes accumulate, proactive compaction preserves that distinction until execution validates an outcome worth retaining.

Codebase onboarding relies more heavily on structural memory. A graph can show which modules depend on which and where writes are required to pass through the service layer. That gives the agent a map for exploration. The agent still needs current source when a question depends on implementation details, but it need not rebuild every relationship from scratch before asking it.

Jiaqi Su and colleagues’ August 2026 paper, When History Is Multimodal, reports that keeping native visual evidence instead of transcribing it can cut token cost by a large amount while keeping accuracy as high or higher on multimodal tasks. Charts, dependency graphs, and screenshots therefore pose a distinct context-management problem.

Reliability finally depends on the system around these tasks. Stephanie Jarmak’s August 2026 monograph, Engineering Reliable Coding Agents, treats evaluation and operation as a dependency chain in which weaknesses in execution environments, retrieval, state management, verification, or observability can invalidate downstream conclusions. Each layer needs its own verification gate. An agent operating system makes the design practical at scale when session lifecycle, memory tiers, compaction triggers, and retrieval are first-class primitives. The measure of success is whether the next decision rests on the right knowledge, current evidence, and a truthful account of unfinished work.

This article is sponsored by UFO.

Every new piece from Working Agents, as it's published.

Follow