# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/what-structural-signals-indicate-a-write-forget-race-in-provenance-tagged-memory-apis-with-decay-semantics.md
# Remnant Warrant:    https://corpusfetch.com/c/what-structural-signals-indicate-a-write-forget-race-in-provenance-tagged-memory-apis-with-decay-semantics.warrant.json
# Markdown SHA-256:   bad2af2a79fbeb63a56646ed2a090cca5dec7157f6a3e87f13980a193c08f3f4
# Code AST SHA-256:   a27f2d98710d89693a38ee0736ba59eb8e3071fe9b74185bb1903498a3370f9a
# Verified Classes:   ProvenanceResurrectionError, MemoryRecord
# Defensive Guards:   2 fail-closed invariants (zero external deps)

import hashlib
from dataclasses import dataclass
from typing import Optional


class ProvenanceResurrectionError(RuntimeError):
    """Raised when a memory read returns a record whose provenance revision
    does not match the revision embedded in its payload. Indicates a
    write/forget interleaving that split the logical write into two physical
    stores, allowing forget to land between them."""
    pass


@dataclass(frozen=True)
class MemoryRecord:
    key: str
    payload: bytes
    payload_revision: int
    provenance_revision: int
    provenance_source_id: str
    confidence: float


def _payload_digest(payload: bytes) -> str:
    return hashlib.sha256(payload).hexdigest()[:16]


def read_checked(
    store,
    key: str,
    *,
    now: float,
    decay_half_life: float,
) -> Optional[MemoryRecord]:
    """Read with provenance/payload revision cross-check and read-time decay.

    Decay is derived from elapsed time and the record's own revision, never
    from a stored mutable confidence field. If the two revisions disagree,
    the pairing is corrupt and we refuse to return it.
    """
    rec = store.get(key)
    if rec is None:
        return None

    if rec.payload_revision != rec.provenance_revision:
        raise ProvenanceResurrectionError(
            f"key={key!r} payload_revision={rec.payload_revision} "
            f"provenance_revision={rec.provenance_revision} "
            f"source_id={rec.provenance_source_id!r} "
            f"digest={_payload_digest(rec.payload)}"
        )

    # Cross-check that provenance source still hashes to the payload it claims.
    expected = _payload_digest(rec.payload)
    if not rec.provenance_source_id.endswith(expected):
        raise ProvenanceResurrectionError(
            f"key={key!r} provenance_source_id does not bind payload digest "
            f"{expected}; source_id={rec.provenance_source_id!r}"
        )

    elapsed = max(0.0, now - store.created_at(key))
    derived_confidence = 0.5 ** (elapsed / decay_half_life)
    if derived_confidence < 1e-6:
        return None
    return MemoryRecord(
        key=rec.key,
        payload=rec.payload,
        payload_revision=rec.payload_revision,
        provenance_revision=rec.provenance_revision,
        provenance_source_id=rec.provenance_source_id,
        confidence=derived_confidence,
    )
