# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/when-must-a-raft-leader-refuse-to-serve-reads-after-losing-lease-quorum.md
# Remnant Warrant:    https://corpusfetch.com/c/when-must-a-raft-leader-refuse-to-serve-reads-after-losing-lease-quorum.warrant.json
# Markdown SHA-256:   4d7bc6625f2ec8a053a28a72bca3d65becd740586c67595414c0da4460d9ecfb
# Code AST SHA-256:   46b4d1ac1a48366197646b8ca35dcee235670dea636f95581992aabbc75a05a3
# Verified Classes:   StaleReadRefused, LeaderReadGate
# Defensive Guards:   2 fail-closed invariants (zero external deps)

import time
from dataclasses import dataclass


class StaleReadRefused(RuntimeError):
    """Raised when a leader cannot prove quorum-backed authority for a linearizable read."""
    pass


@dataclass
class LeaderReadGate:
    lease_duration_s: float
    max_clock_skew_s: float
    last_quorum_ack_monotonic: float  # time.monotonic() of last majority heartbeat ack
    read_deadline_s: float

    def _lease_margin_ok(self, now: float) -> bool:
        effective = self.lease_duration_s - self.max_clock_skew_s
        return (now - self.last_quorum_ack_monotonic) <= effective

    def admit_linearizable_read(self, now: float, quorum_ack_within_deadline: bool) -> None:
        if not self._lease_margin_ok(now):
            raise StaleReadRefused(
                f"lease margin exhausted: age={now - self.last_quorum_ack_monotonic:.3f}s "
                f"> effective={self.lease_duration_s - self.max_clock_skew_s:.3f}s"
            )
        if not quorum_ack_within_deadline:
            raise StaleReadRefused(
                f"ReadIndex quorum not confirmed within {self.read_deadline_s:.3f}s; "
                "refusing to serve possibly-stale linearizable read"
            )
        # Safe to serve: quorum-backed authority proven at admission time.


def serve_read(gate: LeaderReadGate, quorum_ack_within_deadline: bool) -> str:
    now = time.monotonic()
    gate.admit_linearizable_read(now, quorum_ack_within_deadline)
    return "value"
