Files
breakpilot-compliance/ai-compliance-sdk/internal/iace/fmea_data_sources.go
T
Benjamin Admin de140e564e feat(iace): FMEA P1 — open methodology anchors + bp_iace_fmea_kb
P1 of the auto-FMEA build plan: establish the public-domain methodology
foundation (no AIAG-VDA/SAE/IEC tables reproduced).
- fmea_data_sources.go: MIL-STD-882E severity (Cat I-IV→1-10) + probability
  (A-F→1-10 with per-hour λ bands), OccurrenceFromRate(λp·α), SeverityForCategory,
  MIL-STD-1629A CriticalityCm = λp·α·β·t. Own 1-10 projection, government-anchored.
- 4 versioned source docs (MIL-STD-1629A, MIL-STD-882E, NASA RCM, FMD-91/NPRD-91)
  ingested into the new RAG collection bp_iace_fmea_kb (whitelisted).
- Tests for all scales/mappings/criticality (green).

Next (P1 step 2): fetch FMD-91/NPRD-91 bulk λ/α tables from DTIC.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-12 22:59:01 +02:00

100 lines
4.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package iace
// Open, public-domain methodology anchors for the auto-FMEA (P1 of the FMEA
// build plan). Every scale here is anchored on US-Government PUBLIC-DOMAIN
// sources — MIL-STD-882E (system-safety severity/probability) and MIL-STD-1629A
// (FMECA criticality). The 1-10 projection is BreakPilot's OWN scale; NO
// AIAG-VDA / SAE J1739 / IEC 60812 table is reproduced (those are copyrighted).
// Failure-rate (λ) and failure-mode-ratio (α) values come later from NPRD-91 /
// FMD-91 (RAC, public domain). See project_fmea_build_plan / opensource-fmea-sources.
// FMEADataSourcesNote is the audit/attribution line for the FMEA methodology.
const FMEADataSourcesNote = "FMEA-Methodik + Skalen verankert an US-Gov Public Domain " +
"(MIL-STD-1629A FMECA-Kritikalität, MIL-STD-882E Severity/Probability, NASA RCM). " +
"Ausfallraten/Mode-Verteilungen aus NPRD-91/FMD-91 (RAC, Public Domain). " +
"Das 1-10-Mapping ist BreakPilot-eigen; KEINE AIAG-VDA/SAE/IEC-Tabelle reproduziert."
// FMEASeverityBand maps a MIL-STD-882E Table-I severity CATEGORY to our 1-10 S.
type FMEASeverityBand struct {
Category string `json:"category"` // "I".."IV"
LabelDE string `json:"label_de"`
Desc string `json:"desc"` // public-domain threshold (injury/$)
Severity int `json:"severity"` // our 1-10 projection
}
// MILStd882Severity returns the four MIL-STD-882E severity categories, ordered
// most→least severe, with our 1-10 projection. (882E is US-Gov public domain.)
func MILStd882Severity() []FMEASeverityBand {
return []FMEASeverityBand{
{Category: "I", LabelDE: "Katastrophal", Desc: "Tod, dauerhafte Vollinvalidität oder irreversibler schwerer Umweltschaden", Severity: 10},
{Category: "II", LabelDE: "Kritisch", Desc: "Dauerhafte Teilinvalidität oder Krankenhausaufenthalt mehrerer Personen", Severity: 7},
{Category: "III", LabelDE: "Marginal", Desc: "Verletzung/Erkrankung mit Ausfalltag(en)", Severity: 4},
{Category: "IV", LabelDE: "Vernachlässigbar", Desc: "Geringfügige Verletzung ohne Ausfalltag", Severity: 2},
}
}
// FMEAOccurrenceBand maps a MIL-STD-882E Table-II probability LEVEL to our 1-10
// O. LambdaMax is the upper bound (failures per operating hour) we use to bin a
// computed mode rate; the per-hour calibration is ours, anchored on 882E order.
type FMEAOccurrenceBand struct {
Level string `json:"level"` // "A".."F"
LabelDE string `json:"label_de"`
LambdaMax float64 `json:"lambda_max"` // inclusive upper bound, /h (0 ⇒ eliminated)
Occurrence int `json:"occurrence"` // our 1-10 projection
}
// MILStd882Probability returns the six MIL-STD-882E probability levels (individual
// item), ordered most→least frequent, with our 1-10 projection + a per-hour
// failure-rate band used by OccurrenceFromRate.
func MILStd882Probability() []FMEAOccurrenceBand {
return []FMEAOccurrenceBand{
{Level: "A", LabelDE: "Häufig", LambdaMax: 1, Occurrence: 10}, // ≥ 1e-1
{Level: "B", LabelDE: "Wahrscheinlich", LambdaMax: 1e-1, Occurrence: 8}, // 1e-2 .. 1e-1
{Level: "C", LabelDE: "Gelegentlich", LambdaMax: 1e-2, Occurrence: 6}, // 1e-3 .. 1e-2
{Level: "D", LabelDE: "Selten", LambdaMax: 1e-3, Occurrence: 4}, // 1e-6 .. 1e-3
{Level: "E", LabelDE: "Unwahrscheinlich", LambdaMax: 1e-6, Occurrence: 2},
{Level: "F", LabelDE: "Ausgeschlossen", LambdaMax: 0, Occurrence: 1},
}
}
// OccurrenceFromRate maps a mode failure rate (λp·α, failures per operating hour)
// onto the 1-10 occurrence axis via the MIL-STD-882E probability bands. A rate
// ≤ 0 is "eliminated" (1); anything ≥ 0.1/h saturates at "frequent" (10).
func OccurrenceFromRate(modeRatePerHour float64) int {
if modeRatePerHour <= 0 {
return 1
}
bands := MILStd882Probability()
// bands[0] (A) has the highest threshold; walk most→least frequent and take
// the first band whose lower edge the rate clears.
for i := 0; i < len(bands)-1; i++ {
lowerEdge := bands[i+1].LambdaMax // edge between band i and i+1
if modeRatePerHour > lowerEdge {
return bands[i].Occurrence
}
}
return bands[len(bands)-2].Occurrence // E (improbable) for tiny positive rates
}
// SeverityForCategory returns our 1-10 severity for a MIL-STD-882E category
// ("I".."IV"); 0 if unknown.
func SeverityForCategory(category string) int {
for _, b := range MILStd882Severity() {
if b.Category == category {
return b.Severity
}
}
return 0
}
// CriticalityCm computes the MIL-STD-1629A modal criticality
// Cm = λp · α · β · t, where λp = part failure rate (/h), α = failure-mode ratio
// (fraction of part failures in this mode), β = conditional probability the mode
// produces the analysed effect, t = operating hours. Fully public-domain method.
func CriticalityCm(lambdaP, alpha, beta, operatingHours float64) float64 {
if lambdaP < 0 || alpha < 0 || beta < 0 || operatingHours < 0 {
return 0
}
return lambdaP * alpha * beta * operatingHours
}