---
name: trim-claude-md
description: Use when CLAUDE.md exceeds 200 lines, shows the Claude Code "large CLAUDE.md will impact performance" warning, or whenever the project's CLAUDE.md feels bloated. Audits the file against Anthropic's documented destination categories (rules, invariants, path-scoped rules, skills, hooks, docs, plans, auto memory) and proposes a multi-file reorganization before any write. Brand-agnostic, works on any project.
argument-hint: <project-path-or-blank-for-cwd>
---

## What This Skill Does

Trims a project's CLAUDE.md down to the size and shape Anthropic explicitly recommends in [Claude Code memory docs](https://code.claude.com/docs/en/memory). The target is **under 200 lines per CLAUDE.md** — anything beyond consumes context and reduces adherence.

This skill does NOT just delete content. It triages every section against the official destination categories and proposes WHERE each chunk should live (sometimes CLAUDE.md, more often `.claude/rules/`, `docs/`, or `plans/`).

**Trigger phrases:** "trim claude.md", "claude.md is too large", "shrink CLAUDE.md", `/trim-claude-md`, or any conversation where the operator hits the "large CLAUDE.md will impact performance" warning.

**Critical safety rule:** This skill NEVER silent-edits CLAUDE.md or any other project file. Every run produces a proposal first. The operator must explicitly approve before any write.

---

## Anthropic's documented destination categories

These are the canonical buckets per the official docs. Every section of a CLAUDE.md belongs in exactly one:

| Category | Destination | Loaded? | When to use |
|---|---|---|---|
| **Hard rules** | `CLAUDE.md` (rules section) | Every session | Forbidden vocab, voice rules, US English, "always do X" |
| **Invariants** | `CLAUDE.md` (invariants section, terse) | Every session | Source-of-truth boundaries, protected columns, key file paths |
| **Top commands** | `CLAUDE.md` (commands section, 5-10 max) | Every session | Daily commands operators run |
| **Pointers** | `CLAUDE.md` (one-liner per area) | Every session | "Deeper context for X lives in Y" |
| **Path-specific guidance** | `.claude/rules/<topic>.md` with `paths:` frontmatter | Only when Claude touches matching files | Per-area conventions, schema details, file-specific rules |
| **Multi-step procedures** | New skill or existing skill | On invocation only | Setup runbooks, repeatable workflows |
| **Hard enforcement** ("must run before X") | Hook in `settings.json` | Lifecycle event, non-negotiable | Pre-commit, pre-push, formatters |
| **One-time setup** | `docs/setup-<topic>.md` | Not auto-loaded | GCP service account, n8n credentials, env var setup |
| **State snapshots / history** | `plans/` or commit messages | Not loaded | "As of YYYY-MM-DD", "Pipeline harness shipped", current row counts |
| **Operational learnings Claude discovers** | Auto memory | Per-session, on demand | Claude writes these itself |

**Critical:** `@import` syntax does NOT reduce context. Imported files still load in full at launch. The only true context-saver is `.claude/rules/` with `paths:` frontmatter (loads only when matching files are touched) or skills (load only when invoked).

---

## Step 1: Gather Context

Take the project path from `$ARGUMENTS` if provided, otherwise use the current working directory.

1. Read the target CLAUDE.md (`<project>/CLAUDE.md` or `<project>/.claude/CLAUDE.md`).
2. Measure: lines, characters, sections, "as of YYYY-MM-DD" date references count.
3. Read `~/.claude/CLAUDE.md` (user-level) — note what's already there to avoid duplication.
4. List existing destinations:
   - `<project>/.claude/rules/*.md` (count + topics covered)
   - `<project>/docs/*.md` (count + topics covered)
   - `<project>/plans/*.md` (count, most recent date)
   - Existing skills (`<project>/.claude/skills/` if any)
5. Read `<project>/.claude/settings.json` if present — note existing hooks.

Output: a one-screen audit. Lines, char count, anti-pattern count, destinations already in use.

---

## Step 2: Categorize Every Section

Walk the CLAUDE.md heading by heading. For each section (top-level or sub-heading), apply this decision tree:

### Decision tree per section

1. **Is it a rule Claude must follow?** ("Never X", "Always Y", forbidden vocab, voice rules)
   → KEEP in CLAUDE.md (rules section)

2. **Is it an invariant about how the system works?** (source-of-truth claim, protected boundary, key file path)
   → KEEP in CLAUDE.md (invariants section), but trim to one line if it's currently a paragraph

