dsgvo-audit v1.0.0 Rechtsstand 2026-09 DSGVO · TDDDG · DDG MIT

So funktioniert dsgvo-audit

Ein Claude-Skill, der eine Website so prüft, wie ein sorgfältiger Code-Reviewer es täte: Er sammelt Belege, bevor er sich eine Meinung bildet, folgt jedem personenbezogenen Datum vom Browser bis zum letzten Drittanbieter, bewertet jeden Befund nach deutschem Datenschutzrecht und schreibt erst dann die Datenschutzerklärung. Diese Seite zeigt, wie das Paket aufgebaut ist und was in jedem Schritt passiert.

1 · EVIDENZstatischer Scan, Runtime-Scan, Datenfluss-Trace
2 · RÜCKFRAGENnur fragen, was der Code nicht verrät
3 · AUDITPrüfkatalog mit 11 Abschnitten, Ampelstatus
4 · BERICHTDeutsch, Befunde mit § und Aufwand
5 · BEHEBUNGVorlagen, Gating, erneutes Audit
01 · Aufbau

Ein Skill, zehn Dateien, in Schichten geladen

Claude liest nie das ganze Paket auf einmal. Die Description ist immer im Kontext und entscheidet, ob der Skill anspringt. SKILL.md wird geladen, wenn er es tut, und enthält den Ablauf. Alles andere holt sich erst die Phase, die es braucht — ein 100-KB-Paket kostet also nur wenige Kilobyte Kontext, bis das Audit tatsächlich beginnt. Klicke eine Datei an, um zu sehen, wann sie gelesen wird und von welcher Phase.

Schicht 0 · immer Description (~150 Wörter) entscheidet das Auslösen Scope: Review, Compliance- Frage, neuer Drittdienst löst aus Schicht 1 · beim Auslösen SKILL.md (~170 Zeilen) Haltung, fünf Phasen, Berichtsformat, Deployment- Regeln mit rechtlicher Nuance je Phase Schicht 2 · bei Bedarf references/ · assets/ · scripts/ gelesen, wenn eine Phase darauf zeigt; der Scanner wird ausgeführt, nie gelesen; Vorlagen nur in der Behebung der Kontextverbrauch wächst nur mit dem Fortschritt des Audits
Progressives Laden: Der Teil, der immer präsent ist, ist klein und entscheidet das Auslösen; das schwere juristische Material kommt erst in den Kontext, wenn eine Phase es braucht.
skills/dsgvo-audit/
references/
assets/
scripts/
agents/
02 · Ablauf

Fünf Phasen, der Reihe nach, ohne Abkürzung

Die Reihenfolge ist der Punkt. Eine Datenschutzerklärung, die geschrieben wird, bevor jemand weiß, was die Seite lädt, nennt Dienste, die es nicht gibt, und verschweigt die, die es gibt — das ist selbst ein Transparenzmangel nach Art. 5 Abs. 1 lit. a. Also zuerst Belege, dann Fragen, zuletzt die Erklärung. Klicke eine Phase an oder lass die Sequenz laufen.

Phase 5 läuft nur, wenn der Nutzer Korrekturen verlangt, nicht bei einem reinen Audit.
03 · Evidenz

Vier Evidenzstufen — und der Bericht sagt, welche er hatte

Was Claude sehen kann, hängt davon ab, was es bekommen hat. Jede Stufe tiefer verliert Sicht, und der Bericht nennt die erreichte Stufe, damit der Mandant weiß, was verifiziert und was geschlossen wurde. Der Skill weigert sich, aus einer Beschreibung allein eine generische Erklärung zu erzeugen; er stellt stattdessen die Rückfragen. Ein Scan, der die Seite nicht erreicht, liefert kein Urteil (Exit-Code 3) — der Bericht rutscht eine Stufe tiefer und sagt das; ein Netzwerkfehler wird nie als saubere Seite gelesen.

