Skip to content
2 changes: 1 addition & 1 deletion docs/SKILL-CHEAT-SHEET.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ owned by [docs/CATALOG-TAXONOMY.md](CATALOG-TAXONOMY.md).
| [`/disk-hygiene:clean`](../plugins/disk-hygiene/skills/clean/SKILL.md) | `disk-hygiene` | Audit a directory tree for stale leftovers and remove validated paths |
| [`/docs-hygiene:audit-derivability`](../plugins/docs-hygiene/skills/audit-derivability/SKILL.md) | `docs-hygiene` | Judge whether a doc earns its existence or should become a pointer |
| [`/docs-hygiene:audit-encapsulation`](../plugins/docs-hygiene/skills/audit-encapsulation/SKILL.md) | `docs-hygiene` | Find external citations reaching into a skill's private surfaces |
| [`/docs-hygiene:audit-noise`](../plugins/docs-hygiene/skills/audit-noise/SKILL.md) | `docs-hygiene` | Classify markdown for stale citations, ghost refs, and meta-commentary |
| [`/docs-hygiene:audit-noise`](../plugins/docs-hygiene/skills/audit-noise/SKILL.md) | `docs-hygiene` | Classify markdown for citations, ghost refs, meta-commentary, plan/conversational/tracker residue |
| [`/docs-hygiene:audit-progressive-disclosure`](../plugins/docs-hygiene/skills/audit-progressive-disclosure/SKILL.md) | `docs-hygiene` | Grade instruction files for split opportunities and hub/spoke disclosure defects |
| [`/docs-hygiene:compress`](../plugins/docs-hygiene/skills/compress/SKILL.md) | `docs-hygiene` | Tighten markdown by dropping flavor while preserving every directive |
| [`/docs-hygiene:extract-ssot`](../plugins/docs-hygiene/skills/extract-ssot/SKILL.md) | `docs-hygiene` | Deduplicate repeated prose into one named source of truth |
Expand Down
2 changes: 1 addition & 1 deletion plugins/docs-hygiene/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
"name": "docs-hygiene",
"version": "0.19.2",
"version": "0.20.0",
"description": "Documentation-hygiene toolkit: compress (flavor-trim markdown with a semantic-diff safety net), audit-noise (classify markdown noise), extract-ssot (deduplicate repeated content into a single source of truth), audit-encapsulation (detect citations into skill-private surfaces), rename-references (sweep stale references after renames), audit-derivability (classify whether a whole document earns its existence — could a fresh agent re-derive it from the code?), audit-progressive-disclosure (grade instruction files against a load-tier model for split opportunities and hub/spoke disclosure defects), write-for-agents (authoring-time doctrine that fires while agent-consumed markdown is being written), and write-for-humans (the same moment for the other reader — end-user READMEs, RFCs, release notes and guides — resolving the consuming project's own style guide first).",
"author": {
"name": "Melodic Software",
Expand Down
67 changes: 67 additions & 0 deletions plugins/docs-hygiene/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,72 @@
# Changelog — docs-hygiene plugin

## [0.20.0]

### Added

- **`audit-noise` gains the three residue shapes markdown had no owner for (#3125).** The code-side
sibling `/code-tidying:audit-comment-residue` detects four residue shapes; this skill detected
five noise shapes; the two sets did not tile the space. Only `history-narration` had a markdown
counterpart (this skill's `citation`). `plan-reference`, `conversational-antecedent`, and
`ticket-pr-residue` had **no detector on either side of the boundary**, so a README, rule body, or
`CLAUDE.md` saying "as you asked, retry three times" or "see PR #45 for the rationale" was
invisible to the whole fleet — not because a file type was skipped, but because of a gap behind an
otherwise correct boundary. `audit-noise` is now an eight-shape classifier: `plan-reference` and
`conversational-antecedent` at Tier 1, `ticket-pr-residue` at Tier 2.

**The shapes went to `audit-noise` rather than widening the code skill to `.md`**, and the reason
is a treatment conflict, not a preference. On a markdown line the code skill's `history-narration`
and this skill's `citation` fire together with opposite rulings — `citation` says relocate to a
`## Sources` footer, `history-narration` says delete. Two owners for one line is a precedence
problem; one owner per file type is not. So the boundary is now explicitly by FILE TYPE, with the
three shape *names* deliberately shared so one authoring failure keeps one name wherever it lands.
The shapes also inherit this skill's more mature target router (`--paths-file`, offset/limit
pagination, space-safe porcelain parsing) for free.

**The patterns are adapted, not copied, and the adaptation is the substance of the change.** The
code lib classifies only the extracted *comment* portion of a line; this one classifies whole
prose, where the same words are load-bearing far more often. Measured against this repository's
own 1136-file tracked-markdown corpus, four of the sibling's cues had to go: `per the plan`
prefix-matches "per the planning chapter" (and a doc citing a plan artifact that still exists is a
live cross-reference, not residue); `as planned` is a substring of "was planned", so "what was
planned, what was done instead" self-matched; `in this change` and `in this session` are ordinary
domain vocabulary in an agent-tooling corpus. `in this PR` survives only with a first-person actor
behind it, which is what separates narration ("in this PR we switch the default") from a live
referent ("the files changed in this PR"). `as we discussed` stands down in front of an anaphoric
follower (`above`, `below`, `in §3`), which makes it an intra-document cross-reference. Those
tightenings cut the corpus delta from 32 findings to 12.

**`conversational-antecedent`'s follower test asks what the reference points AT**, rather than
which preposition introduces it. A bare `in` exemption would have spared "as we decided in the
ADR" (right) and "as we decided in favor of X" or "as we discussed in yesterday's meeting"
(wrong — the referent there is the conversation, not a document), so `in` stands the shape down
only ahead of a document locator: a `§` or `#anchor`, a section/chapter/step/table, a link or
path, an inline-code reference the strip removed, or a named durable document. Tracker nouns are
deliberately absent from that set — a decision parked in an issue is provenance, which
`ticket-pr-residue` owns and this shape must not launder — as are nouns for the conversation
itself. Followers are compared case-insensitively, so a capitalised `Above` no longer falls
through. Both first-person actor tests — this one and `plan-reference`'s `in this PR` — admit a
contracted pronoun in either the straight or the typographic (U+2019) apostrophe, so
"in this PR we've already switched the default" and "as we've discussed" no longer escape the
shape they are; `conversational-antecedent` admits only `'ve` and `'d`, the two auxiliaries its
past-participle follower can take, which keeps the present-tense passive "as you're asked" out.

**The actor-less passive `As requested, …` is the same shape without the pronoun**, and it is
matched only as a clause-final adverbial. That bound is what keeps the live attribution "as
requested by the client" and the ordinary verb phrase "was requested" out, without a second
pattern to maintain; a closing quote does not count as the clause break, because behind one the
words are a quoted voice rather than the page's own address to its reader.

**`ticket-pr-residue`'s carve-out is restated in markdown terms** rather than inherited: a task-list
checklist item (`- [ ] … #123`) and a `TODO(#123)`-family marker are never flagged, because both
denote OUTSTANDING tracked work — the reference is the actionable part of the line — which is what
the code skill's sanctioned-`TODO` exception is actually about. Nothing further is carved out: the
sanctioned home for a *provenance* citation is a `## Sources` / `## History` footer, and the
existing section exemptions already skip those (as they skip `CHANGELOG.md`, fenced blocks, and
frontmatter) before any shape runs, so re-implementing that as a pattern would duplicate a rule
that already holds. An inline parenthetical (`… (tracked in #482)`) stays Tier 2 on purpose, so a
reviewer rules on it rather than the scanner.

## [0.19.2]

### Changed
Expand Down
2 changes: 1 addition & 1 deletion plugins/docs-hygiene/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ and authoring axes of doc upkeep.
| Skill | What it does |
|---|---|
| `/docs-hygiene:compress` | Tightens markdown by dropping flavor (filler, hedging, articles) while preserving all content, behind a mandatory fresh-context semantic-diff audit that reverts any semantic loss. Supports an optional `caveman` plugin backend (`/caveman:compress`) with a built-in in-session fallback. |
| `/docs-hygiene:audit-noise` | Read-only classifier for five markdown noise shapes (historical citations, ghost refs to ephemeral working directories, "why this file exists" preambles, hard-coupled consumer lists, scope/loading meta-commentary) with tiered findings and per-shape treatment guidance. |
| `/docs-hygiene:audit-noise` | Read-only classifier for eight markdown noise shapes (historical citations, ghost refs to ephemeral working directories, "why this file exists" preambles, hard-coupled consumer lists, scope/loading meta-commentary, plan/changeset references, conversational antecedents, tracker/PR back-references) with tiered findings and per-shape treatment guidance. |
| `/docs-hygiene:extract-ssot` | Deduplicates repeated content into a single named source of truth and migrates call sites to cite it by heading. Reports duplication at every multiplicity in three labelled buckets — a lone recap of an existing SSOT, a drifting pair with no declared owner, and clusters that meet the Rule of Three — while refuse-fast verification gates (Rule of Three, Tier-0 evidence) keep *creating* a new artifact reserved for 3+ instances; below that, only non-abstracting remedies are offered. |
| `/docs-hygiene:audit-encapsulation` | Detects external citations reaching into skill-private surfaces inside `.claude/skills/<name>/` (private subdirectories, heading anchors, schema files) and routes each violation to a remediation path. Ships its own public-surface contract reference. |
| `/docs-hygiene:rename-references` | Sweeps stale references after renames — the forms plain token grep misses: slash-command tokens, relative paths from moved files, frontmatter chains and globs — via a 12-form pattern library with audit, half-rename detection, and apply modes. |
Expand Down
Loading