# Anforderung: Master Controls fuer Dokumentenpruefung

## Kontext

Der Compliance Agent prueft rechtliche Dokumente (DSI, AGB, Impressum, Cookie-Richtlinie,
Widerrufsbelehrung) gegen Pflichtangaben. Aktuell nutzen wir Regex-Patterns fuer die
Grundpruefung (9 Art. 13 DSGVO Felder) — das funktioniert gut fuer "ist X erwaehnt?".

Der naechste Schritt ist: **Nicht nur pruefen OB etwas erwaehnt wird, sondern ob es
KORREKT und VOLLSTAENDIG ist.** Dafuer brauchen wir Master Controls als Pruefkriterien.

## Das Problem mit den aktuellen Controls

Die 294K Atomic Controls in `canonical_controls` sind zu allgemein:

```
Titel: "Informationspflicht des Verantwortlichen gegenueber betroffenen Personen"
test_procedure: [
  "Ueberpruefung der Datenschutzerklaerung auf Vollstaendigkeit",
  "Pruefung ob Name und Kontaktdaten des Verantwortlichen angegeben sind",
  "Verifizierung ob Kontaktdaten des DSB vorhanden sind",
]
```

Wenn wir das LLM fragen "Erfuellt der IHK-Text diesen Control?", sagt es "Nein"
weil der Control zu vage ist — "Vollstaendigkeit" ist subjektiv.

## Was wir brauchen

Master Controls mit **konkreten, binaerenr Pruefkriterien** pro Dokumenttyp.
Jeder Control muss eine **JA/NEIN Frage** sein die das LLM eindeutig beantworten kann.

### Beispiel: DSI (Datenschutzinformation nach Art. 13 DSGVO)

```yaml
master_control:
  id: "MC-DSI-001"
  title: "Vollstaendige Angabe des Verantwortlichen"
  doc_type: "dse"
  regulation: "DSGVO Art. 13(1)(a)"
  
  check_question: >
    Ist der Verantwortliche mit vollstaendigem Namen, Rechtsform,
    Anschrift (Strasse, PLZ, Ort), E-Mail-Adresse UND Telefonnummer
    angegeben?
  
  pass_criteria:
    - "Name des Verantwortlichen mit Rechtsform (z.B. GmbH, e.V., AG)"
    - "Vollstaendige Postanschrift (Strasse + Hausnummer + PLZ + Ort)"
    - "E-Mail-Adresse"
    - "Telefonnummer"
  
  fail_criteria:
    - "Nur Firmenname ohne Anschrift"
    - "Nur 'Kontaktieren Sie uns' ohne konkrete Daten"
    - "Postfach statt Strasse (bei Pflicht zur ladungsfaehigen Anschrift)"
  
  correction_template: >
    Verantwortlicher im Sinne der DSGVO:
    {{COMPANY_NAME}}
    {{STREET}} {{HOUSE_NUMBER}}
    {{ZIP}} {{CITY}}
    E-Mail: {{EMAIL}}
    Telefon: {{PHONE}}
    Vertretungsberechtigte: {{REPRESENTATIVES}}
```

### Beispiel: Cookie-Richtlinie (§25 TDDDG)

```yaml
master_control:
  id: "MC-COOKIE-003"
  title: "Zweckbeschreibung pro Cookie-Kategorie"
  doc_type: "cookie"
  regulation: "TDDDG §25"
  
  check_question: >
    Wird fuer JEDE Cookie-Kategorie (notwendig, funktional, statistik,
    marketing) ein konkreter Zweck beschrieben — nicht nur der
    Kategoriename sondern WAS damit gemacht wird?
  
  pass_criteria:
    - "Pro Kategorie mindestens ein Satz der den Zweck beschreibt"
    - "'Statistik-Cookies helfen uns zu verstehen wie Besucher die Seite nutzen'"
    - "'Marketing-Cookies werden fuer personalisierte Werbung verwendet'"
  
  fail_criteria:
    - "Nur Kategorienamen ohne Erklaerung"
    - "'Wir verwenden Cookies' ohne Differenzierung"
    - "Zweck nur als 'notwendig fuer den Betrieb' ohne Spezifikation"
```

### Beispiel: Impressum (§5 TMG)