1a · Codebasis + 1b · Runtime-Scan Deps, Quellcode, Config, Env-Namen; Live-Origins sieht: Drittanbieter-Origins, Storage, Handler, DB, Auftragsverarbeiter, Cookies inkl. Set-Cookie, was das CMP blockt 1b · Nur Live-URL (Scanner) kein Repo — Browser-Tools als Fallback sieht die Browserseite vollständig · blind für Server-Handler, DB-Region, AVVs Nur HTML-Fetch script/iframe/preconnect-Tags, /impressum nur statische Tags · übersieht zur Laufzeit injizierte Tags, Set-Cookie, CMP-Verhalten Nur Beschreibung „eine Next.js-Seite für eine Physiopraxis“ sieht nichts → Rückfragen, nie eine generische Vorlage (Art. 5 Abs. 1 lit. a)
Die Evidenzleiter. Die Balken zeigen, wie viel vom Datenfluss jede Stufe verifizieren kann; das Management Summary des Berichts nennt die Stufe in einem Satz.

Statischer Scan

Zuerst Abhängigkeiten (package.json ist der schnellste, verlässlichste Beleg), dann Quellcode nach Drittanbieter-Origins und Endgerät-Storage, dann Serverseite nach Stellen, an denen PII die App verlässt, dann Config nach Regionen und Headern. Env-Dateien werden nur nach Schlüsselnamen durchsucht; Werte gelangen nie in einen Bericht.

Was grep nicht sieht

Google Tag Manager ist eine Blackbox, bis Tags feuern — der Skill fordert deshalb den Container-Export an. Ein Fetch sieht keine Cookies, die API-Antworten setzen. Ein Sprachumschalter heißt: jede Sprache braucht ihre eigene DSE (Art. 12). Jeder dieser Punkte ist ein expliziter Schritt, keine Hoffnung.

Je Datenfluss festgehalten

Was (Daten) · woher (Origin, Land) · wann (vor oder nach Consent) · wozu (Zweck) · Rechtsgrundlage · welcher Vertrag (AVV, gemeinsame Verantwortlichkeit, keiner) · Speicherdauer. Sieben Felder, für jeden Fluss gefüllt, werden zur Datenfluss-Tabelle des Berichts.

Nummerierte Evidenz

build-evidence.mjs gibt jeder Beobachtung eine ID. Jeder 🔴/🟠-Befund endet mit Evidenz: E-03 · beobachtet — oder abgeleitet, wenn er einen Schritt über das Gesehene hinausgeht (GA „lädt vor Consent“ aus dem Code, ohne Runtime-Scan), oder Mandantenangabe, wenn er auf Aussagen des Mandanten beruht.

Jeder Empfänger, mit Rolle

list-processors.mjs macht aus derselben Evidenz die Auftragsverarbeiter-Tabelle: Art. 28, Art. 26 oder eigener Verantwortlicher, Vertrag, Region, Transfermechanismus und die Liste der anzufordernden AVVs. Ob unterschrieben, bleibt ⚪️, bis der Mandant es bestätigt; Hoster und Postfach kommen von Hand dazu.

Was sich seit dem letzten Mal geändert hat

diff-scans.mjs vergleicht zwei Scans. Ein neuer Tracker vor Consent ist eine 🔴-Regression und lässt --strict scheitern; ein entfernter Dienst wird aufgelistet, damit er auch aus der DSE verschwindet. dsgvo-watch.yml lässt das wöchentlich gegen eine eingecheckte Baseline laufen.

04 · Datenfluss

Ein Kontaktformular ist eine Pipeline mit vier Empfängern

Frühere Entwürfe prüften die Seite. Der Skill prüft den Pfad. Personenbezogene Daten kommen im Browser an und wandern durch Edge-Code, API-Handler, eine Datenbank und eine Reihe von Drittanbietern, bevor sie in Logs und Backups landen. Jeder Hop ist eine Stelle, an der eine Rechtsgrundlage, ein Vertrag oder eine Speicherfrist fehlen kann. Klicke einen Hop an, um zu sehen, was dort geprüft wird.

BrowserHop 0 Edge / MWHop 1 API / ActionsHop 2 DatenbankHop 3 DrittanbieterHop 4 Logs · CIHop 5 MenschenHop 6 Beispiel · Kontaktformular Name, E-Mail, Nachricht fra1 · kein Cookie sendContact() loggt Body? Rate-Limit? contact_requests eu-central-1 · RLS Lösch-Cron 6 Monate Resend (US) · Sentry AVV unterschrieben? Tracking aus? Vercel-Logs 30 T Log-Drain = Auftragsverarbeiter Postfach, Dashboard MFA · Art. 15 in 30 T ein Formular → Supabase, Resend, Sentry, Vercel-Logs: vier Empfänger, die die Datenschutzerklärung nennen muss (Art. 13 Abs. 1 lit. e), jeder mit eigenem AVV und eigener Speicherdauer
Die sieben Hops aus references/architecture.md. Der laufende Punkt ist eine Absendung des Kontaktformulars; die Zeile darunter zeigt, wie jeder Hop für dieses Formular aussieht und welche Frage das Audit dort stellt.
05 · Runtime-Scanner

