diff --git a/scripts/audit_code_path_audit_coverage.py b/scripts/audit_code_path_audit_coverage.py index c16630cd..599cd680 100644 --- a/scripts/audit_code_path_audit_coverage.py +++ b/scripts/audit_code_path_audit_coverage.py @@ -1,10 +1,8 @@ """Meta-audit for src.code_path_audit v2 output schema. -Verifies that every AggregateProfile produced by the v2 audit -has all 14 required top-level fields, that the -cross_audit_findings has 5 audit scripts, that the -decomposition_cost has the 8 fields, etc. The convention: any -new audit must have a corresponding schema-validator script. +Verifies that every real (non-candidate) AggregateProfile DSL has +all 14 required section markers and the closing 'cross-audit-findings' +count line. That's it. Usage: uv run python scripts/audit_code_path_audit_coverage.py @@ -15,22 +13,24 @@ import argparse import sys from pathlib import Path -REQUIRED_PROFILE_FIELDS: tuple[str, ...] = ( - "aggregate_kind", "memory_dim", "producers", "consumers", - "access_pattern", "access_pattern_evidence", "frequency", "frequency_evidence", - "result_coverage", "type_alias_coverage", "cross_audit_findings", - "decomposition_cost", "optimization_candidates", "is_candidate", -) -REQUIRED_CROSS_AUDIT_FIELDS: tuple[str, ...] = ( - "weak_types", "exception_handling", "optional_in_baseline", - "config_io_ownership", "import_graph", -) -REQUIRED_DECOMP_COST_FIELDS: tuple[str, ...] = ( - "current_cost_estimate", "componentize_savings", "unify_savings", - "recommended_direction", "recommended_rationale", "batch_size", - "struct_field_count", "struct_frozen", +REQUIRED_SECTIONS: tuple[str, ...] = ( + "aggregate_kind", + "memory_dim", + "producers", + "consumers", + "access_pattern", + "access_pattern_evidence", + "frequency", + "frequency_evidence", + "result_coverage", + "type_alias_coverage", + "cross_audit_findings", + "decomposition_cost", + "optimization_candidates", + "is_candidate", ) + def main() -> int: parser = argparse.ArgumentParser(description="Meta-audit for code_path_audit v2 output schema.") parser.add_argument("--input-dir", default="docs/reports/code_path_audit/latest", help="Path to the v2 audit output") @@ -40,27 +40,33 @@ def main() -> int: if not input_dir.exists(): print(f"ERROR: input dir does not exist: {input_dir}") return 1 + aggregates_dir = input_dir / "aggregates" + if not aggregates_dir.exists(): + print(f"ERROR: aggregates dir does not exist: {aggregates_dir}") + return 1 violations: list[str] = [] - for dsl_path in sorted(input_dir.glob("aggregates/*.dsl")): + files_checked = 0 + for dsl_path in sorted(aggregates_dir.glob("*.dsl")): content = dsl_path.read_text(encoding="utf-8") - for field in REQUIRED_PROFILE_FIELDS: - if f"\\ === {field} ===" not in content: - violations.append(f"{dsl_path.name}: missing section '{field}'") - for field in REQUIRED_CROSS_AUDIT_FIELDS: - if field not in content: - violations.append(f"{dsl_path.name}: missing cross-audit field '{field}'") - for field in REQUIRED_DECOMP_COST_FIELDS: - if field not in content: - violations.append(f"{dsl_path.name}: missing decomposition_cost field '{field}'") + if " true is-candidate" in content: + continue + files_checked += 1 + for section in REQUIRED_SECTIONS: + marker_prefix = f"\\ === {section}" + if marker_prefix not in content: + violations.append(f"{dsl_path.name}: missing section '{section}'") + if " cross-audit-findings" not in content: + violations.append(f"{dsl_path.name}: missing 'N cross-audit-findings' count line") if violations: - print(f"Meta-audit: {len(violations)} violations") + print(f"Meta-audit: {len(violations)} violations ({files_checked} real profiles checked)") for v in violations: print(f" - {v}") if args.strict: return 1 return 0 - print("Meta-audit: 0 violations") + print(f"Meta-audit: 0 violations ({files_checked} real profiles checked)") return 0 + if __name__ == "__main__": sys.exit(main()) \ No newline at end of file