3. **Does it apply ONLY when working in a specific area of the codebase?** (e.g., "When editing pillars/*.md, ...")
   → MOVE to `.claude/rules/<topic>.md` with `paths:` frontmatter matching that area

4. **Is it a multi-step procedure?** ("To set up X: 1. ..., 2. ..., 3. ...")
   → MOVE to a skill (new or existing) OR to `docs/setup-<topic>.md` if one-time

5. **Is it state / history?** ("As of <date>", "Current state", "Pipeline X shipped on Y")
   → CUT. Move to commit message OR plans/. Replace with one-liner pointer if needed.

6. **Is it a hard enforcement need?** ("Must run before commit", "Must validate before push")
   → MOVE to a hook in `settings.json`. The CLAUDE.md instruction is unreliable; hooks are not.

7. **Is it operational knowledge Claude could discover for itself?** (Build commands, debugging insights)
   → CUT. Auto memory will accumulate these.

8. **Is it a multi-paragraph description of a feature that has its own plan or doc?**
   → CUT to a one-line pointer. The deep description lives in the plan/doc.

### Anti-patterns to flag

Scan for these explicit indicators that something doesn't belong in CLAUDE.md:

- `as of YYYY-MM-DD` / `As of <date>` headings → state snapshot, almost always CUT
- `## Current state` / `## Pipeline state` → snapshot, CUT
- `Shipped X on Y date` paragraphs → history, CUT
- Numbered setup steps ("1. Install X, 2. Configure Y, 3. Run Z") → MOVE to docs/skill
- Token contract / schema descriptions that already exist as JSON files → CUT, point to the JSON
- Multi-paragraph workflow / runbook descriptions → MOVE to skill or rule
- Email setup / credentials setup / one-time auth flow → MOVE to `docs/setup-*.md`
- Date references older than 6 months → flag for "still current?" review

### Output of Step 2

A categorization table:

```
Section: "Verified corrections / forbidden claims"
  Lines: 145-178
  Category: Hard rules
  Action: KEEP in CLAUDE.md (no change)
  Reasoning: Direct rules Claude must follow

Section: "Current state (2026-05-20)"
  Lines: 21-32
  Category: State snapshot
  Action: CUT
  Reasoning: Anti-pattern — dated snapshot, will be wrong in 90 days

Section: "Substack publication state"
  Lines: 234-289
  Category: Multi-paragraph runbook
  Action: MOVE to .claude/rules/substack.md (paths: substack/**/*, tools/push-to-substack.cjs)
  Reasoning: Only relevant when working on Substack tooling
```

---

## Step 3: Produce the Proposal

Write a single `proposal.md` file in the target project at `<project>/.claude/trim-claude-md-proposal.md` (gitignored — add to `.gitignore` if not already excluded):

### Proposal structure

```markdown
# CLAUDE.md trim proposal — YYYY-MM-DD

## Before
- File: <project>/CLAUDE.md
- Lines: <N>
- Characters: <M>
- Status: <Over/Under> Anthropic's 200-line target

## After (projected)
- CLAUDE.md: <N'> lines (-<delta>)
- New files: <list>
- Moved sections: <count>
- Cut sections: <count>

## Section-by-section actions

[Categorization table from Step 2, with proposed action + reasoning per section]

## Proposed new files

### .claude/rules/<topic>.md
- paths: [<glob1>, <glob2>]
- Pulls from CLAUDE.md sections: <list>
- Full content: [...]

### docs/setup-<topic>.md
- Pulls from CLAUDE.md sections: <list>
- Full content: [...]

[Repeat per new file]

## Proposed new CLAUDE.md content

[Full content of the trimmed CLAUDE.md, ~150-200 lines max]

## Approval needed

Reply "approved" to apply ALL changes.
Reply "approved partial: <section-names>" to apply only specific moves.
Reply "reject: <reason>" to discard the proposal.
```

Then summarize the proposal in the conversation:

> CLAUDE.md trim proposal saved to <path>. Before: <N> lines. After: ~<N'> lines. New files: <count>. Cut: <count>. Reply "approved" to apply, or read the proposal file first.

**STOP HERE.** Do not write any project files. Wait for the operator.

---

## Step 4: Apply on Approval

Only when the operator explicitly approves:

