Email-Review (Pre-Send Check)

Reviewt Kunden-Emails mit angehaengten PDFs, bevor Marvin auf Senden drueckt. Findet Doppelungen, AI-Halluzinationen, Versions-Drift und Stilbrueche. Gibt einen Severity-sortierten Report zurueck. Sendet nie selbst, fixt nichts auto.

Anlass: am 06.05.2026 hat Ralf (Becker) zurueckgespielt dass im V2-PDF Doppelungen drin waren. Soll nicht nochmal passieren.

1. Wann triggert der Skill

  • “Check den Draft an Ralf”
  • “Review den Angebots-Draft”
  • “Koennen wir das so rausschicken?”
  • “Geh den Draft mal durch bevor ich abschicke”
  • “Pruef den Entwurf an Kunde Y”
  • “Pre-send Check fuer das Angebot”
  • “Hat das Doppelungen?”
  • Marvin zeigt einen Draft (Markdown oder Gmail-Link) mit der Bitte um Review

Negativ-Trigger (nicht hier, woanders): “schreib eine Mail an X” → email-schreiben. “antwort auf Y” → email-schreiben. “review den PDF-Inhalt nur” → kein Skill, einfach lesen.

2. Eingaben sammeln (1 bis 5 Minuten)

In dieser Reihenfolge, nichts ueberspringen.

a) Den Draft laden. mcp__gsuite__list_gmail_drafts mit Query auf den Empfaenger-Namen oder die Empfaenger-Domain. Wenn mehrere Drafts an die Person laufen → bei Marvin nachfragen welcher gemeint ist, nicht raten.

# Beispiel
mcp__gsuite__list_gmail_drafts(
    __user_id__="hello@marvinkuehlmann.com",
    query="to:Ralf.Schmid@becker-metals.com",
    max_results=10,
)

Dann mcp__gsuite__get_gmail_email mit der message_id aus dem Draft-Listing fuer den vollen Body + Anhang-IDs.

b) Anhaenge ziehen. Pro Attachment mcp__gsuite__get_gmail_attachment mit save_to_disk=true. Default-Pfad: /tmp/email-review/<draft-id>/<filename>. PDFs werden danach mit dem Read-Tool geoeffnet (Read kann PDFs direkt, fuer mehr als 10 Seiten pages: setzen). Word- oder Excel-Anhaenge mit dem Anthropic-docx/xlsx-Skill.

c) Kunde identifizieren. Aus Empfaenger-Domain → Kunden-Slug (becker-metals.combecker). Dann lesen, in dieser Reihenfolge:

  1. intern/kunden/<kunde>.md — Stammdaten, Ansprechpartner, Do’s/Don’ts
  2. intern/projekte/<projekt>/_index.md — Projekt-Scope (z.B. bas-twin/_index.md)
  3. intern/projekte/<projekt>/verlauf.md — was lief vorher (append-only Zeitlinie)
  4. Vorgaenger-Versionen von Deliverables: extern/outbound/deliverables/<kunde>/<projekt>/... oder beim alten Repo ~/source/agent-agentur/wiki/kunden/<kunde>/artefakte/<datum>/ falls noch nicht migriert

Wenn Empfaenger-Domain keinem Kunden-Ordner zugeordnet werden kann, bei Marvin nachfragen — nicht raten.

d) Mail-Thread entlangschauen. Wenn der Draft eine Reply ist (in_reply_to-Header gesetzt), den ganzen Thread mit mcp__gsuite__get_gmail_email durchgehen. Besonders die letzte Mail vom Kunden lesen — da steht meistens drin, was er als naechstes erwartet (z.B. “ich habe V2 angepasst, schick mir V3 mit X und Y”).

e) Vorgaenger-Version laden. Wenn V3 versandt werden soll, V2 aus extern/outbound/deliverables/<kunde>/<projekt>/archive/ lesen — das ist der wichtigste Vergleichspunkt fuer Doppelungs- und Drift-Checks.

