# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/when-must-an-mcp-server-reject-a-client-s-last-event-id-resume-request-rather-than-honor-it.md
# Remnant Warrant:    https://corpusfetch.com/c/when-must-an-mcp-server-reject-a-client-s-last-event-id-resume-request-rather-than-honor-it.warrant.json
# Markdown SHA-256:   502c08e6305abccdaa68ccee7086ca142c8b4dc36ec1be1304590dded210f567
# Code AST SHA-256:   781800e057733d8ead990583db061903ad20a5ceeb45c31e171cd699169a7b00
# Verified Classes:   NonResumableStreamError, StreamGeneration
# Defensive Guards:   5 fail-closed invariants (zero external deps)

class NonResumableStreamError(RuntimeError):
    """Raised when a Last-Event-ID resume cannot be safely honored."""


class StreamGeneration:
    def __init__(self, token: str):
        self.token = token
        self.events: list[tuple[str, str]] = []  # (event_id, payload)
        self.terminal = False

    def append(self, seq: int, payload: str) -> str:
        event_id = f"{self.token}:{seq}"
        self.events.append((event_id, payload))
        return event_id

    def mark_terminal(self) -> None:
        self.terminal = True


def resume_stream(gen: StreamGeneration, last_event_id: str, buffer_head_seq: int) -> list[str]:
    if gen.terminal:
        raise NonResumableStreamError(
            f"stream generation {gen.token} is terminal; client must reset"
        )
    token, _, seq_str = last_event_id.partition(":")
    if token != gen.token:
        raise NonResumableStreamError(
            f"generation mismatch: client claims {token!r}, server is {gen.token!r}"
        )
    try:
        seq = int(seq_str)
    except ValueError:
        raise NonResumableStreamError(f"malformed event id {last_event_id!r}")
    if seq > len(gen.events):
        raise NonResumableStreamError(
            f"event id {last_event_id!r} is beyond tail; client state is inconsistent"
        )
    if seq < buffer_head_seq:
        raise NonResumableStreamError(
            f"event id {last_event_id!r} evicted (head={buffer_head_seq}); gap cannot be bridged"
        )
    return [payload for _, payload in gen.events[seq:]]
