From d892ad161f78fdc7c9fc18138a587790a0e28ad5 Mon Sep 17 00:00:00 2001 From: Benjamin Admin Date: Sun, 12 Apr 2026 23:04:35 +0200 Subject: [PATCH] feat: Domain-Fragen fuer 10 weitere Domains (24 von 39 total, 62%) 10 neue Context-Structs + Field-Resolver + 22 YAML-Regeln + Frontend: - Agriculture: Pestizid-KI, Tierwohl, Umweltdaten - Social Services: Schutzbeduerftiger, Leistungszuteilung, Fallmanagement - Hospitality: Gaeste-Profiling, dynamische Preise, Bewertungsmanipulation=BLOCK - Insurance: Praemien, Schadensautomation, Betrugserkennung - Investment: Algo-Trading, Robo Advisor (MiFID II) - Defense: Dual-Use, Exportkontrolle, Verschlusssachen - Supply Chain: Lieferantenueberwachung, Menschenrechte (LkSG) - Facility: Zutrittskontrolle, Belegung, Energie - Sports: Athleten-Tracking, Fan-Profiling Domains mit Fragen: 24 von 39 (62%) YAML-Regeln total: ~66 Neue BLOCKs: Bewertungsmanipulation (UWG/DSA) Co-Authored-By: Claude Opus 4.6 (1M context) --- .../app/sdk/advisory-board/page.tsx | 218 +++++++++++++++++- ai-compliance-sdk/internal/ucca/models.go | 73 ++++++ .../internal/ucca/policy_engine.go | 118 ++++++++++ .../policies/ucca_policy_v1.yaml | 160 +++++++++++++ 4 files changed, 568 insertions(+), 1 deletion(-) diff --git a/admin-compliance/app/sdk/advisory-board/page.tsx b/admin-compliance/app/sdk/advisory-board/page.tsx index 2f697ff..074a520 100644 --- a/admin-compliance/app/sdk/advisory-board/page.tsx +++ b/admin-compliance/app/sdk/advisory-board/page.tsx @@ -376,6 +376,24 @@ function AdvisoryBoardPageInner() { mkt_deepfake: false, mkt_minors: false, mkt_targeting: false, mkt_labeled: false, // Manufacturing mfg_machine_safety: false, mfg_ce_required: false, mfg_validated: false, + // Agriculture + agr_pesticide: false, agr_animal_welfare: false, agr_environmental: false, + // Social Services + soc_vulnerable: false, soc_benefit: false, soc_case_mgmt: false, + // Hospitality + hos_guest_profiling: false, hos_dynamic_pricing: false, hos_review_manipulation: false, + // Insurance + ins_risk_class: false, ins_claims: false, ins_premium: false, ins_fraud: false, + // Investment + inv_algo_trading: false, inv_advice: false, inv_robo: false, + // Defense + def_dual_use: false, def_export: false, def_classified: false, + // Supply Chain + sch_supplier: false, sch_human_rights: false, sch_environmental: false, + // Facility + fac_access: false, fac_occupancy: false, fac_energy: false, + // Sports + spo_athlete: false, spo_fan: false, spo_doping: false, // Hosting (single-select tile) hosting_provider: '' as string, hosting_region: '' as string, @@ -535,11 +553,56 @@ function AdvisoryBoardPageInner() { minors_targeted: form.mkt_minors, ai_content_labeled: form.mkt_labeled, } : undefined, - manufacturing_context: ['mechanical_engineering', 'electrical_engineering', 'plant_engineering', 'chemicals', 'food_beverage', 'textiles', 'packaging'].includes(form.domain) ? { + manufacturing_context: ['mechanical_engineering', 'electrical_engineering', 'plant_engineering', 'chemicals', 'food_beverage'].includes(form.domain) ? { machine_safety: form.mfg_machine_safety, ce_marking_required: form.mfg_ce_required, safety_validated: form.mfg_validated, } : undefined, + agriculture_context: ['agriculture', 'forestry', 'fishing'].includes(form.domain) ? { + pesticide_ai: form.agr_pesticide, + animal_welfare: form.agr_animal_welfare, + environmental_data: form.agr_environmental, + } : undefined, + social_services_context: ['social_services', 'nonprofit'].includes(form.domain) ? { + vulnerable_groups: form.soc_vulnerable, + benefit_decision: form.soc_benefit, + case_management: form.soc_case_mgmt, + } : undefined, + hospitality_context: ['hospitality', 'tourism'].includes(form.domain) ? { + guest_profiling: form.hos_guest_profiling, + dynamic_pricing: form.hos_dynamic_pricing, + review_manipulation: form.hos_review_manipulation, + } : undefined, + insurance_context: ['insurance'].includes(form.domain) ? { + risk_classification: form.ins_risk_class, + claims_automation: form.ins_claims, + premium_calculation: form.ins_premium, + fraud_detection: form.ins_fraud, + } : undefined, + investment_context: ['investment'].includes(form.domain) ? { + algo_trading: form.inv_algo_trading, + investment_advice: form.inv_advice, + robo_advisor: form.inv_robo, + } : undefined, + defense_context: ['defense'].includes(form.domain) ? { + dual_use: form.def_dual_use, + export_controlled: form.def_export, + classified_data: form.def_classified, + } : undefined, + supply_chain_context: ['textiles', 'packaging'].includes(form.domain) ? { + supplier_monitoring: form.sch_supplier, + human_rights_check: form.sch_human_rights, + environmental_impact: form.sch_environmental, + } : undefined, + facility_context: ['facility_management'].includes(form.domain) ? { + access_control_ai: form.fac_access, + occupancy_tracking: form.fac_occupancy, + energy_optimization: form.fac_energy, + } : undefined, + sports_context: ['sports'].includes(form.domain) ? { + athlete_tracking: form.spo_athlete, + fan_profiling: form.spo_fan, + } : undefined, store_raw_text: true, } @@ -1257,6 +1320,159 @@ function AdvisoryBoardPageInner() { )} + + {/* Agriculture */} + {['agriculture', 'forestry', 'fishing'].includes(form.domain) && ( +
+

Landwirtschaft — Compliance-Fragen

+
+ + + +
+
+ )} + + {/* Social Services */} + {['social_services', 'nonprofit'].includes(form.domain) && ( +
+

Soziales — Compliance-Fragen

+
+ + + +
+
+ )} + + {/* Hospitality / Tourism */} + {['hospitality', 'tourism'].includes(form.domain) && ( +
+

Tourismus & Gastronomie — Compliance-Fragen

+
+ + + +
+
+ )} + + {/* Insurance */} + {['insurance'].includes(form.domain) && ( +
+

Versicherung — Compliance-Fragen

+
+ + + +
+
+ )} + + {/* Investment */} + {['investment'].includes(form.domain) && ( +
+

Investment — Compliance-Fragen

+
+ + +
+
+ )} + + {/* Defense */} + {['defense'].includes(form.domain) && ( +
+

Verteidigung — Compliance-Fragen

+
+ + +
+
+ )} + + {/* Supply Chain (Textiles, Packaging) */} + {['textiles', 'packaging'].includes(form.domain) && ( +
+

Lieferkette — Compliance-Fragen

+

LkSG — Lieferkettensorgfaltspflichtengesetz.

+
+ + +
+
+ )} + + {/* Sports */} + {['sports'].includes(form.domain) && ( +
+

Sport — Compliance-Fragen

+
+ + +
+
+ )} )} diff --git a/ai-compliance-sdk/internal/ucca/models.go b/ai-compliance-sdk/internal/ucca/models.go index 208430d..7f588be 100644 --- a/ai-compliance-sdk/internal/ucca/models.go +++ b/ai-compliance-sdk/internal/ucca/models.go @@ -236,6 +236,15 @@ type UseCaseIntake struct { ConstructionContext *ConstructionContext `json:"construction_context,omitempty"` MarketingContext *MarketingContext `json:"marketing_context,omitempty"` ManufacturingContext *ManufacturingContext `json:"manufacturing_context,omitempty"` + AgricultureContext *AgricultureContext `json:"agriculture_context,omitempty"` + SocialServicesCtx *SocialServicesContext `json:"social_services_context,omitempty"` + HospitalityContext *HospitalityContext `json:"hospitality_context,omitempty"` + InsuranceContext *InsuranceContext `json:"insurance_context,omitempty"` + InvestmentContext *InvestmentContext `json:"investment_context,omitempty"` + DefenseContext *DefenseContext `json:"defense_context,omitempty"` + SupplyChainContext *SupplyChainContext `json:"supply_chain_context,omitempty"` + FacilityContext *FacilityContext `json:"facility_context,omitempty"` + SportsContext *SportsContext `json:"sports_context,omitempty"` // Opt-in to store raw text (otherwise only hash) StoreRawText bool `json:"store_raw_text,omitempty"` @@ -359,6 +368,70 @@ type ManufacturingContext struct { SafetyValidated bool `json:"safety_validated"` // Sicherheitsvalidierung durchgefuehrt } +// AgricultureContext captures agriculture/forestry compliance data +type AgricultureContext struct { + PesticideAI bool `json:"pesticide_ai"` // KI steuert Pestizideinsatz + AnimalWelfare bool `json:"animal_welfare"` // KI beeinflusst Tierhaltung + EnvironmentalData bool `json:"environmental_data"` // Umweltdaten verarbeitet +} + +// SocialServicesContext captures social services/nonprofit data +type SocialServicesContext struct { + VulnerableGroups bool `json:"vulnerable_groups"` // Schutzbeduerftiger Personenkreis + BenefitDecision bool `json:"benefit_decision"` // KI beeinflusst Leistungszuteilung + CaseManagement bool `json:"case_management"` // KI in Fallmanagement +} + +// HospitalityContext captures hospitality/tourism data +type HospitalityContext struct { + GuestProfiling bool `json:"guest_profiling"` // Gaeste-Profilbildung + DynamicPricing bool `json:"dynamic_pricing"` // Dynamische Preisgestaltung + ReviewManipulation bool `json:"review_manipulation"` // KI beeinflusst Bewertungen +} + +// InsuranceContext captures insurance-specific data (beyond FinancialContext) +type InsuranceContext struct { + RiskClassification bool `json:"risk_classification"` // KI klassifiziert Versicherungsrisiken + ClaimsAutomation bool `json:"claims_automation"` // Automatisierte Schadenbearbeitung + PremiumCalculation bool `json:"premium_calculation"` // KI berechnet Praemien individuell + FraudDetection bool `json:"fraud_detection"` // Betrugserkennung +} + +// InvestmentContext captures investment-specific data +type InvestmentContext struct { + AlgoTrading bool `json:"algo_trading"` // Algorithmischer Handel + InvestmentAdvice bool `json:"investment_advice"` // KI-gestuetzte Anlageberatung + RoboAdvisor bool `json:"robo_advisor"` // Automatisierte Vermoegensberatung +} + +// DefenseContext captures defense/dual-use data +type DefenseContext struct { + DualUse bool `json:"dual_use"` // Dual-Use Technologie + ExportControlled bool `json:"export_controlled"` // Exportkontrolle relevant + ClassifiedData bool `json:"classified_data"` // Verschlusssachen verarbeitet +} + +// SupplyChainContext captures textile/packaging/supply chain data (LkSG) +type SupplyChainContext struct { + SupplierMonitoring bool `json:"supplier_monitoring"` // KI ueberwacht Lieferanten + HumanRightsCheck bool `json:"human_rights_check"` // Menschenrechtspruefung in Lieferkette + EnvironmentalImpact bool `json:"environmental_impact"` // Umweltauswirkungen analysiert +} + +// FacilityContext captures facility management data +type FacilityContext struct { + AccessControlAI bool `json:"access_control_ai"` // KI-Zutrittskontrolle + OccupancyTracking bool `json:"occupancy_tracking"` // Belegungsueberwachung + EnergyOptimization bool `json:"energy_optimization"` // Energieoptimierung +} + +// SportsContext captures sports/general data +type SportsContext struct { + AthleteTracking bool `json:"athlete_tracking"` // Athleten-Performance-Tracking + FanProfiling bool `json:"fan_profiling"` // Fan-/Zuschauer-Profilbildung + DopingDetection bool `json:"doping_detection"` // KI in Doping-Kontrolle +} + // DataTypes specifies what kinds of data are processed type DataTypes struct { PersonalData bool `json:"personal_data"` diff --git a/ai-compliance-sdk/internal/ucca/policy_engine.go b/ai-compliance-sdk/internal/ucca/policy_engine.go index 5a0bb66..ca7d2f3 100644 --- a/ai-compliance-sdk/internal/ucca/policy_engine.go +++ b/ai-compliance-sdk/internal/ucca/policy_engine.go @@ -532,6 +532,33 @@ func (e *PolicyEngine) getFieldValue(field string, intake *UseCaseIntake) interf return nil } return e.getManufacturingContextValue(parts[1], intake) + case "agriculture_context": + if len(parts) < 2 || intake.AgricultureContext == nil { return nil } + return e.getAgricultureContextValue(parts[1], intake) + case "social_services_context": + if len(parts) < 2 || intake.SocialServicesCtx == nil { return nil } + return e.getSocialServicesContextValue(parts[1], intake) + case "hospitality_context": + if len(parts) < 2 || intake.HospitalityContext == nil { return nil } + return e.getHospitalityContextValue(parts[1], intake) + case "insurance_context": + if len(parts) < 2 || intake.InsuranceContext == nil { return nil } + return e.getInsuranceContextValue(parts[1], intake) + case "investment_context": + if len(parts) < 2 || intake.InvestmentContext == nil { return nil } + return e.getInvestmentContextValue(parts[1], intake) + case "defense_context": + if len(parts) < 2 || intake.DefenseContext == nil { return nil } + return e.getDefenseContextValue(parts[1], intake) + case "supply_chain_context": + if len(parts) < 2 || intake.SupplyChainContext == nil { return nil } + return e.getSupplyChainContextValue(parts[1], intake) + case "facility_context": + if len(parts) < 2 || intake.FacilityContext == nil { return nil } + return e.getFacilityContextValue(parts[1], intake) + case "sports_context": + if len(parts) < 2 || intake.SportsContext == nil { return nil } + return e.getSportsContextValue(parts[1], intake) } return nil @@ -719,6 +746,97 @@ func (e *PolicyEngine) getManufacturingContextValue(field string, intake *UseCas return nil } +func (e *PolicyEngine) getAgricultureContextValue(field string, intake *UseCaseIntake) interface{} { + if intake.AgricultureContext == nil { return nil } + switch field { + case "pesticide_ai": return intake.AgricultureContext.PesticideAI + case "animal_welfare": return intake.AgricultureContext.AnimalWelfare + case "environmental_data": return intake.AgricultureContext.EnvironmentalData + } + return nil +} + +func (e *PolicyEngine) getSocialServicesContextValue(field string, intake *UseCaseIntake) interface{} { + if intake.SocialServicesCtx == nil { return nil } + switch field { + case "vulnerable_groups": return intake.SocialServicesCtx.VulnerableGroups + case "benefit_decision": return intake.SocialServicesCtx.BenefitDecision + case "case_management": return intake.SocialServicesCtx.CaseManagement + } + return nil +} + +func (e *PolicyEngine) getHospitalityContextValue(field string, intake *UseCaseIntake) interface{} { + if intake.HospitalityContext == nil { return nil } + switch field { + case "guest_profiling": return intake.HospitalityContext.GuestProfiling + case "dynamic_pricing": return intake.HospitalityContext.DynamicPricing + case "review_manipulation": return intake.HospitalityContext.ReviewManipulation + } + return nil +} + +func (e *PolicyEngine) getInsuranceContextValue(field string, intake *UseCaseIntake) interface{} { + if intake.InsuranceContext == nil { return nil } + switch field { + case "risk_classification": return intake.InsuranceContext.RiskClassification + case "claims_automation": return intake.InsuranceContext.ClaimsAutomation + case "premium_calculation": return intake.InsuranceContext.PremiumCalculation + case "fraud_detection": return intake.InsuranceContext.FraudDetection + } + return nil +} + +func (e *PolicyEngine) getInvestmentContextValue(field string, intake *UseCaseIntake) interface{} { + if intake.InvestmentContext == nil { return nil } + switch field { + case "algo_trading": return intake.InvestmentContext.AlgoTrading + case "investment_advice": return intake.InvestmentContext.InvestmentAdvice + case "robo_advisor": return intake.InvestmentContext.RoboAdvisor + } + return nil +} + +func (e *PolicyEngine) getDefenseContextValue(field string, intake *UseCaseIntake) interface{} { + if intake.DefenseContext == nil { return nil } + switch field { + case "dual_use": return intake.DefenseContext.DualUse + case "export_controlled": return intake.DefenseContext.ExportControlled + case "classified_data": return intake.DefenseContext.ClassifiedData + } + return nil +} + +func (e *PolicyEngine) getSupplyChainContextValue(field string, intake *UseCaseIntake) interface{} { + if intake.SupplyChainContext == nil { return nil } + switch field { + case "supplier_monitoring": return intake.SupplyChainContext.SupplierMonitoring + case "human_rights_check": return intake.SupplyChainContext.HumanRightsCheck + case "environmental_impact": return intake.SupplyChainContext.EnvironmentalImpact + } + return nil +} + +func (e *PolicyEngine) getFacilityContextValue(field string, intake *UseCaseIntake) interface{} { + if intake.FacilityContext == nil { return nil } + switch field { + case "access_control_ai": return intake.FacilityContext.AccessControlAI + case "occupancy_tracking": return intake.FacilityContext.OccupancyTracking + case "energy_optimization": return intake.FacilityContext.EnergyOptimization + } + return nil +} + +func (e *PolicyEngine) getSportsContextValue(field string, intake *UseCaseIntake) interface{} { + if intake.SportsContext == nil { return nil } + switch field { + case "athlete_tracking": return intake.SportsContext.AthleteTracking + case "fan_profiling": return intake.SportsContext.FanProfiling + case "doping_detection": return intake.SportsContext.DopingDetection + } + return nil +} + func (e *PolicyEngine) getDataTypeValue(field string, intake *UseCaseIntake) interface{} { switch field { case "personal_data": diff --git a/ai-compliance-sdk/policies/ucca_policy_v1.yaml b/ai-compliance-sdk/policies/ucca_policy_v1.yaml index be53199..53cc675 100644 --- a/ai-compliance-sdk/policies/ucca_policy_v1.yaml +++ b/ai-compliance-sdk/policies/ucca_policy_v1.yaml @@ -1393,6 +1393,166 @@ rules: severity: WARN rationale: "CE-Kennzeichnung ist Pflicht fuer Maschinenprodukte mit KI" + # Agriculture + - id: R-AGR-001 + category: "K. Landwirtschaft" + title: "KI steuert Pestizideinsatz" + condition: { field: "agriculture_context.pesticide_ai", operator: "equals", value: true } + effect: { risk_add: 15 } + severity: WARN + rationale: "Umwelt- und Gesundheitsrisiken bei KI-gesteuertem Pflanzenschutz" + + - id: R-AGR-002 + category: "K. Landwirtschaft" + title: "KI beeinflusst Tierhaltung" + condition: { field: "agriculture_context.animal_welfare", operator: "equals", value: true } + effect: { risk_add: 10 } + severity: INFO + rationale: "Tierschutzrelevanz bei automatisierter Haltungsentscheidung" + + # Social Services + - id: R-SOC-001 + category: "K. Soziales" + title: "KI trifft Leistungsentscheidungen fuer schutzbeduerftiger Gruppen" + condition: + all_of: + - field: "social_services_context.vulnerable_groups" + operator: "equals" + value: true + - field: "social_services_context.benefit_decision" + operator: "equals" + value: true + effect: { risk_add: 25, dsfa_recommended: true, controls_add: [C_FRIA, C_HUMAN_OVERSIGHT] } + severity: WARN + rationale: "Leistungsentscheidungen fuer Schutzbeduerftiger erfordern FRIA" + + - id: R-SOC-002 + category: "K. Soziales" + title: "KI in Fallmanagement" + condition: { field: "social_services_context.case_management", operator: "equals", value: true } + effect: { risk_add: 15 } + severity: WARN + rationale: "Fallmanagement betrifft Grundrechte der Betroffenen" + + # Hospitality / Tourism + - id: R-HOS-001 + category: "K. Tourismus" + title: "Dynamische Preisgestaltung" + condition: { field: "hospitality_context.dynamic_pricing", operator: "equals", value: true } + effect: { risk_add: 10, controls_add: [C_TRANSPARENCY] } + severity: INFO + rationale: "Personalisierte Preise erfordern Transparenz" + + - id: R-HOS-002 + category: "K. Tourismus" + title: "KI manipuliert Bewertungen" + condition: { field: "hospitality_context.review_manipulation", operator: "equals", value: true } + effect: { risk_add: 20, feasibility: NO } + severity: BLOCK + rationale: "Bewertungsmanipulation verstoesst gegen UWG und DSA" + + # Insurance + - id: R-INS-001 + category: "K. Versicherung" + title: "KI-gestuetzte Praemienberechnung" + condition: { field: "insurance_context.premium_calculation", operator: "equals", value: true } + effect: { risk_add: 20, dsfa_recommended: true } + severity: WARN + rationale: "Individuelle Praemien koennen diskriminierend wirken (AGG, Annex III Nr. 5)" + + - id: R-INS-002 + category: "K. Versicherung" + title: "Automatisierte Schadenbearbeitung" + condition: { field: "insurance_context.claims_automation", operator: "equals", value: true } + effect: { risk_add: 15, art22_risk: true } + severity: WARN + rationale: "Automatische Schadensablehnung kann Art. 22 DSGVO ausloesen" + + # Investment + - id: R-INV-001 + category: "K. Investment" + title: "Algorithmischer Handel" + condition: { field: "investment_context.algo_trading", operator: "equals", value: true } + effect: { risk_add: 15 } + severity: WARN + rationale: "MiFID II Anforderungen an algorithmischen Handel" + + - id: R-INV-002 + category: "K. Investment" + title: "KI-gestuetzte Anlageberatung (Robo Advisor)" + condition: { field: "investment_context.robo_advisor", operator: "equals", value: true } + effect: { risk_add: 20, controls_add: [C_HUMAN_OVERSIGHT, C_TRANSPARENCY] } + severity: WARN + rationale: "Anlageberatung ist reguliert (WpHG, MiFID II) — Haftungsrisiko" + + # Defense + - id: R-DEF-001 + category: "K. Verteidigung" + title: "Dual-Use KI-Technologie" + condition: { field: "defense_context.dual_use", operator: "equals", value: true } + effect: { risk_add: 25 } + severity: WARN + rationale: "Dual-Use Technologie unterliegt Exportkontrolle (EU VO 2021/821)" + + - id: R-DEF-002 + category: "K. Verteidigung" + title: "Verschlusssachen in KI verarbeitet" + condition: { field: "defense_context.classified_data", operator: "equals", value: true } + effect: { risk_add: 20, controls_add: [C_ENCRYPTION] } + severity: WARN + rationale: "VS-NfD und hoeher erfordert besondere Schutzmassnahmen" + + # Supply Chain (LkSG) + - id: R-SCH-001 + category: "K. Lieferkette" + title: "KI-Menschenrechtspruefung in Lieferkette" + condition: { field: "supply_chain_context.human_rights_check", operator: "equals", value: true } + effect: { risk_add: 10 } + severity: INFO + rationale: "LkSG-relevante KI-Analyse — Bias bei Laenderrisiko-Bewertung beachten" + + - id: R-SCH-002 + category: "K. Lieferkette" + title: "KI ueberwacht Lieferanten" + condition: { field: "supply_chain_context.supplier_monitoring", operator: "equals", value: true } + effect: { risk_add: 10 } + severity: INFO + rationale: "Lieferantenbewertung durch KI kann indirekt Personen betreffen" + + # Facility Management + - id: R-FAC-001 + category: "K. Facility" + title: "KI-Zutrittskontrolle" + condition: { field: "facility_context.access_control_ai", operator: "equals", value: true } + effect: { risk_add: 15, dsfa_recommended: true } + severity: WARN + rationale: "Biometrische oder verhaltensbasierte Zutrittskontrolle ist DSGVO-relevant" + + - id: R-FAC-002 + category: "K. Facility" + title: "Belegungsueberwachung" + condition: { field: "facility_context.occupancy_tracking", operator: "equals", value: true } + effect: { risk_add: 10 } + severity: INFO + rationale: "Belegungsdaten koennen Rueckschluesse auf Verhalten erlauben" + + # Sports + - id: R-SPO-001 + category: "K. Sport" + title: "Athleten-Performance-Tracking" + condition: { field: "sports_context.athlete_tracking", operator: "equals", value: true } + effect: { risk_add: 15 } + severity: WARN + rationale: "Leistungsdaten von Athleten sind besonders schuetzenswert" + + - id: R-SPO-002 + category: "K. Sport" + title: "Fan-/Zuschauer-Profilbildung" + condition: { field: "sports_context.fan_profiling", operator: "equals", value: true } + effect: { risk_add: 15, dsfa_recommended: true } + severity: WARN + rationale: "Massen-Profiling bei Sportevents erfordert DSFA" + # --------------------------------------------------------------------------- # G. Aggregation & Ergebnis # ---------------------------------------------------------------------------