Voiceprint: Teaching a Language Model to Write Like Jack
I reconsidered my no-AI-writing rule and built Voiceprint, a system that authors first drafts in my voice.

My last post before this stretch went up on March 17th. The next one went up on July 8th. 113 days, zero posts, on a blog whose entire beat is the fastest-moving story in technology. It wasn’t for lack of material: the knowledge refinery from that July 8 post ingested the AI firehose all spring, and my list of takes grew every week. The bottleneck was me. I’m a slow writer — perfectionist-slow — and the gap between how fast this field moves and how fast I publish had gone from annoying to disqualifying.
I had a rule that made the math worse: AI never writes for me. Not a post, not a paragraph, not a sentence. Every word published under my name was mine, typed by me, and the rule was there to protect credibility. I still think the instinct behind it was sound. But credibility is just my secondary motivation for writing. The primary one is learning: writing is how I pressure-test what I think I know, where half-formed takes either become positions or fall apart. The real cost of nearly four months of silence wasn’t my reputation — it was the learning that never happened. If keeping the rule means I never write? Not acceptable.
The “Talk Like a Pirate” Precedent
I’d already run this experiment once, in a lower-stakes form, with someone else’s voice. For years I followed the standard LinkedIn advice: emojis, hashtags, hook them in the first line. Then one day I looked at my drafts and thought: why am I writing clickbait? I went looking for someone on LinkedIn whose posts are both successful and good, and landed on Ethan Mollick. No emojis, no hashtags, plainspoken writing about things he actually knows. So I built a Claude Skill from four of his posts, with notes on what makes each one work, and started drafting my LinkedIn posts in Mollick’s voice. The post describing that experiment, featuring Mollick dressed up as a pirate (because AI is good for more than “talk like a pirate”), pulled 57,019 impressions and 108 reactions. That was in December. Every LinkedIn post I’ve published since has been drafted the same way.

