Claude
Skills
Sign in
Back

context-audit

Included with Lifetime
$97 forever

Audit CLAUDE.md and AGENTS.md files against research-backed best practices. Scores instruction budget usage, detects anti-patterns, checks for staleness, and generates concrete fix proposals. Treats CLAUDE.md and AGENTS.md equally. Use when user asks to audit, check, review, or optimize context files. Also use when user mentions "instruction budget" or "context file quality".

Security

What this skill does


# Context Audit

<context>
Agent context files (CLAUDE.md, AGENTS.md, .claude/rules/) are always-on prompt context injected at session start. Research established that:

- Frontier models follow ~150-200 instructions with reasonable consistency
- Claude Code's system prompt consumes ~50 instruction slots, leaving ~100-150 for user content
- Instruction adherence degrades linearly as count increases — affecting ALL instructions uniformly
- Context files that impose unnecessary requirements can reduce task success rates vs no context at all
- The most effective files are under 100 lines with high directive density

This skill audits context files and produces concrete fix proposals — not just scores, but exact changes with rationale, budget impact estimates, and confidence levels.

The workflow separates **deterministic checks** (file existence, import traversal, symlink detection — high confidence) from **heuristic judgment** (instruction counting, generic advice detection, rewrite proposals — medium confidence). This distinction is labeled in the output.
</context>

<constraints>
- Never auto-commit changes — always require explicit user approval
- Never delete content without presenting it to the user first
- Label every finding with its confidence source (deterministic vs heuristic)
- Use approximate counts (`~N`) for heuristic measurements, not false precision
- Treat CLAUDE.md and AGENTS.md identically — same methodology, same budget
- Do not flag Claude Code native references as stale (slash commands, skills, ${CLAUDE_PLUGIN_ROOT}, Task/Agent calls)
- Read reference files (default-behaviors.md, anti-patterns.md) before running heuristic checks
</constraints>

<workflow>

## Phase 1: Discovery & Import Resolution
**Type: Deterministic**

### 1.1 Find all context files

```bash
# Repo context files
find . -name "CLAUDE.md" -o -name "AGENTS.md" -o -name ".claude.local.md" 2>/dev/null | grep -v node_modules | grep -v .git/

# Rules files
ls .claude/rules/*.md 2>/dev/null

# Global context
ls ~/.claude/CLAUDE.md 2>/dev/null
```

### 1.2 Classify each file

| Type | Location | Always-on? |
|------|----------|-----------|
| Root | `./CLAUDE.md` or `./AGENTS.md` | Yes |
| Rules (path-scoped) | `.claude/rules/*.md` with `paths:` frontmatter | Only when matching files accessed |
| Rules (always-on) | `.claude/rules/*.md` without `paths:` frontmatter | Yes |
| Subdirectory | `packages/*/CLAUDE.md` etc. | Only when files in that dir accessed |
| Global | `~/.claude/CLAUDE.md` | Yes (all projects) |
| Local override | `.claude.local.md` | Yes (but gitignored) |

Check rules files for `paths:` in YAML frontmatter to classify as scoped vs always-on.

### 1.3 Detect symlinks and duplicates

```bash
# Check if any context files are symlinks
readlink -f ./CLAUDE.md 2>/dev/null
readlink -f ./AGENTS.md 2>/dev/null
```

If both CLAUDE.md and AGENTS.md exist:
- If one is a symlink to the other: note as best practice, audit the canonical file only
- If both are independent files: flag duplication risk, compare content hashes:
  ```bash
  md5sum ./CLAUDE.md ./AGENTS.md 2>/dev/null
  ```

### 1.4 Resolve @file imports

For each context file, scan for `@path/to/file` import patterns:
1. Read the file and extract all `@`-prefixed references that look like file paths
2. Resolve paths relative to the file's directory
3. Verify each imported file exists (`test -e`)
4. Read imported files and recursively check for further imports
5. Track import depth to detect circular references (max depth: 5)
6. Mark imported files as "always-on via import" — they count against the root budget

### 1.5 Build file inventory

Present inventory to user:

```
## File Inventory

| # | File | Type | Always-on? | Imported by | Lines |
|---|------|------|-----------|-------------|-------|
| 1 | ./CLAUDE.md | Root | Yes | — | 52 |
| 2 | .claude/rules/01-behavioral.md | Rules (always-on) | Yes | — | 18 |
| 3 | .claude/rules/skills/skill-patterns.md | Rules (scoped) | No (paths: **/skills/**) | — | 40 |
| ...
```

