# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference) # Canonical Residual: https://corpusfetch.com/c/what-bitemporal-state-invariants-must-survive-retroactive-corrections-to-past-events.md # Remnant Warrant: https://corpusfetch.com/c/what-bitemporal-state-invariants-must-survive-retroactive-corrections-to-past-events.warrant.json # Markdown SHA-256: d9343b68933aecb627992c14f9d6895586788f0276c868305a6c844887256203 # Code AST SHA-256: d2ac09bb0d36278afa269762eaa4042dd03adb776bb24a940ada7405a8c93e55 # Verified Classes: TimeMode, BitemporalVerdict, BitemporalFact, BitemporalQuery, BitemporalPolicy, BitemporalManifest, BitemporalGuard # Defensive Guards: 0 fail-closed invariants (zero external deps) from dataclasses import dataclass from enum import Enum, auto import hashlib import json class TimeMode(Enum): VALID_TIME = auto() TRANSACTION_TIME = auto() BOTH = auto() class BitemporalVerdict(Enum): SINGLE_TIMESTAMP = auto() BITEMPORAL_QUERY_SAFE = auto() IMPLICIT_CONFLATION = auto() CORRECTION_OVERWRITE_RISK = auto() @dataclass(frozen=True) class BitemporalFact: fact_id: str valid_start: float valid_end: float transaction_start: float transaction_end: float has_correction_lineage: bool @dataclass(frozen=True) class BitemporalQuery: fact_id: str time_mode: TimeMode | None @dataclass(frozen=True) class BitemporalPolicy: require_explicit_mode: bool require_correction_lineage: bool @dataclass(frozen=True) class BitemporalManifest: verdict: BitemporalVerdict directive: str manifest_digest: str class BitemporalGuard: @staticmethod def _hash(data: str) -> str: return hashlib.sha256(data.encode("utf-8")).hexdigest() @classmethod def evaluate_query( cls, fact: BitemporalFact, query: BitemporalQuery, policy: BitemporalPolicy ) -> BitemporalManifest: # Gate 1: Explicit mode required if policy.require_explicit_mode and query.time_mode is None: return BitemporalManifest( verdict=BitemporalVerdict.IMPLICIT_CONFLATION, directive=f"HALT: Query for {query.fact_id} lacks explicit time mode.", manifest_digest=cls._hash(f"NO_MODE:{query.fact_id}") ) # Gate 2: Correction lineage if policy.require_correction_lineage and not fact.has_correction_lineage: if fact.valid_start != fact.transaction_start: return BitemporalManifest( verdict=BitemporalVerdict.CORRECTION_OVERWRITE_RISK, directive=f"HALT: Fact {fact.fact_id} has valid/transaction time divergence but no correction lineage.", manifest_digest=cls._hash(f"NO_LINEAGE:{fact.fact_id}") ) # Gate 3: Single timestamp fallback if fact.valid_start == fact.transaction_start and fact.valid_end == fact.transaction_end: digest = cls._hash(json.dumps({ "fact": fact.fact_id, "valid": f"{fact.valid_start:.0f}-{fact.valid_end:.0f}", "txn": f"{fact.transaction_start:.0f}-{fact.transaction_end:.0f}" }, sort_keys=True)) return BitemporalManifest( verdict=BitemporalVerdict.SINGLE_TIMESTAMP, directive=f"PROCEED: Fact {fact.fact_id} has aligned timestamps.", manifest_digest=digest ) # Gate 4: Bitemporal safe digest = cls._hash(json.dumps({ "fact": fact.fact_id, "valid": f"{fact.valid_start:.0f}-{fact.valid_end:.0f}", "txn": f"{fact.transaction_start:.0f}-{fact.transaction_end:.0f}", "mode": query.time_mode.name if query.time_mode else "NONE", "lineage": str(fact.has_correction_lineage) }, sort_keys=True)) return BitemporalManifest( verdict=BitemporalVerdict.BITEMPORAL_QUERY_SAFE, directive=f"PROCEED: Bitemporal fact {fact.fact_id} with mode {query.time_mode.name if query.time_mode else 'NONE'}.", manifest_digest=digest )