Skip to content

Latest commit

 

History

History
102 lines (80 loc) · 4.66 KB

File metadata and controls

102 lines (80 loc) · 4.66 KB

Contributing to watermark-remover

Thanks for helping keep the skill accurate and the cleaners reliable. The project is a small Python skill (skills/remove-ai-marks/) plus tests — focused PRs land fastest.

Who can do what

Action Who
Open issues Anyone
Suggest a release Anyone (use the Release suggestion issue template)
Open pull requests Anyone (fork the repo)
Approve and merge pull requests Maintainer only (@elkaix)

main is protected. A change needs a pull request, a passing CI check (test), and an approving review from the code owner before merge. Only the maintainer can give that approval. Direct pushes to main are blocked for non-admins.

To suggest a release without a code change: open a Release suggestion issue.

Cutting a release (maintainer)

Pushing a v* tag is the whole release. It triggers release-pypi.yml, which publishes to PyPI via Trusted Publishing and then creates the GitHub release, and release-images.yml, which pushes the GHCR images.

  1. Bump version in pyproject.toml and merge that to main.
  2. Write docs/release-notes/v<version>.md and merge it before tagging. The first line is the release title (# v1.2.3 — short summary); everything after it is the release body. A tag pushed without its notes file still releases, but silently falls back to commit-generated notes.
  3. Tag the merged commit and push it: git tag -a v1.2.3 -m "…" && git push origin v1.2.3.

The GitHub release is gated on the PyPI publish succeeding, so a release never announces an artifact that failed to ship. A tag that is not a plain vX.Y.Z (v1.2.3-rc1, v1.2.3b1) is published as a prerelease and is never marked "Latest", so it does not move the README release badge. Re-running the job on an existing release updates it rather than failing.

Prerequisites

  • Python 3.10+ (stdlib only for the skill scripts; optional rewrite backends use HTTP to local Ollama / OpenAI-compatible endpoints)
  • Install test extras: python3 -m pip install -r requirements-test.txt
  • From the repo root: make check must pass before you open a PR
  • Optional for manual checks: c2patool, exiftool, and external visible-mark adapters

Layout

Path Role
skills/remove-ai-marks/SKILL.md Agent skill entry (workflow, ethics)
skills/remove-ai-marks/scripts/ Layer A/B hooks + image/container cleaners
skills/remove-ai-marks/references/ Vendors, mark classes, matrix, ethics
DESIGN.md Module seams, invariants, guarantee classes, roadmap
tests/ Pytest suite and fixtures
.github/workflows/ci.yml CI job test

Layers (what to change where)

  1. Layer A (Unicode / format controls) — deterministic scripts under scripts/ (text_unicode.py, clean_text.py, inspect_text.py). Prefer tests with fixtures in tests/fixtures/.
  2. Layer B (statistical rewrite) — rewrite_text.py is the backend seam; tsapa.py owns evolutionary optimization. No bundled model.
  3. Layer V (visible images) — morphomod.py owns masks, dilation, PNG restore, and external detector/inpainter adapters. Never guess a region.
  4. Layer M (C2PA / EXIF / XMP / props) — image_meta.py delegates HEIF/ AVIF to heif_meta.py; container_meta.py handles SVG/PDF/DOCX/ODT/HTML/MD.
  5. Soft-binding risk — inspect_soft_binding.py detects and warns; removal remains out of scope.
  6. Batch orchestration — share discovery through batch_inputs.py; do not duplicate traversal/output-path logic in CLI modules.

Checklist for a change

  • Behaviour matches SKILL.md / references/removal-matrix.md when relevant
  • Unit tests updated or added under tests/
  • make check passes (compile + tests + CLI smoke)
  • Docs updated (README and/or skill references) if user-facing behaviour changes
  • No drive-by refactors unrelated to the fix or feature

PR expectations

  • Stay focused and match existing style (stdlib-first scripts, clear CLI flags)
  • Do not commit secrets, private user files, or large binary fixtures unless needed and redacted
  • Respect references/ethics.md: this tool is for content the user owns

Questions? Open an issue describing the input type (text / image / document) and which layer failed or is missing.

Community