""" Domain-Driven Regulatory Case Study Catalog & Cryptographic Provenance Provider. Provides authoritative benchmark use cases, statutory reference guides, and SHA-256/W3C PROV-O anchors. """ import json from pathlib import Path from typing import Dict, Any, List, Optional, Tuple from src.core.config import PROJECT_ROOT, BENCHMARKS_DIR, SYNTHETIC_DIR CATALOG_PATH = BENCHMARKS_DIR / "case_studies_catalog.json" class CaseStudyCatalog: def __init__(self, catalog_path: Path = CATALOG_PATH): self.catalog_path = catalog_path self._data: Dict[str, Any] = {} self._domains_by_id: Dict[str, Dict[str, Any]] = {} self._cases_by_id: Dict[str, Dict[str, Any]] = {} self._cases_by_title: Dict[str, Dict[str, Any]] = {} self.load() def load(self): if not self.catalog_path.exists(): raise FileNotFoundError(f"Case studies catalog not found at {self.catalog_path}") self._data = json.loads(self.catalog_path.read_text(encoding="utf-8")) self._domains_by_id.clear() self._cases_by_id.clear() self._cases_by_title.clear() for domain in self._data.get("domains", []): dom_id = domain["domain_id"] self._domains_by_id[dom_id] = domain for case in domain.get("case_studies", []): case["domain_id"] = dom_id case["domain_name"] = domain["domain_name"] self._cases_by_id[case["case_id"]] = case self._cases_by_title[case["title"]] = case @property def raw_data(self) -> Dict[str, Any]: return self._data def list_domains(self) -> List[Dict[str, Any]]: return self._data.get("domains", []) def get_domain(self, domain_id: str) -> Optional[Dict[str, Any]]: return self._domains_by_id.get(domain_id) def get_case(self, case_id: str) -> Optional[Dict[str, Any]]: return self._cases_by_id.get(case_id) def get_case_by_title(self, title: str) -> Optional[Dict[str, Any]]: return self._cases_by_title.get(title) def get_cases_for_domain(self, domain_id_or_name: str) -> List[Dict[str, Any]]: for dom in self._data.get("domains", []): if dom["domain_id"] == domain_id_or_name or dom["domain_name"] == domain_id_or_name: return dom.get("case_studies", []) return [] def get_case_document_text(self, case_id_or_title: str) -> str: case = self.get_case(case_id_or_title) or self.get_case_by_title(case_id_or_title) if not case: return "" rel_path = case.get("file_path", "") full_path = PROJECT_ROOT / rel_path if full_path.exists(): data = json.loads(full_path.read_text(encoding="utf-8")) return data.get("raw_document_text", "") return "" def render_quick_bar(self, case_id_or_title: str) -> str: case = self.get_case(case_id_or_title) or self.get_case_by_title(case_id_or_title) if not case: return "" expected = case.get("expected_conformity", "UNKNOWN") if "PASSED" in expected or "CONFORMANT" in expected: pill_color = "#10b981" pill_bg = "#ecfdf5" pill_border = "#a7f3d0" elif "PROHIBITED" in expected: pill_color = "#991b1b" pill_bg = "#fee2e2" pill_border = "#f87171" elif "FAILED" in expected or "NON-CONFORMANT" in expected: pill_color = "#b91c1c" pill_bg = "#fef2f2" pill_border = "#fca5a5" else: pill_color = "#b45309" pill_bg = "#fffbeb" pill_border = "#fde68a" reqs = case.get("regulatory_requirements", {}) fine = reqs.get("fine_exposure_tier", "N/A") tier = case.get("statutory_tier", "AI System") celex = case.get("provenance", {}).get("celex", "32024R1689") eli_uri = case.get("provenance", {}).get("eli_uri", "http://data.europa.eu/eli/reg/2024/1689/oj") return f"""
{expected} ⚖️ {tier} 💰 {fine.split('(')[0].strip()} 📜 EUR-Lex CELEX:{celex} ↗
""" def render_factsheet_html(self, case_id_or_title: str) -> str: case = self.get_case(case_id_or_title) or self.get_case_by_title(case_id_or_title) if not case: return "
Select a case study to display statutory reference factsheet.
" prov = case.get("provenance", {}) reqs = case.get("regulatory_requirements", {}) guidance = case.get("auditor_guidance", {}) frameworks = reqs.get("harmonized_frameworks", {}) expected = case.get("expected_conformity", "UNKNOWN") # Color coding status pill if "PASSED" in expected or "CONFORMANT" in expected: pill_color = "#10b981" pill_bg = "#ecfdf5" pill_border = "#a7f3d0" elif "PROHIBITED" in expected: pill_color = "#7f1d1d" pill_bg = "#fee2e2" pill_border = "#f87171" elif "FAILED" in expected or "NON-CONFORMANT" in expected: pill_color = "#b91c1c" pill_bg = "#fef2f2" pill_border = "#fca5a5" else: pill_color = "#d97706" pill_bg = "#fffbeb" pill_border = "#fde68a" # Mandatory articles tags (12.5px symmetric pills) articles_html = " ".join([ f"{a}" for a in reqs.get("mandatory_articles", []) ]) # NIST tags nist_html = " ".join([ f"{n}" for n in frameworks.get("nist_ai_rmf", []) ]) # ISO tags iso_html = " ".join([ f"{i}" for i in frameworks.get("iso_42001", []) ]) # GDPR tags gdpr_html = " ".join([ f"{g}" for g in frameworks.get("gdpr", []) ]) html = f"""
{case.get('domain_name', 'Domain')}

{case.get('title')}

Legal Basis: {case.get('legal_basis')}
{expected}
🎯 Statutory Intended Purpose: {guidance.get('intended_purpose', '')}
Mandatory EU AI Act Requirements
{articles_html or 'N/A'}
Conformity Procedure: {reqs.get('conformity_procedure', 'N/A')}
Statutory Fine Ceiling: {reqs.get('fine_exposure_tier', 'N/A')}
Harmonized Framework Crosswalk
NIST AI RMF: {nist_html or 'None'}
ISO/IEC 42001: {iso_html or 'None'}
GDPR: {gdpr_html or 'None'}
⚠️ Auditor Pitfall & Common Failure Mode: {guidance.get('common_pitfalls', '')}
🔐 Cryptographic Provenance & Legal Anchor (EUR-Lex) CELEX:{prov.get('celex', '32024R1689')} ↗
"{prov.get('statutory_quote', '')[:220]}..."
Statutory Quote SHA-256: {prov.get('statutory_quote_sha256', '')[:16]}...
Model Spec SHA-256: {prov.get('spec_file_sha256', '')[:16]}...
W3C PROV-O Entity: {prov.get('prov_o_entity', '')}
""" return html