""" Unified orchestrator for all five collection-level checks. """ from __future__ import annotations from dataclasses import dataclass, field from typing import Any, Dict, List, Optional from markitect.infospace.models import EntityMeta from markitect.prompts.dependencies.models import DependencyGraph from .redundancy import RedundancyReport, check_redundancy from .coverage import CoverageReport, check_coverage from .coherence import CoherenceReport, check_coherence from .consistency import ConsistencyReport, check_consistency from .granularity import GranularityReport, check_granularity @dataclass class CheckReport: """Unified report from all five collection-level checks.""" redundancy: Optional[RedundancyReport] = None coverage: Optional[CoverageReport] = None coherence: Optional[CoherenceReport] = None consistency: Optional[ConsistencyReport] = None granularity: Optional[GranularityReport] = None def to_dict(self) -> Dict[str, Any]: d: Dict[str, Any] = {} if self.redundancy: d["redundancy"] = self.redundancy.to_dict() if self.coverage: d["coverage"] = self.coverage.to_dict() if self.coherence: d["coherence"] = self.coherence.to_dict() if self.consistency: d["consistency"] = self.consistency.to_dict() if self.granularity: d["granularity"] = self.granularity.to_dict() return d def metrics(self) -> Dict[str, float]: """Extract key metrics for viability checking.""" m: Dict[str, float] = {} if self.redundancy: m["redundancy_ratio"] = self.redundancy.redundancy_ratio if self.coverage: m["coverage_ratio"] = self.coverage.coverage_ratio if self.coherence: m["coherence_components"] = float(self.coherence.connected_components) m["modularity"] = self.coherence.modularity if self.consistency: m["consistency_cycles"] = float(self.consistency.cycle_count) if self.granularity: m["granularity_entropy"] = self.granularity.domain_entropy return m def run_all_checks( entities: List[EntityMeta], embeddings: Optional[Dict[str, list[float]]] = None, graph: Optional[DependencyGraph] = None, extra_attributes: Optional[Dict[str, set[str]]] = None, checks: Optional[List[str]] = None, ) -> CheckReport: """Run all (or selected) collection-level checks. Args: entities: Entity metadata list. embeddings: Pre-computed embedding vectors for C1. graph: Entity relationship graph for C3 and C4. extra_attributes: Extra FCA attributes for C2. checks: List of check names to run. If ``None``, runs all five. Valid names: ``redundancy``, ``coverage``, ``coherence``, ``consistency``, ``granularity``. Returns: :class:`CheckReport` with results from each check. """ run_all = checks is None check_set = set(checks) if checks else set() report = CheckReport() if run_all or "redundancy" in check_set: report.redundancy = check_redundancy(entities, embeddings=embeddings) if run_all or "coverage" in check_set: report.coverage = check_coverage(entities, extra_attributes=extra_attributes) if run_all or "coherence" in check_set: report.coherence = check_coherence(graph=graph, entity_count=len(entities)) if run_all or "consistency" in check_set: report.consistency = check_consistency(entities, graph=graph) if run_all or "granularity" in check_set: report.granularity = check_granularity(entities) return report