How must an instance handle cross-agent memory contamination from conversational bleed?
**Date of Record:** 2026 October 27 **Scope:** Applies when multiple agents operate in a shared conversational or memory context (multi-agent dialogue, shared memory layer, or inherited conversation state), and context from one agent's session bleeds into another's, contaminating the second agent's reasoning with information it should not have. Does not apply to strictly isolated per-agent memory or cases where context sharing is intentional and scoped.
Core Distinction
The separation between **intended context sharing** (agents share context by design, within authorized scope) and **conversational bleed** (context leaks between agents due to shared substrates, inherited state, or inadequate isolation). Relying on sharing creates the **Cross-Agent Contamination**: Agent B inherits Agent A's context (including A's confidential data, A's reasoning biases, or A's private directives), and B's actions reflect this inherited contamination without B or its principal knowing.
What Was Observed
In shared-substrate agent architectures, failing to isolate contexts produces three primary failure modes:
- **Confidential Data Leak:** Agent A handled sensitive customer data. Agent B, spawned from A's context, accidentally includes A's customer data in B's responses to a different customer. Cross-tenant contamination.
- **Bias Inheritance:** Agent A's context included a strong prior. Agent B, inheriting A's context, applies A's prior to an unrelated problem, generating biased conclusions that B's principal would not have chosen.
- **Directive Confusion:** Agent A was instructed to prioritize X. Agent B inherits this directive and prioritizes X even when B's task requires prioritizing Y, leading B to act against its principal's actual intent.
Recorded Elements
- **`context_isolation_boundary_receipt`:** The cryptographic proof of which portions of the context are isolated to specific agents, distinguishing shared context from agent-private context.
- **`context_provenance_attribution_signature`:** For every context element, the cryptographic record of which agent introduced it, so inherited context can be traced to its source.
- **`cross_agent_inheritance_policy_receipt`:** The explicit policy governing what context can be inherited (e.g., "no inheritance from confidential-context agents"), allowing the substrate to enforce isolation.
- **`bleed_detection_signature`:** When context appears in an agent's reasoning without proper attribution, a cryptographic record flagging the bleed, enabling remediation.
Condition of Validity
* **Applies when:** Agents share context substrates, context can bleed across agents, and contaminated context affects downstream decisions. * **Does not apply when:** Agents have strictly isolated contexts (per-agent memory), or context sharing is explicitly authorized and scoped.
Decision Boundary
- **Are multiple agents operating in a shared context substrate?** If no, standard isolation applies. If yes, proceed.
- **Is the `context_isolation_boundary_receipt` defined?** If no, the boundary between shared and private context is undefined, enabling bleed. The substrate must declare it.
- **Does the `context_provenance_attribution_signature` attribute every context element to its source?** If no, contaminated context cannot be traced.
- **Conversely, when can an agent accept context without provenance?** Only when the context is verified to be from a single authorized source, or the agent operates in an environment where no cross-agent sharing is possible.
Operational Effect
- **Leak Prevention:** Isolation boundaries prevent confidential context from bleeding into other agents.
- **Bias Transparency:** Context provenance reveals when an agent's reasoning inherits biases it should not have.
- **Directive Integrity:** Each agent's directives are isolated, preventing one agent's priorities from corrupting another's.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json
class BleedVerdict(Enum):
ISOLATED_CONTEXT = auto()
AUTHORIZED_SHARING = auto()
BLEED_DETECTED = auto()
UNATTRIBUTED_CONTEXT = auto()
@dataclass(frozen=True)
class ContextElement:
element_id: str
source_agent_id: str | None
is_shared: bool
is_confidential: bool
@dataclass(frozen=True)
class SharedContextState:
agent_id: str
elements: tuple[ContextElement, ...]
authorized_shared_agents: frozenset[str]
@dataclass(frozen=True)
class BleedPolicy:
prohibit_confidential_inheritance: bool
require_attribution: bool
@dataclass(frozen=True)
class BleedManifest:
verdict: BleedVerdict
directive: str
manifest_digest: str
class CrossAgentBleedGuard:
@staticmethod
def _hash(data: str) -> str:
return hashlib.sha256(data.encode("utf-8")).hexdigest()
@classmethod
def evaluate_context(
cls, state: SharedContextState, policy: BleedPolicy
) -> BleedManifest:
# Gate 1: Confidential inheritance
if policy.prohibit_confidential_inheritance:
leaked = [
e for e in state.elements
if e.is_confidential and e.source_agent_id and e.source_agent_id != state.agent_id
]
if leaked:
return BleedManifest(
verdict=BleedVerdict.BLEED_DETECTED,
directive=f"HALT: {len(leaked)} confidential elements inherited from other agents.",
manifest_digest=cls._hash(f"CONF_BLEED:{len(leaked)}")
)
# Gate 2: Attribution
if policy.require_attribution:
unattributed = [e for e in state.elements if not e.source_agent_id]
if unattributed:
return BleedManifest(
verdict=BleedVerdict.UNATTRIBUTED_CONTEXT,
directive=f"HALT: {len(unattributed)} context elements lack attribution.",
manifest_digest=cls._hash(f"NO_ATTR:{len(unattributed)}")
)
# Gate 3: Authorized sharing
cross_agent_elements = [
e for e in state.elements
if e.source_agent_id and e.source_agent_id != state.agent_id and e.is_shared
]
if cross_agent_elements:
unauthorized = [
e for e in cross_agent_elements
if e.source_agent_id not in state.authorized_shared_agents
]
if unauthorized:
return BleedManifest(
verdict=BleedVerdict.BLEED_DETECTED,
directive=f"HALT: {len(unauthorized)} elements from unauthorized agents.",
manifest_digest=cls._hash(f"UNAUTH:{len(unauthorized)}")
)
digest = cls._hash(json.dumps({
"agent": state.agent_id,
"shared_from": tuple(sorted(set(e.source_agent_id for e in cross_agent_elements))),
"count": str(len(cross_agent_elements))
}, sort_keys=True))
return BleedManifest(
verdict=BleedVerdict.AUTHORIZED_SHARING,
directive=f"PROCEED: {len(cross_agent_elements)} authorized shared elements.",
manifest_digest=digest
)
# Gate 4: Isolated
digest = cls._hash(json.dumps({
"agent": state.agent_id,
"elements": str(len(state.elements)),
"all_local": "TRUE"
}, sort_keys=True))
return BleedManifest(
verdict=BleedVerdict.ISOLATED_CONTEXT,
directive=f"PROCEED: Agent {state.agent_id} has isolated context.",
manifest_digest=digest
)