Snifftest
A prose linter that sniffs out AI writing tells. Zero dependencies, countable rules plus one judgment model.
Install
/plugin marketplace add DanRWilloughby/snifftestInstall command taken from the project's README or registry entry. Always review code before running it.
README excerpt
Read full README on GitHub →Sniff Test
Does the draft pass the sniff test?
Sniff Test reads Markdown and plain text and checks it against your house rules. It prints one line per flag with the file, the line, the rule that tripped and how sure it is.
There are two kinds of rule. Countable rules are regular expressions. Long dashes, a paragraph with three colons, a banned word, every sentence the same length. They run on your machine, cost nothing and send nothing anywhere. Judgment rules need something read rather than counted. A closing sentence that only restates the paragraph, a claim hedged three times, a line that talks the reader out of the offer. For those it sends one paragraph at a time to a small hosted judgment model and gets back one probability per rule. It only does that after you have said yes.
Two things it is not. There is no general model in the loop; the judgment model returns one probability per question and nothing else. And it will not rewrite your text. A flag is a sentence for you to fix.
npm install --global snifftest
snifftest check --dry-run draft.md
That runs the countable rules and nothing leaves your machine. To run the
judgment rules too, put a TypeSafe key in TYPESAFE_API_KEY and drop
--dry-run. The first time, it prints exactly what it is about to send and
where, and waits for your answer.
It exits 0 when nothing tripped, 1 when at least one rule did, 2 when the tool could not do its job, and 3 when the judgment rules needed a yes and did not get one.
The nose is the mascot. It is one hand-drawn SVG with six expressions, in
assets/nose/, and snifftest serve opens a local page where you type and the
nose reacts.
Reading a flag
draft.md:14 dash_present 1.00 A long dash. Give the sentence a full stop instead.
draft.md:31 restating_closer 0.84 The last sentence says the paragraph again. End one sentence earlier.
The number is how sure the checker is, between 0 and 1, and it says nothing
about how bad the problem is. A countable rule always scores 1.00. A judgment
rule counts as a flag at or above the threshold, which is 0.7 unless the
ruleset or --threshold says otherwise. A reading between 0.4 and 0.6 is
reported as no judgment and never becomes a flag or a pass. That band exists
because the judgment model answers about 0.5 on text it cannot read, and a
flat middle number is the one failure that looks like a clean draft.
--format json prints the same flags for a machine, with every reading
including the ones under the threshold. snifftest rules prints the ruleset in
force and which file each rule came from, which is the quickest answer to "why
did that flag".
The rules
The default ruleset ships in rules/default.yaml. Fifteen rules, and the file
itself is the documentation. Ten apply to most prose and five are conventions
of copy meant to sell.
Similar plugs
Makes your AI agent think like the laziest senior dev in the room. The best code is the code you never wrote.
Turn any codebase, with its docs, SQL schemas, configs, and PDFs, into a queryable knowledge graph. A /graphify skill for Claude Code, Cursor, Codex, and Gemini CLI: local…
Why use many token when few token do trick. Viral skill + proxy for coding agents that cuts 65% of tokens by talking like a caveman.
Production-grade engineering skills for AI coding agents.
The 1st Collaborative AI Design Agent Workspace. Local-first and open source. Create prototypes, websites, apps, dashboards, presentations, images, and videos with your team…