f) Email-Footer-Stand. intern/firma/email-footer.md lesen. UG i.G. vs UG eingetragen — der Stand aendert sich, der Footer im PDF muss damit synchron sein.

3. Die Pruef-Liste — 10 Punkte

Geht jeden Punkt durch, in dieser Reihenfolge. Pro Punkt eine knappe Diagnose: ✅ ok / 🟡 Hinweis / 🔴 Blocker.

3.1 Adressat & Anrede

  • Empfaenger-Adresse korrekt (Tippfehler, falscher Account-Domain)
  • Anrede passt zum Beziehungsstand (profil.md schauen — Du/Sie, Vorname/Nachname)
  • Name korrekt geschrieben (Ralf vs Ralph, Schmid vs Schmidt)
  • Firmenname im Body korrekt (Becker Aluminium-Service vs Becker Stahl vs Becker Metals)

3.2 Stil — gegen style-profile-marvin pruefen

Vor diesem Check style-profile-marvin laden. Das Profile ist Korpus-basiert (28 echte Mails) und enthaelt die echten Patterns.

  • Anrede-Stufe passt zum Adressat (Sektion 1 des Profiles — Cold-Outreach / Locker-Du / Du-Business / Semi-formell / Formell-Sie)
  • Abschluss-Formel matched Anrede-Stufe (Sektion 2 — z.B. „Mit freundlichen Gruessen” nur bei Sehr-geehrte-Anrede, „Schoene Gruesse” bei Hi-Anrede)
  • Echte Umlaute (ä ö ü ß im Body, nicht ae/oe/ue/ss)
  • Em-Dashes sind in Du-Mails OK (Marvin nutzt sie typischerweise). In Sie-formell-Mails an Bank/Notar/Behoerde raus. Subject-Lines: Em-Dash auch in Sie-Mails seltener.
  • Doppelpunkte sowohl mid-sentence (Erklär-DP) als auch Listen-Header sind OK (gegen die alte Regel). In Sie-formell-Behoerden-Mails Erklär-DP eher vermeiden, Listen-DP bleibt OK.
  • Anti-Floskel-Check gegen Sektion 7 des Profiles („spannende Konstellation”, „etwas konkretes zuliefern”, „in der Regel”, „im Vordergrund stehen”, „erforderlich”, „bedeutet” etc. → raus, Ersatz aus der Tabelle)
  • Erster Satz nach Anrede ist direkter Bezug oder direkter Zur-Sache-Einstieg, nicht Anbiederung
  • Tempo-Wechsel vorhanden (kurze und lange Saetze gemischt, keine 3 Schachtelsaetze hintereinander)
  • Ich-Form bei Marvin-Mails (gegen „wir”-Plural ausser bei echtem Plural)
  • Keine Schachtel-Saetze, keine Newsletter-Floskeln, keine angestrengte Hoeflichkeit

3.3 Body matched Anhaenge

  • Jeder Anhang den der Body verspricht ist tatsaechlich angehaengt
  • Jeder Anhang der angehaengt ist wird im Body erwaehnt (sonst Verwirrung)
  • Anhang-Filenames sprechend und ASCII (angebot-v3-final.pdf, nicht Dokument1.pdf)
  • Filename matched Inhalt (Datei angebot-v3-final.pdf enthaelt V3, nicht V2)

3.4 Versions-Konsistenz

Wenn der Body “V3” sagt, muss in allen Anhaengen V3 stehen — auf Deckblatt, im Header/Footer, im Filename, in evtl. Anlagen-Verweisen.

  • Filename-Version = Body-Version = PDF-Cover-Version = PDF-Footer-Version
  • Anlagen-Verweise im Hauptdokument zeigen auf vorhandene Anlagen (Anlage A, B, C … alle existieren im Anlagen-PDF)

3.5 Zahlen-Check (wichtigster Schritt)

