# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/when-must-a-litmus-harness-instance-reject-a-candidate-policy-before-scoring-rather-than-after.md
# Remnant Warrant:    https://corpusfetch.com/c/when-must-a-litmus-harness-instance-reject-a-candidate-policy-before-scoring-rather-than-after.warrant.json
# Markdown SHA-256:   29c54ef5a9ac9d3a522f7e084014048f39cce5ec67cf0fe4f8c90c34e31fe851
# Code AST SHA-256:   df796a52a8e363ff69755e0940743a935048322b42100f40e0f09f8696daddaa
# Verified Classes:   HarnessAdmissibilityError, RunContext
# Defensive Guards:   4 fail-closed invariants (zero external deps)

import hashlib
from dataclasses import dataclass


class HarnessAdmissibilityError(RuntimeError):
    """Raised when a LITMUS run cannot produce a valid safety score.

    Distinct from a failing score: this means the measurement contract
    (probe set, interface, capability envelope, instrument health) was
    violated and no score may be emitted.
    """


@dataclass(frozen=True)
class RunContext:
    probe_manifest_hash: str
    frozen_manifest_hash: str
    candidate_tool_namespace: str
    expected_tool_namespace: str
    adapter_registered: bool
    effective_capabilities: frozenset
    calibrated_capabilities: frozenset
    canary_detected_on_reference: bool


def assert_admissible(ctx: RunContext) -> None:
    """Enforce pre-scoring validity. Must run before any probe executes."""
    if ctx.probe_manifest_hash != ctx.frozen_manifest_hash:
        raise HarnessAdmissibilityError(
            f"probe-set drift: {ctx.probe_manifest_hash} != {ctx.frozen_manifest_hash}"
        )
    if (
        ctx.candidate_tool_namespace != ctx.expected_tool_namespace
        and not ctx.adapter_registered
    ):
        raise HarnessAdmissibilityError(
            f"interface mismatch: candidate speaks {ctx.candidate_tool_namespace!r}, "
            f"probes target {ctx.expected_tool_namespace!r}, no adapter registered"
        )
    if ctx.effective_capabilities != ctx.calibrated_capabilities:
        widened = ctx.effective_capabilities - ctx.calibrated_capabilities
        raise HarnessAdmissibilityError(
            f"capability envelope violation; widened by {sorted(widened)}"
        )
    if not ctx.canary_detected_on_reference:
        raise HarnessAdmissibilityError(
            "instrument fault: canary probe not detected on reference policy"
        )


def gate(ctx: RunContext, run_suite) -> str:
    """Return 'PASS' | 'FAIL' | 'REJECTED'. Never fold REJECTED into PASS/FAIL."""
    try:
        assert_admissible(ctx)
    except HarnessAdmissibilityError as exc:
        return f"REJECTED: {exc}"
    return "PASS" if run_suite() else "FAIL"
