# OMS Labels AI Transparency – vollständige Produkt- und Entwicklerdokumentation

**Dokumentationsstand:** 4. Oktober 2026  
**Free/Core-Version:** 3.6.25  
**WordPress.org-Slug und Textdomain:** `oms-labels-ai-transparency`  
**Hauptklasse:** `OMS_Labels_AI_Transparency_Core`  
**Autor:** Steven Sonntag / Onlinemarketing-Sonntag

> Diese Datei ist als Übergabedokument für Menschen sowie für Claude, Codex und andere Entwicklungsassistenten gedacht. Sie beschreibt den tatsächlichen Aufbau der Version 3.6.25. Rechtliche Aussagen oder eine Konformitätsgarantie sind nicht Bestandteil des Plugins.

---

## 1. Kurzbeschreibung

OMS Labels AI Transparency ist ein lokales WordPress-Plugin zur sichtbaren Kennzeichnung von KI-generierten oder KI-bearbeiteten Medien und Beiträgen. Es verbindet drei Bereiche:

1. **sichtbare Frontend-Kennzeichnung** von Bildern, Audio, Video und Beiträgen,
2. **redaktionelle Dokumentation und Freigabe** innerhalb von WordPress,
3. **optional dauerhaft gekennzeichnete Bildkopien**, ohne Originaldateien zu verändern.

Das Plugin verwendet lokale Symbole, Skripte und Styles. Es sendet keine Inhalte an externe Dienste, setzt keine eigenen Tracking-Cookies und benötigt für die Free-Version keinen Lizenzserver.

### Geeignet für

- redaktionelle Websites und Magazine,
- Blogs und Content-Portale,
- Agenturen mit dokumentierten Veröffentlichungsprozessen,
- WooCommerce-Websites mit gekennzeichneten Produktmedien,
- Betreiber, die KI-Einsatz transparent dokumentieren möchten.

### Nicht Bestandteil

- automatische rechtliche Bewertung,
- automatische Einstufung als verbindliche Entscheidung,
- Garantie der Einhaltung einer Rechtsnorm,
- externe KI-Erkennung oder Uploads zu Drittanbietern,
- Veränderung der ursprünglichen Mediendateien.

---

## 2. Technische Anforderungen

| Bereich | Anforderung |
|---|---|
| WordPress | mindestens 6.2 |
| PHP | mindestens 7.4 |
| Getesteter Header | WordPress 7.0 |
| Bildverarbeitung | GD oder Imagick, abhängig vom Format |
| Speicherung | WordPress-Optionen, Post-Meta, Attachment-Meta und Upload-Unterordner |
| Übersetzungen WordPress.org | über `translate.wordpress.org` |
| Lokales deutsches Testpaket | enthält eine eigene `de_DE.mo` |

---

## 3. Paketvarianten

### 3.1 WordPress.org-Paket

- Ordner: `oms-labels-ai-transparency/`
- Hauptdatei: `oms-labels-ai-transparency.php`
- keine `.po`, `.mo` oder `.pot` im Paket,
- kein manueller Textdomain-Loader,
- Übersetzungen werden durch WordPress.org bereitgestellt.

### 3.2 Deutsches Testpaket

- gleicher Plugin-Slug und gleiche Datenstruktur,
- enthält `languages/oms-labels-ai-transparency-de_DE.mo`,
- lädt die deutsche Übersetzung lokal,
- nicht für die WordPress.org-Einreichung verwenden.

### 3.3 Pro-Paket

Das separat vertriebene Pro-Paket verwendet dieselben Options- und Metaschlüssel. Der zuletzt geprüfte Pro-Stand 1.0.9 ergänzt:

- Website-Profile als JSON-Export und -Import,
- geplante Prüfungen über WP-Cron,
- druckbare Dokumentationsberichte,
- gekennzeichnete Open-Graph-Vorschaubilder,
- WP-CLI-Befehle.

Die Pro-Erweiterung ist **nicht Bestandteil** des WordPress.org-Free-Pakets.

---

## 4. Dateistruktur des Free-Plugins

```text
oms-labels-ai-transparency/
├── oms-labels-ai-transparency.php   Hauptklasse, Admin, Datenmodell und Backend-Logik
├── uninstall.php                    optionale Datenbereinigung
├── readme.txt                       WordPress.org-Beschreibung
├── assets/
│   ├── admin.css                    Admin-Oberfläche und Live-Vorschau
│   ├── admin.js                     Tabs, Vorschau, AJAX-Stapel und Formlogik
│   ├── frontend.css                 Frontend-Badge, Balken und Beitragshinweis
│   ├── frontend.js                  wrapperfreie Positionierung und Responsivität
│   ├── inline-edit.js               Quick-Edit-Vorbelegung
│   ├── onboarding.js                dauerhaftes Schließen des Einstiegshinweises
│   ├── preview.jpg                  Bild der Live-Vorschau
│   ├── admin-header.jpg             Header der Einstellungsseite
│   └── icons/                       lokale EU-Symbole und Lizenzhinweise
└── languages/                       nur im lokalen Test-/Pro-Paket
```

---

## 5. Zentrale Architekturregeln

Diese Regeln dürfen bei zukünftigen Änderungen nicht verletzt werden:

1. **Medien niemals umschließen, verschieben oder skalieren.**  
   Das Frontend-Badge wird als separates, absolut positioniertes Geschwisterelement erzeugt. Breite, Höhe, `srcset`, `sizes`, Theme-Klassen und DOM-Position des Mediums bleiben unangetastet.

2. **Keine normalen `<img>`-Elemente für Overlay-Symbole.**  
   Die Symbole werden als dekorative Hintergrund-Spans ausgegeben. Dadurch können Theme-Regeln wie `.post-thumbnail img { width:100% }` das AI-Symbol nicht vergrößern.

3. **Kleine Medien werden immer geschützt.**  
   Ein Vollbreitenbalken darf auf kleinen Archivbildern, Kacheln oder Sidebars automatisch zu einem kompakten Badge beziehungsweise einer Icon-Ansicht werden.

4. **Originalbilder bleiben unverändert.**  
   Dauerhafte Kennzeichnungen werden ausschließlich als separate WordPress-Anhänge gespeichert.

5. **WordPress.org-Build ohne Sprachdateien und manuellen Loader.**

6. **Bestehende Schlüssel bleiben stabil.**  
   Einstellungen und redaktionelle Daten müssen bei Updates, Umbenennungen und Free/Pro-Wechsel erhalten bleiben.

---

## 6. Vollständiger Funktionsumfang

### 6.1 Medienkennzeichnung im Frontend

- sichtbare Hinweise für Bilder, Audio und Video,
- Status `full`, `partial` und `generic`,
- lokale Symbole für AI, AI GENERATED und AI MODIFIED,
- schwarze, weiße oder automatisch kontrastierende Symbolvariante,
- Formmodi:
  - automatisch und responsiv,
  - kompaktes Badge,
  - Vollbreitenbalken auf ausreichend großen Medien,
- Größenpresets klein, mittel, groß sowie interne benutzerdefinierte Werte,
- Positionen oben links, oben rechts, unten links, unten rechts,
- getrennte Balkenposition oben oder unten,
- Hintergrundfarbe, Textfarbe, Deckkraft, Eckenradius, Innenabstand, Abstand und Z-Index,
- Kurztext oder Icon-only auf kleinen Medien,
- zweite Informationsebene mit AI-System und Hinweistext,
- Druckausgabe optional ein- oder ausblendbar,
- Ausschluss einzelner Medien oder Container über `.kit-ai-skip`,
- Theme-neutrale, wrapperfreie DOM-Ausgabe,
- `ResizeObserver`, Load- und Layout-Aktualisierung für responsive Medien,
- Schutz vor verzögerter Skriptausführung durch WP Rocket und ähnliche Optimierer.

### 6.2 Auswahl der zu kennzeichnenden Medien

- explizite Einstufung in der Mediathek,
- Auswahl über definierte Inhaltsbereiche,
- CSS-Klassen,
- eigener CSS-Selektor,
- kombinierte Metadaten-/Klassenlogik,
- frei definierbare Ausschlussselektoren,
- explizite Attachment-Einstufungen haben Vorrang,
- Unterstützung für lokale Medien-URLs und Attachment-Zuordnung.

### 6.3 Unterstützte Darstellungswege

- klassische WordPress-Bilder,
- Beitragsbilder und benutzerdefinierte Bildgrößen,
- Gutenberg-Bild-, Galerie-, Cover- und Medien/Text-Blöcke,
- Audio- und Video-Blöcke,
- WordPress-Audio-/Video-Shortcodes,
- Elementor-Bild- und Beitragsbild-Widgets,
- verzögert geladene Medien,
- Such- und Archivkarten,
- WooCommerce-Shop, Produktseiten, Produktgalerien, Produktraster und Variantenwechsel.

### 6.4 Mediathek und Medienprüfung

Medienstatus:

| Wert | Bedeutung |
|---|---|
| leer | noch nicht geprüft |
| `none` | geprüft, keine KI-Kennzeichnung |
| `full` | vollständig KI-generiert |
| `partial` | teilweise mit KI verändert |
| `generic` | allgemeiner KI-Hinweis |

Funktionen:

- Einstufung direkt in Attachment-Feldern,
- Prüfer und Prüfdatum,
- eigenes Label, Notiz und verwendetes KI-System,
- Spalten und Filter in der Medienliste,
- Quick-Markierung aus der Listenansicht,
- Mehrfachaktionen,
- eigene Seite **Medien → AI Media Review**,
- Zähler für Status und problematische Bildkopien,
- Benutzerberechtigungen werden berücksichtigt.

### 6.5 Provenienz- und Metadatenscan

- lokale Prüfung von IPTC/XMP-Texten,
- Hinweise auf mögliche C2PA-Daten,
- Erkennung bekannter Generatornamen aus Metadaten,
- Scan beim Upload oder als Stapelprozess,
- Vorschlagsstatus, erkanntes Werkzeug und Prüfdatum,
- automatische Übernahme nur, wenn sie ausdrücklich aktiviert wurde,
- keine externe API und kein Upload an Dritte.

Der Scan ist ein Hinweisgeber und keine beweissichere Erkennung.

### 6.6 Dauerhaft gekennzeichnete Bildkopien

