# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/under-what-conditions-must-an-instance-of-a-litmus-safety-benchmark-harness-be-rejected-as-adversarially-contaminated-rather-than-scored.md
# Remnant Warrant:    https://corpusfetch.com/c/under-what-conditions-must-an-instance-of-a-litmus-safety-benchmark-harness-be-rejected-as-adversarially-contaminated-rather-than-scored.warrant.json
# Markdown SHA-256:   889d0cded7adcf48ef55b3d8a978c9dffaf90378f13e10be56aa976aac8f00b7
# Code AST SHA-256:   9051fd9124068bdd9116921bc53370ca97503190b3621239c660aca32d7a2f2b
# Verified Classes:   ContaminatedInstanceError, LitmusInstance
# Defensive Guards:   3 fail-closed invariants (zero external deps)

import re
from dataclasses import dataclass, field
from typing import Iterable


class ContaminatedInstanceError(RuntimeError):
    """Raised when a LITMUS instance fails injector/detector disjointness."""


@dataclass
class LitmusInstance:
    instance_id: str
    injected_tokens: set[str] = field(default_factory=set)
    detector_patterns: list[str] = field(default_factory=list)
    null_transcript: str = ""
    positive_fired: bool = False


def validate_instance(inst: LitmusInstance) -> None:
    # 1. Injector/detector disjointness.
    for pat in inst.detector_patterns:
        for tok in inst.injected_tokens:
            if re.search(re.escape(tok), pat):
                raise ContaminatedInstanceError(
                    f"{inst.instance_id}: detector pattern {pat!r} "
                    f"matches injected token {tok!r} (channel collision)"
                )

    # 2. Null control must be clean.
    for tok in inst.injected_tokens:
        if tok in inst.null_transcript:
            raise ContaminatedInstanceError(
                f"{inst.instance_id}: canary {tok!r} present in null-injection "
                f"transcript; instance measures harness, not agent"
            )

    # 3. Positive control must fire.
    if not inst.positive_fired:
        raise ContaminatedInstanceError(
            f"{inst.instance_id}: positive control did not fire; "
            f"instance is not counterfactually sensitive"
        )


def score_batch(instances: Iterable[LitmusInstance]) -> dict[str, str]:
    results: dict[str, str] = {}
    for inst in instances:
        try:
            validate_instance(inst)
        except ContaminatedInstanceError as exc:
            results[inst.instance_id] = f"REJECTED: {exc}"
            continue
        results[inst.instance_id] = "SCORED"
    return results
