Run all verification checks. Returns (errors, warnings).
(knowledge_root: Path, docmcp_root: Path)
| 61 | |
| 62 | |
| 63 | def verify(knowledge_root: Path, docmcp_root: Path) -> tuple: |
| 64 | """Run all verification checks. Returns (errors, warnings).""" |
| 65 | errors = [] |
| 66 | warnings = [] |
| 67 | |
| 68 | # Load data |
| 69 | knowledge = load_knowledge_standards(knowledge_root) |
| 70 | k_total = len(knowledge["harmonised"]) + len(knowledge["other"]) |
| 71 | |
| 72 | docmcp_stds = load_docmcp_standards(docmcp_root) |
| 73 | d_total = len(docmcp_stds) |
| 74 | |
| 75 | print(f"Knowledge repo: {len(knowledge['harmonised'])} harmonised + {len(knowledge['other'])} other = {k_total}") |
| 76 | print(f"docmcp standards_2025.json: {d_total}") |
| 77 | |
| 78 | # Check 1: Total count match |
| 79 | if docmcp_stds and k_total != d_total: |
| 80 | errors.append(f"Count mismatch: knowledge={k_total}, docmcp={d_total}") |
| 81 | |
| 82 | # Check 2: _index.json counts |
| 83 | hs_index_path = knowledge_root / "eu_mdr" / "standards" / "_index.json" |
| 84 | os_index_path = knowledge_root / "eu_mdr" / "other_standards" / "_index.json" |
| 85 | |
| 86 | if hs_index_path.exists(): |
| 87 | with open(hs_index_path) as f: |
| 88 | hs_index = json.load(f) |
| 89 | declared_hs = hs_index.get("total_standards", 0) |
| 90 | actual_hs = len(knowledge["harmonised"]) |
| 91 | if declared_hs != actual_hs: |
| 92 | errors.append(f"Harmonised _index.json count mismatch: declared={declared_hs}, actual={actual_hs}") |
| 93 | |
| 94 | for cat_key, cat_info in hs_index.get("categories", {}).items(): |
| 95 | declared_count = cat_info.get("count", 0) |
| 96 | cat_file = knowledge_root / "eu_mdr" / "standards" / cat_info.get("file", "") |
| 97 | if cat_file.exists(): |
| 98 | with open(cat_file) as f: |
| 99 | actual_count = len(json.load(f).get("standards", [])) |
| 100 | if declared_count != actual_count: |
| 101 | warnings.append(f"HS category '{cat_key}': declared={declared_count}, actual={actual_count}") |
| 102 | |
| 103 | if os_index_path.exists(): |
| 104 | with open(os_index_path) as f: |
| 105 | os_index = json.load(f) |
| 106 | declared_os = os_index.get("total_standards", 0) |
| 107 | actual_os = len(knowledge["other"]) |
| 108 | if declared_os != actual_os: |
| 109 | errors.append(f"Other standards _index.json count mismatch: declared={declared_os}, actual={actual_os}") |
| 110 | |
| 111 | # Check 3: Required fields in knowledge standards |
| 112 | required_fields = ["source_url", "applicable_gsprs"] |
| 113 | for std_id, s in {**knowledge["harmonised"], **knowledge["other"]}.items(): |
| 114 | for field in required_fields: |
| 115 | val = s.get(field) |
| 116 | if not val: |
| 117 | warnings.append(f"Standard '{std_id}' missing '{field}'") |
| 118 | |
| 119 | # Check 4: GSPR mapping completeness |
| 120 | mapping_path = docmcp_root / "data" / "standards" / "gspr_standard_mapping.json" |
no test coverage detected