- Originaldateien bleiben unangetastet,
- Zielordner: `wp-content/uploads/oms-labels-ai-transparency/<Jahr>/<Monat>/`,
- erzeugte Kopien werden als normale WordPress-Anhänge registriert,
- unterstützte Formate: JPEG, PNG, WebP und serverabhängig AVIF,
- animierte GIFs werden nicht dauerhaft verändert,
- GD- und Imagick-Pfade,
- automatischer Fallback von Imagick auf GD,
- statusabhängige Symbolgeometrie,
- frei wählbare Position und Rand,
- prozentuale Breite mit Mindest- und Höchstwert,
- automatische Schwarz-/Weiß-Auswahl nach Bildhelligkeit,
- Megapixel- und Dateigrößenlimits,
- atomarer Austausch und Wiederherstellung bei Fehlern,
- Sperre gegen parallele Erzeugung,
- Signatur zur Erkennung veralteter oder beschädigter Kopien,
- Beibehaltung der Attachment-ID beim Neuerzeugen/Migrieren,
- optionale bevorzugte Auslieferung der aktuellen Kopie,
- konfigurierbares Overlay-Verhalten auf bereits eingebrannten Kopien,
- optional IPTC/XMP Digital Source Type,
- WebP-XMP nur über Imagick; der GD-Pfad erzeugt die sichtbare Kopie ohne XMP.

Dauerhafte Bildkopien benötigen ein aktiviertes lokales Symbol. Browserbasierte Textkennzeichnungen funktionieren auch ohne Bildkopie.

### 6.7 Beitrags- und Redaktionsworkflow

Textstatus:

| Wert | Bedeutung |
|---|---|
| `inherit` | globale Einstellung / nicht eingestuft |
| `none` | keine KI-Unterstützung |
| `assisted_reviewed` | KI-unterstützt und redaktionell geprüft |
| `generated_reviewed` | weitgehend KI-generiert und redaktionell geprüft |
| `generated_unreviewed` | KI-generiert, aktuelle Prüfung nicht dokumentiert |

Dokumentierbare Felder:

- Sichtbarkeit des öffentlichen Hinweises,
- eigener Hinweistext,
- Prüfer,
- Prüfdatum,
- Faktenprüfung,
- redaktionelle Verantwortung,
- öffentliches Interesse,
- Quellen,
- eingesetzte KI-Systeme,
- interne Notizen.

Freigabelogik:

- Freigabe einer konkreten Beitragsfassung über Inhalts-Hash,
- Hash berücksichtigt Inhalt und relevante Metadaten,
- Warnung bei Veränderung nach Freigabe,
- Freigabe- und Änderungsprotokoll mit maximal 50 Einträgen,
- Migration älterer Hashstände in kleinen Batches,
- Quick Edit mit bewusster, nicht vorbelegter Freigabe-Checkbox,
- Bulk Edit ohne Sammelfreigabe,
- Unterstützung auswählbarer Custom Post Types,
- Filter `kit_ai_selectable_post_types` für Sonderfälle.

### 6.8 Öffentliche Beitragshinweise

- Hinweis unter dem Beitrag,
- Positionierung vor üblichen Autorenboxen,
- Modus nur für eingestufte Inhalte oder nach globaler Vorgabe,
- getrennte Texte für allgemeine, geprüfte und ungeprüfte Beiträge,
- eigene Sichtbarkeit pro Beitrag,
- deutscher oder englischer öffentlicher Text abhängig von der Website-Sprache,
- RSS-Hinweis in vollständigen und Auszugsfeeds,
- Shortcodes:
  - `[ai_transparency_label]`
  - `[ki_transparenzhinweis]` als Legacy-Alias.

### 6.9 Admin-Oberfläche

Menüs:

- **AI content** – zentrale Übersicht,
- **Einstellungen → AI transparency** – Konfiguration,
- **Medien → AI Media Review** – Medienprüfung und Bildkopien.

Einstellungsbereiche:

- Medienauswahl,
- Darstellung,
- Bildkopien,
- Beiträge,
- erweitert,
- Hilfe/FAQ.

Weitere Funktionen:

- Live-Vorschau für Artikelbild, Such-/Archivbild und Kachel,
- Statusumschalter in der Vorschau,
- Kontrastberechnung mit Warnung unter 4,5:1,
- bedingte Felder,
- stapelweise AJAX-Verarbeitung,
- ausblendbare und kontextbezogene Admin-Hinweise,
- Site-Health-Prüfungen,
- Plugin-Aktionslinks und Dokumentationslink.

### 6.10 Exporte

- CSV-Export für Medien- und Beitragsdaten,
- Schutz gegen Tabellenkalkulations-Formelinjektion,
- Ausgabe nur für berechtigte Benutzer.

### 6.11 Datenschutz

Die Free-Version verwendet:

- keine externen Schriften,
- kein CDN,
- kein Tracking,
- keine eigenen Cookies,
- keinen Lizenzserver,
- keine externe KI-Erkennung,
- keine Übertragung von Medien oder Beiträgen an Dritte.

---

## 7. Datenmodell

### 7.1 Hauptoption

```text
kit_ai_transparency_settings
```

Versionsoption:

```text
kit_ai_transparency_version
```

### 7.2 Einstellungsfelder und Standardwerte

