feat(audit): P106 MC-Audit-Type + P83 BUILD_SHA in Dockerfiles + P80 v2 full
CI / secret-scan (push) Has been skipped
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / validate-canonical-controls (push) Successful in 16s
CI / detect-changes (push) Successful in 11s
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / loc-budget (push) Failing after 16s
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) Successful in 2m42s
CI / test-go (push) Has been skipped
CI / iace-gt-coverage (push) Has been skipped
CI / test-python-backend (push) Successful in 41s
CI / test-python-document-crawler (push) Has been skipped
CI / test-python-dsms-gateway (push) Has been skipped

P106 — mc_audit_type.py: zentrales Quality-Thema.
Klassifiziert pro MC: verifiable / process_internal / doc_internal /
ambiguous. Pattern-Match auf check_question + title + fail_criteria
(Schulung, AVV abgeschlossen, TOM umgesetzt, DSFA durchgefuehrt,
Ausnahmen dokumentieren, kostenfrei zur Verfuegung, opt-out
intern ermoeglichen, …).

Interne MCs werden in der MC-Auswertung NICHT mehr als FAIL gewertet,
sondern als CHECK markiert (audit_status='check'). Sie zaehlen im
build_scorecard als skipped (nicht failed) damit der Score realistisch
ist. build_internal_checks_block_html() rendert sie als separaten
blauen Block 'Pruefungen die wir von aussen NICHT durchfuehren koennen'
nach dem MC-Scorecard.

Erwartete Wirkung: bei VW 95 FAILs → wahrscheinlich 30-40 echte
verifiable_fails + 50-60 internal_checks. GF-Mail wird drastisch
realistischer (statt 'Sie haben 95 Verstoesse' → 'Sie haben 35
extern sichtbare Themen + 60 interne Checks, bitte mit DSB klaeren').

P83 — BUILD_SHA in backend/admin/consent-tester Dockerfiles als
ARG + ENV. check-rebuild-needed.sh kann jetzt deployed vs local SHA
vergleichen + REBUILD REQUIRED melden.

P80 v2 — check_replay.py macht jetzt vollstaendigen Replay aller
post-fetch Quality-Generatoren: vendor_normalizer (Dedup),
audit_quality_checks, cookie_compliance_audit, tcf_vendor_authority,
cookie_value_entropy, cookie_network_tracer. Snapshots aus alter Zeit
zeigen jetzt im Replay den aktuellen Audit-Stand.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-05-22 08:57:02 +02:00
parent bd65b6f318
commit e2be51b0aa
7 changed files with 384 additions and 11 deletions
@@ -86,27 +86,81 @@ def replay_from_snapshot(
parts: list[str] = []
# P80 v2 — Quality-Checks aus dem aktuellen Code auf Snapshot-Daten
# anwenden. Wir replayen NICHT die MC-Pipeline (zu schwer ohne
# rag_document_checker re-run), aber alle nachgelagerten Findings-
# Generatoren (audit_quality, cookie_compliance_audit, vendor_normalizer,
# entropy, network-trace) bekommen Snapshot-Daten und liefern den
# aktuellen Stand.
# anwenden. Vollstaendiger Replay aller post-fetch Findings-Generatoren.
cookie_t = doc_texts.get("cookie") or doc_texts.get("dse") or ""
# Vendor-Normalize (Dedup + Garbage-Filter)
try:
from compliance.services.vendor_normalizer import normalize_vendors
cmp_vendors = normalize_vendors(list(cmp_vendors))
except Exception as e:
logger.warning("Replay v2: normalizer failed: %s", e)
# Audit-Quality
try:
from compliance.services.audit_quality_checks import (
run_all as run_aq,
run_all as run_aq, build_audit_quality_block_html,
)
cookie_t = doc_texts.get("cookie") or doc_texts.get("dse") or ""
aq = run_aq(banner_result, cookie_t, cmp_vendors, doc_entries)
if aq:
from compliance.services.audit_quality_checks import (
build_audit_quality_block_html,
)
aq_html = build_audit_quality_block_html(aq)
parts.append(aq_html)
section_sizes["audit_quality_v2"] = len(aq_html)
except Exception as e:
logger.warning("Replay v2: audit_quality failed: %s", e)
# Cookie-Compliance-Audit
try:
from compliance.services.cookie_compliance_audit import (
audit_cookie_compliance, build_cookie_audit_block_html,
)
ca = audit_cookie_compliance(db, cookie_t, banner_result)
if ca and (ca.get("declared_count") or ca.get("browser_count")):
ca_html = build_cookie_audit_block_html(ca)
parts.append(ca_html)
section_sizes["cookie_audit_v2"] = len(ca_html)
except Exception as e:
logger.warning("Replay v2: cookie_audit failed: %s", e)
# TCF Authority
try:
from compliance.services.tcf_vendor_authority import (
cross_reference_with_tcf, build_tcf_authority_block_html,
)
tcf = cross_reference_with_tcf(db, cmp_vendors)
if tcf:
tcf_html = build_tcf_authority_block_html(tcf)
parts.append(tcf_html)
section_sizes["tcf_v2"] = len(tcf_html)
except Exception as e:
logger.warning("Replay v2: tcf failed: %s", e)
# Entropy + Network-Trace
try:
from compliance.services.cookie_value_entropy import (
check_cookies_for_entropy_mismatch, build_entropy_block_html,
)
from compliance.services.cookie_network_tracer import (
trace_cookie_network, build_network_trace_block_html,
)
cd = (banner_result or {}).get("cookies_detailed") or []
e1 = check_cookies_for_entropy_mismatch(cd)
if e1:
ent_html = build_entropy_block_html(e1)
parts.append(ent_html)
section_sizes["entropy_v2"] = len(ent_html)
site_url = ""
for entry in (doc_entries or []):
if entry.get("url"):
site_url = entry["url"]; break
net = trace_cookie_network(cd, site_url)
if net:
net_html = build_network_trace_block_html(net)
parts.append(net_html)
section_sizes["network_trace_v2"] = len(net_html)
except Exception as e:
logger.warning("Replay v2: entropy/network failed: %s", e)
# P82: GF-1-Pager zuerst (5-Bullet-Summary)
try:
from compliance.services.gf_one_pager import build_gf_one_pager_html