16fd406c1a
Task #17 — Folgegefahren-Modell as Vorbereitungs-Commit (no DB schema change yet; persistence via separate [migration-approved] commit). New: - secondary_harms.go: SecondaryHarm struct + six canonical categories (consumer_safety, product_liability, food_safety, environmental, reputation, financial) with DE labels. - hazard_pattern_types.go: HazardPattern extended with optional SecondaryHarms field — pattern library can now attach consequential- damage chains. - hazard_patterns_secondary_demo.go: two worked examples - HP2000 Glasbruch carbonated bottling (the "Cola splitter" scenario from the IACE strategy discussion) with consumer_safety + food_safety + reputation chains - HP2001 Pharma fill-finish cross-contamination with consumer_safety + product_liability under AMG §84 Bonus fix: - compliance_crossover.go AllPatterns() was a duplicate enumeration that silently drifted from collectAllPatterns() in pattern_registry.go. Pre-fix: 1058 patterns visible. Post-fix: 1213 patterns. The 155 invisible patterns included CRA, ISO12100 gaps, robot-cell, CNC extended, VDMA, textile-agri, GT-bremse — anything added after the original AllPatterns was authored. Audit-Suite (cmd/iace-audit) now sees the full set. Next steps for full secondary-harm rollout: - DB migration: hazards table + secondary_harms array column - API: surface secondary_harms in /projects/:id/hazards response - Frontend: collapsible Folgegefahren-Panel in HazardTable
90 lines
3.5 KiB
Go
90 lines
3.5 KiB
Go
package iace
|
|
|
|
// SecondaryHarm models the consequential damage chain triggered by a primary
|
|
// hazard. The classical IACE / ISO-12100 model treats Hazard -> Harm as a
|
|
// single step ("operator gets crushed"). BreakPilot extends this with a
|
|
// follow-on chain so the risk assessment can address:
|
|
//
|
|
// - consumer_safety: end customer exposed to defective product
|
|
// (e.g. glass shards in a bottled drink that reaches a supermarket)
|
|
// - product_liability: manufacturer liability under ProdHaftG / EU PLD
|
|
// - food_safety: traceability and recall obligations (VO 178/2002)
|
|
// - environmental: spill, contamination, waste-disposal consequence
|
|
// - reputation: brand damage that escalates to investor / market level
|
|
// - financial: direct cost (lawsuit, recall, fine)
|
|
//
|
|
// This struct is the data contract; persistence is deferred to a future
|
|
// migration. The pattern library can already attach SecondaryHarms to a
|
|
// HazardPattern; the API layer surfaces them on hazard generation.
|
|
//
|
|
// See memory project_attribution_strategy.md plus the "Cola splitter" worked
|
|
// example from the IACE strategy discussion (2026-05-20).
|
|
type SecondaryHarm struct {
|
|
// Type is one of the SecondaryHarmType* constants below.
|
|
Type string `json:"type"`
|
|
|
|
// Description is a single sentence describing the secondary harm
|
|
// scenario in concrete terms ("Splitter in Folgeflasche bei
|
|
// Karussell-Abfueller -> Endkunde verletzt").
|
|
Description string `json:"description"`
|
|
|
|
// LegalBasis cites the legal framework that turns the secondary harm
|
|
// into an actionable obligation (e.g. "ProdHaftG §1" or "VO 178/2002
|
|
// Art. 14"). Helps auditors trace the obligation.
|
|
LegalBasis string `json:"legal_basis,omitempty"`
|
|
|
|
// SuggestedMitigations is a free-text list of measures specific to
|
|
// the secondary chain (e.g. "Spueltunnel", "Inline-Kamera",
|
|
// "Glasbruchsensor"). Distinct from the primary-mitigations because
|
|
// they protect downstream stakeholders, not the operator.
|
|
SuggestedMitigations []string `json:"suggested_mitigations,omitempty"`
|
|
|
|
// Owner identifies the role responsible for handling this secondary
|
|
// harm in the customer organisation. Common values:
|
|
// "qm" / "product_safety" / "enterprise_risk" / "legal"
|
|
// Empty if responsibility is shared.
|
|
Owner string `json:"owner,omitempty"`
|
|
}
|
|
|
|
// SecondaryHarmType constants — kept short and stable.
|
|
const (
|
|
SecondaryHarmConsumerSafety = "consumer_safety"
|
|
SecondaryHarmProductLiability = "product_liability"
|
|
SecondaryHarmFoodSafety = "food_safety"
|
|
SecondaryHarmEnvironmental = "environmental"
|
|
SecondaryHarmReputation = "reputation"
|
|
SecondaryHarmFinancial = "financial"
|
|
)
|
|
|
|
// AllSecondaryHarmTypes returns the canonical six categories in the order
|
|
// they should appear in UI dropdowns.
|
|
func AllSecondaryHarmTypes() []string {
|
|
return []string{
|
|
SecondaryHarmConsumerSafety,
|
|
SecondaryHarmProductLiability,
|
|
SecondaryHarmFoodSafety,
|
|
SecondaryHarmEnvironmental,
|
|
SecondaryHarmReputation,
|
|
SecondaryHarmFinancial,
|
|
}
|
|
}
|
|
|
|
// SecondaryHarmLabelDE returns the human-readable German label.
|
|
func SecondaryHarmLabelDE(t string) string {
|
|
switch t {
|
|
case SecondaryHarmConsumerSafety:
|
|
return "Endkundensicherheit"
|
|
case SecondaryHarmProductLiability:
|
|
return "Produkthaftung"
|
|
case SecondaryHarmFoodSafety:
|
|
return "Lebensmittelsicherheit"
|
|
case SecondaryHarmEnvironmental:
|
|
return "Umweltschaden"
|
|
case SecondaryHarmReputation:
|
|
return "Reputation/Marke"
|
|
case SecondaryHarmFinancial:
|
|
return "Finanzieller Schaden"
|
|
}
|
|
return t
|
|
}
|