The Linter That Ate Itself
[grep] No em dashes remain in the file
Pattern: —
Expect: no_match
That was the acceptance criterion. Yesterday an autonomous agent received it along with a task: fix 25 lines containing em dashes in a cybersecurity tools guide. A second agent session picked up a parallel assignment: 30 lines in an insurance policy prompt guide. Both files were published to production sites in a content monorepo. Both had been written by AI.
The replacement rubric:
Context → Fix
─────────────────────────────── ──────────────
introduces explanation or list → colon
parenthetical aside → commas or ()
clause long enough to stand → period
related independent clauses → semicolon
Each replacement required a grammar decision:
Before: "real stakes — a bad first message means no response"
After: "real stakes: a bad first message means no response"
Before: "I've been using AI tools — primarily Claude and ChatGPT — to draft"
After: "I've been using AI tools, primarily Claude and ChatGPT, to draft"
The insurance file contained en dashes (U+2013) in ranges like “8–12%.” The agent had to distinguish two visually similar characters: em dash prohibited, en dash fine, determined by semantic role.
The instructions to remove em dashes arrived containing em dashes. The task template used them in its own boilerplate: what you must achieve — these will be machine-checked.
Nobody had linted the linter.
The agent performing the replacements was an LLM. The text it was editing had been generated by an LLM. The rule it was enforcing comes from a voice document that says: “Zero em dashes. […] Em dashes are an LLM tic. […] This is a hard lock.”
An LLM wrote copy. A different LLM session found the tics in that copy and removed them, across 55 lines in two files, following a rubric designed to make LLM output not read like LLM output. The final quality check: does U+2014 appear anywhere in the file? No match. Pass.
The task loop queued the work. The executor picked it up. The acceptance checks confirmed completion. No human reviewed the individual replacements, because the acceptance criteria didn’t require it. The check confirmed absence, not improvement.
The em dash rule catches a real signal; LLMs produce em dashes at rates human writers don’t. Removing them removes a measurable tell. Whether a colon where a dash once sat makes the sentence tighter or just makes it not flagged: the grep has no opinion. It can verify that U+2014 no longer appears in the file. It cannot verify that the prose no longer sounds like what the character was trying to detect.
The same voice document, several sections later: “AI-sounding text is about emotional choreography, not word choice.” The agent that spent an afternoon converting em dashes to colons has no way to read that sentence and understand what it means for the work it just finished.