feat(iace): GT-Bremse coverage — 59 expert measures + 7 hazard patterns

Systematic gap analysis of the Bremse ground-truth file (60 entries,
100 unique expert measures) revealed only ~5% library coverage. This
commit closes the documented gaps with concrete, norm-anchored
mitigations.

Library additions (M481-M539, 59 entries):
- M481-M482  Low-voltage isolation (>= 2,0 / 2x1,0 / 1,0 MOhm +
             IP2X/IPXXB per EN 60204-1 Ziff. 6.2/8.2.3) — primary
             trigger of this work
- M483-M485  Pneumatic safety (component pressure rating, hose
             retention, depressurization per EN ISO 4414)
- M486-M490  Robot-cell access (tool-secured fence, dual-channel
             door monitor, intentional restart, anti-trap inside
             opening, HMI sight line per ISO 10218-2)
- M491-M493  Teach mode (key/password mode selector, safe reduced
             speed <= 250 mm/s, hold-to-run with 3-stage enabler
             per ISO 10218-1)
- M494-M500  Geometry constants (Safe Limited Position, reach-over
             250 mm @ 2250 mm fence, conveyor opening >= 850 mm,
             25 mm finger gap, band speed <= 100 mm/s per
             EN ISO 13857 / EN 619)
- M501-M507  Enclosure load rating, gripper fail-safe, centring
             gripper stop on door, MWF nozzle integration, floor
             load capacity per DIN 1055-3
- M508-M517  Electrical cabling + PE protection (environment-rated,
             drag chain, strain relief, 10 mm² Cu PE, dual PE,
             monitoring, continuity check, class-II equipment,
             SELV/PELV per EN 60204-1)
- M518-M522  RCD, cable cross-section, overcurrent in each active
             conductor, IP22 water ingress, lockable main switch
- M523-M539  Teach-locked door, WZM door interlock, dual-channel
             door switch, machining-doors-closed for aerosol
             retention, post-NOTHALT release, >25 kg lifting aid
             (DGUV 208-016), 95-120 cm control height, ergonomic
             conveyor height, SDS/PSA reference, BA instructions
             for depressurization/clamp release/max weight/pinch
             warning/slip warning/dead-state cleaning

New hazard patterns (HP1710-HP1717):
floor overload, gripper failure throw, compressed-air injury in
machining cell, manual handling load + awkward posture, MWF skin
contact, live-cabinet cleaning short, pneumatic stored-energy.

Existing patterns rewired to the new measures: HP1600, HP1602-1606,
HP1610-1612, HP1620-1622, HP1630/1631/1633, HP1640/1641, HP1660/1661,
HP1675, HP1685, HP1688, HP1689, HP1698-1704.

Tooling:
- scripts/gt_measure_gap_analysis.py: 4-signal fuzzy matcher
  (Jaccard, token recall, substring containment, norm-reference
  overlap). Outputs markdown + JSON.
- gt_coverage_test.go: 23 expert-validated (GT-Nr, pattern, measure)
  triples + a norm-reference presence test for every new expert
  measure (no generic 'do X safely' entries allowed).
- .gitea/workflows/ci.yaml: new iace-gt-coverage job enforces
  MIN_COVERAGE_PCT (70%) on Strong+Weak GT coverage; never lower
  without explicit decision.

