=== SEO'n'AI - AI Image check&mark ===
Contributors: geraldwalter
Tags: ai, transparency, iptc, metadata, media library
Requires at least: 6.0
Tested up to: 6.8
Requires PHP: 7.4
Stable tag: 1.3.5
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Reads and writes the IPTC provenance marking of AI generated images, and shows a badge wherever they appear. No re-encoding.

== Description ==

This is not a watermark plugin. It works on the layer underneath: the provenance metadata inside your image files.

Image generators are increasingly expected to embed a machine-readable marking — an IPTC `DigitalSourceType` value in XMP, or a C2PA manifest. SEO'n'AI - AI Image check&mark opens your files and reads it. It tells you which images carry such a marking, which do not, and it can write the missing marking into them. The visible badge on the front end is the second half: the human-readable side of the same disclosure.

= What makes this different =

* It **reads** provenance metadata. Uploads are inspected on arrival; if the file declares itself as AI generated, the image is marked automatically. No other step needed.
* It detects **C2PA / Content Credentials** manifests as well as XMP.
* It **writes losslessly**. The XMP packet is inserted into the container by hand — JPEG APP1, PNG `iTXt`, WebP RIFF chunk. The compressed image data is copied through byte for byte. Nothing is re-encoded, no quality is lost. Watermarking plugins cannot do this, because re-encoding is how they work.
* It **does not touch a single pixel**. The badge is a CSS overlay you can restyle or switch off at any moment.
* It tells you **where the badge does not appear** — bluntly, on its own settings screen, instead of letting you assume it is everywhere.

= Features =

* A per-image checkbox in the attachment details panel, and a one-click "Mark as AI generated" link on every row of the media list
* A **Marking details** screen per image: what the file actually carries — IPTC DigitalSourceType, C2PA, per generated size — including the raw XMP block, so you can verify rather than trust
* A badge in the corner of every image WordPress renders, with configurable text, position, size and style
* An honest alt text, so screen reader users get the disclosure too
* A `data-ai-generated="true"` attribute on the image tag
* Detection of an existing marking (IPTC DigitalSourceType, C2PA) on upload, per image, for a hand-picked selection, and as one run across the whole library
* Automatic marking of uploads whose file already declares itself as AI generated
* Writing the marking into new uploads **and into images already in your library**, one at a time, or as one batch run over everything that is missing it
* A filter and a status column in the media library

Neither the reading nor the writing is held back: you can examine every image in your library, and write the marking into every image that needs one, with no limits and no quota. What the paid add-on adds is changing *many images at once*.

A file is never given a second metadata block. If it already carries XMP from another tool — a photo editor, a stock library — that block is left exactly as it is and the plugin says so instead of writing next to it.

= Honest about the limits =

The badge is a CSS overlay. It appears where WordPress renders the page, and nowhere else. It does **not** appear in:

* Social media previews — the platform loads the file, not your page
* The image file itself, when downloaded or opened by direct URL
* Images used as CSS backgrounds
* RSS feeds and newsletters
* Page builders and sliders that build their own markup
* Lightboxes that rebuild the image element
* Google Images, scrapers and hotlinking third parties

The plugin says so plainly on its own settings screen, under "Where the badge is shown", along with three ways to deal with it.

= Optional add-on =

**SEO'n'AI - AI Image check&mark Pro** is a separate, paid plugin from the author's own shop. It adds two things this plugin does not do at all: marking many images at once — bulk actions in the list view, bulk buttons in the grid, and the option to mark everything a library scan found — and burning the badge into the image files themselves, across every generated size, with a backup of the originals and a one-click restore. None of that code is in this plugin, and this plugin never downloads it — if you want it, you install it yourself.

== Installation ==

1. Upload the `seonai-image-check-mark` folder to `/wp-content/plugins/`, or install it through the plugin installer.
2. Activate the plugin.
3. Go to **Media → AI Image check&mark** to set the badge text and behaviour.
4. In the media library, hover an image row and click **Mark as AI generated** — or open any image and tick the box in the attachment details panel.

== Frequently Asked Questions ==

= Does this make my site compliant with the EU AI Act? =

No plugin can promise that. This one helps you disclose AI generated images visibly and machine-readably. Whether that is sufficient depends on your content, your role and your jurisdiction. Please take legal advice if you need certainty.

= Does it change my image files? =

Only the metadata, and only when you ask it to, and only when the file has no XMP block yet. The pixel data is never re-encoded.

= I ran an image optimiser and the marking disappeared. =

That is what optimisers do: they rebuild the image, and a rebuilt image has lost its metadata block. The plugin watches for exactly this and writes the marking back. If you would rather it did not, switch off "Keep it in the file" in the settings.

= The marking is in the file but an online checker does not find it. =

