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.
| 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.
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.
- Bump
versioninpyproject.tomland merge that tomain. - Write
docs/release-notes/v<version>.mdand 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. - 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.
- 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 checkmust pass before you open a PR - Optional for manual checks:
c2patool,exiftool, and external visible-mark adapters
| 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 |
- Layer A (Unicode / format controls) — deterministic scripts under
scripts/(text_unicode.py,clean_text.py,inspect_text.py). Prefer tests with fixtures intests/fixtures/. - Layer B (statistical rewrite) —
rewrite_text.pyis the backend seam;tsapa.pyowns evolutionary optimization. No bundled model. - Layer V (visible images) —
morphomod.pyowns masks, dilation, PNG restore, and external detector/inpainter adapters. Never guess a region. - Layer M (C2PA / EXIF / XMP / props) —
image_meta.pydelegates HEIF/ AVIF toheif_meta.py;container_meta.pyhandles SVG/PDF/DOCX/ODT/HTML/MD. - Soft-binding risk —
inspect_soft_binding.pydetects and warns; removal remains out of scope. - Batch orchestration — share discovery through
batch_inputs.py; do not duplicate traversal/output-path logic in CLI modules.
- Behaviour matches
SKILL.md/references/removal-matrix.mdwhen relevant - Unit tests updated or added under
tests/ -
make checkpasses (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
- 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.
- Code of Conduct — expected behaviour in the project
- Security policy — how to report vulnerabilities privately
- Bug report and feature request templates