From 23696f42a8b80966f407f2d58889ec205e92ce4d Mon Sep 17 00:00:00 2001 From: Victor Kuznetsov Date: Fri, 28 Aug 2026 10:06:13 -0700 Subject: [PATCH] Enable measured provenance relaxation for the Microsoft badge The OCR badge census split the 343 Microsoft-C2PA uploads into 86 badge carriers and 257 true badge-less files (the watermark is a per-user opt-in). Badge-less scores max 0.251 / p99 0.213, so the 0.266 relaxed gate admits the three faint badges in [0.251, 0.38) with zero measured false fills; re-verified on the provenance path as 3 band detections and 0/257 badge-less fires. --- docs/module-internals.md | 8 ++++++-- src/remove_ai_watermarks/microsoft_engine.py | 14 +++++++++----- tests/test_microsoft_engine.py | 9 ++++++--- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/docs/module-internals.md b/docs/module-internals.md index c274148..90e8305 100644 --- a/docs/module-internals.md +++ b/docs/module-internals.md @@ -823,8 +823,12 @@ and 1200 non-overlapping no-signal controls. At the strict 0.38 gate, 15/17 confirmed carriers fired (min 0.249, p50 0.519, p90 0.578, max 0.579), while 0/1200 controls fired (p99 0.200, max 0.293). The provenance cohort produced 78/343 fires, but that is not a recall measurement because provenance identifies -the provider, not the presence of this visible layout. No provenance relaxation -ships until that cohort is visually labeled. +the provider, not the presence of this visible layout. That cohort was later +labeled by an OCR badge census (2026-08-28: 86 badge carriers, 257 badge-less, +badge-less max 0.251 / p99 0.213), which is what enabled the shipped provenance +relaxation 0.7: the relaxed band [0.251, 0.38) holds three faint badges and +zero false fills, re-verified as 3 band detections with 0/257 badge-less fires +on the provenance path. The detector and removal mask must use compatible geometry. A detector that fires while producing an empty or misplaced mask is a removal failure even if diff --git a/src/remove_ai_watermarks/microsoft_engine.py b/src/remove_ai_watermarks/microsoft_engine.py index 38ef3c4..39802cc 100644 --- a/src/remove_ai_watermarks/microsoft_engine.py +++ b/src/remove_ai_watermarks/microsoft_engine.py @@ -22,10 +22,14 @@ status was not adjudicated, and 1200 non-overlapping no-signal controls: (aspect 3.73-3.89 over 720..1536 px), margins ~0.010/0.007 of the same basis. One size mode, so the shared 3-rung ladder is untouched and the locate box simply wraps the pill with NCC slack. - * STRICT ONLY (``provenance_ncc_factor`` 1.0): controls max 0.293 / p99 - 0.200; confirmed carriers p50 0.519 / p90 0.578 / max 0.579, with 15/17 - above the 0.38 gate. Provenance alone does not relax the gate: only 78/343 - files in that cohort crossed it, and the rest were not visually labeled. + * Provenance relaxation 0.7 (relaxed gate 0.266), enabled 2026-08-28 when the + cohort the strict-only note was waiting for became available: an OCR badge + census split the 343 Microsoft-C2PA uploads into 86 badge carriers and 257 + true badge-less files (the watermark is a per-user opt-in, so 75% of MS + uploads carry none). Badge-less max 0.251 / p99 0.213, so the relaxed band + [0.251, 0.38) holds three genuine faint badges and zero false fills + (measured 3/3; doubao ships 0.7 on a 58%-precision band). Strict controls + max 0.293 / p99 0.200 vs the 0.38 gate. * Front-end "binary": the pill is a bold opaque overlay; the tophat blob is solid with dark-text holes, exactly the template's shape. """ @@ -88,7 +92,7 @@ _CONFIG = TextMarkConfig( min_gw=24, detect_frontend="binary", scale_basis="long", - provenance_ncc_factor=1.0, + provenance_ncc_factor=0.7, ) diff --git a/tests/test_microsoft_engine.py b/tests/test_microsoft_engine.py index f9437f4..f0d21e0 100644 --- a/tests/test_microsoft_engine.py +++ b/tests/test_microsoft_engine.py @@ -76,9 +76,12 @@ class TestLocate: class TestConfig: - def test_strict_only_no_provenance_relaxation(self): - # Provenance names Microsoft, not the presence of this visible layout. - assert MicrosoftEngine().config.provenance_ncc_factor == 1.0 + def test_provenance_relaxation_is_the_measured_07(self): + # The relaxed band was measured on the OCR-censused MS cohort: 257 + # badge-less files max 0.251, so the 0.266 relaxed gate admits the three + # faint badges in [0.251, 0.38) with zero measured false fills. Do not + # move the factor without re-censusing the badge-less cohort. + assert MicrosoftEngine().config.provenance_ncc_factor == 0.7 def test_long_scale_basis(self): assert MicrosoftEngine().config.scale_basis == "long"