f534b52817
Add cmd/iace-audit CLI with 5 deterministic methods that find engine gaps without ground truth: - A reachability: 1058 patterns vs achievable tag universe - B consistency: components vs their declared hazard categories - C vocabulary: limits-form tokens vs keyword dictionary - D echo: limits-form sentences vs generated hazards (jaccard) - E hierarchy: hazards vs ISO 12100 design/protection/info levels Library fixes triggered by A+B+C findings: - tag_resolver: synonym map for electrical/pneumatic/hydraulic aliases - component_library: crush_point + EN03 (gravitational) on C014/C128 (Hubwerk family) - fixes HP1014/1015/1017/1018 which were silently weakly_reachable. noise_source added on 7 components (C006/C011/ C017/C020/C031/C041/C096). electrical_part on 8 drive components (C031/C032/C033/C034/C035/C036/C037/C038/C077/C092). cyber tag on 10 sensors (C081-C090) + 3 IT components (C111/C112/C116) + KI module C119 (ai_model added). pneumatic_part+hydraulic_part on valves C091/C093, hydraulic_part+chemical_risk on pump C097, moving_part on motion controller C075 - keyword_dictionary: EN03 added to aufzug/lift/hubwerk/hubgeraet (was wrongly EN04-only). New keyword entries for hub-action verbs: absenken/senken/anheben/heben + hubhoehe/hubweg/hubgeschwindig Audit impact: - A: weakly_reachable 409 -> 358 (-51 patterns now fully reachable) - B: incomplete components 46 -> 30 (-16, -33%) - HP1018 (Person unter absenkendem Maschinenteil eingeklemmt): weakly_reachable -> reachable Why: methods A/B/C surfaced that the Kistenhubgeraet test project generated 0 crush-under-load hazards despite OSHA 1910.212(a)(3) + EN ISO 12100 6.3.5.5 explicitly requiring them. Three orthogonal bugs (missing crush_point tag, wrong energy source mapping, missing action verbs in dictionary) silently disabled the entire lift crush pattern family.
85 lines
3.3 KiB
Go
85 lines
3.3 KiB
Go
package audit
|
|
|
|
// Stubs for Methods B-E. Each is filled in its own file as the audit
|
|
// suite grows. Keeping the type contracts here lets the CLI compile
|
|
// before each method has its full implementation.
|
|
|
|
// ============================================================================
|
|
// Method B — Component Self-Consistency
|
|
// ============================================================================
|
|
|
|
type CategoryGap struct {
|
|
Category string `json:"category"`
|
|
SuggestedTags []string `json:"suggested_tags"`
|
|
}
|
|
|
|
type ComponentResult struct {
|
|
ComponentID string `json:"component_id"`
|
|
NameDE string `json:"name_de"`
|
|
DeclaredCategories []string `json:"declared_categories"`
|
|
CoveredCategories []string `json:"covered_categories"`
|
|
MissingForCategories []CategoryGap `json:"missing_for_categories,omitempty"`
|
|
}
|
|
|
|
type ConsistencyReport struct {
|
|
TotalComponents int `json:"total_components"`
|
|
Consistent int `json:"consistent"`
|
|
Incomplete int `json:"incomplete"`
|
|
IncompleteComponents []ComponentResult `json:"incomplete_components"`
|
|
}
|
|
|
|
// ============================================================================
|
|
// Method C — Limits-Form Vocabulary Diff
|
|
// ============================================================================
|
|
|
|
type DictionarySuggestion struct {
|
|
Token string `json:"token"`
|
|
Field string `json:"field"`
|
|
PatternIDs []string `json:"pattern_ids"`
|
|
}
|
|
|
|
type VocabularyReport struct {
|
|
UniqueTokens int `json:"unique_tokens"`
|
|
KnownTokens []string `json:"known_tokens"`
|
|
UnknownTokens []string `json:"unknown_tokens"`
|
|
SuggestedDictionaryEntries []DictionarySuggestion `json:"suggested_dictionary_entries"`
|
|
}
|
|
|
|
// ============================================================================
|
|
// Method D — Limits-Form Echo
|
|
// ============================================================================
|
|
|
|
type OrphanedPhrase struct {
|
|
Field string `json:"field"`
|
|
Phrase string `json:"phrase"`
|
|
BestScore float64 `json:"best_score"`
|
|
}
|
|
|
|
type EchoReport struct {
|
|
TotalPhrases int `json:"total_phrases"`
|
|
Echoed int `json:"echoed"`
|
|
Orphaned int `json:"orphaned"`
|
|
OrphanedPhrases []OrphanedPhrase `json:"orphaned_phrases"`
|
|
}
|
|
|
|
// ============================================================================
|
|
// Method E — Hierarchy Completeness
|
|
// ============================================================================
|
|
|
|
type HazardHierarchyResult struct {
|
|
HazardID string `json:"hazard_id"`
|
|
Name string `json:"name"`
|
|
Category string `json:"category"`
|
|
Levels []string `json:"present_levels"`
|
|
MissingLevels []string `json:"missing_levels"`
|
|
}
|
|
|
|
type HierarchyReport struct {
|
|
TotalHazards int `json:"total_hazards"`
|
|
Complete int `json:"complete"`
|
|
MissingDesign int `json:"missing_design"`
|
|
MissingProtection int `json:"missing_protection"`
|
|
MissingInfo int `json:"missing_information"`
|
|
IncompleteHazards []HazardHierarchyResult `json:"incomplete_hazards"`
|
|
}
|