Match the vendor registries against metadata, not coded pixels

The registries are raw substrings and the shortest tokens are four and five bytes
(`Bria`, `Adobe`, `Canva`). Over a megabyte of compressed pixel data such a sequence
turns up by chance: `Bria` matched inside the entropy-coded scan of 4 of 14,707
corpus JPEGs, in none of which the manifest names Bria. The rate is what a four-byte
pattern predicts on that corpus, and the Bria entry asserts AI, so a chance match can
declare an image AI-generated rather than merely mislabel its signer.

`_metadata_region` gives the registry scans the container's metadata: JPEG marker
segments before the coded scan, PNG chunks other than IDAT, both trailers, and
whatever `scan_head` appended past the window. Every other check keeps the full
buffer -- their markers are long and distinctive. A container that does not parse is
returned whole, since dropping real evidence to avoid a chance match is the wrong
trade. `c2pa_marker_in` already refuses a bare `c2pa` substring for this reason;
this is the same defence for the registries.

Verified the way the rules require for a change that MOVES a verdict: over all 48,905
corpus images, exactly one file changed, the one named in advance, from
"C2PA Content Credentials (Bria Artificial Intelligence)" to "(unknown signer)".
Record-path parity is 0 disagreements, down from 75 when this work started.

The audit's own baseline comparison is fixed here too. It compared confidence and
signals only, and so reported "0 changed" for the run whose single intended
correction was a watermark line -- the change it exists to show.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Victor Kuznetsov
2026-08-05 21:10:55 -07:00
co-authored by Claude Opus 5
parent 9a29dcac8a
commit 1124c591be
4 changed files with 147 additions and 12 deletions
+6
View File
@@ -391,6 +391,12 @@ metadata extraction from verdict logic:
metadata record into the same evidence type without file access. Diagnostic
values under `error` and `kind` are excluded from evidence while nested raw
bytes remain available through encoded binary fields.
- The vendor registries are matched over `_metadata_region(head)`, not the whole scan
buffer: they see the container's metadata and not its coded pixels. The tokens are
raw substrings and the shortest are four and five bytes, so over a megabyte of
compressed data one turns up by chance, and the entry it hits may assert AI. The
trim happens only when the container parses -- a malformed or unknown one is left
whole, because dropping real evidence to avoid a chance match is the wrong trade.
- `identify_from_evidence` evaluates that evidence without reopening the source. Rules
that decide a verdict live here, not in extraction: extraction has two
implementations, and a rule in only one of them is a rule the other lacks. The