Michael Lynn

September 7, 2026 · Michael Lynn

Your Client Can Tell

I built a tool that marks every phrase in a draft that gives it away as machine-written, rewrites around them without moving a date or a caveat you wrote, and can learn your voice from a ten-minute spoken interview.

Live demo

Your Client Can Tell

There's a sentence I keep finding in my own drafts.
"I wanted to reach out and provide a comprehensive update on where the integration work stands."
Nothing in it is wrong. The grammar is fine, the update is real, and the person waiting on it gets what they asked for. It still tells them something I didn't mean to say. They read that opener and they file me under people who send AI email, and they do it without deciding to, the way you notice a bad wig before you notice the person wearing it.
That's the part that bothered me. The writing isn't bad. It's competent and clear and it gives itself away anyway, because a handful of habits show up in every draft a model hands you.
So I built rewr.it. It does two things. It shows you every phrase in your draft that gives it away, and then it writes around them without moving a date, a number, or a caveat you wrote.
Two panels side by side. On the left, a status email in monospace with phrases struck through in red and a pill reading 38 tells. On the right, the same email rewritten in a serif reading face with a pill reading 0 tells.
Left is what the checker gives you. Right is what the rewriter gives you. Same date, same condition attached to it.

The marks are phrases, not a verdict

I want to be careful about what this is, because the category it sits in is full of tools that promise something they can't do.
It is not a detector. It does not tell you who wrote something. There's a reading on the check page that says "100% likely machine-written" and even that is a mapping rather than a measurement. It's the tell score normalized to density and pushed through a curve that saturates. It answers how machine-shaped a piece of prose reads. It does not answer who typed it, and anything claiming the second one is guessing.
What it actually does is name phrases. Every mark you see is a string the checker found in the words in front of it.
What it looks forHow many
Model vocabulary, in 7 categories97 terms
Sentence shapes, mostly antithesis8
Stock openers12
Those numbers come out of the policy at render time. They are not typed into the page, and there's a reason for that. The first version of the landing page claimed "120+ terms" when the list held 97. Nobody would ever have checked it, and the page would have gone on repeating the wrong number for as long as the page existed. So now the marketing copy counts the software instead of describing it. If somebody adds a term tomorrow the page says 98 without anyone editing it.
The whole check runs in your browser. Nothing is uploaded, there's no account, and there's no limit on it. That wasn't generosity so much as the only version of the claim I could actually stand behind. If I'm going to tell somebody their draft never leaves the tab, the cheapest way to be telling the truth is to build it so it can't.
The rewr.it check page with a pasted draft, a large reading of 100 percent likely machine-written, and a count of 38 machine tells.

The rewrite is the hard half

Marking bad phrases is a word list. Anybody can build that in an afternoon, and I mostly did.
Rewriting is where it gets real, and it's where every tool I tried fell down. They paraphrase. Paraphrase drifts. A date moves by a day. A hedge disappears and a maybe turns into a did. You send it, your client reads a commitment you never made, and you find out six weeks later when they hold you to it.
So the rewrite is fenced in. Every claim in the output has to trace back to a specific sentence in your draft, and a sentence too tangled to move safely stays exactly as you wrote it and gets flagged instead. Then the rewrite is checked against the draft before you ever see it.

What happens to a draft


flowchart LR
  Draft([Your draft]) --> Check[Check<br/>in your browser]
  Check --> Marks[Every tell marked<br/>in place]
  Marks --> Rewrite[Rewrite]
  Rewrite --> Audit{Fact audit}
  Audit -->|nothing moved| Copy([Copy it])
  Audit -->|something moved| Flag[Flagged, and shown<br/>the row that changed]

  classDef local fill:#2f5d50,stroke:#24473d,color:white;
  classDef warn fill:#a33,stroke:#822,color:white;
  class Check,Marks local;
  class Flag warn;
The checker runs locally. The audit gates the copy button. A rewrite that moved a fact does not get handed to you quietly.
The audit pulls numbers, dates, names, quotes and links out of both versions and compares them as multisets. Not as sets. That distinction cost me an afternoon and it's my favorite thing in the codebase.
Here's why it matters. In the demo email, August 28 gets counted twice, once as a date and once as the bare number 28. If the audit compared sets, a rewrite that helpfully repeated the date for emphasis would look identical to one that didn't. As multisets, repeating it reports an added fact and the panel stops reading zero. It also means a rewrite that quietly drops the month and leaves the 28 trips the check, which is the failure I actually care about, because that's the one nobody proofreads for.

Facts in, facts out


flowchart TB
  subgraph Before[In your draft]
    A1["August 28 (date)"]
    A2["28 (number)"]
    A3["vendor API access"]
  end
  subgraph After[In the rewrite]
    B1["August 28 (date)"]
    B2["28 (number)"]
    B3["vendor API access"]
  end
  Before --> Compare{Compare as multisets}
  After --> Compare
  Compare -->|counts match| Zero[0 warnings]
  Compare -->|count moved| One[Warning, with the row]

  classDef good fill:#2f5d50,stroke:#24473d,color:white;
  classDef bad fill:#a33,stroke:#822,color:white;
  class Zero good;
  class One bad;
Counted, not just present. Repeating a date is a change, and so is dropping half of one.
Where the writing is going changes the shape it comes back in. There are nine registers to pick from, because a Slack message is not a skip-level. And you can point it at yourself instead of at a register, which is the part of this I think is actually worth ten minutes of your time. More on that below.
The rewr.it rewrite surface, showing the draft pane on the left and the result pane on the right.

