BOHICA-LABS / BOHICA-LABS/vsdd-factory
feat: CLAUDE.md health-check + threshold-driven compaction (mirror STATE.md size governance)
- Dominant language
- Rust
- Stars
- 2
- Forks
- 1
- Avg merge
- 6h 43m
- Merged PRs (30d)
- 29
Description
## Summary
vsdd-factory has a mature **STATE.md** size-governance system (warn/critical thresholds, a PostToolUse hook, a health-check skill, and a compaction skill that externalizes history to cycle files). It has **no equivalent for CLAUDE.md** — only `scaffold-claude-md`, which *generates* a CLAUDE.md but never measures or compacts it.
Because CLAUDE.md is loaded **in full into every session's context**, an unbounded CLAUDE.md is arguably a bigger context-rot liability than STATE.md. This proposes a parallel **CLAUDE.md health-check + compaction** capability that mirrors the STATE.md pattern and delegates the actual rewrite to Anthropic's official `claude-md-management` tooling driven by a VSDD-specialized prompt.
## Motivation / evidence
External research (sources below) — flagged honestly as **mostly community/blog heuristics, not authoritative Anthropic benchmarks**:
- **Context rot is real and continuous, not cliff-like.** Chroma's 2025 study (18 frontier models incl. Claude Opus 4) shows quality degrades as input grows, well before the max window. Anthropic's own context-engineering guidance: curate, don't dump.
- **CLAUDE.md size thresholds (community consensus, soft evidence):** measurable degradation begins ~**150 lines** (~4.5–5.5k tokens / 8–12 KB); severe ~**250 lines** (~7.5–8.75k tokens / 14–18 KB). High-performers sit at **60–100 lines**. Anthropic's docs recommend keeping CLAUDE.md **under ~200 lines**. *(No single authoritative Anthropic number for "warning/critical" exists — these are blog/community figures: TurboDocx, Buildcamp, dometrain, HN threads. Treat the percentages in those posts skeptically.)*
- **There is no native "compact CLAUDE.md".** `/compact` operates on **conversation history**, not CLAUDE.md. The closest official mechanism is the **`claude-md-management` plugin** (`claude-md-improver` audit/score + targeted-update workflow), plus `#`, `/init`, `/memory`. CLAUDE.md is treated as persistent human-curated config, deliberately *not* auto-summarized.
Real-world trigger: compacting a downstream project's CLAUDE.md from **391 → 250 lines (−36%)** by collapsing reproduced deep-dives to "load-bearing rule + pointer" and externalizing detail to ADRs / research notes — done manually with `claude-md-improver`. vsdd should make this a first-class, threshold-driven capability.
## Existing STATE.md mechanism to mirror
| Component | STATE.md (exists) | CLAUDE.md (proposed) |
|---|---|---|
| PostToolUse size hook | `hooks/validate-state-size.sh` — WARN >200, BLOCK >500, allows writes that **reduce** size (compaction-in-progress via `git show HEAD` compare) | `hooks/validate-claude-md-size.sh` — WARN/CRITICAL (see below), same "reduced size → allow" escape |
| Health-check skill | `check-state-health` → HEALTHY / WARNING / NEEDS-COMPACT | `check-claude-md-health` (or extend `check-state-health`) |
| Compaction skill | `compact-state` → extracts history to `cycles//*.md`, slims to <200 | `compact-claude-md` → delegates to `claude-md-improver` w/ VSDD prompt |
| Generator | `scaffold-claude-md` | (unchanged) |
## Proposal
### 1. `validate-claude-md-size.sh` (PostToolUse hook)
Fire on Write/Edit to any `CLAUDE.md`. Mirror the STATE hook's structure, **including the "this write reduced the line count → exit 0" compaction-in-progress escape**, so the compaction skill can rewrite without tripping its own gate.
Recommended thresholds (CLAUDE.md-specific, **lower than STATE's 200/500** because CLAUDE.md degrades earlier per context-rot research):
- **WARN at >150 lines** (stderr advisory; non-blocking)
- **CRITICAL at >250 lines**
**Open question — block vs. advise at critical:** STATE.md is factory-owned, so it hard-BLOCKs at 500. CLAUDE.md is **human-authored**; a hard block on a user editing their own file is hostile. Recommendation: **advisory-only at critical** (loud stderr + suggest `/vsdd-factory:compact-claude-md`), reserving hard-block for an opt-in strict mode. Token-based thresholds (≈5k warn / ≈8k critical) are a more robust alternative to raw line counts — worth supporting both.
### 2. `check-claude-md-health` skill
Diagnostic, read-only. Reports **HEALTHY / WARNING / NEEDS-COMPACT** plus a content-quality pass borrowing `claude-md-improver`'s six-dimension rubric (commands, architecture, non-obvious patterns, conciseness, currency, actionability) and the A–F score. Run at session start alongside `factory-health` / `check-state-health`, and before convergence gates.
### 3. `compact-claude-md` skill — **leverages the Anthropic tool with a specialized prompt**
Rather than reimplement compaction, **invoke `claude-md-management:claude-md-improver`** (the official audit + targeted-update workflow) but drive it with a **VSDD-aware system prompt** that encodes:
- **"Load-bearing rule + pointer" principle** — keep the invariant + 1 line; move the deep-dive out.
- **VSDD-aware routing targets** — externalize detail to the *right* place:
- architectural rationale → **ADRs** (`docs/adr/…`), referenced by ID
- research/verification narratives → **`.factory/research/*.md`**
- pipeline/run history, decisions, lessons → **STATE.md / `cycles//*.md`** (NOT CLAUDE.md)
- path-scoped conventions → **`.claude/rules/`** with `paths:` frontmatter
- module-specific context → **subdirectory `CLAUDE.md`** (lazy-loaded)
- large procedures → **skills** (metadata-only until invoked)
- **Preserve test-pinned literals** — never drop strings referenced by tests/CI/registrations (the manual run had to retain exact literals like ticket IDs, ports, env-var seam names).
- **Show diffs, get confirmation, never delete content silently** — only relocate, exactly like `compact-state`'s safety contract.
### 4. Content-routing guidance (the "some of it belongs in STATE, not CLAUDE.md" point)
Document the boundary explicitly so authors (and agents) stop accreting run/pipeline narrative into CLAUDE.md:
- **CLAUDE.md** = stable, project-wide, load-bearing rules + pointers; loaded every session.
- **STATE.md / cycle files** = pipeline run state, decisions, burst/adversary history, lessons.
- **ADRs / research / specs** = the deep "why" and verification detail.
## Acceptance criteria
- [ ] PostToolUse hook warns >150 / flags critical >250 lines on any `CLAUDE.md`, and **does not fire when a write reduces size** (compaction-in-progress).
- [ ] `check-claude-md-health` reports HEALTHY/WARNING/NEEDS-COMPACT + quality grade; wired into session-start health checks.
- [ ] `compact-claude-md` delegates to `claude-md-improver` with the VSDD routing prompt, shows diffs, requires confirmation, never deletes (only relocates), and preserves test-pinned literals.
- [ ] Thresholds configurable (line- or token-based); critical defaults to advisory, hard-block behind opt-in.
- [ ] Docs state the CLAUDE.md vs STATE.md vs ADR/research content boundary.
## Notes / decisions to settle
1. New `compact-claude-md` skill vs. extending `scaffold-claude-md` into a `manage-claude-md` skill?
2. Line-count vs token-count thresholds (or both)? Tokens are more robust but need a tokenizer/estimate.
3. Hard-block at critical, or advisory-only for human-authored CLAUDE.md?
4. Should `claude-md-management` be a declared dependency, or invoked best-effort if installed (graceful skip otherwise)?
## Sources
Chroma "Context Rot" (2025); Anthropic "Effective context engineering for AI agents"; Anthropic `claude-plugins-official/claude-md-management` (`claude-md-improver` SKILL); Claude Code docs (memory, costs, context-window, compaction); TurboDocx, Buildcamp, dometrain, SFEIR, HN threads (community heuristics — treat numeric claims as soft).
Contributor guide
Assessment
This issue has not been assessed yet.