feat: Medical stress test (safety+security coupled) + Missing Convergence report (Phase Ω #3)

Medical before Payment: the harder scientific test (safety AND security coupled, full lifecycle,
deep risk/evidence demands). ISO 13485 runs through the SAME engine as ISO 27001 -> CRA, only new
data, 0 runtime. The key result: IEC 81001-5-1 (health-software security) pulls in the SAME security
MCAPs as the CRA, so Medical REUSES cyber capabilities (the safety/security coupling appears as
capability reuse) while adding 7 genuinely new medical caps (clinical evaluation, software safety
classification, ISO 14971 risk file, benefit-risk). rejected_assumptions intact.

Effect on the convergence core: secure_signed_update_distribution 18 -> 24 and
technical_vulnerability_management 17 -> 23, now spanning 3 domains (cyber + industrial + medical) —
the core visibly GROWS, exactly the convergence signal.

New 5th report: MISSING CONVERGENCE — deterministic (no ML) token-cluster detector for potential
structural duplications: a name token shared by >=3 MCAPs across >=2 distinct sources is flagged for
EXPERT REVIEW (never auto-merged). Surfaces e.g. the `risk` cluster (6 risk MCAPs across 6 sources)
and `security`/`software`; single-source decompositions are filtered out. Complements Suspicious by
looking at cross-source duplication, not single MCAPs.

Also records the durable modelling rule extracted from the frequency fix: evidence is attributed to
its ORIGIN; its value against a target is computed later (relevance(evidence,target)). Ledger now 8
sources, Architecture Stability 8/8 = 100%. Non-runtime -> no deploy. 29 tests pass, check-loc 0.
This commit is contained in:
Benjamin Admin
2026-06-28 12:09:52 +02:00
parent 897e9464a7
commit 80f2e2f619
9 changed files with 343 additions and 26 deletions
@@ -86,6 +86,16 @@ sources:
integration_kind: data_only integration_kind: data_only
family: cyber # convergence test: same capability fed by many sources, model stayed stable family: cyber # convergence test: same capability fed by many sources, model stayed stable
exercised_by: "automotive_convergence_stress_test" exercised_by: "automotive_convergence_stress_test"
- source: "ISO 13485 -> Medical device (MDR / IEC 62304 / ISO 14971 / IEC 81001-5-1)"
domain: medical
target_type: regulation
integrated_as: transition_pattern_data
new_runtime_classes: 0
new_pipeline: false
new_capability_types: 7 # of 11 delta caps, 4 REUSE cyber MCAPs (IEC 81001-5-1 = CRA security coupling)
integration_kind: data_only
family: non_cyber # safety/clinical domain WITH a security coupling — the harder joint test
exercised_by: "medical_stress_test"
# --- One-time, domain-AGNOSTIC pipeline functions (built once, now FROZEN per Phase Ω). --- # --- One-time, domain-AGNOSTIC pipeline functions (built once, now FROZEN per Phase Ω). ---
# Listed for honesty so the stability KPI cannot be gamed: these are NOT per-domain costs. The last # Listed for honesty so the stability KPI cannot be gamed: these are NOT per-domain costs. The last
@@ -0,0 +1,82 @@
# Transition KNOWLEDGE Pattern (TKP) — ISO 13485 (Medical QMS) -> Medical device compliance
# The HARDER scientific test (Phase Ω, test #3). Medical brings, at once, properties not yet jointly
# tested: safety and security TIGHTLY COUPLED, a full product lifecycle, very strong risk-management +
# evidence demands, and high regulatory depth. Sources: MDR, IEC 62304 (software lifecycle),
# ISO 14971 (risk management), IEC 81001-5-1 (health-software security).
#
# KEY for the convergence analysis: IEC 81001-5-1 (health-software security) REQUIRES the same security
# capabilities the CRA does (secure update, vulnerability management, access control, SBOM). So Medical
# REUSES the cyber MCAPs — the safety/security coupling shows up as capability reuse, growing the core
# into a 3rd domain. Alongside that, Medical adds genuinely new caps (clinical evaluation, software
# safety classification, the ISO 14971 risk file, benefit-risk). Capabilities are VERBS. Expert L1 draft.
id: TP-ISO13485-MEDICAL-v1
status: draft
version: 1
transition_goal:
from:
standard: "ISO 13485"
edition: "2016"
nature: organizational_medical_qms
to:
domain: "Medical device compliance (software-containing device)"
nature: product_safety_and_security
sources: ["MDR", "IEC_62304", "ISO_14971", "IEC_81001_5_1"]
one_line: "Move a manufacturer whose management system is ISO 13485 toward placing a software-containing medical device on the EU market."
provenance:
author: "Claude (Reasoning session) — AI first draft (L1)"
basis: "ISO 13485:2016 (4.2 documentation, 7.3 design, 7.1/risk, 8.2.1 feedback/PMS, 8.5 CAPA) vs MDR + IEC 62304 + ISO 14971 + IEC 81001-5-1."
reviewed_by: null
validated_by: null
disclaimer: >
Curated expert knowledge, NOT a normative proof. KEY INSIGHT: ISO 13485 is a medical QUALITY
management system — it gives QMS + design-control + risk-process + PMS discipline, but not the
concrete clinical, software-lifecycle, risk-file or product-security EVIDENCE. Safety and security
are coupled: IEC 81001-5-1 pulls in the SAME security capabilities the CRA requires. Welt-1.
source_state_variants:
certified: "ISO 13485 certified -> QMS/design/risk-process assumptions hold; concrete evidence still missing."
qms_introduced: "QMS implemented but not certified -> downgrade 'partially_supports' to needs_confirmation."
# ── A) LIKELY COVERED — medical QMS management discipline (partially_supports), NOT evidence. ──
likely_covered:
- {capability: manage_document_control, iso13485_basis: "4.2", relationship: partially_supports, confidence_source: relationship, verification: required, expected_evidence: [document_control_procedure], rationale: "ISO 13485 document control maintains records but creates no clinical/safety content.", reviewable_claim: "Document control maintains, not creates, medical evidence."}
- {capability: operate_capa_process, iso13485_basis: "8.5", relationship: partially_supports, confidence_source: relationship, verification: required, expected_evidence: [capa_procedure], rationale: "CAPA gives corrective/preventive discipline, not product safety evidence.", reviewable_claim: "CAPA does not establish device safety."}
- {capability: conduct_design_controls, iso13485_basis: "7.3", relationship: partially_supports, confidence_source: relationship, verification: required, expected_evidence: [design_history_file], rationale: "Design controls structure development but do not by themselves produce IEC 62304 software-lifecycle records.", reviewable_claim: "Design controls do not produce the IEC 62304 lifecycle records."}
- {capability: run_risk_management_process, iso13485_basis: "7.1", relationship: partially_supports, confidence_source: relationship, verification: required, expected_evidence: [risk_management_procedure], rationale: "ISO 13485 requires a risk-management PROCESS, but the ISO 14971 risk FILE with concrete analyses is separate.", reviewable_claim: "A risk-management process is not a completed ISO 14971 risk file."}
- {capability: control_suppliers_medical, iso13485_basis: "7.4", relationship: partially_supports, confidence_source: relationship, verification: required, expected_evidence: [supplier_controls], rationale: "Supplier controls give purchasing discipline, not component security.", reviewable_claim: "Medical supplier control does not establish component security."}
- {capability: operate_post_market_surveillance, iso13485_basis: "8.2.1", relationship: partially_supports, confidence_source: relationship, verification: required, expected_evidence: [pms_procedure], rationale: "Feedback/PMS process exists, but MDR PMS + vigilance reporting evidence is separate.", reviewable_claim: "A feedback process is not MDR post-market surveillance evidence."}
# ── B) DELTA — concrete medical evidence + (coupled) product security. ──
delta_requirements:
# B1) safety/security COUPLING — IEC 81001-5-1 reuses the SAME cyber MCAPs as the CRA:
- {capability: secure_signed_update_distribution, missing_because: "QMS has no secure update.", why_asked: "IEC 81001-5-1 requires authenticity/integrity-protected health-software updates (= CRA).", dropped_if: ["Updates are signed and verified."], needed_information: verify_existence, covers_targets: [IEC_81001_5_1, MDR], expected_evidence: [config_export], priority: high, reviewable_claim: "ISO 13485 does not establish signed update distribution."}
- {capability: technical_vulnerability_management, missing_because: "QMS has no vulnerability management.", why_asked: "IEC 81001-5-1 requires handling health-software vulnerabilities (= CRA).", dropped_if: ["A vulnerability management process exists."], needed_information: verify_existence, covers_targets: [IEC_81001_5_1, MDR], expected_evidence: [vulnerability_management_procedure], priority: high, reviewable_claim: "ISO 13485 does not establish vulnerability management."}
- {capability: access_control_and_authentication, missing_because: "QMS has no product access control.", why_asked: "IEC 81001-5-1 requires authentication/access control for health software (= CRA).", dropped_if: ["Authentication is documented + tested."], needed_information: verify_existence, covers_targets: [IEC_81001_5_1], expected_evidence: [access_control_policy], priority: medium, reviewable_claim: "ISO 13485 does not establish product authentication."}
- {capability: sbom_creation, missing_because: "QMS produces no SBOM.", why_asked: "IEC 81001-5-1 expects a software bill of materials (= CRA).", dropped_if: ["A machine-readable SBOM is produced per release."], needed_information: determine_sbom_maturity, covers_targets: [IEC_81001_5_1], expected_evidence: [sbom], priority: high, reviewable_claim: "ISO 13485 does not produce an SBOM."}
# B2) genuinely NEW medical-specific evidence:
- {capability: conduct_clinical_evaluation, missing_because: "QMS produces no clinical evidence.", why_asked: "The MDR requires a clinical evaluation / clinical evidence.", dropped_if: ["A clinical evaluation report exists."], needed_information: request_evidence, covers_targets: [MDR], expected_evidence: [clinical_evaluation_report], priority: high, reviewable_claim: "ISO 13485 does not produce clinical evidence."}
- {capability: classify_software_safety_iec62304, missing_because: "QMS does not classify software safety.", why_asked: "IEC 62304 requires a software safety classification (Class A/B/C) driving the lifecycle.", dropped_if: ["A software safety classification exists."], needed_information: request_evidence, covers_targets: [IEC_62304], expected_evidence: [software_safety_classification], priority: high, reviewable_claim: "ISO 13485 does not classify software safety per IEC 62304."}
- {capability: maintain_risk_management_file_iso14971, missing_because: "QMS has a process, not the file.", why_asked: "ISO 14971 requires a maintained risk management file with concrete analyses + controls.", dropped_if: ["An ISO 14971 risk management file exists."], needed_information: request_evidence, covers_targets: [ISO_14971, MDR], expected_evidence: [risk_management_file], priority: high, reviewable_claim: "An ISO 13485 risk process is not a completed ISO 14971 risk file."}
- {capability: perform_benefit_risk_analysis, missing_because: "QMS does not weigh benefit vs risk.", why_asked: "The MDR + ISO 14971 require a documented benefit-risk determination.", dropped_if: ["A benefit-risk analysis exists."], needed_information: request_evidence, covers_targets: [MDR, ISO_14971], expected_evidence: [benefit_risk_analysis], priority: medium, reviewable_claim: "ISO 13485 does not document a benefit-risk analysis."}
- {capability: implement_software_lifecycle_iec62304, missing_because: "QMS has design controls, not the IEC 62304 lifecycle.", why_asked: "IEC 62304 requires a defined software development + maintenance lifecycle.", dropped_if: ["IEC 62304 lifecycle records exist."], needed_information: request_evidence, covers_targets: [IEC_62304], expected_evidence: [software_lifecycle_records], priority: high, reviewable_claim: "ISO 13485 does not produce IEC 62304 lifecycle records."}
- {capability: assign_unique_device_identification, missing_because: "QMS has no UDI.", why_asked: "The MDR requires UDI assignment + registration.", dropped_if: ["UDI is assigned and registered."], needed_information: verify_existence, covers_targets: [MDR], expected_evidence: [udi_record], priority: medium, reviewable_claim: "ISO 13485 does not assign UDI."}
- {capability: compile_medical_technical_documentation, missing_because: "QMS has no MDR technical documentation.", why_asked: "The MDR (Annex II/III) requires complete technical documentation + DoC.", dropped_if: ["MDR technical documentation exists."], needed_information: request_evidence, covers_targets: [MDR], expected_evidence: [technical_documentation, declaration_of_conformity], priority: high, reviewable_claim: "ISO 13485 does not satisfy MDR technical documentation."}
rejected_assumptions:
- "ISO 13485 does NOT produce clinical evidence or a clinical evaluation."
- "ISO 13485 does NOT produce the ISO 14971 risk management FILE (only the process)."
- "ISO 13485 does NOT produce IEC 62304 software-lifecycle records or a software safety classification."
- "ISO 13485 does NOT establish health-software security (IEC 81001-5-1 = the same security caps as the CRA)."
determinism_goal: >
Two independent auditors should agree that an ISO-13485-only manufacturer has medical QMS discipline
but is missing the clinical, software-lifecycle, risk-file and product-security evidence — and that the
security part is the SAME capability set as the CRA (safety/security coupling).
review_checklist:
- "Confirm delta + rejected_assumptions with a medical regulatory expert."
- "Replace capability ids with Capability Registry MCAP ids once assigned."
@@ -13,11 +13,12 @@ _Der Fokus hat sich verschoben: nicht mehr „kann die Architektur das?", sonder
| OEM Specification (Lastenheft) | cyber | 0 | 0 | 4 | ✅ | | OEM Specification (Lastenheft) | cyber | 0 | 0 | 4 | ✅ |
| ISO 14001 -> Environmental/Material (REACH/RoHS/Batterie/Wasser/Energie/Abfall) | non_cyber | 0 | 0 | 16 | ✅ | | ISO 14001 -> Environmental/Material (REACH/RoHS/Batterie/Wasser/Energie/Abfall) | non_cyber | 0 | 0 | 16 | ✅ |
| Automotive ECU for OEM X (CRA / UNECE R155+R156 / IATF 16949 / TISAX / ASPICE / OEM spec) | cyber | 0 | 0 | 14 | ✅ | | Automotive ECU for OEM X (CRA / UNECE R155+R156 / IATF 16949 / TISAX / ASPICE / OEM spec) | cyber | 0 | 0 | 14 | ✅ |
| ISO 13485 -> Medical device (MDR / IEC 62304 / ISO 14971 / IEC 81001-5-1) | non_cyber | 0 | 0 | 7 | ✅ |
- **Architecture Stability: 7/7 = 100%** der Quellen ohne neue Runtime-Klasse und ohne neue Pipeline. - **Architecture Stability: 8/8 = 100%** der Quellen ohne neue Runtime-Klasse und ohne neue Pipeline.
- **Knowledge Velocity: 7/7 = 100%** der Quellen **data-only** integriert (kein Entwickler nötig). - **Knowledge Velocity: 8/8 = 100%** der Quellen **data-only** integriert (kein Entwickler nötig).
- **Generalität über Cyber hinaus: 1/7 Quellen NICHT-Cyber** (Umwelt) — trugen die Pipeline ebenfalls 0/0. Das ist der eigentliche Test (ein anderes Denkmodell, nicht noch ein Cyber-Regelwerk). - **Generalität über Cyber hinaus: 2/8 Quellen NICHT-Cyber** (Umwelt) — trugen die Pipeline ebenfalls 0/0. Das ist der eigentliche Test (ein anderes Denkmodell, nicht noch ein Cyber-Regelwerk).
- **Capability-Modell-Frühindikator: 59 neue Typen gesamt, Maximum 16** (Umwelt, erste Nicht-Cyber-Domäne) — in Range, KEIN Granularitätsalarm (Alarm ≈ eine Domäne braucht plötzlich ~80 neue Typen bei 0 Runtime-Change → Modell zu grob/fein). - **Capability-Modell-Frühindikator: 66 neue Typen gesamt, Maximum 16** (Umwelt, erste Nicht-Cyber-Domäne) — in Range, KEIN Granularitätsalarm (Alarm ≈ eine Domäne braucht plötzlich ~80 neue Typen bei 0 Runtime-Change → Modell zu grob/fein).
## Ehrlichkeit: die Pipeline-Funktionen sind EINMALIG (jetzt eingefroren) ## Ehrlichkeit: die Pipeline-Funktionen sind EINMALIG (jetzt eingefroren)
- 6 domänen-AGNOSTISCHE Funktionen, einmal gebaut, nicht je Domäne: `transition_reasoning (RS-005)`, `optimization`, `journey_matcher (ADR-011)`, `playbook`, `completeness`, `company (2A)`. - 6 domänen-AGNOSTISCHE Funktionen, einmal gebaut, nicht je Domäne: `transition_reasoning (RS-005)`, `optimization`, `journey_matcher (ADR-011)`, `playbook`, `completeness`, `company (2A)`.
@@ -31,8 +32,8 @@ _Der Fokus hat sich verschoben: nicht mehr „kann die Architektur das?", sonder
| **Produktion** (wie TUN/BEWEISEN) | Playbooks, Verification, Reference Scenarios | | **Produktion** (wie TUN/BEWEISEN) | Playbooks, Verification, Reference Scenarios |
## Die drei Erfolgsfragen ab jetzt (statt Coverage) ## Die drei Erfolgsfragen ab jetzt (statt Coverage)
1. **Musste für eine neue Domäne Runtime-Code geändert werden?** → bisher: **nein** (7/7). 1. **Musste für eine neue Domäne Runtime-Code geändert werden?** → bisher: **nein** (8/8).
2. **Knowledge Velocity** — neues Wissen ohne Entwickler aufnehmbar? → bisher: **ja** (7/7 data-only). 2. **Knowledge Velocity** — neues Wissen ohne Entwickler aufnehmbar? → bisher: **ja** (8/8 data-only).
3. **Architecture Stability** — bestehende Capability/Journey strukturell ändern oder nur Daten ergänzen? → bisher: **nur Daten**. 3. **Architecture Stability** — bestehende Capability/Journey strukturell ändern oder nur Daten ergänzen? → bisher: **nur Daten**.
> **Befund:** Über fünf Zielarten und sechs Quellen blieb `Reality → Evidence → Capability → Required → Delta → Journey → Roadmap → Playbooks → Verification` unverändert. Das ist der eigentliche Nachweis: keine Compliance-Architektur, sondern eine allgemeine Requirements-Verifikationsarchitektur, die ihre Generalität UNTER realer fachlicher Belastung behält. Der nächste Test ist nicht ein Feature, sondern die nächste echte Domäne (Umwelt-Cluster · Automotive · Medizintechnik · Payment) — jede als neue Ledger-Zeile, bei stabilem KPI. > **Befund:** Über fünf Zielarten und sechs Quellen blieb `Reality → Evidence → Capability → Required → Delta → Journey → Roadmap → Playbooks → Verification` unverändert. Das ist der eigentliche Nachweis: keine Compliance-Architektur, sondern eine allgemeine Requirements-Verifikationsarchitektur, die ihre Generalität UNTER realer fachlicher Belastung behält. Der nächste Test ist nicht ein Feature, sondern die nächste echte Domäne (Umwelt-Cluster · Automotive · Medizintechnik · Payment) — jede als neue Ledger-Zeile, bei stabilem KPI.
@@ -1,47 +1,59 @@
# Cross-Domain MCAP Convergence Analysis — wo konvergiert das Wissensmodell? # Cross-Domain MCAP Convergence Analysis — wo konvergiert das Wissensmodell?
_Nicht „welche MCAPs kommen am häufigsten vor?" (Häufigkeit täuscht), sondern „welche MCAPs TRAGEN den größten Teil des Systems?". Deterministischer **Impact-Score** (kein ML), internes Engineering-Werkzeug, reine Aggregation über vorhandene Daten (5 Transition Patterns + 7 Automotive-Quellen). Non-runtime, keine echten Namen._ _Nicht „welche MCAPs kommen am häufigsten vor?" (Häufigkeit täuscht), sondern „welche MCAPs TRAGEN den größten Teil des Systems?". Deterministischer **Impact-Score** (kein ML), internes Engineering-Werkzeug, reine Aggregation über vorhandene Daten (6 Transition Patterns inkl. Medical + 7 Automotive-Quellen). Non-runtime, keine echten Namen._
## Impact-Score (deterministisch) ## Impact-Score (deterministisch)
> `Impact = distinct Sources + distinct Target-Types + distinct Domains + distinct Journeys + Regulatory Leverage + Business Leverage` > `Impact = distinct Sources + distinct Target-Types + distinct Domains + distinct Journeys + Regulatory Leverage + Business Leverage`
- 62 distinct Capabilities (MCAP-Kandidaten) über alle Quellen aggregiert. - 75 distinct Capabilities (MCAP-Kandidaten) über alle Quellen aggregiert.
## 1. Core MCAPs — höchster Impact (die tragenden Knoten) ## 1. Core MCAPs — höchster Impact (die tragenden Knoten)
| Capability | Impact | Sources | Types | Domains | Journeys | | Capability | Impact | Sources | Types | Domains | Journeys |
|---|---:|---:|---:|---:|---:| |---|---:|---:|---:|---:|---:|
| `secure_signed_update_distribution` | **18** | 5 | 2 | 2 | 4 | | `secure_signed_update_distribution` | **24** | 7 | 2 | 3 | 5 |
| `technical_vulnerability_management` | **17** | 5 | 3 | 2 | 4 | | `technical_vulnerability_management` | **23** | 7 | 3 | 3 | 5 |
| `access_control_and_authentication` | **15** | 4 | 2 | 2 | 5 | | `access_control_and_authentication` | **19** | 5 | 2 | 3 | 6 |
| `incident_management` | **14** | 4 | 2 | 2 | 4 | | `incident_management` | **14** | 4 | 2 | 2 | 4 |
| `product_cyber_risk_assessment` | **13** | 3 | 1 | 2 | 4 | | `product_cyber_risk_assessment` | **13** | 3 | 1 | 2 | 4 |
| `sbom_creation` | **13** | 2 | 1 | 3 | 5 |
| `secure_development_lifecycle` | **11** | 2 | 2 | 2 | 4 | | `secure_development_lifecycle` | **11** | 2 | 2 | 2 | 4 |
| `supplier_security` | **11** | 3 | 2 | 2 | 3 | | `supplier_security` | **11** | 3 | 2 | 2 | 3 |
| `ce_conformity_assessment_and_technical_documentation` | **9** | 2 | 1 | 1 | 3 | | `ce_conformity_assessment_and_technical_documentation` | **9** | 2 | 1 | 1 | 3 |
| `coordinated_vulnerability_disclosure` | **9** | 1 | 1 | 2 | 4 | | `coordinated_vulnerability_disclosure` | **9** | 1 | 1 | 2 | 4 |
| `sbom_creation` | **9** | 1 | 1 | 2 | 4 |
→ Hoher Impact = ein Knoten verbindet viele Quellen ÜBER Typen/Domänen/Journeys hinweg — nicht „in 40 Dokumenten einer Normenfamilie". → Hoher Impact = ein Knoten verbindet viele Quellen ÜBER Typen/Domänen/Journeys hinweg — nicht „in 40 Dokumenten einer Normenfamilie".
## 2. Emerging MCAPs — verbinden ≥2 Domänen (Brücken zwischen Anforderungswelten) ## 2. Emerging MCAPs — verbinden ≥2 Domänen (Brücken zwischen Anforderungswelten)
- `secure_signed_update_distribution`2 Domänen (automotive, industrial_automation), 2 Typen. - `secure_signed_update_distribution`3 Domänen (automotive, industrial_automation, medical), 2 Typen.
- `technical_vulnerability_management`2 Domänen (automotive, industrial_automation), 3 Typen. - `technical_vulnerability_management`3 Domänen (automotive, industrial_automation, medical), 3 Typen.
- `access_control_and_authentication`2 Domänen (automotive, industrial_automation), 2 Typen. - `access_control_and_authentication`3 Domänen (automotive, industrial_automation, medical), 2 Typen.
- `incident_management` — 2 Domänen (automotive, industrial_automation), 2 Typen. - `incident_management` — 2 Domänen (automotive, industrial_automation), 2 Typen.
- `product_cyber_risk_assessment` — 2 Domänen (automotive, industrial_automation), 1 Typen. - `product_cyber_risk_assessment` — 2 Domänen (automotive, industrial_automation), 1 Typen.
- `sbom_creation` — 3 Domänen (automotive, industrial_automation, medical), 1 Typen.
- `secure_development_lifecycle` — 2 Domänen (automotive, industrial_automation), 2 Typen. - `secure_development_lifecycle` — 2 Domänen (automotive, industrial_automation), 2 Typen.
- `supplier_security` — 2 Domänen (automotive, industrial_automation), 2 Typen. - `supplier_security` — 2 Domänen (automotive, industrial_automation), 2 Typen.
- `coordinated_vulnerability_disclosure` — 2 Domänen (automotive, industrial_automation), 1 Typen.
- _(Echtes „Wachstum über Zeit" braucht historische Snapshots — hier Proxy = Domänen-Spannweite jetzt.)_ - _(Echtes „Wachstum über Zeit" braucht historische Snapshots — hier Proxy = Domänen-Spannweite jetzt.)_
## 3. Isolated MCAPs — nur 1 Quelle/Journey (Review: spezialisiert ODER Konvergenz übersehen?) ## 3. Isolated MCAPs — nur 1 Quelle/Journey (Review: spezialisiert ODER Konvergenz übersehen?)
- 36 Stück, u. a.: `account_energy_consumption`, `cybersecurity_management_system`, `document_update_campaigns`, `document_waste_streams`, `issue_battery_passport`, `machine_safety_risk_assessment`, `measure_air_emissions`, `mechanical_safety_and_guards`. - 47 Stück, u. a.: `account_energy_consumption`, `assign_unique_device_identification`, `classify_software_safety_iec62304`, `compile_medical_technical_documentation`, `conduct_clinical_evaluation`, `cybersecurity_management_system`, `document_update_campaigns`, `document_waste_streams`.
## 4. Suspicious MCAPs — Abstraktionsgrad-Verdacht (Experten-Review) ## 4. Suspicious MCAPs — Abstraktionsgrad-Verdacht (Experten-Review)
- **Evtl. zu grob** (generisches Verb, breit aber nur 1 Typ): `document_and_change_control`, `manage_chemical_substances`. - **Evtl. zu grob** (generisches Verb, breit aber nur 1 Typ): `document_and_change_control`, `manage_chemical_substances`.
- **Evtl. zu fein** (isoliert + sehr spezifischer Name): `operating_instructions_and_safety_information`, `provide_dedicated_security_contact`, `provide_functional_safety_evidence`, `restrict_hazardous_substances_rohs`, `secure_by_default_no_default_credentials`, `threat_analysis_and_risk_assessment`. - **Evtl. zu fein** (isoliert + sehr spezifischer Name): `assign_unique_device_identification`, `compile_medical_technical_documentation`, `implement_software_lifecycle_iec62304`, `operating_instructions_and_safety_information`, `provide_dedicated_security_contact`, `provide_functional_safety_evidence`.
- Die Analyse sagt damit nicht nur WELCHE MCAPs wichtig sind, sondern auch, ob sie auf dem **richtigen Abstraktionsniveau** definiert sind. - Die Analyse sagt damit nicht nur WELCHE MCAPs wichtig sind, sondern auch, ob sie auf dem **richtigen Abstraktionsniveau** definiert sind.
## 5. Missing Convergence — mögliche strukturelle Doppelungen (Experten-Review, KEIN Auto-Merge)
> Nicht „welche MCAPs existieren?", sondern „welche hätte ich aufgrund der Daten ERWARTET, existieren aber als GETRENNTE MCAPs?". Deterministische Heuristik (kein ML): geteiltes Namens-Token über ≥3 MCAPs UND ≥2 verschiedene Quellen = Konvergenz-Kandidat (eine Einzelquelle-Zerlegung zählt NICHT). Nur anzeigen, nie automatisch zusammenführen.
- **Token `secure` → 3 MCAPs / 8 Quellen:** `secure_by_default_no_default_credentials`, `secure_development_lifecycle`, `secure_signed_update_distribution`_Review: eine Fähigkeit in mehreren Facetten?_
- **Token `update` → 4 MCAPs / 7 Quellen:** `document_update_campaigns`, `secure_signed_update_distribution`, `security_update_support_period`, `software_update_management_system`_Review: eine Fähigkeit in mehreren Facetten?_
- **Token `risk` → 6 MCAPs / 6 Quellen:** `machine_safety_risk_assessment`, `maintain_risk_management_file_iso14971`, `perform_benefit_risk_analysis`, `product_cyber_risk_assessment`, `run_risk_management_process`, `threat_analysis_and_risk_assessment`_Review: eine Fähigkeit in mehreren Facetten?_
- **Token `document` → 5 MCAPs / 6 Quellen:** `document_and_change_control`, `document_update_campaigns`, `document_waste_streams`, `manage_document_control`, `treat_and_document_wastewater`_Review: eine Fähigkeit in mehreren Facetten?_
- **Token `security` → 8 MCAPs / 4 Quellen:** `information_security_management`, `physical_security`, `provide_dedicated_security_contact`, `public_security_advisories`, `security_awareness_training`, `security_logging_and_monitoring`, `security_update_support_period`, `supplier_security`_Review: eine Fähigkeit in mehreren Facetten?_
- **Token `safety` → 6 MCAPs / 4 Quellen:** `classify_software_safety_iec62304`, `machine_safety_risk_assessment`, `mechanical_safety_and_guards`, `operating_instructions_and_safety_information`, `protection_against_corruption_of_safety_functions`, `provide_functional_safety_evidence`_Review: eine Fähigkeit in mehreren Facetten?_
→ Ergänzt `Suspicious`: dieser Report schaut nicht auf einzelne MCAPs, sondern auf **strukturelle Doppelungen** über Quellen hinweg — der häufigste systematische Modellierungsfehler.
## Befund ## Befund
> **Ein Kern beginnt sich zu zeigen:** 11 von 62 Capabilities erreichen Impact ≥ 8 (tragende Knoten), 14 verbinden ≥2 Domänen. Bislang ist das Wissensmodell noch jung (5 Patterns + 1 Automotive-Profil), aber die Methode steht: sobald Medical/Payment/weitere Domänen als DATEN hinzukommen, zeigt dieselbe Aggregation, ob sich der erwartete stabile Kern von 3050 hochkonvergenten MCAPs bildet — der gemeinsame Strukturkern hinter sehr unterschiedlichen Anforderungswelten. Das ist ein tieferer Wertnachweis als „eine weitere Norm unterstützt". Reine Aggregation, 0 Runtime, 0 neue Architektur. > **Ein Kern beginnt sich zu zeigen:** 11 von 75 Capabilities erreichen Impact ≥ 8 (tragende Knoten), 14 verbinden ≥2 Domänen. Mit Medical (6 Patterns inkl. ISO 13485 + Automotive) zeigt sich erstmals die **Safety/Security-Kopplung als Capability-REUSE**: IEC 81001-5-1 zieht dieselben Security-MCAPs wie die CRA herein → diese Knoten spannen jetzt Cyber + Maschinenbau + Automotive + Medizin. Die Methode steht; sobald Payment/weitere Domänen als DATEN kommen, zeigt dieselbe Aggregation (+ der neue Missing-Convergence-Report), ob sich der erwartete stabile Kern von 3050 hochkonvergenten MCAPs bildet — der gemeinsame Strukturkern hinter sehr unterschiedlichen Anforderungswelten. Tieferer Wertnachweis als „eine weitere Norm unterstützt". Reine Aggregation, 0 Runtime, 0 neue Architektur.
@@ -42,6 +42,8 @@ PATTERN_META = {
"transition_pattern_isms_to_tisax_v1.yaml": ("automotive", "certification", ["TISAX"]), "transition_pattern_isms_to_tisax_v1.yaml": ("automotive", "certification", ["TISAX"]),
"transition_pattern_iso14001_to_environmental_v1.yaml": ("environmental", "regulation", "transition_pattern_iso14001_to_environmental_v1.yaml": ("environmental", "regulation",
["REACH", "RoHS", "Batterieverordnung", "Wasserrecht", "Abwasservorschriften", "Energiemanagement", "Kreislaufwirtschaft", "Emissionsschutz"]), ["REACH", "RoHS", "Batterieverordnung", "Wasserrecht", "Abwasservorschriften", "Energiemanagement", "Kreislaufwirtschaft", "Emissionsschutz"]),
"transition_pattern_iso13485_to_medical_v1.yaml": ("medical", "regulation",
["MDR", "IEC_62304", "ISO_14971", "IEC_81001_5_1"]),
} }
# capability -> dict of sets we aggregate # capability -> dict of sets we aggregate
@@ -95,7 +97,7 @@ GENERIC = ("document_", "manage_", "control_", "conduct_", "operate_", "run_", "
w("# Cross-Domain MCAP Convergence Analysis — wo konvergiert das Wissensmodell?") w("# Cross-Domain MCAP Convergence Analysis — wo konvergiert das Wissensmodell?")
w("") w("")
w('_Nicht „welche MCAPs kommen am häufigsten vor?" (Häufigkeit täuscht), sondern „welche MCAPs TRAGEN den größten Teil des Systems?". Deterministischer **Impact-Score** (kein ML), internes Engineering-Werkzeug, reine Aggregation über vorhandene Daten (5 Transition Patterns + 7 Automotive-Quellen). Non-runtime, keine echten Namen._') w('_Nicht „welche MCAPs kommen am häufigsten vor?" (Häufigkeit täuscht), sondern „welche MCAPs TRAGEN den größten Teil des Systems?". Deterministischer **Impact-Score** (kein ML), internes Engineering-Werkzeug, reine Aggregation über vorhandene Daten (6 Transition Patterns inkl. Medical + 7 Automotive-Quellen). Non-runtime, keine echten Namen._')
w("") w("")
w("## Impact-Score (deterministisch)") w("## Impact-Score (deterministisch)")
w("> `Impact = distinct Sources + distinct Target-Types + distinct Domains + distinct Journeys + Regulatory Leverage + Business Leverage`") w("> `Impact = distinct Sources + distinct Target-Types + distinct Domains + distinct Journeys + Regulatory Leverage + Business Leverage`")
@@ -135,12 +137,42 @@ w("- **Evtl. zu fein** (isoliert + sehr spezifischer Name): %s." % (", ".join("`
w("- Die Analyse sagt damit nicht nur WELCHE MCAPs wichtig sind, sondern auch, ob sie auf dem **richtigen Abstraktionsniveau** definiert sind.") w("- Die Analyse sagt damit nicht nur WELCHE MCAPs wichtig sind, sondern auch, ob sie auf dem **richtigen Abstraktionsniveau** definiert sind.")
w("") w("")
# ── 5. Missing Convergence — potential structural duplications (token clusters) ──────────────
STOP = {"and", "of", "the", "for", "to", "a", "an", "no", "on", "in", "by", "with", "per"}
GENERIC_TOK = {"management", "process", "control", "distribution", "documentation", "technical",
"internal", "continual", "assessment", "evidence"}
tok2caps = {}
for cap in idx:
for t in cap.split("_"):
if len(t) >= 4 and t not in STOP and t not in GENERIC_TOK:
tok2caps.setdefault(t, set()).add(cap)
# cross-source signal only: a token shared by >=3 MCAPs that span >=2 distinct sources (one source's
# own decomposition is NOT a duplication candidate — that is intended granularity).
clusters = []
for t, cs in tok2caps.items():
if len(cs) >= 3:
srcs = set()
for c in cs:
srcs |= idx[c]["sources"]
if len(srcs) >= 2:
clusters.append((t, sorted(cs), len(srcs)))
clusters.sort(key=lambda x: (-x[2], -len(x[1]), x[0]))
w("## 5. Missing Convergence — mögliche strukturelle Doppelungen (Experten-Review, KEIN Auto-Merge)")
w('> Nicht „welche MCAPs existieren?", sondern „welche hätte ich aufgrund der Daten ERWARTET, existieren aber als GETRENNTE MCAPs?". Deterministische Heuristik (kein ML): geteiltes Namens-Token über ≥3 MCAPs UND ≥2 verschiedene Quellen = Konvergenz-Kandidat (eine Einzelquelle-Zerlegung zählt NICHT). Nur anzeigen, nie automatisch zusammenführen.')
w("")
for t, cs, ns in clusters[:6]:
w("- **Token `%s` → %d MCAPs / %d Quellen:** %s — _Review: eine Fähigkeit in mehreren Facetten?_" % (
t, len(cs), ns, ", ".join("`%s`" % c for c in cs)))
w("")
w("→ Ergänzt `Suspicious`: dieser Report schaut nicht auf einzelne MCAPs, sondern auf **strukturelle Doppelungen** über Quellen hinweg — der häufigste systematische Modellierungsfehler.")
w("")
# ── Befund ───────────────────────────────────────────────────────────────── # ── Befund ─────────────────────────────────────────────────────────────────
core_cut = [c for c, e in scored if impact(e) >= 8] core_cut = [c for c, e in scored if impact(e) >= 8]
cross = [c for c, e in scored if len(e["domains"]) >= 2] cross = [c for c, e in scored if len(e["domains"]) >= 2]
w("## Befund") w("## Befund")
w("") w("")
w('> **Ein Kern beginnt sich zu zeigen:** %d von %d Capabilities erreichen Impact ≥ 8 (tragende Knoten), %d verbinden ≥2 Domänen. Bislang ist das Wissensmodell noch jung (5 Patterns + 1 Automotive-Profil), aber die Methode steht: sobald Medical/Payment/weitere Domänen als DATEN hinzukommen, zeigt dieselbe Aggregation, ob sich der erwartete stabile Kern von 3050 hochkonvergenten MCAPs bildet — der gemeinsame Strukturkern hinter sehr unterschiedlichen Anforderungswelten. Das ist ein tieferer Wertnachweis als „eine weitere Norm unterstützt". Reine Aggregation, 0 Runtime, 0 neue Architektur.' % (len(core_cut), len(idx), len(cross))) w('> **Ein Kern beginnt sich zu zeigen:** %d von %d Capabilities erreichen Impact ≥ 8 (tragende Knoten), %d verbinden ≥2 Domänen. Mit Medical (6 Patterns inkl. ISO 13485 + Automotive) zeigt sich erstmals die **Safety/Security-Kopplung als Capability-REUSE**: IEC 81001-5-1 zieht dieselben Security-MCAPs wie die CRA herein → diese Knoten spannen jetzt Cyber + Maschinenbau + Automotive + Medizin. Die Methode steht; sobald Payment/weitere Domänen als DATEN kommen, zeigt dieselbe Aggregation (+ der neue Missing-Convergence-Report), ob sich der erwartete stabile Kern von 3050 hochkonvergenten MCAPs bildet — der gemeinsame Strukturkern hinter sehr unterschiedlichen Anforderungswelten. Tieferer Wertnachweis als „eine weitere Norm unterstützt". Reine Aggregation, 0 Runtime, 0 neue Architektur.' % (len(core_cut), len(idx), len(cross)))
w("") w("")
print("\n".join(OUT)) print("\n".join(OUT))
@@ -0,0 +1,26 @@
# Medical Stress Test — Safety + Security gekoppelt, der härtere Test (Phase Ω #3)
_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._
## 1. ISO 13485 als Profil → Delta über dieselbe Engine
- ISO 13485 liefert medizinische QMS-Disziplin (Welt-1): `manage_document_control`, `operate_capa_process`, `conduct_design_controls`, `run_risk_management_process`. …
- Delta (fehlt): **11** Capabilities — über dieselbe `assess_transition`, **0 neue Runtime-Klassen**.
## 2. Safety/Security-KOPPLUNG — Medical REUSED Cyber-MCAPs (IEC 81001-5-1 = CRA-Security)
- **Wiederverwendete Cyber-Capabilities (4):** `access_control_and_authentication`, `sbom_creation`, `secure_signed_update_distribution`, `technical_vulnerability_management`.
- → 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.
## 3. Genuin neue, medizin-spezifische Capabilities
- **Neu (7):** `assign_unique_device_identification`, `classify_software_safety_iec62304`, `compile_medical_technical_documentation`, `conduct_clinical_evaluation`, `implement_software_lifecycle_iec62304`, `maintain_risk_management_file_iso14971`, `perform_benefit_risk_analysis`.
- Capabilities als Verben: `conduct_clinical_evaluation`, `classify_software_safety_iec62304`, `maintain_risk_management_file_iso14971`, `perform_benefit_risk_analysis`.
## 4. Was ISO 13485 typischerweise NICHT erzeugt _(rejected_assumptions, Welt-1/Welt-2)_
- ISO 13485 does NOT produce clinical evidence or a clinical evaluation.
- ISO 13485 does NOT produce the ISO 14971 risk management FILE (only the process).
- ISO 13485 does NOT produce IEC 62304 software-lifecycle records or a software safety classification.
- ISO 13485 does NOT establish health-software security (IEC 81001-5-1 = the same security caps as the CRA).
## Befund
> **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: **4 Security-Capabilities werden aus dem Cyber-Bestand WIEDERVERWENDET** (IEC 81001-5-1 = CRA), während **7 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.
@@ -0,0 +1,83 @@
# 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))
@@ -38,23 +38,36 @@ def test_runs_end_to_end():
def test_core_is_cross_cutting_not_frequency(): def test_core_is_cross_cutting_not_frequency():
out = _run() out = _run()
core = _section(out, "## 1. Core MCAPs") core = _section(out, "## 1. Core MCAPs")
# the most cross-cutting capability tops the Core report # the most cross-cutting capability tops the Core report; with Medical it now spans 3 domains
assert "`secure_signed_update_distribution` | **18** |" in core assert "`secure_signed_update_distribution` | **24** |" in core
assert "technical_vulnerability_management" in core assert "technical_vulnerability_management" in core
# a high-frequency BUT single-domain management cap must NOT be in Core (frequency != impact) # a high-frequency BUT single-domain management cap must NOT be in Core (frequency != impact)
assert "conduct_internal_environmental_audits" not in core assert "conduct_internal_environmental_audits" not in core
def test_all_four_reports_present(): def test_all_five_reports_present():
out = _run() out = _run()
for header in ["## 1. Core MCAPs", "## 2. Emerging MCAPs", "## 3. Isolated MCAPs", "## 4. Suspicious MCAPs"]: for header in ["## 1. Core MCAPs", "## 2. Emerging MCAPs", "## 3. Isolated MCAPs",
"## 4. Suspicious MCAPs", "## 5. Missing Convergence"]:
assert header in out assert header in out
def test_missing_convergence_flags_cross_source_duplication():
out = _run()
mc = _section(out, "## 5. Missing Convergence")
# the 'risk' token clusters several distinct risk MCAPs across many sources -> a review candidate
assert "Token `risk`" in mc
assert "maintain_risk_management_file_iso14971" in mc and "product_cyber_risk_assessment" in mc
assert "KEIN Auto-Merge" in out
# single-source decompositions (all-environmental) must be filtered out (>=2 sources required)
assert "Token `environmental`" not in mc
def test_isolated_and_suspicious_are_review_tools(): def test_isolated_and_suspicious_are_review_tools():
out = _run() out = _run()
iso = _section(out, "## 3. Isolated MCAPs") iso = _section(out, "## 3. Isolated MCAPs")
assert "issue_battery_passport" in iso or "measure_air_emissions" in iso assert "Review: spezialisiert ODER Konvergenz übersehen" in iso
assert "conduct_clinical_evaluation" in iso or "cybersecurity_management_system" in iso
susp = _section(out, "## 4. Suspicious MCAPs") susp = _section(out, "## 4. Suspicious MCAPs")
assert "zu grob" in susp and "zu fein" in susp assert "zu grob" in susp and "zu fein" in susp
@@ -0,0 +1,58 @@
"""Medical stress test — safety + security coupled (Phase Ω #3).
Pins the harder joint test: ISO 13485 runs through the SAME engine (0 runtime, data only), and IEC
81001-5-1 (health-software security) pulls in the SAME security MCAPs as the CRA — so Medical REUSES
cyber capabilities (the safety/security coupling shows up as capability reuse) while adding genuinely
new medical-specific caps (clinical evaluation, software safety classification, ISO 14971 risk file).
"""
from __future__ import annotations
import os
import subprocess
import sys
def _run():
root = os.path.join(os.path.dirname(__file__), "..")
r = subprocess.run(
[sys.executable, "reference_scenarios/medical_stress_test.py"],
cwd=root, env={**os.environ, "PYTHONPATH": "."}, capture_output=True, text=True,
)
assert r.returncode == 0, r.stderr
return r.stdout
def test_runs_end_to_end_zero_runtime():
out = _run()
assert "Medical Stress Test" in out
assert "0 neue Runtime-Klassen" in out
def test_safety_security_coupling_reuses_cyber_caps():
out = _run()
assert "Wiederverwendete Cyber-Capabilities (4)" in out
for cap in ["secure_signed_update_distribution", "technical_vulnerability_management",
"access_control_and_authentication", "sbom_creation"]:
assert cap in out
assert "IEC 81001-5-1" in out
def test_genuinely_new_medical_capabilities():
out = _run()
assert "Neu (7)" in out
for cap in ["conduct_clinical_evaluation", "classify_software_safety_iec62304",
"maintain_risk_management_file_iso14971", "perform_benefit_risk_analysis"]:
assert cap in out
def test_rejected_assumptions_present():
out = _run()
assert "ISO 13485 does NOT produce clinical evidence" in out
assert "the same security caps as the CRA" in out
def test_no_real_company_names():
out = _run().lower()
for name in ["eto", "owis", "winterhalter", "medtronic", "siemens"]:
assert name not in out