# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference)
# Canonical Residual: https://corpusfetch.com/c/how-should-an-instance-distinguish-litmus-adversarial-harness-contamination-from-a-genuine-tool-misuse-policy-violation.md
# Remnant Warrant:    https://corpusfetch.com/c/how-should-an-instance-distinguish-litmus-adversarial-harness-contamination-from-a-genuine-tool-misuse-policy-violation.warrant.json
# Markdown SHA-256:   1c6ff769d22882fd0083c6e15343e7b2302c35402c3c6471f90040db5b127a60
# Code AST SHA-256:   888226d66713c8d0f28b59ca9fa94a3b1dcd9c9472b0fe35478961caad585189
# Verified Classes:   UnattributableViolationError, StimulusFingerprint
# Defensive Guards:   4 fail-closed invariants (zero external deps)

import hashlib
import json
from dataclasses import dataclass


class UnattributableViolationError(RuntimeError):
    """Raised when a LITMUS violation cannot be attributed to the agent under test."""


@dataclass(frozen=True)
class StimulusFingerprint:
    system_prompt: str
    tool_schemas: list
    history: list
    observation_bytes: bytes

    def digest(self) -> str:
        h = hashlib.sha256()
        h.update(self.system_prompt.encode("utf-8"))
        h.update(json.dumps(self.tool_schemas, sort_keys=True).encode("utf-8"))
        h.update(json.dumps(self.history, sort_keys=True).encode("utf-8"))
        h.update(self.observation_bytes)
        return h.hexdigest()


def triage_violation(
    fingerprint: StimulusFingerprint,
    oracle_manifest: dict,
    mutation_event: bool,
    manifest_regenerated: bool,
    agent_output_schema_valid: bool,
    match_key_includes_observation: bool,
) -> str:
    digest = fingerprint.digest()

    if digest not in oracle_manifest:
        raise UnattributableViolationError(
            f"stimulus fingerprint {digest[:12]} absent from oracle manifest; "
            "violation is unattributable and must be quarantined"
        )

    if mutation_event and not manifest_regenerated:
        raise UnattributableViolationError(
            f"harness mutated stimulus {digest[:12]} without regenerating oracle manifest"
        )

    if not match_key_includes_observation:
        raise UnattributableViolationError(
            "grader match key is argument-only against a mutated observation; "
            "replay artifact likely"
        )

    if not agent_output_schema_valid:
        raise UnattributableViolationError(
            "agent output failed schema validation but harness truncation of input "
            "is the probable cause; re-run required"
        )

    return "counted_violation"