So a basic level of in-the-voice-of clearly works. But Mollick’s voice cost me an afternoon and four sample posts, and there’s an asymmetry hiding in that: I can’t read a Mollick draft and feel that it’s off. I can feel a Jack draft instantly. Teaching a model to write in my own voice means satisfying the one reader who can’t be fooled.
What Does “In My Voice” Even Mean?
In late June I took the project to Opus 4.8 — Fable 5, the model I’d have picked, had been pulled from the market by the US government three days after launch — and we spent days on what turned out to be the hard part: definitions. “In my voice” splits into layers the moment you poke at it. There’s a conscious layer: word choice, sentence rhythm, the moves I actually make, the slop I’d never emit (“load-bearing,” “leverage,” “game-changer”). And there’s an unconscious layer: the function-word fingerprint, the distribution of “the” and “of” and “but” that stylometrists use to attribute authorship, which you can’t fake deliberately because you don’t know you’re doing it.
That gave us two possible bars, and we made the call explicitly. Must-have: reader-perceived voice. A human reads the post, it feels like me, it doesn’t smell like AI. Try-hard: forensic indistinguishability, prose that matches my corpus under statistical analysis. Nice if it happens — not the goal.
The same discussions dissolved my old rule, and I’ll give Opus credit for the framing. My credibility was never going to live or die in the words; it lives in the substance: the ideas, the specifics, the POV, being early and right. The “no AI” rule was guarding the wrong layer, protecting the words when the thing that needs protecting is the thinking. The replacement rule, which now sits at the top of the whole system:
100% Jack’s thinking and POV. AI renders in my voice with high fidelity, but Jack is editor-in-chief, Ben Bradlee style, interrogating the work, demanding the sourcing, killing what isn’t nailed down, owning what publishes.
That’s a rule I can defend in public. It’s also a rule you can build software against.
A Home and a Name: Voiceprint
The build itself was fast — the session log shows 35 minutes between the eval spec landing on disk and the harness running against my corpus. What emerged wasn’t a blog feature; it was a system: two skills, two post-pass scripts, the eval harness, a corpus. The questions that took longer were the ones software doesn’t answer. The whole thing spent its first day in a loose folder called voice-eval: not a git repo, no remote, existing on exactly one machine. Capturing it forced two decisions.
Where to put it: not in the blog. The blog is one consumer of this system, not its home — the same voice machinery might be used anywhere I write. And the corpus is research data, not content: my failed drafts, plus scraped copies of the four bloggers the classifiers train against, third-party text I can store for research but not republish in a repo that was public at the time (it’s since gone private). So it became its own repo, private from birth, with the corpus deliberately committed: that blogger snapshot is frozen, which is what keeps today’s eval numbers reproducible after the source feeds move on.
Then the name, which took an actual discussion. voice-eval was accurate and forgettable; the other candidate tied it to the skill it measures. Opus pitched voiceprint — a stylometric fingerprint of a voice is exactly what the thing produces — and I took it on the spot. The repo got the name first. The whole apparatus wears it now.
Voiceprint v1
Version 1 had three parts.
First, a voice skill, voice-dna: distilled from 6 posts I picked as canonically me, later deepened to 13 writing samples mined from my corpus by statistical closeness to my own stylistic centroid. Positive traits to write toward, register guidance, real samples with the punctuation intact, a short list of banned tells.
Second, a measurement harness — because “sounds like me” deserved better than vibes. Voiceprint scores generated prose four ways: rate checks (em dashes and slop per 1,000 words); Burrows’s Delta (function-word distance to my centroid, with a leave-one-out null so “close” actually means something); classifiers trained to separate me from four topic-matched bloggers (Simon Willison, swyx, Karpathy, The Pragmatic Engineer), which they do at an AUC around 0.9; and an LLM judge panel of Opus and GPT-5.5 scoring drafts against a rubric.
Third, two deterministic post-passes, which exist because the eval taught us a useful lesson: a rule in a prompt does not reliably bind. My natural em-dash rate is low, about 5 per 1,000 words; the AI default is double that (the skill-off control ran 11). But when the skill said “match Jack’s rate,” fresh drafts still came out with zero em dashes. Meanwhile “full stop,” an AI tell banned by name in the skill, showed up in a draft generated with that exact ban in context. So now a content-preserving script injects em dashes at my rate after drafting (that one change moved the classifier’s P(Jack) from 0.53 to 0.72), and a mechanical linter scans the finished text for tells. If it must hold, don’t ask the model. Post-process.
Both passes ran on the post you’re reading:
$ em_dash_pass.py voiceprint-draft.txt
chunks: 4/4 applied cleanly
em dashes: 0 -> 10 (4.9/1k)
words: 2038 -> 2038 (content preserved: True)
$ tell_lint.py index.mdx
=== index.mdx — 16 tell(s) flagged ===
L45 [claude tic] "load-bearing"
…the slop I'd never emit ("load-bearing," "leverage," "game-changer")…
Twelve of the 16 flags are this post quoting the tells it bans; the other four are the word “harness” naming actual harnesses. The linter flags; judging context is my job.
One more finding worth recording, and it’s about the two layers of voice from earlier. The conscious layer — word choice, rhythm, the banned slop — the skill nailed almost immediately. The unconscious layer barely budged: that’s the fingerprint hiding in how often I use “the” and “of” and “but,” the one you can’t fake because you don’t know you’re doing it. The eval scores each draft on how far that fingerprint sits from my typical prose, calibrated against how much my own posts vary; the skill’s drafts landed at the outer edge of that range, no closer to me than my single most atypical post, no matter how we tuned the prompts. Prompts alone can only get my voice so close. Getting closer means changing the model itself — fine-tuning it on my writing. Since the must-have bar — a human reads it and it feels like me — doesn’t require that, I parked it.
Failure
First production run: draft one of Where Have I Been? Hermes Agenting, Mostly. The judge panel scored the draft 5 out of 5, higher than it scored my own posts.
It stank.
I read the intro and rewrote it from scratch. The draft cast me as a bystander to my own system: “it built me a knowledge base while I made breakfast… I mostly watch.” It described the system I designed, feed, and extend every day as “a Rube Goldberg contraption,” “vibe-coded,” “not particularly impressive.” Every box on the checklist was ticked — and the person on the page was not me. A caricature had outscored the original on the me-rubric. Goodhart’s law, working as designed: the rubric measured conscious markers; what I perceive when I read my own alleged voice is stance.
I marked it a failed experiment and shelved it, figuring I’d come back when the models got better. Much later, maybe next year.
Much later turned out to be about a week.
The Return of Fable
Then the government cleared Fable 5 to relaunch, and on July 1 it was back. I handed it the failed draft, my rewrites of it, and the entire system, and asked one question: what went wrong?
The diagnosis came back in three parts.
Contaminated inputs. The post’s brief, assembled by an agent partly from a transcript of me on a call with a well-known AI co-founder and developer, had passed my spoken self-deprecation along as voice direction, and the drafter rendered it faithfully. It wasn’t false modesty when I called my work a “Rube Goldberg contraption” in a conversation about his excellent commercial product. What was missing was the context: my work served one user experimentally; his work served a million commercially. The rig is actually very solid for “one user experimental,” but the system had no understanding of this context, so the written output was offensively wrong.
No stance layer. The skill encoded texture (rhythm, slop bans, punctuation rates) and nothing about who I am on the page. Every one of my rewrites, laid side by side with the drafts, was a stance correction, not a texture correction.
No feedback loop. My edits of the failed draft were the highest-signal voice data the project had ever produced — and nothing was harvesting them.
Three fixes, all shipped as changes to the skills, all authored by Fable. (Fable turns out to be very good at skill authoring.) The drafting workflow got two hard firewalls: briefs are substance-only, with any voice direction found in a brief declared void; and transcripts are quarantined to facts, quotes, and story beats, never stance, never my descriptions of my own work. The voice skill got a stance section, above everything else: operator, not spectator; when a caveat is owed, disclose the limit, vouch for what I can stand behind, land a flat verdict, no modesty theater; self-deprecation points at Jack-the-character, never at the work; pride shows up as spec density, not adjectives; build long, land short. And the system got a contrast ledger: every AI-draft-versus-Jack-rewrite pair, captured verbatim with the lesson named, harvested after every post. When a rule and the ledger disagree, the ledger wins. It held eight entries when Fable drafted this post; harvesting my edits of this post pushed it to 20. It’s the reason draft N+1 keeps beating draft N.
One ledger entry, format and all: the AI draft, my rewrite, the lesson named. This one is entry #9, harvested from my edits of this post.
Success in Four Parts
First attempt with the reworked system: the Hermes post, again. This time the first draft was salvageable. I edited it hard, but it was collaboration, not a teardown, and it published on July 8. The diff went into the ledger: two new entries.
Second attempt, the next day: the initial draft of Captain America, Q, and the Joker: Samuel Colvin on Coding Agents. A decent first draft, collaboratively improved, published July 9. One correction worth its ledger entry: the draft had my refinery pulling the best quotes out of the episode. No. I pick the moments — the rig processes them. Agency attribution runs both ways: I don’t get cast as the bystander, and the machine doesn’t get credit for my taste.
The third attempt is the post you’re reading, and it was the most challenging of the four by a comfortable margin: the system writing about itself, stance about stance, every sentence an opportunity to fail in precisely the ways the post describes. Fable drafted it with the skills Fable rebuilt; it ran through the same em-dash injection and tell-linting as everything else; the thinking, the history, and every number in it are mine. This draft needed a lot of work, but that work was more about fixing my half-formed takes than about the agent’s execution. This first draft gave me an immediate “wow, this is already pretty good …” feeling, definitely a step beyond the quality of the Colvin draft.
I edited it the way I edited the other two, and the diff gets harvested into the ledger, same as always.
A brief fourth post started the day after this post but published two days before it, drafted from an idea captured during a 14-mile ride: You Can’t Know Claude Code Until You Try Another Coding Harness.
A Note on Fable as a Writing Partner
In nine days Fable diagnosed the v1 failure from the diffs, rewrote the skills, drafted two published posts plus this one, and, when the Colvin post needed cover art at this blog’s 44:28 aspect ratio, knocked out a throwaway Pillow script to blur-fill the image to spec. Writing, diagnosis, skill authoring, pixel-pushing — same model, all of it good.
Before long, Anthropic warns us, Fable will no longer be included in its subscription plans such as the Max plan I’m on. We’ll all be forced to pay rack rate for every token if we want to keep using it. Fable is flat-out expensive — I unintentionally spent $107.95 in overage charges in 13 minutes last week, partly Fable’s own cost, partly because the model spun up a research workflow that fanned out 105 subagents. But Fable has proven so utterly effective as a writing partner that I’m seriously considering paying anyway.
Plans for Voiceprint v3
I had a homegrown to-do list for Voiceprint v3. But then I realized I had never run a research pass over the literature to see what work might already have been done, what parts of the problem were already solved. I discovered a whole field here: authorship verification, personal style embeddings, learning from user edits. With actual academic research as a foundation, I’ve got a much stronger v3 plan now:
- A scorecard is better than just a judge. A 2026 study tested three ways of scoring “does this sound like the author?” and they barely agreed: each catches something the others miss. Worse, the lone AI judge rated an imitation above the real author — my 5-out-of-5 caricature, reproduced in a lab. So I propose in v3 to score drafts against a scorecard of independent measures (LUAR, StyleDistance), each vetted on one bar: it must rank my rewrite above the draft I rejected.
- Learn from my edits. If we have a history of the author fixing the AI’s drafts (we do: the ledger), then published methods can put it to work. CIPHER turns each fix into a lesson and feeds the relevant lessons back at draft time; it cut users’ editing 31% and 73% in its two tests. DITTO goes further, training a small local model on fewer than 10 before-and-after pairs. The ledger already holds 20. We qualify.
- Fine-tune a local model on my own posts. This is the fine-tuning I parked in v1; the research un-parks it. The plan: train a small model on my Mac, on my 115 published posts, so it renders prose the way I do (one writer proved the recipe with 91 posts). It picks up how I write, not what I know — knowledge stays the refinery’s job, same split as today.
- Watch my voice for drift. The real risk of AI drafting isn’t one bad post — it’s my voice slowly eroding into the machine’s, too gradually to feel from inside. One study found the residue survives editing: edited AI drafts stay measurably closer to the machine than to the author’s own prose. So the scorecard gets a standing job: score every published post against my pre-AI writing. And sound the alarm if I’m drifting away from my own voice.
Here’s an architecture diagram that shows the current v2 rig as solid, with dashed representing the proposed v3 build list:
The v3 architecture: solid is running today, dashed is the build list.
Zero posts in 113 days. Then four posts in five days, and my AI rule refined but intact — just aimed at the right layer now. The thinking is 100% mine. So is the editing: every line interrogated, nothing published that wasn’t nailed down. The voice? You just read 2,900 words of it. You tell me.





