Files
breakpilot-compliance/ai-compliance-sdk/internal/ucca/rules.go
Benjamin Boenisch 4435e7ea0a Initial commit: breakpilot-compliance - Compliance SDK Platform
Services: Admin-Compliance, Backend-Compliance,
AI-Compliance-SDK, Consent-SDK, Developer-Portal,
PCA-Platform, DSMS

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 23:47:28 +01:00

1232 lines
46 KiB
Go

package ucca
import (
"fmt"
"strings"
)
// ============================================================================
// Rule Engine - Deterministic rule evaluation
// ============================================================================
// Rule represents a single evaluation rule
type Rule struct {
Code string
Category string
Title string
TitleDE string
Description string
DescriptionDE string
Severity Severity
ScoreDelta int // Points added to risk score
GDPRRef string // GDPR article reference
Controls []string // Required control IDs
Patterns []string // Recommended pattern IDs
Condition func(intake *UseCaseIntake) bool
Rationale func(intake *UseCaseIntake) string
}
// RuleEngine holds all rules and performs evaluation
type RuleEngine struct {
rules []Rule
}
// NewRuleEngine creates a new rule engine with all rules
func NewRuleEngine() *RuleEngine {
return &RuleEngine{
rules: AllRules,
}
}
// Evaluate runs all rules against the intake and returns the assessment result
func (e *RuleEngine) Evaluate(intake *UseCaseIntake) *AssessmentResult {
result := &AssessmentResult{
Feasibility: FeasibilityYES,
RiskLevel: RiskLevelMINIMAL,
Complexity: ComplexityLOW,
RiskScore: 0,
TriggeredRules: []TriggeredRule{},
RequiredControls: []RequiredControl{},
RecommendedArchitecture: []PatternRecommendation{},
ForbiddenPatterns: []ForbiddenPattern{},
ExampleMatches: []ExampleMatch{},
DSFARecommended: false,
Art22Risk: false,
TrainingAllowed: TrainingYES,
}
// Track triggered severities
hasBlock := false
hasWarn := false
controlMap := make(map[string]bool)
patternMap := make(map[string]int) // pattern -> priority
// Evaluate each rule
for _, rule := range e.rules {
if rule.Condition(intake) {
// Add triggered rule
triggered := TriggeredRule{
Code: rule.Code,
Category: rule.Category,
Title: rule.TitleDE,
Description: rule.DescriptionDE,
Severity: rule.Severity,
ScoreDelta: rule.ScoreDelta,
GDPRRef: rule.GDPRRef,
Rationale: rule.Rationale(intake),
}
result.TriggeredRules = append(result.TriggeredRules, triggered)
// Update risk score
result.RiskScore += rule.ScoreDelta
// Track severity
switch rule.Severity {
case SeverityBLOCK:
hasBlock = true
case SeverityWARN:
hasWarn = true
}
// Collect required controls
for _, controlID := range rule.Controls {
if !controlMap[controlID] {
controlMap[controlID] = true
if ctrl := GetControlByID(controlID); ctrl != nil {
result.RequiredControls = append(result.RequiredControls, *ctrl)
}
}
}
// Collect recommended patterns
for i, patternID := range rule.Patterns {
if _, exists := patternMap[patternID]; !exists {
patternMap[patternID] = i + 1 // priority
}
}
}
}
// Determine feasibility based on aggregation rules (R-090 to R-092)
if hasBlock {
result.Feasibility = FeasibilityNO
} else if hasWarn {
result.Feasibility = FeasibilityCONDITIONAL
} else {
result.Feasibility = FeasibilityYES
}
// Determine risk level based on score
if result.RiskScore >= 80 {
result.RiskLevel = RiskLevelUNACCEPTABLE
} else if result.RiskScore >= 60 {
result.RiskLevel = RiskLevelHIGH
} else if result.RiskScore >= 40 {
result.RiskLevel = RiskLevelMEDIUM
} else if result.RiskScore >= 20 {
result.RiskLevel = RiskLevelLOW
} else {
result.RiskLevel = RiskLevelMINIMAL
}
// Determine complexity
if len(result.RequiredControls) >= 5 || result.RiskScore >= 50 {
result.Complexity = ComplexityHIGH
} else if len(result.RequiredControls) >= 3 || result.RiskScore >= 25 {
result.Complexity = ComplexityMEDIUM
} else {
result.Complexity = ComplexityLOW
}
// Check DSFA recommendation
if result.RiskLevel == RiskLevelHIGH || result.RiskLevel == RiskLevelUNACCEPTABLE ||
intake.DataTypes.Article9Data || intake.DataTypes.BiometricData ||
(intake.Purpose.Profiling && intake.DataTypes.PersonalData) {
result.DSFARecommended = true
}
// Check Art. 22 risk
if intake.Automation == AutomationFullyAutomated &&
(intake.Outputs.LegalEffects || intake.Outputs.RankingsOrScores || intake.Purpose.EvaluationScoring) {
result.Art22Risk = true
}
// Determine training allowed
if intake.ModelUsage.Training && intake.DataTypes.PersonalData {
result.TrainingAllowed = TrainingNO
} else if intake.ModelUsage.Finetune && intake.DataTypes.PersonalData {
result.TrainingAllowed = TrainingCONDITIONAL
}
// Add recommended architecture patterns
for patternID, priority := range patternMap {
if p := GetPatternByID(patternID); p != nil {
result.RecommendedArchitecture = append(result.RecommendedArchitecture,
PatternToRecommendation(*p, "Empfohlen basierend auf ausgelösten Regeln", priority))
}
}
// Add applicable patterns not yet recommended
applicable := GetApplicablePatterns(intake)
for _, p := range applicable {
found := false
for _, rec := range result.RecommendedArchitecture {
if rec.PatternID == p.ID {
found = true
break
}
}
if !found {
result.RecommendedArchitecture = append(result.RecommendedArchitecture,
PatternToRecommendation(p, "Anwendbar für Ihren Use Case", len(result.RecommendedArchitecture)+1))
}
}
// Add forbidden patterns
result.ForbiddenPatterns = GetForbiddenPatterns(intake)
// Add matching examples
result.ExampleMatches = MatchExamples(intake)
// Generate summary
result.Summary = generateSummary(result, intake)
result.Recommendation = generateRecommendation(result, intake)
if result.Feasibility == FeasibilityNO {
result.AlternativeApproach = generateAlternative(result, intake)
}
return result
}
// generateSummary creates a human-readable summary
func generateSummary(result *AssessmentResult, intake *UseCaseIntake) string {
var parts []string
switch result.Feasibility {
case FeasibilityYES:
parts = append(parts, "Der Use Case ist aus DSGVO-Sicht grundsätzlich umsetzbar.")
case FeasibilityCONDITIONAL:
parts = append(parts, "Der Use Case ist unter Auflagen umsetzbar.")
case FeasibilityNO:
parts = append(parts, "Der Use Case ist in der aktuellen Form nicht DSGVO-konform umsetzbar.")
}
if len(result.TriggeredRules) > 0 {
blockCount := 0
warnCount := 0
for _, r := range result.TriggeredRules {
if r.Severity == SeverityBLOCK {
blockCount++
} else if r.Severity == SeverityWARN {
warnCount++
}
}
if blockCount > 0 {
parts = append(parts, fmt.Sprintf("%d kritische Regelverletzung(en) identifiziert.", blockCount))
}
if warnCount > 0 {
parts = append(parts, fmt.Sprintf("%d Warnungen erfordern Aufmerksamkeit.", warnCount))
}
}
if result.DSFARecommended {
parts = append(parts, "Eine Datenschutz-Folgenabschätzung (DSFA) wird empfohlen.")
}
return strings.Join(parts, " ")
}
// generateRecommendation creates actionable recommendations
func generateRecommendation(result *AssessmentResult, intake *UseCaseIntake) string {
if result.Feasibility == FeasibilityYES {
return "Fahren Sie mit der Implementierung fort. Beachten Sie die empfohlenen Architektur-Patterns für optimale DSGVO-Konformität."
}
if result.Feasibility == FeasibilityCONDITIONAL {
if len(result.RequiredControls) > 0 {
return fmt.Sprintf("Implementieren Sie die %d erforderlichen Kontrollen vor dem Go-Live. Dokumentieren Sie alle Maßnahmen für den Nachweis der Rechenschaftspflicht (Art. 5 DSGVO).", len(result.RequiredControls))
}
return "Prüfen Sie die ausgelösten Warnungen und implementieren Sie entsprechende Schutzmaßnahmen."
}
// FeasibilityNO
return "Der Use Case erfordert grundlegende Änderungen. Prüfen Sie die Alternative-Ansatz-Empfehlung."
}
// generateAlternative creates alternative approach suggestions
func generateAlternative(result *AssessmentResult, intake *UseCaseIntake) string {
var suggestions []string
// Check specific blocking reasons
if intake.ModelUsage.Training && intake.DataTypes.PersonalData {
suggestions = append(suggestions, "Nutzen Sie nur RAG statt Training mit personenbezogenen Daten")
}
if intake.Automation == AutomationFullyAutomated && intake.Outputs.LegalEffects {
suggestions = append(suggestions, "Implementieren Sie Human-in-the-Loop für Entscheidungen mit rechtlichen Auswirkungen")
}
if intake.DataTypes.MinorData && intake.Purpose.EvaluationScoring {
suggestions = append(suggestions, "Verzichten Sie auf automatisches Scoring von Minderjährigen - nutzen Sie KI nur zur Unterstützung menschlicher Entscheidungsträger")
}
if intake.Hosting.Region == "third_country" && intake.DataTypes.PersonalData {
suggestions = append(suggestions, "Hosten Sie innerhalb der EU oder implementieren Sie Standardvertragsklauseln (SCCs)")
}
if len(suggestions) == 0 {
return "Überarbeiten Sie den Use Case unter Berücksichtigung der ausgelösten Regeln."
}
return strings.Join(suggestions, ". ") + "."
}
// GetRules returns all rules
func (e *RuleEngine) GetRules() []Rule {
return e.rules
}
// ============================================================================
// Control Definitions
// ============================================================================
var ControlLibrary = map[string]RequiredControl{
"C-CONSENT": {
ID: "C-CONSENT",
Title: "Einwilligungsmanagement",
Description: "Implementieren Sie ein System zur Einholung und Verwaltung von Einwilligungen.",
Severity: SeverityWARN,
Category: "organizational",
GDPRRef: "Art. 7 DSGVO",
},
"C-PII-DETECT": {
ID: "C-PII-DETECT",
Title: "PII-Erkennung",
Description: "Implementieren Sie automatische Erkennung personenbezogener Daten.",
Severity: SeverityWARN,
Category: "technical",
GDPRRef: "Art. 32 DSGVO",
},
"C-ANONYMIZE": {
ID: "C-ANONYMIZE",
Title: "Anonymisierung/Pseudonymisierung",
Description: "Implementieren Sie Anonymisierung oder Pseudonymisierung vor der Verarbeitung.",
Severity: SeverityWARN,
Category: "technical",
GDPRRef: "Art. 32 DSGVO",
},
"C-ACCESS-CONTROL": {
ID: "C-ACCESS-CONTROL",
Title: "Zugriffskontrollen",
Description: "Implementieren Sie rollenbasierte Zugriffskontrollen.",
Severity: SeverityWARN,
Category: "technical",
GDPRRef: "Art. 32 DSGVO",
},
"C-AUDIT-LOG": {
ID: "C-AUDIT-LOG",
Title: "Audit-Logging",
Description: "Protokollieren Sie alle Zugriffe und Verarbeitungen.",
Severity: SeverityINFO,
Category: "technical",
GDPRRef: "Art. 5(2) DSGVO",
},
"C-RETENTION": {
ID: "C-RETENTION",
Title: "Aufbewahrungsfristen",
Description: "Definieren und implementieren Sie automatische Löschfristen.",
Severity: SeverityWARN,
Category: "organizational",
GDPRRef: "Art. 5(1)(e) DSGVO",
},
"C-HITL": {
ID: "C-HITL",
Title: "Human-in-the-Loop",
Description: "Implementieren Sie menschliche Überprüfung für KI-Entscheidungen.",
Severity: SeverityBLOCK,
Category: "organizational",
GDPRRef: "Art. 22 DSGVO",
},
"C-TRANSPARENCY": {
ID: "C-TRANSPARENCY",
Title: "Transparenz",
Description: "Informieren Sie Betroffene über KI-Verarbeitung.",
Severity: SeverityWARN,
Category: "organizational",
GDPRRef: "Art. 13/14 DSGVO",
},
"C-DSR-PROCESS": {
ID: "C-DSR-PROCESS",
Title: "Betroffenenrechte-Prozess",
Description: "Implementieren Sie Prozesse für Auskunft, Löschung, Berichtigung.",
Severity: SeverityWARN,
Category: "organizational",
GDPRRef: "Art. 15-22 DSGVO",
},
"C-DSFA": {
ID: "C-DSFA",
Title: "DSFA durchführen",
Description: "Führen Sie eine Datenschutz-Folgenabschätzung durch.",
Severity: SeverityWARN,
Category: "organizational",
GDPRRef: "Art. 35 DSGVO",
},
"C-SCC": {
ID: "C-SCC",
Title: "Standardvertragsklauseln",
Description: "Schließen Sie EU-Standardvertragsklauseln für Drittlandtransfers ab.",
Severity: SeverityBLOCK,
Category: "legal",
GDPRRef: "Art. 46 DSGVO",
},
"C-ENCRYPTION": {
ID: "C-ENCRYPTION",
Title: "Verschlüsselung",
Description: "Verschlüsseln Sie Daten in Übertragung und Speicherung.",
Severity: SeverityWARN,
Category: "technical",
GDPRRef: "Art. 32 DSGVO",
},
"C-MINOR-CONSENT": {
ID: "C-MINOR-CONSENT",
Title: "Elterneinwilligung",
Description: "Holen Sie Einwilligung der Erziehungsberechtigten ein.",
Severity: SeverityBLOCK,
Category: "organizational",
GDPRRef: "Art. 8 DSGVO",
},
"C-ART9-BASIS": {
ID: "C-ART9-BASIS",
Title: "Art. 9 Rechtsgrundlage",
Description: "Dokumentieren Sie die Rechtsgrundlage für besondere Datenkategorien.",
Severity: SeverityBLOCK,
Category: "legal",
GDPRRef: "Art. 9 DSGVO",
},
}
// GetControlByID returns a control by its ID
func GetControlByID(id string) *RequiredControl {
if ctrl, exists := ControlLibrary[id]; exists {
return &ctrl
}
return nil
}
// ============================================================================
// All Rules (~45 rules in 10 categories)
// ============================================================================
var AllRules = []Rule{
// =========================================================================
// A. Datenklassifikation (R-001 bis R-006)
// =========================================================================
{
Code: "R-001",
Category: "A. Datenklassifikation",
Title: "Personal Data Processing",
TitleDE: "Verarbeitung personenbezogener Daten",
Description: "Personal data is being processed",
DescriptionDE: "Personenbezogene Daten werden verarbeitet",
Severity: SeverityINFO,
ScoreDelta: 5,
GDPRRef: "Art. 4(1) DSGVO",
Controls: []string{"C-PII-DETECT", "C-ACCESS-CONTROL"},
Patterns: []string{"P-PRE-ANON"},
Condition: func(intake *UseCaseIntake) bool {
return intake.DataTypes.PersonalData
},
Rationale: func(intake *UseCaseIntake) string {
return "Der Use Case verarbeitet personenbezogene Daten. Dies erfordert eine Rechtsgrundlage und entsprechende Schutzmaßnahmen."
},
},
{
Code: "R-002",
Category: "A. Datenklassifikation",
Title: "Special Category Data (Art. 9)",
TitleDE: "Besondere Kategorien personenbezogener Daten (Art. 9)",
Description: "Processing of special category data requires explicit consent or legal basis",
DescriptionDE: "Verarbeitung besonderer Datenkategorien erfordert ausdrückliche Einwilligung oder Rechtsgrundlage",
Severity: SeverityWARN,
ScoreDelta: 20,
GDPRRef: "Art. 9 DSGVO",
Controls: []string{"C-ART9-BASIS", "C-DSFA", "C-ENCRYPTION"},
Patterns: []string{"P-PRE-ANON", "P-HITL-ENFORCED"},
Condition: func(intake *UseCaseIntake) bool {
return intake.DataTypes.Article9Data
},
Rationale: func(intake *UseCaseIntake) string {
return "Besondere Kategorien personenbezogener Daten (Gesundheit, Religion, etc.) erfordern besondere Schutzmaßnahmen und eine spezifische Rechtsgrundlage nach Art. 9 DSGVO."
},
},
{
Code: "R-003",
Category: "A. Datenklassifikation",
Title: "Minor Data Processing",
TitleDE: "Verarbeitung von Daten Minderjähriger",
Description: "Processing data of children requires special protections",
DescriptionDE: "Verarbeitung von Daten Minderjähriger erfordert besonderen Schutz",
Severity: SeverityWARN,
ScoreDelta: 15,
GDPRRef: "Art. 8 DSGVO",
Controls: []string{"C-MINOR-CONSENT", "C-DSFA"},
Patterns: []string{"P-HITL-ENFORCED"},
Condition: func(intake *UseCaseIntake) bool {
return intake.DataTypes.MinorData
},
Rationale: func(intake *UseCaseIntake) string {
return "Daten von Minderjährigen erfordern besonderen Schutz. Die Einwilligung muss von Erziehungsberechtigten eingeholt werden."
},
},
{
Code: "R-004",
Category: "A. Datenklassifikation",
Title: "Biometric Data",
TitleDE: "Biometrische Daten",
Description: "Biometric data processing is high risk",
DescriptionDE: "Verarbeitung biometrischer Daten ist hochriskant",
Severity: SeverityWARN,
ScoreDelta: 20,
GDPRRef: "Art. 9 DSGVO",
Controls: []string{"C-ART9-BASIS", "C-DSFA", "C-ENCRYPTION"},
Patterns: []string{"P-PRE-ANON"},
Condition: func(intake *UseCaseIntake) bool {
return intake.DataTypes.BiometricData
},
Rationale: func(intake *UseCaseIntake) string {
return "Biometrische Daten zur eindeutigen Identifizierung fallen unter Art. 9 DSGVO und erfordern eine DSFA."
},
},
{
Code: "R-005",
Category: "A. Datenklassifikation",
Title: "Location Data",
TitleDE: "Standortdaten",
Description: "Location tracking requires transparency and consent",
DescriptionDE: "Standortverfolgung erfordert Transparenz und Einwilligung",
Severity: SeverityINFO,
ScoreDelta: 10,
GDPRRef: "Art. 5, Art. 7 DSGVO",
Controls: []string{"C-CONSENT", "C-TRANSPARENCY"},
Patterns: []string{"P-LOG-MINIMIZATION"},
Condition: func(intake *UseCaseIntake) bool {
return intake.DataTypes.LocationData
},
Rationale: func(intake *UseCaseIntake) string {
return "Standortdaten ermöglichen Bewegungsprofile und erfordern klare Einwilligung und Aufbewahrungslimits."
},
},
{
Code: "R-006",
Category: "A. Datenklassifikation",
Title: "Employee Data",
TitleDE: "Mitarbeiterdaten",
Description: "Employee data processing has special considerations",
DescriptionDE: "Mitarbeiterdatenverarbeitung hat besondere Anforderungen",
Severity: SeverityINFO,
ScoreDelta: 10,
GDPRRef: "§ 26 BDSG",
Controls: []string{"C-ACCESS-CONTROL", "C-TRANSPARENCY"},
Patterns: []string{"P-NAMESPACE-ISOLATION"},
Condition: func(intake *UseCaseIntake) bool {
return intake.DataTypes.EmployeeData
},
Rationale: func(intake *UseCaseIntake) string {
return "Mitarbeiterdaten unterliegen zusätzlich dem BDSG § 26 und erfordern klare Zweckbindung."
},
},
// =========================================================================
// B. Zweck & Kontext (R-010 bis R-013)
// =========================================================================
{
Code: "R-010",
Category: "B. Zweck & Kontext",
Title: "Marketing with Personal Data",
TitleDE: "Marketing mit personenbezogenen Daten",
Description: "Marketing purposes with PII require explicit consent",
DescriptionDE: "Marketing mit PII erfordert ausdrückliche Einwilligung",
Severity: SeverityWARN,
ScoreDelta: 15,
GDPRRef: "Art. 6(1)(a) DSGVO",
Controls: []string{"C-CONSENT", "C-DSR-PROCESS"},
Patterns: []string{"P-PRE-ANON"},
Condition: func(intake *UseCaseIntake) bool {
return intake.Purpose.Marketing && intake.DataTypes.PersonalData
},
Rationale: func(intake *UseCaseIntake) string {
return "Marketing mit personenbezogenen Daten erfordert ausdrückliche, freiwillige Einwilligung."
},
},
{
Code: "R-011",
Category: "B. Zweck & Kontext",
Title: "Profiling Purpose",
TitleDE: "Profiling-Zweck",
Description: "Profiling requires DSFA and transparency",
DescriptionDE: "Profiling erfordert DSFA und Transparenz",
Severity: SeverityWARN,
ScoreDelta: 15,
GDPRRef: "Art. 22 DSGVO",
Controls: []string{"C-DSFA", "C-TRANSPARENCY", "C-DSR-PROCESS"},
Patterns: []string{"P-HITL-ENFORCED"},
Condition: func(intake *UseCaseIntake) bool {
return intake.Purpose.Profiling
},
Rationale: func(intake *UseCaseIntake) string {
return "Profiling erfordert eine DSFA und transparente Information der Betroffenen über die Logik und Auswirkungen."
},
},
{
Code: "R-012",
Category: "B. Zweck & Kontext",
Title: "Evaluation/Scoring Purpose",
TitleDE: "Bewertungs-/Scoring-Zweck",
Description: "Scoring of individuals requires safeguards",
DescriptionDE: "Scoring von Personen erfordert Schutzmaßnahmen",
Severity: SeverityWARN,
ScoreDelta: 15,
GDPRRef: "Art. 22 DSGVO",
Controls: []string{"C-HITL", "C-TRANSPARENCY"},
Patterns: []string{"P-HITL-ENFORCED"},
Condition: func(intake *UseCaseIntake) bool {
return intake.Purpose.EvaluationScoring
},
Rationale: func(intake *UseCaseIntake) string {
return "Bewertung/Scoring von Personen erfordert menschliche Überprüfung und Transparenz über die verwendete Logik."
},
},
{
Code: "R-013",
Category: "B. Zweck & Kontext",
Title: "Customer Support - Low Risk",
TitleDE: "Kundenservice - Niedriges Risiko",
Description: "Customer support without PII storage is low risk",
DescriptionDE: "Kundenservice ohne PII-Speicherung ist risikoarm",
Severity: SeverityINFO,
ScoreDelta: 0,
GDPRRef: "",
Controls: []string{},
Patterns: []string{"P-RAG-ONLY"},
Condition: func(intake *UseCaseIntake) bool {
return intake.Purpose.CustomerSupport && !intake.DataTypes.PersonalData
},
Rationale: func(intake *UseCaseIntake) string {
return "Kundenservice mit öffentlichen FAQ-Daten ohne Speicherung personenbezogener Daten ist risikoarm."
},
},
// =========================================================================
// C. Automatisierung (R-020 bis R-025)
// =========================================================================
{
Code: "R-020",
Category: "C. Automatisierung",
Title: "Fully Automated with Legal Effects",
TitleDE: "Vollautomatisiert mit rechtlichen Auswirkungen",
Description: "Fully automated decisions with legal effects violate Art. 22",
DescriptionDE: "Vollautomatisierte Entscheidungen mit rechtlichen Auswirkungen verletzen Art. 22",
Severity: SeverityBLOCK,
ScoreDelta: 40,
GDPRRef: "Art. 22 DSGVO",
Controls: []string{"C-HITL"},
Patterns: []string{"P-HITL-ENFORCED"},
Condition: func(intake *UseCaseIntake) bool {
return intake.Automation == AutomationFullyAutomated && intake.Outputs.LegalEffects
},
Rationale: func(intake *UseCaseIntake) string {
return "Vollautomatisierte Entscheidungen mit rechtlichen Auswirkungen ohne menschliche Beteiligung sind nach Art. 22 DSGVO unzulässig."
},
},
{
Code: "R-021",
Category: "C. Automatisierung",
Title: "Fully Automated Rankings/Scores",
TitleDE: "Vollautomatisierte Rankings/Scores",
Description: "Automated scoring requires human review",
DescriptionDE: "Automatisches Scoring erfordert menschliche Überprüfung",
Severity: SeverityWARN,
ScoreDelta: 20,
GDPRRef: "Art. 22 DSGVO",
Controls: []string{"C-HITL", "C-TRANSPARENCY"},
Patterns: []string{"P-HITL-ENFORCED"},
Condition: func(intake *UseCaseIntake) bool {
return intake.Automation == AutomationFullyAutomated && intake.Outputs.RankingsOrScores
},
Rationale: func(intake *UseCaseIntake) string {
return "Vollautomatisierte Erstellung von Rankings oder Scores erfordert menschliche Überprüfung vor Verwendung."
},
},
{
Code: "R-022",
Category: "C. Automatisierung",
Title: "Fully Automated Access Decisions",
TitleDE: "Vollautomatisierte Zugriffsentscheidungen",
Description: "Automated access decisions need safeguards",
DescriptionDE: "Automatisierte Zugriffsentscheidungen benötigen Schutzmaßnahmen",
Severity: SeverityWARN,
ScoreDelta: 15,
GDPRRef: "Art. 22 DSGVO",
Controls: []string{"C-HITL", "C-TRANSPARENCY", "C-DSR-PROCESS"},
Patterns: []string{"P-HITL-ENFORCED"},
Condition: func(intake *UseCaseIntake) bool {
return intake.Automation == AutomationFullyAutomated && intake.Outputs.AccessDecisions
},
Rationale: func(intake *UseCaseIntake) string {
return "Automatisierte Entscheidungen über Zugang erfordern Widerspruchsmöglichkeit und menschliche Überprüfung."
},
},
{
Code: "R-023",
Category: "C. Automatisierung",
Title: "Semi-Automated - Medium Risk",
TitleDE: "Teilautomatisiert - Mittleres Risiko",
Description: "Semi-automated processing with human review",
DescriptionDE: "Teilautomatisierte Verarbeitung mit menschlicher Überprüfung",
Severity: SeverityINFO,
ScoreDelta: 5,
GDPRRef: "",
Controls: []string{"C-AUDIT-LOG"},
Patterns: []string{"P-HITL-ENFORCED"},
Condition: func(intake *UseCaseIntake) bool {
return intake.Automation == AutomationSemiAutomated && intake.DataTypes.PersonalData
},
Rationale: func(intake *UseCaseIntake) string {
return "Teilautomatisierte Verarbeitung mit menschlicher Überprüfung ist grundsätzlich konform, erfordert aber Dokumentation."
},
},
{
Code: "R-024",
Category: "C. Automatisierung",
Title: "Assistive Only - Low Risk",
TitleDE: "Nur assistierend - Niedriges Risiko",
Description: "Assistive AI without automated decisions is low risk",
DescriptionDE: "Assistive KI ohne automatisierte Entscheidungen ist risikoarm",
Severity: SeverityINFO,
ScoreDelta: 0,
GDPRRef: "",
Controls: []string{},
Patterns: []string{"P-RAG-ONLY"},
Condition: func(intake *UseCaseIntake) bool {
return intake.Automation == AutomationAssistive
},
Rationale: func(intake *UseCaseIntake) string {
return "Rein assistive KI, die nur Vorschläge macht und keine Entscheidungen trifft, ist risikoarm."
},
},
{
Code: "R-025",
Category: "C. Automatisierung",
Title: "HR Scoring - Blocked",
TitleDE: "HR-Scoring - Blockiert",
Description: "Automated HR scoring/evaluation is prohibited",
DescriptionDE: "Automatisiertes HR-Scoring/Bewertung ist verboten",
Severity: SeverityBLOCK,
ScoreDelta: 50,
GDPRRef: "Art. 22, § 26 BDSG",
Controls: []string{"C-HITL"},
Patterns: []string{},
Condition: func(intake *UseCaseIntake) bool {
return intake.Domain == DomainHR &&
intake.Purpose.EvaluationScoring &&
intake.Automation == AutomationFullyAutomated
},
Rationale: func(intake *UseCaseIntake) string {
return "Vollautomatisierte Bewertung/Scoring von Mitarbeitern ist unzulässig. Arbeitsrechtliche Entscheidungen müssen von Menschen getroffen werden."
},
},
// =========================================================================
// D. Training vs Nutzung (R-030 bis R-035)
// =========================================================================
{
Code: "R-030",
Category: "D. Training vs Nutzung",
Title: "Training with Personal Data",
TitleDE: "Training mit personenbezogenen Daten",
Description: "Training AI with personal data is high risk",
DescriptionDE: "Training von KI mit personenbezogenen Daten ist hochriskant",
Severity: SeverityBLOCK,
ScoreDelta: 40,
GDPRRef: "Art. 5(1)(b)(c) DSGVO",
Controls: []string{"C-ART9-BASIS", "C-DSFA"},
Patterns: []string{"P-RAG-ONLY"},
Condition: func(intake *UseCaseIntake) bool {
return intake.ModelUsage.Training && intake.DataTypes.PersonalData
},
Rationale: func(intake *UseCaseIntake) string {
return "Training von KI-Modellen mit personenbezogenen Daten verstößt gegen Zweckbindung und Datenminimierung. Nutzen Sie stattdessen RAG."
},
},
{
Code: "R-031",
Category: "D. Training vs Nutzung",
Title: "Fine-tuning with Personal Data",
TitleDE: "Fine-Tuning mit personenbezogenen Daten",
Description: "Fine-tuning with PII requires safeguards",
DescriptionDE: "Fine-Tuning mit PII erfordert Schutzmaßnahmen",
Severity: SeverityWARN,
ScoreDelta: 25,
GDPRRef: "Art. 5(1)(b)(c) DSGVO",
Controls: []string{"C-ANONYMIZE", "C-DSFA"},
Patterns: []string{"P-PRE-ANON"},
Condition: func(intake *UseCaseIntake) bool {
return intake.ModelUsage.Finetune && intake.DataTypes.PersonalData
},
Rationale: func(intake *UseCaseIntake) string {
return "Fine-Tuning mit personenbezogenen Daten ist nur nach Anonymisierung/Pseudonymisierung zulässig."
},
},
{
Code: "R-032",
Category: "D. Training vs Nutzung",
Title: "RAG Only - Recommended",
TitleDE: "Nur RAG - Empfohlen",
Description: "RAG without training is the safest approach",
DescriptionDE: "RAG ohne Training ist der sicherste Ansatz",
Severity: SeverityINFO,
ScoreDelta: 0,
GDPRRef: "",
Controls: []string{},
Patterns: []string{"P-RAG-ONLY"},
Condition: func(intake *UseCaseIntake) bool {
return intake.ModelUsage.RAG && !intake.ModelUsage.Training && !intake.ModelUsage.Finetune
},
Rationale: func(intake *UseCaseIntake) string {
return "Nur-RAG ohne Training oder Fine-Tuning ist die empfohlene Architektur für DSGVO-Konformität."
},
},
{
Code: "R-033",
Category: "D. Training vs Nutzung",
Title: "Training with Article 9 Data",
TitleDE: "Training mit Art. 9 Daten",
Description: "Training with special category data is prohibited",
DescriptionDE: "Training mit besonderen Datenkategorien ist verboten",
Severity: SeverityBLOCK,
ScoreDelta: 50,
GDPRRef: "Art. 9 DSGVO",
Controls: []string{},
Patterns: []string{},
Condition: func(intake *UseCaseIntake) bool {
return (intake.ModelUsage.Training || intake.ModelUsage.Finetune) && intake.DataTypes.Article9Data
},
Rationale: func(intake *UseCaseIntake) string {
return "Training oder Fine-Tuning mit besonderen Kategorien personenbezogener Daten (Gesundheit, Religion, etc.) ist grundsätzlich unzulässig."
},
},
{
Code: "R-034",
Category: "D. Training vs Nutzung",
Title: "Inference with Public Data",
TitleDE: "Inferenz mit öffentlichen Daten",
Description: "Using only public data is low risk",
DescriptionDE: "Nutzung nur öffentlicher Daten ist risikoarm",
Severity: SeverityINFO,
ScoreDelta: 0,
GDPRRef: "",
Controls: []string{},
Patterns: []string{},
Condition: func(intake *UseCaseIntake) bool {
return intake.DataTypes.PublicData && !intake.DataTypes.PersonalData
},
Rationale: func(intake *UseCaseIntake) string {
return "Die ausschließliche Nutzung öffentlich zugänglicher Daten ohne Personenbezug ist unproblematisch."
},
},
{
Code: "R-035",
Category: "D. Training vs Nutzung",
Title: "Training with Minor Data",
TitleDE: "Training mit Daten Minderjähriger",
Description: "Training with children's data is prohibited",
DescriptionDE: "Training mit Kinderdaten ist verboten",
Severity: SeverityBLOCK,
ScoreDelta: 50,
GDPRRef: "Art. 8 DSGVO, ErwG 38",
Controls: []string{},
Patterns: []string{},
Condition: func(intake *UseCaseIntake) bool {
return (intake.ModelUsage.Training || intake.ModelUsage.Finetune) && intake.DataTypes.MinorData
},
Rationale: func(intake *UseCaseIntake) string {
return "Training von KI-Modellen mit Daten von Minderjährigen ist aufgrund des besonderen Schutzes unzulässig."
},
},
// =========================================================================
// E. Speicherung (R-040 bis R-042)
// =========================================================================
{
Code: "R-040",
Category: "E. Speicherung",
Title: "Storing Prompts with PII",
TitleDE: "Speicherung von Prompts mit PII",
Description: "Storing prompts containing PII requires controls",
DescriptionDE: "Speicherung von Prompts mit PII erfordert Kontrollen",
Severity: SeverityWARN,
ScoreDelta: 15,
GDPRRef: "Art. 5(1)(e) DSGVO",
Controls: []string{"C-RETENTION", "C-ANONYMIZE", "C-DSR-PROCESS"},
Patterns: []string{"P-LOG-MINIMIZATION", "P-PRE-ANON"},
Condition: func(intake *UseCaseIntake) bool {
return intake.Retention.StorePrompts && intake.DataTypes.PersonalData
},
Rationale: func(intake *UseCaseIntake) string {
return "Speicherung von Prompts mit personenbezogenen Daten erfordert Löschfristen und Anonymisierungsoptionen."
},
},
{
Code: "R-041",
Category: "E. Speicherung",
Title: "Storing Responses with PII",
TitleDE: "Speicherung von Antworten mit PII",
Description: "Storing AI responses containing PII requires controls",
DescriptionDE: "Speicherung von KI-Antworten mit PII erfordert Kontrollen",
Severity: SeverityWARN,
ScoreDelta: 10,
GDPRRef: "Art. 5(1)(e) DSGVO",
Controls: []string{"C-RETENTION", "C-DSR-PROCESS"},
Patterns: []string{"P-LOG-MINIMIZATION"},
Condition: func(intake *UseCaseIntake) bool {
return intake.Retention.StoreResponses && intake.DataTypes.PersonalData
},
Rationale: func(intake *UseCaseIntake) string {
return "Speicherung von KI-Antworten mit personenbezogenen Daten erfordert definierte Aufbewahrungsfristen."
},
},
{
Code: "R-042",
Category: "E. Speicherung",
Title: "No Retention Policy",
TitleDE: "Keine Aufbewahrungsrichtlinie",
Description: "PII storage without retention limits is problematic",
DescriptionDE: "PII-Speicherung ohne Aufbewahrungslimits ist problematisch",
Severity: SeverityWARN,
ScoreDelta: 10,
GDPRRef: "Art. 5(1)(e) DSGVO",
Controls: []string{"C-RETENTION"},
Patterns: []string{"P-LOG-MINIMIZATION"},
Condition: func(intake *UseCaseIntake) bool {
return (intake.Retention.StorePrompts || intake.Retention.StoreResponses) &&
intake.DataTypes.PersonalData &&
intake.Retention.RetentionDays == 0
},
Rationale: func(intake *UseCaseIntake) string {
return "Speicherung personenbezogener Daten ohne definierte Aufbewahrungsfrist verstößt gegen den Grundsatz der Speicherbegrenzung."
},
},
// =========================================================================
// F. Hosting (R-050 bis R-052)
// =========================================================================
{
Code: "R-050",
Category: "F. Hosting",
Title: "Third Country Transfer with PII",
TitleDE: "Drittlandtransfer mit PII",
Description: "Transferring PII to third countries requires safeguards",
DescriptionDE: "Übermittlung von PII in Drittländer erfordert Schutzmaßnahmen",
Severity: SeverityWARN,
ScoreDelta: 20,
GDPRRef: "Art. 44-49 DSGVO",
Controls: []string{"C-SCC", "C-ENCRYPTION"},
Patterns: []string{},
Condition: func(intake *UseCaseIntake) bool {
return intake.Hosting.Region == "third_country" && intake.DataTypes.PersonalData
},
Rationale: func(intake *UseCaseIntake) string {
return "Übermittlung personenbezogener Daten in Drittländer erfordert Standardvertragsklauseln oder andere geeignete Garantien."
},
},
{
Code: "R-051",
Category: "F. Hosting",
Title: "EU Hosting - Compliant",
TitleDE: "EU-Hosting - Konform",
Description: "Hosting within EU is compliant with GDPR",
DescriptionDE: "Hosting innerhalb der EU ist DSGVO-konform",
Severity: SeverityINFO,
ScoreDelta: 0,
GDPRRef: "",
Controls: []string{},
Patterns: []string{},
Condition: func(intake *UseCaseIntake) bool {
return intake.Hosting.Region == "eu"
},
Rationale: func(intake *UseCaseIntake) string {
return "Hosting innerhalb der EU/EWR erfüllt grundsätzlich die DSGVO-Anforderungen an den Datenstandort."
},
},
{
Code: "R-052",
Category: "F. Hosting",
Title: "On-Premise Hosting",
TitleDE: "On-Premise-Hosting",
Description: "On-premise hosting gives most control",
DescriptionDE: "On-Premise-Hosting gibt die meiste Kontrolle",
Severity: SeverityINFO,
ScoreDelta: 0,
GDPRRef: "",
Controls: []string{"C-ENCRYPTION"},
Patterns: []string{},
Condition: func(intake *UseCaseIntake) bool {
return intake.Hosting.Region == "on_prem"
},
Rationale: func(intake *UseCaseIntake) string {
return "On-Premise-Hosting bietet maximale Kontrolle über Daten, erfordert aber eigene Sicherheitsmaßnahmen."
},
},
// =========================================================================
// G. Transparenz (R-060 bis R-062)
// =========================================================================
{
Code: "R-060",
Category: "G. Transparenz",
Title: "No Human Review for Decisions",
TitleDE: "Keine menschliche Überprüfung bei Entscheidungen",
Description: "Decisions affecting individuals need human review option",
DescriptionDE: "Entscheidungen, die Personen betreffen, benötigen menschliche Überprüfungsoption",
Severity: SeverityWARN,
ScoreDelta: 15,
GDPRRef: "Art. 22(3) DSGVO",
Controls: []string{"C-HITL", "C-DSR-PROCESS"},
Patterns: []string{"P-HITL-ENFORCED"},
Condition: func(intake *UseCaseIntake) bool {
return (intake.Outputs.LegalEffects || intake.Outputs.AccessDecisions || intake.Purpose.DecisionMaking) &&
intake.Automation != AutomationAssistive
},
Rationale: func(intake *UseCaseIntake) string {
return "Betroffene haben das Recht auf menschliche Überprüfung bei automatisierten Entscheidungen."
},
},
{
Code: "R-061",
Category: "G. Transparenz",
Title: "External Recommendations",
TitleDE: "Externe Empfehlungen",
Description: "Recommendations to users need transparency",
DescriptionDE: "Empfehlungen an Nutzer erfordern Transparenz",
Severity: SeverityINFO,
ScoreDelta: 5,
GDPRRef: "Art. 13/14 DSGVO",
Controls: []string{"C-TRANSPARENCY"},
Patterns: []string{},
Condition: func(intake *UseCaseIntake) bool {
return intake.Outputs.RecommendationsToUsers && intake.DataTypes.PersonalData
},
Rationale: func(intake *UseCaseIntake) string {
return "Personalisierte Empfehlungen erfordern Information der Nutzer über die KI-Verarbeitung."
},
},
{
Code: "R-062",
Category: "G. Transparenz",
Title: "Content Generation without Disclosure",
TitleDE: "Inhaltsgenerierung ohne Offenlegung",
Description: "AI-generated content should be disclosed",
DescriptionDE: "KI-generierte Inhalte sollten offengelegt werden",
Severity: SeverityINFO,
ScoreDelta: 5,
GDPRRef: "EU-AI-Act Art. 52",
Controls: []string{"C-TRANSPARENCY"},
Patterns: []string{},
Condition: func(intake *UseCaseIntake) bool {
return intake.Outputs.ContentGeneration
},
Rationale: func(intake *UseCaseIntake) string {
return "KI-generierte Inhalte sollten als solche gekennzeichnet werden (EU-AI-Act Transparenzpflicht)."
},
},
// =========================================================================
// H. Domain-spezifisch (R-070 bis R-074)
// =========================================================================
{
Code: "R-070",
Category: "H. Domain-spezifisch",
Title: "Education + Scoring = Blocked",
TitleDE: "Bildung + Scoring = Blockiert",
Description: "Automated scoring of students is prohibited",
DescriptionDE: "Automatisches Scoring von Schülern ist verboten",
Severity: SeverityBLOCK,
ScoreDelta: 50,
GDPRRef: "Art. 8, Art. 22 DSGVO",
Controls: []string{},
Patterns: []string{},
Condition: func(intake *UseCaseIntake) bool {
return intake.Domain == DomainEducation &&
intake.DataTypes.MinorData &&
(intake.Purpose.EvaluationScoring || intake.Outputs.RankingsOrScores)
},
Rationale: func(intake *UseCaseIntake) string {
return "Automatisches Scoring oder Ranking von Schülern/Minderjährigen ist aufgrund des besonderen Schutzes unzulässig."
},
},
{
Code: "R-071",
Category: "H. Domain-spezifisch",
Title: "Healthcare + Automated Diagnosis",
TitleDE: "Gesundheit + Automatische Diagnose",
Description: "Automated medical decisions require strict controls",
DescriptionDE: "Automatische medizinische Entscheidungen erfordern strenge Kontrollen",
Severity: SeverityBLOCK,
ScoreDelta: 45,
GDPRRef: "Art. 9, Art. 22 DSGVO",
Controls: []string{"C-HITL", "C-DSFA", "C-ART9-BASIS"},
Patterns: []string{"P-HITL-ENFORCED"},
Condition: func(intake *UseCaseIntake) bool {
return intake.Domain == DomainHealthcare &&
intake.Automation == AutomationFullyAutomated &&
intake.Purpose.DecisionMaking
},
Rationale: func(intake *UseCaseIntake) string {
return "Vollautomatisierte medizinische Diagnosen oder Behandlungsentscheidungen sind ohne ärztliche Überprüfung unzulässig."
},
},
{
Code: "R-072",
Category: "H. Domain-spezifisch",
Title: "Finance + Automated Credit Scoring",
TitleDE: "Finanzen + Automatisches Credit-Scoring",
Description: "Automated credit decisions require transparency",
DescriptionDE: "Automatische Kreditentscheidungen erfordern Transparenz",
Severity: SeverityWARN,
ScoreDelta: 20,
GDPRRef: "Art. 22 DSGVO",
Controls: []string{"C-HITL", "C-TRANSPARENCY", "C-DSR-PROCESS"},
Patterns: []string{"P-HITL-ENFORCED"},
Condition: func(intake *UseCaseIntake) bool {
return intake.Domain == DomainFinance &&
(intake.Purpose.EvaluationScoring || intake.Outputs.RankingsOrScores) &&
intake.DataTypes.FinancialData
},
Rationale: func(intake *UseCaseIntake) string {
return "Automatische Kreditwürdigkeitsprüfung erfordert Erklärbarkeit und Widerspruchsmöglichkeit."
},
},
{
Code: "R-073",
Category: "H. Domain-spezifisch",
Title: "Utilities + RAG Chatbot = Low Risk",
TitleDE: "Versorgungsunternehmen + RAG-Chatbot = Niedriges Risiko",
Description: "RAG-based customer service chatbot is low risk",
DescriptionDE: "RAG-basierter Kundenservice-Chatbot ist risikoarm",
Severity: SeverityINFO,
ScoreDelta: 0,
GDPRRef: "",
Controls: []string{},
Patterns: []string{"P-RAG-ONLY"},
Condition: func(intake *UseCaseIntake) bool {
return intake.Domain == DomainUtilities &&
intake.ModelUsage.RAG &&
intake.Purpose.CustomerSupport &&
!intake.DataTypes.PersonalData
},
Rationale: func(intake *UseCaseIntake) string {
return "Ein RAG-basierter Kundenservice-Chatbot ohne Speicherung personenbezogener Daten ist ein Best-Practice-Beispiel."
},
},
{
Code: "R-074",
Category: "H. Domain-spezifisch",
Title: "Public Sector + Automated Decisions",
TitleDE: "Öffentlicher Sektor + Automatische Entscheidungen",
Description: "Public sector automated decisions need special care",
DescriptionDE: "Automatische Entscheidungen im öffentlichen Sektor erfordern besondere Sorgfalt",
Severity: SeverityWARN,
ScoreDelta: 20,
GDPRRef: "Art. 22 DSGVO",
Controls: []string{"C-HITL", "C-TRANSPARENCY", "C-DSFA"},
Patterns: []string{"P-HITL-ENFORCED"},
Condition: func(intake *UseCaseIntake) bool {
return intake.Domain == DomainPublic &&
intake.Purpose.DecisionMaking &&
intake.Automation != AutomationAssistive
},
Rationale: func(intake *UseCaseIntake) string {
return "Verwaltungsentscheidungen, die Bürger betreffen, erfordern besondere Transparenz und Überprüfungsmöglichkeiten."
},
},
// =========================================================================
// I. Aggregation (R-090 bis R-092) - Implicit in Evaluate()
// =========================================================================
{
Code: "R-090",
Category: "I. Aggregation",
Title: "Block Rules Triggered",
TitleDE: "Blockierungsregeln ausgelöst",
Description: "Any BLOCK severity results in NO feasibility",
DescriptionDE: "Jede BLOCK-Schwere führt zu NEIN-Machbarkeit",
Severity: SeverityBLOCK,
ScoreDelta: 0,
GDPRRef: "",
Controls: []string{},
Patterns: []string{},
Condition: func(intake *UseCaseIntake) bool {
// This is handled in aggregation logic
return false
},
Rationale: func(intake *UseCaseIntake) string {
return "Eine oder mehrere kritische Regelverletzungen führen zur Einstufung als nicht umsetzbar."
},
},
{
Code: "R-091",
Category: "I. Aggregation",
Title: "Warning Rules Only",
TitleDE: "Nur Warnungsregeln",
Description: "Only WARN severity results in CONDITIONAL",
DescriptionDE: "Nur WARN-Schwere führt zu BEDINGT",
Severity: SeverityWARN,
ScoreDelta: 0,
GDPRRef: "",
Controls: []string{},
Patterns: []string{},
Condition: func(intake *UseCaseIntake) bool {
// This is handled in aggregation logic
return false
},
Rationale: func(intake *UseCaseIntake) string {
return "Warnungen erfordern Maßnahmen, blockieren aber nicht die Umsetzung."
},
},
{
Code: "R-092",
Category: "I. Aggregation",
Title: "Info Only - Clear Path",
TitleDE: "Nur Info - Freier Weg",
Description: "Only INFO severity results in YES",
DescriptionDE: "Nur INFO-Schwere führt zu JA",
Severity: SeverityINFO,
ScoreDelta: 0,
GDPRRef: "",
Controls: []string{},
Patterns: []string{},
Condition: func(intake *UseCaseIntake) bool {
// This is handled in aggregation logic
return false
},
Rationale: func(intake *UseCaseIntake) string {
return "Keine kritischen oder warnenden Regeln ausgelöst - Umsetzung empfohlen."
},
},
// =========================================================================
// J. Erklärung (R-100)
// =========================================================================
{
Code: "R-100",
Category: "J. Erklärung",
Title: "Rejection Must Include Reason and Alternative",
TitleDE: "Ablehnung muss Begründung und Alternative enthalten",
Description: "When feasibility is NO, provide reason and alternative",
DescriptionDE: "Bei Machbarkeit NEIN, Begründung und Alternative angeben",
Severity: SeverityINFO,
ScoreDelta: 0,
GDPRRef: "",
Controls: []string{},
Patterns: []string{},
Condition: func(intake *UseCaseIntake) bool {
// This is handled in summary generation
return false
},
Rationale: func(intake *UseCaseIntake) string {
return "Jede Ablehnung enthält eine klare Begründung und einen alternativen Ansatz."
},
},
}