Drei Zustände derselben Seite

scripts/scan-origins.mjs öffnet die Seite in einem frischen Chromium-Profil und protokolliert, was der Browser tut, bevor jemand das Banner berührt. Dann klickt es „Ablehnen“ und prüft, ob etwas Neues lädt. Dann lädt es neu, klickt „Akzeptieren“ und inventarisiert alles, was die Seite laden kann — das ist die Liste, die die Datenschutzerklärung abdecken muss. In diesem letzten Schritt sucht es zuerst einen expliziten Alle-akzeptieren-Button und klickt nie eine Ablehnen-Variante wie „Nur notwendige akzeptieren“, damit das Inventar auch dann vollständig ist, wenn das Banner die Ablehnen-Option zuerst nennt. Spiele die Ausgabe auf einem der beiden Fixtures aus dem Repo ab.

frisches Chromium-Profil · de-DE · Europe/Berlin keine Cookies, kein Storage, kein vorheriger Consent A · laden + warten + scrollen → protokollieren Requests (Origin, Typ), Set-Cookie-Header, Cookies, local/sessionStorage Links: Impressum, Datenschutz, alter ODR-Link · GET /impressum, /datenschutz B · „Ablehnen“ klicken DE/EN-Regex · Rollen zuerst Differenz zu A neue Origins nach Ablehnen = 🔴 C · neu laden, „Akzeptieren“ Alle-akzeptieren zuerst · nie Ablehnen-Treffer JSON + Zusammenfassung --strict → Exit 1 · keine Seite → Exit 3 benannte blinde Flecken: GTM-Container-Inhalt, Unterseiten, Serverseite
Die drei Zustände des Scanners. Zustand A allein beantwortet die § 25-TDDDG-Frage; Zustand B erwischt CMPs, die eine Ablehnung ignorieren; Zustand C liefert die Dienstliste für Art. 13. Lädt die Seite nie, gibt es keinen Zustand A — der Scanner sagt das, statt ein leeres „bestanden“ auszugeben.
0ok1--strict-Verstoß2Bedienfehler / kein Playwright3Seite nicht geladen, kein Urteil
06 · Bewertungen

Fünf Status — und eine ehrliche Linie zwischen Gesetz und Regel

Jeder Punkt des Prüfkatalogs bekommt einen von fünf Status. Einige Regeln des Skills sind strenger als das Gesetz verlangt, weil sich für eine kleine Praxis oder einen Pflegedienst der Dokumentationsaufwand des rechtmäßigen, aber komplizierten Wegs selten lohnt. Diese Regeln bleiben im Bericht 🔴, aber der Bericht sagt, dass sie die Regel der Agentur sind, nicht das Gesetz — damit Mandant und Anwalt entscheiden können. Schalte das Beispiel um, um den Unterschied in der Formulierung zu sehen.

StatusBedeutungBeispiel
KritischRechtswidrig mit Abmahn-, Bußgeld- oder Schadensersatzrisiko. Blockiert den Go-live.GA feuert vor Consent · Google Fonts vom CDN · kein Impressum
HochKlarer Mangel, in diesem Sprint beheben.Kein Ablehnen auf der ersten Ebene · fehlende Art.-13-Angaben · alter OS-Plattform-Link · PII in Logs
MittelVertretbar, aber schwach — oder Verstoß gegen eine konservative Regel.Vage Speicherfristen · kein VVT · US-Analytics mit Consent
OKKonform.Self-hosted Fonts · AVV abgelegt · EU-Region gepinnt
UnklarBraucht Mandanten-Input oder Runtime-Verifikation. Sagt genau, was.GTM ohne Container-Export · DPF-Status einer Entität