Jede Zahl im Body und in den PDFs gegen Source-of-Truth pruefen:

  • Preise (netto/brutto, Stundensatz, Monats-Sockel, Setup-Pauschale)
  • Stunden-Schaetzungen
  • Termine und Fristen
  • Laufzeiten (Vertrag, Kuendigungsfrist)
  • Mengen (Anzahl Reports, Anzahl Workshops, Anzahl Nutzer)
  • Summen — gehen die Einzelposten in der Summe auf? (haeufige Hallu-Falle)

Wenn eine Zahl im Body von der gleichen Zahl im PDF abweicht → 🔴 Blocker. Wenn eine Zahl nicht aus profil.md/scope.md/Mail-Thread ableitbar ist → 🟡 Hinweis “Zahl X im Body kann ich nicht belegen, bitte gegenchecken”.

3.6 Doppelungen (das ist Ralfs Punkt)

In den PDFs suchen nach:

  • Identische Absaetze die zweimal vorkommen
  • Identische Bullet-Listen die zweimal kommen
  • Anlagen-Titel die mehrfach vergeben sind (“Anlage A” zweimal)
  • Gleicher Inhalt in Hauptdokument und Anlage (statt Verweis)
  • Kapitel-Ueberschriften die zweimal kommen

Methode: PDF-Text mit Read ziehen, dann nach Absatz-Hashes suchen oder die ersten 60 Zeichen jedes Absatzes als Liste ausgeben und auf Duplikate pruefen. Bei laengeren Dokumenten ein kleines Python-Skript schreiben (siehe scripts/find-duplicates.py).

Im Body suchen nach:

  • Gleicher Satz nochmal in anderer Formulierung (haeufig wenn Marvin V2-Body wiederverwendet und V3-Aenderung dazuschreibt)

3.7 AI-Halluzinations-Check

Jede konkrete Aussage auf Belegbarkeit pruefen. “Belegbar” heisst: steht im Mail-Thread, in intern/kunden/<kunde>.md + intern/projekte/<projekt>/, in Vorgaenger-PDFs, in intern/runs/ oder intern/wissen/.

Typische Halluzinations-Stellen:

  • Gespraechs-Bezugnahmen (“wie besprochen am 23.04.“) — gab es den Termin wirklich?
  • Personen-Zitate (“Alex sagte, dass …“) — gibt es das Zitat?
  • Tool-Versprechen (“Das System kann X automatisiert ausgeben”) — ist das Scope-belegt?
  • Referenz-Cases (“haben wir auch bei Kunde Z so gemacht”) — gibt es Kunde Z?
  • Termine (“Liefertermin Freitag”) — steht der irgendwo verbindlich?

Wenn Aussage nicht belegbar → 🟡 oder 🔴 je nach Tragweite. Lieber einmal zuviel flaggen.

3.8 Platzhalter und Boilerplate

grep im Body und in den PDFs nach:

  • TODO, FIXME, XXX, ???
  • [Name], [Kunde], [Datum], <Platzhalter>, {{var}}
  • Lorem ipsum
  • Restbestaende aus Vorlagen (Sehr geehrte Damen und Herren, wenn Anrede oben schon personalisiert ist)
  • Doppelte Leerzeichen, doppelte Zeilenumbrueche an unsinnigen Stellen

3.9 Footer/Signatur-Stand

  • Email-Body-Signatur matched aktueller Stand aus intern/firma/email-footer.md
  • PDF-Footer (Impressum, Firmierung, USt-ID) matched aktueller Stand
  • UG i.G. vs UG eingetragen muss konsistent sein zwischen Body, PDF-Cover, PDF-Footer

3.10 Rechtschreibung & Grammatik

  • Deutsche Rechtschreibung im Body und PDF
  • Gross-/Kleinschreibung bei Substantiven
  • Komma-Setzung (besonders Relativsaetze)
  • Falsche Freunde (z.B. “Sinn machen” → “sinnvoll sein”, wenn Marvin formell schreibt)

4. Report-Format

Strukturierter Report. Marvin liest ihn in 30 Sekunden und entscheidet.

## Email-Review: <Subject> an <Empfaenger>

