Restructure documentation, validate metadata removal, consolidate assets

This commit is contained in:
Victor Kuznetsov committed 2026-07-25 21:08:04 -07:00
1 parent 214c9bb3e7
commit 03cd00f132
172 files changed
+2356 -2863

No files matched your search

+38
View File
@@ -0,0 +1,38 @@
# Repository data
Tracked data is organized by purpose:
```text
data/
fixtures/
provenance/ Real format and provenance fixtures used by tests
calibration/
<vendor>/ Minimal controlled inputs needed to rebuild detector assets
synthid/
originals/ Canonical provider-oracle fixtures, stored once
manifest.csv Provenance and verification record for each original
full-pipeline-quality.csv
Reusable full-pipeline evaluation selection
evaluations/
fidelity/ Evaluation instructions and hand-verified ground truth
```
## Storage rules
1. Store each binary image once. Evaluation manifests and documentation point
to its canonical location.
2. Put executable test fixtures in `fixtures/`.
3. Put only the minimal reproducible detector inputs in `calibration/`.
4. Put externally verified SynthID originals in `synthid/originals/` and keep
both CSV files synchronized.
5. Keep evaluation outputs outside the repository. Record reproducible
commands, hashes, and oracle verdicts instead of committing another corpus
copy. A small curated before-and-after example may live in `docs/images/`
when it is part of the public documentation.
6. Runtime detector assets belong in `src/remove_ai_watermarks/assets/`.
Unregistered research candidates belong in
`scripts/assets/visible-mark-candidates/` so they are not shipped in the
wheel.
The source distribution excludes `data/`; the wheel contains only package
runtime assets.
@@ -1,17 +1,17 @@
# Doubao visible watermark capture
> **Status (captured 2026-05-29; alpha rebuilt 2026-05-31):** the black/gray/white captures were
> taken and are now **committed** in `captures/` (solid colour + watermark, content-free). The alpha
> map is rebuilt by `scripts/visible_alpha_solve.py doubao` (the careful gray-self solve shared with
> Jimeng). The first build claimed "pixel-exact" but left a readable outline on the real sample (issue
> #13 follow-up); removal now reverse-alphas, NCC-aligns, and applies a thin residual inpaint. See the
> `doubao_engine.py` notes in the root `CLAUDE.md`. The text below is kept as the historical capture plan.
> **Status (captured 2026-05-29; asset rebuilt 2026-05-31):** the
> black and gray captures are committed here. The generated alpha
> asset is now a detection silhouette and mask-shaping input only. Current
> removal localizes the mark and sends its footprint to the shared fill backend.
> Reverse-alpha recovery was retired. The details below preserve the historical
> capture rationale.
Goal: capture the Doubao "豆包AI生成" visible watermark over known flat backgrounds so we can
build a per-pixel alpha map and a reverse-alpha-blend remover, the same way the Gemini sparkle
engine works (`src/remove_ai_watermarks/gemini_engine.py`).
rebuild and validate the detection silhouette used by
`src/remove_ai_watermarks/doubao_engine.py`.
## What we already know (verified from prior art, 2026-05-26)
## Historical findings from the capture work
- Blend model: **alpha compositing with a white logo** `watermarked = a*logo + (1-a)*original`,
`logo = (255,255,255)`. Inversion: `original = (watermarked - a*logo) / (1-a)`.
@@ -19,14 +19,13 @@ engine works (`src/remove_ai_watermarks/gemini_engine.py`).
both say "alpha map"). One commercial blog (pixelcleanai) claims "screen blend" instead; the gray
capture below settles it empirically.
- Position: **bottom-right corner**, small margins (right ~8-20px, bottom ~5px), scales with image size.
Confirmed by our sample `data/samples/doubao-1.png` (2048x2048) plus three sources.
Confirmed by our sample `data/fixtures/provenance/doubao-1.png` (2048x2048) plus three sources.
- Size **scales with resolution**. Third-party numbers (~90x18 at <=1024, ~180x40 at >1024) are
approximate and calibrated for ~1024-1280 outputs; at 2048 the strip is much larger. A shipped
third-party alpha map is only 120x20, too small for our 2K/4K target -> capture fresh.
- The planning assumption was that clean inversion leaves residue on textured backgrounds, so the
remover would pair the alpha map with inpainting. After the capture this turned out unnecessary at
the native width (recovery is pixel-exact there and inpaint is off); the shipped remover is
reverse-alpha only, with a residual inpaint applied off-native only.
- The original implementation used reverse-alpha recovery. That path was later
removed in favor of localize then fill because the latter also handles moved
and re-rendered marks.
## Use doubao.com specifically
@@ -35,7 +34,7 @@ the captured template matches our target.
## How to capture (image-edit path, most reliable)
For each seed in `seeds/`:
For each locally generated solid-color seed:
1. Open Doubao image generation, use the image-edit / reference mode, upload the seed.
2. Prompt (Chinese preferred):
@@ -70,16 +69,15 @@ extracted by per-pixel min/median.
- Original download, never a screenshot. PNG preferred; if Doubao only gives JPEG, note it.
- No crop / edit / re-save. Default settings, watermark left ON.
## Naming, drop into `captures/`
## Committed inputs
```
doubao_black_1x1_1.png
doubao_white_1x1_1.png
doubao_gray128_1x1_1.png
doubao_black_16x9_1.png
doubao_content_1x1_1.png
doubao_gray_1x1_1.png
```
The black and gray captures feed `scripts/visible_alpha_solve.py doubao`.
## Also report back
1. Which resolutions and aspect ratios the Doubao UI actually offers.
@@ -1,8 +1,10 @@
# Gemini (Nano Banana) visible sparkle capture
> **Status (captured 2026-05-31):** black/gray/white captures taken and **committed**
> in `captures/` (solid colour + the sparkle, content-free). The sparkle-on-black assets
> **Status (captured 2026-05-31):** the required black capture is committed
> here. The sparkle-on-black assets
> `gemini_bg_{96,48}.png` are rebuilt by `scripts/visible_alpha_solve.py gemini`.
> They support detection and footprint geometry. Current pixel recovery uses the
> shared fill backend, not reverse-alpha inversion.
Google Gemini (Nano Banana) stamps a four-point sparkle icon in the bottom-right corner
via alpha compositing: `watermarked = a*logo + (1-a)*original`. Unlike the Doubao/Jimeng
@@ -20,7 +22,7 @@ text marks, the sparkle is captured over a **pure-black** background, where
## How to capture (image-edit path)
For each solid-colour seed (`seeds/seed_{black,gray,white}_2048.png`, gitignored):
For each locally generated black, gray, or white 2048 px seed:
1. Open Gemini image generation, image-edit / reference mode, upload the seed.
2. Prompt: `Recreate this image exactly as it is, keep it identical, do not add or change anything`
@@ -28,16 +30,15 @@ For each solid-colour seed (`seeds/seed_{black,gray,white}_2048.png`, gitignored
Black is the key one (sparkle on black -> exact alpha). Gray/white cross-check.
## Naming, drop into `captures/`
## Committed input
```
gemini_black_2048.png # the key capture (sparkle on black)
gemini_gray_2048.png
gemini_white_2048.png
```
The solid captures are **committed** (content-free). The synthetic `seeds/` and any
real-content `gemini_content_*.png` validation download are gitignored (local-only).
The gray and white captures were calibration cross-checks and are not needed to
rebuild the assets. Synthetic seeds and real-content validation downloads stay
local.
Rebuild the assets with:
```
@@ -1,15 +1,13 @@
# Jimeng (即梦AI) visible watermark capture
> **Status (completed 2026-05-30):** solid black/gray/white Jimeng captures were
> obtained (issue #13, from @powersee) and the alpha map was solved. Removal is
> reverse-alpha plus a residual inpaint over the glyph footprint; see the
> `jimeng_engine.py` notes in the root `CLAUDE.md`. The text below is kept as the
> capture plan.
> **Status (completed 2026-05-30):** solid black and gray Jimeng captures were
> obtained and the detection asset was solved. The asset now supports detection
> and mask geometry only. Current removal localizes the wordmark and uses the
> shared fill backend. The text below records the capture and calibration work.
Goal: capture the Jimeng / Dreamina "★ 即梦AI" visible wordmark over known flat
backgrounds so we can build a per-pixel alpha map and a reverse-alpha remover, the
same way the Gemini sparkle and Doubao strip engines work
(`src/remove_ai_watermarks/gemini_engine.py`, `doubao_engine.py`).
backgrounds so we can rebuild and validate the silhouette used by
`src/remove_ai_watermarks/jimeng_engine.py`.
## What we learned (verified from the captures, 2026-05-30)
@@ -32,11 +30,10 @@ same way the Gemini sparkle and Doubao strip engines work
width; a real 1440-wide download matched width_frac ~0.21.
- **Per-image render variation:** the alpha maps solved independently from the
black and the gray capture correlate 0.998 but not 1.0 (mean |Δa| ~0.02). Jimeng
re-rasterizes the mark per generation AND jitters its position a few px, so a
single alpha map does NOT pixel-cancel the mark the way Doubao's deterministic
overlay does. Removal therefore: NCC-aligns the alpha to the actual mark (always,
not only off-native), reverse-alphas, then clears the residual with a THIN inpaint
over the glyph footprint (a wide full-footprint pass smeared the texture/edges).
re-rasterizes the mark per generation and jitters its position a few pixels.
This was one reason the old reverse-alpha path needed alignment and residual
inpainting. The current path instead detects the silhouette, localizes the
glyph footprint, and fills that footprint.
## How to capture (image-edit path, most reliable)
@@ -56,19 +53,15 @@ pure white (the mark is nearly invisible on white, as expected).
- Original download, never a screenshot. PNG preferred; if Jimeng only gives JPEG, note it.
- No crop / edit / re-save. Default settings, watermark left ON.
## Naming, drop into `captures/`
## Committed inputs
```
jimeng_cap_A.png # black seed run through Jimeng
jimeng_cap_B.png # white seed
jimeng_cap_C.png # gray seed
jimeng_content_1.png # a normal-content download, for end-to-end validation
```
The solid `jimeng_cap_{A,B,C}.png` captures are **committed** (content-free: a solid
colour + the watermark; the source for `scripts/visible_alpha_solve.py jimeng`). The
synthetic `seeds/` and the real-content `jimeng_content_*.png` validation download are
gitignored (local-only). Rebuild the alpha asset with:
The A and C captures feed
`scripts/visible_alpha_solve.py jimeng`. Rebuild the detection asset with:
```
uv run python scripts/visible_alpha_solve.py jimeng # or: all
@@ -1,15 +1,14 @@
# Samsung Galaxy AI visible watermark capture
> **Status (built 2026-06-05):** flat black/gray/white Samsung Galaxy AI captures
> were obtained (issue #37, from @f-liva) and the alpha map was solved. Removal is
> reverse-alpha plus a thin residual inpaint over the glyph footprint; see the
> `samsung_engine.py` notes in the root `CLAUDE.md`. The text below is the capture
> plan and the open quality follow-up.
> **Status (built 2026-06-05):** flat black and gray Samsung Galaxy AI captures
> were obtained and the detection asset was solved. The asset now supports
> detection and mask geometry only. Current removal localizes the wordmark and
> uses the shared fill backend. The text below records the capture plan and its
> locale and resolution limits.
Goal: capture the Samsung Galaxy AI "✦ Contenuti generati dall'AI" visible wordmark
over known flat backgrounds so we can build a per-pixel alpha map and a reverse-alpha
remover, the same way the Gemini sparkle and the Doubao / Jimeng strips work
(`src/remove_ai_watermarks/gemini_engine.py`, `doubao_engine.py`, `jimeng_engine.py`).
over known flat backgrounds so we can rebuild and validate the silhouette used
by `src/remove_ai_watermarks/samsung_engine.py`.
## What we learned (verified from the captures, 2026-06-05)
@@ -51,15 +50,11 @@ On a Samsung Galaxy AI device (set the UI language to the target locale):
## Files
- `captures/samsung_black_1.png`, `samsung_gray_1.png`, `samsung_white_1.png` --
portrait flat edits (1086 wide), the primary calibration set.
- `captures/samsung_black_2.png`, `samsung_gray_2.png`, `samsung_white_2.png` --
a second (landscape 1920) set.
- `captures/samsung_content_*` -- real-photo validation downloads, **gitignored**
(user content, repo is public).
- `seeds/` -- synthetic solid-color inputs, gitignored (regenerable).
- `samsung_black_1.png` and `samsung_gray_1.png` are the retained solver inputs.
- White, secondary-resolution, and real-content captures were validation
material and are not required to rebuild the asset.
Rebuild the alpha asset with:
Rebuild the detection asset with:
```
uv run python scripts/visible_alpha_solve.py samsung
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

+37
View File
@@ -0,0 +1,37 @@
# Pipeline fidelity evaluation
This evaluation compares diffusion pipelines with
`scripts/fidelity_metrics.py`. The images themselves have one canonical home
in `data/synthid/originals/`; this directory stores only evaluation-specific
ground truth and instructions.
| Original | Provider | Content | Exercises |
| --- | --- | --- | --- |
| `ChatGPT Image May 31, 2026, 02_03_55 PM.png` | OpenAI | Multilingual typography | Text preservation |
| `Gemini_Generated_Image_633uuy633uuy633u.png` | Google | Landscape with a Chinese sign | CJK text preservation |
| `Gemini_Generated_Image_y48j3cy48j3cy48j.png` | Google | Portrait grid | Face identity and skin texture |
## Text ground truth
`ground-truth.json` contains hand-verified OCR for the two text-bearing
originals. To regenerate an OCR seed:
```bash
uv run scripts/fidelity_metrics.py ocr \
"data/synthid/originals/ChatGPT Image May 31, 2026, 02_03_55 PM.png" \
data/synthid/originals/Gemini_Generated_Image_633uuy633uuy633u.png \
--langs en,ru,ch \
--out data/evaluations/fidelity/ground-truth.json
```
Verify and correct the generated text by hand before using it as ground truth.
## Compare
```bash
uv run scripts/fidelity_metrics.py compare \
--original data/synthid/originals/Gemini_Generated_Image_y48j3cy48j3cy48j.png \
--variant controlnet=<out>.png \
--variant qwen=<out>.png \
--ocr-langs ""
```
@@ -0,0 +1,4 @@
{
"ChatGPT Image May 31, 2026, 02_03_55 PM.png": "This is a longer sample text in English.\nTypography can flow smoothly from large to medium size.\nSmaller lines help demonstrate hierarchy, rhythm, and clarity.\nEven the finest text should remain clean and readable.\n这是一段较长的中文示例文本。\n排版可以从大字号逐渐过渡到中字号。\n更小的文字能够展示层次、节奏与清晰度。\n即使是最小的一行,也应该保持清楚易读。\nЭто более длинный пример текста на русском языке.\nТипографика может плавно переходить от крупного размера к среднему.\nБолее мелкие строки показывают иерархию, ритм и ясность.\nДаже самый маленький текст должен оставаться чистым и читаемым.",
"Gemini_Generated_Image_633uuy633uuy633u.png": "每天都是一个新的机会。\n用微笑开始它。\n世界也会向你微笑。"
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 715 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 373 KiB

-35
View File
@@ -1,35 +0,0 @@
# qwen_in — pipeline-fidelity eval set
A small, **stable** set of AI-generated images used to compare the diffusion
removal pipelines (`controlnet` / `sdxl` / `qwen`) for fidelity with
`scripts/fidelity_metrics.py`. Fixing the set in the repo keeps comparisons
reproducible across runs and pipelines.
All four are AI-generated test content (they carry SynthID + C2PA from their
generator — verify with `remove-ai-watermarks identify`), same class as the
`data/samples/` fixtures. No real-person photos.
| file | vendor (SynthID) | content | exercises |
|---|---|---|---|
| `openai_1_original.png` | OpenAI | typography sheet (EN + RU + ZH) | text (multi-script) |
| `openai_2_original.png` | OpenAI | Raiw.cc poster | text (EN, small) |
| `gemini_1_original.png` | Google | landscape + Chinese sign | text (CJK) |
| `gemini_3_original.png` | Google | 3x3 portrait grid | faces (identity / skin texture) |
## Text ground truth
`ground_truth.json` (`{basename: text}`) is the **hand-verified** OCR of the
text-bearing originals, seeded by `fidelity_metrics.py ocr` and corrected by
hand (PaddleOCR mis-reads stylized Cyrillic in particular). It is the reference
for the text CER metric — much cleaner than OCR-vs-OCR. Regenerate the seed with:
uv run scripts/fidelity_metrics.py ocr data/qwen_in/openai_1_original.png \
data/qwen_in/openai_2_original.png data/qwen_in/gemini_1_original.png \
--langs en,ru,ch --out data/qwen_in/ground_truth.json
# then re-verify by hand before trusting it.
## Compare
uv run scripts/fidelity_metrics.py compare \
--original data/qwen_in/gemini_3_original.png \
--variant controlnet=<out>.png --variant qwen=<out>.png --ocr-langs ""
-5
View File
@@ -1,5 +0,0 @@
{
"openai_1_original.png": "This is a longer sample text in English.\nTypography can flow smoothly from large to medium size.\nSmaller lines help demonstrate hierarchy, rhythm, and clarity.\nEven the finest text should remain clean and readable.\n这是一段较长的中文示例文本。\n排版可以从大字号逐渐过渡到中字号。\n更小的文字能够展示层次、节奏与清晰度。\n即使是最小的一行,也应该保持清楚易读。\nЭто более длинный пример текста на русском языке.\nТипографика может плавно переходить от крупного размера к среднему.\nБолее мелкие строки показывают иерархию, ритм и ясность.\nДаже самый маленький текст должен оставаться чистым и читаемым.",
"openai_2_original.png": "raiw.cc\nRaiw.cc – The Platform for the Future\nRaiw.cc is a modern project built for those who value quality, innovation, and reliability.\nSecurity & Reliability\nWe use advanced technologies to protect your data and ensure stable service performance.\nInnovation\nWe continuously explore and implement better solutions to help you stay one step ahead.\nCommunity\nRaiw.cc is an active community of like-minded people who share knowledge, experience, and ideas.\nProgress Together\nWhether you're a developer, creator, or dreamer — raiw.cc is your partner in achieving your goals.\nOur mission is to create opportunities and inspire people to reach new heights.\nRaiw.cc\nVisit raiw.cc today\nExplore more possibilities and start your journey to the future!\nGet Started\nSecure\nInnovative\nCommunity\nForward-Thinking\nINNOVATE · CONNECT · CREATE · GROW",
"gemini_1_original.png": "每天都是一个新的机会。\n用微笑开始它。\n世界也会向你微笑。"
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

-41
View File
@@ -1,41 +0,0 @@
# OpenAI ChatGPT Images 2.0 sample
Reference image generated by OpenAI's ChatGPT Images 2.0 (`gpt-image-2`, launched 2026-04-21). Kept in the repo so the C2PA manifest parser and invisible-watermark pipeline can be re-verified against a real production output.
## `amur-leopard.png`
- Resolution: 1055 x 1491, PNG, 3.0 MB
- Downloaded: 2026-04-22
- Content: AI-generated infographic about the Amur leopard (*Panthera pardus orientalis*), chosen to exercise the model's new accurate-text-rendering feature
### Embedded C2PA manifest (caBX chunk, 23607 bytes)
Parsed by `remove-ai-watermarks metadata --check`:
| Field | Value |
| --- | --- |
| `claim_generator` | GPT-4o |
| `c2pa_spec` | 2.2.0 |
| `digital_source_type` | http://cv.iptc.org/newscodes/digitalsourcetype/trainedAlgorithmicMedia |
| `c2pa_actions` | created, converted |
| Signer | OpenAI OpCo, LLC / OpenAI Media Service API |
| Claim signing CA | Trufo C2PA Claim Signing CA (2025) -> Trufo C2PA Root CA (ECC P384) |
| Timestamp authority | OpenAI TSA Issuing CA -> OpenAI TSA Root CA |
The `trainedAlgorithmicMedia` tag is what triggers "Made with AI" labels on Instagram, Facebook, and X.
### Invisible pixel-level watermark
OpenAI's system card for Images 2.0 states the model embeds an "imperceptible, robust, and content-specific" pixel-level watermark alongside C2PA. This sample was downloaded 2026-04-22, before OpenAI's 19 May 2026 rollout of Google's SynthID watermark across ChatGPT / Codex / the API, so it likely predates SynthID and carries only the original content-specific watermark. Since that rollout, the openai.com/verify tool (in preview) is the public oracle for both signals; there is still no local decoder, so bypass cannot be verified empirically here without the oracle.
## Reproducing the removal
```bash
# C2PA strip only
remove-ai-watermarks metadata amur-leopard.png --remove -o amur-leopard.clean.png
# Full pipeline (visible + diffusion regeneration + metadata)
remove-ai-watermarks all amur-leopard.png -o amur-leopard.all.png --device mps
```
Note: the diffusion step runs at native resolution by default (no pre-downscale), so fine text on a text-heavy infographic like this one is preserved. Pass `--max-resolution N` only if a very large image OOMs the GPU/MPS (that reintroduces a lossy downscale then upscale round-trip).
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 317 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 425 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 815 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 314 KiB

@@ -1,11 +1,10 @@
# SynthID reference corpus
# SynthID oracle fixtures
A locally-collected, labeled image corpus for SynthID work. Two downstream uses:
A compact set of externally verified originals for two uses:
1. **Per-resolution spectral codebook** for an experimental SynthID detector
(carrier frequencies are resolution-dependent, so labels must record the
exact native resolution).
2. **Removal regression set** — verify that our pipeline turns a SynthID-positive
1. **Signal and detector-limit research** with exact native resolutions and
recorded verification sources.
2. **Removal regression set**: verify that a pipeline turns a SynthID-positive
image into a negative one.
There is no reliable local detector of the SynthID pixel watermark (Google's
@@ -15,35 +14,29 @@ external oracle, recorded per image in `verified_via` (see below).
## Layout
```
data/synthid_corpus/
README.md # this protocol (committed)
manifest.csv # labels + provenance (committed; one row per tracked image)
quality_sets/ # reusable test-suite manifests over corpus images
images/ # the labeled corpus (committed)
pos/ # SynthID present
neg/ # SynthID absent (incl. reviewed real photos)
cleaned/ # our pipeline output from a pos image
refs/ # synthetic black/white calibration fills (gitignored, regenerable)
data/synthid/
README.md # collection and verification protocol
manifest.csv # one row per committed original
full-pipeline-quality.csv # reusable evaluation selection
originals/ # one canonical copy of each verified source
```
The labeled images are committed so the corpus is reproducible and the removal
regression set runs in CI. `manifest.csv` is kept in sync with the files on
disk (one row per tracked image; dangling rows are pruned when files are
removed). Before adding any image, confirm it carries no private or
identifiable content you would not publish -- this is a public repo and git
history is permanent. The synthetic `refs/` fills stay gitignored (regenerable,
not part of the labeled set).
The originals are committed so the evaluation set is reproducible and its
hashes can be checked in CI. `manifest.csv` is kept in sync with
`originals/`, one row per file. Generated outputs do not belong here. Store
them outside the repository and record only a reproducible verdict in the
evaluation manifest or documentation.
## Reusable removal-quality set
`quality_sets/full_pipeline_quality_2026-07-25.csv` is the canonical reusable
input set for full-pipeline visual-quality and watermark-removal tests. Its
fixtures are cleared for permanent public test reuse. Tests, benchmarks, and
manual evaluation bundles may read these images repeatedly without requesting
new permission.
`full-pipeline-quality.csv` is the canonical reusable input set for
full-pipeline visual-quality and watermark-removal tests. Its fixtures are
cleared for permanent public test reuse. Tests, benchmarks, and manual
evaluation bundles may read these images repeatedly without requesting new
permission.
The CSV preserves each platform's original filename and maps it to the one
SHA-256-addressed corpus copy. Use `corpus_path` to read the input, but preserve
canonical corpus copy. Use `corpus_path` to read the input, but preserve
`source_filename` in generated result names and keep OpenAI and Gemini outputs
in separate provider groups. This avoids duplicating large PNGs while retaining
the names needed for the corresponding provider oracle.
@@ -67,33 +60,25 @@ Ground-truth quality, strongest first:
- `third-party` — label asserted by an external dataset, not independently verified.
- `none` — unverified.
Prefer `gemini-app` for any image that will train the codebook or gate a test.
Prefer `gemini-app` for any Google image that will gate a test.
## What to collect
For the **codebook** (per target resolution, e.g. 1024x1024, 1024x1536, 1536x2816):
- 30-50+ SynthID-positive outputs per resolution (more is better; ~150-200 per
resolution materially improves carrier discovery).
- At each target resolution, also a batch of **pure-black (#000000)** and
**pure-white (#FFFFFF)** fills generated by the SynthID model — these isolate
the content-independent carrier (the watermark is most of the signal there).
For the **regression set**:
- A handful of `pos` images, their `cleaned` counterparts (run through our
pipeline), and the cleaned re-verified via `gemini-app` (should read negative).
- `neg` controls: non-AI photos and outputs from non-SynthID models (SD,
Midjourney, Firefly) verified negative.
- A small number of positive originals with a recorded provider oracle.
- A quality-set row for every original used by repeatable evaluation.
- Re-run the provider oracle on each newly generated output. Do not commit the
generated output as another corpus copy.
The corpus is committed to a public repo: review every image before adding it
and keep out anything private or identifiable you would not publish.
## Ingesting
Use `scripts/synthid_corpus.py` — it copies a file in, records its sha256,
resolution, format, and C2PA issuer (via our own detector), and appends a row
to `manifest.csv`:
Use `scripts/synthid_corpus.py` to copy a file into `originals/`, record its
SHA-256, resolution, format, and C2PA issuer through our detector, and append a
row to `manifest.csv`:
```bash
uv run python scripts/synthid_corpus.py ingest path/to/*.png \
@@ -105,6 +90,10 @@ uv run python scripts/synthid_corpus.py status # counts by label / resolution
## Autonomous collection via Chrome MCP
> Historical collection notes. Browser interfaces and download behavior can
> change independently of this repository. These steps do not define package
> behavior.
Generation can be driven through the browser (the account must be logged in):
- **Gemini** (`gemini.google.com`): type `Create an image: <prompt>`, wait, hover the
@@ -145,8 +134,8 @@ Download; Leonardo serves the original JPEG in-chat (download button matches).
## Per-platform watermark map (observed, May 2026)
What each platform actually embeds, verified by byte-scan (and Gemini-app oracle
where noted). The detector's coverage is complementary: metadata catches C2PA /
This is a dated observation table, not a live provider compatibility promise.
The detector's coverage is complementary: metadata catches C2PA /
IPTC; `exif_generator` catches EXIF `Make`/`Software` + XMP `CreatorTool`;
`invisible_watermark.py` (imwatermark) catches the open SD/SDXL/FLUX DWT-DCT
watermark on pristine files; the visible detector catches the Gemini-family
+8
View File
@@ -0,0 +1,8 @@
provider,source_filename,corpus_path,sha256,original_signal_verified_via,final_clean_oracle
openai,"ChatGPT Image May 30, 2026, 10_31_08 AM.png","originals/ChatGPT Image May 30, 2026, 10_31_08 AM.png",28ff8732b037f98a4ef5bc277bbcdaa32e5eb9ccbd00b6c8c616e46ef68ae8a0,openai-verify,openai-verify-negative-2026-07-25
openai,"ChatGPT Image May 31, 2026, 02_02_23 PM.png","originals/ChatGPT Image May 31, 2026, 02_02_23 PM.png",228e54413a3ef62b313176dcdba774a56a58c36b54227d1440bc26cbe0aefd82,c2pa-metadata,not-checked-in-final-candidate
openai,"ChatGPT Image May 31, 2026, 02_03_55 PM.png","originals/ChatGPT Image May 31, 2026, 02_03_55 PM.png",05b836ecfe40fd689177fda74384ae4fdcc446505bbc4281cd3cbb6523eb669e,openai-verify,openai-verify-negative-2026-07-25
gemini,"Gemini_Generated_Image_3mc4t93mc4t93mc4.png","originals/Gemini_Generated_Image_3mc4t93mc4t93mc4.png",2c33e75a2db614ce74c83cc0a6ac6c3ac735aca83ab88c9c9345843b124f7856,gemini-app,gemini-app-negative-2026-07-25
gemini,"Gemini_Generated_Image_633uuy633uuy633u.png","originals/Gemini_Generated_Image_633uuy633uuy633u.png",4affd7f27767a445db6abf741355743ba8d95108ad922c9fff045feed8492236,gemini-app,gemini-app-negative-2026-07-25
gemini,"Gemini_Generated_Image_akdbeiakdbeiakdb.png","originals/Gemini_Generated_Image_akdbeiakdbeiakdb.png",8c1a6fb03ef3d45a1f958fb3401e4264e409ff88c2a793061db7f29023454d0e,gemini-app,gemini-app-negative-2026-07-25
gemini,"Gemini_Generated_Image_y48j3cy48j3cy48j.png","originals/Gemini_Generated_Image_y48j3cy48j3cy48j.png",45d79a683134fcba1b147b2aedb669783d474e1fb8a4df329729a0904fd1b46b,gemini-app,gemini-app-negative-2026-07-25
1 provider source_filename corpus_path sha256 original_signal_verified_via final_clean_oracle
2 openai ChatGPT Image May 30, 2026, 10_31_08 AM.png originals/ChatGPT Image May 30, 2026, 10_31_08 AM.png 28ff8732b037f98a4ef5bc277bbcdaa32e5eb9ccbd00b6c8c616e46ef68ae8a0 openai-verify openai-verify-negative-2026-07-25
3 openai ChatGPT Image May 31, 2026, 02_02_23 PM.png originals/ChatGPT Image May 31, 2026, 02_02_23 PM.png 228e54413a3ef62b313176dcdba774a56a58c36b54227d1440bc26cbe0aefd82 c2pa-metadata not-checked-in-final-candidate
4 openai ChatGPT Image May 31, 2026, 02_03_55 PM.png originals/ChatGPT Image May 31, 2026, 02_03_55 PM.png 05b836ecfe40fd689177fda74384ae4fdcc446505bbc4281cd3cbb6523eb669e openai-verify openai-verify-negative-2026-07-25
5 gemini Gemini_Generated_Image_3mc4t93mc4t93mc4.png originals/Gemini_Generated_Image_3mc4t93mc4t93mc4.png 2c33e75a2db614ce74c83cc0a6ac6c3ac735aca83ab88c9c9345843b124f7856 gemini-app gemini-app-negative-2026-07-25
6 gemini Gemini_Generated_Image_633uuy633uuy633u.png originals/Gemini_Generated_Image_633uuy633uuy633u.png 4affd7f27767a445db6abf741355743ba8d95108ad922c9fff045feed8492236 gemini-app gemini-app-negative-2026-07-25
7 gemini Gemini_Generated_Image_akdbeiakdbeiakdb.png originals/Gemini_Generated_Image_akdbeiakdbeiakdb.png 8c1a6fb03ef3d45a1f958fb3401e4264e409ff88c2a793061db7f29023454d0e gemini-app gemini-app-negative-2026-07-25
8 gemini Gemini_Generated_Image_y48j3cy48j3cy48j.png originals/Gemini_Generated_Image_y48j3cy48j3cy48j.png 45d79a683134fcba1b147b2aedb669783d474e1fb8a4df329729a0904fd1b46b gemini-app gemini-app-negative-2026-07-25
+8
View File
@@ -0,0 +1,8 @@
sha256,filename,label,source,model,width,height,format,c2pa_issuer,synthid_metadata,verified_via,added,notes
05b836ecfe40fd689177fda74384ae4fdcc446505bbc4281cd3cbb6523eb669e,"ChatGPT Image May 31, 2026, 02_03_55 PM.png",pos,ChatGPT,gpt-image,1122,1402,png,OpenAI,yes,openai-verify,2026-06-04T00:07:53Z,June 2026 strength-study subject; openai.com/verify: SynthID detected (docs/synthid.md 2.2)
28ff8732b037f98a4ef5bc277bbcdaa32e5eb9ccbd00b6c8c616e46ef68ae8a0,"ChatGPT Image May 30, 2026, 10_31_08 AM.png",pos,ChatGPT,gpt-image,1448,1086,png,OpenAI,yes,openai-verify,2026-06-04T00:07:53Z,June 2026 strength-study subject; openai.com/verify: SynthID detected (docs/synthid.md 2.2)
4affd7f27767a445db6abf741355743ba8d95108ad922c9fff045feed8492236,Gemini_Generated_Image_633uuy633uuy633u.png,pos,Gemini app,gemini,2816,1536,png,Google LLC,yes,gemini-app,2026-06-04T00:08:05Z,June 2026 strength-study subject; Gemini-app Verify with SynthID: detected (docs/synthid.md 2.2)
8c1a6fb03ef3d45a1f958fb3401e4264e409ff88c2a793061db7f29023454d0e,Gemini_Generated_Image_akdbeiakdbeiakdb.png,pos,Gemini app,gemini,2816,1536,png,Google LLC,yes,gemini-app,2026-06-04T00:08:05Z,June 2026 strength-study subject; Gemini-app Verify with SynthID: detected (docs/synthid.md 2.2)
45d79a683134fcba1b147b2aedb669783d474e1fb8a4df329729a0904fd1b46b,Gemini_Generated_Image_y48j3cy48j3cy48j.png,pos,Gemini app,gemini,2816,1536,png,Google LLC,yes,gemini-app,2026-06-04T00:08:05Z,June 2026 strength-study subject; Gemini-app Verify with SynthID: detected (docs/synthid.md 2.2)
2c33e75a2db614ce74c83cc0a6ac6c3ac735aca83ab88c9c9345843b124f7856,Gemini_Generated_Image_3mc4t93mc4t93mc4.png,pos,Gemini app,gemini,2816,1536,png,Google LLC,yes,gemini-app,2026-06-04T00:08:05Z,June 2026 strength-study subject; Gemini-app Verify with SynthID: detected (docs/synthid.md 2.2)
228e54413a3ef62b313176dcdba774a56a58c36b54227d1440bc26cbe0aefd82,"ChatGPT Image May 31, 2026, 02_02_23 PM.png",pos,ChatGPT,gpt-image,1122,1402,png,OpenAI,yes,c2pa-metadata,2026-07-25T20:21:33Z,Reusable full-pipeline quality fixture; original filename preserved in quality-set manifest; cleared for public test reuse
1 sha256 filename label source model width height format c2pa_issuer synthid_metadata verified_via added notes
2 05b836ecfe40fd689177fda74384ae4fdcc446505bbc4281cd3cbb6523eb669e ChatGPT Image May 31, 2026, 02_03_55 PM.png pos ChatGPT gpt-image 1122 1402 png OpenAI yes openai-verify 2026-06-04T00:07:53Z June 2026 strength-study subject; openai.com/verify: SynthID detected (docs/synthid.md 2.2)
3 28ff8732b037f98a4ef5bc277bbcdaa32e5eb9ccbd00b6c8c616e46ef68ae8a0 ChatGPT Image May 30, 2026, 10_31_08 AM.png pos ChatGPT gpt-image 1448 1086 png OpenAI yes openai-verify 2026-06-04T00:07:53Z June 2026 strength-study subject; openai.com/verify: SynthID detected (docs/synthid.md 2.2)
4 4affd7f27767a445db6abf741355743ba8d95108ad922c9fff045feed8492236 Gemini_Generated_Image_633uuy633uuy633u.png pos Gemini app gemini 2816 1536 png Google LLC yes gemini-app 2026-06-04T00:08:05Z June 2026 strength-study subject; Gemini-app Verify with SynthID: detected (docs/synthid.md 2.2)
5 8c1a6fb03ef3d45a1f958fb3401e4264e409ff88c2a793061db7f29023454d0e Gemini_Generated_Image_akdbeiakdbeiakdb.png pos Gemini app gemini 2816 1536 png Google LLC yes gemini-app 2026-06-04T00:08:05Z June 2026 strength-study subject; Gemini-app Verify with SynthID: detected (docs/synthid.md 2.2)
6 45d79a683134fcba1b147b2aedb669783d474e1fb8a4df329729a0904fd1b46b Gemini_Generated_Image_y48j3cy48j3cy48j.png pos Gemini app gemini 2816 1536 png Google LLC yes gemini-app 2026-06-04T00:08:05Z June 2026 strength-study subject; Gemini-app Verify with SynthID: detected (docs/synthid.md 2.2)
7 2c33e75a2db614ce74c83cc0a6ac6c3ac735aca83ab88c9c9345843b124f7856 Gemini_Generated_Image_3mc4t93mc4t93mc4.png pos Gemini app gemini 2816 1536 png Google LLC yes gemini-app 2026-06-04T00:08:05Z June 2026 strength-study subject; Gemini-app Verify with SynthID: detected (docs/synthid.md 2.2)
8 228e54413a3ef62b313176dcdba774a56a58c36b54227d1440bc26cbe0aefd82 ChatGPT Image May 31, 2026, 02_02_23 PM.png pos ChatGPT gpt-image 1122 1402 png OpenAI yes c2pa-metadata 2026-07-25T20:21:33Z Reusable full-pipeline quality fixture; original filename preserved in quality-set manifest; cleared for public test reuse
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 MiB

-41
View File
@@ -1,41 +0,0 @@
sha256,filename,label,source,model,width,height,format,c2pa_issuer,synthid_metadata,verified_via,added,notes
4ef377bde1a1d4eff141972841938643b173f5052992a018b9a21b31ac31731e,"4ef377bd-ChatGPT Image May 23, 2026, 02_43_02 PM.png",pos,ChatGPT,gpt-image,1254,1254,png,OpenAI,yes,openai-verify,2026-05-23T21:48:12Z,fresh post-rollout 2026-05-23; openai.com/verify: SynthID+C2PA detected
d09f84c0e4c6d8b336bf4a9a7277314e940dcb5052ae7051e785cbb3bb42d656,d09f84c0-Gemini_Generated_Image_vq7wkwvq7wkwvq7w.png,pos,Gemini app,gemini,2816,1536,png,Google LLC,yes,c2pa-metadata,2026-05-23T21:52:40Z,"user: latest Gemini, SynthID v2"
7b650522d42db09568e249c04d683c469fb3e280a2c53fcd1031cb9df27c619a,"7b650522-ChatGPT Image May 24, 2026, 12_19_54 PM.png",pos,ChatGPT,gpt-image,1602,982,png,OpenAI,yes,c2pa-metadata,2026-05-24T19:20:25Z,content: misty pine forest at dawn
fb28dba2a82cc101a92fdee5714867b32610d0564f37737fe4bb70782b8ecf32,fb28dba2-Gemini_Generated_Image_dsjlnsdsjlnsdsjl.png,pos,Gemini app,gemini,2816,1536,png,Google LLC,yes,c2pa-metadata,2026-05-24T19:30:25Z,content: elderly fisherman portrait
d20d4cc936dbdfe909c52502039a9e84ba93d97b42b24a0acee5b7d6c71930ae,d20d4cc9-Gemini_Generated_Image_ug6kdpug6kdpug6k.png,pos,Gemini app,gemini,2816,1536,png,Google LLC,yes,c2pa-metadata,2026-05-24T19:33:15Z,content: red coffee mug product shot
28f323345f6496d936c3f1a72f671ddf59d0f81565c24a63bf3286860f633afe,28f32334-chatgpt_fisherman.png,pos,ChatGPT,gpt-image,1023,1537,png,OpenAI,yes,c2pa-metadata,2026-05-24T19:39:20Z,content: elderly fisherman portrait (fetch+blob dl)
88e61a384c2e0b12d97bc66046e4a10542b2987448ba89c4b49e66311e969c84,88e61a38-chatgpt_tokyo.png,pos,ChatGPT,gpt-image,1023,1537,png,OpenAI,yes,c2pa-metadata,2026-05-24T19:42:02Z,content: tokyo street night (fetch+blob dl)
1fa5f77f710c11a4cc69fed60195450def734401ed57c2600a84ce191f985440,1fa5f77f-IMG_0786.HEIC,neg,iPhone (me/post_photos),,4032,3024,heic,,,none,2026-05-24T20:58:47Z,post photo; no C2PA/SynthID (verified)
2ea228ed270cd169e9d38bc3f1a162de7edbf54b6e5ad3c701a3c90010ec7067,2ea228ed-IMG_1791.HEIC,neg,iPhone (me/post_photos),,4032,3024,heic,,,none,2026-05-24T20:58:47Z,post photo; no C2PA/SynthID (verified)
0bb4c176d83fbcbf4e628de7587d6183b9134c4f3fa85f55b96e94185273c7f6,0bb4c176-IMG_1790.HEIC,neg,iPhone (me/post_photos),,4032,3024,heic,,,none,2026-05-24T20:58:47Z,post photo; no C2PA/SynthID (verified)
3fc0c4253f86427777904f41355eacbdcc1a29f6897ec694c7fc68b6e7f70846,3fc0c425-IMG_1450.HEIC,neg,iPhone (me/post_photos),,4032,3024,heic,,,none,2026-05-24T20:58:48Z,post photo; no C2PA/SynthID (verified)
2b148db2b1a314a87647a03828b3d235e7c4c939252f448b572b7658c7bb9723,2b148db2-IMG_1832.HEIC,neg,iPhone (me/post_photos),,4032,3024,heic,,,none,2026-05-24T20:58:48Z,post photo; no C2PA/SynthID (verified)
2d02fed0b6d60ce1142eadac9837a83896569dddbdad7cc5cfdec018f0506d36,2d02fed0-IMG_1520.HEIC,neg,iPhone (me/post_photos),,4032,3024,heic,,,none,2026-05-24T20:58:48Z,post photo; no C2PA/SynthID (verified)
8f170c06f843c2bcf4cf6e249dd76365287fdb3a322637ba93c570f50cb19772,8f170c06-IMG_1078.HEIC,neg,iPhone (me/post_photos),,4032,3024,heic,,,none,2026-05-24T20:58:48Z,post photo; no C2PA/SynthID (verified)
3fc4c8316012abc462df5534d4d995e5af84d35076a2927331107ff994293d9e,3fc4c831-IMG_2566.HEIC,neg,iPhone (me/post_photos),,5712,4284,heic,,,none,2026-05-24T20:58:48Z,post photo; no C2PA/SynthID (verified)
5fe59521d579b536340253d2bcaa7c28ddd2485fa964fc27a9b9e5118ad0cdd1,5fe59521-IMG_1496.HEIC,neg,iPhone (me/post_photos),,4032,3024,heic,,,none,2026-05-24T20:58:48Z,post photo; no C2PA/SynthID (verified)
4ead7918a5aeea7fba78b36af44358fea7ed1db7f46f4bc675152b9d04e68c38,4ead7918-IMG_1300.HEIC,neg,iPhone (me/post_photos),,4032,3024,heic,,,none,2026-05-24T20:58:48Z,post photo; no C2PA/SynthID (verified)
4c795238b89178cf52a3674e721ed7f4cd5068028385491d12171a3c62545c35,4c795238-IMG_3034.HEIC,neg,iPhone (me/post_photos),,5712,4284,heic,,,none,2026-05-24T20:58:49Z,post photo; no C2PA/SynthID (verified)
5abfaccb37c549de67c7f3a751a528a423e24a82c643fdb29094be8debbb206d,5abfaccb-IMG_3018.HEIC,neg,iPhone (me/post_photos),,4032,3024,heic,,,none,2026-05-24T20:58:49Z,post photo; no C2PA/SynthID (verified)
5fed1923d513c1e9ffcba2f240e617fa9344fb39d35144169570ece8b0bd0f33,5fed1923-IMG_0272.HEIC,neg,iPhone (me/post_photos),,4032,3024,heic,,,none,2026-05-24T20:58:49Z,post photo; no C2PA/SynthID (verified)
06b04d8fe8e1cd6bee9a973f93bfda37586924cbfec7d372f59d52aa9196160b,06b04d8f-IMG_1474.HEIC,neg,iPhone (me/post_photos),,5712,4284,heic,,,none,2026-05-24T20:58:49Z,post photo; no C2PA/SynthID (verified)
8fdb574a94e65e14ac29017cf2d5a2ede18a8c4e3f12e04c64292b0d38570062,8fdb574a-IMG_3557.HEIC,neg,iPhone (me/post_photos),,4032,3024,heic,,,none,2026-05-24T20:58:49Z,post photo; no C2PA/SynthID (verified)
c86973424817f62510e2a312b85c52e05adf47ace87a8e717fd442607596f501,c8697342-aistudio_lake.png,pos,Google AI Studio (Nano Banana),gemini-2.5-flash-image,1024,1024,png,,,gemini-app,2026-05-24T21:39:09Z,"API/playground: SynthID pixel CONFIRMED (Gemini-app oracle) + visible sparkle, but NO C2PA/IPTC -> synthid_source blind spot"
1f81827c06d67cf6f6c7f5d53ec8f9738183942a6d1d2717b161fea0fdcc540a,1f81827c-Designer.png,pos,Microsoft Designer,dall-e (Designer),1024,1024,png,"OpenAI, Microsoft",yes,c2pa-metadata,2026-05-24T22:18:40Z,C2PA issuer OpenAI+Microsoft; synthid_source=OpenAI (DALL-E surface inherits OpenAI SynthID+C2PA)
f6dd47a5ffd319aea21bf10dcf9877097666420b02c2620080bac12b03976e7e,f6dd47a5-4ef377bd-gpt-image-2-cleaned.png,cleaned,"our pipeline (invisible/SDXL, native-res default)",stabilityai/stable-diffusion-xl-base-1.0,1254,1254,png,,,openai-verify,2026-05-25T20:50:38Z,"cleaned from 4ef377bd via v0.5.3 'all' at native 1254x1254 (prod-equivalent); openai.com/verify: SynthID NOT detected. Re-confirms #10 native-res default defeats OpenAI SynthID (closes #15 root cause). Note: native res OOMs on 20GB MPS, auto-fell back to CPU."
05b836ecfe40fd689177fda74384ae4fdcc446505bbc4281cd3cbb6523eb669e,05b836ec-openai_1_original.png,pos,ChatGPT,gpt-image,1122,1402,png,OpenAI,yes,openai-verify,2026-06-04T00:07:53Z,June 2026 strength-study subject; openai.com/verify: SynthID detected (docs/synthid.md 2.2)
794e023ea7ae321267fe5af76f4080c98a84a9865669c0733ebfb9757b8638df,794e023e-openai_2_original.png,pos,ChatGPT,gpt-image,1024,1536,png,OpenAI,yes,openai-verify,2026-06-04T00:07:53Z,June 2026 strength-study subject; openai.com/verify: SynthID detected (docs/synthid.md 2.2)
28ff8732b037f98a4ef5bc277bbcdaa32e5eb9ccbd00b6c8c616e46ef68ae8a0,28ff8732-openai_3_original.png,pos,ChatGPT,gpt-image,1448,1086,png,OpenAI,yes,openai-verify,2026-06-04T00:07:53Z,June 2026 strength-study subject; openai.com/verify: SynthID detected (docs/synthid.md 2.2)
4affd7f27767a445db6abf741355743ba8d95108ad922c9fff045feed8492236,4affd7f2-gemini_1_original.png,pos,Gemini app,gemini,2816,1536,png,Google LLC,yes,gemini-app,2026-06-04T00:08:05Z,June 2026 strength-study subject; Gemini-app Verify with SynthID: detected (docs/synthid.md 2.2)
8c1a6fb03ef3d45a1f958fb3401e4264e409ff88c2a793061db7f29023454d0e,8c1a6fb0-gemini_2_original.png,pos,Gemini app,gemini,2816,1536,png,Google LLC,yes,gemini-app,2026-06-04T00:08:05Z,June 2026 strength-study subject; Gemini-app Verify with SynthID: detected (docs/synthid.md 2.2)
45d79a683134fcba1b147b2aedb669783d474e1fb8a4df329729a0904fd1b46b,45d79a68-gemini_3_original.png,pos,Gemini app,gemini,2816,1536,png,Google LLC,yes,gemini-app,2026-06-04T00:08:05Z,June 2026 strength-study subject; Gemini-app Verify with SynthID: detected (docs/synthid.md 2.2)
2c33e75a2db614ce74c83cc0a6ac6c3ac735aca83ab88c9c9345843b124f7856,2c33e75a-gemini_4_original.png,pos,Gemini app,gemini,2816,1536,png,Google LLC,yes,gemini-app,2026-06-04T00:08:05Z,June 2026 strength-study subject; Gemini-app Verify with SynthID: detected (docs/synthid.md 2.2)
2e4ce41cfab456c1d9ea0898e47a5a1d434266ba24e88d4cc807a4180a56925f,2e4ce41c-openai_1_clean_s005.png,cleaned,"our pipeline (SDXL img2img, native)",stabilityai/stable-diffusion-xl-base-1.0,1122,1402,png,,,openai-verify,2026-06-04T00:08:05Z,cleaned at strength 0.05 native; openai.com/verify: SynthID NOT detected (docs/synthid.md 2.2)
f7c52cdfeb14a6be2fff449e89b0181e66e365f36635ee4fcb21567e4cb770ef,f7c52cdf-openai_3_clean_s005.png,cleaned,"our pipeline (SDXL img2img, native)",stabilityai/stable-diffusion-xl-base-1.0,1448,1086,png,,,openai-verify,2026-06-04T00:08:05Z,cleaned at strength 0.05 native; openai.com/verify: SynthID NOT detected (docs/synthid.md 2.2)
37b34274210888702e56eb74f4aa36578f15bf57157a3ebf394f0b8eaa820e19,37b34274-openai_2_clean_s010.png,cleaned,"our pipeline (SDXL img2img, native)",stabilityai/stable-diffusion-xl-base-1.0,1024,1536,png,,,openai-verify,2026-06-04T00:08:05Z,cleaned at strength 0.10 native (min captured for this subject); openai.com/verify: SynthID NOT detected
f99bd9a51814265a23de467d14792db903fef99678b7e7c960d0c6813ed9b0fc,f99bd9a5-gemini_1_clean_s015_max1536.png,cleaned,"our pipeline (SDXL img2img, --max-resolution 1536)",stabilityai/stable-diffusion-xl-base-1.0,2816,1536,png,,,gemini-app,2026-06-04T00:08:05Z,cleaned at strength 0.15 --max-resolution 1536; Gemini-app: SynthID NOT detected (docs/synthid.md 2.2)
4aa5f61c55c1f3fa9bbc49dffff8a404527722637ae694a932245629635b3f2b,4aa5f61c-gemini_2_clean_s015_max1536.png,cleaned,"our pipeline (SDXL img2img, --max-resolution 1536)",stabilityai/stable-diffusion-xl-base-1.0,2816,1536,png,,,gemini-app,2026-06-04T00:08:05Z,cleaned at strength 0.15 --max-resolution 1536; Gemini-app: SynthID NOT detected (docs/synthid.md 2.2)
356196dd63abf011b30b582a0408ccecb726d746065af20ad3611dde72a88725,356196dd-gemini_3_clean_s015_max1536.png,cleaned,"our pipeline (SDXL img2img, --max-resolution 1536)",stabilityai/stable-diffusion-xl-base-1.0,2816,1536,png,,,gemini-app,2026-06-04T00:08:05Z,cleaned at strength 0.15 --max-resolution 1536; Gemini-app: SynthID NOT detected (docs/synthid.md 2.2)
9e4160bb8e3e915d2d4593e37c71495ee7cfcec183602541166f622ebfd84403,9e4160bb-gemini_4_clean_s015_max1536.png,cleaned,"our pipeline (SDXL img2img, --max-resolution 1536)",stabilityai/stable-diffusion-xl-base-1.0,2816,1536,png,,,gemini-app,2026-06-04T00:08:05Z,cleaned at strength 0.15 --max-resolution 1536; Gemini-app: SynthID NOT detected (docs/synthid.md 2.2)
228e54413a3ef62b313176dcdba774a56a58c36b54227d1440bc26cbe0aefd82,"228e5441-ChatGPT Image May 31, 2026, 02_02_23 PM.png",pos,ChatGPT,gpt-image,1122,1402,png,OpenAI,yes,c2pa-metadata,2026-07-25T20:21:33Z,Reusable full-pipeline quality fixture; original filename preserved in quality-set manifest; cleared for public test reuse
1 sha256 filename label source model width height format c2pa_issuer synthid_metadata verified_via added notes
2 4ef377bde1a1d4eff141972841938643b173f5052992a018b9a21b31ac31731e 4ef377bd-ChatGPT Image May 23, 2026, 02_43_02 PM.png pos ChatGPT gpt-image 1254 1254 png OpenAI yes openai-verify 2026-05-23T21:48:12Z fresh post-rollout 2026-05-23; openai.com/verify: SynthID+C2PA detected
3 d09f84c0e4c6d8b336bf4a9a7277314e940dcb5052ae7051e785cbb3bb42d656 d09f84c0-Gemini_Generated_Image_vq7wkwvq7wkwvq7w.png pos Gemini app gemini 2816 1536 png Google LLC yes c2pa-metadata 2026-05-23T21:52:40Z user: latest Gemini, SynthID v2
4 7b650522d42db09568e249c04d683c469fb3e280a2c53fcd1031cb9df27c619a 7b650522-ChatGPT Image May 24, 2026, 12_19_54 PM.png pos ChatGPT gpt-image 1602 982 png OpenAI yes c2pa-metadata 2026-05-24T19:20:25Z content: misty pine forest at dawn
5 fb28dba2a82cc101a92fdee5714867b32610d0564f37737fe4bb70782b8ecf32 fb28dba2-Gemini_Generated_Image_dsjlnsdsjlnsdsjl.png pos Gemini app gemini 2816 1536 png Google LLC yes c2pa-metadata 2026-05-24T19:30:25Z content: elderly fisherman portrait
6 d20d4cc936dbdfe909c52502039a9e84ba93d97b42b24a0acee5b7d6c71930ae d20d4cc9-Gemini_Generated_Image_ug6kdpug6kdpug6k.png pos Gemini app gemini 2816 1536 png Google LLC yes c2pa-metadata 2026-05-24T19:33:15Z content: red coffee mug product shot
7 28f323345f6496d936c3f1a72f671ddf59d0f81565c24a63bf3286860f633afe 28f32334-chatgpt_fisherman.png pos ChatGPT gpt-image 1023 1537 png OpenAI yes c2pa-metadata 2026-05-24T19:39:20Z content: elderly fisherman portrait (fetch+blob dl)
8 88e61a384c2e0b12d97bc66046e4a10542b2987448ba89c4b49e66311e969c84 88e61a38-chatgpt_tokyo.png pos ChatGPT gpt-image 1023 1537 png OpenAI yes c2pa-metadata 2026-05-24T19:42:02Z content: tokyo street night (fetch+blob dl)
9 1fa5f77f710c11a4cc69fed60195450def734401ed57c2600a84ce191f985440 1fa5f77f-IMG_0786.HEIC neg iPhone (me/post_photos) 4032 3024 heic none 2026-05-24T20:58:47Z post photo; no C2PA/SynthID (verified)
10 2ea228ed270cd169e9d38bc3f1a162de7edbf54b6e5ad3c701a3c90010ec7067 2ea228ed-IMG_1791.HEIC neg iPhone (me/post_photos) 4032 3024 heic none 2026-05-24T20:58:47Z post photo; no C2PA/SynthID (verified)
11 0bb4c176d83fbcbf4e628de7587d6183b9134c4f3fa85f55b96e94185273c7f6 0bb4c176-IMG_1790.HEIC neg iPhone (me/post_photos) 4032 3024 heic none 2026-05-24T20:58:47Z post photo; no C2PA/SynthID (verified)
12 3fc0c4253f86427777904f41355eacbdcc1a29f6897ec694c7fc68b6e7f70846 3fc0c425-IMG_1450.HEIC neg iPhone (me/post_photos) 4032 3024 heic none 2026-05-24T20:58:48Z post photo; no C2PA/SynthID (verified)
13 2b148db2b1a314a87647a03828b3d235e7c4c939252f448b572b7658c7bb9723 2b148db2-IMG_1832.HEIC neg iPhone (me/post_photos) 4032 3024 heic none 2026-05-24T20:58:48Z post photo; no C2PA/SynthID (verified)
14 2d02fed0b6d60ce1142eadac9837a83896569dddbdad7cc5cfdec018f0506d36 2d02fed0-IMG_1520.HEIC neg iPhone (me/post_photos) 4032 3024 heic none 2026-05-24T20:58:48Z post photo; no C2PA/SynthID (verified)
15 8f170c06f843c2bcf4cf6e249dd76365287fdb3a322637ba93c570f50cb19772 8f170c06-IMG_1078.HEIC neg iPhone (me/post_photos) 4032 3024 heic none 2026-05-24T20:58:48Z post photo; no C2PA/SynthID (verified)
16 3fc4c8316012abc462df5534d4d995e5af84d35076a2927331107ff994293d9e 3fc4c831-IMG_2566.HEIC neg iPhone (me/post_photos) 5712 4284 heic none 2026-05-24T20:58:48Z post photo; no C2PA/SynthID (verified)
17 5fe59521d579b536340253d2bcaa7c28ddd2485fa964fc27a9b9e5118ad0cdd1 5fe59521-IMG_1496.HEIC neg iPhone (me/post_photos) 4032 3024 heic none 2026-05-24T20:58:48Z post photo; no C2PA/SynthID (verified)
18 4ead7918a5aeea7fba78b36af44358fea7ed1db7f46f4bc675152b9d04e68c38 4ead7918-IMG_1300.HEIC neg iPhone (me/post_photos) 4032 3024 heic none 2026-05-24T20:58:48Z post photo; no C2PA/SynthID (verified)
19 4c795238b89178cf52a3674e721ed7f4cd5068028385491d12171a3c62545c35 4c795238-IMG_3034.HEIC neg iPhone (me/post_photos) 5712 4284 heic none 2026-05-24T20:58:49Z post photo; no C2PA/SynthID (verified)
20 5abfaccb37c549de67c7f3a751a528a423e24a82c643fdb29094be8debbb206d 5abfaccb-IMG_3018.HEIC neg iPhone (me/post_photos) 4032 3024 heic none 2026-05-24T20:58:49Z post photo; no C2PA/SynthID (verified)
21 5fed1923d513c1e9ffcba2f240e617fa9344fb39d35144169570ece8b0bd0f33 5fed1923-IMG_0272.HEIC neg iPhone (me/post_photos) 4032 3024 heic none 2026-05-24T20:58:49Z post photo; no C2PA/SynthID (verified)
22 06b04d8fe8e1cd6bee9a973f93bfda37586924cbfec7d372f59d52aa9196160b 06b04d8f-IMG_1474.HEIC neg iPhone (me/post_photos) 5712 4284 heic none 2026-05-24T20:58:49Z post photo; no C2PA/SynthID (verified)
23 8fdb574a94e65e14ac29017cf2d5a2ede18a8c4e3f12e04c64292b0d38570062 8fdb574a-IMG_3557.HEIC neg iPhone (me/post_photos) 4032 3024 heic none 2026-05-24T20:58:49Z post photo; no C2PA/SynthID (verified)
24 c86973424817f62510e2a312b85c52e05adf47ace87a8e717fd442607596f501 c8697342-aistudio_lake.png pos Google AI Studio (Nano Banana) gemini-2.5-flash-image 1024 1024 png gemini-app 2026-05-24T21:39:09Z API/playground: SynthID pixel CONFIRMED (Gemini-app oracle) + visible sparkle, but NO C2PA/IPTC -> synthid_source blind spot
25 1f81827c06d67cf6f6c7f5d53ec8f9738183942a6d1d2717b161fea0fdcc540a 1f81827c-Designer.png pos Microsoft Designer dall-e (Designer) 1024 1024 png OpenAI, Microsoft yes c2pa-metadata 2026-05-24T22:18:40Z C2PA issuer OpenAI+Microsoft; synthid_source=OpenAI (DALL-E surface inherits OpenAI SynthID+C2PA)
26 f6dd47a5ffd319aea21bf10dcf9877097666420b02c2620080bac12b03976e7e f6dd47a5-4ef377bd-gpt-image-2-cleaned.png cleaned our pipeline (invisible/SDXL, native-res default) stabilityai/stable-diffusion-xl-base-1.0 1254 1254 png openai-verify 2026-05-25T20:50:38Z cleaned from 4ef377bd via v0.5.3 'all' at native 1254x1254 (prod-equivalent); openai.com/verify: SynthID NOT detected. Re-confirms #10 native-res default defeats OpenAI SynthID (closes #15 root cause). Note: native res OOMs on 20GB MPS, auto-fell back to CPU.
27 05b836ecfe40fd689177fda74384ae4fdcc446505bbc4281cd3cbb6523eb669e 05b836ec-openai_1_original.png pos ChatGPT gpt-image 1122 1402 png OpenAI yes openai-verify 2026-06-04T00:07:53Z June 2026 strength-study subject; openai.com/verify: SynthID detected (docs/synthid.md 2.2)
28 794e023ea7ae321267fe5af76f4080c98a84a9865669c0733ebfb9757b8638df 794e023e-openai_2_original.png pos ChatGPT gpt-image 1024 1536 png OpenAI yes openai-verify 2026-06-04T00:07:53Z June 2026 strength-study subject; openai.com/verify: SynthID detected (docs/synthid.md 2.2)
29 28ff8732b037f98a4ef5bc277bbcdaa32e5eb9ccbd00b6c8c616e46ef68ae8a0 28ff8732-openai_3_original.png pos ChatGPT gpt-image 1448 1086 png OpenAI yes openai-verify 2026-06-04T00:07:53Z June 2026 strength-study subject; openai.com/verify: SynthID detected (docs/synthid.md 2.2)
30 4affd7f27767a445db6abf741355743ba8d95108ad922c9fff045feed8492236 4affd7f2-gemini_1_original.png pos Gemini app gemini 2816 1536 png Google LLC yes gemini-app 2026-06-04T00:08:05Z June 2026 strength-study subject; Gemini-app Verify with SynthID: detected (docs/synthid.md 2.2)
31 8c1a6fb03ef3d45a1f958fb3401e4264e409ff88c2a793061db7f29023454d0e 8c1a6fb0-gemini_2_original.png pos Gemini app gemini 2816 1536 png Google LLC yes gemini-app 2026-06-04T00:08:05Z June 2026 strength-study subject; Gemini-app Verify with SynthID: detected (docs/synthid.md 2.2)
32 45d79a683134fcba1b147b2aedb669783d474e1fb8a4df329729a0904fd1b46b 45d79a68-gemini_3_original.png pos Gemini app gemini 2816 1536 png Google LLC yes gemini-app 2026-06-04T00:08:05Z June 2026 strength-study subject; Gemini-app Verify with SynthID: detected (docs/synthid.md 2.2)
33 2c33e75a2db614ce74c83cc0a6ac6c3ac735aca83ab88c9c9345843b124f7856 2c33e75a-gemini_4_original.png pos Gemini app gemini 2816 1536 png Google LLC yes gemini-app 2026-06-04T00:08:05Z June 2026 strength-study subject; Gemini-app Verify with SynthID: detected (docs/synthid.md 2.2)
34 2e4ce41cfab456c1d9ea0898e47a5a1d434266ba24e88d4cc807a4180a56925f 2e4ce41c-openai_1_clean_s005.png cleaned our pipeline (SDXL img2img, native) stabilityai/stable-diffusion-xl-base-1.0 1122 1402 png openai-verify 2026-06-04T00:08:05Z cleaned at strength 0.05 native; openai.com/verify: SynthID NOT detected (docs/synthid.md 2.2)
35 f7c52cdfeb14a6be2fff449e89b0181e66e365f36635ee4fcb21567e4cb770ef f7c52cdf-openai_3_clean_s005.png cleaned our pipeline (SDXL img2img, native) stabilityai/stable-diffusion-xl-base-1.0 1448 1086 png openai-verify 2026-06-04T00:08:05Z cleaned at strength 0.05 native; openai.com/verify: SynthID NOT detected (docs/synthid.md 2.2)
36 37b34274210888702e56eb74f4aa36578f15bf57157a3ebf394f0b8eaa820e19 37b34274-openai_2_clean_s010.png cleaned our pipeline (SDXL img2img, native) stabilityai/stable-diffusion-xl-base-1.0 1024 1536 png openai-verify 2026-06-04T00:08:05Z cleaned at strength 0.10 native (min captured for this subject); openai.com/verify: SynthID NOT detected
37 f99bd9a51814265a23de467d14792db903fef99678b7e7c960d0c6813ed9b0fc f99bd9a5-gemini_1_clean_s015_max1536.png cleaned our pipeline (SDXL img2img, --max-resolution 1536) stabilityai/stable-diffusion-xl-base-1.0 2816 1536 png gemini-app 2026-06-04T00:08:05Z cleaned at strength 0.15 --max-resolution 1536; Gemini-app: SynthID NOT detected (docs/synthid.md 2.2)
38 4aa5f61c55c1f3fa9bbc49dffff8a404527722637ae694a932245629635b3f2b 4aa5f61c-gemini_2_clean_s015_max1536.png cleaned our pipeline (SDXL img2img, --max-resolution 1536) stabilityai/stable-diffusion-xl-base-1.0 2816 1536 png gemini-app 2026-06-04T00:08:05Z cleaned at strength 0.15 --max-resolution 1536; Gemini-app: SynthID NOT detected (docs/synthid.md 2.2)
39 356196dd63abf011b30b582a0408ccecb726d746065af20ad3611dde72a88725 356196dd-gemini_3_clean_s015_max1536.png cleaned our pipeline (SDXL img2img, --max-resolution 1536) stabilityai/stable-diffusion-xl-base-1.0 2816 1536 png gemini-app 2026-06-04T00:08:05Z cleaned at strength 0.15 --max-resolution 1536; Gemini-app: SynthID NOT detected (docs/synthid.md 2.2)
40 9e4160bb8e3e915d2d4593e37c71495ee7cfcec183602541166f622ebfd84403 9e4160bb-gemini_4_clean_s015_max1536.png cleaned our pipeline (SDXL img2img, --max-resolution 1536) stabilityai/stable-diffusion-xl-base-1.0 2816 1536 png gemini-app 2026-06-04T00:08:05Z cleaned at strength 0.15 --max-resolution 1536; Gemini-app: SynthID NOT detected (docs/synthid.md 2.2)
41 228e54413a3ef62b313176dcdba774a56a58c36b54227d1440bc26cbe0aefd82 228e5441-ChatGPT Image May 31, 2026, 02_02_23 PM.png pos ChatGPT gpt-image 1122 1402 png OpenAI yes c2pa-metadata 2026-07-25T20:21:33Z Reusable full-pipeline quality fixture; original filename preserved in quality-set manifest; cleared for public test reuse
@@ -1,8 +0,0 @@
provider,source_filename,corpus_path,sha256,original_signal_verified_via,final_clean_oracle
openai,"ChatGPT Image May 30, 2026, 10_31_08 AM.png","images/pos/28ff8732-openai_3_original.png",28ff8732b037f98a4ef5bc277bbcdaa32e5eb9ccbd00b6c8c616e46ef68ae8a0,openai-verify,openai-verify-negative-2026-07-25
openai,"ChatGPT Image May 31, 2026, 02_02_23 PM.png","images/pos/228e5441-ChatGPT Image May 31, 2026, 02_02_23 PM.png",228e54413a3ef62b313176dcdba774a56a58c36b54227d1440bc26cbe0aefd82,c2pa-metadata,not-checked-in-final-candidate
openai,"ChatGPT Image May 31, 2026, 02_03_55 PM.png","images/pos/05b836ec-openai_1_original.png",05b836ecfe40fd689177fda74384ae4fdcc446505bbc4281cd3cbb6523eb669e,openai-verify,openai-verify-negative-2026-07-25
gemini,"Gemini_Generated_Image_3mc4t93mc4t93mc4.png","images/pos/2c33e75a-gemini_4_original.png",2c33e75a2db614ce74c83cc0a6ac6c3ac735aca83ab88c9c9345843b124f7856,gemini-app,gemini-app-negative-2026-07-25
gemini,"Gemini_Generated_Image_633uuy633uuy633u.png","images/pos/4affd7f2-gemini_1_original.png",4affd7f27767a445db6abf741355743ba8d95108ad922c9fff045feed8492236,gemini-app,gemini-app-negative-2026-07-25
gemini,"Gemini_Generated_Image_akdbeiakdbeiakdb.png","images/pos/8c1a6fb0-gemini_2_original.png",8c1a6fb03ef3d45a1f958fb3401e4264e409ff88c2a793061db7f29023454d0e,gemini-app,gemini-app-negative-2026-07-25
gemini,"Gemini_Generated_Image_y48j3cy48j3cy48j.png","images/pos/45d79a68-gemini_3_original.png",45d79a683134fcba1b147b2aedb669783d474e1fb8a4df329729a0904fd1b46b,gemini-app,gemini-app-negative-2026-07-25
1 provider source_filename corpus_path sha256 original_signal_verified_via final_clean_oracle
2 openai ChatGPT Image May 30, 2026, 10_31_08 AM.png images/pos/28ff8732-openai_3_original.png 28ff8732b037f98a4ef5bc277bbcdaa32e5eb9ccbd00b6c8c616e46ef68ae8a0 openai-verify openai-verify-negative-2026-07-25
3 openai ChatGPT Image May 31, 2026, 02_02_23 PM.png images/pos/228e5441-ChatGPT Image May 31, 2026, 02_02_23 PM.png 228e54413a3ef62b313176dcdba774a56a58c36b54227d1440bc26cbe0aefd82 c2pa-metadata not-checked-in-final-candidate
4 openai ChatGPT Image May 31, 2026, 02_03_55 PM.png images/pos/05b836ec-openai_1_original.png 05b836ecfe40fd689177fda74384ae4fdcc446505bbc4281cd3cbb6523eb669e openai-verify openai-verify-negative-2026-07-25
5 gemini Gemini_Generated_Image_3mc4t93mc4t93mc4.png images/pos/2c33e75a-gemini_4_original.png 2c33e75a2db614ce74c83cc0a6ac6c3ac735aca83ab88c9c9345843b124f7856 gemini-app gemini-app-negative-2026-07-25
6 gemini Gemini_Generated_Image_633uuy633uuy633u.png images/pos/4affd7f2-gemini_1_original.png 4affd7f27767a445db6abf741355743ba8d95108ad922c9fff045feed8492236 gemini-app gemini-app-negative-2026-07-25
7 gemini Gemini_Generated_Image_akdbeiakdbeiakdb.png images/pos/8c1a6fb0-gemini_2_original.png 8c1a6fb03ef3d45a1f958fb3401e4264e409ff88c2a793061db7f29023454d0e gemini-app gemini-app-negative-2026-07-25
8 gemini Gemini_Generated_Image_y48j3cy48j3cy48j.png images/pos/45d79a68-gemini_3_original.png 45d79a683134fcba1b147b2aedb669783d474e1fb8a4df329729a0904fd1b46b gemini-app gemini-app-negative-2026-07-25