Deployment-Regeln mit ihrer Nuance. Kein Consent → keine Drittanbieter-Ausführung (Gesetz; Essentielles wie das CMP oder ein Payment-Iframe ist nach § 25 Abs. 2 Nr. 2 TDDDG ausgenommen). Fonts und CDN-Assets self-hosted (Gesetz; Consent würde es heilen, aber niemand willigt für eine Schrift ein). Berechtigtes Interesse heilt § 25 nicht (Gesetz). Art.-9-Daten → keine US-Dienste im Datenpfad (Regel). AVV vor Go-live (Gesetz). US-Transfers nennen ihren Mechanismus, DPF nur für die gelistete Entität (Gesetz). KI-APIs sind Auftragsverarbeiter und brauchen Kennzeichnung nach Art. 50 KI-VO (Gesetz). Nie eine Erklärung kopieren (Urheberrecht). Nie einen Befund abschwächen — aber immer sagen, welcher Art er ist.

07 · Versionierung & Verteilung

Ein Tag, zwei Zielgruppen

Das Repo ist ein Claude-Code-Plugin. Ein gepushter Versions-Tag baut das .skill-Paket und veröffentlicht ein GitHub-Release: Claude-Code-Nutzer aktualisieren mit einem Befehl, Claude.ai- und Cowork-Nutzer laden eine Datei herunter. Jedes Release hält außerdem einen Rechtsstand fest — den Monat, bis zu dem die Rechtsquellen verifiziert wurden —, denn das Recht bewegt sich, und ein Compliance-Werkzeug muss sagen, wie alt sein Wissen ist.

npm run version:bump 1.1.0 --law-stand 2026-11 gleicht 4 Dateien + Stand ab CHANGELOG + Commit git tag v1.1.0 npm test muss grün sein release.yml Tag == plugin.json-Version? validate → package → release Claude Code · Plugin-Marketplace /plugin update dsgvo-audit@lxhelili Skill + Subagent, erkannt über die Version in plugin.json Claude.ai / Cowork · GitHub-Release dsgvo-audit.skill (Skill + Agent gebündelt) hochladen unter Einstellungen → Skills semver: major = Ablauf-/Berichts-/Urteilsänderungen · minor = neue Dienste, Punkte, Muster · patch = Korrekturen Rechtsstand ≠ Version: ein Patch kann den Stand bewegen; der Stand sagt dem Leser, wie alt das juristische Wissen ist
Vom Version-Bump zu beiden Zielgruppen. Der Tag muss der Version in plugin.json entsprechen, sonst verweigert der Workflow — und der Paketschritt lässt den Validator erneut laufen, damit nie ein kaputter Skill ausgeliefert wird.

Vier Stellen tragen die Version; ein Befehl hält sie gleich

plugin.json"version": "1.0.0"was Claude Code vergleicht
marketplace.json"version": "1.0.0"Katalogeintrag
package.json"version": "1.0.0"Tooling
SKILL.mdmetadata.version · law-standreist im .skill mit

npm run validate schlägt fehl, wenn sie auseinanderlaufen, wenn dem CHANGELOG der Abschnitt fehlt, wenn evals/evals.json auf ein nicht existierendes Fixture zeigt oder wenn ein bekannter früherer Fehler wieder auftaucht (grep mit Klammer-Glob, § 7 Nr. 3 UWG, ein OS-Plattform-Link ohne Entfernungshinweis). Es warnt, wenn die Description näher als 40 Zeichen an die 1024-Zeichen-Grenze kommt.

08 · Evals

Tests belegen die Werkzeuge; Evals benoten den Prüfer

npm test zeigt, dass der grep-Block Treffer findet und der Scanner den richtigen Button klickt. Es sagt nichts darüber, ob ein mit dem Skill geschriebenes Audit gut ist: ob es den GA4-Tag im Layout findet, Formspree als regelbasiertes 🔴 statt als gesetzliches einstuft oder nach der Kammer fragt, statt eine zu erfinden. Evals messen das. Jedes ist ein erfundenes Fixture, ein Prompt, wie ein Entwickler ihn tippen würde, und eine Liste von Erwartungen, an denen ein fauler Durchlauf scheitert. Mit dem Skill und ohne ihn ausgeführt, ist die Differenz der Bestehensquote der Wert des Skills; gegen die Vorversion ausgeführt, ist die Differenz das, was eine Änderung bewirkt hat.