Then it is being lost on the way out, not on the way in. Open "Marking details" on that image and use the delivery check: it fetches the image the way a visitor would and tells you whether you are being served a cached copy from before the marking was written, or a re-encoded one that had its metadata stripped. Writing and then removing the marking again leaves a JPEG byte-identical to the original — that is covered by the test suite. Everything else the plugin does lives in the HTML and CSS.

= Will it overwrite metadata my generator already wrote? =

No. A marking that came with the file is left alone. Only packets this plugin authored carry its own marker, and only those are ever removed.

= Can it detect AI generated images automatically? =

Only when the file says so itself, via XMP or C2PA. There is no reliable way to detect generated images from the pixels, and this plugin does not pretend otherwise. Everything else is your decision.

= Which formats are supported? =

JPEG, PNG and WebP for metadata. The badge overlay works for any image WordPress can render.

== Screenshots ==

1. Marking an image in the media library
2. The badge on the front end
3. "Where it reaches" — the two layers, the badge and the marking in the file, and where each of them stops
4. The marking details screen, showing the raw XMP block inside the file

== Changelog ==

= 1.3.5 =
* The German translation now uses formal address ("Sie") throughout, matching the rest of SEO'n'AI.

= 1.3.4 =
* The Plugin URI now points at the plugin's own page, so it no longer collides with the author URI.

= 1.3.3 =
* Removed the Plugin URI header: it pointed at the same address as the Author URI, which wordpress.org rejects, and only one of the two is required.
* Fixed the plugin description, which advertised bulk marking. That is in the paid add-on, not here.

= 1.3.2 =
* The delivery check now also compares the delivered bytes with the file on disk. It used to answer "the marking arrives" and stop there — which is true and still misleading when what arrives is an older copy of the picture. That is exactly what happens after the image itself changes: same address, so caches keep what they had.

= 1.3.1 =
* Fixed: marked images showed an empty tile in the media library's grid view. The corner label was attached to an element WordPress positions itself, and overriding that collapsed the thumbnail box — the files were never affected, only what you could see. The label now hangs off the preview container and changes no positioning at all.
* Fixed: the corner label in the grid rendered without its text.

= 1.3.0 =
* The coverage screen is now about both layers, not just the badge: it is called "Where it reaches" and puts the XMP marking in the file next to the CSS badge, so it is clear which half reaches how far.
* New hook `sicm_inspect_actions`, which the Pro add-on uses for single-image burn-in on the marking details screen.

= 1.2.0 =
* Fixed, and this is the important one: the IPTC property was written as an RDF attribute. That is valid, and exiftool reads it — but most online checkers and AI detectors only look for the element form, so the marking was there and nobody could find it. It is now written as an element. Files written by earlier versions are detected and rewritten automatically.
* Added a delivery check: it fetches the image the way a visitor would and compares it byte for byte with the file on disk, so a marking that is missing can be told apart from one that is being stripped on the way out.
* The details screen now shows the file path, the byte size of every generated size and the public address, so you can see at a glance whether the file you downloaded is the file the plugin wrote to.

= 1.1.0 =
* New: "Marking details" screen per image — the parsed provenance plus the raw XMP block, and the state of every generated size.
* New: a read-only run across the whole library, so images that were there before the plugin was installed finally get examined.
* New: one-click marking straight from the media list row.
* New: the marking is kept in the file. Image optimisers, media replacers, thumbnail regeneration and the built-in editor all rewrite images and destroy their metadata in the process; the plugin now records what each file looked like, notices when something changed it, and writes the marking back — immediately where it can see the change, otherwise within the hour.
* New: a delivery check. It fetches the image the way a visitor would and compares it with the file on disk, so you can tell a marking that is missing from a marking that is being stripped between your server and your visitors.
* Changed: a second XMP block is never written. A file that already carries XMP from another tool is left untouched and reported as such.
* Changed: bulk marking moved to the Pro add-on. Marking one image at a time, reading every file and writing the marking stay here, without limits.
* Fixed: writing into a PNG or WebP that already had an XMP block would overwrite it.
* Fixed: the content filter could wrap an image twice when `the_content` ran more than once.
* Performance: detection reads only the head of large images instead of the whole file, and batch runs stop on a time budget so they cannot hit the host's execution limit.
* German translation (de_DE, de_AT, de_CH).

= 1.0.0 =
* Initial release.

== Disclaimer ==

This plugin is a tool, not legal advice and not a compliance guarantee. It marks the images you tell it to mark. It cannot detect AI generated images on its own, and it cannot guarantee that a badge appears in contexts it does not control. The author accepts no liability for missing, incorrect or removed markings, for damage to image files, or for any legal consequences arising from the use of this plugin. Keep backups.