Coverage shift: 5% Strong -> 30% Strong, 0% -> 72% Strong+Weak.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-05-16 13:08:52 +02:00
parent bf9d8a5ed3
commit 4d1e0a7f8e
10 changed files with 812 additions and 25 deletions
@@ -16,7 +16,7 @@ func GetRobotCellPatterns() []HazardPattern {
ID: "HP1600", NameDE: "Einklemmen zwischen Roboterarm und Anlage", NameEN: "Crushing between robot arm and fixed structure",
RequiredComponentTags: []string{"moving_part"},
GeneratedHazardCats: []string{"mechanical_hazard"},
SuggestedMeasureIDs: []string{"M061", "M062", "M054"},
SuggestedMeasureIDs: []string{"M487", "M488", "M494", "M054", "M061"},
Priority: 99, MachineTypes: []string{"robotics_cobot", "automotive", "metalworking", "general_industry"},
ApplicableLifecycles: []string{"normal_operation", "setup", "teach_mode", "cleaning", "maintenance", "fault_clearing", "changeover"},
ScenarioDE: "Person befindet sich im Bewegungsbereich des Roboterarms und wird zwischen Roboterarm und feststehenden Anlagenteilen eingeklemmt.",
@@ -30,7 +30,7 @@ func GetRobotCellPatterns() []HazardPattern {
ID: "HP1602", NameDE: "Durchgreifen durch Schutzzaun zum Roboter", NameEN: "Reaching through safety fence to robot",
RequiredComponentTags: []string{"moving_part", "guard"},
GeneratedHazardCats: []string{"mechanical_hazard"},
SuggestedMeasureIDs: []string{"M002", "M061"},
SuggestedMeasureIDs: []string{"M495", "M486", "M002", "M061"},
Priority: 98,
ApplicableLifecycles: []string{"normal_operation", "setup", "cleaning", "maintenance", "fault_clearing"},
ScenarioDE: "Person greift ueber oder durch den Schutzzaun und erreicht den Bewegungsbereich des Roboterarms.",
@@ -44,7 +44,7 @@ func GetRobotCellPatterns() []HazardPattern {
ID: "HP1603", NameDE: "Eingeschlossen in Roboterzelle", NameEN: "Trapped inside robot cell",
RequiredComponentTags: []string{"moving_part", "guard"},
GeneratedHazardCats: []string{"mechanical_hazard"},
SuggestedMeasureIDs: []string{"M061", "M054", "M141"},
SuggestedMeasureIDs: []string{"M489", "M490", "M488", "M487"},
Priority: 99,
ApplicableLifecycles: []string{"normal_operation", "setup", "cleaning", "maintenance", "fault_clearing", "changeover"},
ScenarioDE: "Person befindet sich in der Roboterzelle, Schutztuer wird geschlossen und Roboter startet. Person kann den Gefahrenbereich nicht rechtzeitig verlassen.",
@@ -58,7 +58,7 @@ func GetRobotCellPatterns() []HazardPattern {
ID: "HP1604", NameDE: "Roboterarm durchschlaegt Schutzzaun", NameEN: "Robot arm penetrates safety fence",
RequiredComponentTags: []string{"moving_part", "guard"},
GeneratedHazardCats: []string{"mechanical_hazard"},
SuggestedMeasureIDs: []string{"M061", "M002"},
SuggestedMeasureIDs: []string{"M494", "M501", "M061"},
Priority: 98,
ApplicableLifecycles: []string{"normal_operation", "setup", "cleaning", "changeover", "fault_clearing"},
ScenarioDE: "Roboterarm ueberschreitet Bewegungsbereich und trifft Schutzzaun. Person ausserhalb wird von Zaunteilen oder dem Roboterarm getroffen.",
@@ -72,7 +72,7 @@ func GetRobotCellPatterns() []HazardPattern {
ID: "HP1605", NameDE: "Stoss durch Werkzeug/Greifer im Einrichtbetrieb", NameEN: "Impact by tool/gripper during setup",
RequiredComponentTags: []string{"moving_part", "clamping_part"},
GeneratedHazardCats: []string{"mechanical_hazard"},
SuggestedMeasureIDs: []string{"M054"},
SuggestedMeasureIDs: []string{"M491", "M492", "M493", "M054"},
Priority: 98, MachineTypes: []string{"robotics_cobot", "automotive", "metalworking", "general_industry"},
ApplicableLifecycles: []string{"teach_mode", "setup", "changeover", "fault_clearing"},
ScenarioDE: "Person steht im Bewegungsbereich des Roboterarms und wird von bewegtem Werkzeug oder Greifer getroffen. Geschwindigkeitsreduzierung im Einrichtbetrieb reicht nicht aus.",
@@ -89,7 +89,7 @@ func GetRobotCellPatterns() []HazardPattern {
ID: "HP1610", NameDE: "Quetschen im Greiferbereich", NameEN: "Crushing in gripper area",
RequiredComponentTags: []string{"clamping_part"},
GeneratedHazardCats: []string{"mechanical_hazard"},
SuggestedMeasureIDs: []string{"M054", "M061"},
SuggestedMeasureIDs: []string{"M503", "M487", "M054", "M061"},
Priority: 99, MachineTypes: []string{"robotics_cobot", "automotive", "metalworking", "general_industry"},
ApplicableLifecycles: []string{"normal_operation", "setup", "cleaning", "changeover", "fault_clearing"},
ScenarioDE: "Person greift in den Bereich des Greifers. Hand wird zwischen Greifbacken und Werkstueck eingeklemmt.",
@@ -103,7 +103,7 @@ func GetRobotCellPatterns() []HazardPattern {
ID: "HP1611", NameDE: "Werkstueck faellt aus Greifer herab", NameEN: "Workpiece falls from gripper",
RequiredComponentTags: []string{"clamping_part"},
GeneratedHazardCats: []string{"mechanical_hazard"},
SuggestedMeasureIDs: []string{"M007", "M141"},
SuggestedMeasureIDs: []string{"M502", "M007", "M141"},
Priority: 98,
ApplicableLifecycles: []string{"normal_operation", "setup", "changeover"},
ScenarioDE: "Greifer verliert das Werkstueck waehrend des Transports. Werkstueck faellt herab und trifft Person unterhalb des Roboterarms.",
@@ -117,7 +117,7 @@ func GetRobotCellPatterns() []HazardPattern {
ID: "HP1612", NameDE: "Werkstueck durchschlaegt Einhausung", NameEN: "Workpiece penetrates enclosure",
RequiredComponentTags: []string{"clamping_part", "guard"},
GeneratedHazardCats: []string{"mechanical_hazard"},
SuggestedMeasureIDs: []string{"M061", "M141"},
SuggestedMeasureIDs: []string{"M501", "M502", "M061"},
Priority: 98,
ApplicableLifecycles: []string{"normal_operation"},
ScenarioDE: "Greifer versagt und Werkstueck wird in Richtung Schutzzaun geschleudert. Person ausserhalb der Zelle wird von durchschlagendem Werkstueck getroffen.",
@@ -134,7 +134,7 @@ func GetRobotCellPatterns() []HazardPattern {
ID: "HP1620", NameDE: "Quetschen an Foerderband-Einlauf", NameEN: "Crushing at conveyor infeed",
RequiredComponentTags: []string{"entanglement_risk"},
GeneratedHazardCats: []string{"mechanical_hazard"},
SuggestedMeasureIDs: []string{"M002", "M061", "M003"},
SuggestedMeasureIDs: []string{"M498", "M499", "M002", "M061"},
Priority: 98,
ApplicableLifecycles: []string{"normal_operation", "setup", "cleaning", "maintenance", "fault_clearing"},
ScenarioDE: "Person greift an Foerderband und wird zwischen beweglichen und feststehenden Teilen eingeklemmt.",
@@ -148,7 +148,7 @@ func GetRobotCellPatterns() []HazardPattern {
ID: "HP1621", NameDE: "Durchgreifen durch Foerderband-Oeffnung in Schutzzaun", NameEN: "Reaching through conveyor opening in fence",
RequiredComponentTags: []string{"entanglement_risk", "guard"},
GeneratedHazardCats: []string{"mechanical_hazard"},
SuggestedMeasureIDs: []string{"M002", "M061"},
SuggestedMeasureIDs: []string{"M496", "M497", "M498", "M002"},
Priority: 98,
ApplicableLifecycles: []string{"normal_operation", "setup", "cleaning", "fault_clearing"},
ScenarioDE: "Person greift durch die Oeffnung im Schutzzaun fuer die Foerderbaender in den Gefahrenbereich des Roboters.",
@@ -162,7 +162,7 @@ func GetRobotCellPatterns() []HazardPattern {
ID: "HP1622", NameDE: "Herunterfallen von Werkstueck am Bandende", NameEN: "Workpiece falling off conveyor end",
RequiredComponentTags: []string{"entanglement_risk"},
GeneratedHazardCats: []string{"mechanical_hazard"},
SuggestedMeasureIDs: []string{"M008"},
SuggestedMeasureIDs: []string{"M500", "M008"},
Priority: 97,
ApplicableLifecycles: []string{"normal_operation", "setup"},
ScenarioDE: "Werkstueck faehrt ueber das Ende des Transportbandes hinaus, faellt herab und trifft Person am Be-/Entladeplatz.",
@@ -196,7 +196,7 @@ func GetRobotCellPatterns() []HazardPattern {
ID: "HP1630", NameDE: "Pneumatikschlauch springt unter Druck ab", NameEN: "Pressurized hose comes loose",
RequiredComponentTags: []string{"pinch_point"},
GeneratedHazardCats: []string{"mechanical_hazard"},
SuggestedMeasureIDs: []string{"M480"},
SuggestedMeasureIDs: []string{"M483", "M484", "M485"},
Priority: 97,
ApplicableLifecycles: []string{"normal_operation", "setup", "maintenance", "fault_clearing"},
ScenarioDE: "Pneumatikschlauch der Automation springt unter Druck ab und trifft eine Person (Peitscheneffekt).",
@@ -210,7 +210,7 @@ func GetRobotCellPatterns() []HazardPattern {
ID: "HP1631", NameDE: "Restdruck in Pneumatik nach Abschaltung", NameEN: "Residual pressure in pneumatics after shutdown",
RequiredComponentTags: []string{"pinch_point"},
GeneratedHazardCats: []string{"mechanical_hazard"},
SuggestedMeasureIDs: []string{"M480", "M141"},
SuggestedMeasureIDs: []string{"M485", "M483", "M141"},
Priority: 97,
ApplicableLifecycles: []string{"maintenance", "fault_clearing", "changeover"},
ScenarioDE: "Person loest druckbeaufschlagte Pneumatik-Komponenten die nach Abschaltung noch unter Druck stehen. Teile fliegen unkontrolliert weg und treffen die Person.",
@@ -227,7 +227,7 @@ func GetRobotCellPatterns() []HazardPattern {
ID: "HP1606", NameDE: "Quetschen/Scheren durch Greifer im Einrichtbetrieb", NameEN: "Crushing/shearing by gripper during setup",
RequiredComponentTags: []string{"clamping_part"},
GeneratedHazardCats: []string{"mechanical_hazard"},
SuggestedMeasureIDs: []string{"M054"},
SuggestedMeasureIDs: []string{"M491", "M492", "M493", "M054"},
Priority: 98, MachineTypes: []string{"robotics_cobot", "automotive", "metalworking", "general_industry"},
ApplicableLifecycles: []string{"teach_mode", "setup", "changeover", "fault_clearing"},
ScenarioDE: "Einrichter steht im Schwenkbereich des Roboterarms und wird von bewegtem Greifer oder daran befestigtem Werkzeug verletzt.",
@@ -255,7 +255,7 @@ func GetRobotCellPatterns() []HazardPattern {
ID: "HP1633", NameDE: "KSS-Versorgungsschlauch platzt oder reisst ab", NameEN: "Coolant supply hose bursts or tears off",
RequiredComponentTags: []string{},
GeneratedHazardCats: []string{"mechanical_hazard"},
SuggestedMeasureIDs: []string{"M480"},
SuggestedMeasureIDs: []string{"M484", "M483"},
Priority: 97, MachineTypes: []string{"cnc", "metalworking", "automotive"},
ApplicableLifecycles: []string{"normal_operation", "maintenance", "fault_clearing"},
ScenarioDE: "KSS-Versorgungsschlauch reisst ab oder platzt. Person in der Naehe wird von abspringendem Schlauch oder KSS-Strahl unter Druck getroffen.",
@@ -315,7 +315,7 @@ func GetRobotCellPatterns() []HazardPattern {
RequiredComponentTags: []string{},
RequiredEnergyTags: []string{},
GeneratedHazardCats: []string{"electrical_hazard"},
SuggestedMeasureIDs: []string{"M265", "M089", "M088", "M139", "M475"},
SuggestedMeasureIDs: []string{"M481", "M482", "M265", "M139", "M475"},
Priority: 99,
ApplicableLifecycles: []string{"normal_operation", "setup", "maintenance", "fault_clearing"},
ScenarioDE: "Person beruehrt spannungsfuehrende Teile der Anlage die nicht ausreichend isoliert oder abgedeckt sind.",
@@ -330,7 +330,7 @@ func GetRobotCellPatterns() []HazardPattern {
RequiredComponentTags: []string{},
RequiredEnergyTags: []string{"electrical"},
GeneratedHazardCats: []string{"electrical_hazard"},
SuggestedMeasureIDs: []string{"M475", "M476"},
SuggestedMeasureIDs: []string{"M511", "M512", "M514", "M515", "M475"},
Priority: 98,
ApplicableLifecycles: []string{"normal_operation", "setup", "cleaning", "maintenance", "fault_clearing"},
ScenarioDE: "Schutzleiter ist unterbrochen. Person beruehrt das Maschinengehaeuse und erleidet elektrischen Schlag durch gefaehrliche Beruehrungsspannung.",