feat(iace): Sprint 3A — Operational State Graph + fix(ucca) flaky keyword sort
State Graph: - 9 Standard-Betriebszustaende (startup, homing, automatic_operation, manual_operation, teach_mode, maintenance, cleaning, emergency_stop, recovery_mode) - 20 State-Transitions als gerichteter Graph - OperationalStates + StateTransitions Felder in HazardPattern, MatchInput, PatternMatch - patternMatches() filtert Patterns nach Betriebszustand (nil = feuert immer) - Narrative-Parser extrahiert States aus Maschinenbeschreibung (22 Keywords + 4 Transition-Keywords) - 27 bestehende Patterns mit State-Einschraenkungen annotiert (10 operational, 15 maintenance, 2 cobot) - MatchReason um operational_state + state_transition Typen erweitert (Explainability) - 6 neue Tests: NilFiresAlways, MaintenanceFilter, StateTransition, MatchReasons, Count, TransitionValid UCCA fix: - Stabiler Tiebreaker (Pattern-ID aufsteigend) bei gleichem Keyword-Score in MatchByKeywords - Behebt flaky TestControlPatternIndex_MatchByKeywords (1/10 Failure-Rate durch Go map iteration order) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -219,9 +219,14 @@ func (idx *ControlPatternIndex) MatchByKeywords(text string) []PatternMatch {
|
||||
})
|
||||
}
|
||||
|
||||
// Simple insertion sort (small N)
|
||||
// Sort by keyword hits descending, then by pattern ID ascending (stable tiebreaker)
|
||||
for i := 1; i < len(matches); i++ {
|
||||
for j := i; j > 0 && matches[j].KeywordHits > matches[j-1].KeywordHits; j-- {
|
||||
for j := i; j > 0; j-- {
|
||||
higher := matches[j].KeywordHits > matches[j-1].KeywordHits
|
||||
sameTie := matches[j].KeywordHits == matches[j-1].KeywordHits && matches[j].Pattern.ID < matches[j-1].Pattern.ID
|
||||
if !higher && !sameTie {
|
||||
break
|
||||
}
|
||||
matches[j], matches[j-1] = matches[j-1], matches[j]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user