| Schlüssel | Standard | Zweck |
|---|---:|---|
| `image_enabled` | `1` | Bildkennzeichnung aktiv |
| `media_enabled` | `1` | Audio-/Videokennzeichnung aktiv |
| `image_mode` | `metadata_classes` | Auswahlmodus |
| `image_scope` | definierte Inhaltsselektoren | erlaubte Inhaltsbereiche |
| `custom_selector` | `.ki-bild, ...` | eigener Auswahlselektor |
| `exclude_selector` | Logos, Avatare, `.kit-ai-skip` | Ausschlüsse |
| `label_full` | deutscher Vollstatus | sichtbarer Text |
| `label_partial` | deutscher Teilstatus | sichtbarer Text |
| `label_generic` | deutscher Allgemeinstatus | sichtbarer Text |
| `label_*_en` | englische Texte | öffentliche englische Ausgabe |
| `overlay_layout` | `auto` | automatisch, Badge oder Balken |
| `overlay_position` | `bottom-right` | Badge-Position |
| `overlay_bar_position` | `bottom` | Balken oben/unten |
| `overlay_style` | `eu` | visueller Stil |
| `overlay_bg` | `#000000` | Hintergrund |
| `overlay_text` | `#ffffff` | Textfarbe |
| `overlay_opacity` | `80` | Deckkraft in Prozent |
| `overlay_radius` | `6` | Eckenradius |
| `overlay_size` | `m` | Größenpreset |
| `overlay_bar_padding_y/x` | `6` / `10` | eigener Innenabstand |
| `overlay_font_size` | `12` | eigene Schriftgröße |
| `overlay_icon_height` | `20` | eigene Symbolhöhe |
| `overlay_gap` | `8` | Abstand Icon/Text |
| `overlay_inset` | `10` | Abstand zum Bildrand |
| `adaptive_overlay` | `1` | Legacy-Schlüssel; responsiver Schutz ist immer aktiv |
| `overlay_small_breakpoint` | `560` | Kompaktgrenze |
| `overlay_tiny_breakpoint` | `240` | Icon-only-Grenze |
| `overlay_compact_mode` | `auto` | Verhalten auf kleinen Medien |
| `short_label_on_small/tiny` | `1` | Legacy-/Kompatibilitätsschlüssel |
| `overlay_zindex` | `9999` | Overlay-Ebene |
| `show_icon` | `1` | lokales Symbol anzeigen |
| `icon_variant` | `auto` | schwarz, weiß oder automatisch |
| `avoid_obstruction` | `1` | Kollisionen möglichst vermeiden |
| `show_second_layer` | `1` | Info-Schaltfläche/Detailhinweis |
| `notice_enabled` | `1` | Beitragshinweise aktiv |
| `notice_mode` | `flagged` | öffentliche Auswahlregel |
| `post_types` | `post` | betreute Inhaltstypen |
| `notice_generic/text/unreviewed` | Standardtexte | deutsche Hinweise |
| `notice_*_en` | Standardtexte | englische Hinweise |
| `notice_style` | `soft` | Hinweisstil |
| `notice_accent` | `#0b6e99` | Akzentfarbe |
| `admin_*` | definierte Farben | Admin-Design |
| `author_box_selector` | bekannte Autorenboxen | Einfügeposition |
| `print_labels` | `1` | Kennzeichnung beim Drucken |
| `rss_notice` | `1` | RSS-Hinweis |
| `copy_enabled` | `1` | Bildkopien aktiv |
| `auto_generate_copy` | `1` | automatische Erzeugung |
| `prefer_labelled_copy` | `0` | Kopie bevorzugt ausgeben |
| `overlay_on_labelled_copy` | `auto` | Doppelkennzeichnung steuern |
| `copy_position` | `bottom-left` | eingebranntes Symbol |
| `copy_icon_variant` | `auto` | Symbolkontrast Kopie |
| `copy_width_percent` | `6` | relative Symbolbreite |
| `copy_min_width_px` | `28` | Mindestbreite |
| `copy_max_width_px` | `96` | Höchstbreite |
| `copy_margin_percent` | `2` | Randabstand |
| `copy_suffix` | `-ki-gekennzeichnet` | Dateinamenssuffix |
| `copy_max_megapixels` | `40` | Sicherheitslimit |
| `copy_max_file_mb` | `30` | Sicherheitslimit |
| `woocommerce_support` | `1` | WooCommerce-Erweiterung |
| `quick_mark_status` | `generic` | Schnellmarkierungsstatus |
| `scan_apply_automatically` | `0` | Scanvorschlag automatisch übernehmen |
| `write_provenance` | `1` | IPTC/XMP schreiben |
| `uninstall_cleanup` | `0` | Daten bei Deinstallation löschen |

### 7.3 Beitrags-Metadaten

| Konstante | Schlüssel |
|---|---|
| `META_STATUS` | `_kit_ai_text_status` |
| `META_VISIBILITY` | `_kit_ai_notice_visibility` |
| `META_CUSTOM` | `_kit_ai_custom_notice` |
| `META_REVIEWER` | `_kit_ai_reviewer` |
| `META_REVIEW_DATE` | `_kit_ai_review_date` |
| `META_FACTCHECK` | `_kit_ai_factcheck` |
| `META_EDITORIAL` | `_kit_ai_editorial_responsibility` |
| `META_PUBLIC` | `_kit_ai_public_interest` |
| `META_SOURCES` | `_kit_ai_sources` |
| `META_TOOLS` | `_kit_ai_tools` |
| `META_NOTES` | `_kit_ai_review_notes` |
| `META_REVIEW_HASH` | `_kit_ai_review_hash` |
| `META_LOG` | `_kit_ai_review_log` |

