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), the doc language's own 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): if off, skip this step entirely—never invoke the engine, never report a finding. Otherwise, the engine ships INSIDE this skill folder at ./lib/, so the skill works even when it travels alone. Your context carries this skill's base directory—substitute it for <skill base dir> and run exactly:
cd "<skill base dir>" && node ./lib/emdash.mjs --mode=<unspaced|spaced> <absolute-file.md> [more absolute paths ...]
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. --mode is the CONFIGURED emDash value verbatim (never off — that branch already returned above). Output is file:line:col: context per hit, one line per finding; a bare TOTAL: N line closes the run. 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).
- 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: 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)
| class |
step it powers |
grant |
on denial |
| read |
scan docs for mechanics + quality, against any house rules |
Read·Grep·Glob (·Bash—the emDash engine runs via node ./lib/emdash.mjs, per Method step 2b; Read/Grep/Glob cannot execute it) |
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
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.
1---2name: doc-quality3description: 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.4---56# Doc-Quality78Answer in the USER'S language; keep technical terms, commands, paths, and check ids verbatim.910Find what makes a doc hard to read or mechanically malformed. Report CONFIRMED findings; style opinions stay SUSPECTED.1112## Parameters13- **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).14- **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.1516## The two axes17| axis | layer | catches |18|---|---|---|19| 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), the doc language's own spacing/orthography rules, obvious misspellings |20| quality | semantic | filler and repetition (the same point twice), walls of text, buried leads, unexplained jargon for the doc's audience, ambiguous instructions |2122## Method231. **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.242. **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.25 - **2b. Em-dash convention (`emDash`, `.coalledger.json`, global + project merge):** if `off`, skip this step entirely—never invoke the engine, never report a finding. Otherwise, the engine ships INSIDE this skill folder at `./lib/`, so the skill works even when it travels alone. Your context carries this skill's **base directory**—substitute it for `<skill base dir>` and run exactly:26 `cd "<skill base dir>" && node ./lib/emdash.mjs --mode=<unspaced|spaced> <absolute-file.md> [more absolute paths ...]`27 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. `--mode` is the CONFIGURED `emDash` value verbatim (never `off` — that branch already returned above). Output is `file:line:col: context` per hit, one line per finding; a bare `TOTAL: N` line closes the run. 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).283. **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.294. **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".305. **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).3132## Escalation boundary33Whether 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".3435## Grants & denials (CLASSIFY-BLOCK)36| class | step it powers | grant | on denial |37|---|---|---|---|38| read | scan docs for mechanics + quality, against any house rules | `Read`·`Grep`·`Glob` (·`Bash`—the `emDash` engine runs via `node ./lib/emdash.mjs`, per Method step 2b; `Read`/`Grep`/`Glob` cannot execute it) | refuse that file, report it unscanned—never a false clean bill |39| 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 |4041A 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.4243## Output44| # | path:line | axis | finding | severity | fix |4546CONFIRMED table only; SUSPECTED (style/word-choice questions) as a separate list, never the main table.4748**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`.4950## Fix mode (choice-gated)51After 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.5253- **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.54- **Let me pick:** list findings (including proposed prose trims, shown as before/after); the user selects.55- **Report only:** exit unchanged.5657NEVER auto-fix: any prose rewrite, cut, or word-choice change — meaning belongs to the author.5859## Multilingual60Mechanics 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.6162## Problem report63If this canary misbehaves, OFFER to file it at <https://github.com/TheColliery/CoalLedger/issues> with a user-reviewed summary — never auto-submit.