plan: Banner-Check upgrade to L1/L2 with expert hints

Detailed plan for upgrading the 22 existing Playwright-based banner
checks to the same quality level as the document checks:
- 6 L1 + 30 L2 hierarchical checks
- Expert hints with EuGH/CNIL/DSK/EDPB references
- 3-phase evidence (before consent, after reject, after accept)
- Dark pattern detection (button size, color, click asymmetry)
- Estimated 3-4h implementation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-05-07 17:48:11 +02:00
parent 7c17321089
commit 313ee5073b
+164
View File
@@ -0,0 +1,164 @@
# Plan: Banner-Check auf Dokumentenpruefungs-Qualitaet upgraden
## Ziel
Die 22 bestehenden Banner-Checks auf das gleiche Qualitaetsniveau bringen
wie die 138 Dokumenten-Checks: L1/L2-Hierarchie, Expert-Level Hints mit
EuGH/CNIL/DSK-Referenzen, strukturiertes CheckItem-Format.
## Bestehende 22 Checks (Inventar)
### Banner Text & Verhalten (1-11)
1. `impressum_link` — Impressum aus Banner erreichbar
2. `dse_link` — DSE-Link im Banner
3. `wrong_dse_consent` — Falsche Formulierung ("Zustimmung zur DSE")
4. `reject_button_visible` — Ablehnen-Button sichtbar
5. `pre_ticked_checkboxes` — Vorausgewaehlte Checkboxen (EuGH Planet49)
6. `dark_pattern_button_size` — Akzeptieren groesser als Ablehnen
7. `cookie_wall` — Seite nach Ablehnung nutzbar
8. `re_access_settings` — Einstellungen erneut zugaenglich
9. `third_party_dse_link` — DSE zeigt auf eigene Seite
10. `dark_pattern_language` — Manipulative Sprache
11. `non_modal_dismiss` — Klick ausserhalb = keine Einwilligung
### Advanced Compliance (12-20)
12. `click_count_asymmetry` — Gleiche Klickanzahl fuer Accept/Reject
13. `color_contrast_dark_pattern` — Ablehnen-Button nicht unsichtbar
14. `google_consent_mode_defaults` — GCM Default = denied
15. `cookies_before_consent` — Keine Cookies vor Consent
16. `registration_consent_coupling` — Koppelungsverbot Art. 7(4)
17. `banner_language_mismatch` — Sprache = Seitensprache
18. `consent_cookie_expiry_13m` — Max 13 Monate (CNIL)
19. `nudging_reject_hidden` — Ablehnen nicht versteckt
20. `stirring_emotional_language` — Emotionale Manipulation
### Phasen-basiert (21-22)
21. `tracking_before_consent` — Tracking vor Einwilligung
22. `tracking_after_reject` — Tracking nach Ablehnung
## Geplante L1/L2-Struktur
### L1: Banner-Grundanforderungen (6 Checks)
| ID | Label | Prueft |
|----|-------|--------|
| banner_present | Banner vorhanden | Wird ein Cookie-Banner angezeigt? |
| banner_choices | Wahlmoeglichkeit | Akzeptieren UND Ablehnen moeglich? |
| banner_legal_links | Rechtliche Links | Impressum + DSE erreichbar? |
| banner_consent_valid | Gueltige Einwilligung | Keine Pre-Ticked Boxes, kein Auto-Consent? |
| banner_pre_consent | Keine Vorab-Cookies | Keine Tracking-Cookies vor Consent? |
| banner_post_reject | Ablehnung respektiert | Tracking stoppt nach Ablehnung? |
### L2: Detail-Checks pro L1 (30+ Checks)
#### Unter "banner_choices" (Wahlmoeglichkeit):
- reject_visible — Ablehnen-Button sichtbar auf erster Ebene
- reject_same_clicks — Gleiche Klickanzahl wie Akzeptieren
- reject_same_size — Gleiche Buttongroesse (kein Dark Pattern)
- reject_same_prominence — Gleiche Farbgebung/Kontrast
- reject_no_scroll — Ablehnen ohne Scrollen erreichbar
- reject_no_nudging — Kein Nudging/Stirring
#### Unter "banner_legal_links":
- impressum_accessible — Impressum trotz Overlay erreichbar
- dse_link_present — DSE-Link im Banner vorhanden
- dse_link_own — DSE zeigt auf eigene Seite (nicht Drittanbieter)
- dse_readable — DSE ist vor Einwilligung einsehbar
#### Unter "banner_consent_valid":
- no_pre_ticked — Keine vorausgewaehlten Checkboxen
- no_wrong_wording — Keine "Zustimmung zur DSE"
- no_modal_dismiss — Klick ausserhalb != Einwilligung
- no_coupling — Kein Koppelungsverbot-Verstoss
- no_emotional_language — Keine manipulative Sprache
- consent_revocable — Einstellungen erneut zugaenglich (Art. 7(3))
- consent_expiry — Consent-Cookie max 13 Monate (CNIL)
#### Unter "banner_pre_consent":
- no_tracking_scripts — Keine Tracking-Scripts vor Consent
- no_tracking_cookies — Keine Tracking-Cookies vor Consent
- gcm_default_denied — Google Consent Mode Default = denied
- no_facebook_pixel — Kein Meta Pixel vor Consent
- no_google_analytics — Kein GA vor Consent
#### Unter "banner_post_reject":
- tracking_stops — Tracking-Scripts entfernt nach Ablehnung
- cookies_removed — Tracking-Cookies entfernt nach Ablehnung
- no_new_tracking — Keine neuen Tracker nach Ablehnung
- site_functional — Seite bleibt nutzbar (kein Cookie-Wall)
#### Unter "banner_present":
- banner_language — Sprache = Seitensprache
- banner_provider_named — CMP-Anbieter identifizierbar
## Expert-Level Hints (Beispiele)
### Dark Pattern Button-Groesse:
"EDPB Guidelines 3/2022 (Deceptive Design Patterns), Rn. 62: Akzeptieren
und Ablehnen muessen 'gleichwertig praesentiert' werden. Konkret: Gleiche
Schriftgroesse, Buttongroesse und Farbprominenz. Die CNIL hat Google
(150 Mio. EUR) und Facebook (60 Mio. EUR) u.a. wegen Klick-Asymmetrie
bestraft."
### Pre-Consent Tracking:
"§25 Abs. 1 TDDDG: Zugriff auf Endgeraet (Cookie setzen, Script laden)
erst NACH informierter Einwilligung. Tracking vor Banner-Interaktion ist
ein Verstoss. Haeufig: Google Tag Manager laedt GA4 bereits beim
Seitenaufruf — GTM selbst ist erlaubt, die darin konfigurierten Tags
muessen aber consent-gesteuert sein."
### Cookie-Wall:
"EDPB Guidelines 05/2020, Rn. 39: Verweigerung der Einwilligung darf
nicht dazu fuehren, dass die Website nicht mehr nutzbar ist (sog.
'Cookie Wall'). Ausnahme: Paywall-Modelle ('Consent or Pay') sind
nach EDPB Opinion 08/2024 unter engen Bedingungen zulaessig."
### Consent-Cookie Laufzeit:
"CNIL-Leitlinie (Dez. 2020): Consent-Entscheidung darf max. 13 Monate
gespeichert werden. Danach muss erneut gefragt werden. Viele CMPs
setzen Default auf 365 Tage — das ist noch im Rahmen. Ueber 395 Tage
ist ein Verstoss."
## Technische Umsetzung
### Phase 1: Banner-Check Datenmodell (Backend)
- Neues Package `consent-tester/checks/` mit L1/L2-Struktur
- Jeder Check bekommt: id, label, level, parent, severity, hint
- Runner aggregiert Checks und berechnet Scores
- Response-Format analog zu DocCheckResult (completeness_pct, correctness_pct)
### Phase 2: Consent-Tester Integration
- Bestehende Checks (banner_text_checker, banner_advanced_checks) mappen
auf neue L1/L2-Struktur
- Phasen-Violations als L2-Checks unter banner_pre_consent / banner_post_reject
- Tracking-Services als Evidence (matched_text)
### Phase 3: Frontend
- BannerCheckTab zeigt L1/L2 hierarchisch (wie ChecklistView)
- 3-Phasen-Zusammenfassung oben
- Fortschrittsbalken (gruen/blau)
- Hints unter fehlgeschlagenen Checks
### Phase 4: Email-Report
- Gleiche HTML-Formatierung wie Dokumentenpruefung
- Hints + Evidence + Phase-Zuordnung
## Dateien
| Datei | Aktion |
|-------|--------|
| consent-tester/checks/__init__.py | Neu: L1/L2 Check-Definitionen |
| consent-tester/checks/banner_checks.py | Neu: 6 L1 + 30 L2 Checks mit Hints |
| consent-tester/checks/runner.py | Neu: Aggregation + Scoring |
| consent-tester/services/consent_scanner.py | Anpassen: Neues Response-Format |
| backend-compliance/compliance/api/agent_doc_check_routes.py | Erweitern: Banner-Result-Mapping |
| admin-compliance/app/sdk/agent/_components/BannerCheckTab.tsx | Erweitern: ChecklistView-Integration |
## Geschaetzter Aufwand
~3-4 Stunden:
- 1h: L1/L2 Check-Definitionen + 36 Expert-Level Hints
- 1h: Consent-Tester Mapping + Runner
- 0.5h: Backend Response-Mapping
- 0.5h: Frontend Integration
- 0.5h: Test + Deploy + Ground Truth