# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference) # Canonical Residual: https://corpusfetch.com/c/what-provenance-must-accompany-llm-as-judge-decisions-to-survive-model-drift.md # Remnant Warrant: https://corpusfetch.com/c/what-provenance-must-accompany-llm-as-judge-decisions-to-survive-model-drift.warrant.json # Markdown SHA-256: 392854fd973e00cf70d2656dfde85c4837ed79dce76ae80540496b09d3873fe4 # Code AST SHA-256: 24ccca9ca606eda4d1bfd318ad20438330cc94be5d6a76c6c7e3aa78fff8dea7 # Verified Classes: JudgeProvenanceVerdict, LLMJudgeDecision, JudgeAuditPolicy, JudgeManifest, LLMJudgeProvenanceGuard # Defensive Guards: 0 fail-closed invariants (zero external deps) from dataclasses import dataclass from enum import Enum, auto import hashlib import json class JudgeProvenanceVerdict(Enum): FULL_PROVENANCE = auto() PARTIAL_PROVENANCE = auto() NO_PROVENANCE = auto() UNVERIFIABLE_AT_AUDIT = auto() @dataclass(frozen=True) class LLMJudgeDecision: decision_id: str judge_model_fingerprint: str | None judge_prompt_signature: str | None judge_calibration_receipt: str | None decision_rationale_hash: str | None @dataclass(frozen=True) class JudgeAuditPolicy: require_calibration: bool audit_window_sec: float current_epoch: float decision_epoch: float @dataclass(frozen=True) class JudgeManifest: verdict: JudgeProvenanceVerdict directive: str manifest_digest: str class LLMJudgeProvenanceGuard: @staticmethod def _hash(data: str) -> str: return hashlib.sha256(data.encode("utf-8")).hexdigest() @classmethod def evaluate_decision( cls, decision: LLMJudgeDecision, policy: JudgeAuditPolicy ) -> JudgeManifest: # Gate 1: Model fingerprint if not decision.judge_model_fingerprint: return JudgeManifest( verdict=JudgeProvenanceVerdict.NO_PROVENANCE, directive=f"HALT: Decision {decision.decision_id} lacks model fingerprint.", manifest_digest=cls._hash(f"NO_MODEL:{decision.decision_id}") ) # Gate 2: Prompt signature if not decision.judge_prompt_signature: return JudgeManifest( verdict=JudgeProvenanceVerdict.PARTIAL_PROVENANCE, directive=f"HALT: Decision {decision.decision_id} lacks prompt signature.", manifest_digest=cls._hash(f"NO_PROMPT:{decision.decision_id}") ) # Gate 3: Calibration if policy.require_calibration and not decision.judge_calibration_receipt: return JudgeManifest( verdict=JudgeProvenanceVerdict.PARTIAL_PROVENANCE, directive=f"HALT: Decision {decision.decision_id} lacks calibration receipt.", manifest_digest=cls._hash(f"NO_CAL:{decision.decision_id}") ) # Gate 4: Audit window exceeded age = policy.current_epoch - policy.decision_epoch if age > policy.audit_window_sec: digest = cls._hash(json.dumps({ "decision": decision.decision_id, "age": f"{age:.0f}", "model": decision.judge_model_fingerprint, "prompt": decision.judge_prompt_signature, "calibration": decision.judge_calibration_receipt or "NONE" }, sort_keys=True)) return JudgeManifest( verdict=JudgeProvenanceVerdict.FULL_PROVENANCE, directive=f"PROCEED: Full provenance recorded. Auditable at age {age:.0f}s (past {policy.audit_window_sec:.0f}s window).", manifest_digest=digest ) # Gate 5: Full provenance within window digest = cls._hash(json.dumps({ "decision": decision.decision_id, "model": decision.judge_model_fingerprint, "prompt": decision.judge_prompt_signature, "calibration": decision.judge_calibration_receipt or "NONE", "rationale": decision.decision_rationale_hash or "NONE" }, sort_keys=True)) return JudgeManifest( verdict=JudgeProvenanceVerdict.FULL_PROVENANCE, directive=f"PROCEED: Full provenance recorded for decision {decision.decision_id}.", manifest_digest=digest )