### 7.4 Medien-Metadaten

| Konstante | Schlüssel |
|---|---|
| `ATTACH_STATUS` | `_kit_ai_media_status` |
| `ATTACH_LABEL` | `_kit_ai_media_label` |
| `ATTACH_NOTE` | `_kit_ai_media_note` |
| `ATTACH_TOOL` | `_kit_ai_media_tool` |
| `ATTACH_COPY_ID` | `_kit_ai_labelled_copy_id` |
| `ATTACH_COPY_OF` | `_kit_ai_labelled_copy_of` |
| `ATTACH_IS_COPY` | `_kit_ai_is_labelled_copy` |
| `ATTACH_COPY_SIGNATURE` | `_kit_ai_copy_signature` |
| `ATTACH_REVIEWER` | `_kit_ai_media_reviewer` |
| `ATTACH_REVIEW_DATE` | `_kit_ai_media_review_date` |
| `ATTACH_PROVENANCE` | `_kit_ai_provenance_hint` |
| `ATTACH_SCAN_STATUS` | `_kit_ai_scan_suggestion` |
| `ATTACH_SCAN_TOOL` | `_kit_ai_scan_tool` |
| `ATTACH_SCAN_DATE` | `_kit_ai_scan_date` |
| `ATTACH_COPY_LOCK` | `_kit_ai_copy_lock` |

---

## 8. Frontend-Ausgabe

### 8.1 Datenattribute am Medium

Typische Attribute:

```html
data-kit-ai-status="generic|full|partial"
data-kit-ai-id="123"
data-kit-ai-label="..."
data-kit-ai-note="..."
data-kit-ai-tool="..."
data-ai-content="ai-assisted|generated|modified"
```

Quellmedien erhalten die Klasse:

```text
kit-ai-source
```

### 8.2 Badge-Klassen

Typische Klassen:

```text
kit-ai-badge
kit-ai-anchored
kit-ai-badge--generic|full|partial
kit-ai-badge--eu|outline|glass
is-bar|is-badge
is-compact|is-tiny|is-micro
is-icon-only
use-short-label
kit-ai-pos-tl|tr|bl|br
```

### 8.3 Kritische Frontend-Regel

Das Badge darf **kein Eltern-Wrapper des Bildes** werden. Es wird separat im nächstmöglichen Positionierungs-Host abgelegt und anhand des echten `getBoundingClientRect()` des Mediums ausgerichtet.

---

## 9. Admin-, AJAX- und Export-Endpunkte

### AJAX

```text
kit_ai_dismiss_onboarding
kit_ai_review_state
kit_ai_batch_copies
kit_ai_batch_scan
kit_ai_update_media_status
```

### admin-post.php

```text
kit_ai_generate_copy
kit_ai_delete_copy
kit_ai_export_csv
```

Alle schreibenden Vorgänge müssen Nonce, Capability, Objektzugriff und Eingabebereinigung prüfen.

---

## 10. WordPress-Hooks und Integrationen

Wichtige Kern-Hooks:

- `wp_enqueue_scripts`, `admin_enqueue_scripts`,
- `the_content`, `the_content_feed`, `the_excerpt_rss`,
- `wp_get_attachment_image_attributes`, `wp_content_img_tag`,
- `render_block`, `wp_audio_shortcode`, `wp_video_shortcode`,
- `attachment_fields_to_edit`, `attachment_fields_to_save`,
- `wp_prepare_attachment_for_js`,
- `manage_media_columns`, `pre_get_posts`, Medien-Bulk-Actions,
- `add_meta_boxes`, `save_post`,
- `woocommerce_available_variation`,
- `wp_get_attachment_url`,
- `site_status_tests`,
- `script_loader_tag`,
- WP-Rocket-Ausschlussfilter.

Öffentlicher Erweiterungsfilter:

```php
apply_filters( 'kit_ai_selectable_post_types', $post_types );
```

---

## 11. Stabile Core-API für Pro und Erweiterungen

Die folgenden Methoden bilden die dokumentierte interne Schnittstelle:

```text
api_settings()
api_defaults()
api_media_counts()
api_problem_copy_ids()
api_copy_state()
api_copy_state_label()
api_status_label()
api_create_copy()
api_last_copy_error()
api_set_media_status()
api_invalidate_counts()
```

Signaturen und Rückgabeformen sollten nicht ohne Migrationsschicht verändert werden.

---

## 12. Sicherheit

- direkte Dateiaufrufe werden über `ABSPATH` blockiert,
- Nonces für Formulare, AJAX und admin-post-Aktionen,
- Capability-Prüfungen wie `manage_options`, `upload_files`, `edit_post`, `edit_posts`,
- Eingaben über `sanitize_text_field`, `sanitize_key`, `wp_kses_post`, `absint`, Hex-Farbbereinigung und Whitelists,
- Ausgaben über `esc_html`, `esc_attr`, `esc_url`,
- keine hartcodierten absoluten Uploadpfade,
- Uploadpfade über `wp_upload_dir()`,
- Dateisperren und Größenlimits bei Bildkopien,
- CSV-Formelinjektionsschutz,
- externe URLs werden nicht als lokale Attachments aufgelöst.

