agentleFS
TheCollieryTheColliery/CoalLedger/skills/doc-quality/SKILL.md

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.

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
  1. Distinctive:

    House rules first: if the project defines its own style or language rules (a style guide, formatting conventions, per-language orthography …

    line 24
  2. Very specific:

    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 …

    line 27
  3. Distinctive:

    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 …

    line 53
  4. Distinctive:

    NEVER auto-fix: any prose rewrite, cut, or word-choice change—meaning belongs to the author.

    line 59
  5. Very specific:

    If this canary misbehaves, OFFER to file it at <https://github.com/TheColliery/CoalLedger/issues> with a user-reviewed summary—never …

    line 65

≈ “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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

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

axislayercatches
language mechanicsmechanicaldecomposed 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
qualitysemanticfiller and repetition (the same point twice), walls of text, buried leads, unexplained jargon for the doc's audience, ambiguous instructions

Method

  1. 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.
  2. 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 reads emDash itself, never copy it into a command: when it is off the engine reads nothing and prints TOTAL: 0. Your context carries this skill's base directory—substitute it for <skill base dir>, then run exactly: 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 prints, {"root": "<absolute project folder>", "docs": ["<absolute doc path>", ...]}. Then run: cd "<skill base dir>" && node ./lib/emdash.mjs --list The cd is 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's root is 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 is file:line:col: context per hit, one line per finding; a bare TOTAL: N line closes the run. If any target file is unreadable, the closing line reads TOTAL: 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, same cd requirement, 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-period and ja-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|ko limits 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.mjs also exits 1 on a call with no file, where emdash.mjs exits 0), so the exit code never counts findings; the output shape is NOT 2b's: with --json one JSON array of { file, findings } entries, without it one file:line:col [rule] description | snippet line per finding and a closing N finding(s) across M file(s) line (no TOTAL: line); an unreadable file prints FAIL <file>: <reason> on stderr. Each --json entry names its rule id and authority; 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 trade emdash.mjs accepts.
  3. 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.
  4. 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".
  5. 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: true bypasses the floor this run—report everything down to low—and say so: state that severityFloor was 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)

classstep it powersgranton denial
readscan docs for mechanics + quality, against any house rulesRead·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
writeApply 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 emDash convention—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 (emDash findings 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.

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.