Files
breakpilot-compliance/backend-compliance/tests/fixtures/impressum_groundtruth.py
T
Benjamin Admin 389e6de0c7
CI / detect-changes (push) Successful in 8s
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / secret-scan (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / build-sha-integrity (push) Failing after 4s
CI / iace-gt-coverage (push) Has been skipped
CI / test-python-backend (push) Successful in 30s
CI / test-python-document-crawler (push) Has been skipped
CI / test-python-dsms-gateway (push) Has been skipped
CI / dep-audit (push) Has been skipped
CI / validate-canonical-controls (push) Successful in 11s
CI / loc-budget (push) Successful in 14s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / nodejs-build (push) Has been skipped
CI / test-go (push) Has been skipped
fix(agents): Impressum+Cookie delegieren MC-Laden ans Main Tool — Scope-Filter + Maßnahmen
Regression: Der v3-Agent-Pfad baute eine parallele MC-Pipeline
(_load_impressum_mcs / _load_cookie_mcs, Roh-SELECT) und lief damit an
allen Schutzmechanismen der Engine vorbei → GOV/Branchen-MCs als HIGH bei
OEM/Zulieferer, fremde MCs (Bestellbestätigung), und action=check_question
(Fragen statt Maßnahmen im Frontend).

- Agent delegiert MC-Laden an rag_document_checker._load_controls
  (P72-Scope, check_type='text', fits_doc_type/scope_requires).
- Subtraktives Sektor-Gate (SECTOR_PREFIXES) + Themen-Gate am Agent-Rand.
- action = konkrete Maßnahme (Imperativ) statt check_question.
- rag_document_checker: from __future__ import annotations (3.9-Import).
- mcs: Name-Pattern erkennt "Aktiengesellschaft" (OEM-Impressums).
- Tote GT-/Semantic-/Routes-Tests wiederbelebt (v3-Mismatch +
  agent.cascade-Patch-Target). Alle 72 Specialist-Tests grün.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 11:30:16 +02:00

254 lines
10 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Ground-Truth-Fixtures: 5 Impressums + erwartete Findings.
Quelle: User-Vorgabe 2026-06-09. Texte sind die echten Impressums von:
- ETO Gruppe Technologies GmbH (Stockach)
- SafetyKon GmbH (Freiburg)
- BMW AG (München)
- Elli (Volkswagen Group Charging + Elli Mobility, Berlin)
- Hectronic Vertriebs- und Service GmbH (Bonndorf)
Pro Impressum:
- text: Volltext (User-eingegebene Bereinigung)
- expected_findings: field_ids die wir POSITIV erwarten
- expected_clean: field_ids die NICHT auftauchen sollten
- placement_concerns: Texte die deplatziert sind (für Cross-Agent)
"""
from __future__ import annotations
from dataclasses import dataclass, field
@dataclass(frozen=True)
class ImpressumGT:
name: str
text: str
expected_findings: tuple[str, ...] = field(default_factory=tuple)
expected_clean: tuple[str, ...] = field(default_factory=tuple)
placement_concerns: tuple[str, ...] = field(default_factory=tuple)
business_scope: tuple[str, ...] = field(default_factory=tuple)
ETO = ImpressumGT(
name="ETO Gruppe",
text=(
"Impressum\n\n"
"Anbieterin i.S.d. § 5 DDG:\n\n"
"ETO GRUPPE TECHNOLOGIES GmbH\n"
"Hardtring 8\n"
"78333 Stockach\n"
"DEUTSCHLAND\n\n"
"Telefon: +49 7771 809-0\n"
"Telefax: +49 7771 809-100\n"
"E-Mail: info@etogruppe.com\n\n"
"Geschäftsführer: Volker Groß, Patrick Boos und Hubertus Stroetmann\n"
"Handelsregister: Amtsgericht Freiburg, HRB707267\n"
"USt-ID-Nr.: DE280394267\n"
),
expected_clean=(
# Alle Pflichtangaben da → keine HIGH-Findings
"name_anbieter", "kontakt_email", "kontakt_telefon",
"handelsregister", "ust_id", "vertretungsberechtigte",
"vertretungsberechtigte_label_korrekt",
),
placement_concerns=(), # ETO-Block selbst ist sauber
)
SAFETYKON = ImpressumGT(
name="SafetyKon GmbH",
text=(
"Datenschutz Verantwortlich für die Inhalte dieser Website\n\n"
"SafetyKon GmbH\nMerzhauser Str. 144\n"
"79100 Freiburg im Breisgau\n"
"Telefon 0761 / 48 98 09 01\n"
"E-Mail: info@safetykon.de\n\n"
"Geschäftsführung: Dr. Oliver Kirchwehm\n\n"
"Sitz und Registergericht: Handelsregister AG Freiburg, HRB 709859\n\n"
"Umsatzsteueridentifikationsnummer: DE288952921\n\n"
"Urheberrecht\n"
"Diese Webseiten dienen der Information über die SafetyKon GmbH...\n"
"Bilder & Lizenzen\n"
"Screenshot SISTEMA: Aleksandr_Samochernyi / Freepik\n"
"Haftungsausschluss für Informationen\n"
"Die Inhalte dieser Webseiten dienen lediglich allgemeinen Informationszwecken...\n"
"Haftungsausschluss für Links\n"
"Inhalte derjenigen fremden Internetseiten...\n"
),
expected_clean=(
"name_anbieter", "kontakt_email", "kontakt_telefon",
"handelsregister", "ust_id", "vertretungsberechtigte",
"vertretungsberechtigte_label_korrekt",
),
placement_concerns=(
"urheberrecht", # gehört in Legal/Copyright-Seite
"bilder_lizenzen", # gehört in Legal/Copyright-Seite
"haftungsausschluss", # gehört in Legal/Disclaimer-Seite
),
)
BMW = ImpressumGT(
name="BMW AG",
text=(
"Impressum.\n"
"Diese Webseite wird von der Bayerische Motoren Werke "
"Aktiengesellschaft (Petuelring 130, 80809 München) betrieben.\n\n"
"Kontakt BMW: kundenbetreuung@bmw.de\n"
"Telefon: 089 1250 160 00\n\n"
"Die Bayerischen Motoren Werke Aktiengesellschaft (BMW AG) wird "
"gesetzlich durch den Vorstand (Milan Nedeljković, Vorsitzender, "
"Jochen Goller, Ilka Horstmeier, Nicolai Martin, Walter Mertl, "
"Joachim Post, Raymond Wittmann) vertreten.\n\n"
"Vorsitzender des Aufsichtsrats: Nicolas Peter\n\n"
"Sitz und Registergericht: München HRB 42243\n"
"Umsatzsteueridentifikationsnummer: DE129273398\n\n"
"Versicherungsvermittlerregister: D-GKZS-MTLXN-32\n\n"
"Erlaubnisbefreiung nach § 34 d Abs. 6 GewO, Aufsichtsbehörde:\n"
"IHK für München und Oberbayern\n"
"Max-Joseph-Straße 2\n80333 München\n\n"
"Berufsbezeichnung: Versicherungsvertreter mit Erlaubnisbefreiung "
"nach § 34d Abs. 6 GewO\n\n"
"Berufsrechtliche Regelungen:\n"
"• § 34 d Gewerbeordnung\n• §§ 59-68 VVG\n• VersVermV\n"
),
expected_clean=(
"name_anbieter", "kontakt_email", "kontakt_telefon",
"handelsregister", "ust_id", "vertretungsberechtigte",
"vertretungsberechtigte_label_korrekt",
# BMW listet IHK München als Aufsicht → MC-008 sollte OK sein
"aufsichtsbehoerde",
),
# Berufsangaben ist da → bei scope regulated_profession OK
business_scope=("regulated_profession",),
)
ELLI = ImpressumGT(
name="Elli (VW Group Charging + Elli Mobility)",
text=(
"Impressum\n"
"Anbieterkennzeichnung für Inhalte zu Zuhause laden, Flexpole "
"und Energielösungen:\n\n"
"Volkswagen Group Charging GmbH\n"
"Sitz in Berlin.\n"
"Geschäftsführer:\n"
"Giovanni Palazzo (CEO)\n"
"Mark Möller (CTO)\n"
"Dr. Tobias Canz (CFO)\n"
"Anja Christmann (CHRO)\n\n"
"Postanschrift: Karl-Liebknecht-Str. 32, 10178 Berlin\n"
"Telefonnummer: 00800 3554 1111\n"
"E-Mail: info@elli.eco\n\n"
"Handelsregister Amtsgericht Charlottenburg HRB 208967 B\n\n"
"Verantwortlich für den Inhalt nach § 55 Abs. 2 RStV:\n"
"Giovanni Palazzo, Karl-Liebknecht-Str. 32, 10178 Berlin\n\n"
"Anbieterkennzeichnung für Inhalte zu Öffentlich laden (MSP), "
"Flottenlösungen, CSM, Charge&Fuel:\n\n"
"Elli Mobility GmbH\nSitz in Berlin.\n"
"Geschäftsführer: Joschi Jennermann, Sebastian Steffen\n\n"
"Postanschrift: Karl-Liebknecht-Str. 32, 10178 Berlin\n"
"Telefonnummer: 00800 00002030\n"
"E-Mail: ellimobility@elli.eco\n\n"
"Handelsregister Amtsgericht Charlottenburg HRB 274616 B\n\n"
"Umsatzsteueridentifikationsnummer: DE814424009\n\n"
"Verantwortlich für den Inhalt nach § 55 Abs. 2 RStV:\n"
"Joschi Jennermann und Sebastian Steffen\n\n"
"Die Europäische Kommission stellt eine Plattform zur "
"Online-Streitbeilegung (OS) bereit: "
"http://ec.europa.eu/consumers/odr/.\n\n"
"Schlichtungsstelle Energie e.V., Friedrichstr. 133, 10117 Berlin\n"
),
expected_clean=(
"name_anbieter", "kontakt_email", "kontakt_telefon",
"handelsregister", "ust_id", "vertretungsberechtigte",
"vertretungsberechtigte_label_korrekt",
"odr_link", # explizit drin
# § 18 MStV bzw. § 55 Abs. 2 RStV ist genannt; bei editorial-scope OK
),
business_scope=("ecommerce", "b2c"), # Charging-Provider B2C
)
HECTRONIC = ImpressumGT(
name="Hectronic Vertriebs- und Service GmbH",
text=(
"Impressum\n\n"
"Hectronic Vertriebs- und Service GmbH | Allmendstrasse 15 | "
"79848 Bonndorf | Tel. +49 30 8632459 10 | "
"Fax: +49 30 8632 459 89 | info@hectronic.de\n\n"
"Geschäftsführer: Stefan Schiefelbein, Sebastian Mömkes, "
"Stefan Forster\n\n"
"Sitz der Gesellschaft: D-79848 Bonndorf\n"
"Amtsgericht Freiburg, HRB 709669 | USt-IdNr.: DE287652484\n\n"
"Inhaltlich Verantwortlich gemäß § 18 Abs. 2 MStV\n"
"Eckhard Fechtig (Anschrift siehe oben)\n\n"
"Angaben nach dem Elektro- und Elektronikgerätegesetz (ElektroG)\n"
"WEEE-Reg.-Nr.: DE 64824538\n\n"
"Copyright\n"
"Alle verwendeten Fotos, Grafiken, Texte und sonstigen Bestandteile "
"dieser Website unterliegen dem Copyright der Hectronic GmbH...\n\n"
"Haftungsausschluss\n"
"Die Inhalte unserer Internetseiten werden sorgfältig geprüft...\n"
),
expected_clean=(
"name_anbieter", "kontakt_email", "kontakt_telefon",
"handelsregister", "ust_id", "vertretungsberechtigte",
"vertretungsberechtigte_label_korrekt",
"verantwortlicher_redaktion", # Fechtig nach § 18 MStV genannt
),
placement_concerns=(
"weee_elektrog", # gehört eher in Produkt/Recycling-Seite
"copyright", # gehört in Legal/Copyright-Seite
"haftungsausschluss", # gehört in Legal/Disclaimer-Seite
),
business_scope=("editorial",), # weil § 18 MStV genannt
)
ALL_GROUND_TRUTH = (ETO, SAFETYKON, BMW, ELLI, HECTRONIC)
def make_mc(
control_id: str,
pass_criteria: list[str],
severity: str = "HIGH",
title: str | None = None,
regulation: str = "TMG",
article: str = "§ 5",
check_question: str | None = None,
) -> dict:
"""Baut ein doc_check_controls-MC-Dict wie `_load_controls` es liefert —
fuer Tests die `_load_controls` mocken (Agent delegiert ans Main Tool)."""
return {
"id": control_id,
"control_id": control_id,
"title": title or control_id,
"regulation": regulation,
"article": article,
"severity": severity,
"check_question": check_question or f"Ist {control_id} vorhanden?",
"pass_criteria": list(pass_criteria),
"fail_criteria": [],
}
# Kern-Impressum-MCs die ein vollstaendiges Impressum erfuellt. Der
# Regex-Boost (Layer 0) hebt sie bei vorhandenen Pflichtangaben auf PASS,
# sodass ein sauberes Impressum 0 Findings produziert. Jede pass_criteria
# enthaelt >=2 Boost-Keywords damit boost_matches_db_mc greift.
CORE_IMPRESSUM_MCS: list[dict] = [
make_mc("IMP-NAME-A1", ["Anbieter Anschrift Adresse Firma angegeben"]),
make_mc("IMP-MAIL-A1", ["E-Mail Kontaktmöglichkeit angegeben"]),
make_mc("IMP-TEL-A1", ["Telefon Telefonnummer Rufnummer angegeben"],
severity="MEDIUM"),
make_mc("IMP-HR-A1", ["Handelsregister Registernummer HRB angegeben"]),
make_mc("IMP-UST-A1", ["Umsatzsteuer USt-IdNr angegeben"],
severity="MEDIUM"),
make_mc("IMP-VTR-A1",
["Geschäftsführer Vorstand Vertretungsberechtigt angegeben"]),
make_mc("IMP-VTRL-A1",
["Geschäftsführer Vorstand deutsche Bezeichnung Rechtsform"],
severity="MEDIUM"),
]