feat(iace): de-bias severity estimate; risk ranking 57%->69% vs Fachmann
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / secret-scan (push) Has been skipped
CI / dep-audit (push) Has been skipped
CI / detect-changes (push) Successful in 8s
CI / sbom-scan (push) Has been skipped
CI / build-sha-integrity (push) Failing after 4s
CI / validate-canonical-controls (push) Successful in 11s
CI / loc-budget (push) Successful in 15s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / nodejs-build (push) Has been skipped
CI / test-go (push) Failing after 44s
CI / iace-gt-coverage (push) Successful in 22s
CI / test-python-backend (push) Has been skipped
CI / test-python-document-crawler (push) Has been skipped
CI / test-python-dsms-gateway (push) Has been skipped

The engine's hand-set DefaultSeverity systematically over-estimates severity
(GT shows crushing 3.3 vs 2.2, struck_by 3.1 vs 2.5; electrical was already
close). EstimateSeverity blends the pattern default 50/50 with the contact
mode's GT-calibrated typical severity (baseS) — keeps pattern-specific signal,
removes the bias. Our own model, no norm table.

Effect across both GTs: severity within +-1 78%->88%; risk RANK concordance
57%->69% (Kistenhub 45%->70%). Wired into iace_handler_init.go so the
BreakPilot risk line uses the de-biased severity.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-06-09 13:52:19 +02:00
parent bc78ddd3e5
commit a910793d12
3 changed files with 78 additions and 35 deletions
@@ -225,11 +225,12 @@ func (h *IACEHandler) InitializeProject(c *gin.Context) {
// (see iace/risk_estimation.go + DATA_SOURCES.md). No EN ISO
// 13849-1 risk-graph table or parameter binning is reproduced.
if mp.DefaultSeverity > 0 && mp.DefaultExposure > 0 {
s := iace.EstimateSeverity(mp.HazardCats, mp.ScenarioDE, mp.DefaultSeverity)
w := iace.EstimateProbabilityW(mp.HazardCats, mp.ScenarioDE)
p := iace.EstimateAvoidabilityP(mp.HazardCats, mp.ScenarioDE)
_, level := iace.EstimateRiskLevel(mp.DefaultSeverity, mp.DefaultExposure, w, p)
_, level := iace.EstimateRiskLevel(s, mp.DefaultExposure, w, p)
desc += fmt.Sprintf("\n\nRisikoeinschaetzung (BreakPilot-Modell): S%d · F%d · W%d · P%d → Risiko: %s",
mp.DefaultSeverity, mp.DefaultExposure, w, p, level)
s, mp.DefaultExposure, w, p, level)
}
if mp.ISO12100Section != "" {
desc += "\n\nKlassifikation: EN ISO 12100 Abschnitt " + mp.ISO12100Section