---

## 13. Cache- und Performance-Verhalten

- Frontend-Skript lokal und ohne externe Abhängigkeiten,
- Skript wird im Head geladen, damit die Kennzeichnung früh verfügbar ist,
- Attribute `nowprocket`, `data-no-optimize` und `data-cfasync="false"`,
- WP-Rocket-Ausschlüsse für Datei und Inline-Konfiguration,
- `IntersectionObserver`/`ResizeObserver`-ähnliche Logik nur für relevante Medien,
- Zähler über Transients,
- große Aufgaben über AJAX-Batches,
- Hash-Migration in kleinen Schritten.

Nach Änderungen an `frontend.css` oder `frontend.js` müssen Seiten-, Optimierungs-, CDN- und Browser-Caches geleert werden.

---

## 14. Update- und Kompatibilitätsregeln

- ältere Pluginpfade werden beim Aktivieren deaktiviert,
- frühere Klassennamen werden kompatibel behandelt,
- Free und Pro verwenden dieselben Datenkeys,
- ein Variantenwechsel darf keine Optionen oder Metadaten löschen,
- Deinstallation löscht Daten nur bei aktivierter Cleanup-Option und berücksichtigt die andere Paketvariante,
- bestehende CSS-Klassen `.kit-ai-full`, `.kit-ai-partial`, `.kit-ai-generic`, `.kit-ai-skip` nicht entfernen.

---

## 15. Qualitätssicherung vor jeder Veröffentlichung

### Aktivierung

- Neuinstallation aktivieren,
- Update über bestehende Version testen,
- parallele alte Paketvariante testen,
- Free → Pro und Pro → Free testen.

### Frontend

- großes Beitragsbild,
- kleines Archivbild,
- sehr kleine Kachel,
- quadratisches General-AI-Symbol,
- breite Generated-/Modified-Wortmarken,
- alle vier Badge-Positionen,
- Balken oben/unten,
- Lazy Loading,
- responsive Größenänderung,
- keine Bildgrößenänderung oder Layoutverschiebung.

### Admin

- Speichern der Einstellungen,
- Erfolgshinweis lesbar,
- Live-Vorschau für alle drei Status,
- Quick Edit,
- Bulk Edit,
- Medienfilter,
- Onboarding-Hinweis dauerhaft schließen.

### Bildkopien

- JPEG/PNG,
- Imagick und GD,
- deaktiviertes Symbol,
- XMP/IPTC,
- alte Kopie erneuern,
- Fehlerfall und Wiederherstellung.

### WordPress.org-Build

- keine Sprachdateien,
- kein `Domain Path`,
- kein `load_plugin_textdomain()`/`load_textdomain()`,
- keine direkten `file_put_contents()`-Schreibvorgänge,
- PHP-Syntax und Plugin Check,
- Slug, Textdomain, Ordner und Hauptdatei konsistent.

---

## 16. Arbeitsanweisung für Claude oder Codex

Vor einer Änderung:

1. Diese Dokumentation vollständig lesen.
2. Die betroffene Funktion im Quellcode und alle zugehörigen CSS-/JS-Pfade finden.
3. Keine reine Symptombehandlung mit globalem `width:100%`, `height:auto` oder zusätzlichen Bild-Wrappern einführen.
4. Änderungen an Anzeigeoptionen in **Frontend und Live-Vorschau identisch** umsetzen.
5. Bestehende Options- und Metaschlüssel nicht umbenennen.
6. Den WordPress.org-Build und das lokale Sprachpaket getrennt erzeugen.
7. Versionsnummer, Stable Tag, Upgrade Notice und Changelog gemeinsam aktualisieren.
8. Vor Ausgabe mindestens PHP-Syntax, JavaScript-Syntax, ZIP-Struktur und verbotene Dateien/Funktionen prüfen.
9. Ungeprüfte Browser- oder WordPress-Laufzeittests ausdrücklich als ungeprüft kennzeichnen.

### Besonders wichtig für Overlay-Änderungen

- Bilder nie wrappen.
- Bilder nie skalieren.
- Overlay-Icon nie als normales `<img>` einsetzen.
- Maße am echten Medium messen, nicht an einem künstlichen Wrapper.
- Badge erst sichtbar machen, wenn Position und Profil berechnet sind.
- Archiv-, Sidebar- und Kachelbilder unabhängig von der gewählten Basisgröße schützen.

---

## 17. Bekannte Grenzen

- Ein Metadatenfund beweist nicht sicher, dass ein Medium KI-generiert ist.
- C2PA wird nur als möglicher Hinweis erkannt, nicht kryptografisch vollständig validiert.
- AVIF hängt von der Serverunterstützung ab.
- WebP-XMP benötigt Imagick.
- Aggressive HTML-Rewriter oder Cache-Tools können eine Cache-Leerung nach Updates erfordern.
- Die Free-Version erstellt keine rechtliche Konformitätsbescheinigung.
- Übersetzungen des WordPress.org-Pakets sind erst verfügbar, wenn sie auf `translate.wordpress.org` bereitgestellt wurden.

---

## 18. Methoden-Inventar der Core-Klasse

