A pre-commit hook that scans staged files for language that normalizes harm to animals — idioms, industry euphemisms, and tech jargon — and suggests clearer alternatives. It runs locally before any code leaves the developer's machine, making it the earliest enforcement point in the development workflow. No external dependencies; patterns compile at import time.
Note
This project is part of the Open Paws ecosystem — AI infrastructure for the animal liberation movement. Explore the full platform →
# .pre-commit-config.yaml
repos:
- repo: https://github.com/Open-Paws/no-animal-violence-pre-commit
rev: v0.2.0
hooks:
- id: no-animal-violence
files: \.(py|ts|js|md|yaml|yml)$ # recommended: limit to text files
exclude: ^tests/fixtures/ # optional: skip known-bad fixtures- Install pre-commit:
pip install pre-commit
- Add the hook config above to
.pre-commit-config.yamlin your repository root. - Install the hooks:
pre-commit install
- Run against all existing files (recommended on first install):
pre-commit run no-animal-violence --all-files
- From this point on, the hook runs automatically on every
git commit.
Run without installing (one-shot scan):
pre-commit try-repo https://github.com/Open-Paws/no-animal-violence-pre-commit no-animal-violence --all-filesThe hook scans each staged file line-by-line against 65+ compiled regular expressions (case-insensitive) covering three categories:
- Animal idioms in code and prose —
kill two birds with one stone,guinea pig,cattle vs. pets,herding cats,canary in the coal mine, and 30+ others - Industry euphemisms for exploitation —
livestock→ farmed animals,processing plant→ slaughterhouse,humane slaughter,spent hens,depopulation, and others - Tech jargon with harmful roots —
master/slave→ primary/replica,whitelist/blacklist→ allowlist/denylist,cowboy coding,code monkey,dogfooding
On any match the hook prints the file path, line number, matched phrase, and suggested alternative, then exits non-zero to block the commit:
Animal violence language detected:
src/utils.py:14
Found: "kill two birds with one stone"
Suggest: "accomplish two things at once"
docs/architecture.md:37
Found: "cattle vs. pets"
Suggest: "ephemeral vs. persistent"
2 instance(s) found. Consider using the suggested alternatives.
Fix the flagged phrases, re-stage, and commit again.
All filtering uses standard pre-commit arguments — no environment variables or config files are required:
| Option | Example | Effect |
|---|---|---|
files |
`.(py | ts |
exclude |
^tests/fixtures/ |
Skip paths matching the pattern |
stages |
[pre-commit, manual] |
Control when the hook runs |
All patterns are built in. There is no external config file to maintain.
The scanner can also be invoked directly, outside of pre-commit:
pip install git+https://github.com/Open-Paws/no-animal-violence-pre-commit.git
no-animal-violence-check src/utils.py docs/README.mdExit code 0 = clean. Exit code 1 = one or more violations found.
- Canonical pattern dictionary — authoritative source for all 65+ patterns and rationale
- pre-commit documentation — general hook configuration reference
.pre-commit-hooks.yaml— hook manifest for this repo
This hook is one layer in a multi-tool detection suite. Each tool targets a different enforcement point:
| Tool | Enforcement point |
|---|---|
| no-animal-violence-pre-commit ← you are here | Local git commit |
| no-animal-violence-action | GitHub Actions CI |
| reviewdog-no-animal-violence | PR inline annotations |
| eslint-plugin-no-animal-violence | JS/TS editor + lint |
| vale-no-animal-violence | Prose / docs |
| vscode-no-animal-violence | VS Code extension |
| danger-plugin-no-animal-violence | Danger.js PR checks |
Implementation details
The hook is a single Python file (no_animal_violence_check.py) with no runtime dependencies beyond the standard library.
Pattern structure: Each entry in PATTERNS is a (regex_string, alternative_string) tuple. All patterns are compiled once at module load time into COMPILED using re.IGNORECASE.
Execution flow:
pre-commitcalls theno-animal-violence-checkconsole script with a list of staged filenames as arguments.main()iterates over each filename and callscheck_file().check_file()opens the file in UTF-8 mode (with error replacement for binary content), iterates line-by-line, and runs all compiled regexes viafinditer.- Findings are collected as
(filepath, line_number, matched_text, alternative)tuples. - If any findings exist, they are printed to stdout and the process exits with code
1, blocking the commit.
Pattern source: Patterns are auto-generated from project-compassionate-code and derived from the no-animal-violence canonical dictionary. The pattern list in this repo is currently maintained as a copy (a known DRY limitation tracked for future resolution). Pattern changes must be applied consistently in both repos until automatic sync is implemented.
Python requirement: 3.8+. The hook is registered in .pre-commit-hooks.yaml with language: python and types: [text].
Contributions are welcome — especially new patterns. The most useful additions are phrases that appear in real codebases and have clear, professionally neutral alternatives.
- Fork the repository and create a feature branch.
- Patterns live in the
PATTERNSlist inno_animal_violence_check.py. Each entry is a(regex, alternative)tuple. - Run the test suite:
python -m pytest tests/
- Verify the hook end-to-end:
pre-commit try-repo . no-animal-violence --all-files - Open a parallel PR in no-animal-violence if adding a new phrase to the canonical dictionary.
- Use movement-standard language in alternatives: "farmed animals" not "livestock", "slaughterhouse" not "processing facility".
MIT — see LICENSE. Copyright (c) 2026 Open Paws.
Pattern dictionary maintained by the Open Paws community. This hook is auto-generated from project-compassionate-code, which submits animal-friendly PRs to open-source repositories at scale.
Donate · Discord · openpaws.ai · Volunteer
