fix(iace): rename 58 duplicate HP-IDs in extended.go/extended2.go
Background: hazard_patterns_extended.go (HP045-074) and _extended2.go (HP074-102) shared their entire ID range with the semantically-different patterns in hazard_patterns_cobot.go, hazard_patterns_press.go, hazard_patterns_operational.go and hazard_patterns_extended_dguv.go. The collision had lived unnoticed because TestGetBuiltinHazardPatterns_- UniqueIDs only checks the 44 builtin patterns (HP001-HP044). Examples of the collision: - HP059 = "Kollision Mensch-Roboter" (cobot.go) vs "Kupplung — mechanisch" (extended.go) - HP060 = "Quetschen durch Werkzeug am Cobot" (cobot.go) vs "Diagnosemodul — Software" (extended.go) - HP073 = "Wartung ohne LOTO" (operational.go) vs "Hydraulikventil — hydraulisch" (extended.go) At runtime collectAllPatterns() returned both patterns under the same ID which made downstream lookups (e.g. hazardPatternMeasures map keyed by pattern_id) non-deterministic — last-loaded wins, dropping the other pattern's mitigation set silently. Rename strategy (no deletes — both patterns are real and earn their SuggestedMeasureIDs after the category-filter work): extended.go HP045..HP073 -> HP1800..HP1828 (29 IDs) extended2.go HP074..HP102 -> HP1830..HP1858 (29 IDs) cobot/press/operational/extended_dguv keep their original IDs because: - compliance_triggers.go references HP059/HP060 with the cobot meaning - pattern_engine_test.go references HP073 with the LOTO/maintenance meaning - phase3_4_test.go references HP073 the same way New regression test: - TestAllPatterns_UniqueIDs runs over collectAllPatterns() and fails if ANY pattern in the runtime set duplicates an ID. The old TestGetBuiltinHazardPatterns_UniqueIDs stays for the builtin subset. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -113,6 +113,40 @@ func TestEveryPattern_HasCategoryCompatibleMeasure(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestAllPatterns_UniqueIDs pins that collectAllPatterns() — i.e. every
|
||||
// pattern that the engine actually sees at runtime — has globally unique
|
||||
// HP-IDs. The older TestGetBuiltinHazardPatterns_UniqueIDs only checks the
|
||||
// 44 builtin ones and missed 58 duplicates between extended.go/extended2.go
|
||||
// and cobot/press/operational/extended_dguv.go that lived undetected for
|
||||
// months (a hazard with the same HP-ID but different scenario would silently
|
||||
// shadow its sibling in the persistence layer).
|
||||
func TestAllPatterns_UniqueIDs(t *testing.T) {
|
||||
seen := map[string]string{} // HP-ID -> first NameDE
|
||||
dups := []string{}
|
||||
for _, p := range collectAllPatterns() {
|
||||
if p.ID == "" {
|
||||
t.Errorf("pattern with empty ID: %s", p.NameDE)
|
||||
continue
|
||||
}
|
||||
if prev, ok := seen[p.ID]; ok {
|
||||
dups = append(dups, p.ID+" ("+prev+" vs "+p.NameDE+")")
|
||||
continue
|
||||
}
|
||||
seen[p.ID] = p.NameDE
|
||||
}
|
||||
if len(dups) > 0 {
|
||||
t.Errorf("%d duplicate HP-IDs across all pattern sources:", len(dups))
|
||||
const maxList = 20
|
||||
for i, d := range dups {
|
||||
if i >= maxList {
|
||||
t.Errorf(" ... and %d more", len(dups)-maxList)
|
||||
break
|
||||
}
|
||||
t.Errorf(" - %s", d)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func joinCats(cats []string) string {
|
||||
out := ""
|
||||
for i, c := range cats {
|
||||
|
||||
Reference in New Issue
Block a user