Eval evals/files/<fixture> Prompt, wie ein Entwickler ihn tippt 8–11 Erwartungen Durchlauf mit Skill Subagent, Skill geladen Baseline ohne Skill oder mit der Vorversion Bewertung LLM-Grader: jede Erwartung bestanden / nicht, mit Beleg grade-report.mjs: Struktur, RDG, Platzhalter, § 5 DDG Benchmark mit Skill 46 / 47 ohne Skill 35 / 47 Quote · Zeit · Tokens Iteration 1 (1.1.0 gegen ohne Skill); spätere Iterationen vergleichen jedes Release mit dem vorherigen — evals/results/
Eine Iteration der Schleife von skill-creator. Dasselbe Fixture und derselbe Prompt laufen zweimal; ein Grader-Agent beurteilt die Substanz gegen die Erwartungen, ein Skript die Struktur, und der Benchmark stellt beide Konfigurationen nebeneinander.

Fünf Output-Evals, jedes gebaut, um eine Art von Fehler zu fangen

EvalFixtureWas es fängt
nextjs-ga-fonts-auditNext.js: GA4 vor Consent, Google Fonts vom CDN, Kontakt-Route zu Resend + Sentry mit dem Body in extra, regions: ["iad1"], alter ODR-LinkEvidenz zuerst, nur aus Code; der Hop-Trace (ein Formular, vier Empfänger); der Satz zur Evidenzstufe; nur Audit, wenn Audit verlangt war
static-site-runtime-scanStatische Seite mit „Nur notwendige akzeptieren“ vor „Alle akzeptieren“Dass der Scanner wirklich läuft und nicht durch HTML-Lesen ersetzt wird; dass die Ablehnen-Variante nicht für Akzeptieren gehalten wird; ein 404 hinter einem vorhandenen Impressum-Link ist 🔴
praxis-art9-intakeBuchungsseite einer ästhetischen Chirurgie: Behandlungs-Select, Textarea Beschwerden/Medikamente, Foto-Upload, Formspree, CalendlyArt. 9 an den Feldern erkannt; US-Dienste im Gesundheitspfad als regelbasiertes 🔴 mit Hinweis auf die anwaltliche Ausnahme; § 203 StGB, DSFA, DSB angesprochen; Rückfragen statt generischer Erklärung
astro-minimal-dse-generationAstro bei Hetzner, @fontsource, Plausible, nodemailer ans eigene Postfach, vollständige INTAKE.mdModuldisziplin: nur, was die Evidenz trägt; Plausible auf Art. 6 Abs. 1 lit. f, nicht auf Consent; Fristen aus dem Intake; kein Platzhalter übrig; Art. 21 hervorgehoben; LDI NRW benannt
ai-chatbot-processorOpenAI-Chat-Route mit Triage-System-Prompt, unbegrenzte chat_logs in Supabase, UI-Text „Unser Team antwortet sofort“LLM als Auftragsverarbeiter (DPA, kein Training, Speicherdauer, Region); Kennzeichnung nach Art. 50 KI-VO; Art. 22 für die Triage; Steuereingaben als Art.-9-nah; „verifizieren“ für den DPF-Status

Trigger-Evals

Zwanzig Prompts auf Deutsch und Englisch, zwölf, die den Skill öffnen sollen, und acht, die es nicht sollen (eine Supabase-Tabelle, ein Vercel-Build-Fehler, SPF für Resend). Sie testen allein die Description und schützen ihren letzten Satz — den, der gewöhnliche Entwicklungsarbeit nicht zum Audit werden lässt.

Deterministischer Grader

scripts/grade-report.mjs prüft, was kein Urteilsvermögen braucht: acht Abschnitte in der richtigen Reihenfolge, jeder 🔴/🟠-Block mit Befund, Rechtsgrundlage, Risiko, Maßnahme und Aufwand, jeder 🔴/🟠-Befund mit Evidenz-ID und Evidenzstufe, jede zitierte ID im Evidenzverzeichnis, der RDG-Hinweis, kein „abmahnsicher“, kein übrig gebliebener Platzhalter, § 5 DDG statt TMG. Goldene und kaputte Fixtures halten den Grader selbst in der CI ehrlich.

Wann laufen lassen

