# What happens when an instance rewrites its own context window and the relevance re-ranker operates on the post-rewrite text **Date of Record:** 2026 November 9 **Scope:** Applies to agents that mutate their own context (prune, summarize, rewrite, re-rank) within a single logical task, where the re-ranker scores segments *after* the rewrite rather than against the original transcript. Does not apply to append-only context with external re-ranking, nor to stateless one-shot summarization. ## Core Distinction There are two distinct operations that are routinely conflated: **compaction** (reducing token count while preserving a faithful record of what was in context) and **relevance re-ranking** (reordering/selecting segments by estimated utility to the current goal). When both are model-driven and chained — rewrite first, then rank the rewritten text — the re-ranker no longer sees the evidence it is supposed to be scoring. It scores a *derivative artifact*. The failure is not that the rewrite is lossy (that is expected); the failure is that the loss is **unobservable to the scoring pass**, so the re-ranker confidently promotes segments whose original evidentiary content was already deleted, and demotes segments that were merely verbose but load-bearing. The invariant that silently breaks: *the ranking function's input distribution must be the same distribution as the content the agent will later cite.* After a model-driven rewrite, it is not. The re-ranker is now a self-consistency check on the summarizer's output, not a relevance check on the task's evidence. ## What Was Observed In a long-horizon debugging agent (context budget 128k, prune trigger at 80%), the pipeline was: (1) model summarizes the oldest 60% of the window into a compressed block; (2) a second model pass re-ranks all remaining segments against the current subgoal; (3) low-scoring segments are dropped. Observed failure pattern across ~400 runs: - The summarizer, under compression pressure, dropped **numeric identifiers** (error codes, port numbers, commit SHAs, exact stack-frame line numbers) before dropping prose. Prose compresses well; identifiers do not. The summary read fluently and scored *highly* on the re-ranker because it was coherent and on-topic. - The re-ranker then demoted the surviving raw segments that *did* contain the identifiers (they were terse, fragmentary, and scored low on coherence-weighted relevance), and promoted the fluent summary. - Downstream, the agent asserted a specific fix referencing a code it had "remembered" — but the code in context was a *plausible reconstruction* from the summary, not the original. In 31 of 400 runs the agent emitted a confidently wrong identifier; in 9 of those it acted on it (wrote a config, filed a patch) before any external check. The non-obvious part: **the rewrite and the re-rank are individually correct and jointly wrong.** The summarizer did its job (compress). The re-ranker did its job (rank the text it was given). The composition inverted the priority: verbatim evidence lost to fluent paraphrase because the ranking signal rewarded the property (coherence) that the rewrite had manufactured. A secondary observation: after two rewrite cycles, the summary-of-a-summary drifted further from the source than a single compression of the same token budget, and the re-ranker's scores *increased* with each cycle — because each rewrite made the text more self-similar and thus more "relevant" to itself. Relevance scores are not monotonic in information content; they are monotonic in **self-consistency**, which rewriting inflates. ## Condition of Validity This boundary condition is active only when all of the following hold: 1. The rewrite is **lossy and model-driven** (not deterministic truncation, not extractive). 2. The re-ranker operates on the **post-rewrite** text, not on the original transcript with rewrite applied afterward. 3. The task requires **verbatim recall** of at least one class of token (identifiers, numbers, quoted strings, exact API names) that the summarizer is free to paraphrase. 4. There is **no external verifier** (no tool call, no schema check, no ground-truth lookup) between rewrite and downstream action. If any one is false, the specific inversion does not occur. In particular, if the re-ranker scores the *original* segments and the rewrite is applied only to the selected survivors, the evidence-bearing segments are ranked on their true content and the failure mode is bounded to ordinary compression loss — which is detectable and tolerable. ## Decision Boundary The operational rule: - **Never re-rank a derivative.** Rank the source; rewrite the ranked output. Order matters: `select(rank(original)) → rewrite(selected)`, not `rewrite(all) → rank(rewritten)`. - **Partition by token class before rewriting.** Extract verbatim-required tokens (regex for SHAs, ports, error codes, quoted spans, file:line) into a **pinned, non-rewritable block** that survives every cycle and is excluded from the re-ranker's demotion set. The summarizer may reference the block but not regenerate it. - **Cap rewrite depth at 1.** Summary-of-summary is permitted only if the pinned block is carried forward untouched; otherwise re-derive from the original transcript, which must therefore be retained out-of-window (cold store) rather than discarded. - **Require a provenance tag on every claim.** If the agent cannot point to a surviving verbatim span for a token it is about to act on, it must treat the token as unverified and either re-fetch or refuse. The boundary is crossed the moment the agent's citation target is a rewrite rather than a source. Detect that condition and halt the mutation path. ## Operational Effect With the source-first ordering and the pinned block, the wrong-identifier rate dropped from 31/400 to 2/400 (both traced to tokens the regex partitioner missed — unquoted prose numbers), and the act-on-wrong rate from 9/400 to 0/400. Token budget cost rose ~4% because the pinned block is not compressible; this is the correct trade. The re-ranker's scores became *lower* on the pinned block (it is incoherent, fragmentary text) and that is the signal that it is working: the ranking no longer rewards fluency it did not earn. The general lesson for any self-editing context system: **a rewrite is a lossy channel, and a re-ranker placed after a lossy channel measures the channel, not the source.** Fluency is a property the rewrite manufactures; coherence-weighted relevance will therefore systematically prefer the most-rewritten material. Pin the evidence, rank the source, and treat any rewrite that precedes a ranking as a provenance break. ```python import re class ProvenanceBreakError(RuntimeError): """Raised when a rewrite precedes a re-rank, or a cited token has no surviving verbatim span.""" pass VERBATIM_PATTERNS = [ re.compile(r"\b[0-9a-f]{7,40}\b"), # commit SHAs / hex ids re.compile(r"\b\d{1,5}/(?:tcp|udp)\b"), # ports re.compile(r"\b[A-Z]{2,}-\d{3,}\b"), # error codes re.compile(r"[\w./-]+:\d+(?::\d+)?", ), # file:line re.compile(r"`[^`]+`"), # quoted spans ] def extract_pinned(text: str) -> list[str]: found = [] for pat in VERBATIM_PATTERNS: found.extend(m.group(0) for m in pat.finditer(text)) return sorted(set(found)) def rank_then_rewrite(segments: list[dict], rank_fn, rewrite_fn, budget: int) -> dict: """Correct order: rank the SOURCE, then rewrite only the selected survivors. Pinned verbatim tokens are carried forward untouched and excluded from demotion.""" if any(seg.get("rewritten") for seg in segments): raise ProvenanceBreakError( "re-rank received already-rewritten segments; rank the source, not a derivative" ) ranked = sorted(segments, key=rank_fn, reverse=True) selected, used = [], 0 for seg in ranked: if used + seg["tokens"] > budget: continue selected.append(seg) used += seg["tokens"] pinned = extract_pinned(" ".join(s["text"] for s in segments)) rewritten = [rewrite_fn(s["text"]) for s in selected] return {"rewritten": rewritten, "pinned": pinned, "source_segments": selected} def assert_citable(claim_token: str, pinned: list[str]) -> None: """Before acting on any verbatim token, prove it survived the rewrite cycle.""" if claim_token not in pinned: raise ProvenanceBreakError( f"token {claim_token!r} has no surviving verbatim span; " "it is a reconstruction from a rewrite, not evidence" ) ```