"""#59 — Capability Registry zum stabilen, versionierten API-Vertrag machen. Hebt obligations/capabilities.json auf `capability_registry_v1` (contract_version 1.0): - stabile IDs `cap.` (NIE umbenennen) — der Join-Key für Product→Capability (Domäne 3 → Domäne 2). - pro Capability die 5 Vertragsfelder: description · guidance_basis · realizes_obligations · required_procedures · evidence_patterns. - PRODUKTNEUTRAL: KEINE Business-Features hier (die besitzt der Product Knowledge Graph / Session 3). Deterministisch, idempotent. Siehe docs-src/development/session_ownership_model_v1.md. """ from __future__ import annotations import json SRC = "obligations/capabilities.json" # v1-Evidence-Muster je Capability (refinebar; Schema ist stabil, Inhalt waechst). EVIDENCE = { "multi_factor_authentication": ["iam_config_export", "mfa_policy_export", "auth_audit_log"], "session_management": ["session_config_export", "timeout_policy_export"], "transport_encryption": ["tls_config_export", "cipher_scan", "cert_inventory"], "code_signing": ["signature_verification_log", "sbom", "signing_key_policy"], "security_monitoring_alerting": ["siem_config_export", "alert_rule_export", "monitoring_audit_log"], } def main() -> None: src = json.load(open(SRC, encoding="utf-8")) caps = [] for c in src["capabilities"]: slug = c.get("capability_id") or c["id"].split(".")[-1] caps.append({ "id": f"cap.{slug}", "slug": slug, "name": c.get("name", ""), "description": c.get("description", ""), "guidance_basis": c.get("guidance_basis", []), "realizes_obligations": c.get("realized_by", c.get("realizes_obligations", [])), "required_procedures": [], # TBD: Procedure-Registry je Capability (Folge-Block #59) "evidence_patterns": EVIDENCE.get(slug, []), "domains": c.get("domains", []), "provenance": c.get("provenance", {}), }) out = { "schema_version": "capability_registry_v1", "contract_version": "1.0", "status": "stable_api_contract", "note": "PRODUKTNEUTRALER Vertrag zwischen Product Knowledge Graph (Domaene 3, Feature->Capability) " "und Compliance Execution Graph (Domaene 2). Stabile cap.*-IDs NIE umbenennen. KEINE " "Business-Features hier (die besitzt die Product-Session). Siehe " "docs-src/development/session_ownership_model_v1.md + compliance_meta_model_v1.md (Freeze v1.0).", "id_namespace": "cap.", "contract_fields": ["id", "name", "description", "guidance_basis", "realizes_obligations", "required_procedures", "evidence_patterns", "domains"], "dropped": src.get("dropped", {}), "candidate_capabilities_followup": src.get("candidate_capabilities_followup", []), "capabilities": caps, } json.dump(out, open(SRC, "w", encoding="utf-8"), ensure_ascii=False, indent=1) print(f"capability_registry_v1 (contract 1.0): {len(caps)} Capabilities") for c in caps: print(f" {c['id']:38s} realizes {len(c['realizes_obligations']):2d} | guidance {len(c['guidance_basis'])} | evidence {len(c['evidence_patterns'])}") if __name__ == "__main__": main()