From 7b3a6f0dcd27a1cc3702fe6b7fb733dd7ff63cac Mon Sep 17 00:00:00 2001 From: Benjamin Admin Date: Tue, 9 Jun 2026 16:08:02 +0200 Subject: [PATCH] =?UTF-8?q?fix(iace):=20close=20domain-gate=20gaps=20?= =?UTF-8?q?=E2=80=94=20generic=20patterns=20with=20press/welding/glass=20t?= =?UTF-8?q?ext?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Observed on a real Kistenhubgeraet (lift) project: generic mechanical patterns (e.g. HP1000 "Quetschen Arm zwischen Pressenteilen") carry NO machine type and only generic tags (crush_point, rotating_part), so they fired for a lift; the narrow domain-gate terms missed their press/welding/glass wording. Broadens domainGateTerms (pressenteil, pressraum, blechbearbeitung, punktschweiss, schweisselektrod, elektrodenspalt) and adds a dom_glass domain (glasschneid/glasbearbeitung/...) with its emit keywords. New test pins that the four observed leakers now require a dom_* tag. Ghost=0, Leakage=0, coverage held on both GTs. Co-Authored-By: Claude Opus 4.7 --- .../internal/iace/keyword_dictionary.go | 1 + .../internal/iace/pattern_domain_gates.go | 8 +++- .../iace/pattern_domain_gates_test.go | 41 +++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 ai-compliance-sdk/internal/iace/pattern_domain_gates_test.go diff --git a/ai-compliance-sdk/internal/iace/keyword_dictionary.go b/ai-compliance-sdk/internal/iace/keyword_dictionary.go index 4a2b88b2..e9aaae1f 100644 --- a/ai-compliance-sdk/internal/iace/keyword_dictionary.go +++ b/ai-compliance-sdk/internal/iace/keyword_dictionary.go @@ -68,6 +68,7 @@ func GetKeywordDictionary() []KeywordEntry { {Keywords: []string{"drehmaschine", "fraesmaschine", "zerspanung"}, ExtraTags: []string{"dom_cnc"}}, {Keywords: []string{"maehdrescher", "ballenpresse", "feldhaecksler", "traktor"}, ExtraTags: []string{"dom_agri"}}, {Keywords: []string{"rolltreppe", "fahrtreppe", "fahrsteig"}, ExtraTags: []string{"dom_escalator"}}, + {Keywords: []string{"glasschneid", "glasbearbeitung", "flachglas", "glasscheibe", "glaskante", "glasmaschine"}, ExtraTags: []string{"dom_glass"}}, // Ghost-Closure (Emit-Seite): macht die 34 toten Required-Tags // emittierbar, jeweils NUR via domaenenspezifische Keywords -> die 120 // Ghost-Patterns feuern wieder, aber nur fuer ihre echte Maschine (kein diff --git a/ai-compliance-sdk/internal/iace/pattern_domain_gates.go b/ai-compliance-sdk/internal/iace/pattern_domain_gates.go index 03adac36..d5492088 100644 --- a/ai-compliance-sdk/internal/iace/pattern_domain_gates.go +++ b/ai-compliance-sdk/internal/iace/pattern_domain_gates.go @@ -27,6 +27,11 @@ var domainGateTerms = map[string]string{ "stanzhub": "dom_press", "pressenhub": "dom_press", "pressenstoessel": "dom_press", "dauerhub": "dom_press", "exzenterpresse": "dom_press", "beinpresse": "dom_press", "stanzpresse": "dom_press", "umformpresse": "dom_press", + "pressenteil": "dom_press", "pressraum": "dom_press", "blechbearbeitung": "dom_press", + "werkzeugraum der presse": "dom_press", + // Glas-Bearbeitung + "glasschneid": "dom_glass", "glasbearbeitung": "dom_glass", "glasscheibe": "dom_glass", + "glaskante": "dom_glass", // Kunststoff / Spritzguss / Extrusion "spritzgie": "dom_plastics", "extruder": "dom_plastics", "extrusion": "dom_plastics", "kunststoffschmelze": "dom_plastics", "schliesseinheit": "dom_plastics", @@ -39,7 +44,8 @@ var domainGateTerms = map[string]string{ "schleifscheibe": "dom_grinding", "schleifbock": "dom_grinding", // Schweissen "widerstandsschweiss": "dom_welding", "lichtbogenschweiss": "dom_welding", - "schutzgasschweiss": "dom_welding", + "schutzgasschweiss": "dom_welding", "punktschweiss": "dom_welding", + "schweisselektrod": "dom_welding", "elektrodenspalt": "dom_welding", // Solar / PV "pv-modul": "dom_solar", "photovoltaik": "dom_solar", "pv-anlage": "dom_solar", "dc-steckverbindung": "dom_solar", "solarmodul": "dom_solar", diff --git a/ai-compliance-sdk/internal/iace/pattern_domain_gates_test.go b/ai-compliance-sdk/internal/iace/pattern_domain_gates_test.go new file mode 100644 index 00000000..63800a17 --- /dev/null +++ b/ai-compliance-sdk/internal/iace/pattern_domain_gates_test.go @@ -0,0 +1,41 @@ +package iace + +import ( + "strings" + "testing" +) + +// TestDomainGate_NamedLeakersGated pins the concrete cross-domain leakers that +// were observed firing for a Kistenhubgeraet (lift) project: generic patterns +// whose text names a press/welding/glass machine but which carry no machine +// type and only generic tags. After applyDomainGates they MUST require a dom_* +// tag, so they no longer fire for unrelated machines. +func TestDomainGate_NamedLeakersGated(t *testing.T) { + leakers := []string{ + "Quetschen Arm zwischen Pressenteilen", + "Quetschen durch Punktschweisselektroden", + "Laerm bei Glasschneidemaschine", + "Laerm bei Blechbearbeitung (Stanzen)", + } + byName := map[string]HazardPattern{} + for _, p := range collectAllPatterns() { + byName[p.NameDE] = p + } + for _, n := range leakers { + p, ok := byName[n] + if !ok { + t.Errorf("leaker pattern %q not found in library", n) + continue + } + hasDom := false + for _, tag := range p.RequiredComponentTags { + if strings.HasPrefix(tag, "dom_") { + hasDom = true + break + } + } + if !hasDom { + t.Errorf("%s (%q) not domain-gated; RequiredComponentTags=%v", p.ID, n, p.RequiredComponentTags) + } + } +}