fix(identify): stop flagging multi-actor C2PA manifests as integrity clashes

The C2PA issuer attribution (`c2pa`) and the SynthID proxy (`synthid`) are
derived from the same manifest, so treating them as independent signals made
rule 1 fire on legitimate multi-actor manifests where a product wraps another
vendor's engine (Microsoft Designer on OpenAI, Microsoft on Google) or an edit
chain re-signs (Adobe over a Gemini original). 19 such files in the
2026-06-01/02 spaces batches read as "likely spoofed/laundered" before this.

Group `c2pa` + `synthid` into one provenance source via `_CLASH_SOURCE`; rule 1
now requires two vendors from different sources. A manifest vendor still clashes
with a genuinely independent stamp (EXIF/XMP generator, IPTC AISystemUsed, AIGC,
xAI).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Victor Kuznetsov
2026-06-02 19:02:35 -07:00
co-authored by Claude Opus 4.8
parent 9cb66992bd
commit df0fafe94e
3 changed files with 47 additions and 5 deletions
+22
View File
@@ -731,6 +731,28 @@ class TestIntegrityClashesHelper:
# C2PA Google + SynthID-Google proxy is consistent, not a contradiction.
assert _integrity_clashes({"c2pa": "Google", "synthid": "Google"}, None, camera_has_ai_marker=True) == []
def test_multi_actor_manifest_no_clash(self):
# A multi-actor C2PA manifest names a product + the engine it wraps in ONE
# valid chain (Microsoft Designer on OpenAI, Microsoft on Google, Adobe over
# a Gemini original). The c2pa issuer attribution and the SynthID proxy share
# the same manifest source, so the differing vendors must NOT read as a clash.
for c2pa_vendor, synthid_vendor in (("Microsoft", "OpenAI"), ("Microsoft", "Google"), ("Adobe", "Google")):
assert (
_integrity_clashes({"c2pa": c2pa_vendor, "synthid": synthid_vendor}, None, camera_has_ai_marker=True)
== []
)
def test_manifest_vendor_vs_independent_signal_clashes(self):
# A vendor named only inside the manifest still clashes with a genuinely
# independent stamp (here an EXIF/XMP generator tag) naming a third vendor.
clashes = _integrity_clashes(
{"c2pa": "Microsoft", "synthid": "Google", "exif_generator": "Ideogram"},
None,
camera_has_ai_marker=True,
)
assert len(clashes) == 1
assert "Ideogram" in clashes[0]
def test_single_vendor_no_clash(self):
assert _integrity_clashes({"c2pa": "OpenAI"}, None, camera_has_ai_marker=True) == []