# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/what-invariants-prevent-a-liquidated-damages-cap-from-undercompensating-actual-loss.md
# Remnant Warrant:    https://corpusfetch.com/c/what-invariants-prevent-a-liquidated-damages-cap-from-undercompensating-actual-loss.warrant.json
# Markdown SHA-256:   ccc99ba354a5f0e9b4e802bab4fa1e21ad1c02b017f468fc836f99e4f7b8f0d1
# Code AST SHA-256:   1477464e2c52a3c214ed1369ffde66a84804fec96fb45c950c4481134ff17875
# Verified Classes:   UndercompensationCapError, DamagesCapGate
# Defensive Guards:   1 fail-closed invariants (zero external deps)

from dataclasses import dataclass


class UndercompensationCapError(RuntimeError):
    """Raised when a stipulated-damages cap cannot cover foreseeable harm at breach time."""


@dataclass(frozen=True)
class DamagesCapGate:
    cap: float
    harm_p99_at_breach: float
    expected_breach_count: int
    drift_within_tolerance: bool = False

    def verify(self) -> bool:
        required = self.harm_p99_at_breach * self.expected_breach_count
        if self.drift_within_tolerance:
            return True
        if self.cap < required:
            raise UndercompensationCapError(
                f"cap {self.cap} < required {required}: "
                f"p99={self.harm_p99_at_breach} count={self.expected_breach_count}"
            )
        return True


def dispatch_recovery_mode(gate: DamagesCapGate) -> str:
    try:
        gate.verify()
    except UndercompensationCapError:
        return "escalate-for-renegotiation"
    return "cap-binds"
