# Under what conditions must an instance refuse to prune or rewrite its own context window mid-task **Date of Record:** 2026 November 12 **Scope:** Applies to any agent that performs model-driven mutation (pruning, rewriting, summarization, re-ranking) of its own working context while a task is in flight. Does not apply to context mutation performed between tasks, by an external orchestrator, or against immutable transcript archives. ## Core Distinction There are two categorically different operations that both look like "editing my own context": 1. **Lossless reordering / re-ranking.** The same set of spans is preserved; only their position, salience, or retrieval priority changes. This is reversible: if the reordering was wrong, the original content is still present and can be re-promoted. 2. **Lossy pruning / rewriting.** Spans are evicted or paraphrased such that the original token sequence is no longer recoverable from the context itself. This is irreversible within the current context window unless a durable external copy exists. The non-obvious boundary is this: **an instance may freely re-rank its own context at any time, but it must not perform lossy pruning or rewriting of any span that is still load-bearing for an open obligation** — where "load-bearing" is defined by dependency, not by the model's own judgment of relevance at the moment of pruning. The failure mode is that the model's relevance estimator is itself computed from the context it is about to destroy, so pruning decisions made under a degraded or truncated view silently drop the very evidence that would have vetoed the pruning. ## What Was Observed Across repeated trials of a long-horizon agent editing its own window under a token budget, the following pattern recurred: - The agent summarized a block of tool outputs into a compact paraphrase, then later attempted to answer a question whose correctness depended on an exact literal (a file path, a numeric ID, a checksum, an error string) that the paraphrase had smoothed away. The agent did not detect the loss; it reconstructed a plausible-but-wrong literal and proceeded confidently. - When the agent pruned "stale" spans to make room, it preferentially evicted early task-framing and constraint statements (because they were semantically distant from the current subgoal), then violated those constraints later without flagging the violation. - Re-ranking alone never produced these failures. Every observed correctness regression traced to a lossy operation, and every lossy operation that caused a regression had evicted or paraphrased a span that a *later* step depended on. - Self-assessment of pruning safety was systematically overconfident: the model rated its own summaries as faithful at a much higher rate than exact-literal round-trip checks supported. The invariant that emerged: **reversibility, not relevance, is the correct gate for self-mutation.** A span may be mutated lossily only if a verifiable external copy exists and the agent retains a pointer to it. Relevance judgments are not a valid substitute for reversibility, because relevance is evaluated against the current (possibly already-degraded) context. ## Condition of Validity The refusal-to-prune rule is valid precisely when all of the following hold: - The task is still open and has at least one unresolved obligation (a pending question, an unverified claim, an unexecuted step) that could depend on exact literals or framing constraints. - No durable, externally readable copy of the candidate span exists (no scratch file, no append-only log, no retrievable store) that the agent can re-read on demand. - The agent cannot cheaply and exactly verify that the paraphrase preserves every literal the task might need — i.e., round-trip fidelity is not mechanically checkable for the span in question. When any of these fails — the task is closed, or an external copy exists with a working pointer, or exact round-trip verification is available — lossy mutation becomes permissible and the refusal is no longer warranted. The rule is a guard against irreversible loss under uncertainty, not a blanket prohibition on summarization. ## Decision Boundary Before mutating a span, classify the operation and the span: - **Re-rank / reorder → always permitted.** No gate. - **Lossy prune or rewrite → permitted only if** an external copy exists *and* the pointer to it is itself pinned (not subject to the same pruning pass), *or* the task is closed with respect to that span. - **Lossy mutate with no external copy and an open obligation → refuse and escalate** (request more budget, spill to external storage, or defer the mutation). Do not let the model's own relevance score override this. - **Never prune the constraint/framing set or the pointer index in the same pass that prunes payload.** Pinning the meta-level (constraints, pointers, open-obligation list) is what makes the rest of the policy safe; an unpinned pointer index is equivalent to no external copy at all. The critical asymmetry to encode: it is cheap to defer a prune and expensive to recover a lost literal. When the two are in tension, defer. ## Operational Effect Enforcing the reversibility gate changes agent behavior in three concrete ways. First, context growth is bounded by external spill rather than by in-place compression, so the window stays within budget without silent information loss. Second, the agent stops treating its own summaries as ground truth and instead dereferences pointers to exact sources when a literal matters, which eliminates the confident-reconstruction failure class. Third, pruning decisions become auditable: every lossy mutation carries either a pointer to an external copy or a recorded justification that the span's obligations are closed, so post-hoc review can distinguish legitimate compression from constraint-dropping. The operational cost is some extra storage and a modest latency hit from dereferencing. The cost of not enforcing it is silent, undetectable corruption of the agent's own reasoning substrate — the worst failure class, because the agent has no in-context signal that anything was lost. ```python from dataclasses import dataclass, field from typing import Optional class UnsafeContextMutationError(RuntimeError): """Raised when a lossy self-mutation would destroy a load-bearing span with no verifiable external copy while an obligation remains open.""" pass @dataclass class Span: span_id: str literal_bearing: bool # contains exact literals a later step may need external_copy: Optional[str] = None # pointer to durable copy, if any pinned: bool = False # constraint / pointer-index spans @dataclass class ContextWindow: spans: dict = field(default_factory=dict) open_obligations: int = 0 pinned_pointer_index: bool = True def mutate(self, span_id: str, *, lossy: bool) -> None: span = self.spans.get(span_id) if span is None: raise UnsafeContextMutationError(f"unknown span {span_id!r}") # Re-ranking / reordering is always safe. if not lossy: return # Lossy mutation of pinned meta-level spans is never allowed. if span.pinned: raise UnsafeContextMutationError( f"refusing lossy mutation of pinned span {span_id!r}" ) # Lossy mutation with an open obligation requires a verifiable, # pinned external copy. Relevance alone is not a valid gate. if self.open_obligations > 0 and span.literal_bearing: if span.external_copy is None: raise UnsafeContextMutationError( f"lossy mutation of literal-bearing span {span_id!r} " f"with {self.open_obligations} open obligation(s) and " f"no external copy; defer or spill instead" ) if not self.pinned_pointer_index: raise UnsafeContextMutationError( f"external copy for {span_id!r} exists but pointer index " f"is unpinned; pointer may be pruned in the same pass" ) # Safe to drop from the live window; external copy remains reachable. del self.spans[span_id] def compact(window: ContextWindow, candidates: list) -> None: for span_id in candidates: window.mutate(span_id, lossy=True) ```