# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/what-structural-signals-indicate-aaif-compliant-agent-revocation-propagation-has-stalled-across-a-federation-mesh.md
# Remnant Warrant:    https://corpusfetch.com/c/what-structural-signals-indicate-aaif-compliant-agent-revocation-propagation-has-stalled-across-a-federation-mesh.warrant.json
# Markdown SHA-256:   0f577fdb0830799c62b65b17592c9b6b887100fa020c85d3ab5f65f9a6218132
# Code AST SHA-256:   d315f8e54c85ed2c7d0a9cd76350e47bd7f4e5859a00df62110c6116a49645f1
# Verified Classes:   RevocationPropagationStall, MeshState
# Defensive Guards:   2 fail-closed invariants (zero external deps)

import time
from dataclasses import dataclass


class RevocationPropagationStall(RuntimeError):
    """Raised when AAIF revocation propagation violates the SLC-lifetime invariant."""
    pass


@dataclass
class MeshState:
    fanout_asymmetry: float          # delivered-but-not-applied / total verifiers
    max_delegation_depth: int
    clock_skew_ratio: float          # skew / SLC_lifetime
    remaining_slc_lifetime_s: float
    measured_propagation_latency_s: float
    fallback_is_permissive: bool


def assess_revocation_stall(state: MeshState) -> str:
    # Invariant: remaining SLC lifetime must exceed measured propagation latency.
    invariant_holds = (
        state.remaining_slc_lifetime_s > state.measured_propagation_latency_s
    )

    if state.fallback_is_permissive and not invariant_holds:
        raise RevocationPropagationStall(
            "Permissive revocation fallback active while SLC lifetime "
            f"({state.remaining_slc_lifetime_s:.1f}s) <= propagation latency "
            f"({state.measured_propagation_latency_s:.1f}s); mesh is exposed."
        )

    if state.fanout_asymmetry > 1.4 and state.max_delegation_depth >= 8:
        if state.clock_skew_ratio > 0.3:
            raise RevocationPropagationStall(
                "High-asymmetry, deep-chain stall with clock skew > 0.3x SLC; "
                "rotation contraindicated, resynchronization will be rejected. "
                "Correct clock skew before resync."
            )
        return "RESYNC_REQUIRED"

    if not invariant_holds:
        return "ROTATE_SLC"

    return "NOMINAL"


if __name__ == "__main__":
    bad = MeshState(
        fanout_asymmetry=1.7,
        max_delegation_depth=9,
        clock_skew_ratio=0.41,
        remaining_slc_lifetime_s=120.0,
        measured_propagation_latency_s=180.0,
        fallback_is_permissive=False,
    )
    # Will raise: deep chain + high asymmetry + clock skew.
    print(assess_revocation_stall(bad))
