100 lines
4.5 KiB
Markdown
100 lines
4.5 KiB
Markdown
# 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
|
|
|
|
1. **Deterministic-first** — scan, state, patch-apply, and token-estimate are
|
|
scripts (no model). AI does only classification and prose distillation.
|
|
2. **Remind, don't nag** — the `SessionStart` hook only reminds; it never runs
|
|
analysis or mutates anything. All mutation is user-invoked. Reminders snooze
|
|
(at most once/day while stale).
|
|
3. **Non-intrusive** — state lives in-project under a gitignored `.dochygiene/`;
|
|
no global index. The tool never silently edits the user's repo.
|
|
4. **Git-safe cleanup** — runs only on a clean/committed tree (or after an auto
|
|
WIP checkpoint); each run lands as one reviewable commit.
|
|
5. **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 `SessionStart`
|
|
hook declared in `hooks/hooks.json`, emitting a `systemMessage` banner).
|
|
- **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`). `auto` runs 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/`) plus `invariants.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 `SessionStart` hook spends no AI tokens, never mutates, keeps `timeout`
|
|
low (≤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: frozen` frontmatter, `.dochygiene-ignore`,
|
|
append-only logs) are never flagged.
|
|
- Changing any behavioral invariant requires updating `invariants.md` and the
|
|
golden examples, with explicit human approval.
|
|
|
|
## External Dependencies
|
|
|
|
- Claude Code plugin/hook runtime (`hooks/hooks.json`, `systemMessage` banner).
|
|
- A local tokenizer approximation for the token estimator (no API token
|
|
counting at check time).
|