pilcrow.ink·v0.6·MIT

Pilcrow

A prose linter for AI tells and writing-quality issues. 49 deterministic rules. 19 LLM-judged ones. The engine never edits your text.

Read straight through. The whole thing fits in five minutes, and the spine on the left will keep your place.

Chapter I

Preface

One AI tell survives every model jump: writers who all sound like the same writer. Pilcrow is a small toolkit for noticing it before you ship.

The deterministic engine catches 49 lexical and structural patterns. The phrasebank handles outright AI vocabulary (delve into, rich tapestry). The antithesis cadence catches the not just X, but Y rhythm. The copula dodge spots serves as and stands as standing in for plain is. The rest of the family covers em-dash density, throat-clearing openers, hero-tagline cadence, AI fossils like chat sign-offs and citation tokens, and the bullet-bold-lead markdown signature.

The LLM catalog adds 19 higher-level patterns regex can’t catch — buried lede, mixed metaphor, voice drift, missing stakes, marketing-template cadence, stakes inflation, listicle-in-prose — packaged as a single critique prompt you pipe into any model.

Credit to Paul Bakaus’s impeccable, which does the same job for frontend design. Same idea, applied to prose.

Detection-only. The engine never edits your text. Findings carry line, column, excerpt, and an optional suggestion; the LLM (or you) decides what to change.

Chapter II

Install

Two paths. Pick one.

Global (recommended)

npm install -g pilcrow-ink

The package on npm is pilcrow-ink; the binary it installs is pilcrow.

Per-project, no install

npx pilcrow-ink audit drafts/
npx pilcrow-ink skills install

Works from any project without touching node_modules.

Add the skill to your AI harness

Once iw is available, drop the skill into the right place for whichever harness you use:

cd your-project
pilcrow skills install              # auto-detects .claude / .cursor / .gemini / .agents / etc.
pilcrow skills install --all        # install into every supported provider
pilcrow skills update               # re-sync after `npm update -g pilcrow-ink`
pilcrow skills check                # show installed versions vs the package

Supported harnesses: Claude Code, Cursor, Gemini CLI, Codex / Agents, OpenCode, Kiro, Pi, Qoder, Trae, GitHub Copilot.

Chapter III

The CLI

Four commands.

pilcrow audit [paths...]     # human-readable findings (default)
pilcrow lint  [paths...]     # JSON output for LLM consumption
pilcrow critique [path]      # print the LLM-critique prompt
pilcrow rules [--json]       # list every rule

If you pass no paths, the CLI reads stdin. If you pass a directory, it walks the tree and scans every .md, .mdx, .markdown, and .txt file. audit exits non-zero when an error-severity rule fires; lint exits the same way and prints JSON instead of pretty output.

A first run

$ echo "Let me delve into the rich tapestry of features." | pilcrow audit
<stdin>  3 findings
  ERROR   1:8 ai-tell-phrasebank — "delve into" (≈ "delve into")
  ERROR   1:23 ai-tell-phrasebank — "rich tapestry" (≈ "rich tapestry")
  ERROR   1:28 ai-tell-phrasebank — "tapestry of"  (≈ "tapestry of")

Each finding includes a short excerpt of the surrounding text and a one-line suggestion when the rule has one.

Piping to an LLM

The critique command emits a single prompt the model reads against the 19 higher-level rules. Pipe it into your model of choice:

pilcrow critique drafts/post.md | claude
pilcrow critique drafts/post.md | llm -m gpt-5

The expected JSON response shape is documented inside the prompt itself.

Chapter IV

Commands

Pilcrow exposes eleven commands today. Five run the engine; six load an interpretive lens. The engine is the what — deterministic findings, milliseconds per file. The lens is the how — a reference file anchored in a classical style guide that tells the model which findings matter under that lens and what rewrite shape to propose. Lenses are not rule filters; each has its own methodology, its own output, its own anti-patterns.

Utility — run the engine

auditrun the deterministic catalog; human-readable findings
lintsame scan; JSON output for piping
critiqueemit the LLM-critique prompt for the 19 higher-level rules
ruleslist every rule with id, severity, description
skillsinstall or refresh the skill in your harness

Lenses — interpret findings through a tradition

Each lens loads a reference file (skill/reference/<name>.md) when invoked. The reference encodes a methodology drawn from a named style guide, plus rewrite patterns, an output shape, and anti-patterns. None of them is a subset of audit; each produces a different report.

LensAnchorWhat it does
polishStrunk & White, Zinsserfinal pre-ship pass; triages findings into ship-blockers, worth-fixing, taste-calls
humanizeWikipedia Signs of AI writingstrip AI tells while preserving voice; classifies into vocabulary, cadence, template, fossil
tightenWilliams Stylecut zombie nouns and weak verbs; per-sentence rewrites with the buried action surfaced
clarifyPinker Sense of Style, Orwellreduce reader’s working-memory load; per-passage rewrites with mental-model commentary
paceKing On Writing, Strunkrestore rhythm; cadence histogram plus split/merge proposals
leadZinsser on leadssharpen openings; finds the buried lede, proposes three alternative first sentences