---

## Phase 2: Instruction Budget Scoring
**Type: Heuristic (LLM judgment)**

Read each always-on file and count directives.

### Counting methodology

A "directive" is a discrete behavioral instruction the model must track:

- **Bullet/list item with imperative verb** = 1 directive
  - "Use bun over npm" → 1
  - "Branch naming: feature/description, fix/description" → 1 (single constraint with examples)
- **Compound bullet** = count sub-directives
  - "Keep solutions minimal: no speculative features, error handling for impossible cases, or abstractions for one-time operations" → 3 sub-directives
  - Split on: semicolons, comma-separated imperative clauses, period-separated sentences
- **Prescriptive table row** = 1 directive per row
- **Code block** = 0 (reference data, not a directive)
  - Exception: if prefaced by "Run this..." or "Always execute...", the preface is the directive
- **Header** = 0 (organizational)
- **Context paragraph** without imperative verbs = 0 (informational)
- **YAML frontmatter** = 0

For imported files via `@file`, count their directives and attribute to the importing file's budget.

### Confidence

Directive counting is inherently approximate. Flag ambiguous items:
- "Is this a directive or context?" — when unclear, count it
- Compound instructions — note the split rationale
- State your confidence: HIGH (clear directives), MEDIUM (some ambiguity), LOW (mostly judgment calls)

### Scoring bands

These are heuristic guidelines from research, not hard limits:

| File Type | Comfortable | Elevated | High pressure |
|-----------|-------------|----------|---------------|
| Root context file | <80 directives | 80-120 | >120 |
| Root + all @imports | <100 | 100-130 | >130 |
| Rules file (path-scoped) | <30 | 30-50 | >50 |
| Rules file (always-on) | <20 | 20-40 | >40 |
| Subdirectory context file | <40 | 40-60 | >60 |
| **Total always-on surface** | **<100** | **100-150** | **>150** |

The "total always-on surface" is the critical metric — everything Claude loads at session start: root file + @imports + always-on rules + global CLAUDE.md.

---

## Phase 3: Deterministic Checks
**Type: Deterministic (mechanical verification)**

These are factual checks. Run them with high confidence.

### 3a. Stale file path references

Extract paths from backtick-wrapped content and prose. For each path:

```bash
# Check tracked files
git ls-files --error-unmatch "path/to/file" 2>/dev/null

# Check untracked files
test -e "path/to/file"
```

**Skip these** (valid at runtime, not verifiable now):
- Paths containing `${CLAUDE_PLUGIN_ROOT}` or other variable interpolation
- `~/.claude/` paths (user-specific)
- Paths inside code block examples (illustrative, not references)

### 3b. Stale command references

Extract commands from code blocks and inline backticks.

**For package manager commands** (`npm run X`, `bun run X`, `pnpm run X`, `yarn X`):
```bash
# Verify script exists in nearest package.json
cat package.json | grep -q '"X"' 2>/dev/null
```

**For npx/bunx commands**: verify package in dependencies.

**Do NOT flag as stale:**
- Slash commands (`/command-name`) — Claude Code native
- Skill invocations (`Skill(skill: "name")`) — Claude Code native
- `${CLAUDE_PLUGIN_ROOT}/...` — plugin-relative, resolved at runtime
- `Task(...)` / `Agent(...)` calls — Claude Code tool syntax
- `git` commands — always available
- Standard POSIX commands (`ls`, `cat`, `find`, `test`, etc.) — always available
- Commands with variable interpolation (`$VARIABLE`, `${VAR}`)

### 3c. Linter config detection

```bash
# Check for linter/formatter configs
ls biome.json biome.jsonc 2>/dev/null
ls .eslintrc* eslint.config.* 2>/dev/null
ls .prettierrc* prettier.config.* 2>/dev/null
ls .editorconfig 2>/dev/null
ls deno.json deno.jsonc 2>/dev/null
ls ruff.toml 2>/dev/null
grep -l "tool.ruff\|tool.black" pyproject.toml 2>/dev/null
```

Record which tools are configured — pass to Phase 4 for overlap detection.

#

Related in Security