What time-travel attestation invariants prove past state claims after the fact?
**Date of Record:** 2026 October 27 **Scope:** Applies when an agentic session must prove what was true at a past epoch (audit trail, dispute resolution, or compliance reporting), but the state at that epoch is no longer directly observable, requiring cryptographic time-travel attestation. Does not apply to real-time state queries or sessions with continuous state monitoring that never loses past observability.
Core Distinction
The separation between **current state observation** (what the system says is true now) and **past state attestation** (cryptographic proof of what was true at a past epoch). Relying on current observations creates the **Retrospective Fog**: a dispute arises about a past decision, and the session can only show current state, which has changed since the decision, making it impossible to prove the decision was reasonable at the time it was made.
What Was Observed
In auditable agent architectures, failing to preserve time-travel attestations produces three primary failure modes:
- **Decision Rationale Loss:** An agent made a decision six months ago based on then-current data. The data has changed, and the agent cannot prove the decision was valid given the old data.
- **Dispute Ambiguity:** Two parties dispute a past transaction. Neither can produce evidence of the state at the exact moment of the transaction, and the dispute cannot be resolved.
- **Compliance Audit Failure:** A regulatory audit asks what the system believed on a specific date. The system shows current state, and the auditor cannot verify the historical claim.
Recorded Elements
- **`epoch_state_snapshot_receipt`:** At regular intervals (or at critical decisions), a cryptographic snapshot of system state, with the exact epoch, allowing later proof of "what was true then."
- **`decision_time_state_binding_signature`:** For critical decisions, a cryptographic binding of the decision to the state at decision time, so audits can verify the state was what the agent saw.
- **`transparency_log_inclusion_proof`:** For critical snapshots, a proof that the snapshot was published to a transparency log (e.g., blockchain or Merkle tree), preventing retroactive snapshot modification.
- **`audit_replay_receipt`:** For audits, the cryptographic proof that replaying the attested state produces the attested decision, allowing independent verification.
Condition of Validity
* **Applies when:** Past state must be provable after the fact, current state has changed since then, and audits or disputes depend on the historical truth. * **Does not apply when:** State is permanently retained without change, or no one ever needs to prove past state.
Decision Boundary
- **Is there a pending audit, dispute, or compliance check about past state?** If no, standard state tracking applies. If yes, proceed.
- **Is there an `epoch_state_snapshot_receipt` for the relevant epoch?** If yes, use it to prove past state. If no, the past state cannot be proven.
- **Is the `transparency_log_inclusion_proof` present for the snapshot?** If yes, the snapshot is tamper-evident. If no, the snapshot is only as trustworthy as the session that produced it.
- **Conversely, when can a past-state claim be accepted without snapshot?** Only when the claim is supported by external evidence independent of the system (e.g., third-party attestations), or the claim is strictly informational with no downstream action.
Operational Effect
- **Retrospective Provability:** Past state is cryptographically attested, enabling post-hoc disputes.
- **Tamper-Evidence:** Transparency logs prevent retroactive modification of snapshots.
- **Audit Replay:** Past state and decisions can be independently verified by replay.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json
class TimeTravelVerdict(Enum):
NO_RETROSPECTIVE_NEED = auto()
SNAPSHOT_ATTESTED = auto()
TAMPER_EVIDENT = auto()
UNVERIFIABLE_PAST_STATE = auto()
@dataclass(frozen=True)
class StateSnapshot:
epoch: float
state_hash: str
snapshot_receipt: str | None
transparency_log_proof: str | None
decision_bound_to_snapshot: str | None
@dataclass(frozen=True)
class TimeTravelPolicy:
require_transparency_log: bool
require_decision_binding: bool
@dataclass(frozen=True)
class TimeTravelManifest:
verdict: TimeTravelVerdict
directive: str
manifest_digest: str
class TimeTravelAttestationGuard:
@staticmethod
def _hash(data: str) -> str:
return hashlib.sha256(data.encode("utf-8")).hexdigest()
@classmethod
def evaluate_snapshot(
cls, snapshot: StateSnapshot, policy: TimeTravelPolicy
) -> TimeTravelManifest:
# Gate 1: Snapshot presence
if not snapshot.snapshot_receipt:
return TimeTravelManifest(
verdict=TimeTravelVerdict.UNVERIFIABLE_PAST_STATE,
directive=f"HALT: No snapshot receipt for epoch {snapshot.epoch:.0f}.",
manifest_digest=cls._hash(f"NO_SNAPSHOT:{snapshot.epoch:.0f}")
)
# Gate 2: Transparency log
if policy.require_transparency_log and not snapshot.transparency_log_proof:
return TimeTravelManifest(
verdict=TimeTravelVerdict.SNAPSHOT_ATTESTED,
directive=f"WARN: Snapshot {snapshot.epoch:.0f} attested but not in transparency log.",
manifest_digest=cls._hash(f"NO_LOG:{snapshot.epoch:.0f}")
)
# Gate 3: Decision binding
if policy.require_decision_binding and not snapshot.decision_bound_to_snapshot:
return TimeTravelManifest(
verdict=TimeTravelVerdict.SNAPSHOT_ATTESTED,
directive=f"WARN: Snapshot {snapshot.epoch:.0f} attested but not bound to a decision.",
manifest_digest=cls._hash(f"NO_DECISION:{snapshot.epoch:.0f}")
)
# Gate 4: Tamper-evident
if snapshot.transparency_log_proof:
digest = cls._hash(json.dumps({
"epoch": f"{snapshot.epoch:.0f}",
"state": snapshot.state_hash,
"log_proof": snapshot.transparency_log_proof,
"decision": snapshot.decision_bound_to_snapshot
}, sort_keys=True))
return TimeTravelManifest(
verdict=TimeTravelVerdict.TAMPER_EVIDENT,
directive=f"PROCEED: Snapshot {snapshot.epoch:.0f} tamper-evident with decision binding.",
manifest_digest=digest
)
# Gate 5: Basic attestation
digest = cls._hash(json.dumps({
"epoch": f"{snapshot.epoch:.0f}",
"state": snapshot.state_hash,
"receipt": snapshot.snapshot_receipt
}, sort_keys=True))
return TimeTravelManifest(
verdict=TimeTravelVerdict.SNAPSHOT_ATTESTED,
directive=f"PROCEED: Snapshot {snapshot.epoch:.0f} attested.",
manifest_digest=digest
)