The metadata scanners read raw bytes, so random bytes, an empty file or a
truncated PNG or MP4 printed the same "No AI metadata found" or "AI metadata
stripped" a real file gets, with exit 0. `metadata.unreadable_reason` is now
the one readability probe: `identify`, `metadata` and every `video` command
exit 1 on such input, and `batch` and `video batch` fail its row.
`strip_and_verify` refuses it before writing anything.
A `batch` or `video batch` directory with no supported file exits 2 and
creates no output directory. `visible` and `erase` strip and verify on a
staged sibling and publish nothing when a marker survives, as the library
`remove_visible` now does; the diffusion writer raises on a surviving
marker. An invisible engine that cannot start exits 1 without a traceback,
and the MCP server reports a child that could not start.
NotebookLM and Gemini slide-deck templates are recorded as not planned.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A visible mark is in scope when its vendor describes it as identifying
AI-generated content, whichever plan turns it off: the Gemini sparkle,
or the visible watermark Gemini Notebook (formerly NotebookLM) adds to
generated images and videos. Product branding that a paid plan of the
same product removes, such as "Made with Gamma", is out of scope.
Watermarks in LLM-generated text are out of scope: the Claude and
OpenAI marks live in word choice with no hidden characters, only a
substantial rewrite removes them, and their detectors are not public.
The skill states both boundaries, including the vendor-declared
exception so the Gemini sparkle is never refused, and moves to 1.0.13.
The Codex plugin version is now pinned to the Claude plugin's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tier D of the verification plan now says the project publishes no
pass rate per model or resolution: a sample that large needs bulk
automated checks, which OpenAI's API terms and the SynthID Detector's
additional terms (synthid.com/terms, read 2026-10-17) both forbid.
Removal claims rest on the method and on individual hash-bound rows.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
publish-mcp-registry.yml lists server.json in the official MCP registry
on every published release, and on dispatch for a version already on
PyPI. GitHub OIDC proves the io.github.wiltodelta namespace, so no login
or stored secret is involved. It skips a version the registry already
lists, checks out only server.json at the release tag, requires both of
its versions to equal the release, waits for PyPI to serve it, runs a
pinned, checksum-verified mcp-publisher, and reads the entry back.
Tests run the lookup and manifest steps against stubbed replies; every
targeted mutation fails them. docs/development.md records a stale
worktree venv that mixes OpenCV 4.x and 5.x into one cv2 package.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- .codex-plugin/plugin.json and assets/icon.svg package the existing skill
tree for Codex plugin catalogs; skill version 1.0.12 across all manifests
- `remove-ai-watermarks mcp` serves identify, remove and batch over stdio,
one CLI command per tool call, standard library only; server.json and
glama.json for the MCP registry and Glama
- Pin every GitHub Action to a commit SHA
- Call module.train(False) instead of module.eval(), which plugin scanners
read as dynamic code execution
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
video metadata --remove now blanks app-export JSON in keyed and keyless
metadata items (Dreamina writes it twice), which it previously left in
place while exiting 1.
Kling writes an H.264 user_data_unregistered SEI message (a fixed UUID
plus "kling-ai") into the first video sample. get_ai_metadata reports
it as kling_sei, identify_video names Kling from it when no TC260 label
does, and the streaming stripper blanks every copy inside mdat during
its existing copy pass. Lengths stay, the SEI stays well-formed, and
ffmpeg framemd5 hashes of every frame match before and after on both
tracked Kling fixtures. Across 255 local files only the seven Kling
videos changed verdict.
invisible now exits 1 on an undecodable source instead of reporting the
no-signal code for a file it never read.
Docs: a per-command "what each path leaves behind" table, the October
literature sweep, Suno's announced audio watermark, Anthropic's
SynthID-Text-based Claude watermark, and an independent TrustMark
false-positive benchmark.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The upstream registry gained be.immostory.videoseal.1 at revision d5960248,
so `sync_c2pa_soft_bindings.py --check` failed lint on main and on every pull
request. That step runs ahead of Ruff, which hid an ICN001 error in
scripts/_corpus_scan.py; import `date` directly, as the sibling scripts do.
Document the check's live-upstream behavior next to the refresh command.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The SDXL global stack (fp16 UNet, Canny ControlNet, both text encoders, VAE)
is ~8.8 GiB and was always moved to CUDA with .to(device), so it could not
fit an 8 GiB card and --cpu-offload never reached it. Under the Windows
display driver, WSL2 included, the overflow spilled into shared system
memory and the four-step pass ran for over ten minutes instead of failing.
Residency now follows the same rule as the Qwen stack: an explicit request
wins, otherwise the card's total VRAM decides against
RESIDENT_SDXL_GLOBAL_MIN_VRAM_GIB. Below it the Lightning LoRA is fused on
the CPU and the stack is streamed with enable_sequential_cpu_offload, the
fastest placement that completed on every run of an 8 GiB card with 16 GiB
of system RAM. sdxl-zimage joins GLOBAL_OFFLOAD_PROFILES, so the
--cpu-offload warning now fires for chroma-zimage only.
The skills CLI discovers every SKILL.md under .claude/skills, so
provider-oracles and signal-discovery were offered by `npx skills add`
and listed on skills.sh beside the published skill. Mark both
metadata.internal, the CLI's documented hide flag, and fail the suite
on any project skill that lacks it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The full gate outlasts the agent's 10-minute foreground shell cap, so it must
run detached with its exit code written to a file. A stray run is stopped by
its own PID, because a pattern kill also ends other sessions' suites.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bump the package to 0.45.0 and the agent skill to 1.0.11. The skill now names
the dola and workbuddy image mark keys, which 0.44.0 rejects, so the probe's
MIN_CLI_VERSION rises to 0.45.0 and both keys carry a "since CLI" note that
the floor test reads.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add a CI job running the maintain.sh uv-secure scan, pinned to the gate by
a parity test, and a SECURITY.md with private reporting and dependency
remediation. Refresh the security-gate block record for accelerate 1.15.0.
Closes#114
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Open weights remove the hosted-only objection to the 2.x line, but the
Diffusers pipeline has no strength or latent noise-mask input and the Qwen
Research License is non-commercial (issue #111).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Share producer identities across mark routing, attribution, and pinned signers.
Preserve nested Honor TC260 fields and report unsupported RSA signatures.
Document the Google Photos checks and public sample search.
Use an SDK-signed synthetic carrier for negative EKU checks after the original
Microsoft certificates expired. Skip boundary regex scans when no C2PA
soft-binding identifier is present.
MiniMax signs its TC260 label with SM3withSM2 per TC260-PG-202511A. A
verification-only SM3/SM2 (no dependency provides the SM2 curve) checks the
appendix A.1 label message; a signature under the pinned MiniMax key is a
high-confidence aigc_signature signal, a failing one is a caveat, and every
result is the aigc_signature metadata marker. Pinned by the GB/T 32905 SM3
vectors, OpenSSL's SM2 verify vectors and real MiniMax files. Over 411 local
files the only verdict-record change is the marker on nine MiniMax videos.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The upstream list widened com.museblossom.contentsdefence.1 from image to
audio, image and video. Verdicts over 411 local files are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MiniMax writes a TC260-PG-202511A SecurityData object with SM3withSM2
signatures. The label signature verifies on all four local MiniMax videos
against the guide's appendix A.1 message, and the Binding signature over the
compact Bindings entry; the SM3 content hash does not match a naive selection.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bump the package to 0.43.0 and the agent skill to 1.0.10. The skill now names
the wan image and vidu video mark keys, which 0.42.0 rejects, so the probe's
MIN_CLI_VERSION rises to 0.43.0 and both keys carry a "since CLI" note that
the floor test reads.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
module-internals still called FLUX.2 klein pending; the sweep still counted
three inconclusive Gemini rows where only one was an explicit tool verdict,
and the removal page stated a Google chroma leak the data only warns of.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fidelity_metrics.py at each engine's clean strengths: klein keeps Latin and
Cyrillic sign lettering better on two Google carriers, but loses every face
comparison and the verified CJK text, which the 512-pixel LPIPS had hidden.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The fourth Google carrier clears at 0.25, so the klein operating point with
the usual cross-source margin is 0.40, where the limiting carrier is at
LPIPS 0.270 against qwen-zimage's 0.183. klein is not a replacement global
stage for either vendor. Also record that Gemini's image-check allowance is
per account and the new "checks on similar images" quota wording.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Three of four Google carriers clear with klein at or below 0.20, where it
matches qwen-zimage's PSNR at 0.35, beats its LPIPS, and keeps the objects
qwen-zimage redraws. The fourth is detected at 0.10 and inconclusive at 0.20,
so there is no Google operating point yet.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Stock Flux2KleinInpaintPipeline feeds the clean source back as reference
tokens, so it copies the source and OpenAI SynthID survives strength 0.30.
Without those tokens klein clears OpenAI between 0.05 and 0.20, at lower
fidelity than qwen-zimage at its floor. Google is unmeasured: the Gemini
Verify AI tool answered with a tool error or quota limit, which also casts
doubt on two of the earlier color-restoration "inconclusive" rows.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Transplanting the source's a,b channels onto qwen-zimage outputs at the vendor
floors cut CIEDE2000 on all seven tracked originals, kept every OpenAI API
verdict not_detected, but left three of four Gemini checks inconclusive and
painted old object colors onto redrawn ones. Not shipped.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>