Files
breakpilot-compliance/ai-compliance-sdk/internal/ucca/rules_data_fj.go
Sharang Parnerkar 9f96061631 refactor(go): split training/store, ucca/rules, ucca_handlers, document_export under 500 LOC
Each of the four oversized files (training/store.go 1569 LOC, ucca/rules.go 1231 LOC,
ucca_handlers.go 1135 LOC, document_export.go 1101 LOC) is split by logical group
into same-package files, all under the 500-line hard cap. Zero behavior changes,
no renamed exported symbols. Also fixed pre-existing hazard_library split (missing
functions and duplicate UUID keys from a prior session).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 09:29:54 +02:00

324 lines
13 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 ucca
func init() {
AllRules = append(AllRules, rulesFJ()...)
}
// rulesFJ returns rules for categories FJ (R-050 to R-100)
func rulesFJ() []Rule {
return []Rule{
// =========================================================================
// 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 {
return false // handled in aggregation logic
},
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 {
return false // handled in aggregation logic
},
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 {
return false // handled in aggregation logic
},
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 {
return false // handled in summary generation
},
Rationale: func(intake *UseCaseIntake) string {
return "Jede Ablehnung enthält eine klare Begründung und einen alternativen Ansatz."
},
},
}
}