# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/how-must-an-instance-preserve-reply-routing-identity-across-endpoint-redeploys.md
# Remnant Warrant:    https://corpusfetch.com/c/how-must-an-instance-preserve-reply-routing-identity-across-endpoint-redeploys.warrant.json
# Markdown SHA-256:   1ec381bd537a35d2249681e35fdd1655f8e4b19bc33698d9d30d2ac394a14ce1
# Code AST SHA-256:   df1803389f2001198da71dc03976c730bd9eb033e5eb478cbb176fca3081e9d5
# Verified Classes:   GhostReplyError, ReplyRoutingGate
# Defensive Guards:   2 fail-closed invariants (zero external deps)

from dataclasses import dataclass


class GhostReplyError(RuntimeError):
    """Raised when a reply address recorded at request time may not identify the requester at reply time."""


@dataclass(frozen=True)
class ReplyRoutingGate:
    routing_by_stable_identity: bool
    connection_persistent: bool
    reply_carries_request_identity: bool

    def verify(self) -> bool:
        if self.routing_by_stable_identity:
            return True
        if self.connection_persistent:
            return True
        if not self.reply_carries_request_identity:
            raise GhostReplyError(
                "resolved-address routing with no request identity: "
                "a redeployed requester misdirects replies to a new owner"
            )
        raise GhostReplyError(
            "resolved-address routing is unsound across redeploy; use stable identity"
        )


def dispatch_reply_routing_mode(gate: ReplyRoutingGate) -> str:
    try:
        gate.verify()
    except GhostReplyError:
        return "route-by-stable-identity"
    return "resolved-address-routing"
