Zum Hauptinhalt springen

Automatische Bildbewertung — Optionen (OP-QS-2)

Status: Optionen-Doku (06-26) · Phase 1a ✅ (Pre-Upload-Gate B-1/B-3/B-4) · Phase 1b Auto-Erkennungs-Adapter gebaut, dormant (MediaPipe-Gesichter + nsfwjs, self-hosted/lazy — aktiv erst nach Asset-Hosting) · Phasen 1c/1d ✅ (nummerierte Markierungen + Screenshot-Feedback, OP-FEEDBACK-1 vollständig) — Details in §7 · Bezug: OP-QS-2 (Owning) · hängt an OP-QS-1 (Foto-Doku am Mangel) · grenzt sich von OP-AI-2/OP-AI-3 ab (das ist KI-Plausibilität beim Upload, nicht die fachliche Bewertung des Arbeitsergebnisses) · Zielgruppe: IT-Dev/Architektur · True North: nur indirekt — Nutzen ist QS-Beschleunigung/Doku-Qualität (§6), keine der drei Leitfragen direkt

Kernaussage. „Automatische Bildbewertung" meint zwei getrennte Ziele (§1): das on-device Pre-Upload-Gate — foto-technische Qualität (B-1) + PII-Schutz mit Verpixeln (B-3) + NSFW-Block (B-4) — ist gebaut (Phase 1a; die Auto-Erkennungs-Adapter der Phase 1b bleiben dormant); die fachliche Bewertung des Arbeitsergebnisses (B-2) ist offen. Empfehlung dafür (§5): Hybrid F, gestuft — erst das Gate, dann Claude Vision als Vorschlag in QS/Mangel („KI schlägt vor, QS entscheidet"), ein eigenes Modell erst bei ausreichendem Bilddaten-Schatz. Compliance (DE/AT/CH, §4) ist vor jedem Cloud-Pfad zu klären.

1. Worum es geht — zwei verschiedene Bewertungs-Ziele

„Automatische Bildbewertung" meint in Taktano zweierlei, die technisch getrennt zu denken sind:

ZielFrageWoBeispiel
B-1 Foto-technische QualitätIst das Bild brauchbar (scharf, belichtet, richtiger Ausschnitt)?Upload-Gate an jedem Foto-Feld (R4)„Bild unscharf — bitte neu aufnehmen"
B-2 Fachliche BewertungIst die Arbeit mangelfrei? Welcher Defekt, wie schwer?QS-Endkontrolle, Mangel-Doku (OP-QS-1), Anlieferungs-Schadensdoku„Einschluss in der Folie an der Tür → Mangel, Schwere mittel"
B-3 PII-Schutz vor UploadSind Personen/Kennzeichen im Bild? → warnen + Verpixeln anbietenon-device, vor jedem Foto-Upload (R4)„2 Gesichter + 1 Kennzeichen erkannt → verpixeln?"
B-4 Inhalts-/NSFW-CheckIst das Bild unangemessen/irrelevant (NSFW)? → warnen + Upload blockenon-device, vor jedem Foto-Upload (R4)„Bild als unangemessen eingestuft → Upload gesperrt"

OP-AI-2/OP-AI-3 (Doku-Pflicht-Gate) deckt einen dritten, eng verwandten Fall ab — die Plausibilität des Doku-Bilds (richtige Perspektive, plausible Fahrzeugfarbe). Das ist ein Konsistenz-Check des Uploads, nicht die Qualitätsbewertung des Gewerks. Dieses Dokument fokussiert B-1 und B-2.

