Fix what the verification pass found in the knob removal

An adversarial review of 52b2c11 (five independent audits, each finding put to
two skeptics, plus a completeness critic) found four defects that commit
introduced and several stale claims it should have caught.

The install hint no longer installs -- again. Folding five hints into one
INVISIBLE_EXTRA constant dropped the shell quoting the originals had, so the
printed remediation was `pip install remove-ai-watermarks[qwen-zimage]`. Bare
brackets are a glob in zsh, the macOS default shell: it dies with "no matches
found" before pip runs. That is the exact failure 52b2c11 existed to stop
producing, reintroduced in a different form by a bulk replace. The constant is
quoted now, and a test asserts the quotes rather than the bare substring -- the
old assertions passed either way, which is why nothing caught it.

Three tests were not guarding what they claimed:

- The commit's headline behaviour change, per-profile polish resolution inside
  the engine, had no test at all. Rebinding resolve_adaptive_polish to the
  pre-commit `bool(value)` left the full suite green. Now covered by a test that
  drives the real engine and observes whether humanizer.adaptive_polish ran;
  that mutation now fails it.
- TestAvailability still asserted the pre-commit (torch, diffusers) contract, so
  in a diffusion-only environment it was simply wrong, and comparing each gate to
  a tuple copied from itself could never catch the two gates disagreeing -- the
  drift the shared REMOVAL_MODULES was introduced to prevent. Replaced with a
  test that simulates each module's absence and requires BOTH gates to close.
- Both CUDA-refusal guards skipped in every environment, including CI: they were
  gated on the diffusion stack, which no CI job installs. The refusal fires
  before any torch attribute is read, so they now run everywhere; only the dtype
  assertion keeps its skip.

Also: the retired-knob test covered `invisible` but not `all` or `batch`, though
all three declared those options separately; and smoke_matrix.py still called
remove_watermark(region=...), a parameter 52b2c11 deleted, with the resulting
TypeError swallowed into a skip by a broad except.

Stale documentation the previous sweep missed: known-limitations still described
an MPS out-of-memory fallback and a lighter-pipeline escape that no code can
produce; module-internals declared Canny thresholds of 100/200 as a compatibility
contract while the code uses 13/64, attributed enable_model_cpu_offload to
deleted profiles, and still warned that the engine and CLI defaults differ (this
commit's predecessor made them identical); cli.md gated `all` on the `diffusion`
extra; python-api claimed "cuda" was the only accepted explicit device when
"auto" is too. The claim that `device` is not a parameter was wrong in both
module-internals and .claude/rules/development.md -- it is one, deliberately, and
now says so. `--cpu-offload` help and the pipeline's CUDA guard both still
pointed at MPS.

Not fixed here, reported instead -- both are outside this repo:
- ComfyUI-remove-ai-watermarks nodes.py:332 passes num_inference_steps and
  guidance_scale (plus min_resolution/upscaler from bf4bfc1). distribute.yml's
  comfyui job runs on every release and fails the release if the node sync fails,
  so 0.25.0 needs that node updated first.
- raiw-app modal_app.py:422-425 forwards the same two kwargs into
  remove_watermark. Latent: it is pinned to 1a77e24 and nothing supplies a value
  today, so it fires on the next pin bump.

pre-commit: 1) maintain.sh - exit 0 (1093 tests, Pyright 0 errors, no
vulnerabilities); 2) /simplify - not re-run, this commit is the applied output of
a five-dimension adversarial review; 3) docs sync - grepped MPS/mps, the extras
names and every symbol touched across README, docs/, scripts/, .claude/; updated
6 docs; 4) CLAUDE.md - corrected the device claim in .claude/rules/development.md
and added the shell-quoting rule

Verified by execution, not assertion: smoke_matrix --quick 51 pass / 0 fail,
_knob_rows driven directly 10 pass / 0 fail / 7 skip (no CUDA), the install hint
rendered and round-tripped through zsh, and each new test confirmed to fail
under the mutation it is meant to catch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Victor Kuznetsov
2026-08-03 16:31:39 -07:00
co-authored by Claude Opus 5
parent 52b2c115e8
commit 2f72257996
13 changed files with 213 additions and 130 deletions
+28 -9
View File
@@ -363,16 +363,21 @@ class TestInvisibleCommand:
that advertises a capability the library does not have. Click now refuses the
option itself, which is the honest answer and the one a caller can act on.
"""
for retired in (
retired = (
["--model", "org/custom-sdxl"],
["--steps", "20"],
["--guidance-scale", "5.5"],
["--device", "cpu"],
["--auto"],
):
result = runner.invoke(main, ["invisible", str(sample_png), *retired, "--force"])
assert result.exit_code == 2, f"{retired[0]}: {result.output}"
assert "No such option" in result.output, f"{retired[0]}: {result.output}"
)
# All THREE diffusion commands, not just `invisible`. Each used to declare these
# inline, so removing them from one and not the others is a live possibility.
for command in ("invisible", "all", "batch"):
target = str(sample_png.parent) if command == "batch" else str(sample_png)
for args in retired:
result = runner.invoke(main, [command, target, *args, "--force"])
assert result.exit_code == 2, f"{command} {args[0]}: {result.output}"
assert "No such option" in result.output, f"{command} {args[0]}: {result.output}"
def test_retired_pipeline_names_are_rejected_not_silently_remapped(self, runner, sample_png):
"""default/sdxl/controlnet/qwen were removed with their CPU code paths.
@@ -862,11 +867,12 @@ class TestBatchCommand:
assert out[0, 0, 3] == 0
assert out[100, 100, 3] == 255
def test_batch_explicit_adaptive_polish_overrides_the_qwen_zimage_off(self, runner, tmp_path):
"""qwen-zimage leaves the polish off by default; a typed flag still turns it on.
def test_batch_forwards_an_explicit_adaptive_polish(self, runner, tmp_path):
"""A typed --adaptive-polish must reach the engine as True, not as None.
The off is a parameter-source check, not a changed default, so it must yield to
an explicit --adaptive-polish rather than swallowing it.
This mocks the engine, so it covers the CLI's forwarding only; the per-profile
resolution of an UNSET flag happens inside the real engine and is guarded by
test_invisible_engine.py::TestEngineResolvesThePolishPerProfile.
"""
input_dir = _make_batch_dir(tmp_path, count=2)
output_dir = tmp_path / "output"
@@ -943,6 +949,19 @@ class TestGpuHintMarkup:
profiles run -- so following the advice produced a second, different failure.
"""
def test_the_hint_is_a_command_the_user_can_actually_paste(self, runner, sample_png):
"""The extras bracket must be shell-quoted.
A bulk replace once folded these hints into one constant and dropped the quotes
the originals had. `pip install remove-ai-watermarks[qwen-zimage]` dies with
"zsh: no matches found" on the macOS default shell before pip ever runs -- an
install hint that does not install, which is the failure this hint was fixed to
stop producing in the first place.
"""
with patch("remove_ai_watermarks.invisible_engine.is_available", return_value=False):
result = runner.invoke(main, ["invisible", str(sample_png)])
assert "pip install 'remove-ai-watermarks[qwen-zimage]'" in result.output
def test_invisible_install_hint_names_the_working_extra(self, runner, sample_png):
with patch("remove_ai_watermarks.invisible_engine.is_available", return_value=False):
result = runner.invoke(main, ["invisible", str(sample_png)])