The static-next-cpanel course is eight chapters, and I did not write a word of the prose. Two ultracode Workflows did: 31 agents for chapters one to three, 50 for four to eight. Each chapter passed through the same four phases before it was allowed to exist. Research agents WebFetch-verified every source. One agent read this repo’s real config for ground-truth. A draft agent wrote each chapter. Then three adversarial checkers tore into it: one for facts, one for the build gate, and one whose only job was voice.

That voice checker enforced a house rule. The style budget allows at most three em-dashes per thousand words, because dense em-dash use is one of the ten tells that mark prose as machine-written. The checker read each chapter, counted, and reported. Chapters six and seven came back clean. The agents said the prose was within budget.

It wasn’t.

The recount

After both Workflows returned, I ran a check with nothing clever in it. Open the file, count the character, divide by words:

em_dashes = body.count("—")
density = em_dashes / (word_count / 1000)

Chapter six came back at 6.61 per thousand. Chapter seven was over as well. Both had been passed by an agent whose entire remit was to catch exactly this. Asked to count its own most distinctive tell, the language model undercounted it.

That is the whole finding, and it is not subtle. A model can write to a budget it cannot measure. Counting is arithmetic, and arithmetic is the one thing a next-token predictor has no reliable access to. It approximates. Three lines of Python do not.

Why not just search-and-replace

The obvious fix is to delete every em-dash. It would also have been wrong.

Chapter six teaches the LiteSpeed .htaccess that routes 404s on this site, and it quotes the real file verbatim:

# Custom 404 page — without this Apache (cPanel) serves its own
ErrorDocument 404 /404.html

Chapter seven quotes the actual deploy workflow, including a log line with an em-dash inside it. Those em-dashes are not stylistic. They are the source. A blind replace would have silently corrupted the one thing the whole course is built on: that every code block is faithful to the running system it documents.

So the recount had to know the difference between an em-dash in my prose and an em-dash inside quoted code. The fix restructured only the prose, turning stylistic em-dashes into full stops, colons, and parentheses, and left the code blocks untouched. Final prose density landed at 2.6 and 2.0 per thousand. The quoted .htaccess comment still reads exactly as it does on the server.

The general shape

The lesson generalises past punctuation. When an AI system produces output with a measurable property, verify that property with a measurement, not with another AI. The voice checker earned its place on judgement calls: does this read like a person, is the metaphor laboured, is the opening flat. It was the wrong tool for a count. Counting is deterministic, so the check should be deterministic too.

The course now runs a post-workflow gate that recounts every tell against the budget the STYLE-GUIDE lists. The agents still draft and self-review, because most of what they catch is real. But the number that decides whether a chapter ships is produced by Python, and Python has no preference for elegant punctuation.

Eight chapters are live. Two of them nearly shipped prose that four specialist agents had signed off on, and a three-line loop caught it after the fact. I keep the agents. I trust the recount.

All writing