Strip invisible AI watermarks from text through adversarial perturbation.
AI text generators embed probabilistic watermarksβinvisible statistical signatures baked into word choice, sentence rhythm, and transition patterns. When you run your own writing through an AI for polish, these watermarks tag your text as "synthetic." That's bullshit.
rehuman breaks those signatures. It perturbs text adversariallyβrestructuring syntax, swapping register, injecting human idiosyncrasiesβwhile preserving meaning via Sentence-BERT semantic validation.
Raw AI-Polished Text β Parse β Detect β Perturb β Validate β Human-Grade Output
AI-likelihood: 0.84 AI-likelihood: 0.31
Linux / macOS:
git clone <repo>
cd rehuman
chmod +x scripts/setup_env.sh
./scripts/setup_env.sh
source venv/bin/activateWindows:
git clone <repo>
cd rehuman
scripts\setup_env.bat
venv\Scripts\activate.batManual (if scripts fail):
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
python -m spacy download en_core_web_md
python -m nltk.downloader punkt averaged_perceptron_taggerVerify installation:
python -m unittest tests.test_enginepython -m cli.main input.txt -o output.txtpython -m cli.main input.txt -o output.txt --statsOutput:
=== STATS ===
AI-likelihood (pre): 0.847
AI-likelihood (post): 0.312
Reduction: 0.535
Sentences processed: 12
Validation passed: True
Low β Minimal changes, stays close to original:
python -m cli.main input.txt --aggression lowMedium β Balanced, default. Best for most use cases:
python -m cli.main input.txt --aggression medium --statsHigh β Maximum disruption. More voice shift but stronger watermark breaking:
python -m cli.main input.txt --aggression high --diffSame seed = same result:
python -m cli.main input.txt -s 42 -o clean.txtpython -m cli.main input.txt --json > report.jsonContains: original, perturbed, pre/post detection scores, validation results, seed.
Preview without writing:
python -m cli.main input.txt --dry-run --diffcat draft.txt | python -m cli.main --aggression high > clean.txtpython gui/app.py- Paste text into the left panel or click Open File
- Select aggression level and threshold
- Optionally set a seed for reproducibility
- Click Process Text
- View cleaned output in the right panel
- Check stats bar for AI-likelihood reduction
- Click Save Output to write to file
| Metric | What it measures | AI typical | Human typical |
|---|---|---|---|
| Uniformity | Sentence length variance | High (0.8+) | Low (0.3-0.6) |
| Transition Pattern | Formal connector overuse | High (0.7+) | Low (0.1-0.3) |
| Vocabulary Richness (TTR) | Type-Token Ratio | Low (0.2-0.4) | High (0.5-0.8) |
| Hedge Density | Modal/qualifier frequency | High (0.5+) | Low (0.1-0.2) |
| Formality Index | Corporate buzzword density | High (0.6+) | Low (0.0-0.2) |
Composite = weighted blend of all five. Target: < 0.35 for clean passage through detectors.
Uniformity Measures sentence length variance. AI tends to produce uniform-length sentences.
- High (0.8+) β Likely AI
- Low (0.3-0.6) β Likely human
Transition Pattern Counts formal connectors (furthermore, moreover, consequently...). AI overuses these.
- High (0.7+) β Likely AI
- Low (0.1-0.3) β Likely human
Vocabulary Richness (TTR) Type-Token Ratio. AI has lower lexical diversity.
- Low (0.2-0.4) β Likely AI
- High (0.5-0.8) β Likely human
Hedge Density Frequency of modal/qualifier words (may, might, potentially, arguably...).
- High (0.5+) β Likely AI
- Low (0.1-0.2) β Likely human
Formality Index Density of corporate buzzwords (leverage, utilize, robust, holistic...).
- High (0.6+) β Likely AI
- Low (0.0-0.2) β Likely human
| Level | What it does | Use when... |
|---|---|---|
low |
Subtle synonym swaps, minimal restructuring | You need the text to stay very close to original |
medium |
Balanced disruption: syntax + lexicon + light idiosyncrasy | Default. Breaks Claude/ChatGPT signatures reliably |
high |
Heavy: fragments, comma splices, interjections, register mixing | Maximum watermark breaking; more voice shift |
Controls how strictly meaning is preserved. Default: 0.82.
| Threshold | Behavior |
|---|---|
| 0.90 | Very conservative, minimal changes |
| 0.82 | Balanced (default) |
| 0.70 | Permissive, more aggressive perturbation |
| 0.60 | High risk of meaning drift |
python -m cli.main input.txt -t 0.75 --statsAdd your own synonym mappings in data/synonyms.json:
{
"your_word": ["human_alt_1", "human_alt_2", "human_alt_3"]
}Add human tics in data/idiosyncrasies.json:
{
"asides": ["(your aside here)"],
"fragments": ["Your fragment."],
"interjections": ["Your interjection, "]
}βββββββββββββββββββ ββββββββββββββββ βββββββββββββββββββ
β Input Text ββββββΆβ Parser ββββββΆβ Sentence List β
βββββββββββββββββββ ββββββββββββββββ βββββββββββββββββββ
β
βΌ
βββββββββββββββββββ ββββββββββββββββ βββββββββββββββββββ
β Reconstruct βββββββ Validator βββββββ Perturbation β
β (paragraphs) β β (BERT) β β Engine β
βββββββββββββββββββ ββββββββββββββββ βββββββββββββββββββ
β
ββββββββ΄βββββββ
βΌ βΌ
βββββββββββ ββββββββββββ
βSyntacticβ β Lexical β
βββββββββββ ββββββββββββ
βββββββββββ ββββββββββββ
βIdiosync.β β Smoothingβ
βββββββββββ ββββββββββββ
- Parse (
parser.py) β spaCy segments sentences, POS tags, dependency trees - Detect (
detector.py) β Scores 5 statistical markers for AI-likelihood - Perturb (
perturbation/) β Four disruption modules applied sequentially:- Syntactic β Clause reordering, fragmentation, inversion
- Lexical β Synonym substitution with connotation awareness
- Idiosyncrasy β Human tics: asides, fragments, comma splices
- Smoothing β Cross-sentence n-gram disruption, transition breaking
- Validate (
validator.py) β Sentence-BERT cosine similarity gate (default β₯0.82) - Reconstruct β Paragraph structure preserved, output delivered
rehuman/
βββ src/
β βββ engine.py # Pipeline orchestrator
β βββ parser.py # spaCy text parsing
β βββ detector.py # AI pattern detection
β βββ validator.py # Semantic similarity (BERT)
β βββ perturbation/
β βββ syntactic.py # Sentence restructuring
β βββ lexical.py # Synonym substitution
β βββ idiosyncrasy.py # Human tics & fragments
β βββ smoothing.py # N-gram & transition breaking
βββ cli/
β βββ main.py # Click CLI
βββ gui/
β βββ app.py # tkinter GUI
βββ data/
β βββ synonyms.json # Curated synonym map
β βββ idiosyncrasies.json # Human tics database
β βββ stopwords.txt # Custom stopword list
βββ tests/ # pytest/unittest suite
βββ docs/
β βββ architecture.md # Deep-dive architecture
β βββ usage.md # Extended usage guide
βββ scripts/
β βββ setup_env.sh # Linux/macOS setup
β βββ setup_env.bat # Windows setup
βββ requirements.txt
βββ pyproject.toml
βββ README.md
βββ CONTRIBUTING.md
βββ CHANGELOG.md
# Run all tests
python -m unittest discover tests/
# Run specific module
python -m unittest tests.test_engine
python -m unittest tests.test_perturbationEdit data/synonyms.json:
{
"your_buzzword": ["human_alt_1", "human_alt_2", "human_alt_3"]
}Edit data/idiosyncrasies.json:
{
"asides": ["(your aside here)"],
"fragments": ["Your fragment."],
"interjections": ["Your interjection, "]
}Edit src/detector.py β the analyze() method contains the composite weighting:
composite = (
scores["uniformity"] * 0.25 +
scores["transition_pattern"] * 0.20 +
(1.0 - scores["vocabulary_richness"]) * 0.20 +
scores["hedge_density"] * 0.15 +
scores["formality_index"] * 0.20
)| Error | Fix |
|---|---|
No module named 'spacy' |
pip install -r requirements.txt |
Can't find model 'en_core_web_md' |
python -m spacy download en_core_web_md |
sentence-transformers not installed |
pip install sentence-transformers |
| Output looks too different | Increase threshold: -t 0.90 or decrease aggression: -a low |
| Watermark still detected | Increase aggression: -a high or decrease threshold: -t 0.70. Run twice with different seeds. |
| GUI won't launch | Ensure customtkinter is installed: pip install customtkinter |
| Tests fail on first run | Ensure spaCy model is downloaded: python -m spacy download en_core_web_md |
See CONTRIBUTING.md for guidelines on adding perturbation strategies, detection metrics, and code style.
See CHANGELOG.md for version history.
MIT β do what you want. Build on it. Break things with it. Just don't be boring.
Built with cold coffee and zero patience for invisible control. β