# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/when-must-a-memory-write-be-rejected-at-commit-time-despite-passing-admission-validation.md
# Remnant Warrant:    https://corpusfetch.com/c/when-must-a-memory-write-be-rejected-at-commit-time-despite-passing-admission-validation.warrant.json
# Markdown SHA-256:   a2afdb3c2f7b45578b11da2a49ebe13144179339a62b2d70a0559e2a13704767
# Code AST SHA-256:   4575ea26c7be581d3dfaf1db16f25dbf28675a6a46f4bbee8623b6298ad881bb
# Verified Classes:   MemoryCommitError, RecordState
# Defensive Guards:   5 fail-closed invariants (zero external deps)

import time
from dataclasses import dataclass
from typing import Mapping, Optional


class MemoryCommitError(RuntimeError):
    """Raised when a write passes admission but fails commit-time validation."""

    def __init__(self, cause: str, detail: str):
        super().__init__(f"{cause}: {detail}")
        self.cause = cause
        self.detail = detail


@dataclass(frozen=True)
class RecordState:
    tombstoned: bool
    revoked: bool
    expires_at: float  # monotonic seconds


def commit_write(
    provenance: Mapping[str, RecordState],
    own_ttl_seconds: float,
    revocation_freshness_bound: float,
    last_revocation_sync: float,
    now: Optional[float] = None,
) -> float:
    """Validate and commit a memory write. Returns the commit timestamp.

    Rejects if any provenance ancestor is tombstoned, revoked, or expired
    as of commit, or if the revocation view is staler than the bound.
    """
    t = time.monotonic() if now is None else now

    if t - last_revocation_sync > revocation_freshness_bound:
        raise MemoryCommitError(
            "REVOCATION_RACE",
            f"revocation view is {t - last_revocation_sync:.3f}s stale, "
            f"bound is {revocation_freshness_bound:.3f}s",
        )

    if own_ttl_seconds <= 0:
        raise MemoryCommitError(
            "OWN_TTL_NONPOSITIVE",
            f"own_ttl={own_ttl_seconds:.3f}s at commit",
        )

    for rec_id, state in provenance.items():
        if state.tombstoned:
            raise MemoryCommitError(
                "PROVENANCE_TOMBSTONED",
                f"ancestor {rec_id!r} was forgotten before commit",
            )
        if state.revoked:
            raise MemoryCommitError(
                "PROVENANCE_REVOKED",
                f"ancestor {rec_id!r} is revoked at commit",
            )
        remaining = state.expires_at - t
        if remaining <= 0:
            raise MemoryCommitError(
                "ANCESTOR_TTL_EXPIRED",
                f"ancestor {rec_id!r} expired {-remaining:.3f}s before commit",
            )

    return t
