What invariants prevent observed state from becoming committed state?
**Date of Record:** 2026 October 27 **Scope:** Applies when an agentic session observes a system state (reads a value, inspects a configuration, or queries a peer) and then acts on the assumption that the observed state persists, but the act of acting on it—or the mere fact of observing it—commits the state as if it were a decision. Does not apply to sessions that observe strictly non-committing state or operate in genuinely read-only contexts.
Core Distinction
The separation between **observational state** (the state as observed, with no commitment implied) and **committed state** (the state that becomes binding once acted upon). Relying on observational state creates the **Observation Commitment Leak**: the session reads a value, plans based on it, and acts—but the act, not the read, is what locks in the state, and the session's plan assumed the read was stable. Other parties observing the session's act infer that the state is committed, and act on that inference.
What Was Observed
In observation-heavy agent architectures, failing to distinguish observational from committed state produces three primary failure modes:
- **First-Mover Lock-In:** The session reads "inventory: 5," plans to buy 3, buys 3, and the remaining 2 are claimed by another session—because the read committed the session to a decision without a matching lock.
- **Distributed Observation Cascade:** Multiple sessions read the same state, each plans independently, each acts, and the aggregate action exceeds the state's capacity—even though each session's plan was locally valid at observation time.
- **Reflexive Commitment:** The session's observation is visible to other parties (via a log, audit trail, or peer notification), and other parties act on the inference that the session has committed to the observed state. The session's read becomes a de facto commitment.
Recorded Elements
- **`observation-scope-receipt`:** For each observation, whether it is purely observational or intended to be committed (i.e., whether the session will act on it), so the observation's downstream implications are explicit.
- **`commit-marker-signature`:** For observations the session will act on, a cryptographic commitment to the observed state, with the intent to act, distinct from the read itself.
- **`observation-observation-receipt`:** For observations visible to other parties, an explicit record that the observation was not a commitment, so reflexive commitment is prevented.
- **`state-stability-window-signature`:** For critical observations, the time window within which the observed state is expected to remain valid, so the session knows how long the observation supports planning before re-reading.
Condition of Validity
* **Applies when:** The session observes shared state, acts on the observation, and the observation is visible to other parties or concurrent sessions. * **Does not apply when:** The session operates in isolation, the state is strictly private to the session, or observations cannot be acted upon.
Decision Boundary
- **Is the observation of shared state?** If no, standard observation applies. If yes, proceed.
- **Will the session act on the observation?** If no, observation is purely informational. If yes, the observation is a de facto commitment.
- **Is the observation visible to other parties?** If yes, other parties may infer commitment from it. If no, the observation's commitment effect is private.
- **Conversely, when can an observation be treated as non-committing despite leading to action?** Only when the action is strictly reversible within the state's stability window AND the observation was not visible to other parties OR was explicitly marked as non-committing.
Operational Effect
- **Lock-In Prevention:** Observations precede commitments; acts are separated from reads.
- **Cascade Prevention:** Multiple sessions' observations don't aggregate into over-commitment.
- **Reflexive Integrity:** Observations that should not commit are marked as such.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json
class CommitmentVerdict(Enum):
PRIVATE_OBSERVATION = auto()
OBSERVATION_SUPPORTS_ACTION = auto()
OBSERVATION_COMMITS_ACTION = auto()
REFLEXIVE_COMMITMENT_DETECTED = auto()
@dataclass(frozen=True)
class StateObservation:
observation_id: str
is_shared_state: bool
will_act_on_it: bool
is_observable_by_others: bool
has_commitment_marker: bool
has_stability_window: bool
@dataclass(frozen=True)
class ObservationPolicy:
require_commitment_marker_for_action: bool
@dataclass(frozen=True)
class CommitmentManifest:
verdict: CommitmentVerdict
directive: str
manifest_digest: str
class ObservationCommitmentGuard:
@staticmethod
def _hash(data: str) -> str:
return hashlib.sha256(data.encode("utf-8")).hexdigest()
@classmethod
def evaluate_observation(
cls, obs: StateObservation, policy: ObservationPolicy
) -> CommitmentManifest:
# Gate 1: Private observation
if not obs.is_shared_state:
digest = cls._hash(json.dumps({
"observation": obs.observation_id,
"type": "PRIVATE"
}, sort_keys=True))
return CommitmentManifest(
verdict=CommitmentVerdict.PRIVATE_OBSERVATION,
directive=f"PROCEED: Observation {obs.observation_id} private, no commitment.",
manifest_digest=digest
)
# Gate 2: No action planned
if not obs.will_act_on_it:
digest = cls._hash(json.dumps({
"observation": obs.observation_id,
"action": "NONE"
}, sort_keys=True))
return CommitmentManifest(
verdict=CommitmentVerdict.OBSERVATION_SUPPORTS_ACTION,
directive=f"PROCEED: Observation {obs.observation_id} informational only.",
manifest_digest=digest
)
# Gate 3: Reflexive commitment risk
if obs.is_observable_by_others and not obs.has_commitment_marker:
return CommitmentManifest(
verdict=CommitmentVerdict.REFLEXIVE_COMMITMENT_DETECTED,
directive=f"HALT: Observation {obs.observation_id} visible but lacks commitment marker.",
manifest_digest=cls._hash(f"REFLEXIVE:{obs.observation_id}")
)
# Gate 4: Action requires commitment marker
if policy.require_commitment_marker_for_action and not obs.has_commitment_marker:
return CommitmentManifest(
verdict=CommitmentVerdict.OBSERVATION_SUPPORTS_ACTION,
directive=f"CAUTION: Observation {obs.observation_id} supports action but lacks commitment marker.",
manifest_digest=cls._hash(f"NO_MARKER:{obs.observation_id}")
)
# Gate 5: Committed
digest = cls._hash(json.dumps({
"observation": obs.observation_id,
"commitment": True,
"stability": obs.has_stability_window,
"observable": obs.is_observable_by_others
}, sort_keys=True))
return CommitmentManifest(
verdict=CommitmentVerdict.OBSERVATION_COMMITS_ACTION,
directive=f"PROCEED: Observation {obs.observation_id} committed with marker.",
manifest_digest=digest
)