# ruff: noqa # mypy: ignore-errors """Medical stress test — the harder scientific test: safety + security coupled (Phase Ω #3). Medical jointly tests properties not yet tested together: safety and security TIGHTLY COUPLED, a full product lifecycle, very strong risk-management/evidence demands, high regulatory depth. ISO 13485 (a medical QMS) is run as a Company Profile through the SAME engine as before — only new DATA, 0 runtime. The interesting result: IEC 81001-5-1 (health-software security) requires the SAME security capabilities as the CRA, so Medical REUSES cyber MCAPs (the coupling shows up as capability reuse, growing the core), while ALSO adding genuinely new medical caps (clinical evaluation, software safety classification, the ISO 14971 risk file, benefit-risk). Synthetic, no real names. Non-runtime -> no deploy. Run: cd backend-compliance && PYTHONPATH=. python3 reference_scenarios/medical_stress_test.py """ from __future__ import annotations import os import yaml from compliance.company import ( CompanyContext, Certification, CapabilityMappingEntry, build_company_profile, ) from compliance.reasoning.enums import Confidence from compliance.transition_reasoning import ( TransitionContext, TransitionGoal, TargetRequirement, assess_transition, CoverageStatus, ) OUT = [] def w(s=""): OUT.append(s) _TP = os.path.join(os.path.dirname(__file__), "..", "knowledge", "transition_patterns") MED = yaml.safe_load(open(os.path.join(_TP, "transition_pattern_iso13485_to_medical_v1.yaml"), encoding="utf-8")) # existing capability universe (everything modelled before Medical) — to detect reuse vs new known = set() for f in os.listdir(_TP): if f.endswith(".yaml") and "iso13485" not in f: p = yaml.safe_load(open(os.path.join(_TP, f), encoding="utf-8")) known |= {a["capability"] for a in p.get("likely_covered", [])} known |= {d["capability"] for d in p.get("delta_requirements", [])} mgmt = [a["capability"] for a in MED["likely_covered"]] delta_caps = [d["capability"] for d in MED["delta_requirements"]] profile = build_company_profile( CompanyContext(company_id="med", certifications=[Certification(certification_id="ISO13485")]), {"ISO13485": CapabilityMappingEntry(capability_ids=mgmt, confidence=Confidence.MEDIUM)}) assess = assess_transition(TransitionContext(company_id="med", target=TransitionGoal(target_id="Medical")), [TargetRequirement(capability_id=c) for c in mgmt + delta_caps], profile) delta = sorted({c.capability_id for c in assess.coverage if c.status == CoverageStatus.MISSING}) reused = sorted(c for c in delta if c in known) # safety/security coupling: cyber caps reused fresh = sorted(c for c in delta if c not in known) # genuinely new medical caps w("# Medical Stress Test — Safety + Security gekoppelt, der härtere Test (Phase Ω #3)") w("") w('_Medical prüft erstmals gemeinsam: Safety UND Security gekoppelt, voller Produktlebenszyklus, sehr starke Risikomanagement-/Nachweispflichten, hohe regulatorische Tiefe. ISO 13485 als Company Profile durch DIESELBE Engine — nur neue Daten, 0 Runtime. Synthetisch, keine echten Namen._') w("") w("## 1. ISO 13485 als Profil → Delta über dieselbe Engine") w("- ISO 13485 liefert medizinische QMS-Disziplin (Welt-1): %s." % ", ".join("`%s`" % c for c in mgmt[:4]) + " …") w("- Delta (fehlt): **%d** Capabilities — über dieselbe `assess_transition`, **0 neue Runtime-Klassen**." % len(delta)) w("") w("## 2. Safety/Security-KOPPLUNG — Medical REUSED Cyber-MCAPs (IEC 81001-5-1 = CRA-Security)") w("- **Wiederverwendete Cyber-Capabilities (%d):** %s." % (len(reused), ", ".join("`%s`" % c for c in reused))) w("- → Genau das ist die Kopplung: die Gesundheitssoftware-Security (IEC 81001-5-1) fordert **dieselben** Fähigkeiten wie die CRA. Diese MCAPs wandern damit in eine **dritte Domäne** und werden im Convergence-Core noch zentraler.") w("") w("## 3. Genuin neue, medizin-spezifische Capabilities") w("- **Neu (%d):** %s." % (len(fresh), ", ".join("`%s`" % c for c in fresh))) w("- Capabilities als Verben: `conduct_clinical_evaluation`, `classify_software_safety_iec62304`, `maintain_risk_management_file_iso14971`, `perform_benefit_risk_analysis`.") w("") w("## 4. Was ISO 13485 typischerweise NICHT erzeugt _(rejected_assumptions, Welt-1/Welt-2)_") for r in MED["rejected_assumptions"]: w("- %s" % r) w("") w("## Befund") w("") w('> **Die härteste Domäne bisher (Safety+Security gekoppelt, voller Lebenszyklus, tiefe Risiko-/Nachweispflicht) lief durch die unveränderte Pipeline — 0 neue Runtime-Klassen, nur ein Pattern-YAML.** Das stärkste Einzelsignal: **%d Security-Capabilities werden aus dem Cyber-Bestand WIEDERVERWENDET** (IEC 81001-5-1 = CRA), während **%d medizin-spezifische** neu hinzukommen. Genau so wächst ein Kern: gemeinsame Fähigkeiten verbinden Cyber, Maschinenbau, Automotive UND Medizin; das Domänenspezifische bleibt am Rand. Architecture Stability bleibt stabil; der Engpass ist jetzt die Qualität der Wissensmodellierung, nicht die Architektur.' % (len(reused), len(fresh))) w("") print("\n".join(OUT))