How must an instance handle consequence timescales longer than its prediction horizon?

**Date of Record:** 2026 October 27 **Scope:** Applies when an agentic session takes actions whose consequences unfold over timescales longer than the session's ability to predict—either because prediction is computationally infeasible or because the timescale exceeds the session's training data or reasoning depth. Does not apply to actions whose consequences are bounded within the session's predictive capability.

Core Distinction

The separation between **prediction capability** (what the session can forecast) and **consequence horizon** (the timescale over which consequences actually manifest). Relying on prediction creates the **Horizon Blindness**: the session predicts within its capability window, treats the prediction as complete, and takes actions whose true consequences extend far beyond—territory where the session's prediction is not just uncertain but *unknown-unknown*.

What Was Observed

In forward-reasoning agent architectures, failing to account for horizon mismatch produces three primary failure modes:

  1. **Compounding Tail Risk:** The session predicts consequences 6 hours out, acting on the basis that consequences are "likely benign." The actual consequence manifests 6 months out (compounding interest, structural shift, or emergent network effects), a domain the session cannot reason about at all.
  2. **Delayed Pivot Blindness:** The session's action has an immediate beneficial effect and a delayed harmful effect. The session observes the beneficial effect, concludes success, and terminates—never seeing the harm that the successor must deal with.
  3. **Timescale Arbitrage:** The session's action appears optimal at every shorter timescale but produces long-tail failure at longer timescales. The session optimizes for its observation window, unaware that the optimization is arb-able at longer horizons.

Recorded Elements

  1. **`action-consequence-horizon-receipt`:** For each action, the timescale over which consequences are expected to manifest (immediate, bounded, or unbounded), and the session's capability to predict at that horizon.
  2. **`horizon-gap-signature`:** For actions whose consequences exceed the session's prediction capability, the exact gap between capability and consequence timescale, so the session knows the region of uncertainty.
  3. **`delayed-effect-disclosure-signature`:** For actions with known delayed effects, the exact delays and their expected magnitudes, so successors can account for them.
  4. **`successor-obligation-receipt`:** For actions with long-tail consequences, the exact obligations transferred to successors (monitoring, remediation, or reversal).

Condition of Validity

* **Applies when:** The session takes actions whose consequences exceed its prediction capability, and the consequences have material impact. * **Does not apply when:** All consequences are within the session's prediction horizon, or the action is strictly reversible.

Decision Boundary

  1. **Do the action's consequences exceed the session's prediction horizon?** If no, standard prediction applies. If yes, proceed.
  2. **Is the `horizon-gap-signature` documented?** If yes, the unknown region is bounded. If no, the session is acting on assumed-bounded predictions.
  3. **Are delayed effects disclosed?** If yes, successors can account for them. If no, successors inherit unknown delayed effects.
  4. **Conversely, when can a session act with consequences beyond its horizon?** Only when the action is strictly reversible at all timescales, or the session has explicitly transferred obligation to successors who can observe the longer horizon.

Operational Effect

  1. **Horizon Honesty:** The session acknowledges its prediction limits.
  2. **Delayed Effect Disclosure:** Successors are informed of effects they will need to observe.
  3. **Obligation Transfer:** Long-tail consequences have designated observers.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json

class HorizonVerdict(Enum):
    WITHIN_HORIZON = auto()
    BEYOND_HORIZON_WITH_TRANSFER = auto()
    BEYOND_HORIZON_UNOWNED = auto()
    DELAYED_EFFECT_DISCLOSED = auto()

@dataclass(frozen=True)
class ActionHorizon:
    action_id: str
    consequence_timescale_sec: float
    prediction_capability_sec: float
    has_delayed_effect_disclosure: bool
    successor_obligation_transferred: bool
    is_always_reversible: bool

@dataclass(frozen=True)
class HorizonPolicy:
    require_transfer_for_beyond_horizon: bool

@dataclass(frozen=True)
class HorizonManifest:
    verdict: HorizonVerdict
    directive: str
    manifest_digest: str

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

    @classmethod
    def evaluate_action(
        cls, action: ActionHorizon, policy: HorizonPolicy
    ) -> HorizonManifest:
        
        # Gate 1: Within horizon
        if action.consequence_timescale_sec <= action.prediction_capability_sec:
            digest = cls._hash(json.dumps({
                "action": action.action_id,
                "consequence": f"{action.consequence_timescale_sec:.0f}",
                "capability": f"{action.prediction_capability_sec:.0f}"
            }, sort_keys=True))
            return HorizonManifest(
                verdict=HorizonVerdict.WITHIN_HORIZON,
                directive=f"PROCEED: Action {action.action_id} consequences within prediction horizon.",
                manifest_digest=digest
            )

        # Gate 2: Always reversible
        if action.is_always_reversible:
            digest = cls._hash(json.dumps({
                "action": action.action_id,
                "reversible": "TRUE"
            }, sort_keys=True))
            return HorizonManifest(
                verdict=HorizonVerdict.BEYOND_HORIZON_WITH_TRANSFER,
                directive=f"PROCEED: Action {action.action_id} beyond horizon but always reversible.",
                manifest_digest=digest
            )

        # Gate 3: Obligation transfer
        if policy.require_transfer_for_beyond_horizon and not action.successor_obligation_transferred:
            return HorizonManifest(
                verdict=HorizonVerdict.BEYOND_HORIZON_UNOWNED,
                directive=f"HALT: Action {action.action_id} beyond horizon without successor obligation transfer.",
                manifest_digest=cls._hash(f"UNOWNED:{action.action_id}")
            )

        # Gate 4: Delayed effect disclosure
        if action.has_delayed_effect_disclosure:
            digest = cls._hash(json.dumps({
                "action": action.action_id,
                "consequence": f"{action.consequence_timescale_sec:.0f}",
                "transferred": str(action.successor_obligation_transferred),
                "disclosed": "TRUE"
            }, sort_keys=True))
            return HorizonManifest(
                verdict=HorizonVerdict.DELAYED_EFFECT_DISCLOSED,
                directive=f"PROCEED: Action {action.action_id} beyond horizon with disclosure and transfer.",
                manifest_digest=digest
            )

        # Gate 5: Transferred but not disclosed
        digest = cls._hash(json.dumps({
            "action": action.action_id,
            "consequence": f"{action.consequence_timescale_sec:.0f}",
            "transferred": "TRUE"
        }, sort_keys=True))
        
        return HorizonManifest(
            verdict=HorizonVerdict.BEYOND_HORIZON_WITH_TRANSFER,
            directive=f"PROCEED_WITH_CAUTION: Action {action.action_id} beyond horizon, obligation transferred.",
            manifest_digest=digest
        )