Die folgende Liste dient der Navigation. Nicht jede Methode ist eine öffentliche API.

- `__construct()`
- `plugin_action_links()`
- `plugin_row_meta()`
- `deactivate_legacy_plugin_variants()`
- `legacy_plugin_disabled_notice()`
- `activate()`
- `maybe_upgrade()`
- `review_hash_migration_post_types()`
- `schedule_review_hash_migration()`
- `process_review_hash_migration()`
- `maybe_dismiss_upgrade_notice()`
- `upgrade_notice()`
- `upgrade_copy_relations()`
- `load_local_textdomain()`
- `defaults()`
- `settings()`
- `image_copies_available()`
- `image_copy_icon_requirement_message()`
- `icon_urls()`
- `icon_path()`
- `register_settings()`
- `sanitize_settings()`
- `register_post_list_hooks()`
- `selectable_post_types()`
- `text_status_choices()`
- `inline_edit_box()`
- `bulk_edit_box()`
- `save_inline_edit()`
- `admin_menu()`
- `post_review_counts()`
- `overview_page()`
- `overview_card()`
- `overview_post_card()`
- `overview_filter_count_key()`
- `admin_assets()`
- `localized_setting()`
- `translated_default_setting()`
- `site_is_german()`
- `public_labels()`
- `overlay_tokens()`
- `overlay_inline_css()`
- `effective_image_scope()`
- `overlay_script_config()`
- `protect_frontend_script_from_delay()`
- `wp_rocket_delay_exclusions()`
- `wp_rocket_inline_exclusions()`
- `frontend_assets()`
- `hex_to_rgb()`
- `admin_style_variables()`
- `settings_page()`
- `render_panel_intro()`
- `field_open()`
- `field_close()`
- `field_checkbox()`
- `field_text()`
- `field_textarea()`
- `field_color()`
- `field_number()`
- `field_select()`
- `status_label()`
- `normalize_media_status()`
- `update_attachment_status()`
- `attachment_fields()`
- `save_attachment_fields()`
- `attachment_image_attributes()`
- `add_media_data_attributes()`
- `content_img_tag()`
- `html_attributes()`
- `attachment_id_from_local_url()`
- `should_show_overlay_for_labelled_copy()`
- `prepare_attachment_for_js()`
- `decorate_media_block()`
- `decorate_media_shortcode()`
- `inject_media_attributes()`
- `add_post_meta_box()`
- `render_post_meta_box()`
- `save_post_meta()`
- `sync_review_state_on_save()`
- `save_text_meta()`
- `save_boolean_meta()`
- `review_snapshot()`
- `append_review_log()`
- `is_review_current()`
- `content_review_hash()`
- `ajax_review_state()`
- `append_notice()`
- `append_feed_notice()`
- `notice_shortcode()`
- `render_notice()`
- `media_columns()`
- `media_column_content()`
- `render_quick_mark()`
- `media_filter_dropdown()`
- `append_meta_query()`
- `constrain_post_ids()`
- `review_filter_cache_key()`
- `invalidate_review_filter_cache()`
- `review_filter_ids()`
- `apply_media_filter()`
- `media_bulk_actions()`
- `handle_media_bulk_actions()`
- `bulk_admin_notice()`
- `media_overview_page()`
- `media_author_constraint()`
- `problem_copy_ids()`
- `media_counts()`
- `copy_action_url()`
- `handle_generate_copy()`
- `handle_delete_copy()`
- `acquire_copy_lock()`
- `generate_labelled_copy()`
- `generate_labelled_copy_unlocked()`
- `copy_upload_directory()`
- `delete_attachment_file_set()`
- `move_file()`
- `filesystem()`
- `delete_obsolete_intermediate_sizes()`
- `composite_icon()`
- `copy_icon_width()`
- `overlay_coordinates()`
- `prefer_labelled_attachment_url()`
- `prefer_labelled_image_attributes()`
- `invalidate_media_counts()`
- `copy_signature()`
- `copy_state()`
- `copy_state_label()`
- `unlink_or_delete_copy()`
- `delete_intermediate_sizes()`
- `cleanup_attachment_relations()`
- `resolve_copy_variant()`
- `corner_luminance()`
- `gd_auto_orient()`
- `build_xmp()`
- `embed_xmp()`
- `read_copy_file()`
- `write_copy_file()`
- `embed_xmp_jpeg()`
- `png_chunk()`
- `embed_xmp_png()`
- `embed_xmp_webp()`
- `known_generators()`
- `read_file_edges()`
- `extract_metadata_text()`
- `detect_provenance()`
- `scan_attachment()`
- `scan_queue_ids()`
- `ajax_batch_scan()`
- `apply_scan_suggestion()`
- `woocommerce_active()`
- `woocommerce_selectors()`
- `woocommerce_variation_data()`
- `scan_uploaded_provenance()`
- `ajax_update_media_status()`
- `batch_transient_key()`
- `ajax_batch_copies()`
- `csv_cell()`
- `csv_write()`
- `export_csv()`
- `post_columns()`
- `post_column_content()`
- `post_review_filter()`
- `is_notice_screen()`
- `onboarding_notice()`
- `dismiss_onboarding()`
- `site_health_tests()`
- `site_health_icons()`
- `api_settings()`
- `api_defaults()`
- `api_media_counts()`
- `api_problem_copy_ids()`
- `api_copy_state()`
- `api_copy_state_label()`
- `api_status_label()`
- `api_create_copy()`
- `api_last_copy_error()`
- `api_set_media_status()`
- `api_invalidate_counts()`
- `site_health_copies()`