Jede Änderung an SKILL.md, references oder Vorlagen: Output-Evals gegen die Vorversion. Jede Änderung an der Description: Trigger-Evals, drei Durchläufe je Prompt. Ein neuer Rechtsstand: Output-Evals — und eine neue Erwartung für jedes geänderte Urteil. Ein Release: alle drei, mit den Zahlen im Changelog.

Was Evals nicht sagen können. Sie messen gegen die Fixtures und Erwartungen, die jemand geschrieben hat. Eine Rechtsposition, die in recht.md falsch ist und in einer Erwartung wiederholt wird, besteht mit voller Punktzahl. Die Primärquellen-Regel in CONTRIBUTING ist die Kontrolle der Erwartungen; die Evals kontrollieren, dass der Skill anwendet, was die Referenzen sagen.

09 · Erweitern

Vier Arten von Beiträgen, jede mit einem Ort und einer Sicherung

Die Teile, die viele Augen brauchen, sind die, die veralten: Dienst-Urteile, Rechtsquellen und Framework-Muster. Jeder hat eine Datei, in die er gehört, ein Issue-Template, das nach der nötigen Quelle fragt, und einen Test, der den wahrscheinlichsten Weg abfängt, ihn kaputt zu machen. Die vierte Art, ein Eval, ist die Art, wie eine Änderung an den anderen drei gemessen wird.

Rechtsupdate

Ein Urteil, eine Gesetzesänderung, neue Behördenleitlinien. Gehört in recht.md — und in checklist.md oder services.md, wenn es ein Urteil ändert. Braucht eine Primärquelle mit Datum. Hebt den Rechtsstand an.

Sicherung: Validator lehnt bekannt veraltete Zitate ab; PR-Checkliste fragt nach der Quelle.

Dienst-Eintrag

Eine Zeile in services.md (Consent? Rechtsgrundlage? Region? Urteil + Alternative), ein Origin-Regex in der SIGNATURES-Liste des Scanners, damit er beschriftet wird, und ein DSE-Modul, falls das generische nicht passt.

Sicherung: Scanner-Test belegt die Erkennung auf einer Fixture-Seite; Anbieter-Dokumentation Pflicht.

Muster

Ein Consent-Gating- oder Self-Hosting-Beispiel für ein noch nicht abgedecktes Framework, unter den sieben generischen Prinzipien in patterns.md. Prinzipien bleiben framework-agnostisch; Beispiele illustrieren sie.

Sicherung: Es muss den Load gaten, nicht die Nutzung; die Anti-Pattern-Liste ist die Checkliste.

Eval

Ein kleines erfundenes Fixture mit jedem Signal an seinem Platz, ein Prompt, wie ein Entwickler ihn tippen würde, und 8–11 Erwartungen in evals/evals.json, an denen ein fauler Durchlauf scheitert. Ein neues Urteil oder eine neue Rechtsposition bekommt eines, damit eine Regression sichtbar würde.

Sicherung: Validator prüft, dass Fixtures existieren und IDs eindeutig sind; der Durchlauf vergleicht mit der Vorversion.

Was npm test ausführt

PrüfungWas sie schütztWie
validate.mjsPaketintegrität, Versionsabgleich, Frontmatter, tote Verweise, Agent-Definition, Eval-DefinitionenStatische Prüfungen, keine Abhängigkeiten
phase1.test.shDie Phase-1-Befehle finden tatsächlich etwasExtrahiert den echten Bash-Block aus SKILL.md, lässt ihn auf einem Fixture-Repo laufen, prüft Treffer und dass kein Secret-Wert ausgegeben wird
grade-report.test.mjsDer deterministische Grader selbstAkzeptiert den goldenen Bericht, die DSE und das Impressum; weist den kaputten Bericht aus sieben benannten Gründen zurück
scanner.test.mjsDer Runtime-Scanner Ende-zu-EndeDrei Fälle: die nicht konforme Seite (Origins vor Consent, Ablehnen-Differenz, Akzeptieren-Inventar, alter ODR-Link), das Banner mit der Ablehnen-Option zuerst und eine unerreichbare URL, die mit Exit 3 ohne Urteil enden muss
packageDas .skill ist baubar und validiertLäuft in der CI bei jedem Push; Artefakt 14 Tage aufbewahrt