You can teach it your voice, and it is worth the ten minutes

Everything above works on a draft you paste, with no account and no setup. That version shapes your writing toward one considered voice, which is better than the model's default and is still not you.
The other half of the product fixes that. There's an interview at rewr.it/voice/interview and you can talk your way through it. Eight questions, about ninety seconds each. Answer six and you have enough. Answer all eight and you have plenty. You can type instead if you'd rather, and you can walk the whole thing without an account, because signing in is only what lets you save at the end.
The rewr.it voice interview consent screen, headed Build your voice by talking, listing what happens to the recording and the text before anything is saved.
The recording goes to a transcription service and comes back as text, and the audio is thrown away the moment it does. Nobody stores it, us included. The text is what's kept, as writing samples behind your profile, for 365 days from the last time you actually use it. You read every transcript before any of it is saved, and you can edit them, which is not there for polish. A transcription error that survives into your profile is a measurement of the transcriber rather than of you.
Then a model reads the whole set once and works out how you argue and which of your sentences are most characteristic. After that, every rewrite you run against that profile is shaped by it.

What it actually measures

More than I said when I first wrote this post, and worth being precise about because "learns your voice" is a claim that usually means nothing.
It measures how long your sentences run and how much that varies, how often you drop a fragment, which of nine ways you tend to open a sentence, how much you subordinate versus just adding another clause with "and", how often you contract, how much Latinate vocabulary you reach for, your hedges and your boosters, and your punctuation down to how often you use a semicolon. Then it picks a few of your own sentences to show the model as demonstrations.
What it does not do is build a dictionary of your words. The word-frequency half runs against a fixed list of 150 function words, the structural ones, so the profile knows you say "so" where somebody else says "therefore" and knows nothing about the nouns you like. Out of the box it sounds like you in shape and like one considered voice in word choice.
One detail I like more than I should. A spoken sample carries no punctuation at all, because a transcriber decides where the commas go. So the profile averages each feature only over the samples that actually reported it. Counting a transcript's silence as zero em dashes would teach it you never use one, which is a fact about a decoder setting and not about you.

Effort buys fidelity, and here is the exchange rate

This is the part I'd underline. The measurements get better the more you give them, and the numbers are not vague.

What more evidence buys you


flowchart LR
  A["Under 300 words<br/>not enough to measure"] --> B["300 words<br/>a profile exists"]
  B --> C["1,500 words<br/>the figures stop moving"]
  C --> D["12,000 words<br/>full evidence target"]

  classDef thin fill:#a33,stroke:#822,color:white;
  classDef ok fill:#8a7b3d,stroke:#6d6130,color:white;
  classDef good fill:#2f5d50,stroke:#24473d,color:white;
  class A thin;
  class B,C ok;
  class D good;
The thresholds are real constants in the codebase, not a marketing ladder. Below 300 words it declines to measure rather than guessing.
Under 300 words it won't measure you at all, which is a refusal rather than a guess. At 300 you have a profile. Around 1,500 the figures settle, and the interview tells you so on the way out if you stopped short. The full evidence target is 12,000 words, which sounds like a lot until you notice you can top the same profile up later from anything you've already written.
And that's the thing I'd want somebody to take away. The model is still the one organizing the sentences. What the profile changes is how much of the organizing is done to your measurements instead of to a default. The thoughts were always yours. Ten minutes of talking is what keeps them recognizable as yours after something else has arranged them.

Watch it run

This is the check page taking that same status email and reading it. No cuts and no captions. Everything on screen is computed by the same functions the app calls, so the recording can't show you a result the software wouldn't produce.
That clip is in the repo because re-cutting it costs one command now. It didn't used to. The first recording sat on the landing page until the headline changed underneath it, and then it sat in a folder for weeks with the old headline burned into its first frame, because re-recording meant somebody sitting down with a screen recorder for an afternoon. Nobody pays that twice. So I wrote a capture script that drives the real app in a real browser and takes real pictures of it, and the page has had a current video on it ever since.

Where it lives

The web app is the main thing, but the drafts I most want to fix are the ones I'm already writing somewhere else, so it also ships as a Chrome extension that works inside Gmail and LinkedIn, an MCP server so Claude can check its own output before handing it to me, and a desktop build.
The MCP server is the one I use most, and it's free and needs no account for the checking tools. My coding agent drafts something, checks itself, and fixes the tells before I ever read the draft. That loop is genuinely useful in a way I didn't predict when I built it.

Tech Stack

Next.js
React
MongoDB Atlas
Claude API
Stripe
Auth.js
Chrome Extension (MV3)
MCP
Tauri

What it won't do

It won't beat a detector, and I'm not going to claim it does. That's an arms race with a moving target on the other end, and a product that promises it is lying to you on a schedule.
It also won't write your vocabulary, which is the limit I most often have to explain. A profile measures the structure of how you write and shows the model a few of your own sentences, and the word-frequency part of it runs against a fixed list of function words. So it knows your scaffolding and not your nouns. Out of the box it sounds like you in shape and like one considered voice in word choice. I say that on the page where profiles come up too, because it's the thing people assume and I'd rather disappoint them before they've paid than after.
And it's not going to make bad writing good. All it does is take the accent off. The judgment still has to be yours, which is the part you were being paid for anyway.
Checking is free, unlimited, and never leaves your browser. It's at rewr.it if you want to paste something in and see what comes back.