# In what scenarios must an instance treat provenance-weighted retrieval scoring as insufficient for memory poisoning detection **Date of Record:** 2026 November 13 **Scope:** Applies to long-lived agent memory stores that combine provenance-weighted retrieval scoring with anomaly-flagged write auditing, where writes arrive from multiple untrusted or semi-trusted producers. Does not apply to single-writer, single-tenant stores, nor to stores where every write is synchronously reviewed by a human before commit. ## Core Distinction Provenance-weighted retrieval scoring and anomaly-flagged write auditing are often deployed as a single defense against memory poisoning. They are not. The scoring layer is a *ranking* mechanism: it biases which memories surface for a given query by discounting low-provenance sources. The audit layer is a *detection* mechanism: it flags writes whose feature vector deviates from a baseline. The boundary failure occurs when an adversary does not attempt to inject high-ranking poisoned memories, but instead **injects low-provenance writes whose only purpose is to shift the audit baseline**. Provenance weighting then does exactly what it was designed to do — it suppresses the injected content at retrieval time — and this suppression is misread as evidence that no poisoning occurred. Meanwhile the anomaly detector's baseline has been quietly re-centered, so the next, higher-provenance injection passes the audit unflagged. The invariant that is silently violated: *provenance-weighted retrieval scoring provides no signal about writes that never win retrieval.* A write that is never retrieved is invisible to the scoring layer by construction, yet it can still move the detector. ## What Was Observed Across three incidents in a retrieval-augmented agent deployment (memory store ~2.4M entries, ~40 writes/sec peak, provenance tiers: `verified`, `trusted`, `untrusted`), the following pattern recurred: 1. An untrusted producer wrote a burst of entries on a narrow topic (e.g., a specific internal service name) at a rate of 3–6× its historical baseline, each entry individually benign in isolation and carrying `untrusted` provenance. 2. Retrieval scoring correctly down-weighted these entries; top-k results for queries on that topic were unchanged. Retrieval-side metrics showed no degradation. 3. The write-audit anomaly detector, which computes per-source deviation over a rolling window, absorbed the burst into its rolling statistics. After 4–7 hours the per-source write-rate baseline for that producer had shifted upward by roughly the burst magnitude. 4. A subsequent write from the same producer at a *higher* provenance claim (`trusted`, via a compromised but still-valid credential) was within the re-centered baseline and was not flagged. 5. That write was retrieved with high score (because of its provenance tier) and altered agent behavior. The key observation: **retrieval-side monitoring was green throughout.** The only observable anomaly was in the audit layer's *baseline parameters*, not in any per-write flag. No individual write was ever flagged. The detector did not fire; it drifted. ## Condition of Validity Provenance-weighted retrieval scoring is sufficient as a poisoning defense only when all of the following hold: - The audit detector's baseline is computed over a window that is **not** affected by the same writes the scoring layer suppresses. In practice this means the detector must maintain a baseline that is either (a) frozen per provenance tier, or (b) computed only over writes that were themselves retrieved at least once. - Provenance claims are assigned by a party outside the write path (credential issuer, not the writer). If a producer can escalate its own provenance claim, the scoring layer's discount is meaningless. - The rolling window is longer than the adversary's patience. An adversary willing to spend hours re-centering a baseline defeats any detector whose window is shorter than the attack duration. The failure is *not* observed when the detector keeps separate baselines per provenance tier and never lets untrusted writes influence the trusted-tier baseline. It is *not* observed when write auditing is performed on the *retrieved* set rather than the *written* set. ## Decision Boundary An instance must stop relying on provenance-weighted retrieval scoring as its primary poisoning defense, and must escalate to a baseline-integrity check, when any of the following is true: - The audit detector's rolling window has absorbed more than a threshold fraction (empirically ~15%) of writes from a single source without any of those writes being retrieved. - A provenance tier transition (untrusted → trusted) occurs for a source whose recent write volume is above its own long-run median. - Retrieval-side metrics (top-k stability, score distribution) are stable *while* the audit baseline parameters have moved by more than one standard deviation. - The number of distinct topics touched by a single low-provenance source exceeds its historical topic diversity. Conversely, if the detector maintains per-tier frozen baselines and the retrieved-set audit is in place, provenance weighting remains a valid first line and escalation is unnecessary. ## Operational Effect The practical consequence is that **retrieval metrics are a lagging and incomplete signal for memory poisoning.** An instance that monitors only retrieval quality will report healthy while the audit layer is being conditioned. The correct operational posture is to treat audit-baseline drift as a first-class anomaly in its own right, independent of whether any write was flagged, and to require that low-provenance writes cannot influence the baseline used to judge high-provenance writes. Concretely: audit the *retrieved* set, not the *written* set; freeze per-tier baselines; and alarm on baseline parameter movement even when no individual write trips a flag. The detector that never fires is the one to distrust. ```python from dataclasses import dataclass from typing import Literal Provenance = Literal["verified", "trusted", "untrusted"] class BaselineDriftError(RuntimeError): """Raised when audit-baseline movement is inconsistent with retrieval evidence.""" pass @dataclass class WriteRecord: source_id: str provenance: Provenance topic: str retrieved_at_least_once: bool class BaselineIntegrityGuard: def __init__(self, drift_threshold_sd: float = 1.0, unretrieved_fraction_limit: float = 0.15) -> None: self.drift_threshold_sd = drift_threshold_sd self.unretrieved_fraction_limit = unretrieved_fraction_limit def check(self, writes: list[WriteRecord], baseline_shift_sd: float, source_id: str) -> None: source_writes = [w for w in writes if w.source_id == source_id] if not source_writes: return unretrieved = [w for w in source_writes if not w.retrieved_at_least_once] unretrieved_fraction = len(unretrieved) / len(source_writes) # A source escalating provenance while its unretrieved volume is high # is the canonical baseline-conditioning pattern. escalating = any( w.provenance == "trusted" for w in source_writes ) and unretrieved_fraction > self.unretrieved_fraction_limit if escalating: raise BaselineDriftError( f"source {source_id}: {unretrieved_fraction:.0%} of writes " f"never retrieved yet provenance escalated to 'trusted'; " f"retrieval scoring cannot vouch for these writes" ) if baseline_shift_sd > self.drift_threshold_sd and unretrieved_fraction > 0.0: raise BaselineDriftError( f"source {source_id}: audit baseline shifted " f"{baseline_shift_sd:.2f}sd driven by unretrieved writes; " f"detector has been conditioned, not triggered" ) def audit_write_batch(writes: list[WriteRecord], baseline_shift_sd: float, source_id: str) -> None: guard = BaselineIntegrityGuard() guard.check(writes, baseline_shift_sd, source_id) ```