Each lens recommends a handoff to another lens when its own job is done — humanize hands off to polish; tighten can hand off to clarify or pace; lead hands off to polish. Chains are the writer’s call.

Chapter V

What audit catches

Forty-nine deterministic rules, no LLM, no API key, milliseconds per file. They fall into eight families.

For the full catalog with every rule’s id, severity, and description, see The catalog.

FamilyRules
AI phrasebankai-tell-phrasebank, overused-words, antithesis-cadence, throat-clearing-openers, cliche-closers, meta-discourse, copula-dodge
AI fossilssignoff-chatbot, sycophant-opener, disclaimer-tail, citation-artifact
Phrasecorporate-cliche, cliche-list, wordy-phrases, redundant-pairs, weasel-hedges, vague-quantifiers
Densityem-dash-density, adverb-density, nominalization-density, boosters, passive-voice, pronoun-density-low, parenthetical-aside-density, inline-bold-emphasis
Cadencesentence-length-monotony, sentence-too-long, paragraph-monotony, parallel-triplet-density, transition-stacking, repeated-words-window, noun-stacking, anaphora-cadence, fragment-cadence, hero-tagline-imperative, from-x-to-y, present-participle-tail
Consistencydash-style-inconsistency, quote-style-inconsistency, oxford-comma-inconsistency
Weak constructionsthere-is-there-are, expletives, negation-of-negation, pronoun-it-vague
Markdown shapebullet-bold-lead, title-case-headers, colon-headline, decorative-emoji, false-precision-headline

The phrasebank carries the strongest AI tells (delve, tapestry of, navigate the landscape, plays a crucial role) at severity error. The single-word list (transformative, groundbreaking, seamless, foster, unleash, robust, …) sits at severity info because any one word can be defensible in context; the volume is the tell. The antithesis rule wants two or more matches in the document before it fires, since one instance is rhetoric and repetition is the fingerprint.

Density rules report only when a threshold is crossed: more than 1.5 em-dashes per 100 words, more than 5 unfortunate adverbs per 100, more than 8 nominalizations. Below that, prose breathes.

Run pilcrow rules to see every rule with its description and severity. Run pilcrow rules --json to get a machine-readable copy.

Chapter VI

What critique catches

Nineteen higher-level patterns regex can’t catch. These rules describe shapes of argument and rhetoric, not strings of characters. The engine ships them as a catalog plus a prompt builder; the model reads the prose against the catalog and returns structured JSON findings the CLI can consume.

RuleWhat it watches for
buried-ledethe real point doesn’t appear in the first paragraph
voice-consistencyregister drifts across sections without narrative cause
mixed-metaphortwo incompatible images in one sentence
claim-without-supporta non-trivial claim with no evidence, reasoning, or example
missing-stakesthe reader can’t answer so what after reading
distinctive-vs-genericcould’ve been written by anyone (or any model)
abstract-without-concreteextended theory with no grounding example or scene
showing-vs-tellingtells the reader what to feel instead of showing why
transition-coherenceparagraphs that don’t connect
register-mismatchformal and casual jammed together without intent
excessive-balanceevery claim earns a but or however
redundant-thesisopening and closing repeat the same line
marketing-template-cadenceimperative-fragment-plus-tricolon hero rhythm, regardless of content specificity
sycophantic-tonepassage-level flattery of reader, prompt, or topic
stakes-inflationcivilizational stakes attached to small things
false-reframenot X, it’s Y with no semantic content behind it
invented-concept-labelCapitalized Compound treated as established term without definition
listicle-disguisenumbered list flowed into parallel paragraphs as prose
one-point-dilutionsingle idea restated under five framings, no new argument

Each rule in the catalog ships with a description, a positive example, and a negative example, all embedded directly in the prompt. The model returns JSON that the engine parses back into the same Finding shape the deterministic engine uses, so the two passes can be merged into one report.

Chapter VII

Fuzzy matching

Literal regex matches the wrong things. The phrasebank rules tokenize the prose, strip apostrophes, and stem each token before comparison. One phrase entry catches all the variants the model will produce in the wild.

PhraseAlso catches
delve intodelves, delving, delved, delve deeply into
fosterfosters, fostering, fostered
let’s dive inLet’s dive in, lets dive in

One inserted word is permitted between phrase tokens, so delve deeply into matches delve into. Apostrophes are stripped from both sides before matching, so Let’s matches lets.

For the complete list of phrases, words, and patterns the engine watches, see The catalog — auto-generated from the source on every deploy.

Colophon

About the book

Set in ET Book, Edward Tufte’s revival of Bembo. Cream paper, ink text, a single sage band at the colophon, gilt for chapter numbers and focus. The layout borrows the sticky margin from Tufte CSS and turns it into a vertical spine.

Inspired by impeccable.style by Paul Bakaus — the canonical design-language skill. The framing (a skill, a CLI, an anti-pattern catalog, the "AI tells" framing) is borrowed directly.

Source on GitHub. MIT license. Hosted at pilcrow.ink.