From a8c61eb320c81c168e2e0e02a28804373589ab33 Mon Sep 17 00:00:00 2001 From: Benjamin Admin Date: Thu, 25 Jun 2026 01:35:14 +0200 Subject: [PATCH] fix(ai-sdk): warewashing-scoped supersession of generic thermal duplicates The generic hot-surface patterns HP016 (high_temperature) and HP018 (actuator burn) fire for dishwashers via broad tags and duplicate the precise warewashing pattern HP2201 (Boiler/Tank/Spuelkammer). Suppress HP016/HP018 only when dom_warewashing is present, so the specific pattern wins and the duplicate is dropped. Scoped to the domain tag -> Kistenhub/Bremse and every non-warewashing machine keep the generic patterns unchanged. Warewashing recall stays 100% (25/25), precision 90% -> 92.6% (2 dupes removed). Bremse 26 pins and Kistenhub benchmark unaffected. Co-Authored-By: Claude Opus 4.7 --- .../internal/iace/pattern_enclosure.go | 21 +++++++++++++++++++ .../internal/iace/pattern_engine.go | 5 +++++ 2 files changed, 26 insertions(+) diff --git a/ai-compliance-sdk/internal/iace/pattern_enclosure.go b/ai-compliance-sdk/internal/iace/pattern_enclosure.go index a10cdf0e..343db431 100644 --- a/ai-compliance-sdk/internal/iace/pattern_enclosure.go +++ b/ai-compliance-sdk/internal/iace/pattern_enclosure.go @@ -42,3 +42,24 @@ func guardedLifecycles(p HazardPattern, tagSet map[string]bool) []string { } return p.ApplicableLifecycles } + +// Domain-specific supersession. +// +// A generic pattern that fires via a broad tag (e.g. high_temperature) can +// duplicate a domain-specific pattern that describes the same hazard more +// precisely. When the domain is present, the specific pattern wins and the +// generic duplicate is dropped. Scoped to the domain tag, so machines outside +// the domain keep the generic pattern — regression-safe by construction. +// +// HP016 (generic hot surfaces) -> HP2201 (Boiler/Tank/Spuelkammer) +// HP018 (actuator burn) -> HP2201 (same contact-burn hazard) +var genericSupersededByWarewashing = map[string]bool{ + "HP016": true, + "HP018": true, +} + +// supersededByDomainSpecific reports whether a generic pattern is replaced by a +// more precise equivalent that the project's domain already provides. +func supersededByDomainSpecific(p HazardPattern, tagSet map[string]bool) bool { + return tagSet["dom_warewashing"] && genericSupersededByWarewashing[p.ID] +} diff --git a/ai-compliance-sdk/internal/iace/pattern_engine.go b/ai-compliance-sdk/internal/iace/pattern_engine.go index cc37a560..3aacfc2d 100644 --- a/ai-compliance-sdk/internal/iace/pattern_engine.go +++ b/ai-compliance-sdk/internal/iace/pattern_engine.go @@ -416,6 +416,11 @@ func patternMatches(p HazardPattern, tagSet map[string]bool, input MatchInput) b return false } + // Domain-specific supersession (generic duplicate replaced by a precise one). + if supersededByDomainSpecific(p, tagSet) { + return false + } + return true }