feat(iace): bridge OSHA MD library to pattern engine, body-part-specific lift crush hazards
- M600-M604: lift endstop mitigations (Kriechgeschwindigkeit, Schaltleiste, Mindestabstand, Hold-to-run, Trittblech) — cite OSHA + EN ISO identifiers - HP2100-HP2102: body-part crush patterns for lift family (foot under platform, hand/body against fixed structure, leg between lift and lateral structure), restricted via MachineTypes filter - pattern_machinetype_overrides.go: post-load pass fills MachineTypes on 14 legacy patterns (HP1000 Walzen, HP539 Schweiss, HP545/HP782 Glas, HP756/HP757/HP760 Fahrtreppe, HP1400-1402 CNC, HP045/HP049 Pressen, HP420-422 Conveyor) to prevent drift on Kistenhubgeraet-style projects Why: Kistenhubgeraet re-init exposed two gaps — the abstract "Bremse versagt bei Absenkbewegung" pattern fired but the concrete foot-crush body-part variant was missing, AND ~10 unrelated patterns fired purely because their RequiredTags incidentally aligned. Override map avoids touching 1000+ LOC pattern files that already exceed the soft cap. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
package iace
|
||||
|
||||
// Body-part-specific crush hazards at lift / hoist / scissor-lift endstops.
|
||||
// Bridges the gap that the Kistenhubgeraet re-init exposed: the abstract
|
||||
// "Bremse versagt bei Absenkbewegung" pattern fires, but the concrete
|
||||
// "Fuss unter absenkender Hubplattform" body-part variant did not exist.
|
||||
//
|
||||
// Each pattern restricts to lift-family machine types via MachineTypes,
|
||||
// so a press / CNC / textile project does not pick them up. Mitigations
|
||||
// reference the new M600-M604 (lift endstop) library plus the existing
|
||||
// M001 (geometry), M002 (safety distance), M141 (warning sign).
|
||||
|
||||
func GetLiftEndstopPatterns() []HazardPattern {
|
||||
liftTypes := []string{"lift", "hoist", "elevator", "scissor_lift"}
|
||||
return []HazardPattern{
|
||||
{
|
||||
ID: "HP2100",
|
||||
NameDE: "Fuss-Quetschung unter absenkender Hubplattform am Bodenanschlag",
|
||||
NameEN: "Foot crush under descending lift platform at floor stop",
|
||||
RequiredComponentTags: []string{"crush_point", "gravity_risk", "person_under_load"},
|
||||
RequiredEnergyTags: []string{"gravitational"},
|
||||
MachineTypes: liftTypes,
|
||||
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||
SuggestedMeasureIDs: []string{"M600", "M601", "M604", "M141"},
|
||||
Priority: 92,
|
||||
ScenarioDE: "Fuss oder Bein des Bedieners gelangt waehrend des Absenkvorgangs unter die " +
|
||||
"Hubplattform. Bei Erreichen der unteren Endlage wird der Fuss zwischen Plattform " +
|
||||
"und Boden gequetscht.",
|
||||
TriggerDE: "Unsachgemaesse Position des Bedieners beim Be-/Entladen, fehlende Schaltleiste, fehlender Trittschutz",
|
||||
HarmDE: "Fussquetschung, Mittelfussfraktur, Zehenamputation",
|
||||
AffectedDE: "Bediener, Wartungspersonal",
|
||||
ZoneDE: "Bodenbereich unter Hubplattform, umlaufende Spalte",
|
||||
DefaultSeverity: 4,
|
||||
DefaultExposure: 3,
|
||||
DefaultAvoidability: 2,
|
||||
ISO12100Section: "6.3.5.5 Quetschen — Mindestabstaende",
|
||||
ClarificationQuestionsDE: []string{
|
||||
"Ist eine umlaufende Quetsch-Schaltleiste an der Plattformunterkante verbaut?",
|
||||
"Ist die Hubgeschwindigkeit am unteren Endanschlag auf <=15 mm/s reduziert (siehe M600)?",
|
||||
"Verhindert ein Trittblech / Unterfahrschutz das Hineinfahren von Fuessen?",
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "HP2101",
|
||||
NameDE: "Hand- oder Koerper-Quetschung gegen feste Struktur beim Hochfahren der Hubeinheit",
|
||||
NameEN: "Hand or body crush against fixed structure during lift upward travel",
|
||||
RequiredComponentTags: []string{"crush_point", "gravity_risk"},
|
||||
RequiredEnergyTags: []string{"gravitational"},
|
||||
MachineTypes: liftTypes,
|
||||
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||
SuggestedMeasureIDs: []string{"M602", "M603", "M600", "M141"},
|
||||
Priority: 90,
|
||||
ScenarioDE: "Beim Hochfahren der Last gelangen Hand oder Koerperteile des Bedieners " +
|
||||
"zwischen die hoechste Position der Hubeinheit (z.B. mit beladener Palette) und " +
|
||||
"eine feste Struktur oberhalb (Decke, Vorbau, Querbalken einer umschliessenden Anlage).",
|
||||
TriggerDE: "Eingriff in den Verfahrweg waehrend Hubvorgang, fehlende konstruktive Begrenzung der Endlage",
|
||||
HarmDE: "Hand- oder Armquetschung, im Extremfall Brustkorbkompression",
|
||||
AffectedDE: "Bediener, Einrichter, Wartungspersonal",
|
||||
ZoneDE: "Oberhalb hoechster Hubposition, Vorbau/Decke der umschliessenden Anlage",
|
||||
DefaultSeverity: 4,
|
||||
DefaultExposure: 2,
|
||||
DefaultAvoidability: 2,
|
||||
ISO12100Section: "6.3.5.5 Quetschen — Mindestabstaende",
|
||||
ClarificationQuestionsDE: []string{
|
||||
"Welcher Mindestabstand zu festen Strukturen oberhalb der hoechsten Hubposition ist gegeben? (Empfehlung: 120 mm fuer Kopf, 100 mm fuer Hand)",
|
||||
"Ist der Tippbetrieb (Hold-to-run) durch ein Testprotokoll mit Stop-Zeit-Messung verifiziert?",
|
||||
"Existiert eine redundante Hardware-Endlage zusaetzlich zur Software-Begrenzung?",
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "HP2102",
|
||||
NameDE: "Quetschung Bein/Koerper zwischen Hubeinheit und seitlicher Struktur",
|
||||
NameEN: "Leg/body crush between lift unit and lateral structure",
|
||||
RequiredComponentTags: []string{"crush_point", "gravity_risk", "moving_part"},
|
||||
RequiredEnergyTags: []string{"gravitational"},
|
||||
MachineTypes: liftTypes,
|
||||
GeneratedHazardCats: []string{"mechanical_hazard"},
|
||||
SuggestedMeasureIDs: []string{"M602", "M601", "M141"},
|
||||
Priority: 85,
|
||||
ScenarioDE: "Person befindet sich seitlich neben der Hubeinheit und wird waehrend " +
|
||||
"der Bewegung gegen eine feste Struktur (Regalwand, Stuetze, andere Anlage) gequetscht.",
|
||||
TriggerDE: "Aufenthalt in Quetschzone bei Bewegung, fehlende Absperrung",
|
||||
HarmDE: "Beinfraktur, Beckenquetschung",
|
||||
AffectedDE: "Bediener, vorbeigehende Personen",
|
||||
ZoneDE: "Seitlicher Bereich neben Hubeinheit, Lichte Weite zu festen Strukturen",
|
||||
DefaultSeverity: 4,
|
||||
DefaultExposure: 2,
|
||||
DefaultAvoidability: 2,
|
||||
ISO12100Section: "6.3.5.5 Quetschen — Mindestabstaende",
|
||||
ClarificationQuestionsDE: []string{
|
||||
"Welcher Sicherheitsabstand zu seitlichen festen Strukturen ist gegeben (Empfehlung 500 mm Koerperdurchgang)?",
|
||||
"Ist der Bereich seitlich der Hubeinheit als Gefahrenzone markiert oder abgeschrankt?",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ func GetProtectiveMeasureLibrary() []ProtectiveMeasureEntry {
|
||||
all = append(all, GetTextileAgriMeasures()...) // Textil + Landmaschinen (Phase 5)
|
||||
all = append(all, getGTBremseMeasures()...) // GT-Bremse-Coverage-Gaps (M483-M522)
|
||||
all = append(all, GetCRAMeasures()...) // CRA / DIN EN 40000-1-2 cyber-resilience (M540-M548)
|
||||
all = append(all, getLiftEndstopMeasures()...) // Lift/hoist endstop (M600-M604) — bridges OSHA MD library
|
||||
return all
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
package iace
|
||||
|
||||
// Lift / hoist / scissor-lift endstop mitigations — bridges the OSHA
|
||||
// minimum-distance library (minimum_distances.go, Task #18) into the
|
||||
// pattern-engine measure library. Each entry cites the concrete OSHA
|
||||
// value AND its EU-norm pendant by identifier only.
|
||||
//
|
||||
// Engineering rounding values come from MD_OSHA_* IDs in
|
||||
// minimum_distances.go. We do not duplicate the source text here —
|
||||
// the Tech-File renderer can join MD_OSHA_* into the rendered text
|
||||
// at output time.
|
||||
|
||||
func getLiftEndstopMeasures() []ProtectiveMeasureEntry {
|
||||
return []ProtectiveMeasureEntry{
|
||||
// M600 — Cruise/creep speed at end of travel
|
||||
{
|
||||
ID: "M600",
|
||||
ReductionType: "protection",
|
||||
SubType: "speed_control",
|
||||
Name: "Kriechgeschwindigkeit am Endanschlag (Hubgeraete)",
|
||||
Description: "Hubgeschwindigkeit am Ende der Verfahrbewegung (oben und unten) auf maximal 15 mm/s " +
|
||||
"reduzieren. OSHA 29 CFR 1910.217 Hand-Speed-Konstante 63 in/s = 1.600 mm/s als Obergrenze " +
|
||||
"fuer Stopp-Reaktionszeit. Damit ist auch bei spaeter Auslosung der Quetsch-Schaltleiste " +
|
||||
"genug Bremsweg vorhanden.",
|
||||
HazardCategory: "mechanical",
|
||||
Examples: []string{
|
||||
"Hub-Endschalter mit Soft-Stop und Geschwindigkeitsstufe < 15 mm/s in den letzten 50 mm",
|
||||
"Servo-Antrieb mit Ramp-down-Profil ueber die letzten 100 mm Verfahrweg",
|
||||
"Drehzahl-Begrenzer im Frequenzumrichter mit Endlagen-Trigger",
|
||||
},
|
||||
NormReferences: []string{
|
||||
"OSHA 29 CFR 1910.217 (Ds = 63 in/s x Ts)",
|
||||
"EN ISO 13855 (Anordnung von Schutzeinrichtungen)",
|
||||
"EN 1570-1 (Hubtische — Bauanforderungen)",
|
||||
},
|
||||
RiskReduction: &RiskReduction{SeverityDelta: -1, ExposureDelta: -1, ProbabilityDelta: -1},
|
||||
Tags: []string{"crush_point", "gravity_risk", "speed_limit"},
|
||||
},
|
||||
// M601 — Trip-edge sensor under platform (safety bumper)
|
||||
{
|
||||
ID: "M601",
|
||||
ReductionType: "protection",
|
||||
SubType: "safety_device",
|
||||
Name: "Quetsch-Schaltleiste unterhalb der Hubplattform",
|
||||
Description: "Druckempfindliche Schaltleiste (gemaess EN ISO 13856-2) am unteren Rand der Hubplattform " +
|
||||
"loest bei Beruehrung den Hubantrieb sofort aus und kehrt die Bewegung um. Verhindert Quetschung " +
|
||||
"von Fuessen oder Beinen unter absenkender Last. PL c oder hoeher nach EN ISO 13849-1.",
|
||||
HazardCategory: "mechanical",
|
||||
Examples: []string{
|
||||
"Schaltleiste umlaufend an Bodenkante der Hubplattform",
|
||||
"Trittschutz mit redundanter Auswertung am Hubtisch",
|
||||
"Lichtgitter im Bodenbereich als Ergaenzung bei freistehenden Anlagen",
|
||||
},
|
||||
NormReferences: []string{
|
||||
"EN ISO 13856-2 (Schaltleisten)",
|
||||
"EN ISO 13849-1 (PL-Bestimmung)",
|
||||
"EN 1570-1",
|
||||
},
|
||||
RiskReduction: &RiskReduction{SeverityDelta: -2, ExposureDelta: -2, ProbabilityDelta: -2},
|
||||
Tags: []string{"crush_point", "gravity_risk", "safety_device"},
|
||||
},
|
||||
// M602 — Minimum clearance to fixed structure above max lift position
|
||||
{
|
||||
ID: "M602",
|
||||
ReductionType: "design",
|
||||
SubType: "geometry",
|
||||
Name: "Mindestabstand zu festen Strukturen oberhalb der Hubendlage",
|
||||
Description: "Zwischen hoechstem Punkt der Hubeinheit (mit beladenem Werkstueck) und festen Strukturen " +
|
||||
"oberhalb (Decke, Vorbau, Querbalken) muss ein Sicherheitsabstand verbleiben, der das Quetschen " +
|
||||
"von Haenden und Koerper verhindert. Empfehlung: 120 mm fuer Kopf, 100 mm fuer Hand, 25 mm fuer " +
|
||||
"Finger — abgeleitet aus EN 349 / EN ISO 13854 unabhaengig zu pruefen.",
|
||||
HazardCategory: "mechanical",
|
||||
Examples: []string{
|
||||
"Konstruktive Begrenzung der oberen Hubposition durch mechanischen Anschlag",
|
||||
"Software-Endlage mit redundantem Hardware-Sicherheitsschalter",
|
||||
"Auslegungs-Pruefung mit beladener Standard-Palette und Maximal-Hubhoehe",
|
||||
},
|
||||
NormReferences: []string{
|
||||
"EN 349 (Mindestabstaende gegen Quetschen von Koerperteilen)",
|
||||
"EN ISO 13854 (Mindestabstaende gegen Quetschen)",
|
||||
"OSHA 29 CFR 1910.212(a)(5) (Lueftergitter ≤ 1/2 in als Anker)",
|
||||
},
|
||||
RiskReduction: &RiskReduction{SeverityDelta: -2, ExposureDelta: -1},
|
||||
Tags: []string{"crush_point", "gravity_risk"},
|
||||
},
|
||||
// M603 — Hold-to-run with two-hand operation for manual descent
|
||||
{
|
||||
ID: "M603",
|
||||
ReductionType: "protection",
|
||||
SubType: "control_device",
|
||||
Name: "Tippbetrieb / Hold-to-run beim Absenken (mit Verifikations-Nachweis)",
|
||||
Description: "Absenken nur im Tippbetrieb (Hold-to-run): Bedientaster muss waehrend des gesamten " +
|
||||
"Absenkvorgangs gedrueckt gehalten werden. Bei Loslassen stoppt die Bewegung sofort. " +
|
||||
"Im Limits-Form als 'Tippbetrieb' deklariert — durch Tests verifizieren (Stop-Reaktionszeit " +
|
||||
"<= 0,3 s im voll beladenen Zustand).",
|
||||
HazardCategory: "mechanical",
|
||||
Examples: []string{
|
||||
"Tipptaster mit elektrischer Selbstrueckstellung",
|
||||
"Zweihand-Bedienung fuer kritische Absenk-Bereiche (Tipp + Zustimmtaster)",
|
||||
"Pruefprotokoll Stop-Zeit gemaess EN ISO 13849-1 PL c",
|
||||
},
|
||||
NormReferences: []string{
|
||||
"EN ISO 13849-1 (Sicherheitsbezogene Steuerungsteile)",
|
||||
"EN ISO 13851 (Zweihandschaltungen)",
|
||||
"BetrSichV § 4 (Schutzmassnahmen)",
|
||||
},
|
||||
RiskReduction: &RiskReduction{SeverityDelta: -1, ExposureDelta: -2, ProbabilityDelta: -1},
|
||||
Tags: []string{"crush_point", "gravity_risk", "control_device"},
|
||||
},
|
||||
// M604 — Underrun guard / kick plate at platform base
|
||||
{
|
||||
ID: "M604",
|
||||
ReductionType: "design",
|
||||
SubType: "geometry",
|
||||
Name: "Trittblech / Unterfahrschutz an der Hubplattform",
|
||||
Description: "Unter der Hubplattform befindet sich ein umlaufendes Trittblech oder Unterfahrschutz, " +
|
||||
"das das Hineinfahren von Fuessen unter die Plattform mechanisch verhindert. Hoehe ueber Boden " +
|
||||
"maximal 5 mm in unterster Stellung. Trittblech haelt die Last eines Schuhs (mind. 150 kg) " +
|
||||
"ohne Verformung.",
|
||||
HazardCategory: "mechanical",
|
||||
Examples: []string{
|
||||
"Umlaufendes Stahlblech 3 mm Wandstaerke mit Fasen-Kante",
|
||||
"Kombination mit M601 (Schaltleiste) als doppelte Sicherung",
|
||||
"Pruefung jaehrlich auf Verformung und Funktion der Auflage",
|
||||
},
|
||||
NormReferences: []string{
|
||||
"EN 1570-1 (Hubtische)",
|
||||
"EN ISO 13857 (Sicherheitsabstaende)",
|
||||
},
|
||||
RiskReduction: &RiskReduction{SeverityDelta: -2, ExposureDelta: -1},
|
||||
Tags: []string{"crush_point", "gravity_risk"},
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package iace
|
||||
|
||||
// Machine-type overrides for legacy patterns that lacked MachineTypes
|
||||
// filtering at authoring time. Applied as a post-load pass in
|
||||
// collectAllPatterns() so we do not need to touch the large pattern
|
||||
// source files (which would push them past the 500-LOC cap).
|
||||
//
|
||||
// Adding an entry here causes the listed pattern IDs to fire ONLY for
|
||||
// projects whose machine_type is in the value list. This eliminates
|
||||
// drift like "Punktschweisselektroden" firing for a Kistenhubgeraet
|
||||
// project just because tags incidentally aligned.
|
||||
|
||||
var legacyMachineTypeOverrides = map[string][]string{
|
||||
// Walzen / Roller hazards — printing, paper, metalworking only.
|
||||
"HP1000": {"printing", "paper", "textile", "metalworking", "rolling_mill", "food_processing"},
|
||||
// HP306 + HP1530 already carry MachineTypes; skip.
|
||||
|
||||
// Welding-specific patterns.
|
||||
"HP539": {"welding", "spot_welding"},
|
||||
|
||||
// Glass-handling tilters.
|
||||
"HP545": {"glass", "glass_processing"},
|
||||
"HP782": {"glass", "glass_processing"},
|
||||
|
||||
// Escalator-specific.
|
||||
"HP756": {"escalator"},
|
||||
"HP757": {"escalator"},
|
||||
"HP760": {"escalator"},
|
||||
|
||||
// CNC machine tools (these fired on Kistenhubgeraet because they
|
||||
// share crush_point + moving_part tags but are bench-mounted tools).
|
||||
"HP1400": {"cnc", "metalworking", "lathe", "milling"},
|
||||
"HP1401": {"cnc", "metalworking", "lathe", "milling"},
|
||||
"HP1402": {"cnc", "metalworking", "lathe", "milling"},
|
||||
|
||||
// Press-specific (Pressenteile/Pressraum/Werkzeugraum).
|
||||
"HP045": {"press", "hydraulic_press", "mechanical_press", "stamping_press"},
|
||||
"HP049": {"press", "hydraulic_press", "mechanical_press", "stamping_press"},
|
||||
|
||||
// Conveyor-belt-specific drift.
|
||||
"HP420": {"conveyor", "packaging", "food_processing"},
|
||||
"HP421": {"conveyor", "packaging", "food_processing"},
|
||||
"HP422": {"conveyor", "packaging", "food_processing"},
|
||||
}
|
||||
|
||||
// applyMachineTypeOverrides mutates the passed slice in place, setting
|
||||
// MachineTypes on any pattern whose ID is in the override map. Patterns
|
||||
// that already have MachineTypes set are NOT overwritten — the override
|
||||
// only fills the gap.
|
||||
func applyMachineTypeOverrides(patterns []HazardPattern) []HazardPattern {
|
||||
for i := range patterns {
|
||||
if len(patterns[i].MachineTypes) > 0 {
|
||||
continue
|
||||
}
|
||||
if mt, ok := legacyMachineTypeOverrides[patterns[i].ID]; ok {
|
||||
patterns[i].MachineTypes = mt
|
||||
}
|
||||
}
|
||||
return patterns
|
||||
}
|
||||
@@ -43,5 +43,7 @@ func collectAllPatterns() []HazardPattern {
|
||||
patterns = append(patterns, GetISO12100GapPatterns()...) // HP1900-HP1909 ISO 12100 Annex B gaps (Vakuum, Federn, Rutsch, Hochdruckinjektion, Ersticken)
|
||||
patterns = append(patterns, GetCRAPatterns()...) // HP1910-HP1918 CRA / DIN EN 40000-1-2 cyber-resilience spur
|
||||
patterns = append(patterns, GetSecondaryHarmDemoPatterns()...) // HP2000-HP2001 secondary harm chain demos (Cola splitter, Pharma)
|
||||
patterns = append(patterns, GetLiftEndstopPatterns()...) // HP2100-HP2102 lift body-part crush at endstops
|
||||
patterns = applyMachineTypeOverrides(patterns) // Fill MachineTypes on legacy patterns to prevent drift
|
||||
return patterns
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user