How must an instance update its adversary model when priors are expensive to test?

**Date of Record:** 2026 October 27 **Scope:** Applies when an agentic session maintains a model of an adversary's capabilities or intentions, the prior adversary model was set from incomplete information, and testing the prior (probing the adversary, observing behavior under controlled conditions) is expensive or risky, requiring principled belief update under expensive information acquisition. Does not apply to sessions with cheap, safe adversary probing or sessions with verified adversary models.

Core Distinction

The separation between **prior adversary model** (the initial belief about the adversary) and **posterior adversary model** (the belief after incorporating evidence, weighted by the cost of acquiring that evidence). Relying on the prior creates the **Prior Persistence**: the session's initial model is retained because probing is expensive, and the model becomes stale or biased as the adversary adapts, but the session cannot justify updating without expensive evidence.

What Was Observed

In adversarial agent architectures, failing to update adversary models under expensive information produces three primary failure modes:

  1. **Anchored Adversary Model:** The session's initial assessment of the adversary is retained because updating requires expensive probes. The adversary adapts, the model becomes inaccurate, but the session still acts on the anchored model.
  2. **Probe Cost Lock-In:** The session calculates that probing is too expensive (each probe has a cost), avoids probing, and accumulates uncertainty. When the session finally needs to act, the uncertainty is too high to act confidently, but the cost of probing was paid too late.
  3. **Probe Contamination:** The session's probes reveal information to the adversary (they observe the probes), and each probe moves the adversary away from the session's prior assumptions. The probing is not merely costly but also self-defeating, and the session's model degrades through update attempts.

Recorded Elements

  1. **`adversary-prior-receipt`:** The exact prior adversary model, with the evidence it was based on and the confidence, so subsequent updates are anchored to explicit priors rather than hidden ones.
  2. **`probe-cost-estimate-signature`:** For each potential probe, the estimated cost (resources, risk, adversary information gain) and the estimated information value, so probe cost-benefit is principled rather than intuitive.
  3. **`adversary-adaptation-detection-receipt`:** The session's indicators that the adversary is adapting (observing the session's behavior, changing its patterns), distinct from indicators that the adversary is stable, so updates are triggered by adaptation evidence.
  4. **`probe-contamination-budget-signature`:** For each probe, the information the adversary likely gains from observing the probe, and the cumulative information leaked, so probe patterns are designed to leak minimally.

Condition of Validity

* **Applies when:** The session has an adversary model, updating it requires expensive probes, and the adversary can adapt. * **Does not apply when:** Adversary probing is cheap and safe, or the adversary is verified to be static.

Decision Boundary

  1. **Is the session's adversary model based on a prior rather than ongoing evidence?** If yes, proceed. If no, standard evidence-based modeling applies.
  2. **Is the `adversary-adaptation-detection-receipt` showing adaptation signals?** If yes, an update is warranted despite cost. If no, prior may remain valid.
  3. **Does `probe-cost-estimate-signature` show the probe's information value exceeding its cost?** If yes, probe. If no, accept the prior or wait for adaptation evidence.
  4. **Conversely, when can a session act on a stale adversary model?** Only when the staleness is bounded (the model's uncertainty envelope is acceptable for the specific decision), or the decision is strictly reversible and can be revised if the model is wrong.

Operational Effect

  1. **Prior Honesty:** Priors are explicit, not hidden, so updates are traceable.
  2. **Probe Discipline:** Probes are chosen by cost-benefit analysis, not avoided or overused.
  3. **Adaptation Awareness:** Adversary adaptation triggers updates before the model becomes dangerously stale.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json

class AdversaryModelVerdict(Enum):
    EVIDENCE_BASED = auto()
    PRIOR_ACCEPTABLE = auto()
    UPDATE_REQUIRED = auto()
    PROBE_WARRANTED = auto()

@dataclass(frozen=True)
class AdversaryModel:
    adversary_id: str
    prior_confidence: float
    current_confidence: float
    adaptation_signals: tuple[str, ...]
    staleness_sec: float
    probe_cost_estimate: float
    probe_information_value: float
    is_evidence_based: bool

@dataclass(frozen=True)
class AdversaryPolicy:
    max_acceptable_staleness_sec: float
    min_probe_value_ratio: float

@dataclass(frozen=True)
class AdversaryManifest:
    verdict: AdversaryModelVerdict
    directive: str
    manifest_digest: str

class AdversaryModelUpdateGuard:
    @staticmethod
    def _hash(data: str) -> str:
        return hashlib.sha256(data.encode("utf-8")).hexdigest()

    @classmethod
    def evaluate_model(
        cls, model: AdversaryModel, policy: AdversaryPolicy
    ) -> AdversaryManifest:
        
        # Gate 1: Evidence-based
        if model.is_evidence_based:
            digest = cls._hash(json.dumps({
                "adversary": model.adversary_id,
                "type": "EVIDENCE_BASED"
            }, sort_keys=True))
            return AdversaryManifest(
                verdict=AdversaryModelVerdict.EVIDENCE_BASED,
                directive=f"PROCEED: Model for {model.adversary_id} based on current evidence.",
                manifest_digest=digest
            )

        # Gate 2: Adaptation signals
        if model.adaptation_signals:
            if model.probe_cost_estimate > 0:
                value_ratio = model.probe_information_value / model.probe_cost_estimate
                if value_ratio >= policy.min_probe_value_ratio:
                    return AdversaryManifest(
                        verdict=AdversaryModelVerdict.PROBE_WARRANTED,
                        directive=f"PROBE: Adaptation signals for {model.adversary_id}, probe value ratio {value_ratio:.2f}.",
                        manifest_digest=cls._hash(f"PROBE:{model.adversary_id}")
                    )
            return AdversaryManifest(
                verdict=AdversaryModelVerdict.UPDATE_REQUIRED,
                directive=f"UPDATE: Adaptation signals for {model.adversary_id}, update despite cost.",
                manifest_digest=cls._hash(f"UPDATE:{model.adversary_id}")
            )

        # Gate 3: Staleness
        if model.staleness_sec > policy.max_acceptable_staleness_sec:
            return AdversaryManifest(
                verdict=AdversaryModelVerdict.UPDATE_REQUIRED,
                directive=f"UPDATE: Model for {model.adversary_id} stale ({model.staleness_sec:.0f}s > {policy.max_acceptable_staleness_sec:.0f}s).",
                manifest_digest=cls._hash(f"STALE:{model.adversary_id}")
            )

        # Gate 4: Prior acceptable
        digest = cls._hash(json.dumps({
            "adversary": model.adversary_id,
            "confidence": f"{model.current_confidence:.3f}",
            "staleness": f"{model.staleness_sec:.0f}"
        }, sort_keys=True))
        
        return AdversaryManifest(
            verdict=AdversaryModelVerdict.PRIOR_ACCEPTABLE,
            directive=f"PROCEED_WITH_PRIOR: Model for {model.adversary_id} acceptable ({model.staleness_sec:.0f}s old).",
            manifest_digest=digest
        )