Merge remote-tracking branch 'origin/main' into docs/arxiv-paper-review

# Conflicts:
#	.claude/settings.json
#	docs/installation.md
#	docs/supported-signals.md
#	docs/synthid.md
#	docs/verification-plan.md
#	docs/watermarking-landscape.md
#	pyproject.toml
#	src/remove_ai_watermarks/identify.py
#	uv.lock
This commit is contained in:
Victor Kuznetsov
2026-08-26 12:39:05 -07:00
84 changed files with 6888 additions and 1666 deletions
+10
View File
@@ -256,6 +256,7 @@ class TestInvisibleOptionsMirrorTheEngine:
tile=True,
tile_size=768,
tile_overlap=64,
text_manifest=tmp_path / "verified-lines.json",
)
seen: dict[str, object] = {}
@@ -522,6 +523,15 @@ class TestSourceEvidenceHolder:
assert holder.visible_provenance() == api.visible_provenance(DOUBAO)
assert holder.has_invisible_target() == identify.has_invisible_target(DOUBAO)
def test_holder_preserves_invalid_c2pa_removal_hint(self, tampered_chatgpt_png):
from remove_ai_watermarks import api, identify
holder = api._SourceEvidence(tampered_chatgpt_png)
assert identify.identify(tampered_chatgpt_png, check_visible=False).ai_from_metadata is False
assert holder.has_invisible_target() is True
assert holder.has_invisible_target() == identify.has_invisible_target(tampered_chatgpt_png)
def test_extraction_failure_fails_safe_in_both_directions(self, monkeypatch, tmp_path):
"""No provenance means no relaxation; an unknown invisible target means SCRUB.
Leaving a watermark on a paid removal is worse than over-regenerating."""