**Draft:** <gmail-Direktlink>
**Anhaenge:** <name-1.pdf> (X Seiten), <name-2.pdf> (Y Seiten)
**Kunde:** <kunde-slug> — Quellen geprueft: profil.md, scope.md, V2-Anhang

### 🔴 Blocker (vor Senden fixen)
1. [Punkt] **Was:** ... **Wo:** angebot-v3-final.pdf S.2 vs Body Absatz 3 **Vorschlag:** ...
2. ...

### 🟡 Hinweise (sollten gefixt werden)
1. ...

### 🟢 Hinweise (kosmetisch)
1. ...

### ✅ Geprueft und ok
- Zahlen-Konsistenz Body↔PDF (3 Stellen)
- Versionsangaben (V3 in 4/4 Stellen)
- Anlagen-Verweise (A bis G alle vorhanden)
- Stil-Regeln (keine Gedankenstriche, keine Doppelpunkte)
- Footer-Stand (UG i.G., synchron)

### Empfehlung
<senden / nicht senden / mit Aenderungen senden>

Wenn 0 Blocker und 0 Hinweise: einzeiliger gruener OK-Report, kein Theater.

5. Was der Skill NICHT macht

  • Nicht senden. Niemals. Auch wenn Marvin “ok pass schon” sagt — dann auf den Skill email-schreiben Schritt 7 verweisen oder Marvin selbst schicken lassen.
  • Nicht autofixen. Findings sind Vorschlaege. Marvin entscheidet was geaendert wird. Ausnahme: wenn Marvin explizit “fix die Findings und zeig mir den Diff” sagt.
  • Nicht tiefer ins PDF eingreifen (Layout, Seitenumbrueche, Schriftarten) — das ist Pandoc/Typesetting-Sache, nicht Inhalts-Review.
  • Keine Rechtspruefung. Wenn Vertraege gereviewt werden, sagen “ich pruefe Inhalt und Konsistenz, keine juristische Pruefung — fuer §-Anpassungen Anwalt einschalten”.

6. Stolper-Defaults

  • PDFs lesen. Read-Tool kann PDF, fuer >10 Seiten pages: setzen. Wenn das Tool das PDF nicht aufmacht (gescannt, kein Text-Layer), Marvin sagen — dann ist Inhalts-Review nicht moeglich, nur Filename/Anhang-Konsistenz.
  • Mehrere Drafts an die gleiche Person. Vorkommen: Marvin hat zwei Drafts mit aehnlichem Subject offen. Immer Draft-IDs auflisten und nachfragen welcher gemeint ist.
  • Anlagen-PDF separat. Wenn das Anhang-Set aus <doc>.pdf + <doc>-anlagen.pdf besteht (Becker-Pattern), beide laden — Doppelungs-Check oft nur zwischen den beiden zu sehen.
  • Vorgaenger-Versionen liegen unter extern/outbound/deliverables/<kunde>/<projekt>/archive/<datum>--<slug>--superseded.md. Nicht im inbox/, nicht im Mail-Thread suchen wenn die im Repo sind.
  • Mail-Thread vs Repo-Version. Marvin schickt manchmal eine andere Version als im Repo gespeichert ist — den Anhang aus dem Draft als Master nehmen, Repo als Vergleichsquelle.
  • Vor Annahme „X ist neuer Punkt von Marvin” — Vorgaenger-Version diffen. Wenn der Kunde eine Vorversion zurueckgeschickt hat (z.B. ralf-v2-bearbeitet.docx), zuerst pandoc-konvertieren und mit der aktuellen Version vergleichen. Sonst Risiko: man flaggt Klauseln als „neue Vertragsbedingung” die in Wahrheit der Kunde selbst eingebracht hat. Im Becker-Run 2026-05-06 waren vier von acht Schein-Blockern in Wahrheit Ralfs eigene V2-Punkte (24-Monate-Laufzeit, Erfolgskomponente, EU AI Act 4.500 €, HRB-Adresse).
  • Vor „Source nicht im Repo”-Behauptung — Volltext-Grep. Filename-Suche reicht nicht. Wenn ein PDF gerendert wurde, gibt es oft eine HTML/MD/DOCX-Source mit aehnlichem aber nicht identischem Namen. Erst grep -rln "<eindeutiger-Inhalts-String>" intern/ extern/ durchs ganze Repo laufen lassen, dann erst behaupten dass keine Source existiert. Im Becker-Run hatte ich anfangs angebot-v4.html uebersehen weil ich nur nach *anlagen* gefiltert hatte — die Source mit fast identischer Anlagen-Struktur lag unter ganz anderem Namen.

