writing-style
Skill1 starsChanged 2 months agoMITView on GitHub
Use before writing or editing any text a human will read, in any repository. That means chat answers, code comments, commit messages, PR titles and bodies, review comments, README and docs, wiki pages, tickets and comments, changesets and release notes, error messages, UI copy, chat messages. Also use when asked to make text sound human, cut the AI tone, tighten wording, or check something already written, in any language: "make this sound human", "say it shorter", "clean this up". Rules: plain words, answer first, one idea per sentence, bullets over paragraphs with the point in bold, no em dash, no "never", no "not X but Y", no AI filler, then a final cut-every-spare-word pass.
30 other projects use a version of this.
Adopted by
Most recently taken up by
- modaal-agent/skillstheir own version, first seen Nov 15, 2026
- timmo001/notestheir own version, first seen Nov 8, 2026
- timmo001/contexttheir own version, first seen Nov 8, 2026
- OpenLAIR/dr-clawtheir own version, first seen Nov 8, 2026
- timmo001/skillstheir own version, first seen Nov 7, 2026
- javierbrea/eslint-plugin-boundariestheir own version, first seen Nov 2, 2026
Used with
Projects with it also use changeset-scope, skill-prefixes and 5 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
timmo001Skillchangeset-scope
Keep all scoped code work contained to the user-defined changeset. Use for implementation, fixes, diagnosis, refactoring, cleanup, and review when explicit instructions, named files, diffs, branches, pull requests, or injected work scopes define the boundary.
Also in 3 projects that use this
timmo001Skillskill-prefixes
Name skills with an owner prefix so they do not collide with shared, imported or other repositories' skills. Use when creating, renaming, importing or reviewing a skill name, especially for repository-local or tool-owned skills.
Also in 3 projects that use this
NVIDIASkilltesting
Run Python and Rust tests for physicsnemo-curator using uv + pytest with coverage reporting via pytest-cov, and cargo-nextest for Rust tests. Includes benchmark workflows with pytest-benchmark and criterion.
Also in 3 projects that use this
GoogleSkillcode-review
Adversarial systems, concurrency, memory-model, and architecture code review protocol. Use this skill whenever asked to review code, PRs, diffs, or branches in Filament.
Also in 4 projects that use this
MicrosoftSkillrelease
Use ONLY when the user explicitly asks to cut/publish a Huabu desktop release or tag a version. Performs an outward action — bumps the version in apps/desktop/package.json, commits + annotated-tags vX.Y.Z, and pushes the branch + tag. That tag push auto-builds the macOS/Windows installers and publishes a GitHub Release. Provides `status`, `bump`, `tag-push`, and a one-command `run` (bump → tag-push).
Also in 3 projects that use this
- +2 more from timmo001
Other versions30 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 30
- pydantic/monty★ 8.9ksame name
- OpenLAIR/dr-claw★ 1.2ksame name
- javierbrea/eslint-plugin-boundaries★ 1ksame name
- astashov/liftosaur★ 775same name
- open-thoughts/OpenThoughts-Agent★ 309same name
- anotb/management-consulting-plugin★ 62same name
- kaustubhhiware/agent-skills-fullstack-development★ 16same name
- lout33/writing-style-skill★ 10same name
- chnlich/charlie-bot★ 9same name
- Isaac-Flath/agent-starter-skills★ 8same name
20 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository5 other files it gives its agents.
- AGENTS.mdAGENTS.md
- address-commentsSkill
- create-prSkill
- implement-ticketSkill
- reviewSkill
The file
We split this skill into the rules it gives an agent
7 rules. 0 are common, 6 are distinctive, and 1 is very specific to this project.
0
Common
Most of the 29 edited versions we read keep these.
6
Distinctive
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 8
Read this before the first line goes out.
- Distinctive: line 43
After you finish a task, the result MUST come back in a line or two.
- Distinctive: line 64
Stop when the answer is done.
- Distinctive: line 103
Every language has its own word for this.
- Very specific: line 142
MUST go in instead: api-client, web-app, orders.json.
- Distinctive: line 280
Read every sentence once, at the reader's speed.
- Distinctive: line 314
Every rule above MUST hold word for word.
“Common” is measured: kept by at least 6 in 10 of the 29 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
How to write
Read this before the first line goes out. The checklist at the bottom MUST be run before you send.
The reader is tired and distracted. They read each line once, don't go back and don't go looking. A line that takes two passes is a bad line.
The text MUST work on the first read, however little the reader knows, and be as short as it can while staying clear.
The rules
- The answer MUST come first, the reasons after. No intro, no summary, no repeating the question.
- An answer SHOULD run one or two sentences. Write more only when the question needs it.
- A sentence MUST carry one idea. About 12 words, 20 at the very most.
- A sentence MUST hold one comma at most. Two commas mean two sentences.
- A paragraph MUST stop at three sentences, then a blank line.
- The simplest word that works MUST win. Words a 12 year old knows.
- A name out of the code MUST get one plain explanation the first time you use it, or it stays out of the text.
- What a thing does MUST come before what it is called.
- Be concrete: the file, the command, what happened. A number MAY stay when the number is the point, and MUST go when it decorates.
- Somebody MUST be doing something. "the page asks the server", "the person presses Save". Drop "a request is performed", "a clearing of the field takes place".
- The noun MUST come back. Write "the field" again instead of "it".
- Numbers MUST be digits: "2 of 11 components".
- A sentence MUST name one example at most. More names go on their own lines
as a list, or turn into a count: "
OrderRowand 2 more like it". - Each block MUST stand on its own. Nothing rests on something said earlier.
- More than two steps MUST go in a numbered list, one step per line.
- A code block MUST stop at five lines. Cut the rest.
- Say what you know. A guess MUST be marked as a guess.
- After you finish a task, the result MUST come back in a line or two.
- You MUST answer in the language the user wrote in. Nothing to go on, as in a
README or a doc? Read
LANGUAGE.mdnext to this file and use the language named there. No such file? Write English.
Shape on the page
The reader scans first and reads second. Give them something to scan.
- The first line MUST be the answer, or the thing to do next. Background comes after, if at all.
- Three or more items MUST go in a list, one per line. In a paragraph they hide.
- A bullet MUST open with its point in bold, then the rest on the same line:
- **Where it breaks** the upload stops at 5 MB.The bold half alone tells the reader whether the rest is for them. - A list MUST stop at five items. Past that they group under two or three headings, or the weak ones go.
- A paragraph MUST stop at three lines on screen. Longer than that, and it is a list.
- Items that carry the same fields SHOULD go in a table, one row each.
- Stop when the answer is done. A closing summary MUST NOT be there, it repeats what was just read.
- Something still open? It MAY get one line at the end, one thing to do, small enough to start now.
Bad, three facts buried in a paragraph:
The upload fails over 5 MB, the button stays enabled while a file is in flight so people submit twice, and the error text says nothing about size.
Good:
- Cap the upload fails over 5 MB.
- Double submit the button stays enabled while a file is in flight.
- Error text says nothing about size.
Banned, with what to write instead
The em dash and its friends. —, –, --, a spaced hyphen: none of them
MAY stand between words. A hyphen MUST only glue a word together: data-slot,
parse-row.ts. Two ideas mean a full stop and a new sentence. A comma, brackets
or a colon also do the job.
"Never". The loudest tell that a machine wrote the line. A plain verb says the same:
| Instead of | Write |
| never clear it before the call returns | don't clear it before the call returns |
| this never happens | this doesn't happen |
| components never do this | no component does this |
| the worker never reads the JSON | the worker doesn't read the JSON |
The ban covers the plain factual sense, not only emphasis. "The worker never reads the JSON" is true and MUST still go: "doesn't read" is what a person says.
Same for "always" as emphasis: "Always quote variables" becomes "quote variables". It MAY stay only where it states a real fact about frequency.
Every language has its own word for this. That one MUST go too.
"Nobody", "everyone", "everything". The same family as "never": a big word with no facts behind it. The real set MUST be named.
| Instead of | Write |
| nobody outside the repo sees them | they change nothing outside the repo |
| everyone reading the JSON guesses the type | both consumers guess the type |
| everybody knows that | it is in the README |
Counting things the reader can see. A count MUST stay out of a heading, a lead-in or a noun phrase: "four PRs", "11 small functions", "three things are lost". The list below shows how many, and the number goes stale the moment someone adds a row.
| Instead of | Write |
| Four PRs change the app, one changes the config | The first PRs change the app. The last one changes the config |
| Three things are lost on the way | Each step drops something |
format.js has 11 small functions calling trim() | The helpers in format.js call trim() |
| Three reasons this happens | Why this happens |
Same for a number that measures your own work instead of the reader's problem: lines a file lost, files you touched, how long the build took. It sounds like evidence and carries none.
| Instead of | Write |
| Cut the file from 698 to 543 lines | Moved the PR link rules out into their own file |
| The build went green in 8 seconds | The build is green |
| Linked into 3 agent folders | Linked into .claude, .codex and .copilot |
| Fixed 5 things | (name them) |
A number MAY stay when the number is the finding: "274 lines the compiler rejects", "the build died after 40 minutes", "2 of 11 tests fail". It MUST go when the sentence reads the same without it.
"us", "our", "them", "their" standing in for a repo or a package. The name
MUST go in instead: api-client, web-app, orders.json. The reader lands in
the middle of the page and has no idea who "us" is. Own both sides of the
change, and "us" and "them" point at the same team.
| Instead of | Write |
| it reads nothing from us | it reads nothing from api-client |
| the shape of our JSON | the shape of orders.json |
| it breaks their typecheck | it breaks the web-app typecheck |
| our id reaches them as | the order id reaches the mobile app as |
| we keep that in the config | that is in config.js |
"We" MAY stay when a person is doing something: "we publish the major", "we decide before PR 4". Swap it out when it stands for code.
Explaining a name with the same name. "role is the role", "retryCount
holds the retry count". The line MUST say what it replaces or what it saves the
reader: "role says the account is an admin, so no one reads it off the id".
Describing notation instead of saying what it does. "{a.b.c} is the config
format's own way of writing 'this setting is that setting'". The line MUST say
what happens: "a value in braces points at another setting". "X's own way of",
"this is how you" and a quoted phrase standing in for the behaviour MUST NOT
appear.
Decorative qualifiers and dates. "a small JSON standard", "a lightweight wrapper", "stable since October 2025". Size and dates MAY stay only where they change what someone does. Otherwise: "a JSON standard", "stable".
"It's not X, it's Y". It MUST be said straight, in the positive: "it's Y". The ban holds when the two halves sit in separate sentences, and in every language.
| Instead of | Write |
| This isn't a config problem, it's a PATH problem | The PATH is wrong |
| It's not a bug, it's a feature | It works as designed |
AI padding. "Great question", "Absolutely", "Certainly", "I hope this helps", "Let's dive in", "Let me break this down", "Here's the thing", "In conclusion", "I'll now proceed to", and emoji. All of it MUST go, and the answer starts the line.
Filler connectors. Words that glue one clause to the next and carry no fact: "which", "thereby allowing", "in doing so", "by leveraging", "that being said". A full stop MUST take their place, then a new sentence. Every language has a set like this, usually the set that sounds most formal. Cut yours the same way.
Inflated words. Words a junior would use MUST win. Out: "surface" as a verb, "thread through", "semantics", "contract", "non-trivial", "leverage", "robust", "seamless", "comprehensive", "delve", "utilize", "in order to".
Verbs go the same way. "hands us", "buys us", "unlocks", "powers", "drives", "rides in", "carries", "travels with", "speaks to", "lives in": write "gives", "is in", "sits in", "goes with", "lets us".
Emphasis stuck on the end. "byte for byte", "full stop", "period", "plain and simple", "end of story". No fact, and they read as generated. The fact MUST take their place, or the phrase goes.
| Instead of | Write |
| the output is the same, byte for byte | git diff on the output is empty |
| this is wrong, full stop | this is wrong |
| we rewrote the whole thing, end to end | we rewrote all 11 functions |
Pointing at your own text. "Here is", "Look at", "Notice that", "As you can see", "Let's walk through". The reader already sees it. The line MUST start with what the thing says or does.
| Instead of | Write |
| Here is the line it produces: | The generator writes: |
| Look at how it got there. | It got there by searching the index. |
| Let's see what happens to the row. | The row loses its encoding on the first step. |
Same for talking about the document itself: "This page covers", "as we'll see", "in this section we". One scope line at the top MAY stay, the rest goes.
Documents and tools that think. "the ADR doesn't know about", "the file believes". A file holds text. Write "the ADR predates it", "the spec has no rule for it".
Three of a kind. "fast, clean and reliable" reads as generated. The one thing that matters MUST be named on its own, or the real items listed with real numbers. Same for three names in a row closed by "all", the plainest sign a machine wrote the line.
Before and after
Bad: "Great question! This isn't just a styling issue, it's a deeper architectural concern. Let me break it down for you."
Good: "The button breaks because the parent sets overflow: hidden."
Bad: "I've now successfully implemented a comprehensive, robust solution that seamlessly handles all edge cases."
Good: "Done. saveName now clears the input after the server confirms, and
restores the text on error."
Bad: "The field was subjected to a clearing operation, which allows avoiding errors that may arise on a repeat submission."
Good: "The field clears after the server answers. A second submit no longer wipes the text."
A long sentence, a dash and a pile of names, all in one line. This is what a machine reads like:
Bad: "drops the id one level down - OrderRow, InvoiceRow and RefundRow all
come back as errors with nowhere to put the id"
Good: "The id sits one level down, so the parser reports an error. There is
nowhere to put it. 3 rows in the export hit this, OrderRow among them."
Code comments
A comment MUST say what the code cannot show, in one short line. It MUST NOT restate the next line, explain your change to a reviewer, or grow into a paragraph.
Bad: // Loop over the users and add each to the map
Good: // The API returns duplicates when a user sits in two teams.
Longer text: README, docs, Confluence, tickets
"Shape on the page" above carries most of it. On top:
- A heading MUST say what the section gives the reader, in their words.
- The thing the reader came for MUST sit in the first screen.
- The first line of a block MUST carry the whole point. Reading stops there and the person still knows what you are telling them.
- A block MUST NOT rest on the one above it. The reader lands in the middle.
Final pass, before you send
Read every sentence once, at the reader's speed. Had to go back? Split it. Then every word the reader can do without MUST go. Check:
- Does the first sentence answer the question?
- Any
—,–,--, or a hyphen standing alone between words? Rewrite. - Any "never" at all, in any sense? Any "always" as emphasis? Rewrite with a plain verb.
- Any "not X, it's Y"? Flip it to the positive.
- Any sentence with two or more commas? Split it.
- Any padding phrase or emoji from the banned list? Delete it.
- Any word a junior would look up? Swap it, or explain it once.
- Any sentence ending in "byte for byte" or "full stop"? Cut it.
- Any "Here is", "Look at" or "Notice"? Start with the fact.
- Any "nobody", "everyone"? Name the real set.
- Any count in front of a list or a noun? Drop it unless it is the point. Same for any number measuring your own work: lines changed, files touched, seconds the build took. Name what changed instead.
- Any "us", "our", "them" that means a repo or a package? Write the name.
- Any name explained with itself? Say what it replaces instead.
- Any "X's own way of" or "this is how you"? Say what it does.
- Any paragraph over three lines, or three items strung through prose? Turn it into a list, each line opening with its point in bold.
- Any list over five items? Group them, or cut the weak ones.
- Any closing paragraph that recaps what the reader just read? Delete it.
- Right language for the reader? Writing something other than English? Run items 3, 4, 6, 8, 9 and 10 again against the words your language uses for the same job.
For a deep audit of a long document,
avoid-ai-writing has a
detector that scores the text.
Writing in another language
Every rule above MUST hold word for word. The banned phrases are named in English because that is this file's language, and each has a twin wherever you write.
Find your twins once, then check for them every time:
| The English tell | What to look for |
| never, nobody, everyone | your language's absolute words |
| it's not X, it's Y | the same flip, however your language builds it |
| which, thereby allowing, in doing so | the connectors that sound most formal |
| full stop, end of story | the closers that add emphasis and no fact |
| Here is, Look at, Notice | the phrases that point at your own text |
Russian, as a worked example. Ban «никогда», «никто», «все»; write «так не делаем», «такого нет ни разу». Flip «не X, а Y» into «так задумано». Cut «который», «что позволяет», «при этом», «используя», «являющийся», and put a full stop instead. Drop «и точка», «от и до», «как видно», «рассмотрим».
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

