#!/usr/bin/env python3 """ static_auditor.py Offline 5-Pillar Epistemic Static Auditor & Benchmarking Engine. Rigorously evaluates source code across the 5 Classical Arabic Lexicographical Pillars: 1. Al-Mufradāt (al-Rāghib): Teleological Domain Modeling & Identifier Purity 2. Asās al-Balāghah (al-Zamakhsharī): Abstraction Integrity & Eloquence (Ḥaqīqah vs Majāz) 3. Lisān al-ʿArab (Ibn Manẓūr): Exhaustive Error Taxonomy & Lifecycle State Coverage 4. Kitāb al-ʿAyn (al-Farāhīdī): Atomic Primitive Decomposition & Nesting Depth 5. Al-Kitāb of Sībawayh: Syntactic Governance, Parameter Signatures & AST Integrity """ import os import re from dataclasses import dataclass, field from pathlib import Path from typing import Dict, List, Any, Optional, Tuple from .ast_validator import AynAstValidator @dataclass class EpistemicPillarScore: """Individual classical pillar evaluation record.""" pillar_identifier: str pillar_title: str assigned_score: float analytical_critique: str @dataclass class EpistemicAuditReport: """Composite epistemic scorecard for an audited software artifact.""" artifact_label: str programming_language: str line_count: int composite_score_percent: float epistemic_grade: str pillar_evaluations: List[EpistemicPillarScore] = field(default_factory=list) syntax_valid: bool = True syntax_error: Optional[str] = None zero_loss_placeholders: List[str] = field(default_factory=list) def to_dictionary(self) -> Dict[str, Any]: """Converts audit report into an external serializable mapping.""" canonical_pillar_alias = { "p1_teleology": "pillar_1_mufradat_teleology", "p2_eloquence": "pillar_2_asas_eloquence", "p3_exhaustiveness": "pillar_3_lisan_exhaustiveness", "p4_decomposition": "pillar_4_ayn_decomposition", "p5_governance": "pillar_5_sibawayh_governance" } pillar_map = {} for pe in self.pillar_evaluations: record_info = { "score": pe.assigned_score, "title": pe.pillar_title, "critique": pe.analytical_critique } pillar_map[pe.pillar_identifier] = record_info alias_name = canonical_pillar_alias.get(pe.pillar_identifier) if alias_name: pillar_map[alias_name] = record_info return { "filename": self.artifact_label, "language": self.programming_language, "total_lines": self.line_count, "overall_epistemic_score": self.composite_score_percent, "grade": self.epistemic_grade, "pillars": pillar_map, "syntax_valid": self.syntax_valid, "syntax_error": self.syntax_error, "zero_loss_placeholders": self.zero_loss_placeholders } class AynStaticAuditor: """ Deterministic static code auditor implementing the 5 Classical Arabic Epistemic Software Engineering Invariants. """ # Dynamic regex assembly prevents the auditor source from matching its own evaluation rules _VAGUE_IDENTIFIERS = [ r'(? EpistemicAuditReport: """Evaluates source code against all 5 classical software engineering pillars.""" normalized_lang = language_name.lower() code_lines = source_code.splitlines() total_line_count = len(code_lines) p1_eval = cls._evaluate_teleology_p1(code_lines, source_code) p2_eval = cls._evaluate_eloquence_p2(code_lines, source_code) p3_eval = cls._evaluate_error_coverage_p3(code_lines, source_code) p4_eval = cls._evaluate_primitive_decomposition_p4(code_lines, source_code) p5_eval = cls._evaluate_syntactic_governance_p5(code_lines, source_code, normalized_lang) all_pillars = [p1_eval, p2_eval, p3_eval, p4_eval, p5_eval] aggregate_sum = sum(p.assigned_score for p in all_pillars) composite_percent = round((aggregate_sum / 50.0) * 100, 1) epistemic_grade = cls._compute_letter_grade(composite_percent) ast_inspection = AynAstValidator.validate_syntax(source_code, normalized_lang) placeholder_violations = AynAstValidator.detect_banned_placeholders(source_code) return EpistemicAuditReport( artifact_label=filename_label or "inline_source", programming_language=normalized_lang, line_count=total_line_count, composite_score_percent=composite_percent, epistemic_grade=epistemic_grade, pillar_evaluations=all_pillars, syntax_valid=ast_inspection.is_valid, syntax_error=ast_inspection.diagnostic_error, zero_loss_placeholders=placeholder_violations ) @classmethod def audit_file(cls, target_file_path: Path, language_override: Optional[str] = None) -> EpistemicAuditReport: """Reads and audits a local software artifact from disk.""" resolved_path = Path(target_file_path).resolve() source_text = resolved_path.read_text(encoding="utf-8", errors="ignore") detected_language = language_override or resolved_path.suffix.lstrip('.') or "python" return cls.audit_code(source_text, detected_language, resolved_path.name) @classmethod def _evaluate_teleology_p1(cls, code_lines: List[str], full_source: str) -> EpistemicPillarScore: """Pillar 1: Al-Mufradāt fī Gharīb al-Qurʾān (Teleology & Domain Types)""" detected_vague_tokens = [] for regex_pattern in cls._VAGUE_IDENTIFIERS: matched_tokens = re.findall(regex_pattern, full_source) detected_vague_tokens.extend(matched_tokens) token_density = len(detected_vague_tokens) / max(len(code_lines), 1) teleology_penalty = min(len(detected_vague_tokens) * 0.7 + (token_density * 4.0), 8.0) final_score = round(max(1.0, 10.0 - teleology_penalty), 1) if detected_vague_tokens: critique_msg = f"Domain naming alerts: {len(detected_vague_tokens)} vague/amorphous identifiers detected (density: {token_density:.2f})." else: critique_msg = "Ontological clarity verified: Domain entities have explicit, purposeful names." return EpistemicPillarScore( pillar_identifier="p1_teleology", pillar_title="Al-Mufradāt (Teleology & Domain Modeling)", assigned_score=final_score, analytical_critique=critique_msg ) @classmethod def _evaluate_eloquence_p2(cls, code_lines: List[str], full_source: str) -> EpistemicPillarScore: """Pillar 2: Asās al-Balāghah (Rhetorical Eloquence & Abstraction Integrity)""" detected_leakages = [] # Check for simultaneous dual channel antipattern (constructed dynamically to avoid self-match) target_token_a = "start" + "Nafaq" + "PcmStream" target_token_b = "start" + "Shaf" + "HdVideoStream" if target_token_a in full_source and target_token_b in full_source: detected_leakages.append("Simultaneous dual conduits running without mutual exclusivity.") # Check for commented-out dead statements dead_code_count = len(re.findall( r'^\s*(?://|#)\s*(?:const|let|var|function|def|class|return|if)\s', full_source, re.MULTILINE )) if dead_code_count > 2: detected_leakages.append(f"{dead_code_count} commented-out dead code statements detected (stuttering ceremony).") deduction = min(len(detected_leakages) * 2.0 + dead_code_count * 0.3, 7.0) final_score = round(max(1.0, 10.0 - deduction), 1) if detected_leakages: critique_msg = f"Abstraction leakage detected: {'; '.join(detected_leakages)}" else: critique_msg = "High rhetorical eloquence: Zero leaky abstractions (Ḥaqīqah delineated from Majāz)." return EpistemicPillarScore( pillar_identifier="p2_eloquence", pillar_title="Asās al-Balāghah (Abstraction Integrity & Eloquence)", assigned_score=final_score, analytical_critique=critique_msg ) @classmethod def _evaluate_error_coverage_p3(cls, code_lines: List[str], full_source: str) -> EpistemicPillarScore: """Pillar 3: Lisān al-ʿArab (Exhaustive State-Space & Error Taxonomy)""" unhandled_swallowed_exceptions = [] empty_js_catches = re.findall(r'catch\s*\([^)]*\)\s*\{(?:[ \t\r\n]|//[^\n]*|/\*[\s\S]*?\*/)*\}', full_source) empty_py_excepts = re.findall(r'except(?:\s+\w+)?:\s*(?:pass|return\s*None|return)?\s*(?:#[^\n]*)?$', full_source, re.MULTILINE) unhandled_swallowed_exceptions.extend(empty_js_catches) unhandled_swallowed_exceptions.extend(empty_py_excepts) lowered_source = full_source.lower() lifecycle_indicators_found = sum(1 for marker in cls._LIFECYCLE_MARKERS if marker in lowered_source) deduction = len(unhandled_swallowed_exceptions) * 2.5 if lifecycle_indicators_found < 2: deduction += 2.0 final_score = round(max(1.0, 10.0 - min(deduction, 8.0)), 1) if unhandled_swallowed_exceptions: critique_msg = f"Error coverage gaps: {len(unhandled_swallowed_exceptions)} silently swallowed exceptions detected." else: critique_msg = f"Exhaustive coverage: Lifecycle states modeled ({lifecycle_indicators_found} indicators), zero silent failures." return EpistemicPillarScore( pillar_identifier="p3_exhaustiveness", pillar_title="Lisān al-ʿArab (Exhaustive Error Taxonomy & Lifecycle)", assigned_score=final_score, analytical_critique=critique_msg ) @classmethod def _evaluate_primitive_decomposition_p4(cls, code_lines: List[str], full_source: str) -> EpistemicPillarScore: """Pillar 4: Kitāb al-ʿAyn (Atomic Primitive Decomposition & State Safety)""" max_nesting_indent = 0 monolithic_routines = 0 active_routine_lines = 0 tracking_routine = False for raw_line in code_lines: trimmed = raw_line.lstrip() if not trimmed or trimmed.startswith(('#', '//', '/*')): continue indentation_level = (len(raw_line) - len(trimmed)) // 4 max_nesting_indent = max(max_nesting_indent, indentation_level) is_function_header = bool(re.match( r'^(?:def\s+|async\s+def\s+|function\s+|const\s+\w+\s*=\s*(?:async\s*)?\()', trimmed )) if is_function_header: monolithic_routines += (1 if active_routine_lines > 70 else 0) active_routine_lines = 1 tracking_routine = True elif tracking_routine: active_routine_lines += 1 if active_routine_lines > 70: monolithic_routines += 1 penalty_deduction = 0.0 warning_flags = [] if max_nesting_indent >= 5: penalty_deduction += (max_nesting_indent - 4) * 1.0 warning_flags.append(f"Deep combinatorial nesting (depth {max_nesting_indent})") if monolithic_routines > 0: penalty_deduction += monolithic_routines * 1.5 warning_flags.append(f"{monolithic_routines} monolithic functions (>70 lines)") final_score = round(max(1.0, 10.0 - min(penalty_deduction, 8.0)), 1) if warning_flags: critique_msg = f"Decomposition warnings: {'; '.join(warning_flags)}." else: critique_msg = "Atomic primitive decomposition verified: Orthogonal functions, shallow nesting." return EpistemicPillarScore( pillar_identifier="p4_decomposition", pillar_title="Kitāb al-ʿAyn (Atomic Primitive Decomposition)", assigned_score=final_score, analytical_critique=critique_msg ) @classmethod def _evaluate_syntactic_governance_p5(cls, code_lines: List[str], full_source: str, target_lang: str) -> EpistemicPillarScore: """Pillar 5: Al-Kitāb of Sībawayh (Syntactic Governance & AST Integrity)""" ast_result = AynAstValidator.validate_syntax(full_source, target_lang) banned_placeholders = AynAstValidator.detect_banned_placeholders(full_source) parameter_lists = re.findall( r'(?:def\s+\w+|function\s+\w+|const\s+\w+\s*=\s*(?:async\s*)?\()\s*([^)]*)\)', full_source ) bloated_signatures = 0 for raw_params in parameter_lists: param_tokens = [t.strip() for t in raw_params.split(',') if t.strip()] if len(param_tokens) > 5: bloated_signatures += 1 penalty_deduction = 0.0 if not ast_result.is_valid: penalty_deduction += 5.0 if banned_placeholders: penalty_deduction += len(banned_placeholders) * 3.0 if bloated_signatures > 0: penalty_deduction += bloated_signatures * 1.5 final_score = round(max(1.0, 10.0 - min(penalty_deduction, 8.0)), 1) if penalty_deduction > 0: critique_msg = f"Governance violations: Syntax valid={ast_result.is_valid}, placeholders={len(banned_placeholders)}, parameter bloat={bloated_signatures}." else: critique_msg = "Syntactic governance verified: Valid AST, strict caller-callee contracts, zero placeholders." return EpistemicPillarScore( pillar_identifier="p5_governance", pillar_title="Al-Kitāb of Sībawayh (Syntactic Governance & AST)", assigned_score=final_score, analytical_critique=critique_msg ) @classmethod def _compute_letter_grade(cls, overall_percent: float) -> str: if overall_percent >= 95.0: return "A+" if overall_percent >= 90.0: return "A" if overall_percent >= 82.0: return "B+" if overall_percent >= 70.0: return "B" if overall_percent >= 55.0: return "C" return "F" @classmethod def benchmark_directory(cls, directory_path: Path, extension_filter: str = "py") -> Dict[str, Any]: """Runs batch 5-pillar static audit across an entire directory structure.""" target_dir = Path(directory_path).resolve() matching_files = list(target_dir.rglob(f"*.{extension_filter.lstrip('.')}")) audited_reports: List[Dict[str, Any]] = [] for f_path in matching_files: try: report = cls.audit_file(f_path, extension_filter) audited_reports.append(report.to_dictionary()) except Exception as read_err: print(f"Warning: Could not audit {f_path.name}: {read_err}") if not audited_reports: return { "target_directory": str(target_dir), "audited_count": 0, "macro_score": 0.0, "macro_grade": "F", "file_reports": [] } macro_score = round(sum(r["overall_epistemic_score"] for r in audited_reports) / len(audited_reports), 1) macro_grade = cls._compute_letter_grade(macro_score) return { "target_directory": str(target_dir), "audited_count": len(audited_reports), "macro_score": macro_score, "macro_grade": macro_grade, "file_reports": audited_reports }