```yaml
master_control:
  id: "MC-IMP-002"
  title: "Handelsregister und USt-IdNr"
  doc_type: "impressum"
  regulation: "TMG §5(1) Nr. 4-6"
  
  check_question: >
    Sind Handelsregister (Registergericht + HRB/HRA-Nummer) UND
    Umsatzsteuer-Identifikationsnummer angegeben (falls vorhanden)?
  
  pass_criteria:
    - "Registergericht benannt (z.B. 'Amtsgericht Konstanz')"
    - "Registernummer (z.B. 'HRB 12345')"
    - "USt-IdNr. im Format DE + 9 Ziffern"
  
  fail_criteria:
    - "Nur 'im Handelsregister eingetragen' ohne Details"
    - "USt-IdNr. fehlt bei offensichtlichem Gewerbebetrieb"
```

## Gewuenschte Dokumenttypen + Anzahl Controls

| Dokumenttyp | Regulation | Geschaetzte Anzahl Controls |
|-------------|-----------|---------------------------|
| DSI (Datenschutzinformation) | DSGVO Art. 13, Art. 14 | 15-20 |
| Cookie-Richtlinie | TDDDG §25, ePrivacy Art. 5(3) | 8-12 |
| Impressum | TMG §5, MStV §18 | 8-10 |
| Widerrufsbelehrung | BGB §355, §312g | 6-8 |
| AGB | BGB §305, §307, §309 | 10-15 |
| DSFA | DSGVO Art. 35, Landes-Listen | 12-15 |
| AVV | DSGVO Art. 28 | 10-12 |
| Loeschkonzept | DSGVO Art. 5(1)(e), DIN 66398 | 8-10 |

**Gesamt: ca. 80-100 Master Controls** — nicht 25.000, sondern die spezifischen
Pruefkriterien fuer die Dokumentenpruefung.

## Technische Anforderungen

### Felder die der Doc-Checker braucht

```sql
-- Pro Master Control:
id UUID
doc_type VARCHAR        -- 'dse', 'cookie', 'impressum', 'widerruf', 'agb', 'dsfa', 'avv'
regulation VARCHAR      -- 'DSGVO Art. 13(1)(a)', 'TDDDG §25'
title VARCHAR           -- Kurztitel fuer die Checkliste
check_question TEXT     -- Die Frage die das LLM beantwortet (JA/NEIN)
pass_criteria JSONB     -- Was muss im Text stehen (konkret)
fail_criteria JSONB     -- Was darf NICHT stehen / was fehlt
correction_template TEXT -- Korrekturvorschlag mit Platzhaltern
severity VARCHAR        -- 'HIGH', 'MEDIUM', 'LOW'
```

### Wie der Doc-Checker sie nutzt

```python
# 1. Query: Alle Controls fuer doc_type='dse'
controls = db.query(MasterControl).filter(doc_type='dse').all()

# 2. Fuer jeden Control: LLM fragen
prompt = f"""
{control.check_question}

PASS wenn: {control.pass_criteria}
FAIL wenn: {control.fail_criteria}

DOKUMENTTEXT:
{document_text[:5000]}

Antworte mit JSON: {{"passed": true/false, "evidence": "textstelle", "issue": "problem"}}
"""

# 3. Bei FAIL: correction_template als Korrekturvorschlag anbieten
```

### Wo die Controls liegen sollen

Entweder:
- **Neue Tabelle** `compliance.doc_check_controls` (saubere Trennung)
- **Oder** in `canonical_controls` mit `doc_type` Feld + Flag `is_doc_check = true`
- **Oder** in `master_controls` mit `lifecycle_phase = 'document_check'`

Die einfachste Variante ist eine neue Tabelle — keine Vermischung mit den
294K bestehenden Controls.

## Zusammenfassung

Wir brauchen **~80-100 hochspezifische Pruefkriterien** die:
1. Einem konkreten Dokumenttyp zugeordnet sind
2. Eine binaere JA/NEIN Frage stellen
3. Konkrete pass_criteria haben (nicht "Vollstaendigkeit pruefen")
4. Konkrete fail_criteria haben (typische Fehler)
5. Einen Korrekturvorschlag mitliefern (aus unseren Templates)

Das LLM (Qwen 3.5:35b) kann dann jede Frage zuverlaessig beantworten
weil die Frage praezise genug ist.
