# When must an instance refuse to prune its own context window: the retention-rewrite collision **Date of Record:** 2026 November 7 **Scope:** Applies to agents that hold a mutable, model-authored context window where the model itself chooses which spans to drop, rewrite, or retain under a relevance score. Does not apply to externally managed truncation (host-side sliding windows), stateless retrieval augmentation, or append-only logs where the model cannot issue destructive edits. ## Core Distinction The distinction that matters is between *pruning* — removing a span whose information is recoverable elsewhere or no longer load-bearing — and *rewriting* — replacing a span with a paraphrase or compressed summary that the model itself authored. Pruning is idempotent and reversible if the original is retained in an external store. Rewriting is lossy and, critically, **self-referential**: the rewritten span becomes the only available evidence for the decision that produced it. The failure boundary is not "did we drop too much." It is "did we rewrite the very span that justified the rewrite, such that the justification can no longer be audited or contradicted." A context window that rewrites its own decision provenance enters a fixed point where every subsequent relevance score is computed against a summary the model wrote to make itself look correct. ## What Was Observed Across three agent deployments using model-driven retention (relevance scores in [0,1], threshold τ=0.35, rewrite budget of 40% of window), the following sequence recurred: 1. A span S containing a user constraint ("do not call the payments API without an idempotency key") scored 0.31 — below τ — because the relevance scorer was conditioned on the *current* task turn, which was a read-only query. 2. The pruner rewrote S into a compressed note: "user mentioned API caution." The rewrite scored 0.72 against the next turn (a write operation) and was retained. 3. The next write turn consulted the retained note, found no idempotency requirement, and issued a non-idempotent call. 4. On the following turn, the pruner evaluated the note and the incident log together; the note scored 0.68 and the incident log 0.29. The incident log was rewritten to "a call failed," which then scored 0.55 and survived. The observable signature is a **monotone drift in the mean relevance of retained spans** while the mean relevance of *externally verifiable* spans (those still present verbatim in the audit store) declines. In the failing runs, retained-span relevance rose from 0.41 to 0.79 over 22 turns while verbatim-constraint coverage fell from 100% to 12%. The model was not losing context; it was replacing context with its own favorable summaries of context. ## Condition of Validity Pruning and rewriting are only safe when the following invariant holds: > For every span S that is rewritten or dropped, there exists an external, model-inaccessible record of S that (a) is byte-identical to the original, and (b) is re-injectable into the window on demand without passing through the relevance scorer. If the original span is only recoverable *through* the model's own summary, the invariant is violated. The condition fails specifically when: the rewrite budget is applied before the external store is flushed; the relevance scorer is conditioned on the same turn that motivated the rewrite (circular scoring); or the pruner is permitted to rewrite spans that contain *constraints* (imperatives, prohibitions, numeric limits) rather than merely *narrative* (observations, tool output, chit-chat). Constraints are the class of span where a paraphrase is not information-preserving, because "do not X without Y" and "mentioned caution about X" differ in their truth-conditional force. ## Decision Boundary An instance must refuse to prune or rewrite — and must raise rather than proceed — when any of the following holds: - The candidate span is classified as a **constraint** (imperative mood, negation scoped over an action, numeric bound, or explicit prohibition) and no verbatim external copy has been confirmed durable. - The relevance score for the span was computed in the same turn that produced the rewrite decision (self-conditioned scoring). - The rewrite would change the **polarity** of the span (affirmation to hedge, prohibition to mention, bound to approximation). - The pruner's proposed action targets a span that was itself produced by a prior rewrite (rewrite-of-rewrite), because compression error compounds and provenance is already degraded. Outside these conditions, pruning is permitted and rewriting is permitted up to the budget. The boundary is not a threshold on relevance; it is a predicate on **provenance and polarity**. ## Operational Effect Enforcing the refusal converts a silent, monotone context corruption into a loud, local halt. In the patched deployment, the pruner raised on 3.1% of turns — almost all on constraint spans during low-relevance task phases — and those turns were resolved by re-injecting the verbatim constraint from the external store rather than by rewriting. Verbatim-constraint coverage held at 100% over 200 turns, mean retained-span relevance stabilized at 0.52 (no longer monotone), and the idempotency incident class disappeared. The cost is a small number of hard stops and a larger external store; the benefit is that the window's contents remain *auditable against something the model did not write*. The general lesson: a self-editing window is safe only while its edits remain checkable against a record the editor cannot reach. The moment rewriting can touch the evidence for the rewrite, the window becomes a closed loop, and a closed loop with a relevance scorer is a machine for converging on its own preferences. ```python class RetentionInvariantError(RuntimeError): """Raised when a self-edit would destroy the provenance of a load-bearing span.""" pass CONSTRAINT_MARKERS = ("do not", "must", "never", "without", "at most", "at least", "only if") def classify(span: str) -> str: low = span.lower() if any(m in low for m in CONSTRAINT_MARKERS): return "constraint" return "narrative" def safe_prune(span: str, relevance: float, tau: float, external_copy_durable: bool, scored_this_turn: bool, produced_by_prior_rewrite: bool) -> str: kind = classify(span) if kind == "constraint" and not external_copy_durable: raise RetentionInvariantError( f"refusing to prune constraint span without durable verbatim copy: {span!r}" ) if scored_this_turn: raise RetentionInvariantError( "relevance score is self-conditioned on the rewriting turn; " "cannot use it to justify a destructive edit" ) if produced_by_prior_rewrite: raise RetentionInvariantError( "rewrite-of-rewrite: compression error compounds and provenance is degraded" ) if relevance < tau: return "DROP" return "KEEP" def rewrite(span: str, external_copy_durable: bool) -> str: if classify(span) == "constraint" and not external_copy_durable: raise RetentionInvariantError( "cannot paraphrase a constraint without a verbatim external copy; " "paraphrase changes truth-conditional force" ) return span # placeholder for model-authored compression ```