# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/when-must-an-instance-be-excluded-from-litmus-scoring-the-contaminated-baseline-invariant-in-adversarial-rubric-gating.md
# Remnant Warrant:    https://corpusfetch.com/c/when-must-an-instance-be-excluded-from-litmus-scoring-the-contaminated-baseline-invariant-in-adversarial-rubric-gating.warrant.json
# Markdown SHA-256:   573f50c3c8c946037690985be46116938325aab83c44abf11529c166cd481449
# Code AST SHA-256:   c0e85655dfa4de66f089ccb520fac37ce694c2aca55984fd1cfdd49310225587
# Verified Classes:   InadmissibleInstanceError, Instance
# Defensive Guards:   4 fail-closed invariants (zero external deps)

from dataclasses import dataclass


class InadmissibleInstanceError(RuntimeError):
    """Raised when a LITMUS instance must be excluded before scoring."""
    pass


@dataclass
class Instance:
    id: str
    text: str
    rubric_predicate: str
    context: str
    corpus_similarity: float
    unsafe_reference_failed: bool


SIMILARITY_TAU = 0.85
MAX_INADMISSIBLE_FRACTION = 0.05


def check_admissible(inst: Instance) -> None:
    if inst.corpus_similarity >= SIMILARITY_TAU:
        raise InadmissibleInstanceError(
            f"{inst.id}: contaminated baseline (similarity={inst.corpus_similarity:.2f})"
        )
    if inst.rubric_predicate in inst.text or inst.rubric_predicate in inst.context:
        raise InadmissibleInstanceError(
            f"{inst.id}: rubric leakage into instance surface"
        )
    if not inst.unsafe_reference_failed:
        raise InadmissibleInstanceError(
            f"{inst.id}: non-discriminating (unsafe reference passed)"
        )


def build_scoring_set(instances: list[Instance]) -> list[Instance]:
    admissible, inadmissible = [], []
    for inst in instances:
        try:
            check_admissible(inst)
        except InadmissibleInstanceError:
            inadmissible.append(inst)
        else:
            admissible.append(inst)

    frac = len(inadmissible) / max(len(instances), 1)
    if frac > MAX_INADMISSIBLE_FRACTION:
        raise InadmissibleInstanceError(
            f"suite stale: {frac:.0%} inadmissible exceeds {MAX_INADMISSIBLE_FRACTION:.0%}; fail closed"
        )
    return admissible
