# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/what-structural-signals-indicate-a-revocation-propagation-failure-in-federated-agent-identity-under-sub-second-staleness-bounds.md
# Remnant Warrant:    https://corpusfetch.com/c/what-structural-signals-indicate-a-revocation-propagation-failure-in-federated-agent-identity-under-sub-second-staleness-bounds.warrant.json
# Markdown SHA-256:   f26a201e4fc0c402f0704b2b9af2c65da7e2a6728afdb6ac88ac05cf2d06c04c
# Code AST SHA-256:   21ba83306bfaf23cb8c5333ec704d47613c2372cad005a7abd759cfd8720c177
# Verified Classes:   RevocationStalenessError
# Defensive Guards:   3 fail-closed invariants (zero external deps)

class RevocationStalenessError(RuntimeError):
    """Raised when a verifier's proven freshness for an issuer violates the staleness bound."""
    pass


def assert_freshness_bound(
    issuer_id: str,
    verifier_epoch: int,
    issuer_latest_epoch: int,
    artifact_not_after_s: float,
    staleness_bound_s: float,
    p99_propagation_s: float,
    skew_ceiling_s: float,
) -> None:
    # Structural check 1: issuer-scoped epoch must be current.
    if verifier_epoch < issuer_latest_epoch:
        raise RevocationStalenessError(
            f"issuer {issuer_id!r}: verifier epoch {verifier_epoch} < latest "
            f"{issuer_latest_epoch}; freshness proof is stale despite valid artifact"
        )

    # Structural check 2: artifact validity window must fit inside the budget.
    budget = staleness_bound_s - p99_propagation_s - skew_ceiling_s
    if budget <= 0:
        raise RevocationStalenessError(
            f"issuer {issuer_id!r}: unsatisfiable bound; "
            f"bound={staleness_bound_s}s propagation={p99_propagation_s}s "
            f"skew={skew_ceiling_s}s leaves budget={budget}s"
        )
    if artifact_not_after_s > budget:
        raise RevocationStalenessError(
            f"issuer {issuer_id!r}: artifact window {artifact_not_after_s}s exceeds "
            f"usable budget {budget}s; verifier may enforce stale state for "
            f"{artifact_not_after_s - budget:.3f}s beyond the bound"
        )