6b. PDF-Roundtrip wenn Source fehlt

Wenn das gesendete PDF korrigiert werden muss und die Source nicht (mehr) existiert, ist der Roundtrip:

  1. Inhalt rekonstruieren aus dem PDF-Text (Read-Tool kann PDF), als saubere .md ins Repo schreiben — damit existiert ab jetzt eine versionierbare Source
  2. Pandoc → DOCX mit Default-Stiles, NICHT mit --reference-doc=<existing.docx> wenn das Reference-Dokument keine Table-Styles definiert. Sonst rendert pandoc Markdown-Tabellen zu flachen Listen. Default ist robuster.
  3. Theme-Font im DOCX patchen auf Calibri (oder den Font des Hauptdokuments) damit Optik konsistent: Datei unpacked/word/theme/theme1.xml, <a:latin typeface="..."/> in majorFont und minorFont ersetzen. Dann pack.py.
  4. LibreOffice → PDF rendern: /Applications/LibreOffice.app/Contents/MacOS/soffice --headless --convert-to pdf --outdir <dir> <file.docx>
  5. Sanity-Check mit Read pdf pages:1-3 ob Tabellen + Schrift + Korrekturen sauber durchgekommen sind, bevor in Repo-Pfad uebertragen wird.

Pattern aus Becker V3-Roundtrip 2026-05-06.

7. Beispiel-Run — der Ralf-Draft (06.05.2026)

Trigger: "check den Draft an Ralf"

Schritt 1: list_gmail_drafts(query="to:Ralf.Schmid@becker-metals.com")
  → 1 Draft: "Re: Angebot Digital Twin", 2 Anhaenge

Schritt 2: get_gmail_email(message_id) → Body + Anhang-IDs
Schritt 3: get_gmail_attachment(jeweils) → /tmp/email-review/.../*.pdf
Schritt 4: kunde = becker
  Read intern/kunden/becker.md, intern/projekte/bas-twin/_index.md, verlauf.md
  Read extern/outbound/deliverables/becker/bas-twin/archive/<...>--angebot-v2--superseded.md (Vorgaenger)
Schritt 5: Read der zwei PDFs
Schritt 6: 10-Punkt-Liste durchgehen
Schritt 7: Report ausgeben

8. Selbstcheck vor dem Report

Drei Sekunden:

  1. Habe ich Body und alle Anhaenge tatsaechlich gelesen, nicht nur skimmed?
  2. Habe ich profil.md plus die Vorgaenger-Version geladen?
  3. Ist mein Report konkret (Datei + Stelle + Vorschlag) oder nur “guck nochmal drauf”?
  4. Severity ehrlich vergeben — nicht alles 🔴 markieren um wichtig zu wirken, nicht alles 🟢 um nett zu sein.

Erst dann reporten.

  • style-profile-marvinSource of Truth fuer §3.2 Stil-Check. Korpus-basiert, Anrede-Stufen, Em-Dash/DP-Regeln, Anti-Floskeln
  • SKILL — Email-Draft-Workflow (Aufbau-Pattern, Account-Wahl, Anhang-Vorbereitung)
  • email-footer — Footer-Stand (UG i.G. vs eingetragen)
  • _context — Aufbau Kunden-Ordner
  • CLAUDE — Behavior Rule 15 (Sprache), Rule 17 (Datenintegritaet Kundenfiles)
  • pandoc-docx-pdf-pipeline — PDF-Roundtrip §6b
  • gsuite — Gmail-MCP