1. Read `proposal.md`.
2. Write each proposed new file (`.claude/rules/*.md`, `docs/setup-*.md`, skill files, etc.).
3. Overwrite `CLAUDE.md` with the trimmed content.
4. Update `settings.json` if hooks were proposed (with explicit re-confirmation if it modifies existing hooks).
5. Log the operation:
   - Append a line to `~/.claude/skills/trim-claude-md/audit.log`:
     ```
     <ISO date>\t<project>\t<before-lines>→<after-lines>\t<moved-sections-count>\t<cut-sections-count>
     ```
   - This is a learning log: across runs, the skill builds memory of what destinations operators accept.
6. Print a final summary:
   - Files written (with line counts)
   - CLAUDE.md before/after
   - Reminder: "Run `/memory` in Claude Code to verify the trimmed CLAUDE.md is loaded correctly. Run any path-scoped rules by working on a matching file."
7. Suggest a commit message:
   ```
   CLAUDE.md trim: <before> → <after> lines, +<N> rules, +<M> docs
   ```

Do NOT auto-commit. Operator commits when ready.

---

## Heuristics from prior runs (read before categorizing)

These patterns recur across projects. Build intuition by reviewing them before each run:

- **"Current state" sections** — always CUT. They're stale within 90 days and the git log + plans/ cover the actual history.
- **"Daily commands" lists with 30+ entries** — keep the TOP 10. Move the rest to a `docs/commands-reference.md` or a `/commands` skill.
- **Token contract / schema descriptions** — these duplicate JSON files. CUT and point to the JSON file. The schema IS the truth, not the prose description.
- **Pillar/template-specific rules** — `.claude/rules/<area>.md` with `paths:` frontmatter is exactly right.
- **Setup runbooks (one-time)** — `docs/setup-<name>.md`. Operators do this once per env, not every session.
- **n8n workflow node descriptions** — usually belong in a `.claude/rules/workflow.md` with `paths: workflows/*.json`. Only load when Claude actually touches the workflow JSON.
- **Voice / vocab rules** — keep in CLAUDE.md. These ARE the kind of thing every session needs.
- **Brand portability sections** — usually move to `docs/multi-brand-replication.md` since they only matter during cloning.

---

## Authoring rule going forward (include in trimmed CLAUDE.md)

The trimmed CLAUDE.md should end with a short authoring rule so the file stays lean:

```markdown
## When adding to this CLAUDE.md

Before adding any new section, classify it:

| Type | Goes to |
|---|---|
| Hard rule Claude must follow | This file |
| Invariant about the system | This file, one line |
| Multi-step procedure | A skill |
| Path-specific guidance | `.claude/rules/<topic>.md` with `paths:` frontmatter |
| State / history / "as of date" | Commit message OR plans/ |
| One-time setup | `docs/setup-<topic>.md` |
| Hard enforcement | Hook in `settings.json` |

Target stays under 200 lines. Run `/trim-claude-md` quarterly or whenever the Claude Code "large CLAUDE.md" warning fires.
```

---

## Self-improvement: review the audit log periodically

Once a quarter, or after 5+ runs, review `~/.claude/skills/trim-claude-md/audit.log`. Look for:

- Sections that ALWAYS get cut → harden the cut rule (add to the anti-patterns list above)
- Sections that ALWAYS get kept → harden the keep rule
- Destinations that consistently get rejected → soften that proposal (maybe the move is wrong)
- Recurring section names across projects → add to "Heuristics from prior runs"

When patterns emerge, edit this SKILL.md (in the source repo, then `./sync.sh`). The skill literally improves over time as it learns what operators accept.

---

## Multi-brand replication

This skill is intentionally brand-agnostic. Same skill works for any project's CLAUDE.md — content workflows, SaaS codebases, personal projects, anything. The only project-specific knowledge it uses is what it reads from the project's actual files (CLAUDE.md, `.claude/rules/`, `plans/`).

To use on a new project: just `cd <project>` and invoke `/trim-claude-md`.

---

## Important constraints

- **Never silent-edit.** Always propose first, apply only on explicit approval.
- **Never delete plans/ or git history.** CUT means remove from CLAUDE.md; the history goes to commit messages.
- **Idempotent.** Re-running on an already-trimmed CLAUDE.md should propose few or zero changes.
- **Honest about uncertainty.** If a section doesn't clearly fit a category, flag it for operator review rather than guessing.
- **Don't introduce new infrastructure unless the project already uses it.** If the project has no `docs/` folder, propose creating one only if the operator agrees.
