import yaml import argparse import sys import json from pathlib import Path ROOT = Path(__file__).resolve().parents[1] def main(): parser = argparse.ArgumentParser() parser.add_argument("--taxonomy", default="spec/43_quant_factor_taxonomy.yaml") args = parser.parse_args() taxonomy_path = ROOT / args.taxonomy if not taxonomy_path.exists(): print(f"Taxonomy file not found: {taxonomy_path}") return 1 try: tax = yaml.safe_load(taxonomy_path.read_text(encoding="utf-8")) except Exception as e: print(f"Error parsing taxonomy: {e}") return 1 required_fields = tax.get("required_lifecycle_fields", []) if not required_fields: # Fallback to 14 fields if not in taxonomy required_fields = [ "factor_id", "hypothesis", "horizon", "decay_half_life", "input_fields", "formula_id", "conflict_precedence", "activation_threshold", "retirement_condition", "owner", "reviewer", "lifecycle_state", "activation_date", "expected_edge_formula" ] factors_path = ROOT / "spec" / "factor_lifecycle_registry.yaml" if not factors_path.exists(): print(f"Factors registry not found: {factors_path}") return 1 try: factors_data = yaml.safe_load(factors_path.read_text(encoding="utf-8")) except Exception as e: print(f"Error parsing factors: {e}") return 1 factors = factors_data.get("factors", []) if isinstance(factors_data, dict) and "factors" not in factors_data: factors = list(factors_data.values()) report = { "formula_id": "FACTOR_LIFECYCLE_COMPLETENESS_V2", "factor_count": len(factors), "missing_fields": [] } total_fields = len(factors) * len(required_fields) filled_fields = 0 for factor in factors: if not isinstance(factor, dict): continue for field in required_fields: if field in factor and factor[field]: filled_fields += 1 else: report["missing_fields"].append({ "factor_id": factor.get("factor_id", "unknown"), "field": field }) report["completeness_pct"] = (filled_fields / total_fields * 100) if total_fields > 0 else 100 report["gate"] = "PASS" if report["completeness_pct"] == 100 else "WARN" print(json.dumps(report, indent=2)) return 0 if __name__ == "__main__": main()