prose
Skill4 starsChanged 15 days agoApache-2.0View on GitHub
Write or revise prose in this repo (docs/, README, AGENTS, VALUES, CONTRIBUTING, SECURITY, or a doc comment) so it reads in the author's voice rather than a compressed register. Use when editing any markdown prose, when `pnpm check` fails the `prose-health` or `prose` slot, or when asked to review, tighten, or rewrite documentation. Carries the decompression method, the traps that break markdown structure, and the measurement that says whether it worked.
15 other projects use a version of this.
Adopted by
Most recently taken up by
- VladButacu/agentkittheir own version, first seen Nov 15, 2026
- sanmidable/skillstheir own version, first seen Nov 8, 2026
- krkn-s/ai-workspacetheir own version, first seen Nov 1, 2026
- bym6dn6zv5-gif/skillstheir own version, first seen Nov 1, 2026
- raphaelsalaja/skillstheir own version, first seen Nov 1, 2026
- simota/agent-skillstheir own version, first seen Oct 23, 2026
Used with
Projects with it also use design.
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.
Microsoft AzureSkilldesign
Design rules and conventions for the API Center Portal. Use when editing detail pages, card components, badges, layout, navigation, sidebars, or headers. Covers badge styling, metadata placement, page navigation patterns, and layout alignment.
Also in 3 projects that use this
Other versions15 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 15
- cloudflare/computer★ 9.9ksame name
- tokio-rs/topcoat★ 6.4ksame name
- tokio-rs/toasty★ 3.3ksame name
- static-web-server/static-web-server★ 2.4ksame name
- cohen-liel/hivemind★ 108same name
- simota/agent-skills★ 96same name
- raphaelsalaja/skills★ 62same name
- sanmidable/skills★ 2same name
- bym6dn6zv5-gif/skills★ 1same name
- j912835225-prog/whetstone★ 1same name
5 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.
The file
We split this skill into the rules it gives an agent
4 rules. 0 are common, 2 are distinctive, and 2 are very specific to this project.
0
Common
Most of the 13 edited versions we read keep these.
2
Distinctive
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 34
Read the exemplars first: All seven, every time, before writing a word.
- Very specific: line 37
Read the file and fix sentences: Not patterns, sentences. --file <path> lists the longest ones as a starting point.
- Distinctive: line 65
Reflowing markdown eats list structure: If you rewrap a paragraph, a bullet list with no blank lines between items merges into one …
- Distinctive: line 69
Never suppress: No inline vale comments.
“Common” is measured: kept by at least 6 in 10 of the 13 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
prose
The mechanical rules live in .vale/styles/Repo/*.yml and gate at error level. The voice lives in .vale/exemplars/. This skill is the third thing: the shape of a sentence, which neither a rule nor an exemplar can enforce, and which is where this repo's docs actually go wrong.
The failure mode
Docs here drift toward prose that is individually correct and collectively airless. Every rule passes, every sentence parses, and the whole page reads like a specification because the clauses have been packed into modifiers:
| compressed | decompressed |
| a bot wired to a managed vector index | a bot that's wired to a managed vector index |
an arm returning { winner, scores } | an arm that returns { winner, scores } |
| spans emitted without a parent | spans that are emitted without a parent |
| the failure mode observed everywhere | the failure mode that turns up everywhere |
| It diverges by being a framework with a lifecycle | It's a framework that owns a lifecycle |
| the event stream a composition library emits | the event stream that a composition library emits |
| for shapes bindings can't express | for the shapes that bindings can't express |
The common thread is a missing finite verb. A participle (wired, returning, emitted) or a bare noun stack does a clause's work, and the reader has to reconstruct the verb. Giving it back is the whole method.
The one rule that matters
Never insert a word to move a number. The measurement counts that; a compressed sentence is fixed by rewriting it into a finite clause, and the that shows up as a by-product. Adding that to an object relative that reads fine already (a set of functions you can call → a set of functions that you can call) raises the score and makes the prose worse. The exemplars themselves drop object relatives constantly; their high density comes from subject relatives, where that is grammatically obligatory. That distinction is the whole game.
Corollary: if you cannot say which sentence got better, you did not improve it.
Method
- Read the exemplars first. All seven, every time, before writing a word. About 4.2k tokens. They are read-only by contract and the
exemplarscheck fails on any diff, whitespace included. - Measure before you touch anything.
node scripts/prose-health.mjs --report. - Sort by genre, not by score. Explanatory prose (comparison, concepts, blueprint, leaf-arm-spine, deliberation, adoption-decision) can carry essay density. Reference material (api-reference, providers, configuration, composition, cli) is tables and signatures, and a table row has no relative clause to restore. Say so in your report instead of forcing it. The
codeandtblcolumns in the report show you which is which. - Read the file and fix sentences. Not patterns, sentences.
--file <path>lists the longest ones as a starting point. - Re-run
pnpm check --only proseafter every file. Restructuring very easily produces a sentence opening on "There is", which gates at error. - Verify structure, then measure again.
What is not the problem
Diagnostic work already done, twice. Do not redo it:
- Not stripped complementizers after report verbs. Grepping
means|shows|ensures|notes|assumes+ noun phrase across docs/ returns almost nothing. - Not restrictive
whichwanting to bethat. docs/ useswhichless than the exemplars do. - Not present-participial post-modifiers ("steps needing X"). There were exactly two in the whole corpus.
- It is past-participial post-modifiers and noun stacks. This is the live one and it is everywhere.
Why there is no regex for it
A detector for participial post-modifiers was built, measured, and deliberately not shipped. On a labelled corpus (pre-pass vs post-pass docs) it scored roughly 50–70% precision and its before/after delta sat inside its own noise. The reason is structural: without part-of-speech tagging, simple past with an object is indistinguishable from participle with an object.
the token limit truncated the response(finite verb, fine)an arm returning the winner(participle, compress)
Both match <noun> <verb-ed|-ing> <determiner>. Getting this right needs a POS tagger, which is a dependency, and AGENTS.md says not to add those casually. So the constructions live in the table above, for a reader to apply, and the check measures only what needs no tagging. Do not re-attempt the regex unless you are bringing a tagger.
Traps
ThereIsgates at error. Restructuring producesThere is/There areopenings constantly. Re-runpnpm check --only proseafter every file.EmDash,Semicolon,Colongate at error. An aside takes round brackets. One semicolon and one colon to a sentence. A single em dash between clauses is a pause and is fine.HeadingCasegatesdocs/*.md(Chicago). Headings are Title Case and their slugs are load-bearing — 53 anchor links point at them. Never reword a heading without checking every](#anchor)target.- Naming.
Fasciclein prose,fascicleonly as an identifier (the package, thefascicle/*subpaths, thefascicle-viewerbinary). - Reflowing markdown eats list structure. If you rewrap a paragraph, a bullet list with no blank lines between items merges into one paragraph. Treat a list marker as a hard block boundary. This has caused real damage twice.
- Every file has its own wrap width (76 to 113). Preserve each file's; do not impose one.
- Whole-block replacement loses indentation. Matching a block by collapsed whitespace and replacing it will silently double or drop the leading indent inside a list item. Check the result.
- Never re-baseline to clear a failure you introduced. Applies to
checkride.baseline.jsonand.prose-health.jsonalike. - Never suppress. No inline vale comments.
Verify before you commit
Beyond pnpm check:all:
- Structure is unchanged. For every file touched, compare heading count, list-item count, fence count, and link count against the previous commit. They must be identical. This has caught real damage: a reflow that silently merged four bullets and a six-item numbered list into one paragraph.
- Anchors still resolve. Generate the GitHub slug for every heading and match every
](#…)target. - Grep your own diff for the failure modes of mechanical editing: doubled connectives (
, so … , so), subject-verb disagreement left by a person change (you wants,It runs …, have a judge read …, and only pay), and object pronouns contracted with the next clause's verb (nothing in it's still a step).
Each of those has happened here. The third one shipped.
Reporting
Give the before and after number, and state plainly which files you judged should not move, and why. A smaller honest delta beats a larger forced one. "The remaining gap is genre and should not be closed" is a legitimate result.
Reference
node scripts/prose-health.mjs— ratchet against the baseline (theprose-healthcheck)node scripts/prose-health.mjs --report— full table, always exits 0node scripts/prose-health.mjs --file docs/x.md— one file, all metrics, longest sentencesnode scripts/prose-health.mjs --update— rewrite the baseline (deliberate act, own commit, state the reason).check/prose-health.json— structured output- Benchmark:
docs/regression-testing-model-behavior.mdsits at target with no intervention, because it is written as an essay. It is a better reference for this repo's own voice than the exemplars are for a docs page.
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.

