fix(b19): UNK-Noise drastisch reduzieren

BMW4 zeigte 1037 UNK-Findings — die Mail wurde damit unleserlich.
Drei pragmatische Anpassungen:

1. UNK severity: LOW → INFO. Mail-Renderer zeigt jetzt nur
   HIGH/MEDIUM/LOW; INFO bleibt im API-Payload + CSV.
2. UNK wird NICHT emittiert wenn Vendor=First-Party-Owner
   (z.B. "BMW AG" auf bmw.de). Heuristik _is_first_party_owner
   vergleicht Vendor-Name gegen Domain-SLD.
3. auto_learning threshold ≥3 Sites → ≥1 Site. Second-time-Audit
   einer Site hat ihre eigenen Cookies bereits gelernt → kein
   UNK mehr. Single-site Auto-Learning ist absichtlich
   konservativ (Annotation, kein Truth).

Effekt: erwartete Reduktion bei BMW von 1037 UNK → ~50-100
(nur unbekannte 3rd-party-Vendoren). Mail wird lesbar, MAE-
Findings (Salesforce-as-essential) bleiben prominent sichtbar.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-06-08 08:20:39 +02:00
parent eecbd8fc69
commit 327e6a8984
3 changed files with 54 additions and 12 deletions
@@ -40,9 +40,14 @@ def _render(findings: list[dict]) -> str:
severity_color = {
"HIGH": "#dc2626", "MEDIUM": "#f59e0b", "LOW": "#64748b",
}
# Show only the top 12 cards in the mail; rest goes to CSV
# Show only HIGH/MEDIUM/LOW cards in the mail; INFO (UNK auto-
# learning) bleibt nur in CSV — sonst überfüllt die Mail.
mail_findings = [
f for f in findings
if (f.get("severity") or "").upper() in ("HIGH", "MEDIUM", "LOW")
]
cards = []
for f in findings[:12]:
for f in mail_findings[:12]:
sev = (f.get("severity") or "").upper()
color = severity_color.get(sev, "#475569")
meta = ""
@@ -93,8 +98,10 @@ def _render(findings: list[dict]) -> str:
f"BreakPilot-KB.<br><strong>Verteilung:</strong> {type_summary}</p>"
+ "".join(cards)
+ (f"<p style='font-size:12px;color:#64748b;margin-top:8px;'>"
f"<em>… und {len(findings)-12} weitere — vollständige Liste "
f"in <code>cookies-full.csv</code> im ZIP-Anhang.</em></p>"
if len(findings) > 12 else "")
f"<em>… und {len(findings)-len(cards)} weitere "
f"(inkl. {len(findings) - len(mail_findings)} INFO/UNK) "
f"— vollständig in <code>cookies-full-*.csv</code> im "
f"ZIP-Anhang.</em></p>"
if len(findings) > len(cards) else "")
+ "</div>"
)