Commit Graph

569 Commits

Author SHA1 Message Date
Benjamin Admin b0f78ae9a3 feat(cra): readiness derives obligations from Machinery Reg 2023/1230 too
Machine/plant builders are hit by BOTH the CRA and the new Machinery Regulation.
New machinery_reg_cyber.py models its two well-corroborated Annex III cyber-with-
safety essential requirements (1.1.9 protection against corruption, 1.2.1 control-
system safety incl. foreseeable manipulation) in our own words; EU legal text is
freely reusable (Commission Decision 2011/833/EU, source acknowledged), harmonised
standards referenced by identifier only. The readiness check asks "is it
machinery?" and, if so, adds these obligations tagged "Maschinen-VO" alongside the
CRA ones — the combination is visible (regulations list + per-item source badge).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-14 14:26:08 +02:00
Benjamin Admin 2da3e5fdbb copy(cra): readiness check names both regulations + the living-system framing
Intro now states machine/plant builders are hit by BOTH the CRA (manufacturer
duties from 2027) and the new Machinery Regulation 2023/1230 (cyber-affecting-
safety in CE), and frames CRA Art. 13 as a continuously documented risk
assessment over the lifecycle — not a yearly pentest — which we run as a living
system (versioned snapshots). Educates the lead to win them.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-14 13:59:07 +02:00
Benjamin Admin 9660724a2c feat(cra): CRA Readiness Check lead-magnet on /sdk/cra (Track A)
Low-friction, stateless readiness check (no project/DB): business-scope answers
(internet / parameter app / remote maintenance / updates / firmware / personal
data / critical infra) -> Annex III/IV classification (reuses _classify) + a
high-level guideline grouped Code / Prozess / Dokumentation (via Annex I
evidence_type) + conformity path + deadlines + rough effort + the "we implement"
hook and a CTA into the existing project workflow. Endpoint POST /api/v1/cra/
readiness. Reuse + reframe of the existing CRA module — no duplicate questionnaire.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-14 13:33:09 +02:00
Benjamin Admin 398eaf3c36 feat(cra): two-lane breadth — CRA-specific corpus + technical depth
All 6 security use_cases are atom-grain now. Per finding we draw two lanes: the
CRA corpus (use_case=cra, the most on-point CRA obligations) + the technical
depth (code_security for secure-dev, else network_security). Controls merged,
deduped, each tagged with its use_case (shown in the best-practice depth).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-14 12:23:37 +02:00
Benjamin Admin a06c64af48 feat(cra): route secure-dev breadth to code_security (atom-grain)
Both network_security and code_security are now atom-grain. Per-sub_topic
use_case routing: secure_development -> code_security (best for secure-dev
findings), everything else -> network_security. Findings carry breadth_use_case
so the source context (which atom corpus) is visible under the best-practice depth.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-14 11:04:24 +02:00
Benjamin Admin c7845f67d6 feat(cra): attach network_security regulatory breadth (shared Controls-API)
Semantic breadth (2): each finding's CRA-AI is mapped to a network_security
sub_topic and enriched with atom-grain, framework-traceable obligations from the
shared Controls-API (compliance.atom_classification) — at the endpoint/view layer
(SessionLocal), NOT in the pure mapper. CRA-AI anchor + curated measure +
NIST/OWASP crosswalk stay the lead; this is breadth + source evidence. Only
network_security is queried (atom-grain), scoped by sub_topic + limit. Frontend
renders it under the collapsible best-practice depth (control_id · title · source).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-14 10:45:21 +02:00
Benjamin Admin ee1632cd52 feat(cra): snapshot/history UI + measure-class (code-fix vs process) UI
Snapshot/history: "Snapshot speichern" + a version list (status, date, coverage)
you can click through — makes the CRA Art. 13 running system visible (backend
endpoints already live). Measure-class: each finding shows a remediation-class
badge from its CRA evidence_type ("Code-nah" = scan-locatable, code-fix in the
ticket possible; otherwise Prozess/Doku), and the measures section is relabelled
as the Sollzustand (process/build) — no auto-fix buttons on process measures.
Backend: MappedFinding now carries evidence_type.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-14 10:02:17 +02:00
Benjamin Admin 10c32d7f7c feat(cra): cyber-meets-safety bridge as real logic (step 2)
Deterministic bridge (cra_safety_bridge.py): a cyber finding's attack capability
(remote_actuation / code_tampering / integrity_loss / auth_bypass, derived from
its CRA category) is matched against what each CE safety function is vulnerable
to. A match re-opens the mitigated hazard, flags the finding safety_impact (which
floors it to P0), and produces the cross-link. Endpoint accepts safety_functions;
frontend passes the project's safety functions and renders the LIVE cross-links
(no more hardcode). Safety functions are demo input now; come from the CE risk
assessment in production.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-14 08:59:41 +02:00
Benjamin Admin fb4d7641ab feat(cra): priority frontend — weights control, P0/P1 tier badges, quick wins
CRA tab now shows the priority layer: a weights control (5 business objectives,
high/medium/low) that re-computes the assessment live; a Prio column with
P0..P3 tier badges (P0 = non-negotiable floor, reason on hover); the table in
backend priority order; and a Quick-Wins block (high impact, low effort). Demo
flags the safety-cross-linked findings as safety_impact so the P0 floor shows.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-14 08:30:51 +02:00
Benjamin Admin ad83b8dc67 feat(cra): live-wire CRA tab to POST /api/v1/cra/assess (proxy + useCRA)
CRA tab now computes the assessment live: useCRA POSTs the scenario findings
through a new /api/v1/cra/* proxy to the backend mapper and merges the live
mapping (CRA requirement, risk, measures, NIST/OWASP crosswalk) with the
frontend scenario constants (full measure texts + cyber->safety cross-links,
until those move server-side in step 2). Falls back to the static scenario if
the backend is unreachable.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-14 07:30:00 +02:00
Benjamin Admin 7f03ffadcc feat(advisor): wire structured controls into compliance-advisor (HELD, not deployed)
Prompt-augments the RAG-only advisor with the shared use-case->controls API:
deterministic topic detection -> local controls API -> context block, so the
agent can answer from real Control-IDs. 100% local at runtime (no Anthropic).

NOT pushed/deployed: the shared API currently returns MASTER-grain controls,
whose composition is broken (gpre2 object-only clustering -> mega-clusters).
Pending the atom-grain rework of the API. tsc + vitest green.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-13 22:55:14 +02:00
Benjamin Admin f8de5a6dff refactor(cra): NIST/OWASP as collapsible per-finding detail, not a flat column
Per the Co-Pilot-calm principle: the findings table stays compact (Befund /
CRA-Anforderung / Risiko / Maßnahmen) and the NIST/OWASP + ISO 27001
best-practice depth is revealed per finding via a "NIST/OWASP" toggle. Keeps
the 3-layer model (CRA obligation -> measure -> best-practice depth) tidy.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-13 22:11:33 +02:00
Benjamin Admin 43ae33975d feat(cra): NIST/OWASP security golden-set crosswalk + full measure texts in CRA tab
Crosswalk (cra_security_crosswalk.py): deterministic, hand-curated CRA Annex I ->
NIST 800-53 Rev5 + OWASP Top 10:2021 mapping, the authoritative Security Golden
Set (no RAG; semantic breadth comes later via the shared Controls-API). Mapper
attaches NIST/OWASP refs per finding; golden-set completeness pinned by test
(every requirement has >=1 NIST ref). CRA tab now shows the NIST/OWASP best-
practice refs per finding and the full curated measure texts + norm references
(from measures_library_cra.go).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-13 21:24:53 +02:00
Benjamin Admin cadc34dad4 feat(iace): CRA / Cyber tab — demo CRA integration on the Kistenhub project
New "CRA / Cyber" tab in the IACE project (Zusatzmodule). Treats the
Kistenhubgeraet CE project as if it had an IoT module; invented cyber findings
are mapped to CRA Annex I requirements via the REAL backend mapper output
(faithful), and crucially cross-linked to the existing CE safety hazards they
re-open (cyber defeats a mechanically-mitigated guard -> CRA x Machinery Reg).
Frontend fixture for now; live wiring to the mapper endpoint follows.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-13 20:35:21 +02:00
Benjamin Admin 3489eaf8b0 chore(dev): Soul-Reverse-Engineering-Sperre raus (Dev-Modus) + Doc-Tabs immer sichtbar
- compliance-advisor.soul: Quellenschutz/Anti-Leak ersetzt durch Transparenz-
  Modus (nur Dev nutzt den Agent; offene Meta-Antworten erlaubt) + ehrlicher
  Hinweis, dass der Agent nur RAG sieht, NICHT die MC-DB.
- Snapshot: Impressum/DSE/AGB-Tabs immer sichtbar (Hinweis statt Verstecken bei
  fehlendem Text).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-13 20:06:34 +02:00
Benjamin Admin d92dd3b5fc feat(banner): Consent-Historie/Widerruf live erkennen (Borlabs-Stil, #62)
consent_history.detect_consent_history: erkennt CMP-Anbieter (Borlabs/
Usercentrics/OneTrust/Cookiebot/…) aus Storage+Cookies, versionierten Consent
(historie-fähig) + dauerhaftes Widerruf-/Einstellungs-Widget. consent_scanner
ruft es in Phase A; scan_matrix_summary surft summary.consent_history;
browser_cross_finding: positiver Befund wenn vorhanden, sonst Best-Practice-LOW
(„Nutzer sehen, wann sie welcher Version zugestimmt haben"); BrowserBehaviorView
zeigt es im Engine-Detail. Tests: 7 (classify/versioned) + 2 Cross-Finding.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-13 16:38:38 +02:00
Benjamin Admin d720db07dd feat(audit-report): deterministischer Textreport je Audit (MD + PDF) + Bericht-Tab
Firmen-tauglicher Bericht aus den Snapshot-Modulergebnissen (kein Re-Crawl, kein
LLM): Einleitung, Testumfang+Methodik, Management-Summary (4-Status), Detail-
befunde je Modul, Maßnahmen, Rechtlicher Hinweis. Co-Pilot-Tonalität, Tracking-
statt Cookie-Rohzahl, Norm nur referenziert (kein Normtext).
- audit_report.py: assemble_report (pur) + render_markdown + render_pdf (reportlab)
- snapshot_check_routes: GET /report (struktur+md) + GET /report.pdf
- Frontend: AuditReportTab + Proxys (report, report/pdf) + "Bericht"-Tab
- Tests: 5 Assembler (compliance/tests → CI-geprüft) + 1 Vitest

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-13 14:50:45 +02:00
Benjamin Admin 445079cfb2 feat(iace): FMEA source-document register + Anthropic extraction (Haiku)
Quote-verifiable failure extraction via Claude (Haiku 4.5): PDF sent
directly, tool-schema forces verbatim source quotes + applicable flag +
confidence — replaces the unreliable local llama run. Only applicable=true
tuples ingest into bp_iace_failure_kb; every processed doc lands in the
source manifest.

Frontend: FMEA tab now shows a "Quelldokumente" register (every document we
use, with source + licence + link + what was extracted) served from the
embedded manifest via GET /iace/failure-knowledge/sources. Manifest is
placeholder until the 100-doc Haiku run is folded in.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-13 13:34:41 +02:00
Benjamin Admin f1ac45dacf refactor(browser-matrix): ein klarer Button "Cookie-Banner testen (alle Browser)"
CI / detect-changes (push) Successful in 13s
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / secret-scan (push) Has been skipped
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / build-sha-integrity (push) Successful in 11s
CI / validate-canonical-controls (push) Failing after 5s
CI / loc-budget (push) Successful in 13s
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 3m2s
CI / test-go (push) Successful in 57s
CI / iace-gt-coverage (push) Failing after 3s
CI / test-python-backend (push) Failing after 3s
CI / test-python-document-crawler (push) Has been skipped
CI / test-python-dsms-gateway (push) Has been skipped
Schnelltest-nur-Chrome wieder entfernt (User: Banner-Test soll IMMER alle
Browser abdecken). Ein primärer Button im Leerzustand + "Erneut testen" im
Ergebnis-Kopf; beide lösen die volle Matrix aus.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-13 08:41:14 +02:00
Benjamin Admin 3f90e40807 fix(browser-matrix): Tracking-Signal statt Cookie-Rohzahl + Matrix-Schnellpfad
Korrektheit (§ 25 TDDDG): "Cookies vor Consent" ist KEIN Verstoss per se —
technisch notwendige Cookies inkl. des Consent-Cookies (speichert die
Ablehnung) sind nach Abs. 2 erlaubt. Verstoss ist nur nicht-essentielles
TRACKING vor Consent.
- browser_cross_finding: Befund haengt jetzt an violations.before_consent
  (Tracking), nicht an der Cookie-Rohzahl; § 25 Abs. 2-Hinweis im Detail.
  Regressionstest: Cookies-ohne-Tracking → KEIN Befund.
- multi_browser_scanner._extract_dimensions: Score nutzt Tracking-Violations
  + reject_respected-Verdikt statt Rohzahl (Fallback erhalten).
- BrowserBehaviorView: "Cookies vor Consent" nur rot/⚠ bei Tracking,
  "nach Ablehnen" neutral (Verdikt = reject-Spalte); erklaerende Zeile.

Speed: run_consent_test ueberspringt im Matrix-Modus (browser_profile gesetzt)
die teuren Phasen C/D-F/G — nur A+B noetig. Verhindert das 504 beim
Multi-Engine-Scan (BMW 4 Engines lief sonst in den 338s-Gateway-Timeout).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-13 00:10:41 +02:00
Benjamin Admin 85a8a1d545 feat(browser-matrix): Cross-Browser-Befunde + Browser-Default-Einordnung (Phase 4)
- browser_cross_finding: deterministische Sicht ueber die Matrix (keine 2.
  Engine, kein LLM). Findet Inkonsistenzen ZWISCHEN Browsern (Cookies vor
  Consent / Ablehnen nicht universell respektiert / Banner-Links fehlend) und
  ordnet ein: Safari-ITP / Brave-Shields / Firefox-ETP maskieren Verstoesse
  clientseitig → strenge Engine "sauber" ist KEIN Compliance-Beleg, massgeblich
  sind die nachgiebigen (Chrome/Edge). Coverage-Hinweis fuer nicht verfuegbare
  Browser. Je Befund Titel/Detail/Severity/affected/Massnahme.
- snapshot_check_routes: cross_findings frisch in run + GET (nicht persistiert).
- BrowserBehaviorView: "Cross-Browser-Befunde"-Block ueber der Tabelle.
- Tests: test_browser_cross_finding (6).

Offen (Folge-Task): Borlabs-Consent-Historie-Live-Erkennung (braucht
consent-tester-Storage-Scan).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-12 23:22:57 +02:00
Benjamin Admin 9587726936 feat(admin): Tab "Browser-Verhalten" — Per-Browser-Matrix + Screenshots (Phase 3)
- BrowserBehaviorView: laedt gespeicherte Matrix (GET), sonst "Browser-Test
  starten" (POST run, Live-Lauf). Per-Browser-Tabelle (Cookies vor Consent /
  nach Ablehnen / Ablehnen respektiert / Oberflaeche / Score), Engine-Detail
  mit Banner-Screenshot + Oberflaechen-Befunden, Mobil-Badge, "nicht
  verfuegbar"-Zeilen fuer fehlende Browser (arm64-Dev).
- Proxys browser-behavior (GET) + browser-behavior/run (POST, langer Timeout).
- page.tsx: Tab "Browser-Verhalten" (sichtbar sobald scanbare URL im Snapshot).
- consent-tester scan_matrix_summary: banner_findings je Engine im summary
  (Text/Severity/Norm) → Oberflaechen-Befunde im Tab.
- tsc strict clean; Vitest BrowserBehaviorView (2).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-12 23:15:06 +02:00
Benjamin Admin 2f68646c2d fix(advisor): keep_alive 30m gegen Modell-Kaltstart ("Load failed")
Ollama entlädt das 35b-Modell nach 5 Min Leerlauf → jede Frage danach
startet es kalt (Modell-Load) und läuft in den Frontend-Timeout ("Load
failed"). keep_alive='30m' im Chat-Request hält es warm.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-12 13:20:13 +02:00
Benjamin Admin 45df68537e feat(agent): Voll-Audit-Link in die Snapshot-Detail-Seite
Der "Voll-Audit öffnen (alle MCs)"-Link hing in ComplianceResultTabs (aus
der Agent-Seite entfernt). Jetzt im Detail-Header der Snapshot-Ansicht via
snap.check_id → /sdk/agent/audit/{check_id} (Audit-Daten verifiziert
vorhanden). Plus Site-Titel-Header.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-12 10:05:09 +02:00
Benjamin Admin 1b2b030367 feat(agent): /sdk/agent auf Compliance-Check + Snapshot-Historie reduzieren
- Tabs Website-Scan (nie funktioniert), Banner-Check, Agent-Test entfernt;
  Tab-Leiste weg, da nur noch Compliance-Check übrig.
- Unter dem Compliance-Check jetzt die Snapshot-Historie (neuer
  SnapshotHistoryList): neuester oben + farblich markiert, Klick → Detail-
  Seite mit den Ergebnissen. Macht /sdk/agent/snapshots erreichbar.
- ComplianceCheckTab zeigt nach dem Lauf keine Inline-Ergebnisse mehr,
  sondern einen Hinweis auf die Historie (onComplete refresht sie).
- Tote Komponenten gelöscht (ScanResult/BannerCheckTab/AgentTestTab).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-12 09:31:35 +02:00
Benjamin Admin 755ea44343 feat(iace): refresh architecture tab + data-flow diagram + E1 ingest script
- architecture.go: DataSources now reflect the real ingested set (ESAW 2023,
  BLS CFOI, OSHA OTM, PRISM, cobot CC-BY, HSE) with their RAG collections;
  risk stage cites BLS + the searchable RAG layer; matrix stage now mentions
  the distance-benchmark dimension.
- Architektur & Datenfluss tab: new DataFlowDiagram — 4 lanes (input →
  knowledge/RAG-evidence → deterministic engine → outputs) with live counts.
- scripts/ingest_iace_kb.sh: idempotent E1 ingest — creates the 2 collections
  and uploads the 6 datasources docs against a configurable RAG_URL (for prod
  Qdrant), with retry.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-12 09:18:03 +02:00
Benjamin Admin 403e3c66d2 feat(cookie): Deklaration-vs-Bibliothek-Diff-Sicht + Funnel-KPI
Für die Library-getroffene Teilmesse (~32%) pro Cookie die Feld-
Abweichungen deklariert→Library (Kategorie/Laufzeit/Zweck) als Diff-Karte,
plus ehrlicher Funnel (gesamt → geprüft → abweichend) — nicht-getroffene
Cookies sind nicht prüfbar (kein Pass/Fail), passend zur Tonalität.

- analyze_cookies: 'expected'-Soll-Wert an tracker_as_necessary/
  excessive_lifetime/missing_purpose (+ _CAT_LABEL_DE).
- neues cookie_declaration_diff.build_declaration_diff: reine Regroup-
  Aggregation der Findings pro Cookie (single source = analyze_cookies),
  Hinweis-Typen (third_country/eu_alternative) bewusst ausgeschlossen.
- cookie-check exponiert out['declaration_diff'].
- CookieDeclarationDiff.tsx oben im Cookie-Tab (vor Panel/ResultView).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-11 21:00:50 +02:00
Benjamin Admin 97e39579d5 feat(cookie+routing): Storage-Typ-Filter + legal_notice capture-only
#3 Storage-Filter: cookie-check exponiert per-Cookie-Speichertyp
(storage_inventory.per_cookie); CookieResultView bekommt Filter-Chips
(Cookie/Local Storage/Framework …) + eine Speicher-Spalte, Anbieter ohne
passenden Treffer werden ausgeblendet, KPI zeigt gefilterte Zahl.

A-Routing: legal_notice ist jetzt ein kanonischer Doc-Type. Eigene
Discovery-Regel (legal-disclaimer/rechtlicher-hinweis) VOR impressum →
die Disclaimer-Seite wird nicht mehr als Impressum substituiert (Ursache,
dass die Cross-Doc-Reconciliation nie zündete). capture-only: als
doc_entry für B persistiert, aber nicht einzeln gescort (keine 0%-Noise,
da ohne eigene Checkliste). Im Scan-Form als Option auswählbar.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-11 20:45:18 +02:00
Benjamin Admin 0f6cdc93fd fix(snapshot): Cookie-Dedup + schneller Impressum-Tab + Tabellen-Zahl
- Cookies werden je Vendor nach Name dedupliziert (Consent-Phasen-Dubletten;
  BMW 2196 → ~772) — in cookie-check + get_snapshot, behebt aufgeblähte
  Kachel-/Finding-Zahlen.
- Impressum-Snapshot-Check überspringt den ~40s-LLM-Schritt (context skip_llm)
  → Tab lädt sofort statt leer zu bleiben.
- Vendor-Tabelle zeigt nur die Cookie-Zahl (kein 'Cookies'-Wort je Zeile).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-11 19:54:15 +02:00
Benjamin Admin b4981ea9ab feat(iace): benchmark distance panel (Thema 1)
Surface result.distances in the benchmark module: a DistanceComparison
panel showing agreement %, covered values (green), GT-only gaps (amber)
and engine-only extras — mirroring the RiskComparison panel.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-11 16:32:52 +02:00
Benjamin Admin ba7d98be36 feat(reconcile): B — Cross-Doc-Reconciliation (Pflicht in anderem Doc erfüllt)
Ein 'X fehlt'/'zu prüfen'-Finding wird unterdrückt, wenn die Pflicht in einem
ANDEREN Snapshot-Dokument erfüllt ist (z.B. § 36 VSBG / OS-Link stehen bei BMW
in AGB/'Rechtlicher Hinweis', nicht im Impressum → war False Positive).
Konservative Allowlist (impressum: verbraucher_streitbeilegung, odr_link) gegen
False-Reconciliation. Verdrahtet in _run_doc_agent (alle Doc-Checks). Frontend:
'In anderem Dokument abgedeckt'-Sektion. Greift voll nach Scan + Legal-Capture.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-11 15:42:16 +02:00
Benjamin Admin 7258744107 refactor+feat: Snapshot-Router-Split + generischer ChecklistAgent + AGB-Modul
- Item 2: Snapshot-Doc-Checks (cookie/impressum/dse/agb) in snapshot_check_routes.py
  (agent_compliance_check_routes.py 464→365 Z.); gleiche Pfade, in main.py registriert.
- ChecklistAgent-Basis: DSE-Logik generalisiert (L1/L2, kurze Titel, _severity_
  override-Hook). DSEAgent + AGBAgent sind jetzt Thin-Subclasses → künftige
  Doc-Agenten (widerruf/avv/…) trivial.
- Item 4: AGBAgent (§§ 305 ff. BGB, AGB_CHECKLIST) + agb-check + AGB-Tab via
  AgentModuleTab. Kein Library-Firehose.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-11 14:23:29 +02:00
Benjamin Admin b40edd6d33 feat(iace): show ESAW evidence panel in risk view (B1)
The Risikobewertung page only mentioned the data sources as static prose.
Add a collapsible "Datenquellen & Evidenz" panel sourced from
/iace/risk-data-sources: the real Eurostat ESAW 2023 contact-mode shares
per mode, with license + ready-to-print attribution, and the note that
tiers anchor the ordering while values stay GT-calibrated.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-11 14:11:15 +02:00
Benjamin Admin 6b41eec176 feat(iace): surface OSHA distance anchor in Maßnahmen tab (name-resolved)
Makes the OSHA minimum-distance anchor visible per measure in a project
without a DB schema change or re-seed: persisted mitigations store the
measure NAME verbatim (not the catalog ID), and measure names are unique
across the 578-entry library (pinned by test), so a name→ID resolver
bridges the gap.

Backend: MeasureIDByName + MinimumDistancesForMeasureName/LinksForMeasureName;
/iace/minimum-distances now accepts ?measure_name=; link table enriched with
measure_name for one-request UI matching.
Frontend: useMinimumDistances loads the link table once and keys it by name;
OshaDistanceNote renders the anchor (value/CFR/license/EU-hint/relation) on the
matching measure group in the Maßnahmen tab.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-11 13:39:48 +02:00
Benjamin Admin 76be96556d feat(dse): kuratierter DSEAgent + Snapshot-Tab (Art. 13/14, kein Firehose)
DSEAgent wrappt die existierende ART13_CHECKLIST (33 kuratierte Pflichtangaben
L1 + Detailchecks L2) → strukturierter AgentOutput, NICHT der 90k-Library-
Firehose (eCall/Gesundheit/Telekom-Lärm). GET /snapshots/{id}/dse-check spiegelt
impressum-check; doc_input_from_snapshot generalisiert. Frontend: generischer
AgentModuleTab (lazy → AgentResultTab) für Impressum + DSE; DSE-Tab in der
Snapshot-Seite. Plus HRB-Pattern \d→\d+ (volle Registernummer als Beleg).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-11 12:46:46 +02:00
Benjamin Admin 877d540ce1 fix(cookie+impressum): Drittland-FP, Impressum-Beleg, neuer Opt-Out-Finding
- Drittland: unbekannte Herkunft ('N/A') + Self-Hosting feuern nicht mehr —
  First-Party-Session-Cookies (PHPSESSID/JSESSIONID) waren False Positives.
- Impressum _line_of: enges Fenster um den Treffer bei Texten ohne Umbrüche
  (BMW = ein Block) → jede Pflichtangabe zeigt IHREN Beleg statt denselben Satz.
- Neuer Finding-Typ missing_opt_out: einwilligungspflichtiger Anbieter mit
  Cookies ohne Opt-Out-/Widerspruchs-Link (Art. 7 Abs. 3 + Art. 21).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-11 11:59:48 +02:00
Benjamin Admin 5b36b3f367 feat(impressum): Snapshot-Modul-Tab — ImpressumAgent auf gespeichertem Text
Snapshot-Detailseite wird zu Modul-Tabs (Cookies & Tracking | Impressum).
Backend GET /snapshots/{id}/impressum-check laeuft den v3 ImpressumAgent auf
dem gespeicherten Impressum-Text (kein Re-Crawl); Input-Erzeugung in
impressum_input_from_snapshot() ausgelagert (pure + getestet: Text/Scope/
company_name-Fallback/None-Pfad). Frontend laedt lazy beim Tab-Wechsel und
rendert mit dem bestehenden AgentResultTab (keine zweite Engine).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-11 11:24:44 +02:00
Benjamin Admin 39cb6afc23 feat(cookie): Findings bearbeitbar — gruppiert nach Typ + Matrix + Hinweise-Split
CookieFindings: Umschalter [Nach Fehlertyp] (je Typ: Maßnahme + betroffene
Cookies + Ticket-Text) ↔ [Matrix] (Cookie×Typ, ✗ Handlung / ⚠ Hinweis).
Trennung FINDINGS (zu beheben) vs HINWEISE (neutral, gegen DSE zu prüfen).
Backend: kind-Klassifikation (third_country/eu_alternative=hinweis); Drittland-
Remediation neutral formuliert (pro Verarbeiter prüfen, keine 'in DSE benennen'-
Befehle, da DSE-Abdeckung wie BMWs 'in der Regel SCC' oft unzureichend).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-11 11:02:34 +02:00
Benjamin Admin b0115cb10b feat(cookie): 2. Sicht Banner-Kategorie + Fehl-Einsortierung
CookieResultView bekommt einen Umschalter [Rechtliche Rolle] ↔
[Banner-Kategorie] (Notwendig/Funktional/Statistik/Marketing). In beiden
Sichten zeigt jede Cookie-Zeile '→ sollte: Marketing', wenn die tatsächliche
Kategorie laut Library von der deklarierten abweicht (rot bei Tracker als
notwendig, § 25 TDDDG). Neue KPI 'Falsch einsortiert'. Backend liefert dazu
cookie_categories (name→actual_category) aus big_lib im cookie-check-Output;
Seite lädt cookie-check einmal und reicht es an beide Komponenten.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-11 10:33:33 +02:00
Benjamin Admin 7fa9968ce1 feat(cookie): missing_retention — Vendor ohne Speicherdauer/Löschfrist
Vendor-Ebenen-Finding: greift, wenn ein Vendor eine Verarbeitung deklariert
(Kategorie/Zweck), aber KEINE Cookies gelistet sind UND keine persistence
angegeben ist (z.B. Nayoki GmbH — 'necessary' Auftragsverarbeiter ohne
Löschfrist). Die Pro-Cookie-Schleife sah solche Vendors nie (0 Cookies →
0 Findings). Remediation = Ticket-Text 'bitte Löschfrist festlegen'.
Art. 5 Abs. 1 lit. e + Art. 13 Abs. 2 lit. a → Control AUTH-2051-A03.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-11 10:02:59 +02:00
Benjamin Admin 32ba8d16b1 feat(iace): add data-driven Architektur & Datenfluss explainer tab
Adds an auditor-facing view of the IACE engine: a clickable 10-stage
pipeline flow (Grenzen-Formular → ParseNarrative → Pattern-Gates →
Relevanz → Caps → Gefährdungen → Maßnahmen → Risiko → Normen → Matrix),
plus live library counts, the data-source/license register (incl. the
DIN/Beuth + DGUV exclusions), and the norm-matching logic that reconciles
DIN/ISO/OSHA machine-type vocabulary via canonicalMachineType folding.

Backend: BuildArchitecture() with LIVE counts so the diagram can never
drift; GET /iace/architecture; collectAllNorms() extracted from
SuggestNorms as the single source of truth for the norm-library count.
Frontend: useArchitecture hook + page + new IACE nav tab.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-11 09:35:37 +02:00
Benjamin Admin 05a1795ea8 feat(cookie): ② Documentation Drift — Richtlinie vs. Browser-Realität
Cookie-Check-Endpoint liefert jetzt out["drift"] (audit_cookie_compliance):
deklariert (Cookie-Richtlinie-Text) vs. tatsaechlich geladen (Browser).
Frontend zeigt den Reality-Check-Strip oben im Panel: X dokumentiert ·
Y geladen · Z undokumentiert. Pinnt den Vertrag mit test_cookie_drift.py
(undokumentiert-geladen + beide Drift-Richtungen) + Vitest Drift-Strip.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-11 09:33:41 +02:00
Benjamin Admin 289988d23e feat(cookie): ① Storage Inventory + storage_transparency-Finding
Trennt echte Cookies von anderem Endgeraete-Speicher (Local/Session Storage,
IndexedDB, Salesforce-Framework-Artefakte) — § 25 TDDDG ist technologieneutral.
- cookie_storage_inventory: detect_storage_type (Name-Muster ComponentDefStorage/
  __MUTEX/LSKey + Laufzeit-Text) + build_storage_inventory + storage_transparency-
  Summenbefund ('X als Cookie gelistet -> Y echte + Z andere').
- Endpoint cookie-check liefert storage_inventory; Frontend zeigt den Breakdown.

Tests: 4 + Frontend-Vitest gruen. Differenzierungsmerkmal: '740 -> 132 + 608'.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-11 09:05:29 +02:00
Benjamin Admin 577ceae4e6 feat(iace): project-wide risk matrix (Severity × Probability)
Adds GET /projects/:id/risk-matrix — a confidence-aware risk view computed
on read from each hazard's category/scenario/lifecycle using the SAME model
as the GT benchmark (no persistence, so it never goes stale against the
model; the hand-defaulted iace_hazards risk columns stay untouched).

- risk_matrix.go: EstimateHazardRisk (single source of truth for S/F/W/P +
  range + level + confidence) and BuildRiskMatrix (per-hazard list + a 5×5
  Severity×Probability aggregation grid with dominant level per cell).
- Frontend: RiskMatrix grid in the Risikobewertung tab (muted colours per
  the confidence-aware tonality), level counts + tool-confidence summary,
  fed by useRiskMatrix. Shows risk for EVERY project, not only GT ones.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 08:54:47 +02:00
Benjamin Admin 901de1ca97 feat(cookie): A — Findings auditfest an Controls verdrahten
Jeder Cookie-Befund traegt jetzt ein strukturiertes control-Feld
(control_id aus doc_check_controls + regulation + article) statt nur
hardcodeter Strings: vague_duration->AUTH-2051-A03 (Art.5(1)e+13),
tracker_as_necessary->DATA-2851-A05 (§25 TDDDG), third_country->
DATA-1624-A04 (Art.44). Kette Regulation->Article->Control->Finding.
Frontend zeigt die Rechtsgrundlage je Befund. (Controls tragen
regulation/article noch NULL -> hier mitgeliefert bis gepflegt.)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-11 08:44:19 +02:00
Benjamin Admin 4c45f11e43 feat(cookie): Finding 'vague_duration' — unkonkrete Speicherdauer
Flaggt Laufzeit-Angaben ohne konkrete Dauer/Kriterium ('dauerhaft', 'bis zur
Loeschung', 'bis Nutzer deaktiviert', 'unbegrenzt' …) — Art. 5(1)(e) + Art. 13
DSGVO. Library-unabhaengig, gilt fuer ALLE Cookies (Coverage auf BMWs 780).
'13 Monate'/'Session'/'bis Widerruf, max. X' bleiben ok.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-11 08:33:06 +02:00
Benjamin Admin d18ef79f18 feat(cookie): Pro-Cookie-Library-Abgleich (2287er OCD + 35er rich) + Panel
- analyze_cookies gleicht Cookies gegen BEIDE Libraries ab: compliance.cookie_library
  (2287, OCD/CC0 — Kategorie/Retention) + 35er rich-DB (technical_necessity/reid/
  schrems/eu_alternative). 5 Befund-Typen: tracker_as_necessary, missing_purpose,
  excessive_lifetime (Art.5), third_country (Art.44), eu_alternative (kommerziell).
- Endpoint GET /snapshots/{id}/cookie-check (load_big_library batch + analyze).
- Frontend CookieLibraryPanel im Snapshot-Detail.
- Fix CookieResultView: Zweck nicht mehr auf 60 Zeichen gekuerzt; Rolle 'unknown'
  als Strich statt 'Unbekannt'.

Tests: 7 backend + frontend vitest gruen.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-11 08:18:25 +02:00
Benjamin Admin cefadf9e4c test(agent): CookieResultView KPI-Assertion entschaerfen (mehrdeutige '3')
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-11 01:04:37 +02:00
Benjamin Admin 410a814230 fix(agent): Cookie-View CONTROLLER -> Joint-Controller-Gruppe
recipient_type=CONTROLLER (Meta/LinkedIn/Criteo) gehoert zu Art. 26
(eigenverantwortliche Dritte / Joint Controller), nicht zu den eigenen
Verarbeitungen. BMW: 58 eigene / 16 AVV / 7 joint / 2 sonstige (= Mail-VVT).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-11 01:03:20 +02:00
Benjamin Admin 3332eb0bf9 feat(agent): Cookie-Result-View + Check-Historie aus Snapshots
Snapshot-getriebene Result-Views, entkoppelt vom Live-Check:
- CookieResultView: laedt cmp_vendors aus einem Snapshot (kein Re-Crawl),
  KPIs (Anbieter/Cookies/Marketing/Drittland) + Empfaenger-Gruppen
  (Eigene/AVV/Joint-Controller) + aufklappbare Vendor->Cookie-Tabelle.
- Historie (/sdk/agent/snapshots): alle gespeicherten Checks, jederzeit
  oeffnbar (DSB/Mitarbeiter) + Detail-Seite je Snapshot.
- Next.js-Proxys fuer GET /snapshots (Liste) + /snapshots/{id} (einzeln).

BMW-Snapshot 4603d15b: 83 Vendors / 780 Cookies. Library-Abgleich
(cookie_knowledge_db.lookup_cookie) folgt als Phase B.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-11 00:51:25 +02:00