AI speak patterns, part 4
Built from the packs in hooks/lib/patterns. Each section names its own source.
The category index is in ai-speak-patterns.md.
ai-tool-mention
Presets: default, ryan, technical, git, all. Source: Group G research: anthropics/claude-code#1296 and anthropics/claude-code#66602.
Names of AI coding tools, or the agent narrating its own process instead of the change.
| Flagged | Fix |
|---|---|
as requested by the user | state the change directly |
per the user's instructions | state the change directly |
per the assistant, per the model, per the AI | state the change directly |
as suggested by the assistant, as suggested by the model, as suggested by the AI | state the change directly |
the model suggested, the assistant wrote | state the change directly |
AI-generated, AI generated | cut the disclosure |
with AI assistance | cut the disclosure |
generated by AI, written by an AI | cut the disclosure |
generated by or written with a named AI tool | cut the tool name |
a git commit command naming an AI tool | cut the tool name |
A tool name reports only next to process wording (generated by, written by, suggested by) or inside a git commit command, so a comment that just names a tool stays clean. That wording around the model or the assistant reports as well, which a repo whose subject is model output drops with disablePatterns.
benefit-tail
Presets: ryan, technical, git, all. Source: Group G research: AI-generated PR summary and commit body conventions.
A sentence ends in a justification clause tacked on after a comma.
| Flagged | Fix |
|---|---|
, which improves readability and the like | cut the justification clause |
, making it easier to maintain | cut the justification clause |
, for better performance | cut the justification clause |
, ensuring consistency | cut the justification clause |
, so that it's more robust | cut the justification clause |
The noun list is intentionally abstract. A tail that names a measured effect, such as cuts p99 latency to 90ms, does not match.
canned-review
Presets: default, ryan, technical, git, all. Source: Group G research: PR review boilerplate.
Stock PR-review phrasing used regardless of what the diff actually does.
| Flagged | Fix |
|---|---|
LGTM with minor nits | cut, or approve plainly |
Looks good to me | cut, or approve plainly |
Nice work | cut |
Great work on this | cut |
One small suggestion | state the suggestion |
Minor nitpick | state the point |
Overall, this looks good | cut, or approve plainly |
solid implementation | cut |
well-structured | cut, or name the structure |
clean implementation | cut |
It might be worth considering | state the suggestion |
Consider adding tests and I'd suggest are left out. Careful reviewers open with them before a concrete point, which held the full list under 85% precision.
file-narration
Presets: ryan, technical, git, all. Source: Group G research: git commit-message conventions and conventional commits.
Text narrates a trivial file operation instead of stating the change.
| Flagged | Fix |
|---|---|
This commit adds | state the change, cut the frame |
This commit introduces | state the change, cut the frame |
This PR introduces | state the change, cut the frame |
This PR adds | state the change, cut the frame |
Here's what changed | list the changes directly |
The file now contains | state the content directly |
Added a new file called | name the file, cut the frame |
I've updated the, I've added a | state the change, cut the frame |
a line opening with Updated, Added, or Deleted plus a file name | use the imperative mood |
The past-tense form has to open the line, so a conventional-commit subject such as docs: update README stays clean.
praise-sandwich
Presets: ryan, git, all. Source: Group G research: Wikipedia compliment sandwich, Radical Candor feedback sandwich.
Review or reply text opens and closes with praise around a middle critique.
| Flagged | Fix |
|---|---|
| Review or reply text opens and closes with praise around a middle critique. | minParagraphs = 3, minWords = 18 |
Needs praise in the first and last paragraph and a critique marker between them. People are taught this shape too, so the pack stays out of the default preset.
hidden-characters
Presets: default, ryan, technical, git, all. Source: Opus 5.5 replies (U+2011 at 0.33 per 10,000 words), Microsoft known issue on LLM hyphens (Apr 2026), OpenAI U+202F reports (2025), Trojan Source bidi controls, Wikipedia:Signs of AI writing.
Invisible or look-alike characters that model output and chat UIs leave in text.
| Flagged | Fix |
|---|---|
| a zero-width space, zero-width non-joiner, word joiner, or Mongolian vowel separator | remove the zero-width character |
| a zero-width joiner outside an emoji sequence | remove the zero-width joiner |
| a byte order mark after the first character | remove the byte order mark |
| a soft hyphen or non-breaking hyphen | use -, or remove the soft hyphen |
| a narrow no-break space or figure space | use a plain space |
| a Unicode tag character | remove the tag character, it can hide text |
| a variation selector other than the emoji and text selectors | remove the variation selector, it can hide data |
| a bidirectional control character | remove the bidi control |
ChatGPT citation markers: cite followed by turn0search0, or contentReference followed by an oaicite index | remove the citation residue |
Anthropic’s text watermark adds no characters, so this pack cannot see it. In a code file the pack reads the whole file, string literals included, through the code scope. U+00A0 is left out: npm READMEs carry it 5.6 times per 10,000 words. A zero-width joiner inside an emoji sequence and tag characters after the black flag (subdivision flags) stay unflagged. A right-to-left project lists hidden-characters in excludePacks or drops the bidi row with its own pack.
smart-punctuation
Presets: default, ryan, technical, all. Source: Group P research: Wikipedia, Signs of AI writing.
Curly quotes and the ellipsis character typical of text pasted from a chat UI.
| Flagged | Fix |
|---|---|
| a curly double quote | use a straight double quote |
| a curly opening single quote | use a straight single quote |
| a curly apostrophe | use a straight apostrophe |
| an ellipsis character | use three periods |
Prose files are intentionally out of scope: a whole-file scan re-reports typeset quotes that a person committed once. A project that wants files coverage overrides the pack.
unicode-glyphs
Presets: default, ryan, technical, all. Source: Group P research: Wikipedia, Signs of AI writing.
Arrows, box drawing, dingbats, and geometric symbols used in place of plain ASCII or words.
| Flagged | Fix |
|---|---|
| an arrow character | use -> or <-, or words |
| a box-drawing character | use ASCII table characters |
| a dingbat or check mark | use [x], [ ], or words |
| a miscellaneous symbol | use plain words, drop the symbol |
| a bullet character | use - or * for list items |
| a geometric shape character | use plain words, drop the symbol |
Every range skips code points that are also Extended_Pictographic, so emoji stay with the formatting pack and the dash characters stay with em-dash. Prose files stay out of scope for the same reason as smart-punctuation. Code comments are out of scope too: a measured pass over 797 library files found arrows in JSDoc examples and box-drawing type diagrams in hand-written comments, and the pack cannot tell those from decoration.