4.5 KiB
4.5 KiB
Project Context
Purpose
doc-hygiene is a Claude Code plugin that monitors and manages stale and
bloated project documentation. It is installed globally but operates
per-project. It reminds the developer (deterministically, zero AI tokens) on
SessionStart when docs haven't been checked recently, then checks and cleans
on demand via skills.
The plugin holds a core distinction:
- Stale = the doc is wrong (contradicted, orphaned, superseded, provisional, completed-in-place, duplicated). Remedy: fix or remove.
- Bloat = the doc is true but mostly irrelevant (distill, split, freeze). Remedy: change its altitude, almost never delete history.
Severity scales with injection frequency — a stale line in an auto-injected
file (CLAUDE.md, memory index) misleads every session, so it is worse than the
same line in a doc nobody opens.
Design Principles
- Deterministic-first — scan, state, patch-apply, and token-estimate are scripts (no model). AI does only classification and prose distillation.
- Remind, don't nag — the
SessionStarthook only reminds; it never runs analysis or mutates anything. All mutation is user-invoked. Reminders snooze (at most once/day while stale). - Non-intrusive — state lives in-project under a gitignored
.dochygiene/; no global index. The tool never silently edits the user's repo. - Git-safe cleanup — runs only on a clean/committed tree (or after an auto WIP checkpoint); each run lands as one reviewable commit.
- The tool must not become the bloat it polices — report rollover keeps only the latest report.
Tech Stack
- Plugin format: Claude Code plugin (skills + commands + a
SessionStarthook declared inhooks/hooks.json, emitting asystemMessagebanner). - Language: Python, OOP — small single-responsibility classes, dependency injection, immutable transforms where possible.
- Scripts: structured JSON output, correct exit codes, idempotent, testable in isolation with injected clock/filesystem.
- AI layers: classification = Sonnet (hard cases → Opus); generative distillation = Sonnet (explicitly not Haiku); orchestration = Opus.
Project Conventions
Code Style
- Small composable single-responsibility classes; dependency injection for testability; immutable transforms where practical.
- Scripts emit structured JSON and correct exit codes; deterministic and idempotent.
Architecture Patterns
- Deterministic / AI split: the deterministic scanner gathers objective signals and a candidate shortlist; the AI pass classifies and distills.
- Report schema is the linchpin: the machine report (per-file category, signals, op, op-type, safety tier, optional exact-edit, token estimate) is the contract every component consumes. It is designed and frozen first.
- Operation taxonomy: each op is tagged op-type (
deterministic|generative) and safety tier (auto|confirm).autoruns without prompt;confirm(destructive/subjective/generative) escalates for approval. - mtime guard: never apply a cached edit to a file changed since the check.
Testing Strategy
- Assert external behavior at the highest deterministic seam — given an input doc tree / state file / report, the script produces correct structured output and exit code. Do not assert internal class structure.
- The AI classification layer is pinned by golden examples
(
examples/golden/) plusinvariants.md, per the reversion-protection pattern — not by unit assertions.
Git Workflow
- Cleanup requires a clean/committed working tree, or auto-commits a WIP checkpoint first; each cleanup run lands as a single reviewable commit.
confirm-tier approvals are recorded to a decisions log.- No pushing or outbound/network actions — cleanup is local commits only.
Important Constraints
- The
SessionStarthook spends no AI tokens, never mutates, keepstimeoutlow (≤5s), and always exits 0 (never blocks the session). - State and the single most-recent report live under gitignored
.dochygiene/; the scanner always self-excludes it. - Frozen/ignored files (
hygiene: frozenfrontmatter,.dochygiene-ignore, append-only logs) are never flagged. - Changing any behavioral invariant requires updating
invariants.mdand the golden examples, with explicit human approval.
External Dependencies
- Claude Code plugin/hook runtime (
hooks/hooks.json,systemMessagebanner). - A local tokenizer approximation for the token estimator (no API token counting at check time).