Field report · Lab simulation · Preliminary findings
The Drift Test: your label dies on upload
We ran DisclosureGuard's own drift logic — the same deterministic baseline_for + diff_baseline code that powers the Pro Drift Monitor — on labeled assets pushed through simulated social-platform recompression. This page shows the real results, the full methodology, and exactly what the lab can and cannot prove.
Runs
9
3 labeled assets × 3 simulated pipelines (Instagram-style, Meta-style, TikTok-style)
Labels that died
9 / 9
Every asset lost its C2PA manifest and XMP packet; file bytes changed on all 9.
Drift findings
9 critical
3 high (C2PA stripped) · 6 medium (XMP stripped) · 3 low (generator attribution changed)
The results — run by run
Every asset, every pipeline, every finding
Findings below are recorded verbatim from app/drift.py's diff_baseline — nothing hand-written, nothing rounded up. Before = the labeled asset as exported; After = the same file after simulated platform recompression.
| Asset | Pipeline | Before (labeled) | After (recompressed) | Drift findings | Verdict |
|---|---|---|---|---|---|
| A C2PA + XMP + EXIF |
Instagram-style recompress resized to 1080x810, JPEG Q72, all metadata segments dropped |
C2PA: ✓ · XMP: ✓ · EXIF: ✓ 1447 KB · sha256 63905e704e06… |
C2PA: ✗ · XMP: ✗ 330 KB · sha256 908028e3c520… |
CRITICAL Published file content changed HIGH C2PA manifest stripped MEDIUM XMP provenance packet stripped LOW Generator attribution changed |
LABEL DIED |
| A C2PA + XMP + EXIF |
Meta/Facebook-style recompress resized to 1600x1200, JPEG Q70, all metadata segments dropped |
C2PA: ✓ · XMP: ✓ · EXIF: ✓ 1447 KB · sha256 63905e704e06… |
C2PA: ✗ · XMP: ✗ 577 KB · sha256 970c10cb63ac… |
CRITICAL Published file content changed HIGH C2PA manifest stripped MEDIUM XMP provenance packet stripped LOW Generator attribution changed |
LABEL DIED |
| A C2PA + XMP + EXIF |
TikTok-style recompress resized to 1080x810, JPEG Q60, all metadata segments dropped |
C2PA: ✓ · XMP: ✓ · EXIF: ✓ 1447 KB · sha256 63905e704e06… |
C2PA: ✗ · XMP: ✗ 260 KB · sha256 bb828a4549bb… |
CRITICAL Published file content changed HIGH C2PA manifest stripped MEDIUM XMP provenance packet stripped LOW Generator attribution changed |
LABEL DIED |
| B XMP + EXIF |
Instagram-style recompress resized to 1080x810, JPEG Q72, all metadata segments dropped |
C2PA: — · XMP: ✓ · EXIF: ✓ 1450 KB · sha256 b877f918a590… |
C2PA: ✗ · XMP: ✗ 330 KB · sha256 78970024530e… |
CRITICAL Published file content changed MEDIUM XMP provenance packet stripped |
LABEL DIED |
| B XMP + EXIF |
Meta/Facebook-style recompress resized to 1600x1200, JPEG Q70, all metadata segments dropped |
C2PA: — · XMP: ✓ · EXIF: ✓ 1450 KB · sha256 b877f918a590… |
C2PA: ✗ · XMP: ✗ 578 KB · sha256 818d5594b6a6… |
CRITICAL Published file content changed MEDIUM XMP provenance packet stripped |
LABEL DIED |
| B XMP + EXIF |
TikTok-style recompress resized to 1080x810, JPEG Q60, all metadata segments dropped |
C2PA: — · XMP: ✓ · EXIF: ✓ 1450 KB · sha256 b877f918a590… |
C2PA: ✗ · XMP: ✗ 260 KB · sha256 aede8a5ef049… |
CRITICAL Published file content changed MEDIUM XMP provenance packet stripped |
LABEL DIED |
| C EXIF only |
Instagram-style recompress resized to 1080x810, JPEG Q72, all metadata segments dropped |
C2PA: — · XMP: — · EXIF: ✓ 1448 KB · sha256 00193774e0a0… |
C2PA: ✗ · XMP: ✗ 330 KB · sha256 9001ce916530… |
CRITICAL Published file content changed |
LABEL DIED |
| C EXIF only |
Meta/Facebook-style recompress resized to 1600x1200, JPEG Q70, all metadata segments dropped |
C2PA: — · XMP: — · EXIF: ✓ 1448 KB · sha256 00193774e0a0… |
C2PA: ✗ · XMP: ✗ 577 KB · sha256 a8c5cf4e9c4c… |
CRITICAL Published file content changed |
LABEL DIED |
| C EXIF only |
TikTok-style recompress resized to 1080x810, JPEG Q60, all metadata segments dropped |
C2PA: — · XMP: — · EXIF: ✓ 1448 KB · sha256 00193774e0a0… |
C2PA: ✗ · XMP: ✗ 260 KB · sha256 99b162472cac… |
CRITICAL Published file content changed |
LABEL DIED |
Methodology — read before citing
What the lab did, exactly
This is a lab simulation, not a real upload
Real uploads require platform accounts, real network behavior, and per-account settings — none of which a lab can reproduce. Nothing on this page is a claim about what Instagram, TikTok, or Meta actually did to a real file. What the lab does, deterministically:
- Build labeled assets. Three JPEGs are constructed with Pillow plus manually injected metadata segments: an APP11 JUMBF segment carrying a synthetic C2PA manifest, an APP1 XMP packet, and EXIF Make/Model/Software tags. The manifest text states plainly that it is lab-generated — it never impersonates a real tool or signature. Asset A carries all three; B carries XMP + EXIF; C carries EXIF only.
- Verify with DisclosureGuard's own parser. Before any simulation,
app/provenance.pymust detect exactly the provenance each asset claims (A: C2PA+XMP+EXIF, B: XMP+EXIF, C: EXIF). The run aborts if detection disagrees — the lab cannot grade what it cannot see. - Simulate platform recompression. Each asset is decoded with Pillow, downscaled to the pipeline's max dimensions, and re-encoded as JPEG at the pipeline's quality — without carrying any metadata forward (no EXIF, no XMP, no APPn segments). That decode-to-pixels-and-re-encode model is what social-platform encoders do; Pillow's re-encode drops every provenance-bearing segment, and the lab asserts that it did.
- Instagram-style: 1080px max width, JPEG Q72.
- Meta/Facebook-style: 2048px max long edge, JPEG Q70.
- TikTok-style: 1080px max width, JPEG Q60.
- Run DisclosureGuard's own drift logic.
baseline_for()fingerprints the before-bytes;diff_baseline()diffs the after-bytes. Findings are recorded verbatim.
Generated 2026-10-12T15:30:59Z · Raw results: hidden_files/drift-test-results.json (internal, hash-pinned per run) · Reproduce: cd disclosure-guard && python3 hidden_files/drift-test-lab/run_lab.py — deterministic, fixed seeds.
Honest observations
What the numbers don't say
- 9/9 is a lab result. It proves the mechanism (recompression kills embedded provenance) and that DisclosureGuard's drift logic catches it — not that every real upload loses its label. Platforms evolve their encoders; treat this as a demonstrated risk, not a universal law.
- EXIF loss is only caught as a SHA-256 change. Asset C (EXIF-only) produced a single CRITICAL finding — the bytes changed. DisclosureGuard's drift baseline tracks C2PA, XMP, and generator attribution explicitly, but not EXIF presence. The stripping is still detected (nothing survives a byte change), just not named as "EXIF stripped".
- Visible labels survive; embedded labels don't. A burned-in "AI-generated" caption is pixels — recompression keeps it. This test concerns machine-readable provenance (C2PA/XMP/EXIF), which is what EU AI Act Art. 50's machine-readable marking duty cares about.
- SynthID-class pixel watermarks were not tested. Pixel-level watermarks are designed to survive recompression; file parsing cannot verify them. Different mechanism, different test.
Try it on your own file
Don't take our lab's word for it
Free · One check
🧪 Run the free drift check on your own image
Upload an image (or paste a URL) and we'll fingerprint its provenance, run it through the same simulated publish-strip pipeline used above, and show you the before/after diff: did your label survive? Free-plan accounts get one check — no credit card.
Run my free drift check → No signup needed · Drift Monitor watches this automatically on every publish — Go Pro — $49/mo →
Sworn statements
Frequently asked questions
Did you actually upload files to Instagram, TikTok, or Meta?
No. This is a lab simulation of platform recompression — real uploads require platform accounts. The quality levels are approximations from public reports, not platform-published values. The findings are preliminary and reproducible, and this page says so everywhere the numbers appear.
Why should I trust a simulation?
Because the mechanism it models is not in dispute: platforms decode uploads to pixels and re-encode them, and re-encoding drops APPn metadata segments (C2PA/JUMBF, XMP, EXIF). The lab's contribution is measuring that mechanism with DisclosureGuard's own production drift logic — and showing the findings verbatim.
What exactly was stripped in the test?
On every run: the C2PA/JUMBF manifest (when present), the XMP packet (when present), and EXIF fields. The SHA-256 of the file changed on all 9 runs, which is itself a CRITICAL drift finding — the published bytes no longer match the publish-time baseline.
How do I stop my label from dying?
Serve the original file where you control the bytes (your own CDN, ad server, or site), keep a publish-time baseline, and re-check the live file — which is exactly what the Disclosure Drift Monitor does: daily re-fetch plus on-demand checks, with drift findings in your tamper-evident audit log.