What comes out
Every tell is a specific Unicode code point, so the rules are exact rather than clever.
Invisible and zero-width: zero-width space (U+200B), joiner and non-joiner (U+200D, U+200C), word joiner (U+2060), soft hyphen (U+00AD), byte-order mark (U+FEFF), variation selectors (U+FE00 to U+FE0F), bidirectional marks (U+200E, U+200F), and the narrow no-break space (U+202F) behind the 2025 watermark scare.
Punctuation: em dash to a hyphen, comma, space or nothing. En dash to a hyphen. Curly quotes and apostrophes to straight ASCII. The single-character ellipsis to three periods.
Spacing and lookalikes: no-break spaces become normal ones, doubled spaces collapse, and NFKC normalization turns a Cyrillic "а" back into the Latin letter it imitates. NFKC alone ignores dashes, curly quotes and emoji, so each of those needs its own rule.
Originality.AI publishes a reference of 87 such characters with code points and replacements.
Why they break things
The invisible ones are the expensive ones. Python raises a SyntaxError on a curly quote. JSON rejects anything but straight ASCII double quotes. Bidirectional controls power the Trojan Source attack (CVE-2021-42574), where code reads one way to a reviewer and compiles another way. All of them survive copy-paste between editors and operating systems.
The em dash has a duller explanation than a watermark. Training corpora lean on digitized print books, and that prose uses far more dashes than we do. One study measured GPT-4.1 at about 10.6 em dashes per 1,000 words unprompted, and 3.9 when told to stop.
On a Mac the same cleanup runs on ⌘V in any app, offline, through Klipto's Anti-LLM transform.