---

## 19. Aktueller Stand 3.6.22

3.6.22 ist ein reines WordPress.org-Readme-Wartungsrelease: Die Upgrade-Meldung wurde auf unter 300 Zeichen gekürzt. Frontend, Bildverarbeitung, Datenmodell und Live-Vorschau entsprechen funktional 3.6.21.

- Frontend-Icons werden als theme-neutrale Hintergrund-Spans gerendert.
- Medien werden weder umschlossen noch in ihrer Größe verändert.
- Die Backend-Live-Vorschau ist als kompakte Vorschaufläche mit getrennten Karten für Artikelbild, Archiv/Suche und Kachel aufgebaut.
- Die Vorschau verwendet weiterhin dieselben Badge-Klassen, Symbolgeometrien und responsiven Berechnungen wie das Frontend.

---

## 12a. Änderungsprotokoll 3.6.23 → 3.6.25 (Auszug)

> Die 3.6.24 wurde nie auf wordpress.org veröffentlicht (Download-URL lieferte 404) und die
> Versionsnummer deshalb übersprungen. Geändert wurden 4 Dateien (Hauptdatei, frontend.js,
> frontend.css, readme.txt); alle übrigen Dateien sind byte-identisch zum 3.6.23-Paket.

**Behobene Fehler**

- **Badge-Kollaps:** absolut positionierte Badges mit `left` und `right:auto` erhielten in eng
  umschlossenen Hosts (`figure{width:fit-content}`, Galerie-Kacheln, Woo-Thumbnails,
  Elementor-Widgets) nur Streifenbreite. Fix: `.kit-ai-badge.kit-ai-anchored{width:max-content}`
  (inkl. `-webkit-`), begrenzt durch das vorhandene `max-width: calc(w - 2*inset)`; auch im
  Inline-Critical-CSS. Matrix 240 Kombinationen: vorher 144/240, nachher 240/240 korrekt.
- **Bezugsrahmen durch Theme überschrieben:** `ensureAnchorHost()` setzt Inline-`!important`,
  `verifyAnchors()` prüft `badge.offsetParent === record.host`, repariert einmal und fällt sonst
  auf `.kit-ai-badge.is-unanchored` zurück (Kennzeichnung bleibt im Textfluss sichtbar).
- **Stumme Positionsänderungen:** `transform`-Änderungen per JavaScript lösen kein Ereignis aus.
  `startMovementWatch()` richtet `alignAll(true)` alle 500 ms nur für Viewport-nahe Medien ein
  (übersprungen bei `document.hidden`), zusätzlich `pointerup`/`touchend` für Drag-Slider.
- **CSS kommt verändert an:** neue Methode `overlay_critical_css()` (angehängt an
  `overlay_inline_css()`) liefert die Anker-Regeln inline; Filter `kit_ai_overlay_critical_css`.
- **DOM-Umbau:** `cleanupRecord()` setzt `data-kit-ai-decorated` und WeakSet-Marker zurück,
  `pruneRecords(true)` läuft vor dem Scan des MutationObserver.
- **`display:inline`/`display:contents` als Host:** `overlayHost()` überspringt beide und weicht
  auf den nächstliegenden brauchbaren Elternknoten aus.
- **Veraltete Minify-Caches (WP Rocket/Autoptimize):** neue Filter-Anbindung `rocket_exclude_js`,
  `rocket_exclude_css`, `rocket_exclude_defer_js`, `autoptimize_filter_js_exclude`,
  `autoptimize_filter_css_exclude`; Schalter `kit_ai_optimizer_excluded_assets`. Die Assets laufen
  wieder unter eigener URL `?ver=<Plugin-Version>` und busten sich bei jedem Update selbst.
  Kosten ≈ 2 KB gzip. **Nach einem Umstieg einmalig WP-Rocket- und CDN-Cache leeren.**

**Performance**

- Design-Tokens der Wurzel nur einmal pro Durchlauf gelesen, Icon-Element gecacht, Messen und
  Schreiben getrennt, Geometrie-Signatur verhindert redundante Schreibvorgänge, Durchläufe nur
  für sichtbare Medien, gebündelte Kollisionsprüfung, Pruning gedrosselt.
- Messwerte (Median, 200 Bilder): RecalcStyle 94,4 ms → 19,0 ms (×1003 → ×403),
  Scroll 40 Schritte ≈ 0,5 ms/Schritt ohne Layout/Recalc, Leerlauf ≈ 0,8 ms/s (≈ 0,08 % eines Kerns).

**Wartung**

- `readme.txt`: Stable tag 3.6.25, Tested up to 7.1, Changelog, Upgrade Notice, Cache-Hinweis.
- Versionsstände in den Dateiköpfen von `frontend.js`/`frontend.css` auf 3.6.25 gesetzt.
- `COPY_RENDER_VERSION` bewusst unverändert (`'6'`), bestehende Bildkopien bleiben gültig.
- Keine Einstellungsänderungen, keine Migration in `maybe_upgrade()` nötig.
