doc-quality
Skill2 starsChanged 6 days agoApache-2.0View on GitHub
Docs-health readability scan—two axes: QUALITY (bloat: filler, repetition, walls of text, buried leads; clarity: unexplained jargon, ambiguity, sentences that fight the reader) and language MECHANICS (typo, grammar, spelling, orthography—including script-level defects like decomposed characters that render right but break search, doubled spaces, wrong ellipsis/quote characters, an em-dash spacing convention check against `emDash`—engine-detected, off by factory default—spacing rules of the doc's language). Catches UNREADABLE or MALFORMED-LANGUAGE docs. Triggers on: "/doc-quality", "doc-quality", "tighten this doc", "proofread", "typos and grammar", "is this readable". Mechanical layer = deterministic mechanics (Unicode normalization, spacing, punctuation shape—~free, report-only); semantic layer = bloat/clarity judgment + grammar in context (paid, consent-gated). Honors the project's own style/language rules where defined. Severity judged by context, never mechanical.
In this repository6 other files it gives its agents.
- doc-consistencySkill
- doc-groundingSkill
- doc-leakSkill
- doc-rotSkill
- doc-standardSkill
- doc-structureSkill
The file
We split this skill into the rules it gives an agent
5 rules. About 0 are common, 3 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
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
- Distinctive: line 24
House rules first: if the project defines its own style or language rules (a style guide, formatting conventions, per-language orthography …
- Very specific: line 27
Run cd "<skill base dir>" && node ./lib/emdash.mjs --list-path first, then write the run list with your file tool to the exact path it …
- Distinctive: line 53
After any report in an interactive session you MUST present this menu via your question tool (skip only when findings are zero or no user …
- Distinctive: line 59
NEVER auto-fix: any prose rewrite, cut, or word-choice change—meaning belongs to the author.
- Very specific: line 65
If this canary misbehaves, OFFER to file it at <https://github.com/TheColliery/CoalLedger/issues> with a user-reviewed summary—never …
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Doc-Quality
Answer in the USER'S language; keep technical terms, commands, paths, and check ids verbatim.
Find what makes a doc hard to read or mechanically malformed. Report CONFIRMED findings; style opinions stay SUSPECTED.
Parameters
- SCOPE: named files (default when given) | touched doc files this session | whole repo docs—
.md/.mdx/.markdown/.rst/.txt/.adoc/.asciidoc/.org(confirm first if > 20 files). - TIER: Quick = mechanical mechanics only (~free) · Full = adds bloat/clarity + grammar-in-context (paid). Default from
quickVsFull(.coalledger.json, global + project merge); Full is always a separate consent.
The two axes
| axis | layer | catches |
| language mechanics | mechanical | decomposed characters that render identically but break search/sort (normalize-and-compare), doubled spaces, mixed or wrong quote/ellipsis/dash characters, an em-dash spacing mismatch against the configured emDash convention (engine-detected, see Method step 2b—off by factory default, so this row is inert until a project sets it), script-range punctuation/spacing mismatches under a shipped rule (engine-detected, see Method step 2c—EN, ZH, JA and KO tables today), the doc language's own other spacing/orthography rules, obvious misspellings |
| quality | semantic | filler and repetition (the same point twice), walls of text, buried leads, unexplained jargon for the doc's audience, ambiguous instructions |
Method
- House rules first: if the project defines its own style or language rules (a style guide, formatting conventions, per-language orthography rules), those BIND—enforce them over any general rule, and never fight a documented deliberate choice.
- Quick (mechanics): deterministic checks per the table—a mechanics finding is CONFIRMED only when it is objectively wrong in the doc's language (a decomposed character, a doubled space), not a stylistic preference.
- 2b. Em-dash convention (
emDash,.coalledger.json, global + project merge): the engine ships INSIDE this skill folder at./lib/, so the skill works even when it travels alone. It readsemDashitself, never copy it into a command: when it isoffthe engine reads nothing and printsTOTAL: 0. Your context carries this skill's base directory—substitute it for<skill base dir>, then run exactly: Runcd "<skill base dir>" && node ./lib/emdash.mjs --list-pathfirst, then write the run list with your file tool to the exact path it prints,{"root": "<absolute project folder>", "docs": ["<absolute doc path>", ...]}. Then run:cd "<skill base dir>" && node ./lib/emdash.mjs --listThecdis REQUIRED —./lib/resolves against the skill folder, never your project cwd. Target docs must be ABSOLUTE paths, since cwd is now the skill folder. The run list'srootis the absolute path of the project folder that holds the docs (the folder you are working in): a doc whose path runs through a linked folder inside it is refused as unreadable, and so is a doc outside it. No path goes on the command line; the engine reads them from the run list as data. Never pass--mode: it is a flag for the engine's own tests. Output isfile:line:col: contextper hit, one line per finding; a bareTOTAL: Nline closes the run. If any target file is unreadable, the closing line readsTOTAL: unknown (U unreadable; M found in the readable files)and the exit code is 1, so a clean total is never reported over a file the engine could not read. Never re-derive this by eye — the engine already handles fenced/inline code, URLs, Thai lines, blockquotes, and LICENSE/NOTICE/COPYING-class files; see its own header for the exclusion classes and the one class it cannot do (an inline quotation with no blockquote marker — a known, stated over-report the caller adjudicates, never guessed away). - 2c. Script-mechanics (
lang-mechanics.mjs): same skill folder, samecdrequirement, absolute paths, the same run list; no path goes on this line; the engine reads them from the run list. Run (the run list first, as in 2b):cd "<skill base dir>" && node ./lib/lang-mechanics.mjs --json --list. Detection is by SCRIPT RANGE found in the text, resolved per LINE, never by the doc's declared language—today ships four tables: EN (en-double-space-after-period, severity warn; authority Microsoft Writing Style Guide, Periods), ZH (zh-halfwidth-punct,zh-space-before-punct, severity error; GB/T 15834-2011), JA (ja-halfwidth-punct, severity error;ja-fullwidth-comma-periodandja-space-between-fullwidth, severity warn; JTF Japanese Standard Style Guide 4.0, clauses 1.2.1 and 2.3.1.2) and KO (ko-fullwidth-punct, severity error; 새국어생활 24권 4호, 문장 부호 appendix). A line in any other script (Thai included) reports nothing here until its table ships. An error-severity hit is objectively wrong under its named authority; a warn-severity hit rests on a single-author vendor or industry guide, so treat it as SUSPECTED.--script en|zh|ja|kolimits a run to one table. A Han line carrying any Hangul or Kana is silent too (the script resolves to KO/JA on that line, vetoing the ZH rules to close a real Korean-Hanja false positive). The exit contract matches 2b's (exit 0 on findings, exit 1 on an unreadable file;lang-mechanics.mjsalso exits 1 on a call with no file, whereemdash.mjsexits 0), so the exit code never counts findings; the output shape is NOT 2b's: with--jsonone JSON array of{ file, findings }entries, without it onefile:line:col [rule] description | snippetline per finding and a closingN finding(s) across M file(s)line (noTOTAL:line); an unreadable file printsFAIL <file>: <reason>on stderr. Each--jsonentry names its rule id andauthority; a rule with no named authority does not ship, so every hit traces to a cited standard, never a house guess. A 4-space-indented code block—and any nested list item or list-continuation paragraph indented to that depth—is skipped whole too, the same miss-never-a-hit tradeemdash.mjsaccepts.
- 2b. Em-dash convention (
- Full (quality): judge bloat/clarity for the doc's audience and purpose. A cut proposal must not change meaning—quality fixes trim fat, never meat. Grammar/typo judgment runs in the doc's own language.
- Word-choice is a MEANING decision, not a typo: an unusual-but-intentional word, register, or voice gets flagged as SUSPECTED with a question, never "corrected".
- Severity by CONTEXT (never a fixed map), then honor
severityFloor: an ambiguous instruction readers must execute = HIGH; heavy bloat on a front-door doc = MEDIUM; a typo in prose = LOW, and an em-dash convention mismatch is LOW too—it is a style consistency finding, not a comprehension break (a typo inside a command or identifier is doc-grounding territory—it breaks, it does not just read badly).scanEverything: truebypasses the floor this run—report everything down tolow—and say so: state thatseverityFloorwas bypassed, never that every scope cut was bypassed (this canary has none to bypass).
Escalation boundary
Whether the CONTENT is true is doc-grounding; whether the doc is structurally broken is doc-structure. This canary only answers "does it read well and is the language well-formed".
Grants & denials (CLASSIFY-BLOCK)
| class | step it powers | grant | on denial |
| read | scan docs for mechanics + quality, against any house rules | Read·Grep·Glob (·Bash·Write for the run list—the emDash and script-mechanics engines run via node ./lib/emdash.mjs / ./lib/lang-mechanics.mjs, per Method steps 2b/2c; Read/Grep/Glob cannot execute either) | refuse that file, report it unscanned—never a false clean bill |
| write | Apply safe fixes (mechanics only) | Write·Edit (·Bash—checkpoint via git stash/commit) | report + courier the intended change to the dispatcher; never claim applied |
A denial reaches the WORKER as a visible message and propagates NO further—not to the dispatcher, not as a catchable condition. Every row above states a branch or an explicit death; a step that dies says so in the output. Never report a denied step as done, skipped, or clean.
Output
| # | path:line | axis | finding | severity | fix |
CONFIRMED table only; SUSPECTED (style/word-choice questions) as a separate list, never the main table.
Reporting: call ReportFindings when callable—file/line MUST be the defect site, never a paraphrase; an unresolvable line reports your best guess, named imprecise in the wrap-up, never dropped. Severity prefixed in summary (e.g. [HIGH] …) per the severity-by-context rule above, ranked most-severe first, SUSPECTED (style/word-choice) as verdict: PLAUSIBLE; chat then carries only the wrap-up line (counts · SUSPECTED list · overflow past 32) + the fix menu, never a restatement. Not callable → the table above, unchanged. An Apply-fixes click = consent to the Apply-safe-fixes class below (mechanics only), composing with—never bypassing—Fix mode. After any fix round, re-report the same findings with outcome: fixed/skipped/no_change_needed.
Fix mode (choice-gated)
After any report in an interactive session you MUST present this menu via your question tool (skip only when findings are zero or no user is present). NEVER auto-fix a live doc.
- Apply safe fixes: mechanics only (recompose characters, collapse doubled spaces, unify punctuation per the house rule, add/remove the single space around an em-dash to match the configured
emDashconvention—never touch a hit inside a fenced/inline-code, URL, Thai, blockquote, or LICENSE/NOTICE/COPYING-class exclusion, since the engine never reported one there). Each fix: checkpoint (git stash/commit in a git repo; else copy the file aside—never assume git exists) -> apply -> re-read the changed lines -> re-run the engine on the file (emDashfindings only) -> revert if new findings appeared. - Let me pick: list findings (including proposed prose trims, shown as before/after); the user selects.
- Report only: exit unchanged.
NEVER auto-fix: any prose rewrite, cut, or word-choice change—meaning belongs to the author.
Multilingual
Mechanics checks are per-language deterministic (normalization and spacing rules exist per script, not per English). Semantic quality judgment works in the doc's language and degrades to low-confidence SUSPECTED flags on a poorly-handled language, never false alarms.
Problem report
If this canary misbehaves, OFFER to file it at https://github.com/TheColliery/CoalLedger/issues with a user-reviewed summary—never auto-submit.
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.

