Record pipeline-lattice reframing and registered-v3 phase lock

Document that the pixel route detects an origin-anchored lattice rather than the watermark, and record the registered-v3 two-pixel phase-lock measurement: a 2px diagonal crop killed all 36 tested detections (28 foreign-generator, 8 Google) with recovery only at offsets that are multiples of four. Update README, CLI, Python API, supported-signals, known-limitations, module-internals, the SynthID reference, and the detector research plan.
This commit is contained in:
Victor Kuznetsov
2026-08-16 21:53:50 -07:00
parent 8eb9c06265
commit e74b06d1a0
8 changed files with 2679 additions and 134 deletions
+40 -17
View File
@@ -12,7 +12,7 @@ path that still runs on CPU and combines `video` and `diffusion`. Add `heif`
independently when path-based pixel APIs must decode HEIC, HEIF, or AVIF. See
the complete [feature-extra matrix](installation.md#feature-extras).
## Detect the supported SynthID carrier
## Detect the generation-pipeline lattice (experimental)
Install `remove-ai-watermarks[pixels]`, then call the lazy top-level API:
@@ -20,26 +20,48 @@ Install `remove-ai-watermarks[pixels]`, then call the lazy top-level API:
import remove_ai_watermarks as raiw
result = raiw.detect_synthid("input.png")
print(result.status) # "detected" | "not_detected" | "unsupported"
print(result.status) # "detected" | "indeterminate" | "unsupported"
print(result.score) # float for a supported image size, otherwise None
print(result.threshold) # frozen operating point
print(result.reason) # support or non-detection reason, otherwise None
# Opt in when the image may have been spatially resized.
registered = raiw.detect_synthid("resized.png", register_scale=True)
# Force the legacy native-period diagnostic only when auditing that expert.
fixed_diagnostic = raiw.detect_synthid("native-period.png", register_scale=False)
```
The detector is positive-only and covers one measured periodic carrier family
This is experimental and is not a watermark detector. Signed provenance through
`identify` is the supported SynthID route. Its statistic is destroyed by a seven-pixel
crop while the published SynthID evaluation survives aggressive crop and
resize, so a positive identifies the generation pipeline. The result exposes
`identifies_watermark` and `tile_aligned_crop_required` so a caller cannot
reach the wrong conclusion from `status` alone. It is positive-only and covers
one measured periodic lattice family
in the [calibrated image-size range](synthid.md#32-how-our-tool-detects-the-supported-carrier).
Arbitrary dimensions are accepted inside the default range, but spatial
resampling can change the carrier period. `register_scale=True` enables the
slower scale-registered operating point over 250,000 through 10,000,000 decoded
pixels, with both sides at least 64 pixels; the default remains the native-period
detector used by `identify`. Its score is a normalized multi-gate statistic with
a threshold of `1.0`, not the native detector's raw template correlation. Scale
0.5 is outside its reliable positive range.
`not_detected` means only that the selected model did not find its carrier;
`unsupported` is kept separate from a negative result. Neither is proof that
the image contains no SynthID watermark.
The default and `identify` use registered-v3 over 250,000 through 10,000,000
decoded pixels, with both sides at least 256 pixels. An opponent-registered-v1
fallback covers 1 through 10 megapixels, sides of at least 768 pixels, and
periods 7.9 through 12.0; period-8 candidates also require the opponent-color
block-edge codec veto. Large-v1 covers 10 through 18 megapixels. Each score
uses a threshold of `1.0`; registered-v3 also requires independent split-patch
confirmation. The fallback is qualified for measured lossless 0.5x-0.75x
views, not lossy retranscodes.
`register_scale=True` forces the registered-v3 cascade, including its bounded
opponent fallback, while `False` explicitly selects the legacy native-period
fixed-v2 diagnostic below the large-image boundary.
`indeterminate` means only that the selected local model did not find its
carrier; `unsupported` means no local expert covers the input geometry. Neither
is proof that the image contains no SynthID watermark.
Both local and official OpenAI JSON results expose `signal_family`,
`provider_scope`, `backend`, `metadata_used_for_verdict`, and
`pixels_preserved`; the local result adds `identifies_watermark` and
`tile_aligned_crop_required`, so callers do not need to infer the evidence boundary from
the detector name.
Remote transport and response failures raise `OpenAIProvenanceError`. Its
`status_code`, `error_code`, `request_id`, `retry_after`, and `retryable`
attributes let a caller implement bounded backoff or a circuit breaker without
turning an API outage into a false `not_detected` result. One function call still
performs at most one upload.
## Remove visible marks
@@ -330,8 +352,9 @@ Timings and spatial artifacts are opt-in. Artifacts include image-identifying da
such as a thumbnail and perceptual hash; aggregate feature families do not.
`identify_from_evidence` does not reopen the source file by default: it evaluates
metadata only, and registered visible marks and pixel-backed invisible watermarks
remain in the path-based `identify` call.
metadata only, and the pixel-backed checks remain in the path-based `identify`
call: registered visible marks, open invisible-watermark decoders, and the
experimental generation-pipeline lattice signal.
Pass `image_path` together with `check_visible` or `check_invisible` to add those
pixel detectors on top of the SAME evidence. That is how a caller asking one file