"""Neutral discovery of the frozen ARR deterministic processor identity.""" from __future__ import annotations import importlib.util import sys from pathlib import Path from arr_ingestion.validation import ProcessorPolicy # This is the immutable identity of the retired direct-MCP/callback contract. # It is not a selectable active processor version: only the compatibility # replay path uses it, and that path has no review-required state. LEGACY_DIRECT_PROCESSOR_VERSION = "3.0.0" LEGACY_DIRECT_RULE_SET_SHA256 = ( "c41257208324a43e711de13ec9776a5e6486db334757f152531bf8292a2018eb" ) def load_processor_policy(project_root: Path) -> ProcessorPolicy: skill_root = (project_root / "arr-opera-daily-ingest").resolve() script = skill_root / "scripts" / "process_daily.py" module_name = "_arr_runtime_process_daily" specification = importlib.util.spec_from_file_location(module_name, script) if specification is None or specification.loader is None: raise ValueError("ARR daily processor identity is unavailable") module = importlib.util.module_from_spec(specification) prior = sys.modules.get(module_name) sys.modules[module_name] = module try: specification.loader.exec_module(module) processor_version = str(module.PROCESSOR_VERSION) rule_set_sha256 = str(module.rule_set_sha256()) finally: if prior is None: sys.modules.pop(module_name, None) else: sys.modules[module_name] = prior return ProcessorPolicy( processor_version=processor_version, rule_set_sha256=rule_set_sha256, skill_root=skill_root, ) def load_legacy_direct_processor_policy(project_root: Path) -> ProcessorPolicy: """Return the frozen v3 identity for retired direct-MCP replay only. The active package supplies a narrowly scoped ``--legacy-v3-output`` compatibility replay. Keeping this identity separate prevents the ARR2 XML upload path from accepting or producing a v3 review-less result. """ active = load_processor_policy(project_root) return ProcessorPolicy( processor_version=LEGACY_DIRECT_PROCESSOR_VERSION, rule_set_sha256=LEGACY_DIRECT_RULE_SET_SHA256, skill_root=active.skill_root, python_binary=active.python_binary, legacy_direct_v3=True, )