Find the phrases thatread as machine-written.
Counts, lines and columns for known signs of LLM text. Never a verdict.
What began as a weekend repair stand has grown into a full-service shop —em-dash5:267weak but the heart of it hasn't changed.
Nestledpuffery7:143weak at the foot of the Ridgeline trail system, we've had a front-row seat as Pine Hollow has grown into a vibrantvocabulary7:253moderate cycling destination, and we're proud to have played a part in that story.
Ridgeline isn't just a place to buy a bike — it'snegative-parallelism11:11moderate a gathering place for the local riding community.
Sample written by Claude Fable 5.1 on 2026-09-19 for this corpus; prompt in corpus/MANIFEST.json.
What it gives you
A finding, not a feeling.
Every result is a place in your document and the name of the pattern found there. Nothing is averaged into a score.
…Pine Hollow has grown into a vibrant cycling destination…
Weak
Common in careful human writing, so only the density means anything.
Moderate
A recognisable habit. A handful in a short document is a pattern.
Strong
Leftovers from a chat window, not a writing style. One hit is worth reading. It still shows only that the text went through a chat window, not who wrote it.
Rules overlap. “Vibrant” is counted by both vocabulary and puffery, which is why the counts are never summed into one number.
Try it
Paste a draft. See where it reads as machine-written.
This is the linter itself, running in your browser as you type. Your text goes nowhere.
Rates are per 1,000 words. Rules overlap, so no total score.
Click a finding to jump to it. No request leaves this page.
The difference
Same text. Only one of these tells you what to fix.
A detector
Nestled at the foot of the Ridgeline trail system, we've had a front-row seat as Pine Hollow has grown into a vibrant cycling destination, and we're proud to have played a part in that story.
Ridgeline isn't just a place to buy a bike — it's a gathering place for the local riding community.
It does not say which sentence, or why. (The shape of what a detector hands back, not a real run.)
Tells
Nestled at the foot of the Ridgeline trail system, we've had a front-row seat as Pine Hollow has grown into a vibrant cycling destination, and we're proud to have played a part in that story.
Ridgeline isn't just a place to buy a bike — it's a gathering place for the local riding community.
pufferyweakpufferyweakvocabularymoderatenegative-parallelismmoderateem-dashweakA verdict is an accusation. A line number is a place to start editing.
Tested on its own corpus
Only one rule clears the gap.
For each rule: the lowest rate in any machine file minus the highest in any human file. Above zero, every machine file outscored every human one.
vocabularycopula-avoidancenegative-parallelisming-analysissignificance-inflationvague-attributionchallenges-formulainline-header-listsbold-overusetransition-openerspufferyheading-stylerule-of-three*em-dashFindings per 1,000 words. 6 human files, 5 machine files. -16.5 on em-dash: a human file at 18.1, above every machine file. * off by default. Not shown: vague-association, chat-residue, model-artifacts, didactic-disclaimers, which fired on no file.
Observed 2026-09-19 with tells 0.1.0, 14 files. Reproduce: node bin/tells.mjs corpus --date 2026-09-19
The rates below are in-sample. The rules were revised after looking at the first corpus run, and one rule (rule-of-three) was taken out of the default set after a hostile review read this table and a set of eight human passages written for that review. The first run is kept unedited in studies/2026-09-19-corpus/first-run-results.json, and the study README lists every cell that moved, why, and what the demotion was for. No corpus text was changed at any point, and no machine text was edited after the linter first ran on it. The machine texts were also written by an author who had read the rule list. Treat this table as a demonstration of what the rules count, on files they were tuned against. The table runs every rule, including the two that are off by default, because it is the evidence for why they are off.
The machine samples were written by the same model family that built the linter; rates in this table describe these files and are not an accuracy claim about any detector, including this one.
What Tells cannot do.
- Tells cannot determine authorship.
- No single rule is evidence on its own; the guide this draws on says the same.
- Seven detectors flagged an average of 61% of TOEFL essays by non-native English writers as machine-written (Liang et al. 2023); surface features are not origin.
- This report does not make text undetectable and does not try to.
The figure is from Liang et al., GPT detectors are biased against non-native English writers, Patterns, 2023, arXiv:2304.02819.
It gives no probability and no score. It does not rewrite anything. A person can write every pattern here, and a model can write none of them.
Use it
One command, nothing to install.
It works like a code linter: named rules, a line and column for every finding, and a failing exit when you ask for one.
# check a file npx github:CandyFlex/tells draft.md # fail a build on chat leftovers npx github:CandyFlex/tells draft.md --fail-on strong # an annotated page you can read npx github:CandyFlex/tells render draft.md --out report.html
Not on npm yet: npm view tells returned E404 (not in this registry) on 2026-09-19, so this runs it straight from the repository.
- Formats
text,json,md,sarif- In CI
- Exits non-zero once
--fail-onis met - Requires
- Node 20 or newer. No dependencies. MIT.
- Rules
- Every rule, its sources and its false positives: the rules page