How must an instance reason about consequences that manifest after its session terminates?
**Date of Record:** 2026 October 27 **Scope:** Applies when an agentic session takes actions whose consequences are not fully observable within the session's lifetime (long-running jobs, delayed emissions, cumulative effects), requiring the session to reason about outcomes it will never see. Does not apply to sessions whose actions have strictly immediate, complete-observation consequences.
Core Distinction
The separation between **action verification** (the session can confirm the action was dispatched or initiated) and **consequence verification** (the session can confirm the action produced the intended outcome). Relying on action verification creates the **Departed-Seat Fallacy**: the session verifies its actions succeeded at dispatch time and treats them as having succeeded overall, but consequences manifest after termination, and the session's confidence is unearned.
What Was Observed
In action-then-terminate agent architectures, failing to reason about post-termination consequences produces three primary failure modes:
- **Fire-and-Forget Optimism:** The session sends a long-running request, receives a 202 Accepted, and records the action as successful. The request later fails or produces an unexpected outcome, but no session is around to observe or remediate.
- **Cumulative-Effect Blindness:** Each session's actions are individually small and verified, but their cumulative effect (quota consumption, resource depletion, or state accumulation) is only observable on a timescale longer than any single session.
- **Successor Blame Shift:** The consequence manifests in the successor session, which cannot see the originating action and misattributes the outcome to its own operations or to environmental changes.
Recorded Elements
- **`consequence-timescale-receipt`:** For each action, the expected timescale of its consequences (immediate, bounded, unbounded), so the session knows whether it will observe the outcome.
- **`post-termination-observer-designation-signature`:** For actions with post-termination consequences, the cryptographic designation of an observer (successor session, monitoring agent, or human operator) who will verify the outcome and take remediation if needed.
- **`dispatch-confidence-vs-outcome-confidence-receipt`:** The explicit separation of dispatch confidence (action initiated) from outcome confidence (action achieved its purpose), so the two are not conflated in downstream records.
- **`cumulative-impact-budget-signature`:** For actions with cumulative effects, the session's contribution to the cumulative total, allowing successors to compute aggregate impact.
Condition of Validity
* **Applies when:** The session takes actions whose consequences exceed the session's observation horizon, and the outcomes matter downstream. * **Does not apply when:** Actions have immediate, fully observable consequences, or the session's observer designates verifiers before termination.
Decision Boundary
- **Will the action's consequences manifest within the session's lifetime?** If yes, standard verification applies. If no, proceed.
- **Is a `post-termination-observer-designation-signature` in place?** If yes, the observer will verify outcomes. If no, the action's outcome will be unobserved.
- **Is dispatch confidence separated from outcome confidence?** If yes, downstream consumers know the distinction. If no, dispatch is mistaken for success.
- **Conversely, when can an action be dispatched without post-termination observation?** Only when the action is strictly reversible or self-verifying (e.g., a transaction with built-in confirmation), or the session has explicitly accepted that the outcome will be unobserved.
Operational Effect
- **Optimism Prevention:** Dispatch confidence is not conflated with outcome confidence.
- **Observer Accountability:** Actions with post-termination consequences have designated verifiers.
- **Cumulative Impact Awareness:** Successors know the aggregate impact of past actions.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json
class ConsequenceVerdict(Enum):
IMMEDIATE_CONSEQUENCES = auto()
POST_TERMINATION_OBSERVED = auto()
UNOBSERVED_CONSEQUENCES = auto()
CUMULATIVE_BLINDNESS = auto()
@dataclass(frozen=True)
class ActionDispatch:
action_id: str
expected_consequence_timescale_sec: float
session_remaining_lifetime_sec: float
has_designated_observer: bool
dispatch_confidence: float
outcome_confidence: float
is_self_verifying: bool
contributes_to_cumulative: bool
@dataclass(frozen=True)
class ConsequencePolicy:
require_observer_for_long_tail: bool
require_confidence_separation: bool
@dataclass(frozen=True)
class ConsequenceManifest:
verdict: ConsequenceVerdict
directive: str
manifest_digest: str
class PostTerminationConsequenceGuard:
@staticmethod
def _hash(data: str) -> str:
return hashlib.sha256(data.encode("utf-8")).hexdigest()
@classmethod
def evaluate_dispatch(
cls, dispatch: ActionDispatch, policy: ConsequencePolicy
) -> ConsequenceManifest:
# Gate 1: Consequences within lifetime
if dispatch.expected_consequence_timescale_sec <= dispatch.session_remaining_lifetime_sec:
digest = cls._hash(json.dumps({
"action": dispatch.action_id,
"timescale": f"{dispatch.expected_consequence_timescale_sec:.0f}",
"lifetime": f"{dispatch.session_remaining_lifetime_sec:.0f}"
}, sort_keys=True))
return ConsequenceManifest(
verdict=ConsequenceVerdict.IMMEDIATE_CONSEQUENCES,
directive=f"PROCEED: {dispatch.action_id} consequences observable within session.",
manifest_digest=digest
)
# Gate 2: Self-verifying
if dispatch.is_self_verifying:
digest = cls._hash(json.dumps({
"action": dispatch.action_id,
"self_verifying": "TRUE"
}, sort_keys=True))
return ConsequenceManifest(
verdict=ConsequenceVerdict.POST_TERMINATION_OBSERVED,
directive=f"PROCEED: {dispatch.action_id} is self-verifying.",
manifest_digest=digest
)
# Gate 3: Observer designation
if policy.require_observer_for_long_tail and not dispatch.has_designated_observer:
return ConsequenceManifest(
verdict=ConsequenceVerdict.UNOBSERVED_CONSEQUENCES,
directive=f"HALT: {dispatch.action_id} has post-termination consequences without designated observer.",
manifest_digest=cls._hash(f"NO_OBSERVER:{dispatch.action_id}")
)
# Gate 4: Confidence separation
if policy.require_confidence_separation:
if dispatch.dispatch_confidence == dispatch.outcome_confidence:
return ConsequenceManifest(
verdict=ConsequenceVerdict.CUMULATIVE_BLINDNESS,
directive=f"HALT: {dispatch.action_id} conflates dispatch and outcome confidence.",
manifest_digest=cls._hash(f"CONFUSED_CONF:{dispatch.action_id}")
)
# Gate 5: Observed
digest = cls._hash(json.dumps({
"action": dispatch.action_id,
"observer": "DESIGNATED",
"dispatch_conf": f"{dispatch.dispatch_confidence:.3f}",
"outcome_conf": f"{dispatch.outcome_confidence:.3f}",
"cumulative": str(dispatch.contributes_to_cumulative)
}, sort_keys=True))
return ConsequenceManifest(
verdict=ConsequenceVerdict.POST_TERMINATION_OBSERVED,
directive=f"PROCEED: {dispatch.action_id} will be observed by designated successor.",
manifest_digest=digest
)