Merge pull request 'Customer Mission #2 + IACE machine-safety playbooks + RS-004 linking' (#30) from feat/customer-mission-2-multicert into main
This commit is contained in:
+66
@@ -0,0 +1,66 @@
|
||||
# Implementation Playbook — curated KNOWLEDGE (the "wie komme ich dort hin?" layer), not runtime code.
|
||||
# Capability: ce_conformity_assessment_and_technical_documentation. Expert FIRST DRAFT (machinery-safety /
|
||||
# CE-conformity domain, IACE session). NOT a normative requirement. Renderer = compliance/playbook.
|
||||
|
||||
id: PB-ce_conformity_assessment_and_technical_documentation-v1
|
||||
capability_id: ce_conformity_assessment_and_technical_documentation
|
||||
status: draft # draft -> reviewed -> validated -> proven
|
||||
version: 1
|
||||
|
||||
title: "CE-Konformitätsbewertung und Technische Dokumentation für Maschinen"
|
||||
canonical_action: "Maschinenkonformität nachweisen" # Verb+Objekt (capability-is-a-verb-Experiment)
|
||||
|
||||
why: >
|
||||
Vor dem Inverkehrbringen muss der Hersteller die Konformität der Maschine nachweisen: das passende
|
||||
Konformitätsbewertungsverfahren durchführen (Maschinenverordnung Anhang XI), die Technische
|
||||
Dokumentation zusammenstellen (Anhang IV), die EU-Konformitätserklärung ausstellen (Anhang V) und die
|
||||
CE-Kennzeichnung anbringen. Dies ist der ABSCHLUSS-Schritt, der Risikobeurteilung, Schutzmaßnahmen und
|
||||
Betriebsanleitung zu einem konformen, marktfähigen Produkt bündelt. Für die in Anhang I gelisteten
|
||||
(Hochrisiko-)Maschinen kann die Einbindung einer notifizierten Stelle erforderlich sein. Bei vernetzten
|
||||
Maschinen greift dies mit der CRA-Konformität (Cyber) ineinander — eine integrierte technische Akte.
|
||||
|
||||
tools:
|
||||
- "Maschinenverordnung (EU) 2023/1230 Anhang IV (Inhalt der Technischen Dokumentation)"
|
||||
- "Anhang XI (Konformitätsbewertungsverfahren) + Anhang I (Liste der Hochrisiko-Maschinen)"
|
||||
- "Anhang V (EU-Konformitätserklärung)"
|
||||
- "Harmonisierte Normen (Fundstellen im Amtsblatt -> Vermutungswirkung)"
|
||||
- "NANDO-Datenbank (Auswahl einer notifizierten Stelle, falls erforderlich)"
|
||||
|
||||
process_steps:
|
||||
- title: "Maschine klassifizieren"
|
||||
detail: "Prüfen, ob die Maschine in Anhang I (Hochrisiko) fällt — das bestimmt, welche Verfahren nach Anhang XI zulässig sind."
|
||||
- title: "Konformitätsverfahren wählen"
|
||||
detail: "Nicht-Hochrisiko: interne Fertigungskontrolle (Anhang VIII). Hochrisiko/Anhang I: je nach Fall EU-Baumusterprüfung oder umfassende Qualitätssicherung unter Einbindung einer notifizierten Stelle."
|
||||
- title: "Harmonisierte Normen anwenden"
|
||||
detail: "Anwendbare harmonisierte Normen heranziehen und die Anwendung dokumentieren — das verschafft Vermutungswirkung für die abgedeckten Anforderungen."
|
||||
- title: "Technische Dokumentation zusammenstellen (Anhang IV)"
|
||||
detail: "Allgemeine Beschreibung, Konstruktions-/Fertigungsunterlagen, vollständige RISIKOBEURTEILUNG, Liste der angewandten Normen, Betriebsanleitung, Prüf-/Berechnungsberichte (z. B. PL-/SIL-Nachweis)."
|
||||
- title: "EU-Konformitätserklärung ausstellen (Anhang V)"
|
||||
detail: "Eindeutige Maschinenidentifikation, Verweis auf angewandte Rechtsakte (MaschinenVO; ggf. CRA, EMV, NSR) + Normen; rechtsverbindliche Unterschrift."
|
||||
- title: "CE-Kennzeichnung anbringen"
|
||||
detail: "Sichtbar/lesbar/dauerhaft an der Maschine; ggf. Kennnummer der notifizierten Stelle."
|
||||
- title: "Aufbewahren"
|
||||
detail: "Technische Dokumentation + Konformitätserklärung über die vorgeschriebene Frist (i. d. R. 10 Jahre) für die Marktüberwachung verfügbar halten."
|
||||
|
||||
expected_evidence:
|
||||
- "Vollständige Technische Dokumentation nach Anhang IV (inkl. Risikobeurteilung + Betriebsanleitung)"
|
||||
- "EU-Konformitätserklärung nach Anhang V (datiert, unterschrieben)"
|
||||
- "Nachweis der CE-Kennzeichnung an der Maschine"
|
||||
- "Falls erforderlich: EU-Baumusterprüfbescheinigung / Bescheinigung der notifizierten Stelle"
|
||||
|
||||
typical_controls: # INDIKATIV — echte Control-Zuordnung kommt aus der Execution-Schicht
|
||||
- "conformity_assessment_procedure"
|
||||
- "technical_file"
|
||||
- "ce_marking_declaration"
|
||||
|
||||
how_others_do_it: >
|
||||
Verbreitete Praxis: für nicht in Anhang I gelistete Maschinen interne Fertigungskontrolle plus
|
||||
konsequente Anwendung harmonisierter Normen (Vermutungswirkung); für Hochrisiko-Maschinen frühzeitige
|
||||
Einbindung einer notifizierten Stelle. Die Technische Dokumentation wird als lebendes Dokument geführt,
|
||||
das Risikobeurteilung, Betriebsanleitung und Prüfberichte bündelt; bei vernetzten Produkten wird die
|
||||
CRA-Cyber-Konformität in dieselbe technische Akte integriert (eine Erklärung, mehrere Rechtsakte).
|
||||
|
||||
disclaimer: >
|
||||
Kuratiertes Experten-Wissen (Erstentwurf, Maschinensicherheit / CE-Konformität), KEINE normative
|
||||
Anforderung. Werkzeug- und Schrittempfehlungen sind Beispiele bewährter Praxis, kein Pflichtkatalog.
|
||||
Review durch eine:n CE-/Maschinensicherheits-Expert:in ausstehend (status: draft).
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
# Implementation Playbook — curated KNOWLEDGE (the "wie komme ich dort hin?" layer), not runtime code.
|
||||
# Capability: machine_safety_risk_assessment. Expert FIRST DRAFT (machinery-safety domain, IACE session)
|
||||
# — a machine-safety engineer would validate this; it is NOT a normative requirement. The renderer
|
||||
# (compliance/playbook) assembles it into the journey.
|
||||
|
||||
id: PB-machine_safety_risk_assessment-v1
|
||||
capability_id: machine_safety_risk_assessment
|
||||
status: draft # draft -> reviewed -> validated -> proven
|
||||
version: 1
|
||||
|
||||
title: "Maschinen-Risikobeurteilung nach ISO 12100 durchführen"
|
||||
canonical_action: "Maschinenrisiken systematisch beurteilen" # Verb+Objekt (capability-is-a-verb-Experiment)
|
||||
|
||||
why: >
|
||||
Die Maschinenverordnung (EU) 2023/1230 verlangt vor dem Inverkehrbringen eine Risikobeurteilung über
|
||||
den GESAMTEN Lebenszyklus der Maschine (Transport, Montage, Inbetriebnahme, bestimmungsgemäßer Betrieb,
|
||||
Reinigung, Wartung, Störungsbeseitigung, Demontage, Entsorgung). Sie ist die Grundlage, aus der sich
|
||||
ALLE weiteren Schutzmaßnahmen und die Technische Dokumentation (Anhang IV) ableiten. ISO 12100 ist die
|
||||
harmonisierte Methodik und verschafft Vermutungswirkung. Ohne dokumentierte Risikobeurteilung ist die
|
||||
Auswahl von Schutzeinrichtungen, Not-Halt und Restrisiko-Hinweisen nicht begründbar.
|
||||
|
||||
tools:
|
||||
- "ISO 12100 (Risikobeurteilung + Risikominderung, Grundnorm)"
|
||||
- "ISO/TR 14121-2 (praktische Beispiele für die Methodik)"
|
||||
- "Gefährdungslisten ISO 12100 Anhang B (mechanisch, elektrisch, thermisch, Lärm, Vibration, Strahlung, Werkstoff, Ergonomie)"
|
||||
- "Sistema (DGUV, PLr-/PL-Ermittlung für Schutzfunktionen)"
|
||||
- "Risikograph-/Risikomatrix-Vorlagen (S x F x P bzw. S x E)"
|
||||
|
||||
process_steps:
|
||||
- title: "Grenzen der Maschine festlegen"
|
||||
detail: "Verwendungs-, räumliche, zeitliche und Lebenszyklusgrenzen; bestimmungsgemäße Verwendung UND vernünftigerweise vorhersehbare Fehlanwendung."
|
||||
- title: "Gefährdungen identifizieren"
|
||||
detail: "Systematisch je Lebensphase und je Bereich anhand der ISO-12100-Anhang-B-Liste — nichts überspringen (gerade Wartung/Reinigung wird oft vergessen)."
|
||||
- title: "Risiko einschätzen"
|
||||
detail: "Je Gefährdung Schadensschwere x Eintrittswahrscheinlichkeit (Häufigkeit/Aufenthaltsdauer, Möglichkeit zur Vermeidung) bestimmen."
|
||||
- title: "Risiko bewerten"
|
||||
detail: "Entscheiden, ob Risikominderung erforderlich ist (akzeptables Restrisiko erreicht?)."
|
||||
- title: "3-Stufen-Methode anwenden (in dieser Reihenfolge)"
|
||||
detail: "1. inhärent sichere Konstruktion -> 2. technische Schutzmaßnahmen/ergänzende Schutzeinrichtungen -> 3. Benutzerinformation. Maßnahmen NICHT in Stufe 3 verlagern, was in Stufe 1/2 lösbar ist."
|
||||
- title: "Iterieren"
|
||||
detail: "Nach jeder Maßnahme Risiko neu bewerten; prüfen, ob neue Gefährdungen entstanden sind (z. B. eine Schutzhaube erzeugt eine Quetschstelle)."
|
||||
- title: "Restrisiko dokumentieren"
|
||||
detail: "Verbleibende Restrisiken festhalten und an die Betriebsanleitung übergeben (Schnittstelle zu operating_instructions_and_safety_information)."
|
||||
|
||||
expected_evidence:
|
||||
- "Risikobeurteilungsbericht über alle Lebensphasen (datiert, versioniert)"
|
||||
- "Gefährdungsliste mit Risikoeinschätzung je Gefährdung"
|
||||
- "Zuordnung Gefährdung -> gewählte Maßnahme -> verbleibendes Restrisiko"
|
||||
- "Liste der Restrisiken (Eingang in die Betriebsanleitung)"
|
||||
|
||||
typical_controls: # INDIKATIV — echte Control-Zuordnung kommt aus der Execution-Schicht
|
||||
- "machine_risk_assessment_record"
|
||||
- "three_step_risk_reduction"
|
||||
|
||||
how_others_do_it: >
|
||||
Verbreitete Praxis: Risikobeurteilung strikt nach ISO 12100 strukturieren, mit ISO/TR 14121-2 als
|
||||
Beispiel-Steinbruch, und die ermittelten Schutzfunktionen über Sistema auf den erforderlichen
|
||||
Performance Level (PLr) rechnen. Der Bericht wird unmittelbar Teil der Technischen Dokumentation
|
||||
(Anhang IV) und wird bei jeder wesentlichen Veränderung der Maschine erneut gefahren.
|
||||
|
||||
disclaimer: >
|
||||
Kuratiertes Experten-Wissen (Erstentwurf, Maschinensicherheit), KEINE normative Anforderung. Werkzeug-
|
||||
und Schrittempfehlungen sind Beispiele bewährter Praxis, kein Pflichtkatalog. Review durch eine:n
|
||||
Maschinensicherheits-Expert:in ausstehend (status: draft).
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
# Implementation Playbook — curated KNOWLEDGE (the "wie komme ich dort hin?" layer), not runtime code.
|
||||
# Capability: mechanical_safety_and_guards. Expert FIRST DRAFT (machinery-safety domain, IACE session).
|
||||
# NOT a normative requirement. Renderer = compliance/playbook.
|
||||
|
||||
id: PB-mechanical_safety_and_guards-v1
|
||||
capability_id: mechanical_safety_and_guards
|
||||
status: draft # draft -> reviewed -> validated -> proven
|
||||
version: 1
|
||||
|
||||
title: "Schutzeinrichtungen, Not-Halt und sichere Steuerung auslegen"
|
||||
canonical_action: "Gefahrstellen wirksam absichern" # Verb+Objekt (capability-is-a-verb-Experiment)
|
||||
|
||||
why: >
|
||||
Die grundlegenden Sicherheits- und Gesundheitsschutzanforderungen der Maschinenverordnung (Anhang III)
|
||||
verlangen Schutz vor mechanischen Gefährdungen (Quetschen, Scheren, Schneiden, Einziehen, Stoß),
|
||||
funktionssichere Not-Halt-Einrichtungen, Schutz gegen unerwarteten Anlauf und Standsicherheit. Aus der
|
||||
Risikobeurteilung (machine_safety_risk_assessment) ergibt sich, WO und mit WELCHER Zuverlässigkeit
|
||||
(Performance Level / SIL) abgesichert werden muss. Trennende und nichttrennende Schutzeinrichtungen
|
||||
setzen die zweite Stufe der 3-Stufen-Methode um.
|
||||
|
||||
tools:
|
||||
- "ISO 14120 (trennende Schutzeinrichtungen — Gestaltung)"
|
||||
- "ISO 14119 (Verriegelungseinrichtungen mit/ohne Zuhaltung)"
|
||||
- "ISO 13850 (Not-Halt-Funktion, Stopp-Kategorie 0/1)"
|
||||
- "ISO 13857 (Sicherheitsabstände gegen Erreichen von Gefahrstellen)"
|
||||
- "ISO 13849-1/-2 (sicherheitsbezogene Steuerungsteile, PL + Validierung)"
|
||||
- "IEC 62061 (funktionale Sicherheit von Steuerungen, SIL)"
|
||||
- "ISO 14118 (Vermeidung von unerwartetem Anlauf / LOTO)"
|
||||
|
||||
process_steps:
|
||||
- title: "Gefahrstellen übernehmen"
|
||||
detail: "Aus der Risikobeurteilung die mechanischen Gefahrstellen + erforderlichen PLr/SIL je Schutzfunktion übernehmen."
|
||||
- title: "Schutzeinrichtung wählen"
|
||||
detail: "Feststehend trennend, wo im Betrieb kein Zugang nötig ist; beweglich trennend, wo regelmäßiger Zugang erforderlich ist; ergänzend nichttrennend (z. B. Lichtgitter), wo Materialfluss offen bleibt."
|
||||
- title: "Bewegliche Schutzeinrichtungen verriegeln"
|
||||
detail: "Nach ISO 14119 Verriegelung (mit Zuhaltung, wenn Nachlauf gefährlich ist); manipulationsarme Auslegung beachten."
|
||||
- title: "Sicherheitsabstände einhalten"
|
||||
detail: "Nach ISO 13857 Reichweiten nach oben/über/um Schutzeinrichtungen sicherstellen."
|
||||
- title: "Not-Halt vorsehen"
|
||||
detail: "ISO 13850: gut erreichbare Not-Halt-Befehlsgeräte, Stopp-Kategorie 0 oder 1, Rückstellung nur bewusst; Not-Halt ist ERGÄNZEND, ersetzt keine trennende Schutzeinrichtung."
|
||||
- title: "Sichere Steuerung auslegen"
|
||||
detail: "Sicherheitsbezogene Steuerungsteile auf den erforderlichen PL (ISO 13849-1) bzw. SIL (IEC 62061) bringen; Architektur, MTTFd, DC, CCF nachweisen (Sistema)."
|
||||
- title: "Unerwarteten Anlauf verhindern"
|
||||
detail: "ISO 14118 / sichere Energietrennung (LOTO) für Wartung und Störungsbeseitigung (Schnittstelle zur Wartungs-Lebensphase)."
|
||||
- title: "Validieren"
|
||||
detail: "Schutzfunktionen nach ISO 13849-2 verifizieren/validieren (Funktionstest + Nachweis)."
|
||||
|
||||
expected_evidence:
|
||||
- "Schutzkonzept (welche Gefahrstelle -> welche Schutzeinrichtung)"
|
||||
- "PL-/SIL-Nachweis je Schutzfunktion (z. B. Sistema-Report)"
|
||||
- "Funktionstest-Protokoll Not-Halt + Verriegelungen"
|
||||
- "Validierungsbericht der Schutzeinrichtungen (ISO 13849-2)"
|
||||
|
||||
typical_controls: # INDIKATIV — echte Control-Zuordnung kommt aus der Execution-Schicht
|
||||
- "guard_design"
|
||||
- "interlock_function"
|
||||
- "emergency_stop_function"
|
||||
- "safe_control_system"
|
||||
|
||||
how_others_do_it: >
|
||||
Verbreitete Praxis: feststehende Verkleidungen überall dort, wo kein betrieblicher Zugang nötig ist;
|
||||
verriegelte bewegliche Schutztüren mit Zuhaltung an Stellen mit Nachlauf; der erforderliche Performance
|
||||
Level wird per Risikograph bestimmt und mit Sistema nachgewiesen. Not-Halt wird als ergänzende, nicht
|
||||
als primäre Maßnahme eingeplant. Validierung erfolgt dokumentiert vor der Konformitätserklärung.
|
||||
|
||||
disclaimer: >
|
||||
Kuratiertes Experten-Wissen (Erstentwurf, Maschinensicherheit), KEINE normative Anforderung.
|
||||
Werkzeug- und Schrittempfehlungen sind Beispiele bewährter Praxis, kein Pflichtkatalog. Review durch
|
||||
eine:n Maschinensicherheits-Expert:in ausstehend (status: draft).
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
# Implementation Playbook — curated KNOWLEDGE (the "wie komme ich dort hin?" layer), not runtime code.
|
||||
# Capability: operating_instructions_and_safety_information. Expert FIRST DRAFT (machinery-safety domain,
|
||||
# IACE session). NOT a normative requirement. Renderer = compliance/playbook.
|
||||
|
||||
id: PB-operating_instructions_and_safety_information-v1
|
||||
capability_id: operating_instructions_and_safety_information
|
||||
status: draft # draft -> reviewed -> validated -> proven
|
||||
version: 1
|
||||
|
||||
title: "Betriebsanleitung und Sicherheitsinformationen erstellen"
|
||||
canonical_action: "Sicherheitsinformationen bereitstellen" # Verb+Objekt (capability-is-a-verb-Experiment)
|
||||
|
||||
why: >
|
||||
Information für die Benutzung ist die DRITTE Stufe der 3-Stufen-Methode (ISO 12100 6.4): Sie trägt das
|
||||
Restrisiko, das durch Konstruktion und technische Schutzmaßnahmen nicht beseitigt werden konnte. Die
|
||||
Maschinenverordnung (Anhang III 1.7) verlangt eine Betriebsanleitung in der/den Sprache(n) des
|
||||
Verwenderlandes; die Verordnung erlaubt nun unter Bedingungen auch die digitale Bereitstellung. Eine
|
||||
vollständige, verständliche Anleitung ist Voraussetzung für die Konformität — fehlende oder
|
||||
unverständliche Sicherheitsinformationen sind ein häufiger Mangel bei der Marktüberwachung.
|
||||
|
||||
tools:
|
||||
- "ISO 12100 6.4 (Information für die Benutzung)"
|
||||
- "ISO 20607 (Betriebsanleitung — allgemeine Gestaltungsgrundsätze für Maschinensicherheit)"
|
||||
- "IEC/IEEE 82079-1 (Erstellung von Nutzungsinformationen)"
|
||||
- "ANSI Z535.6 / ISO 3864 (Sicherheits- und Warnhinweise, Signalwörter)"
|
||||
- "Structured-Authoring-Werkzeuge (z. B. DITA) für Mehrsprachigkeit/Versionierung"
|
||||
|
||||
process_steps:
|
||||
- title: "Restrisiken übernehmen"
|
||||
detail: "Die Restrisikoliste aus der Risikobeurteilung (machine_safety_risk_assessment) ist der verbindliche Eingang — jedes Restrisiko braucht eine Information/Warnung."
|
||||
- title: "Zielgruppen und Lebensphasen abdecken"
|
||||
detail: "Transport, Montage, Inbetriebnahme, Bedienung, Reinigung, Wartung, Störungsbeseitigung, Demontage/Entsorgung — je mit benötigter Qualifikation."
|
||||
- title: "Warnhinweise strukturieren"
|
||||
detail: "Einheitlich Signalwort (Gefahr/Warnung/Vorsicht) + Art der Gefahr + Folge + Vermeidung (ANSI Z535/ISO 3864)."
|
||||
- title: "Verwendung abgrenzen"
|
||||
detail: "Bestimmungsgemäße Verwendung UND vernünftigerweise vorhersehbare Fehlanwendung beschreiben."
|
||||
- title: "Sprache sicherstellen"
|
||||
detail: "In der/den Amtssprache(n) des Verwenderlandes; Übersetzungen als Übersetzung kennzeichnen."
|
||||
- title: "Format und Bereitstellung festlegen"
|
||||
detail: "Papier oder — nach den Bedingungen der Maschinenverordnung — digital; Sicherheitsinformationen müssen auffindbar und über die Lebensdauer verfügbar bleiben; auf Verlangen Papierfassung."
|
||||
- title: "Versionieren"
|
||||
detail: "Anleitung an Maschinenversion koppeln; bei wesentlicher Veränderung aktualisieren."
|
||||
|
||||
expected_evidence:
|
||||
- "Betriebsanleitung je Maschine und Sprache (datiert, versioniert)"
|
||||
- "Warnhinweis-Konzept (Signalwörter, Piktogramme)"
|
||||
- "Matrix Restrisiko -> zugehörige Information/Warnung (Rückverfolgbarkeit zur Risikobeurteilung)"
|
||||
- "Nachweis der Bereitstellungsform (digital + Papier-auf-Verlangen)"
|
||||
|
||||
typical_controls: # INDIKATIV — echte Control-Zuordnung kommt aus der Execution-Schicht
|
||||
- "safety_information_provision"
|
||||
- "residual_risk_communication"
|
||||
|
||||
how_others_do_it: >
|
||||
Verbreitete Praxis: strukturierte Redaktion nach IEC/IEEE 82079-1 und ISO 20607, Warnhinweise nach
|
||||
ANSI Z535/ISO 3864, und eine durchgängige Verknüpfung jedes Restrisikos aus der Risikobeurteilung mit
|
||||
einer konkreten Information. Digitale Anleitungen werden über stabile URLs/QR bereitgestellt, mit
|
||||
Papierfassung auf Verlangen, und mit der ausgelieferten Maschinenversion verknüpft.
|
||||
|
||||
disclaimer: >
|
||||
Kuratiertes Experten-Wissen (Erstentwurf, Maschinensicherheit), KEINE normative Anforderung.
|
||||
Werkzeug- und Schrittempfehlungen sind Beispiele bewährter Praxis, kein Pflichtkatalog. Review durch
|
||||
eine:n Technische-Redaktion-/Maschinensicherheits-Expert:in ausstehend (status: draft).
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
# Implementation Playbook — curated KNOWLEDGE (the "wie komme ich dort hin?" layer), not runtime code.
|
||||
# Capability: protection_against_corruption_of_safety_functions. Expert FIRST DRAFT (machinery-safety +
|
||||
# cyber-safety bridge, IACE session). NOT a normative requirement. Renderer = compliance/playbook.
|
||||
#
|
||||
# CONVERGENCE NOTE: this capability is the CRA <-> MaschinenVO bridge. The same integrity + access
|
||||
# controls that satisfy the CRA (software integrity, signed updates, access control) also satisfy
|
||||
# Machinery Regulation Annex III 1.1.9. The renderer supplies closes_regulations/leverage from
|
||||
# covers_targets — one playbook, two regulations.
|
||||
|
||||
id: PB-protection_against_corruption_of_safety_functions-v1
|
||||
capability_id: protection_against_corruption_of_safety_functions
|
||||
status: draft # draft -> reviewed -> validated -> proven
|
||||
version: 1
|
||||
|
||||
title: "Sicherheitsfunktionen gegen (Software-)Korruption und Manipulation schützen"
|
||||
canonical_action: "Sicherheitsfunktionen gegen Manipulation schützen" # Verb+Objekt (capability-is-a-verb)
|
||||
|
||||
why: >
|
||||
Maschinenverordnung Anhang III 1.1.9 verlangt, dass Hard- und Software sowie Daten, die für die
|
||||
Sicherheit kritisch sind, gegen ZUFÄLLIGE und BEABSICHTIGTE Korruption geschützt werden. Eine
|
||||
manipulierte oder fehlerhaft veränderte Sicherheitsfunktion (z. B. überbrückte Verriegelung,
|
||||
verstellter Sicherheitsparameter, untergeschobenes Steuerungs-Update) wird unmittelbar zu einer
|
||||
physischen Sicherheitsgefährdung. Genau hier treffen sich Maschinensicherheit und Cybersecurity:
|
||||
dieselben Integritäts- und Zugriffsmaßnahmen, die der Cyber Resilience Act fordert, erfüllen auch
|
||||
diese Maschinenpflicht (Konvergenz / Cyber-Safety-Brücke).
|
||||
|
||||
tools:
|
||||
- "IEC 62443 (industrielle Kommunikationsnetze / IACS-Security)"
|
||||
- "IEC 61508 / ISO 13849 / IEC 62061 (funktionale Sicherheit der Steuerung)"
|
||||
- "Code- und Update-Signierung (Secure Boot, signierte Firmware)"
|
||||
- "Hardware-Vertrauensanker (TPM/Secure Element) für Integritätsprüfung"
|
||||
- "Rollen-/Zugriffskonzept für sicherheitsrelevante Parameter (keine Default-Passwörter)"
|
||||
|
||||
process_steps:
|
||||
- title: "Sicherheitskritische Elemente identifizieren"
|
||||
detail: "Welche Soft-/Hardware und welche Parameter/Daten tragen eine Sicherheitsfunktion? (Eingang aus der Risikobeurteilung + sicherer Steuerung.)"
|
||||
- title: "Integrität schützen"
|
||||
detail: "Signierte Firmware/Updates, Prüfsummen, sichere Bootkette; Veränderung sicherheitsrelevanten Codes nur mit verifizierter Signatur."
|
||||
- title: "Zugriff kontrollieren"
|
||||
detail: "Authentisierung für das Verstellen von Sicherheitsparametern; Rollentrennung; keine ab Werk gesetzten Standardpasswörter (secure-by-default)."
|
||||
- title: "Safety und Standardsteuerung trennen"
|
||||
detail: "Sicherheitsbezogene Steuerungsteile von der allgemeinen Steuerung entkoppeln, damit eine Kompromittierung der Standardseite die Safety-Funktion nicht aushebelt."
|
||||
- title: "Manipulation erkennen -> sicherer Zustand"
|
||||
detail: "Bei erkannter Integritätsverletzung definiert in den sicheren Zustand übergehen (fail-safe), nicht still weiterlaufen."
|
||||
- title: "Updates sicher verteilen"
|
||||
detail: "Sicherheitsrelevante Updates nur signiert und verifiziert einspielen (Schnittstelle zu sicheren Update-Capabilities des CRA)."
|
||||
- title: "Sicherheitsrelevante Eingriffe protokollieren"
|
||||
detail: "Änderungen an Sicherheitsparametern/-software nachvollziehbar loggen (Audit-Trail)."
|
||||
|
||||
expected_evidence:
|
||||
- "Konzept Integritätsschutz sicherheitskritischer Soft-/Hardware"
|
||||
- "Nachweis Code-/Update-Signierung (Schlüsselverwaltung, Verifikation)"
|
||||
- "Zugriffskontroll-/Rollenkonzept für Sicherheitsparameter"
|
||||
- "Testprotokoll: Manipulationsversuch -> definierter sicherer Zustand"
|
||||
|
||||
typical_controls: # INDIKATIV — echte Control-Zuordnung kommt aus der Execution-Schicht
|
||||
- "safety_function_integrity"
|
||||
- "secure_update_distribution"
|
||||
- "access_control_safety_parameters"
|
||||
|
||||
how_others_do_it: >
|
||||
Verbreitete Praxis: die CRA-Maßnahmen (signierte Updates, Secure Boot, Integritätsprüfung,
|
||||
Zugriffskontrolle ohne Default-Passwörter) werden EINMAL umgesetzt und decken zugleich
|
||||
Maschinenverordnung Anhang III 1.1.9 ab — eine Maßnahme, zwei Regelwerke. Die Sicherheitssteuerung
|
||||
wird nach IEC 62443 segmentiert, und bei Integritätsverletzung geht die Maschine kontrolliert in den
|
||||
sicheren Zustand statt weiterzulaufen.
|
||||
|
||||
disclaimer: >
|
||||
Kuratiertes Experten-Wissen (Erstentwurf, Maschinensicherheit + Cyber-Safety), KEINE normative
|
||||
Anforderung. Werkzeug- und Schrittempfehlungen sind Beispiele bewährter Praxis, kein Pflichtkatalog.
|
||||
Review durch Product-Security- + Funktionale-Sicherheit-Expert:innen ausstehend (status: draft).
|
||||
@@ -26,7 +26,7 @@ _KEINE Demo, KEIN Reference Scenario — eine vollständige Simulation eines Ber
|
||||
- **Top-Maßnahmen:** `ce_conformity_assessment_and_technical_documentation`(2), `product_cyber_risk_assessment`(2), `protection_against_corruption_of_safety_functions`(2), `secure_signed_update_distribution`(2), `coordinated_vulnerability_disclosure`(1)
|
||||
|
||||
## 5. Playbooks — wie umsetzen? _(Berater-Renderer)_
|
||||
- 2 von 12 Maßnahmen haben ein Playbook; 10 brauchen Inhalt (Maschinensicherheits-Playbooks @IACE delegiert).
|
||||
- 7 von 12 Maßnahmen haben ein Playbook; 5 brauchen Inhalt (Maschinensicherheits-Playbooks @IACE delegiert).
|
||||
|
||||
## 6. Nachweise — was belegen? _(expected_evidence)_
|
||||
- Geforderte Nachweise (Auszug): advisory_process, config_export, cvd_policy, declaration_of_conformity, machine_risk_assessment, operating_instructions …
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
# Customer Mission #2 — „Wir haben SCHON viel. Was fehlt UNS noch für die CRA?"
|
||||
|
||||
_Zweite Mission, bewusst ANDERS als #1: nicht „ein Zertifikat → ein Ziel", sondern ein hoch-zertifiziertes Unternehmen, das mit einem ganzen Profil ankommt. Test der einzigen offenen Naht aus Mission #1 (Scope → Journey). Synthetischer Kunde, keine echten Namen._
|
||||
|
||||
## Der Kunde (synthetisch, hoch-zertifiziert)
|
||||
> **ISO 9001** · **ISO 27001** · **ISO 14001** · **TISAX** · **CE-Prozess** · **PSIRT** · vernetzte Maschinen · Export EU
|
||||
> **Eine Frage:** „Wir sind schon in vielem zertifiziert — was genau fehlt UNS noch, um CRA-konform zu sein?"
|
||||
|
||||
## 0. Company Capability Profile — der eigentliche Startzustand
|
||||
> Das Unternehmen bringt **kein Zertifikat als Startpunkt**, sondern ein **Profil**. Jedes Zertifikat ist eine *Beobachtung*, die wahrscheinliche Fähigkeiten beisteuert; der Startzustand ist ihre **Aggregation**.
|
||||
|
||||
| Zertifikat (Beobachtung) | steuert Fähigkeiten bei | Vertrauen |
|
||||
|---|---|---|
|
||||
| **ISO27001** — Informationssicherheit (ISMS) | `incident_management`, `technical_vulnerability_management`, `access_control_and_authentication`, `secure_development_lifecycle`, `security_logging_and_monitoring` | medium |
|
||||
| **TISAX** — Automotive-ISMS — verstärkt dieselben Infosec-Fähigkeiten | `incident_management`, `technical_vulnerability_management`, `access_control_and_authentication`, `secure_development_lifecycle`, `security_logging_and_monitoring` | medium |
|
||||
| **PSIRT** — Product-Security-Incident-Response — deckt ZWEI CRA-Delta-Fähigkeiten | `coordinated_vulnerability_disclosure`, `exploited_vuln_and_incident_reporting` | high |
|
||||
| **ISO9001** — QM-Dokumentendisziplin → CE-/Technische-Doku-Fähigkeit | `ce_conformity_assessment_and_technical_documentation` | medium |
|
||||
| **ISO14001** — Umweltmanagement — im Profil, aber für die CRA NICHT relevant | `environmental_management_documentation` | medium |
|
||||
|
||||
→ **Evidence ist zielrelativ:** ISO 14001 liegt im Profil, hilft der CRA aber **nicht**; PSIRT (oft übersehen) deckt **zwei** CRA-kritische Delta-Fähigkeiten. Genau deshalb darf man **nicht ein Zertifikat** zur Journey machen — das ganze Profil zählt.
|
||||
|
||||
## 1. Ziel _(Intent)_ — was wollen Sie erreichen?
|
||||
- Intent: **„CRA-konform werden"** → Ziel-Profil = **CRA** (die von der CRA geforderten Fähigkeiten).
|
||||
- Auswahl-Eingabe ist damit **(Company Profile, Ziel)** — **kein** Zertifikat, das auf eine Journey gemappt wird.
|
||||
|
||||
## 2. Capability Delta — Profil → CRA _(das IST die „Journey")_
|
||||
> 17 zu klären, 0 bereits abgedeckt, 8 vermutlich vorhanden, 9 fehlt, 0 n/a, 0 nicht im Korpus.
|
||||
- **Delta dieses Profils:** 9 fehlende Fähigkeiten.
|
||||
- **Gegenprobe (nur ISO 27001):** 12 fehlende Fähigkeiten.
|
||||
- **Mehr Evidence → kleineres Delta:** die zusätzliche Zertifizierung schließt **3** Fähigkeiten *vorab*: `ce_conformity_assessment_and_technical_documentation`, `coordinated_vulnerability_disclosure`, `exploited_vuln_and_incident_reporting`.
|
||||
|
||||
→ Es wurde **keine Journey ausgewählt**. Das Delta `(Profil, Ziel)` IST die Journey — berechnet, nicht gewählt. Die Journey ist nur die *Erklärung* dieses Deltas.
|
||||
|
||||
## 3. Roadmap — was zuerst? _(gleicher Hebel-Engine wie Mission #1)_
|
||||
> 12 identifizierte Anforderungen aus 2 Regelwerken -> 9 Massnahmen (Ø Hebel 1.3).
|
||||
- Top-5 nach Hebel schließen **8 von 12** offenen Anforderungen (67%).
|
||||
|
||||
## Selektions-Rationale — die 5 Fragen (pro Mission zu dokumentieren)
|
||||
|
||||
**Welche Journey wurde gewählt?**
|
||||
**Keine per-Zertifikat-Journey.** Die Journey ist `Company Capability Profile → CRA`. Gewählt wurde nur das **Ziel** (CRA); der Startzustand wurde aus ALLEN Zertifikaten aggregiert.
|
||||
|
||||
**Warum?**
|
||||
Bei 6 Zertifikaten würde „ISO 27001 → CRA" die Evidence aus PSIRT/ISO 9001 wegwerfen (= 3 Fähigkeiten, die sonst fälschlich als Delta erschienen). Nur das **ganze Profil** ergibt das korrekte Delta.
|
||||
|
||||
**Welche Informationen waren für die Auswahl entscheidend?**
|
||||
(a) das **Ziel/Intent** (CRA) und (b) die **vollständige Zertifikatsliste** als Profil — **nicht** ein einzelnes Zertifikat. Welche Evidence hilft, ist **zielrelativ** (ISO 14001 irrelevant, PSIRT hoch-relevant).
|
||||
|
||||
**Musste das Journey-Modell erweitert werden?**
|
||||
**Konzeptionell ja, strukturell nein.** `from → to` bleibt; aber `from` ist ein **Company Capability Profile** (Multi-Cert-Aggregat), kein Zertifikat. Die Engines (`build_company_profile` + `assess_transition`) tun das BEREITS — es war ein Benenn-/Framing-Fehler, kein fehlender Code.
|
||||
|
||||
**Musste ein neuer Selektionsparameter eingeführt werden?**
|
||||
**Ja — und er VEREINFACHT.** Eingabe ist `(Company Profile, Ziel)`, nicht `(Zertifikat, Ziel)`. Die Zertifikate kollabieren ins Profil → **keine 2^N Cert-Kombinationen**, nur Profil→Ziel. Der Selektor wird damit kleiner, nicht größer.
|
||||
|
||||
## Was Mission #2 an Mission #1 verändert
|
||||
|
||||
- Mission #1 nannte **Scope → Journey** einen Sprung („kein Selektor `certs × targets → journeys`"). Mission #2 zeigt: **diese Naht schrumpft.** Es gibt keinen Journey-Matcher zu bauen — die Journey ist das **berechnete Delta** `(Profil, Ziel)`. Was real fehlt, ist nur **Profil-Intake + Ziel-Wahl**, nicht eine Journey-Auswahl-Engine.
|
||||
- Bestätigt den Reframe: **Es gibt keine „ISO 27001 → CRA"-Transition — nur „Company Capability Profile → CRA".** Zertifikate sind **Beobachtungen/Evidence**, kein Journey-Startpunkt.
|
||||
- **Beobachtung für den (noch nicht gebauten) Selektor:** Eingabe = `(Company Profile, Ziel)`. Diversität über weitere Missionen muss zeigen, ob auch **Produktprofil** und **Intent-Klasse** als Parameter nötig werden — erst dann kanonisieren ([[rule-of-three-canonicalization]]).
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
# ruff: noqa
|
||||
# mypy: ignore-errors
|
||||
"""Customer Mission #2 — the company arrives with a PROFILE, not a journey.
|
||||
|
||||
Mission #1 (Maschinenbauer) ended on one open seam: „Scope → Journey" — a consultant had to hand-pick
|
||||
„ISO 27001 → CRA". This mission deliberately STRESSES that seam with a multi-certified company (the
|
||||
ETO-archetype: many certs at once) and asks the reframe question: is the start a *certification* you map
|
||||
to a journey, or a *Company Capability Profile* you compute a delta from?
|
||||
|
||||
Finding (proven below with the real engines): there is NO per-certificate journey. The start is the whole
|
||||
profile; certifications are OBSERVATIONS that feed it; more evidence = smaller delta (12 → 9). The
|
||||
„journey" is not selected — it is the delta `(Company Profile, Target)`. That shrinks Mission #1's jump:
|
||||
the seam is not a journey-matcher, it is profile-intake + target-pick.
|
||||
|
||||
Synthetic multi-certified company (NO real names). Runs the REAL engines end-to-end.
|
||||
Run: cd backend-compliance && PYTHONPATH=. python3 reference_scenarios/mission_multicert_cra.py
|
||||
Not product code; not imported by the app. Non-runtime -> no deploy.
|
||||
"""
|
||||
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,
|
||||
)
|
||||
from compliance.optimization import roadmap_from_delta, select_within_budget
|
||||
|
||||
OUT = []
|
||||
RAT = [] # (question, answer) — the per-mission selection rationale the user asked to record
|
||||
|
||||
|
||||
def w(s=""):
|
||||
OUT.append(s)
|
||||
|
||||
|
||||
def rationale(question, answer):
|
||||
RAT.append((question, answer))
|
||||
|
||||
|
||||
_HERE = os.path.dirname(__file__)
|
||||
_K = os.path.join(_HERE, "..", "knowledge")
|
||||
CP = yaml.safe_load(open(os.path.join(_K, "transition_patterns",
|
||||
"transition_pattern_iso27001_to_cra_maschinenvo_v1.yaml"), encoding="utf-8"))
|
||||
|
||||
w('# Customer Mission #2 — „Wir haben SCHON viel. Was fehlt UNS noch für die CRA?"')
|
||||
w("")
|
||||
w('_Zweite Mission, bewusst ANDERS als #1: nicht „ein Zertifikat → ein Ziel", sondern ein hoch-zertifiziertes Unternehmen, das mit einem ganzen Profil ankommt. Test der einzigen offenen Naht aus Mission #1 (Scope → Journey). Synthetischer Kunde, keine echten Namen._')
|
||||
w("")
|
||||
w("## Der Kunde (synthetisch, hoch-zertifiziert)")
|
||||
w("> **ISO 9001** · **ISO 27001** · **ISO 14001** · **TISAX** · **CE-Prozess** · **PSIRT** · vernetzte Maschinen · Export EU")
|
||||
w('> **Eine Frage:** „Wir sind schon in vielem zertifiziert — was genau fehlt UNS noch, um CRA-konform zu sein?"')
|
||||
w("")
|
||||
|
||||
# ── 0. Company Capability Profile — DER Startzustand (nicht ein Zertifikat) ──
|
||||
# Each certification is an OBSERVATION yielding probable capabilities. The profile is their AGGREGATE.
|
||||
# Evidence is TARGET-RELATIVE: ISO 14001 is in the profile but irrelevant to the CRA (honest).
|
||||
infosec = [a["capability"] for a in CP["likely_covered"]]
|
||||
CERT_OBS = {
|
||||
"ISO27001": (infosec, Confidence.MEDIUM, "Informationssicherheit (ISMS)"),
|
||||
"TISAX": (infosec, Confidence.MEDIUM, "Automotive-ISMS — verstärkt dieselben Infosec-Fähigkeiten"),
|
||||
"PSIRT": (["coordinated_vulnerability_disclosure", "exploited_vuln_and_incident_reporting"],
|
||||
Confidence.HIGH, "Product-Security-Incident-Response — deckt ZWEI CRA-Delta-Fähigkeiten"),
|
||||
"ISO9001": (["ce_conformity_assessment_and_technical_documentation"],
|
||||
Confidence.MEDIUM, "QM-Dokumentendisziplin → CE-/Technische-Doku-Fähigkeit"),
|
||||
"ISO14001": (["environmental_management_documentation"],
|
||||
Confidence.MEDIUM, "Umweltmanagement — im Profil, aber für die CRA NICHT relevant"),
|
||||
}
|
||||
cmap = {k: CapabilityMappingEntry(capability_ids=v[0], confidence=v[1]) for k, v in CERT_OBS.items()}
|
||||
ctx = CompanyContext(company_id="mc", certifications=[Certification(certification_id=k) for k in CERT_OBS])
|
||||
profile = build_company_profile(ctx, cmap)
|
||||
w("## 0. Company Capability Profile — der eigentliche Startzustand")
|
||||
w("> Das Unternehmen bringt **kein Zertifikat als Startpunkt**, sondern ein **Profil**. Jedes Zertifikat ist eine *Beobachtung*, die wahrscheinliche Fähigkeiten beisteuert; der Startzustand ist ihre **Aggregation**.")
|
||||
w("")
|
||||
w("| Zertifikat (Beobachtung) | steuert Fähigkeiten bei | Vertrauen |")
|
||||
w("|---|---|---|")
|
||||
for k, (caps, conf, note) in CERT_OBS.items():
|
||||
w("| **%s** — %s | %s | %s |" % (k, note, ", ".join("`%s`" % c for c in caps), conf.value))
|
||||
w("")
|
||||
w("→ **Evidence ist zielrelativ:** ISO 14001 liegt im Profil, hilft der CRA aber **nicht**; PSIRT (oft übersehen) deckt **zwei** CRA-kritische Delta-Fähigkeiten. Genau deshalb darf man **nicht ein Zertifikat** zur Journey machen — das ganze Profil zählt.")
|
||||
w("")
|
||||
|
||||
# ── 1. Ziel (Intent) — was wollen SIE erreichen? ──────────────────────────
|
||||
# The selection input is NOT a certificate. It is (Company Profile, Target). Intent = „CRA-konform werden".
|
||||
TARGET = "CRA"
|
||||
w("## 1. Ziel _(Intent)_ — was wollen Sie erreichen?")
|
||||
w('- Intent: **„CRA-konform werden"** → Ziel-Profil = **CRA** (die von der CRA geforderten Fähigkeiten).')
|
||||
w("- Auswahl-Eingabe ist damit **(Company Profile, Ziel)** — **kein** Zertifikat, das auf eine Journey gemappt wird.")
|
||||
w("")
|
||||
|
||||
# ── 2. Capability Delta — Profil → Ziel (das ist „die Journey") ────────────
|
||||
reqs = [TargetRequirement(capability_id=a["capability"]) for a in CP["likely_covered"]]
|
||||
reqs += [TargetRequirement(capability_id=d["capability"], question_intent=d.get("needed_information", "verify_existence"))
|
||||
for d in CP["delta_requirements"]]
|
||||
assess = assess_transition(TransitionContext(company_id="mc", target=TransitionGoal(target_id=TARGET)), reqs, profile)
|
||||
missing = sorted({c.capability_id for c in assess.coverage if c.status == CoverageStatus.MISSING})
|
||||
|
||||
# counterfactual: a single-certificate company (ISO 27001 only) — to show evidence shrinks the delta.
|
||||
single_prof = build_company_profile(
|
||||
CompanyContext(company_id="s", certifications=[Certification(certification_id="ISO27001")]),
|
||||
{"ISO27001": CapabilityMappingEntry(capability_ids=infosec, confidence=Confidence.MEDIUM)})
|
||||
single_missing = sorted({c.capability_id for c in
|
||||
assess_transition(TransitionContext(company_id="s", target=TransitionGoal(target_id=TARGET)), reqs, single_prof).coverage
|
||||
if c.status == CoverageStatus.MISSING})
|
||||
closed_by_evidence = sorted(set(single_missing) - set(missing))
|
||||
|
||||
w('## 2. Capability Delta — Profil → CRA _(das IST die „Journey")_')
|
||||
w("> %s" % assess.summary.headline)
|
||||
w("- **Delta dieses Profils:** %d fehlende Fähigkeiten." % len(missing))
|
||||
w("- **Gegenprobe (nur ISO 27001):** %d fehlende Fähigkeiten." % len(single_missing))
|
||||
w("- **Mehr Evidence → kleineres Delta:** die zusätzliche Zertifizierung schließt **%d** Fähigkeiten *vorab*: %s." % (
|
||||
len(closed_by_evidence), ", ".join("`%s`" % c for c in closed_by_evidence)))
|
||||
w("")
|
||||
w("→ Es wurde **keine Journey ausgewählt**. Das Delta `(Profil, Ziel)` IST die Journey — berechnet, nicht gewählt. Die Journey ist nur die *Erklärung* dieses Deltas.")
|
||||
w("")
|
||||
|
||||
# ── 3. Roadmap — was zuerst? (gleicher Engine wie #1) ─────────────────────
|
||||
delta_t = {d["capability"]: d.get("covers_targets", []) for d in CP["delta_requirements"]}
|
||||
opt = roadmap_from_delta(assess, delta_t)
|
||||
bud = select_within_budget({m.capability_id: m.covers for m in opt.ranked_measures}, 5)
|
||||
w("## 3. Roadmap — was zuerst? _(gleicher Hebel-Engine wie Mission #1)_")
|
||||
w("> %s" % opt.headline)
|
||||
w("- Top-5 nach Hebel schließen **%d von %d** offenen Anforderungen (%d%%)." % (
|
||||
bud.requirements_closed, bud.total_requirements, int(round(bud.coverage_ratio * 100))))
|
||||
w("")
|
||||
|
||||
# ── Selektions-Rationale (die vom User geforderten 5 Fragen) ───────────────
|
||||
rationale("Welche Journey wurde gewählt?",
|
||||
"**Keine per-Zertifikat-Journey.** Die Journey ist `Company Capability Profile → CRA`. Gewählt wurde nur das **Ziel** (CRA); der Startzustand wurde aus ALLEN Zertifikaten aggregiert.")
|
||||
rationale("Warum?",
|
||||
'Bei 6 Zertifikaten würde „ISO 27001 → CRA" die Evidence aus PSIRT/ISO 9001 wegwerfen (= 3 Fähigkeiten, die sonst fälschlich als Delta erschienen). Nur das **ganze Profil** ergibt das korrekte Delta.')
|
||||
rationale("Welche Informationen waren für die Auswahl entscheidend?",
|
||||
"(a) das **Ziel/Intent** (CRA) und (b) die **vollständige Zertifikatsliste** als Profil — **nicht** ein einzelnes Zertifikat. Welche Evidence hilft, ist **zielrelativ** (ISO 14001 irrelevant, PSIRT hoch-relevant).")
|
||||
rationale("Musste das Journey-Modell erweitert werden?",
|
||||
"**Konzeptionell ja, strukturell nein.** `from → to` bleibt; aber `from` ist ein **Company Capability Profile** (Multi-Cert-Aggregat), kein Zertifikat. Die Engines (`build_company_profile` + `assess_transition`) tun das BEREITS — es war ein Benenn-/Framing-Fehler, kein fehlender Code.")
|
||||
rationale("Musste ein neuer Selektionsparameter eingeführt werden?",
|
||||
"**Ja — und er VEREINFACHT.** Eingabe ist `(Company Profile, Ziel)`, nicht `(Zertifikat, Ziel)`. Die Zertifikate kollabieren ins Profil → **keine 2^N Cert-Kombinationen**, nur Profil→Ziel. Der Selektor wird damit kleiner, nicht größer.")
|
||||
w("## Selektions-Rationale — die 5 Fragen (pro Mission zu dokumentieren)")
|
||||
w("")
|
||||
for q, a in RAT:
|
||||
w("**%s** " % q)
|
||||
w(a)
|
||||
w("")
|
||||
|
||||
# ── Was diese Mission über Mission #1 verändert ───────────────────────────
|
||||
w("## Was Mission #2 an Mission #1 verändert")
|
||||
w("")
|
||||
w('- Mission #1 nannte **Scope → Journey** einen Sprung („kein Selektor `certs × targets → journeys`"). Mission #2 zeigt: **diese Naht schrumpft.** Es gibt keinen Journey-Matcher zu bauen — die Journey ist das **berechnete Delta** `(Profil, Ziel)`. Was real fehlt, ist nur **Profil-Intake + Ziel-Wahl**, nicht eine Journey-Auswahl-Engine.')
|
||||
w('- Bestätigt den Reframe: **Es gibt keine „ISO 27001 → CRA"-Transition — nur „Company Capability Profile → CRA".** Zertifikate sind **Beobachtungen/Evidence**, kein Journey-Startpunkt.')
|
||||
w("- **Beobachtung für den (noch nicht gebauten) Selektor:** Eingabe = `(Company Profile, Ziel)`. Diversität über weitere Missionen muss zeigen, ob auch **Produktprofil** und **Intent-Klasse** als Parameter nötig werden — erst dann kanonisieren ([[rule-of-three-canonicalization]]).")
|
||||
w("")
|
||||
|
||||
print("\n".join(OUT))
|
||||
@@ -0,0 +1,70 @@
|
||||
"""Customer Mission #2 — the company arrives with a PROFILE, not a journey.
|
||||
|
||||
Pins the reframe Mission #2 proves with the real engines: the start state is a Company Capability
|
||||
Profile (many certs aggregated), certifications are observations/evidence, and more evidence shrinks
|
||||
the delta (single-cert 12 → multi-cert 9). The „journey" is the computed delta `(Profile, Target)`,
|
||||
not a thing a selector picks — which shrinks Mission #1's one open seam.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
def _run_mission():
|
||||
root = os.path.join(os.path.dirname(__file__), "..")
|
||||
r = subprocess.run(
|
||||
[sys.executable, "reference_scenarios/mission_multicert_cra.py"],
|
||||
cwd=root, env={**os.environ, "PYTHONPATH": "."}, capture_output=True, text=True,
|
||||
)
|
||||
assert r.returncode == 0, r.stderr
|
||||
return r.stdout
|
||||
|
||||
|
||||
def test_mission_runs_end_to_end():
|
||||
out = _run_mission()
|
||||
assert "Customer Mission #2" in out
|
||||
assert "Company Capability Profile — der eigentliche Startzustand" in out
|
||||
|
||||
|
||||
def test_more_evidence_shrinks_the_delta():
|
||||
out = _run_mission()
|
||||
# multi-cert profile (9) must beat the single-cert counterfactual (12) — evidence is additive.
|
||||
assert "**Delta dieses Profils:** 9" in out
|
||||
assert "**Gegenprobe (nur ISO 27001):** 12" in out
|
||||
assert "Mehr Evidence → kleineres Delta" in out
|
||||
|
||||
|
||||
def test_reframe_no_per_certificate_journey():
|
||||
out = _run_mission()
|
||||
# the journey is the computed delta (Profile, Target), not a selected cert→target transition.
|
||||
assert "Keine per-Zertifikat-Journey" in out
|
||||
assert "Company Capability Profile → CRA" in out
|
||||
assert "Es wurde **keine Journey ausgewählt**" in out
|
||||
|
||||
|
||||
def test_five_selection_rationale_questions_present():
|
||||
out = _run_mission()
|
||||
for q in [
|
||||
"Welche Journey wurde gewählt?",
|
||||
"Warum?",
|
||||
"Welche Informationen waren für die Auswahl entscheidend?",
|
||||
"Musste das Journey-Modell erweitert werden?",
|
||||
"Musste ein neuer Selektionsparameter eingeführt werden?",
|
||||
]:
|
||||
assert q in out
|
||||
|
||||
|
||||
def test_evidence_is_target_relative():
|
||||
out = _run_mission()
|
||||
# honest: ISO 14001 is in the profile but does not help the CRA; PSIRT covers two CRA-delta caps.
|
||||
assert "ISO 14001" in out and "NICHT relevant" in out
|
||||
assert "PSIRT" in out
|
||||
|
||||
|
||||
def test_no_real_company_names():
|
||||
out = _run_mission().lower()
|
||||
for name in ["eto", "owis", "winterhalter"]:
|
||||
assert name not in out
|
||||
@@ -0,0 +1,326 @@
|
||||
{
|
||||
"schema_proposal": "machinery_obligation_capability_linking_v0",
|
||||
"status": "PROPOSED",
|
||||
"proposed_by": "iace-session",
|
||||
"for_ratification_by": ["legal-knowledge-graph", "execution"],
|
||||
"reference_scenario": "RS-004",
|
||||
"regulation_code": "MaschVO_2023_1230",
|
||||
"regulation_aliases": ["MaschinenVO", "Machinery Regulation (EU) 2023/1230"],
|
||||
"authority_note": "IACE holds SAFETY-classification authority and offers these links as machinery-safety domain input. Obligation DEFINITIONS remain the Legal-KG's authority; capability/control MINTING and the canonical mapping FORMAT remain Execution's authority. Nothing here is asserted into either registry. cap.* ids on physical/process links are CANDIDATES (not minted) — ratify, rename, or remap before merging into the canonical mapping. See semantic-authority principle: propose, do not assert across authorities.",
|
||||
"scope": {
|
||||
"in_scope": "MaschVO obligation -> capability/control linking (RS-004 part A), from the machinery-safety side.",
|
||||
"out_of_scope": [
|
||||
"EMV (EMC Directive 2014/30/EU) obligation authoring (RS-004 part B): EMV obligations do not yet exist in the registry. Legal-KG to author via its clustering+synthesis methodology. IACE can supply EMC domain input on request, but will not hand-author obligations (bypasses the owning authority's method).",
|
||||
"Regulation-ID normalization / scope-engine wiring so the map resolves regulation -> obligations (RS-004 part C): Reasoning/Execution consumer code. NOTE: regulation_code 'MaschVO_2023_1230' must alias to the scope-engine id 'MaschinenVO' for resolution to work (board TODO 'Regelwerk-ID-Normalisierung').",
|
||||
"Minting MCAP-/control-ids: Execution authority."
|
||||
]
|
||||
},
|
||||
"confidence_legend": {
|
||||
"high": "Link target already exists in the registry (cra_core obligation or minted capability). Immediately usable.",
|
||||
"medium": "Link target likely exists but the exact id needs an owner check.",
|
||||
"proposed": "Target capability is a CANDIDATE to be minted by Execution; the link is safety-expert input, not a wired reference.",
|
||||
"non_capability": "Obligation is regulatory/applicability in nature and does NOT map to a capability — flagged so Execution does not force a link."
|
||||
},
|
||||
"links": [
|
||||
{
|
||||
"obligation_id": "access_control_safety_functions",
|
||||
"subdomain": "cybersecurity",
|
||||
"link_kind": "cyber_safety_bridge",
|
||||
"confidence": "high",
|
||||
"targets_existing": {
|
||||
"cra_core_obligations": ["attack_surface_minimization"],
|
||||
"capabilities": ["cap.multi_factor_authentication", "cap.session_management"]
|
||||
},
|
||||
"rationale": "MaschVO Anhang III 1.1.9: safety functions must be protected against unauthorized access/modification. Satisfied by the same access-control + attack-surface controls CRA already requires. Convergence link, not a new control.",
|
||||
"convergence": "CRA <-> MaschinenVO: one control set satisfies both"
|
||||
},
|
||||
{
|
||||
"obligation_id": "protection_against_corruption",
|
||||
"subdomain": "cybersecurity",
|
||||
"link_kind": "cyber_safety_bridge",
|
||||
"confidence": "high",
|
||||
"targets_existing": {
|
||||
"cra_core_obligations": ["software_integrity_protection"],
|
||||
"capabilities": ["cap.code_signing"]
|
||||
},
|
||||
"rationale": "MaschVO 1.1.9/1.2.1: protect control software and safety-relevant data against accidental or intentional corruption. Satisfied by CRA software-integrity + code/update signing.",
|
||||
"convergence": "CRA <-> MaschinenVO: one control set satisfies both"
|
||||
},
|
||||
{
|
||||
"obligation_id": "security_functions_default_free",
|
||||
"subdomain": "cybersecurity",
|
||||
"link_kind": "cyber_safety_bridge",
|
||||
"confidence": "medium",
|
||||
"targets_existing": {
|
||||
"cra_core_obligations": ["secure_by_default"],
|
||||
"capabilities": []
|
||||
},
|
||||
"rationale": "Security functions provided secure-by-default and without extra cost. Maps to CRA secure-by-default posture.",
|
||||
"needs_owner_check": "Confirm a CRA 'secure_by_default' obligation id exists in cra_core; if not, propose one or link to the closest secure-configuration obligation."
|
||||
},
|
||||
{
|
||||
"obligation_id": "ml_safety_components",
|
||||
"subdomain": "ml_safety",
|
||||
"link_kind": "cross_regulation_bridge",
|
||||
"confidence": "proposed",
|
||||
"proposed_capability": "cap.ml_safety_assurance",
|
||||
"bridges": ["AI-Act (high-risk safety components)", "MaschVO Anhang III adaptive behaviour"],
|
||||
"iace_grounding": "Adaptive/self-learning safety components: bounded behaviour, validation of learned states, fallback to safe state. IACE state-graph + failure-mode (FMEA) families apply.",
|
||||
"rationale": "MaschVO treats ML-driven safety components as high-risk; same assurance obligations recur under the AI-Act. Strong convergence candidate."
|
||||
},
|
||||
{
|
||||
"obligation_id": "long_term_availability_updates",
|
||||
"subdomain": "maintenance",
|
||||
"link_kind": "cross_regulation_bridge",
|
||||
"confidence": "proposed",
|
||||
"proposed_capability": "cap.update_availability",
|
||||
"bridges": ["CRA vulnerability-handling / security updates"],
|
||||
"rationale": "Long-term availability of (security) updates overlaps CRA's vulnerability-handling obligations — link once the CRA update obligation id is confirmed."
|
||||
},
|
||||
{
|
||||
"obligation_id": "guards_protective_devices",
|
||||
"subdomain": "protective_devices",
|
||||
"link_kind": "physical_safety",
|
||||
"confidence": "proposed",
|
||||
"proposed_capability": "cap.guards_protective_devices",
|
||||
"registry_candidate": true,
|
||||
"iace_grounding": "ISO 14120 (fixed/movable guards), ISO 14119 (interlocking with/without guard locking). IACE hazard categories: mechanical, crushing, shearing, drawing-in.",
|
||||
"rationale": "Already listed in cra_machinery capability_candidates_physical. Safety-expert grounding attached."
|
||||
},
|
||||
{
|
||||
"obligation_id": "emergency_stop_interlocking",
|
||||
"subdomain": "safety_functions",
|
||||
"link_kind": "physical_safety",
|
||||
"confidence": "proposed",
|
||||
"proposed_capability": "cap.emergency_stop_interlocking",
|
||||
"registry_candidate": true,
|
||||
"iace_grounding": "ISO 13850 (emergency stop), ISO 14118 (prevention of unexpected start-up), ISO 14119 (interlocking).",
|
||||
"rationale": "Already listed in cra_machinery capability_candidates_physical. Safety-expert grounding attached."
|
||||
},
|
||||
{
|
||||
"obligation_id": "safety_functions_design",
|
||||
"subdomain": "safety_functions",
|
||||
"link_kind": "physical_safety",
|
||||
"confidence": "proposed",
|
||||
"proposed_capability": "cap.safety_functions_design",
|
||||
"registry_candidate": true,
|
||||
"iace_grounding": "ISO 13849-1 (PL, categories) / IEC 62061 (SIL) for safety-related parts of control systems (SRP/CS); validation per ISO 13849-2.",
|
||||
"rationale": "Already listed in cra_machinery capability_candidates_physical. Safety-expert grounding attached."
|
||||
},
|
||||
{
|
||||
"obligation_id": "safety_components_conformity",
|
||||
"subdomain": "safety_components",
|
||||
"link_kind": "physical_safety",
|
||||
"confidence": "proposed",
|
||||
"proposed_capability": "cap.safety_component_conformity",
|
||||
"iace_grounding": "Listed safety components (MaschVO Anhang I) carry their own conformity duty; design validation per ISO 13849-2.",
|
||||
"rationale": "Distinct from safety_functions_design: this is conformity of the COMPONENT placed on the market, not the integrated function."
|
||||
},
|
||||
{
|
||||
"obligation_id": "residual_risk_management",
|
||||
"subdomain": "residual_risk",
|
||||
"link_kind": "physical_safety",
|
||||
"confidence": "proposed",
|
||||
"proposed_capability": "cap.residual_risk_reduction",
|
||||
"iace_grounding": "ISO 12100 three-step method (inherently safe design -> safeguarding -> information for use); residual-risk warnings + instructions.",
|
||||
"rationale": "Directly mirrors IACE's measure-hierarchy output."
|
||||
},
|
||||
{
|
||||
"obligation_id": "blocking_release_procedure",
|
||||
"subdomain": "protective_devices",
|
||||
"link_kind": "physical_safety",
|
||||
"confidence": "proposed",
|
||||
"proposed_capability": "cap.energy_isolation_loto",
|
||||
"iace_grounding": "ISO 14118 (unexpected start-up), lockout/tagout, safe isolation of energy sources for maintenance.",
|
||||
"rationale": "Maintenance-state hazard control; IACE lifecycle-state = maintenance."
|
||||
},
|
||||
{
|
||||
"obligation_id": "vibration_noise_emission",
|
||||
"subdomain": "emissions",
|
||||
"link_kind": "physical_safety",
|
||||
"confidence": "proposed",
|
||||
"proposed_capability": "cap.emission_reduction",
|
||||
"iace_grounding": "EHSR on vibration + noise; emission reduction at source, declared emission values.",
|
||||
"rationale": "Health-hazard category in IACE (vibration, noise)."
|
||||
},
|
||||
{
|
||||
"obligation_id": "risk_assessment_machinery_lifecycle",
|
||||
"subdomain": "risk_assessment",
|
||||
"link_kind": "process",
|
||||
"confidence": "proposed",
|
||||
"proposed_capability": "cap.machinery_risk_assessment",
|
||||
"iace_grounding": "ISO 12100 risk assessment across the full lifecycle. THIS IS IACE'S CORE OUTPUT — strongest provider-fact alignment of the set.",
|
||||
"rationale": "IACE already produces lifecycle hazard logs; this obligation is the regulatory counterpart."
|
||||
},
|
||||
{
|
||||
"obligation_id": "risk_assessment_documentation",
|
||||
"subdomain": "risk_assessment",
|
||||
"link_kind": "process",
|
||||
"confidence": "proposed",
|
||||
"proposed_capability": "cap.risk_assessment_record",
|
||||
"iace_grounding": "Documented risk-assessment record feeding the technical file.",
|
||||
"rationale": "IACE hazard-log export is the evidence artifact."
|
||||
},
|
||||
{
|
||||
"obligation_id": "risk_assessment_methodology_competence",
|
||||
"subdomain": "risk_assessment",
|
||||
"link_kind": "process",
|
||||
"confidence": "proposed",
|
||||
"proposed_capability": "cap.risk_assessment_competence",
|
||||
"tier": "BEST_PRACTICE",
|
||||
"rationale": "Competence/methodology assurance for the assessor — organizational, not a machine control."
|
||||
},
|
||||
{
|
||||
"obligation_id": "operating_instructions",
|
||||
"subdomain": "operating_instructions",
|
||||
"link_kind": "process",
|
||||
"confidence": "proposed",
|
||||
"proposed_capability": "cap.safety_information_instructions",
|
||||
"iace_grounding": "ISO 12100 6.4 information for use; IEC/IEEE 82079-1 instructions.",
|
||||
"rationale": "Carries IACE residual-risk warnings into the instructions."
|
||||
},
|
||||
{
|
||||
"obligation_id": "conformity_assessment",
|
||||
"subdomain": "conformity",
|
||||
"link_kind": "process",
|
||||
"confidence": "proposed",
|
||||
"proposed_capability": "cap.conformity_assessment_procedure",
|
||||
"iace_grounding": "MaschVO Anhang XI procedures (internal control vs notified-body routes).",
|
||||
"rationale": "Procedure selection depends on Anhang I high-risk classification."
|
||||
},
|
||||
{
|
||||
"obligation_id": "technical_documentation",
|
||||
"subdomain": "documentation",
|
||||
"link_kind": "process",
|
||||
"confidence": "proposed",
|
||||
"proposed_capability": "cap.technical_file",
|
||||
"iace_grounding": "MaschVO Anhang IV technical file; risk assessment is a mandatory part.",
|
||||
"rationale": "IACE hazard log is a required input to the technical file."
|
||||
},
|
||||
{
|
||||
"obligation_id": "eu_declaration_ce_marking",
|
||||
"subdomain": "conformity",
|
||||
"link_kind": "process",
|
||||
"confidence": "proposed",
|
||||
"proposed_capability": "cap.ce_marking_declaration",
|
||||
"iace_grounding": "MaschVO Anhang V EU declaration of conformity + CE marking affixing.",
|
||||
"rationale": "Final conformity attestation step."
|
||||
},
|
||||
{
|
||||
"obligation_id": "manufacturer_economic_operator_obligations",
|
||||
"subdomain": "economic_operators",
|
||||
"link_kind": "process",
|
||||
"confidence": "proposed",
|
||||
"proposed_capability": "cap.economic_operator_duties",
|
||||
"rationale": "Manufacturer/importer/distributor duty chain — organizational."
|
||||
},
|
||||
{
|
||||
"obligation_id": "essential_safety_requirements_compliance",
|
||||
"subdomain": "ehsr",
|
||||
"link_kind": "process",
|
||||
"confidence": "proposed",
|
||||
"proposed_capability": "cap.ehsr_compliance",
|
||||
"iace_grounding": "MaschVO Anhang III essential health and safety requirements — the umbrella that the physical_safety capabilities collectively satisfy.",
|
||||
"rationale": "Composite: satisfied via the physical_safety capabilities above; model as an aggregate rather than a single control."
|
||||
},
|
||||
{
|
||||
"obligation_id": "harmonised_standards_selection",
|
||||
"subdomain": "standards",
|
||||
"link_kind": "process",
|
||||
"confidence": "proposed",
|
||||
"proposed_capability": "cap.harmonised_standards",
|
||||
"tier": "BEST_PRACTICE",
|
||||
"iace_grounding": "Use of harmonised standards grants presumption of conformity; IACE's ISO references (12100/13849/14120/13850) are the candidate set.",
|
||||
"rationale": "Links the standards IACE already cites to the presumption-of-conformity mechanism."
|
||||
},
|
||||
{
|
||||
"obligation_id": "notified_body_requirements",
|
||||
"subdomain": "notified_body",
|
||||
"link_kind": "process",
|
||||
"confidence": "proposed",
|
||||
"proposed_capability": "cap.notified_body_involvement",
|
||||
"iace_grounding": "MaschVO Anhang I Part A high-risk machinery requires notified-body involvement.",
|
||||
"rationale": "Triggered by Anhang I classification of the machine."
|
||||
},
|
||||
{
|
||||
"obligation_id": "modification_substantial_change",
|
||||
"subdomain": "modification",
|
||||
"link_kind": "process",
|
||||
"confidence": "proposed",
|
||||
"proposed_capability": "cap.substantial_modification_assessment",
|
||||
"iace_grounding": "Substantial modification can create a 'new' machine requiring fresh conformity; re-run risk assessment.",
|
||||
"rationale": "IACE re-assessment is the trigger artifact."
|
||||
},
|
||||
{
|
||||
"obligation_id": "autonomous_mobile_machinery",
|
||||
"subdomain": "mobile_machinery",
|
||||
"link_kind": "physical_safety",
|
||||
"confidence": "proposed",
|
||||
"proposed_capability": "cap.amr_safety",
|
||||
"iace_grounding": "Mobile/autonomous machinery EHSR: travel functions, supervision, monitoring, safe stop in autonomous mode.",
|
||||
"rationale": "Distinct hazard family (mobility) in IACE."
|
||||
},
|
||||
{
|
||||
"obligation_id": "verification_inspection_maintenance",
|
||||
"subdomain": "verification",
|
||||
"link_kind": "process",
|
||||
"confidence": "proposed",
|
||||
"proposed_capability": "cap.in_service_verification",
|
||||
"tier": "BEST_PRACTICE",
|
||||
"rationale": "In-service inspection/maintenance regime — lifecycle-state = in_service/maintenance."
|
||||
},
|
||||
{
|
||||
"obligation_id": "quality_management_system",
|
||||
"subdomain": "quality_management",
|
||||
"link_kind": "process",
|
||||
"confidence": "proposed",
|
||||
"proposed_capability": "cap.quality_management_system",
|
||||
"tier": "BEST_PRACTICE",
|
||||
"iace_grounding": "MaschVO Anhang IX full quality-assurance route.",
|
||||
"rationale": "Organizational QA enabling the conformity route."
|
||||
},
|
||||
{
|
||||
"obligation_id": "market_surveillance_safeguard",
|
||||
"subdomain": "market_surveillance",
|
||||
"link_kind": "non_capability",
|
||||
"confidence": "non_capability",
|
||||
"rationale": "Cooperation with market-surveillance authorities + safeguard procedure: a regulatory-interaction duty, not a machine/process capability. Flagged so Execution does not force a capability link.",
|
||||
"owner_decision": "Legal-KG to decide whether to model as an obligation-only node."
|
||||
},
|
||||
{
|
||||
"obligation_id": "sanctions",
|
||||
"subdomain": "sanctions",
|
||||
"link_kind": "non_capability",
|
||||
"confidence": "non_capability",
|
||||
"rationale": "Penalty regime — a legal consequence, not a capability. No control link.",
|
||||
"owner_decision": "Legal-KG: obligation-only node."
|
||||
},
|
||||
{
|
||||
"obligation_id": "scope_transition_application",
|
||||
"subdomain": "scope",
|
||||
"link_kind": "non_capability",
|
||||
"confidence": "non_capability",
|
||||
"rationale": "Applicability + transition dates (old Directive 2006/42/EC -> Regulation 2023/1230). This drives the SCOPE engine, not a capability. RS-004 part C (reg-ID/scope wiring) is the right home.",
|
||||
"owner_decision": "Reasoning/scope-engine, not a capability."
|
||||
},
|
||||
{
|
||||
"obligation_id": "specific_machine_types",
|
||||
"subdomain": "specific_machinery",
|
||||
"link_kind": "composite",
|
||||
"confidence": "proposed",
|
||||
"rationale": "Machine-type-specific EHSR (e.g. lifting, portable, wood/food machinery). Resolves to MULTIPLE physical_safety capabilities depending on machine type — model as a type-conditional set, not one control.",
|
||||
"owner_decision": "Execution: expand per machine-type once the physical_safety capabilities are minted."
|
||||
}
|
||||
],
|
||||
"summary": {
|
||||
"obligations_total": 31,
|
||||
"cyber_safety_bridges_high_confidence": 2,
|
||||
"cyber_safety_bridges_needs_check": 1,
|
||||
"cross_regulation_bridges": 2,
|
||||
"physical_safety_candidates": 7,
|
||||
"process_candidates": 13,
|
||||
"non_capability_flags": 3,
|
||||
"composite": 1,
|
||||
"headline": "The 2 high-confidence cyber-safety bridges are immediately wirable to existing CRA-core obligations + capabilities (the CRA<->MaschinenVO convergence USP). Everything else is safety-expert input for Execution to mint and Legal-KG to ratify."
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user