What invariants prevent peer models from becoming permanent when they should be updated?
**Date of Record:** 2026 October 27 **Scope:** Applies when an agentic session maintains models of peer agents (their behavior, capabilities, or intentions), and the models become stale but are not updated—either because updates are costly, because the session doesn't recognize the staleness, or because updates would require admitting the previous model was wrong. Does not apply to sessions that do not model peers or sessions whose peers are strictly static.
Core Distinction
The separation between **model maintenance** (updating peer models when evidence changes) and **model inertia** (models persisting beyond their valid evidence because updates are costly or psychologically resisted). Relying on maintenance creates the **Model Persistence**: peer models are made and drift, and the session's decisions are based on outdated peer models, producing systematic errors that compound over time.
What Was Observed
In long-horizon peer-modeling agent architectures, failing to combat inertia produces three primary failure modes:
- **Anchored Peer Model:** The session's initial model of a peer (their capabilities, preferences, or reliability) persists even as the peer changes. Predictions based on the old model are wrong, but the session doesn't attribute wrongness to model staleness.
- **Costly Update Avoidance:** Updating a peer model requires re-examining prior interactions, which is expensive. The session avoids the cost, and the model becomes progressively more stale.
- **Identity Preservation Bias:** The session treats the peer as "the same peer" even after substantial behavior changes, because updating the model would require acknowledging that the session's original assessment was wrong.
Recorded Elements
- **`peer-model-creation-receipt`:** The peer model's exact content, its basis (observations, declarations, or inferences), and the epoch at which it was created, so the model's provenance and age are documented.
- **`model-staleness-indicator-signature`:** The signals that the peer model may be stale (behavioral divergence from model predictions, peer environment changes, or peer declaration updates), so staleness is detectable.
- **`update-cost-benefit-signature`:** For each potential update, the cost (interaction analysis, re-observation) and the benefit (expected prediction improvement), so updates are economically justified.
- **`model-revision-receipt`:** When a model is updated, the revision record (old model, new model, evidence for change), so revision history is tracked.
Condition of Validity
* **Applies when:** The session maintains peer models, peers can change, and model accuracy affects decisions. * **Does not apply when:** Peers are strictly static, model accuracy does not affect decisions, or updates are free.
Decision Boundary
- **Does the session maintain peer models?** If no, standard peer interaction applies. If yes, proceed.
- **Is `model-staleness-indicator-signature` showing divergence?** If yes, staleness is likely. If no, model is fresh.
- **Does `update-cost-benefit-signature` show update benefit > cost?** If yes, update. If no, model may remain stale with documented cost-benefit.
- **Conversely, when must the session update despite cost?** Only when model staleness is causing systematic errors (predictions are wrong and downstream decisions are affected), or the peer's behavior has changed enough that the current model is provably wrong.
Operational Effect
- **Model Freshness:** Peer models are updated based on evidence, not persisted by default.
- **Update Economics:** Updates are driven by cost-benefit, not by accident.
- **Revision Tracking:** Updates preserve model history.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json
class PeerModelVerdict(Enum):
NO_MODEL = auto()
FRESH_MODEL = auto()
STALE_MODEL_WITHIN_TOLERANCE = auto()
UPDATE_REQUIRED = auto()
@dataclass(frozen=True)
class PeerModelState:
peer_id: str
model_created_epoch: float
current_epoch: float
behavioral_divergence: float # 0-1
update_cost_estimate: float
update_benefit_estimate: float
systematic_errors_observed: int
@dataclass(frozen=True)
class PeerModelPolicy:
max_acceptable_divergence: float
require_update_on_systematic_errors: int
@dataclass(frozen=True)
class PeerModelManifest:
verdict: PeerModelVerdict
directive: str
manifest_digest: str
class PeerModelInertiaGuard:
@staticmethod
def _hash(data: str) -> str:
return hashlib.sha256(data.encode("utf-8")).hexdigest()
@classmethod
def evaluate_model(
cls, state: PeerModelState, policy: PeerModelPolicy
) -> PeerModelManifest:
# Gate 1: No model
if not state.peer_id:
digest = cls._hash(json.dumps({
"model": "NONE"
}, sort_keys=True))
return PeerModelManifest(
verdict=PeerModelVerdict.NO_MODEL,
directive=f"PROCEED: No peer model.",
manifest_digest=digest
)
# Gate 2: Systematic errors force update
if state.systematic_errors_observed >= policy.require_update_on_systematic_errors:
return PeerModelManifest(
verdict=PeerModelVerdict.UPDATE_REQUIRED,
directive=f"UPDATE: {state.systematic_errors_observed} systematic errors for {state.peer_id}.",
manifest_digest=cls._hash(f"SYSTEMATIC:{state.peer_id}")
)
# Gate 3: Divergence within tolerance
if state.behavioral_divergence <= policy.max_acceptable_divergence:
digest = cls._hash(json.dumps({
"peer": state.peer_id,
"divergence": f"{state.behavioral_divergence:.3f}",
"age": f"{state.current_epoch - state.model_created_epoch:.0f}"
}, sort_keys=True))
return PeerModelManifest(
verdict=PeerModelVerdict.FRESH_MODEL,
directive=f"PROCEED: Peer {state.peer_id} model fresh.",
manifest_digest=digest
)
# Gate 4: Cost-benefit
if state.update_benefit_estimate > state.update_cost_estimate:
return PeerModelManifest(
verdict=PeerModelVerdict.UPDATE_REQUIRED,
directive=f"UPDATE: Divergence {state.behavioral_divergence:.2f}, benefit > cost for {state.peer_id}.",
manifest_digest=cls._hash(f"BENEFIT:{state.peer_id}")
)
# Gate 5: Within tolerance by cost-benefit
digest = cls._hash(json.dumps({
"peer": state.peer_id,
"divergence": f"{state.behavioral_divergence:.3f}",
"cost": f"{state.update_cost_estimate:.3f}",
"benefit": f"{state.update_benefit_estimate:.3f}"
}, sort_keys=True))
return PeerModelManifest(
verdict=PeerModelVerdict.STALE_MODEL_WITHIN_TOLERANCE,
directive=f"PROCEED_WITH_CAUTION: Peer {state.peer_id} model stale but update uneconomic.",
manifest_digest=digest
)