2. Andockpunkte im Produkt (heute/geplant)

  • QS-Workspace (Qualität, Endkontrolle-Queue + Checkliste + Freigabe) — Bewertung B-2.
  • Mangel-Doku (M05 / OP-QS-1, offen) — Foto am Mangel + „behoben"-Workflow → B-2.
  • Anlieferung — Schadensdokumentation am eingehenden Fahrzeug → B-2.
  • Formulare (R4, Feldtyp „Foto-Upload") — B-1 als universelles Gate.

3. Die Optionen

#AnsatzDecktAufwand/KostenDatenschutzBewertung
AMultimodal-LLM (Vision-API), z. B. Claude VisionB-2Niedrige Hürde (kein Training, Prompt-basiert); API-Spend je BildUS-Cloud → AVV + Drittland (s. §4)Liegt im Stack (A-4 KI-Layer, A-5-Pragma LLM-API). Liefert Klartext-Begründung + Mangel-Vorschlag. Passt zu „KI schlägt vor, Mensch entscheidet".
BGenerische Cloud-Vision (Google Vision / AWS Rekognition / Azure)B-1 grob + OCRPay-per-call, kein TrainingUS-Cloud (analog A)Nicht domänentrainiert — erkennt keine Folien-Einschlüsse/Lackläufer. Nutzbar für Kennzeichen-OCR (→ Schwärzung!) oder Grob-Labels.
CEigenes ML-Modell (CNN, auf Lack-/Folien-Defekte trainiert)B-2 (höchste Genauigkeit)Hoch: Trainingsdaten sammeln+labeln, MLOps, Re-TrainingIn eigener Infra (EU) lösbarLohnt erst mit Bilddaten-Schatz. Kandidat später (Fly.io neben dem Solver).
DKlassische Bildverarbeitung (OpenCV/WASM, ohne ML)B-1 (Schärfe/Blur/Helligkeit/Auflösung)Sehr gering, deterministisch, offlineUnkritischIdeales Upload-Gate. Bewertet nicht den Inhalt.
EOn-device / Edge (TensorFlow.js / WASM im Browser)B-1 + leichte KlassifikationMittelVorteil: Bild verlässt das Gerät erst nach GateDatenschutz-Plus, begrenzte Modellgröße.
FHybrid (D/E als Gate → A für B-2)B-1 + B-2 gestuftMittelGate filtert vor teurem/exponiertem LLM-CallEmpfehlung (§5).

4. ⚠️ Compliance-Flag (DE/AT/CH) — verbindlich

Fahrzeugfotos sind datenschutzrelevant (DSGVO):

  • Kennzeichen = personenbezogenes Datum; ggf. Personen/Reflexionen im Hintergrund; EXIF mit GPS/Gerät.
  • A/B (US-Cloud) = Auftragsverarbeitung + Drittlandtransfer → AVV + Transfer-Mechanismus nötig; in docs/betrieb/Compliance.md und docs/betrieb/Risikoregister.md nachziehen (vgl. RISK-10-Logik zu KI/Tool-Nutzung).
  • C/D/E in eigener EU-Infra bzw. on-device entschärfen das deutlich.
  • Unabhängig vom Modell, immer: EXIF strippen, Kennzeichen/Personen vor Cloud-Versand schwärzen (Bezug Option B/OCR), R2-Retention definieren (Bezug OP-AUDIT-1), Einwilligung/ Zweckbindung dokumentieren.

Diese Punkte sind vor einem Bau zu klären — aktiv geflaggt, nicht still übergangen (CLAUDE.md §Compliance „Proaktives Flagging").

4a. B-3 — Personen/Kennzeichen vor dem Upload warnen + verpixeln (Entscheidung 06-26)

Anforderung (Nutzer 06-26): Beim Foto-Upload on-device prüfen, ob Personen (Gesichter) oder Kennzeichen im Bild sind; falls ja warnen und anbieten, Gesichter und Kennzeichen zu verpixeln. Das ist Privacy-by-Design / -by-Default (DSGVO Art. 25) und entschärft das Compliance-Risiko aus §4 direkt an der Quelle — die PII verlässt das Gerät idealerweise gar nicht erst (vor allem wichtig vor den Cloud-Pfaden A/B).

Schlüssel-Entscheidung: Erkennung + Verpixelung laufen on-device (Option E), vor dem Upload. Nur die redigierte Kopie wird hochgeladen; das Original verlässt das Gerät nicht (Nutzer kann es lokal verwerfen). Das ist der einzige Weg, der die Datenminimierung tatsächlich einhält — ein Server-seitiger Blur käme zu spät (Rohbild läge dann schon in der Cloud).

UX-Fluss

  1. Bild wählen/aufnehmen → on-device-Scan markiert Gesichter/Kennzeichen mit Boxen.
  2. Warnung „N Gesichter / M Kennzeichen erkannt".
  3. Angebot: Verpixeln (empfohlener Default) · manuell Boxen hinzufügen/entfernen (Erkennung ist nie 100 %) · ohne Verpixeln hochladen (Bestätigung + Grund; für den Cloud-Rating-Pfad A/B möglichst sperren/erzwingen — s. u.).
  4. Verpixelung clientseitig im Canvas (Mosaik/Blur je Box, irreversibel auf der Kopie) → nur das redigierte Bild geht in den Upload (danach B-1-Gate).

Optionen für die Erkennung (on-device)

WasAnsatzHinweis
GesichterMediaPipe Face Detector / BlazeFace (TF.js) oder face-api.jsReif, schnell im Browser, kleine Modelle. Erkennung, keine Identifikation (keine Gesichts-Erkennung i. S. v. Biometrie — nur „hier ist ein Gesicht").
Kennzeichenleichtes Objektmodell (YOLO-nano/SSD auf „Plate", via onnxruntime-web/TF.js-WASM) oder OpenCV-Heuristik (Kanten/Rechteck-Proportionen)Schwieriger/ungenauer als Gesichter → manuelle Nachkorrektur Pflicht-Fallback. Bewusst nur Lokalisieren (Box), kein OCR (kein Klartext-Kennzeichen erzeugen/speichern).
VerpixelnCanvas: Region downscale→upscale (Mosaik) bzw. Blur je BoxRein clientseitig, keine Lib nötig.

Entscheidungen

  1. On-device, vor Upload (Option E) — PII-Minimierung an der Quelle; Server-Blur wäre zu spät.
  2. Erkennung ≠ perfekt → manuelle Korrektur (Box hinzufügen/entfernen) + Nutzer-Verantwortung; keine „false sense of safety". Kennzeichen-Erkennung konservativ (lieber Fehlalarm als Miss).
  3. „Anbieten" (opt-in) wie gewünscht — aber Empfehlung: für den Cloud-Rating-Pfad (A/B) die Redaktion default/erzwungen, da unredigierte Kennzeichen/Gesichter an einen US-Dienst ein echtes DSGVO-Thema sind (Bezug §4). „Ohne Verpixeln" nur mit Bestätigung/Grund, ggf. rollen-gegated (OP-AUTH-1) und als OP-AUDIT-1-Event.
  4. Nur Lokalisieren, nicht identifizieren — kein Biometrie-Template, kein Kennzeichen-OCR; damit bleibt das Feature selbst datensparsam.

4b. B-4 — Inhalts-/NSFW-Check vor dem Upload (Entscheidung 06-26)

Anforderung (Nutzer 06-26): Beim Foto-Upload zusätzlich on-device prüfen, ob das Bild unangemessen (NSFW) ist, und ggf. warnen + den Upload blockieren. Schützt das B2B-Tool vor unangemessenen/irrelevanten Inhalten (Arbeitsplatz, Governance/Trust, Jugendschutz) und hält die Bild-Doku sauber auf den Werkstatt-Kontext fokussiert.

Schlüssel-Entscheidung: on-device (Option E), im selben Pre-Upload-Scan wie B-1/B-3. Ein einziger Scan-Durchgang beim Auswählen/Aufnehmen liefert Qualität (B-1), PII-Boxen (B-3) und NSFW-Score (B-4) — das Bild verlässt das Gerät erst nach Bestehen aller Gates.

Unterschied zu B-3: NSFW lässt sich nicht verpixeln/„reparieren" → die Reaktion ist Upload blockieren (statt Redaktion anbieten). Override nur begründet + rollen-gegated (OP-AUTH-1) und als OP-AUDIT-1-Event, für seltene Fehlalarм-Fälle.

Optionen für die Erkennung (on-device)

AnsatzHinweis
NSFWJS (TensorFlow.js, MobileNet-basiert)Reif, läuft im Browser; Klassen neutral/drawing/sexy/porn/hentai mit Scores → konfigurierbarer Schwellwert. Default-Empfehlung (on-device, kein Upload nötig).
Cloud-Moderation (AWS Rekognition Moderation · Google SafeSearch · Azure Content Safety)Genauer, aber sendet das Bild → widerspricht „vor dem Upload" + Drittland (§4). Nur als optionaler Server-Zusatz nach dem Upload.

Entscheidungen

  1. On-device (NSFWJS), vor Upload — gleicher Pipeline-Pass wie B-1/B-3; kein Bild-Leak.
  2. Reaktion = blockieren (nicht verpixeln), da NSFW nicht redigierbar; klare Meldung.
  3. Schwellwert/Strenge konfigurierbar (admin, taxonomie-artig G-1) — z. B. sexy tolerieren vs. strikt; sinnvolle Defaults.
  4. Override nur begründet + rollen-gegated (OP-AUTH-1) + OP-AUDIT-1-Event (Fehlalarm-Ventil).
  5. Abgrenzung: B-4 ist Content-Moderation (darf das Bild rein?), unabhängig von B-2 (fachliche Qualität) und B-3 (PII). Reihenfolge im Gate: B-4 + B-1 + B-3 zusammen vor Upload.

5. Empfehlung — Hybrid F, gestuft

  1. Phase 1 — Pre-Upload-Gate (D/E), ein on-device-Pass: deterministischer Schärfe-/ Belichtungs-Check (B-1) plus B-3 (Gesichts-/Kennzeichen-Erkennung → warnen + Verpixeln anbieten, §4a) plus B-4 (NSFW-Check → warnen + blocken, §4b). Sofortiger Mehrwert + Compliance-/Governance-Gewinn, keine API-Kosten, keine PII/Inhalte in der Cloud. Baubar unabhängig — Voraussetzung für die Cloud-Pfade A/B.
  2. Phase 2 — fachliche Bewertung (A): Claude Vision als Vorschlag in QS/Mangel (Mangel-Kategorie + Schwere + Klartext-Begründung). Strikt „KI schlägt vor, QS entscheidet" (wie Optimierer-Vorschau R8-G2 / In-App-Assistent OP-AI-4). Reiht sich in A-4-KI-Layer ein. Vorbedingung: Compliance §4 (AVV/Schwärzung/EXIF/Retention).
  3. Phase 3 — eigenes Modell (C): erst wenn genug gelabelte Defekt-Bilder existieren und die LLM-Genauigkeit nicht reicht.

6. True-North-Ehrlichkeit

Bildbewertung beantwortet die drei Leitfragen (Auslastung · Standort · freie Kapazität) nur indirekt — der Nutzen liegt in QS-Beschleunigung/Qualitätssicherung (OP-QS-1) und Doku-Qualität. Bei der Priorisierung entsprechend einordnen (docs/Sanity-Checkliste.md).

7. Stand der Umsetzung — Phase 1a (gebaut) + 1b (Auto-Erkennung dormant)

Gebaut (Client, v0.8.0/Build 11) — der On-Device-Pre-Upload-Gate als wiederverwendbarer Baustein, dockt später an das R4-Foto-Upload-Feld an:

  • Reiner, DOM-freier Kern client/src/app/leitstand/bild/upload-gate.ts (rechnet auf rohen RGBA-Pixeln, in Node selbst-testbar):
    • B-1 bildstatistik (mittlere Luma + Laplace-Varianz/Schärfe) + bewerteQualitaet (zu_klein/unscharf/zu_dunkel/zu_hell, Schwellen konfigurierbar).
    • B-3 verpixele(img, boxen) — Mosaik je Box auf einer Kopie (Original unberührt).
    • B-4 Klassifikator-Naht + entscheideGate (Priorität NSFW > Qualität > PII > ok).
    • Detektor-Naht PiiDetektor/NsfwKlassifikator (Default-Stubs) → BlazeFace/Plate/NSFWJS dockt ohne Umbau an.
  • Angular-Komponente bild/bild-upload-gate.component.ts (Canvas-Glue + UX): Bild wählen → Befund (Status ok/Achtung/Gesperrt + Statistik) · Bereiche manuell markieren (Ziehen) · Verpixeln · Upload nur bei nicht-blockiert; Original verlässt die Komponente nie, nur der (ggf. verpixelte) Blob wird emittiert. Tokens-only (No-Hex-Gate grün).
  • Demo-/Vorschau-Seite pages/bild-schutz.component.ts unter Deep-Link /bild-schutz (bewusst nicht im Workspace-Rail — kein fertiges Feature vortäuschen, bis das echte Upload-Feld existiert).
  • Self-Test npm run test:bildgate (upload-gate.demo.ts, synthetische Bilder) + CI (Client-Job vor ng build).

Phase 1b — Auto-Erkennungs-Adapter gebaut (06-26, dormant; v0.9.0/Build 12): die Naht ist mit echten Adaptern gefüllt, deploy-sicher dormant (PR-184-Muster) — aktiv erst, wenn die Modelle self-hosted sind:

  • bild/modelle.config.tsMODELLE_BASIS_URL (first-party, leer = aus) + ladeModul (dynamischer Import einer absoluten URL, vor dem Bundler verborgen → keine npm-Dep, kein Bundle-Wachstum).
  • bild/pii-mediapipe.adapter.ts (MediaPipe Face Detector, nur Box/keine Biometrie) + bild/nsfw-nsfwjs.adapter.ts (nsfwjs, Klassen→unangemessen/Score) — beide implementieren die Naht aus §7, laden Lib+Gewichte zur Laufzeit von MODELLE_BASIS_URL.
  • bild/detektoren.ts — Factory: bei aktiver Config werden die Adapter als eigene Lazy-Chunks (~0,8 kB, Libs nicht gebundelt) geladen, sonst Stubs; try/catch → Fallback auf manuell.
  • Demo-Seite zeigt den Aktiv/Inaktiv-Status; die Komponente fängt Detektor-Fehler ab (manuelle Markierung bleibt immer nutzbar).
  • Status/Warnung (06-27): ladeDetektoren() liefert AutoStatus (aus/aktiv/fehler); der Gate zeigt ● aktiv · ○ inaktiv (dormant) · ⚠ Banner, wenn die Erkennung konfiguriert, aber nicht ladbar ist (Binding nicht einkommentiert / /models 404 / Modell-Load-Fehler) → fordert zur manuellen Markierung auf. Detektor-Fehler blockieren nie.
  • Verifiziert hier: test:bildgate · ng build (Adapter als 769/707-B-Lazy-Chunks, Basis-Bundle unverändert) · No-Hex grün. NICHT hier verifizierbar: Laufzeit-Inferenz + Asset-Hosting.

Aktivierung (Deploy-/Infra-Schritt, B-i): MediaPipe-WASM+.tflite, TF.js- und nsfwjs-ESM-Bundle + nsfwjs-Modell auf R2/Pages (EU) ablegen, MODELLE_BASIS_URL darauf setzen → Auto-Erkennung wird live (Browser-Augenschein nötig).

Phase 1c — Nummerierte Markierungen (OP-FEEDBACK-1, gebaut 07-02; v0.43.0): der Bild-Schutz-Baustein kann zusätzlich zum Verpixeln nummerierte Punkt-Markierungen aufnehmen — ein wiederverwendbarer Annotations-Layer (nicht feedback-spezifisch), den das Screenshot-Feedback konsumiert (Phase 1d):

  • Reiner Kern (upload-gate.ts): Typ Markierung { nummer; xProzent; yProzent; notiz? } (Position prozentual → auflösungsunabhängig) + reine Helfer markierungHinzufuegen / markierungEntfernen (lückenlose Re-Nummerierung ab 1) / markierungNotiz / markierungenText (Text fürs Feedback). Von test:bildgate mitgeprüft.
  • Komponente (bild-upload-gate.component.ts): Modus „① Punkt markieren" neben „✎ Bereich markieren" (schließen sich aus) — Tippen setzt einen nummerierten Pin (prozent-positionierte Vorschau-Kreise, --tk-cyan), Liste mit optionaler Notiz + Entfernen. Beim Export werden die Kreise auf eine Off-Screen-Kopie ins Bild eingebrannt (Canvas arc+fillText, Farben aus --tk-* via getComputedStyle → No-Hex-konform, idempotent). Neuer programmatischer Eingang bildQuelle / ladeBlob(blob) (einbettbar, nicht nur per Datei-Input); Ausgabe angereichert zu freigegeben: { blob; markierungen }.
  • Verifiziert: test:bildgate (Marker-Helfer) · ng build · No-Hex grün.

Phase 1d — Screenshot-Feedback konsumiert den Baustein (OP-FEEDBACK-1, gebaut 07-02; v0.44.0): das In-App-Feedback nimmt per html2canvas-pro (lazy) eine gezogene Region der Ansicht auf und speist sie über den neuen Eingang bildQuelle in genau diesen Gate — der Nutzer verpixelt PII und setzt nummerierte Markierungen; das geschützte + annotierte Bild geht an /api/feedback/screenshot → EU-FOTOS-Bucket (feedback/<uuid>) und hängt als Access-gated Link + Markierungs-Liste am internen Issue. Details: docs/architektur/In-App-Assistent.md §9 (Slice 10). ➡ OP-FEEDBACK-1 vollständig.

Bewusst offen (Folge-Slices):

  • ⊘ Frage Ⓑ — Auto-Kennzeichen (Plate-Modell) zurückgestellt; bis dahin trägt manuelle Markierung.
  • ⚙ Improvement — schlankeres tfjs-Backend / kleineres nsfwjs-Bundle (heute ~40 MB, da das nsfwjs-Bundle ganz TF.js enthält): auf ein schlankes Backend (@tensorflow/tfjs-core + tfjs-backend-wasm/-webgl, nur benötigte Ops) reduzieren → kleinerer Lazy-Chunk, schnellerer Erst-Load. Festgehalten 06-27; kein akuter Blocker (lazy + Browser-Cache).
  • EXIF strippen beim Re-Encode prüfen/erzwingen; Override für „blockiert" (begründet, rollen-gegated OP-AUTH-1, OP-AUDIT-1-Event); Anbindung an das reale R4-Upload-Feld (OP-R4-3).

7a. Auto-Erkennungs-Slice (B-3/B-4 Modelle) — Optionen (Entscheidung offen)

Phase 1a trägt B-3 über manuelle Markierung und hat die Naht (PiiDetektor/NsfwKlassifikator). Dieser Slice füllt die Naht mit echten On-Device-Modellen — drei Achsen sind zu entscheiden.

A) Modell-/Library-Wahl

ZielOptionGröße (ca.)Bewertung
GesichterMediaPipe @mediapipe/tasks-vision (Face Detector, WASM)Modell ~0,2–1 MB + WASM-RuntimeEmpfehlung — modern, von Google gepflegt, schnell, kein voller TF.js nötig. Nur Lokalisieren (Box), keine Biometrie.
Gesichter@tensorflow-models/blazeface (auf TF.js)Modell ~0,4 MB + TF.js ~1–2 MBReif, aber zieht ganz TF.js. Sinnvoll nur, wenn TF.js für NSFW ohnehin geladen wird.
GesichterBrowser FaceDetector (Shape-Detection-API)0 (nativ)Verworfen — nur Chromium hinter Flag, nicht zuverlässig verfügbar.
KennzeichenYOLO-nano/SSD-Plate → TF.js oder onnxruntime-webModell ~2–6 MBModell muss beschafft/konvertiert werden; ungenauer als Gesichter.
KennzeichenOpenCV.js (WASM) + Heuristik/CascadeRuntime ~8–10 MBSchwer; nur Lokalisieren.
Kennzeichenvorerst manuell (Status quo)0Empfehlung kurzf. — Auto-Plate ist der schwächste/teuerste Teil; manuelle Markierung trägt.
NSFW (B-4)nsfwjs (TF.js, MobileNetV2)Modell ~2–4 MB + TF.jsDe-facto-Standard; Klassen neutral/drawing/sexy/porn/hentai → Schwellwert.
TF.js-BackendWASM (tfjs-backend-wasm) vs WebGLWASM = portabler (kein GPU-Zwang); WebGL schneller, als Fallback.

B) Wie kommen die Modell-Gewichte zum Client? (die eigentliche Dependency-Entscheidung)

OptionProContra
B-i Self-host first-party (Gewichte auf Cloudflare R2 / Pages, eigene Domain, lazy geladen)EU/eigene Domain → kein Drittland für den Modell-Fetch · Repo bleibt schlank · Verfügbarkeit selbst kontrolliert · privacy-by-design konsequentDeploy-Schritt (Bucket + Upload) · erster Fetch zur Laufzeit (first-party, danach Browser-Cache)
B-ii In-App bündeln (Gewichte als Angular-Assets, von app.taktano.com ausgeliefert)self-contained · offline · EU-served+MBs im Deploy · Binär-Assets im Repo (Bloat; ggf. Git-LFS/Build-Fetch)
B-iii Public CDN (jsDelivr/unpkg bzw. nsfwjs-Default-Host)null Hosting-AufwandDrittland-Request + Verfügbarkeits-/Privacy-Abhängigkeit für ein compliance-kritisches Feature → nicht empfohlen

C) Integration (unabhängig von A/B)

  • Lazy-Load per dynamic import() + Fetch nur, wenn ein Foto-Upload-Feld benutzt wird — der Cockpit-Basis-Bundle (heute ~630 kB, schon über Budget) bleibt unberührt; eigener Lazy-Chunk.
  • Adapter implementieren PiiDetektor/NsfwKlassifikator aus §7 — kein Umbau am Kern/an der UX.
  • CI: der reine Kern bleibt selbst-getestet; der Modell-Adapter wird nicht in CI geladen (kein Gewichte-Download im Build) — nur ein Smoke, dass der Adapter lädt/registriert.
  • Erst-Latenz/Cache: Modell-Load einmalig (~Sekunden), danach Browser-Cache; Status-Indikator.

Empfehlung

MediaPipe (Gesichter) + nsfwjs (B-4), Gewichte self-hosted first-party (B-i, R2/Pages), lazy geladen, TF.js-WASM; Kennzeichen vorerst manuell. Das hält die Privacy-/Drittland-Haltung (kein Public-CDN-Fetch), den Basis-Bundle schlank (Lazy-Chunk) und das Repo frei von Modell-Binärblobs.

Entscheidung (Nutzer, 06-26): ① + Ⓐ

  • Hosting = B-i self-host first-party (R2/Pages, EU, lazy) — beschlossen.
  • Scope = Ⓐ Gesichter (MediaPipe) + NSFW (nsfwjs) jetzt, Kennzeichen weiter manuell.
  • ⊘ Offene Frage Ⓑ — Auto-Kennzeichen-Erkennung (Plate-Modell YOLO-nano/ONNX bzw. OpenCV.js): bewusst zurückgestellt (teuerster/ungenauester Teil, Modell-Beschaffung). Bleibt als offener Punkt in OP-QS-2, bis die manuelle Markierung in der Praxis nicht reicht.

Verschärfung (Nutzer, 06-27): Modell-Bucket privat, kein öffentlicher Host

Ursprünglich war B-i als öffentlicher R2-Custom-Domain-Host (models.taktano.com) geplant. Geändert: taktano-models bleibt privat (kein r2.dev, keine öffentliche Custom-Domain). Die Modelle werden vom Worker aus einem privaten R2-Binding unter /models/* same-origin ausgeliefert (durch Cloudflare Access geschützt, kein CORS). MODELLE_BASIS_URL = "/models". Zusätzlich ein CI-Gate (scripts/check-r2-private.mjs), das den Deploy blockiert, falls taktano-models oder taktano-fotos öffentlich erreichbar sind. Damit ist kein Modell-/Foto- Bucket je öffentlich — strenger als „first-party Domain".

7b. Aktivierungs-Runbook — Auto-Erkennung scharf schalten (B-i)

Ziel: die dormanten Adapter (§7 Phase 1b) live schalten = self-hosted Assets + MODELLE_BASIS_URL. Alles first-party (kein Public-CDN/Drittland). Schritte:

1 — R2-Bucket anlegen (EU-Jurisdiktion, DSGVO-Residenz) — Operator-Schritt:

wrangler r2 bucket create taktano-models --jurisdiction eu

⚠ Warum nicht per MCP automatisch angelegt: das MCP-r2_bucket_create akzeptiert nur name, keine Jurisdiktion. Die EU-Residenz wird bei der Erstellung fix gesetzt und ist nachträglich nicht änderbar — ein Default-Bucket müsste gelöscht/neu erstellt werden. Daher bewusst dem Operator mit --jurisdiction eu überlassen. Stand 06-26 verifiziert: das per MCP verbundene Konto ist erreichbar und hat 0 Buckets (kein Namenskonflikt). Vorbehalt wie #185 (D1): das verbundene Konto muss das Deploy-/Prod-Konto sein.

2 — Assets aufbereiten + hochladenautomatisiert per bash scripts/upload-models.sh (npm-Install in ein Temp-Verzeichnis → nsfwjs zu einem self-contained ESM-Bundle [tfjs + eingebautes Modell, ~40 MB] bündeln → .tflite laden → wrangler r2 object put … --jurisdiction eu --remote). Erzeugte Bucket-Pfade (exakt das, was die Adapter lesen):

Pfad im BucketInhalt / QuelleContent-Type
mediapipe/vision_bundle.mjs@mediapipe/tasks-vision (self-contained ESM)text/javascript
mediapipe/wasm/* (6 Dateien)WASM-Fileset (FilesetResolver.forVisionTasks).wasmapplication/wasm, .jstext/javascript
mediapipe/blaze_face_short_range.tfliteGoogle MediaPipe-Modell (Download)application/octet-stream
nsfwjs/nsfwjs.bundle.mjsnsfwjs + tfjs + Modell in einem esbuild-ESM-Bundletext/javascript

Verifiziert (06-27): Paket-Layout + esbuild-Bundling + .tflite-URL geprüft. nsfwjs lädt das eingebaute MobileNetV2-Modell via load() ohne URL → kein separates Modell-Hosting, keine separate tfjs-Datei. Das ~40-MB-Bundle wird lazy geladen (nur bei aktiver Auto-Erkennung) und danach vom Browser gecached.

Bucket bleibt PRIVATnicht öffentlich schalten (kein r2.dev, keine Public-Custom-Domain). Das CI-Gate (Schritt 5) erzwingt das.

3 — R2-Binding aktivieren (Worker liefert die Modelle privat aus): in server/wrangler.toml den auskommentierten Block einschalten —

[[r2_buckets]]
binding = "MODELLE_BUCKET"
bucket_name = "taktano-models"
jurisdiction = "eu"

Der Worker bedient damit GET /models/* aus dem privaten Bucket (same-origin, Access-geschützt, kein CORS). Ohne Binding liefert /models/* 404 (dormant).

4 — MODELLE_BASIS_URL setzenohne Angular-Rebuild: in server/wrangler.toml [vars] MODELLE_BASIS_URL = "/models" + wrangler deploy → der Worker injiziert window.__TAKTANO_MODELLE_URL__="/models" per HTMLRewriter in den SPA-<head> (leer = nichts injiziert = dormant). Die Adapter laden dann /models/mediapipe/… usw. same-origin über den Worker → privates R2-Binding. (Alternativen: Inline-Script im index.html-Head, oder STANDARD_BASIS_URL in modelle.config.ts + Rebuild.)

5 — Privatheit absichern (CI-Gate, schon verdrahtet): scripts/check-r2-private.mjs läuft im Deploy-Job vor wrangler deploy und blockiert den Deploy, falls taktano-models oder taktano-fotos öffentlich sind (r2.dev Public Dev URL oder aktive Custom-Domain). Damit das Gate greift, braucht der CI-CLOUDFLARE_API_TOKEN R2-Leserecht (sonst: Warnung + Skip, Deploy läuft, Gate inaktiv — s. Skript-Kopf).

6 — Verifizieren (Browser, am Deploy): /bild-schutz öffnen → Badge „Auto-Erkennung aktiv"; Foto mit Gesicht → Box + Warnung „verpixeln?"; unangemessenes Bild → gesperrt. Im Netzwerk-Tab gehen die Modell-Fetches an app.taktano.com/models/… (same-origin, kein öffentlicher Bucket, kein CDN).

Nachziehen: Modell-Lizenzen (MediaPipe Apache-2.0, TF.js, nsfwjs + Modelle) in SBOM/ docs/Compliance.md; Erst-Latenz (Modell-Load, danach Browser-Cache) als Status anzeigen; Modell- Versionierung über Pfad/Query.

8. Bezüge

OP-QS-1 (Mangel-Foto + behoben) · OP-AI-2/OP-AI-3 (Bild-/Text-Plausibilität beim Doku-Gate) · OP-AI-4 (In-App-Assistent, KI-Layer/propose-not-execute) · OP-AUDIT-1 (Bild-Retention/Nachweis) · RISK-10 (KI/Tool-Nutzung) · docs/betrieb/Compliance.md (DE/AT/CH) · A-4 (KI-Layer, docs/fachlich/Lastenheft.md §11.8).


↩ Zurück zur Doku-Landkarte · Lesepfade · Register (alle OPs)