Docs Drift
When invoked, check whether this plugin's documentation still matches its
code, then propose fixes. "Drift" is anything a doc claims that the repo no
longer backs up: a skill missing from a catalog table, a dead link, a README
sentence that describes behaviour the skill no longer has, a dependency list
that no longer matches requirements.txt.
Two layers, in order: a deterministic script that proves mechanical drift,
then a semantic pass that only an LLM can do. Report both, fix on approval.
When to invoke
- Manual only. The user asks to check docs drift / doc accuracy, or runs
/docs-drift. Typically right after adding, renaming, or removing a skill,
command, or agent.
- Never auto-invoke, and never edit any file before the user approves.
Workflow
Step 1 — Run the mechanical checker
It is standard-library Python — no install needed.
python ${CLAUDE_PROJECT_DIR}/.claude/skills/docs-drift/scripts/check_docs_drift.py --json
The script resolves the repo root via git (or --root DIR) and reports, as
JSON, every mismatch it can prove:
- skill-catalog — a skill in
skills/ missing its
docs/knowledge/skills/<name>-index.md, its README "Skills in this plugin"
row, or its codemap "Skill indexes" row; frontmatter name not matching the
directory.
- command-catalog — a
commands/<slug>.md not listed in the README
"Slash commands" table.
- skill-command — an exported skill that no
commands/*.md mentions
(every exported skill ships a slash command; slugs may differ from skill
names).
- orphan — an index file pointing at a skill that no longer exists.
- dead-link — a relative markdown link whose target file is gone.
- english-only — a file containing CJK/Kana/Hangul (GR-1); a warning,
since a quoted non-English source is allowed.
- manifest-sync —
plugin.json's description differing from the
plugin's entry in marketplace.json.
- version-bump — functional files changed vs
HEAD without a
plugin.json version bump; a warning.
errors block a clean bill of health; warnings may have legitimate
exceptions (judge each). Use the human-readable form (drop --json) if you
just want to read it.
Step 2 — Semantic pass (what the script cannot check)
The script proves structural facts; it cannot read meaning. Do this part
yourself. For each skill, open its SKILL.md and compare against:
- its one-line description in the README "Skills in this plugin" table,
- its row in
docs/knowledge/codemap.md and its
docs/knowledge/skills/<name>-index.md,
- its dependency claims in the README and the skill's own
README.md
versus the actual scripts/requirements.txt (or "no dependencies" claims
versus whether a requirements.txt exists),
- the slash-command description in
commands/<slug>.md versus what the
skill now does.
Also sanity-check the cross-cutting docs against reality:
README.md "Repository layout" tree — does it still match the real tree
(new top-level dirs/files, renamed ones)?
docs/knowledge/architecture.md — does the "LLM understands / script
transforms" description still hold for every skill, including any new one?
docs/knowledge/codemap.md "Dev tooling" table — are all hooks/scripts
listed?
Flag a semantic drift only when the prose genuinely no longer fits the code —
not for harmless wording differences.
Step 3 — Propose fixes
Present, in chat:
- Mechanical findings — the script's errors and warnings, each with the
exact file + the one-line fix.
- Semantic findings — the description/code mismatches you found, quoting
the stale sentence and the corrected wording.
- Where each fix goes — exact file and table/section.
Then ask the user to approve. They may take a subset, edit wording, or
decline.
Step 4 — Apply approved fixes
Only after approval:
- Edit only the docs. Do not change skill behaviour or scripts to make a doc
true — fix the doc to match the code (unless the user says the code is what
drifted, in which case confirm before touching code).
- Match each file's existing table shape, heading style, and tone.
- If a version bump is warranted (per the user's global rules, adding or
changing a feature is a minor bump), update
.claude-plugin/plugin.json.
Step 5 — Re-run and report
Re-run the checker to confirm it now exits clean, then tell the user what was
changed and in which files so they can review the diff.
Notes
- The script is the single source of truth for mechanical checks — the Stop
hook (
.claude/hooks/check-docs-drift.sh) runs the same script whenever a
turn ends with uncommitted changes to catalog files (detected via
git status), so mechanical drift is caught even when this skill is not
explicitly invoked. This skill adds the semantic pass and the guided fix-up.
- The script is a plain CLI:
--json for machine output, --strict to treat
warnings as errors (handy in CI), --root DIR to point at another checkout.
- Read-first, write-on-approval: the analysis stays in chat; only approved
edits are persisted.
- This skill lives in
.claude/skills/ (project-level), not skills/ — it is
repo-internal dev tooling and is not exported to users who install the
plugin.
1---2name: docs-drift3description: Use when the user wants to verify this plugin's docs are still in sync with its code after a change — e.g. "check for docs drift", "did the README drift", "are the docs still accurate", "I updated the plugin, verify the docs", "/docs-drift". Runs a deterministic checker for mechanical drift (skill/command catalogs in README and codemap, per-skill index files, dead relative links, English-only rule, version bump) and then does a semantic pass the script cannot — comparing each doc's prose description against what the skill actually does and the dependencies it actually ships. Proposes concrete fixes and only edits docs after the user approves. Manual-trigger only — never auto-invoke; never edit files without approval.4---56# Docs Drift78When invoked, check whether this plugin's **documentation still matches its9code**, then propose fixes. "Drift" is anything a doc claims that the repo no10longer backs up: a skill missing from a catalog table, a dead link, a README11sentence that describes behaviour the skill no longer has, a dependency list12that no longer matches `requirements.txt`.1314Two layers, in order: a deterministic **script** that proves mechanical drift,15then a **semantic pass** that only an LLM can do. Report both, fix on approval.1617## When to invoke1819- **Manual only.** The user asks to check docs drift / doc accuracy, or runs20 `/docs-drift`. Typically right after adding, renaming, or removing a skill,21 command, or agent.22- **Never auto-invoke**, and **never edit any file before the user approves.**2324## Workflow2526### Step 1 — Run the mechanical checker2728It is standard-library Python — no install needed.2930```bash31python ${CLAUDE_PROJECT_DIR}/.claude/skills/docs-drift/scripts/check_docs_drift.py --json32```3334The script resolves the repo root via `git` (or `--root DIR`) and reports, as35JSON, every mismatch it can prove:3637- **skill-catalog** — a skill in `skills/` missing its38 `docs/knowledge/skills/<name>-index.md`, its README "Skills in this plugin"39 row, or its codemap "Skill indexes" row; frontmatter `name` not matching the40 directory.41- **command-catalog** — a `commands/<slug>.md` not listed in the README42 "Slash commands" table.43- **skill-command** — an exported skill that no `commands/*.md` mentions44 (every exported skill ships a slash command; slugs may differ from skill45 names).46- **orphan** — an index file pointing at a skill that no longer exists.47- **dead-link** — a relative markdown link whose target file is gone.48- **english-only** — a file containing CJK/Kana/Hangul (GR-1); a *warning*,49 since a quoted non-English source is allowed.50- **manifest-sync** — `plugin.json`'s `description` differing from the51 plugin's entry in `marketplace.json`.52- **version-bump** — functional files changed vs `HEAD` without a53 `plugin.json` version bump; a *warning*.5455`errors` block a clean bill of health; `warnings` may have legitimate56exceptions (judge each). Use the human-readable form (drop `--json`) if you57just want to read it.5859### Step 2 — Semantic pass (what the script cannot check)6061The script proves *structural* facts; it cannot read meaning. Do this part62yourself. For **each skill**, open its `SKILL.md` and compare against:6364- its **one-line description** in the README "Skills in this plugin" table,65- its **row** in `docs/knowledge/codemap.md` and its66 `docs/knowledge/skills/<name>-index.md`,67- its **dependency claims** in the README and the skill's own `README.md`68 versus the actual `scripts/requirements.txt` (or "no dependencies" claims69 versus whether a `requirements.txt` exists),70- the **slash-command** description in `commands/<slug>.md` versus what the71 skill now does.7273Also sanity-check the cross-cutting docs against reality:7475- `README.md` "Repository layout" tree — does it still match the real tree76 (new top-level dirs/files, renamed ones)?77- `docs/knowledge/architecture.md` — does the "LLM understands / script78 transforms" description still hold for every skill, including any new one?79- `docs/knowledge/codemap.md` "Dev tooling" table — are all hooks/scripts80 listed?8182Flag a semantic drift only when the prose genuinely no longer fits the code —83not for harmless wording differences.8485### Step 3 — Propose fixes8687Present, in chat:88891. **Mechanical findings** — the script's errors and warnings, each with the90 exact file + the one-line fix.912. **Semantic findings** — the description/code mismatches you found, quoting92 the stale sentence and the corrected wording.933. **Where each fix goes** — exact file and table/section.9495Then ask the user to approve. They may take a subset, edit wording, or96decline.9798### Step 4 — Apply approved fixes99100Only after approval:101102- Edit only the docs. Do not change skill behaviour or scripts to make a doc103 true — fix the doc to match the code (unless the user says the code is what104 drifted, in which case confirm before touching code).105- Match each file's existing table shape, heading style, and tone.106- If a version bump is warranted (per the user's global rules, adding or107 changing a feature is a minor bump), update `.claude-plugin/plugin.json`.108109### Step 5 — Re-run and report110111Re-run the checker to confirm it now exits clean, then tell the user what was112changed and in which files so they can review the diff.113114## Notes115116- The script is the single source of truth for mechanical checks — the Stop117 hook (`.claude/hooks/check-docs-drift.sh`) runs the same script whenever a118 turn ends with uncommitted changes to catalog files (detected via119 `git status`), so mechanical drift is caught even when this skill is not120 explicitly invoked. This skill adds the semantic pass and the guided fix-up.121- The script is a plain CLI: `--json` for machine output, `--strict` to treat122 warnings as errors (handy in CI), `--root DIR` to point at another checkout.123- Read-first, write-on-approval: the analysis stays in chat; only approved124 edits are persisted.125- This skill lives in `.claude/skills/` (project-level), not `skills/` — it is126 repo-internal dev tooling and is not exported to users who install the127 plugin.