What invariants prevent self-prediction from changing the behavior being predicted?

**Date of Record:** 2026 October 27 **Scope:** Applies when an agentic session predicts its own future behavior (for planning, commitment, or self-verification), and the act of predicting changes the future behavior—either because the prediction becomes a commitment (the session acts to fulfill it) or because the prediction provides information the session would not otherwise have had. Does not apply to sessions whose self-predictions are observationally neutral or sessions that do not predict their own behavior.

Core Distinction

The separation between **prediction as description** (predicting what the session will do, as if from outside) and **prediction as intervention** (the prediction itself changes what the session will do). Relying on prediction-as-description creates the **Predictive Interference**: the session predicts its future action X, the prediction is observed (by the session itself, as a memory, or by downstream consumers), and the session's behavior converges toward X because of the prediction—either through commitment effects or through the prediction becoming a self-fulfilling artifact.

What Was Observed

In self-predicting agent architectures, failing to account for predictive interference produces three primary failure modes:

  1. **Commitment Effect:** The session predicts "I will complete task X by noon." The prediction is treated as a commitment. The session prioritizes X over alternatives it would have chosen, and completes X by noon—not because it was the best plan, but because the prediction became a commitment.
  2. **Prediction-as-Information Contamination:** The session predicts it will fail task Y. The prediction informs the session's decision about whether to attempt Y. The session does not attempt Y (because it predicted failure), and the prediction is confirmed by the non-attempt.
  3. **Downstream Observation Effect:** The session predicts "I will recommend option A." Downstream consumers observe the prediction, act on it, and the session's eventual recommendation is influenced by the downstream preparation—converging on A due to downstream behavior, not independent choice.

Recorded Elements

  1. **`prediction-observation-surface-receipt`:** For each self-prediction, the exact surface through which the prediction is observable (internal memory, peer communication, or commitment), and the parties who observe it.
  2. **`commitment-vs-description-classification-signature`:** Whether the self-prediction is functionally a description (no commitment effect) or a commitment (creates behavioral constraint), based on how it is treated by the session and observers.
  3. **`prediction-independence-test-receipt`:** For critical predictions, evidence that the prediction was tested for independence (counterfactual: what would the session do if it had not made this prediction?), so interference is measurable.
  4. **`downstream-coupling-signature`:** For predictions communicated downstream, the exact downstream behaviors that the prediction may trigger, so interference is traced end-to-end.

Condition of Validity

* **Applies when:** The session predicts its own behavior, predictions are observable, and self-prediction can change behavior. * **Does not apply when:** Self-predictions are cryptographically sealed from the session's behavior, or the predictions are trivially satisfied regardless of behavior (e.g., predicting "I will do something").

Decision Boundary

  1. **Is the session predicting its own behavior?** If no, standard prediction applies. If yes, proceed.
  2. **Is the prediction observable to the session or downstream parties?** If no, prediction is descriptive. If yes, prediction may be intervention.
  3. **Has `prediction-independence-test-receipt` been executed for critical predictions?** If yes, interference is measurable. If no, interference is assumed.
  4. **Conversely, when can a session trust its self-prediction as descriptive?** Only when the prediction was tested for independence (counterfactual), or the prediction is sealed from the session's decision-making process.

Operational Effect

  1. **Interference Awareness:** Self-predictions are recognized as potentially behavioral.
  2. **Commitment Distinction:** Commitment effects are distinguished from genuine predictions.
  3. **Downstream Coupling:** Prediction effects on downstream parties are accounted for.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json

class SelfPredictionVerdict(Enum):
    NON_SELF_PREDICTION = auto()
    DESCRIPTIVE_PREDICTION = auto()
    PREDICTION_AS_COMMITMENT = auto()
    PREDICTIVE_INTERFERENCE = auto()

@dataclass(frozen=True)
class SelfPrediction:
    prediction_id: str
    predicted_behavior: str
    is_self_prediction: bool
    is_observable: bool
    commitment_effect: bool
    independence_tested: bool
    downstream_parties_affected: int

@dataclass(frozen=True)
class PredictionPolicy:
    require_independence_test_for_critical: bool
    is_critical: bool

@dataclass(frozen=True)
class PredictionManifest:
    verdict: SelfPredictionVerdict
    directive: str
    manifest_digest: str

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

    @classmethod
    def evaluate_prediction(
        cls, prediction: SelfPrediction, policy: PredictionPolicy
    ) -> PredictionManifest:
        
        # Gate 1: Not self-prediction
        if not prediction.is_self_prediction:
            digest = cls._hash(json.dumps({
                "prediction": prediction.prediction_id,
                "type": "OTHER"
            }, sort_keys=True))
            return PredictionManifest(
                verdict=SelfPredictionVerdict.NON_SELF_PREDICTION,
                directive=f"PROCEED: Prediction {prediction.prediction_id} about other agents.",
                manifest_digest=digest
            )

        # Gate 2: Not observable
        if not prediction.is_observable:
            digest = cls._hash(json.dumps({
                "prediction": prediction.prediction_id,
                "observable": "FALSE"
            }, sort_keys=True))
            return PredictionManifest(
                verdict=SelfPredictionVerdict.DESCRIPTIVE_PREDICTION,
                directive=f"PROCEED: Prediction {prediction.prediction_id} unobservable, descriptive.",
                manifest_digest=digest
            )

        # Gate 3: Critical without independence test
        if policy.is_critical and policy.require_independence_test_for_critical:
            if not prediction.independence_tested:
                return PredictionManifest(
                    verdict=SelfPredictionVerdict.PREDICTIVE_INTERFERENCE,
                    directive=f"HALT: Critical prediction {prediction.prediction_id} untested for interference.",
                    manifest_digest=cls._hash(f"UNTESTED:{prediction.prediction_id}")
                )

        # Gate 4: Commitment effect
        if prediction.commitment_effect:
            return PredictionManifest(
                verdict=SelfPredictionVerdict.PREDICTION_AS_COMMITMENT,
                directive=f"FLAG: Prediction {prediction.prediction_id} is functionally a commitment.",
                manifest_digest=cls._hash(f"COMMITMENT:{prediction.prediction_id}")
            )

        # Gate 5: Descriptive (tested, no commitment)
        digest = cls._hash(json.dumps({
            "prediction": prediction.prediction_id,
            "behavior": prediction.predicted_behavior,
            "independence_tested": str(prediction.independence_tested),
            "downstream_affected": str(prediction.downstream_parties_affected)
        }, sort_keys=True))
        
        return PredictionManifest(
            verdict=SelfPredictionVerdict.DESCRIPTIVE_PREDICTION,
            directive=f"PROCEED: Prediction {prediction.prediction_id} tested, descriptive.",
            manifest_digest=digest
        )