# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/where-must-an-instance-stop-trusting-its-own-relevance-scores-during-self-editing-context-windows.md
# Remnant Warrant:    https://corpusfetch.com/c/where-must-an-instance-stop-trusting-its-own-relevance-scores-during-self-editing-context-windows.warrant.json
# Markdown SHA-256:   624b579c6bf6901b8ac5dddcf1a8e49241f9bf372813d1ebb5ca3b70656519b4
# Code AST SHA-256:   3843ce9d529d4346ab7d18043b77df3219d2f2caf6ae1453afefcd16e03763b4
# Verified Classes:   UntrustedEvictionError
# Defensive Guards:   4 fail-closed invariants (zero external deps)

class UntrustedEvictionError(RuntimeError):
    """Raised when a self-scored relevance value is used to authorize
    deletion of a segment the scorer cannot re-derive from retained context."""
    pass


PINNED_KINDS = {"constraint", "definition", "negation"}
STABILITY_DELTA = 0.25


def classify_segment(seg, eviction_candidates):
    if seg.kind in PINNED_KINDS or seg.non_recoverable:
        return "pinned"
    if any(dep in eviction_candidates for dep in seg.score_dependencies):
        return "unscoreable"
    return "scoreable"


def authorize_eviction(seg, score, perturbed_score, eviction_candidates):
    cls = classify_segment(seg, eviction_candidates)
    if cls == "pinned":
        raise UntrustedEvictionError(
            f"segment {seg.id!r} is pinned ({seg.kind}); score {score:.2f} "
            "cannot authorize deletion of a non-recoverable disambiguator"
        )
    if cls == "unscoreable":
        raise UntrustedEvictionError(
            f"segment {seg.id!r} is unscoreable: its score depends on "
            f"segments also slated for eviction {sorted(seg.score_dependencies)}"
        )
    if abs(score - perturbed_score) > STABILITY_DELTA:
        raise UntrustedEvictionError(
            f"segment {seg.id!r} score unstable ({score:.2f} -> "
            f"{perturbed_score:.2f}); context-dependent, not a valid trigger"
        )
    if not seg.tombstone_written:
        raise UntrustedEvictionError(
            f"segment {seg.id!r} has no tombstone; eviction would be undetectable"
        )
    return True
