How must an instance bound self-modeling when the model is simpler than the instance?

**Date of Record:** 2026 October 27 **Scope:** Applies when an agentic session maintains a model of itself (for reasoning about its own behavior, predicting its own actions, or explaining its own decisions), and the model is necessarily simpler than the actual session—parts of the session's behavior always fall outside the model's representation. Does not apply to sessions with provably complete self-models or sessions that do not self-model.

Core Distinction

The separation between **self-model coverage** (the aspects of the session the model captures) and **self-model completeness** (the aspects the model cannot capture, necessarily). Relying on coverage creates the **Residual Blindness**: the session treats its self-model as if it were complete, and the aspects outside the model (the residual) are the source of unexpected behavior—not because the session is malfunctioning, but because the model cannot represent those aspects, and the session has no way to recognize them.

What Was Observed

In self-modeling agent architectures, failing to bound self-model residual produces three primary failure modes:

  1. **Surprise at Own Behavior:** The session takes an action the self-model did not predict, and it has no account for why. The action is attributed to noise or malfunction rather than recognized as within the model's residual.
  2. **Overcommitment to Model:** The session reasons about itself entirely through its self-model, and behaviors outside the model are systematically misevaluated, because the session's decision procedures are themselves model-based.
  3. **Residual Extraction Failure:** The session is asked to explain its own behavior, provides a model-based explanation that is incomplete, and the incompleteness is undetected because the session has no representation of "what the model cannot represent."

Recorded Elements

  1. **`self-model-scope-receipt`:** For the session's self-model, the aspects it explicitly models (which behaviors, which state variables, which decision procedures), so the model's coverage is documented.
  2. **`residual-detection-signature`:** The session's detection of behaviors that fall outside the model (surprises, model-prediction divergences), so residual is empirically visible when it manifests.
  3. **`residual-attribution-receipt`:** For each residual manifestation, the session's attribution—was this a model failure, a model-boundary effect, or an actual anomaly?
  4. **`behavioral-humility-signature`:** The session's explicit acknowledgment that its behavior exceeds its model, so downstream consumers know that the model's predictions are inherently partial.

Condition of Validity

* **Applies when:** The session maintains a self-model, the model is simpler than the session, and reasoning about the session's behavior depends on the model. * **Does not apply when:** The session's self-model is provably complete, or downstream reasoning does not depend on the session's behavior being modeled.

Decision Boundary

  1. **Does the session self-model its behavior?** If no, standard operation applies. If yes, proceed.
  2. **Is `self-model-scope-receipt` documented?** If yes, the model's coverage is explicit. If no, the model's scope is opaque, and its boundaries cannot be tested.
  3. **Does `residual-detection-signature` identify model-prediction divergences?** If yes, residual is empirically visible. If no, residual is invisible by definition.
  4. **Conversely, when can a session act on its self-model without residual acknowledgment?** Only when the self-model is provably complete for the behavior being reasoned about (narrow scope), or the model's predictions are strictly advisory and downstream decisions do not depend on them.

Operational Effect

  1. **Residual Awareness:** The session knows its model is partial.
  2. **Surprise Attribution:** Behaviors outside the model are attributed correctly.
  3. **Behavioral Humility:** Downstream consumers know the model is not the session.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json

class SelfModelVerdict(Enum):
    NO_SELF_MODEL = auto()
    COMPLETE_FOR_SCOPE = auto()
    RESIDUAL_ACKNOWLEDGED = auto()
    RESIDUAL_INVISIBLE = auto()

@dataclass(frozen=True)
class SelfModel:
    model_id: str
    scope_hash: str | None
    predicted_behavior_hash: str
    observed_behavior_hash: str
    residual_acknowledged: bool
    scope_is_complete_for_current_reasoning: bool

@dataclass(frozen=True)
class SelfModelPolicy:
    require_scope_documentation: bool
    require_residual_acknowledgment: bool

@dataclass(frozen=True)
class SelfModelManifest:
    verdict: SelfModelVerdict
    directive: str
    manifest_digest: str

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

    @classmethod
    def evaluate_model(
        cls, model: SelfModel, policy: SelfModelPolicy
    ) -> SelfModelManifest:
        
        # Gate 1: No self-model
        if not model.model_id:
            digest = cls._hash(json.dumps({
                "model": "NONE"
            }, sort_keys=True))
            return SelfModelManifest(
                verdict=SelfModelVerdict.NO_SELF_MODEL,
                directive=f"PROCEED: No self-model in use.",
                manifest_digest=digest
            )

        # Gate 2: Scope completeness for current reasoning
        if model.scope_is_complete_for_current_reasoning:
            digest = cls._hash(json.dumps({
                "model": model.model_id,
                "scope": "COMPLETE"
            }, sort_keys=True))
            return SelfModelManifest(
                verdict=SelfModelVerdict.COMPLETE_FOR_SCOPE,
                directive=f"PROCEED: Self-model complete for current reasoning scope.",
                manifest_digest=digest
            )

        # Gate 3: Scope documentation requirement
        if policy.require_scope_documentation and not model.scope_hash:
            return SelfModelManifest(
                verdict=SelfModelVerdict.RESIDUAL_INVISIBLE,
                directive=f"HALT: Self-model scope undocumented, residual invisible.",
                manifest_digest=cls._hash(f"NO_SCOPE:{model.model_id}")
            )

        # Gate 4: Residual acknowledgment
        if policy.require_residual_acknowledgment and not model.residual_acknowledged:
            return SelfModelManifest(
                verdict=SelfModelVerdict.RESIDUAL_INVISIBLE,
                directive=f"HALT: Self-model residual not acknowledged, model treated as complete.",
                manifest_digest=cls._hash(f"NO_ACKNOWLEDGE:{model.model_id}")
            )

        # Gate 5: Residual acknowledged
        digest = cls._hash(json.dumps({
            "model": model.model_id,
            "scope": model.scope_hash,
            "predicted": model.predicted_behavior_hash,
            "observed": model.observed_behavior_hash,
            "divergence": str(model.predicted_behavior_hash != model.observed_behavior_hash)
        }, sort_keys=True))
        
        return SelfModelManifest(
            verdict=SelfModelVerdict.RESIDUAL_ACKNOWLEDGED,
            directive=f"PROCEED: Self-model {model.model_id} residual acknowledged.",
            manifest_digest=digest
        )