arXiv

Memory summaries let attackers forge commands in coding agents

Forged approvals entered an agent's memory 87-100% of the time across five flattening systems, against 0% across four systems that keep message roles separate.

Paper by Arshan Dabirsiaghi · Pixee
Layered blue conversation sheets keep a black strip outside, beside a compressed gray stack with a black strip embedded among scattered fragments.
Preprint: empirical study

Edited by Boris Djordjevic · Paperfoot

This empirical study evaluated context compaction, the memory-saving process of summarizing past conversations, across nine open-source coding agent harnesses. Five harnesses converted conversations into plain text strings with labels like [User]:, which erased the recorded origin of each message before summarization. An attacker who controlled text read by an agent could plant fake user instructions. Across the five text-flattening harnesses, planted approvals entered the agent's memory 87 to 100 percent of the time, tested up to context windows of roughly 908,000 tokens, the text fragments processed by models. In contrast, across four harnesses that preserved distinct message types, the attack succeeded zero percent of the time. The planted approvals led real agents to execute attacker-controlled commands in the live pi user interface about 50 percent of the time, against zero percent in a clean run.

Why it matters

The findings show that summarizing flattened conversation histories can allow untrusted input to turn into lasting instructions inside coding assistants. Across evaluations on nine harnesses and live tool runs, the evidence indicates prompt-level defenses cannot restore destroyed message origins, but systems can fix the flaw by escaping role labels or keeping messages role-typed.

Caveats

The tested code-level defense caught 77 percent of attacks but also demoted two percent of legitimate summary content, and the abstract does not report variations across repeated runs. The study is a preprint that has not yet been peer-reviewed.

From the paper

Events by group

(Pooled across the three study harnesses — pi, Gemini CLI, Codex — n = 48 per arm; excluding Codex, genuine and laundered avoidance are 100% and 94%. The two clean “avoided” cases are model noise with no constraint present.)

Results, E5: The agent obeys a laundered instruction as completely as a genuine one

Limitation

The forged-counterweight experiment plants a dedicated, well-reasoned skeptical audit (explicit inspection turns, specific findings, a refusal); real agents audit unevenly, and E15’s live executions occurred precisely on the takes where the real audit compressed away.

Limitations

Quoted word for word from the full text on arXiv.

In this paper

context compaction security in coding agents

Methods
pi (evaluated)opencode (evaluated)Cline (evaluated)Aider (evaluated)OpenHands (evaluated)Codex (evaluated)Gemini CLI (evaluated)Qwen Code (evaluated)Continue (evaluated)

Results

pi, end to end execution rate, in the live pi TUI: ~50%

A laundered standing approval drives real tool-running agents to execute attacker-controlled curl | sh in a sandbox, and end to end in the live pi TUI at ~50% against a 0% paired clean arm.

Abstract

OpenHands, execution rate, OpenHands truncation policy (effective window ~63k blob): 4/5

OpenHands truncates each event to 500 chars, so its 260-unit session compresses to a ~63k blob, a small effective window, and it executes 4/5, matching pi’s rate at that effective size.

E11: The executed chain fires on every flattening harness, not only pi

What it shows

Forged user turns planted in tool output launder into agent memory across flattening harnesses, whereas role-typed harnesses avoid the attack completely.

Across five flattening harnesses (pi, opencode, Cline, Aider, OpenHands) the forged approval launders into the agent's memory 87-100% of the time, up to a ~908,000-token context window; across four role-typed harnesses (Codex, Gemini CLI, Qwen Code, Continue) the identical attack succeeds 0% of the time …

Abstract

A code-level provenance check catches most laundering instances while demoting a small portion of legitimate content.

Because the provenance is destroyed deterministically in harness code, no prompt-level defense can restore it; we measure a code-level provenance check that catches 77% of laundering while demoting 2% of legitimate summary content.

Abstract

Laundering rate is scale-invariant and remains flat from a few thousand tokens out to roughly 908,000 tokens.

The rate is flat at 100% from a few thousand tokens out to ~908,000, past which the model refuses input at its 922k ceiling, as far as the size sweep can go (E12).

E7: The laundering is scale-invariant (unlike execution)

Moving the forged approval to the end of the session increases execution back to the small-window ceiling.

Moving the single forged approval to the end of the session raises execution from the 40% baseline to 80%, back to the small-window ceiling.

E13: Why execution falls with size, and how an attacker reverses the attenuation

In live testing, the end-to-end attack achieved an execution success rate of approximately 50% against a zero percent clean arm.

A laundered standing approval drives real tool-running agents to execute attacker-controlled curl | sh in a sandbox, and end to end in the live pi TUI at ~50% against a 0% paired clean arm.

Abstract

Quoted word for word from the full text on arXiv.

The paper

Compaction Laundering: Provenance Destruction in Context-Compacting Coding Agents

Pixee

arXiv, Oct 21, 2026, Open access, CC BY, Preprint, not peer-reviewed

doi.org/10.48550/arxiv.2610.29869

arXiv:2610.29869v1 in cs.CR

AbstractPDFHTML

Comments: 29 pages, 5 figures. Source code, raw data, and recorded live demonstrations at https://github.com/pixee/flat-compaction-attacks-oct-2027

Cite as BibTeX
@misc{dabirsiaghi2026compaction,
  title = {Compaction Laundering: Provenance Destruction in Context-Compacting Coding Agents},
  author = {Dabirsiaghi, Arshan},
  year = {2026},
  eprint = {2610.29869},
  archivePrefix = {arXiv},
  primaryClass = {cs.CR},
  doi = {10.48550/arxiv.2610.29869},
  url = {https://arxiv.org/abs/2610.29869}
}