🔀 Separate auditing from applying
The skill audit-ablacao is diagnostic: it reads, classifies, and proposes, and never edits, moves, deletes, or commits. That's not a limitation; it's by design. Applying is a separate request, in another session — for two reasons. First: diagnosing while your hand is on the keyboard gets contaminated by the urge to make changes; you start justifying the cut you already want to make. Second: the report needs to keep existing intact afterward, so you can check whether what was applied is really what was recommended. An audit that makes changes as it goes is an audit you can’t trust.
🆕 Two words before moving on
- Skill: a folder with one file
SKILL.mdthat teaches Claude Code a specific procedure. It’s only loaded when the task calls for it — unlike theCLAUDE.md— which is always read. - Context: the text window the model is “seeing” during that run. Everything that takes up context—including rules that have nothing to do with the task—uses space that could go to the actual work.
- Snapshot: a frozen copy of your config’s current state that you can restore with a command. A git commit is the cheapest snapshot there is.
⚠️ Never cut without a snapshot
Ablation only works as a method because it is reversible. If you can’t restore a command to its previous state, you’re not running an experiment — you’re hoping. And the first time a cut breaks something irreversibly, you’ll abandon the whole process and never touch the config again.
Hard rule: no line goes out before the “before” commit exists. Without git, at minimum a cp -r ~/.claude ~/.claude.bak-AAAA-MM-DD.
Putting the config under git takes thirty seconds and pays off throughout track 4, when you compare versions A, B, and C. Do this in the global config folder (~/.claude) or in the project root, depending on the scope you audited.
📦 Copy and run: config under git
Objective: have a named return point before making any cuts.
# escopo global — a pasta de config do Claude Code cd ~/.claude git init -b main # so na primeira vez git add -A git commit -m "antes da ablacao" # escopo projeto — a config que anda com o repo # cd ~/projetos/<seu-projeto> # git add CLAUDE.md .claude/ # git commit -m "antes da ablacao"
How to verify: run git status. If the output says nothing to commit, working tree clean— you have a restore point. Test the rollback before you need it: git diff after a cut shows exactly what was removed, and git checkout -- CLAUDE.md undoes.
✓ Healthy application session
- ✓New session, with the report in
.mdopen beside it - ✓The “before” commit is already done, and
git statusclean - ✓One change at a time, with the relevant report excerpt pasted into the request
- ✓The report remains untouched—it’s the record of what was decided
✗ Signs things will go wrong
- ✗"Since you're here, apply everything" in the same audit session
- ✗Config outside git, “I’ll version it later”
- ✗Ten changes in a single commit — if something breaks, you won’t know which one caused it
- ✗Report overwritten by the same session that applied the cuts
🎯 Attack in the right order
Section 10 of the report delivers the Top 10 by impact ÷ risk — the changes that return the most context with the lowest risk of breaking behavior. But it isn’t a queue for you to tackle from top to bottom in one day. The practical order is based on risk category, in four waves, and it exists to build trust in the process before you get anywhere near what feels scary.
Wave 1 — Redundancies and conflicts
Almost zero risk. Immediate gain.
The same rule written in three places becomes one; two rules that contradict each other become a decision. You’re not removing behavior—you’re removing copies. No one loses anything, and the config visibly shrinks on day one. Bonus: no more days when one copy changes and the others don’t.
Wave 2 — Legacy / obsolete
Low risk, but requires a check.
Dated instructions: fixes for weaknesses in a model that's no longer in use, exceptions dated 2024, workarounds for bugs that have been fixed. The check is simple—does the original reason still exist? If you can't name the reason, that's a strong sign it's gone.
Wave 3 — Micromanagement → criteria
Medium risk: you change the form, not remove the intent.
The rigid twelve-step process becomes “task + guardrails + exit criteria.” The intent stays intact; what you give back is the freedom for the model to find a better path than yours. At this point, it’s worth observing the behavior for a few days before deciding it’s good.
Wave 4 — What remains in TEST
Unknown risk — that's why it's last.
TEST is the decision the skill makes when it's unsure: it might be dead weight, or it might be holding something together. These aren't applied out of conviction; they're applied through an experiment—and the experiment is the A/B/C plan in Track 4. Putting off this wave isn't cowardice; it's sequencing.
💡 Why start with near-zero risk
The temptation is to start with the biggest cut—that 80-line block you’ve always thought was useless. It’s the heroic cut, and it’s the classic trap: something breaks, you don’t know which of the 80 lines was necessary, you revert everything, and conclude that “the config was right the way it was.”
- •Waves 1 and 2 give you days of evidence that cutting doesn't break anything — that's what builds your confidence for waves 3 and 4
- •Small changes separated by commit make it obvious what caused a behavior change
- •We're not maximizing reduction—the target is quality + autonomy + verifiability ÷ complexity
| Wave | Category | Risk | How to confirm it worked | When to apply |
|---|---|---|---|---|
| 1 | Redundancy / conflict | almost zero | the rule still exists—in one place | first session |
| 2 | Legacy / obsolete | low | you can’t name the original reason | first session |
| 3 | Micromanagement → criteria | medium | the output still meets the new criterion | after days of real use |
| 4 | TEST | unknown | only through an A/B/C experiment | track 4 |
📦 Move the procedure to a skill
This is the module's central argument. A rule that lives in the CLAUDE.md is read in every execution — including the ~90% of tasks that have nothing to do with it. It same a rule inside a skill only costs context when that task comes up. That is load-on-demand: load on demand instead of always. Move the procedure from the CLAUDE.md for a skill is the cheapest way to slim down the config without losing anything — is exactly what the report calls MOVE and of LOAD-ON-DEMAND.
What to look at: the purple block didn’t disappear—it shrank, and the rest became the cyan block, which appears once instead of ten. No instructions were lost; what changed was how many times you pay for it. That’s why MOVE usually delivers more than REMOVE in the first waves: you slim it down without having to decide whether anything is expendable.
🧪 Copy and run: create the skill and extract the block
Objective: remove a procedure from CLAUDE.md and put it in a skill that loads only when called.
# 1. criar a pasta da skill (global; use .claude/skills/ para so o projeto) mkdir -p ~/.claude/skills/<nome-da-skill> # 2. escrever o SKILL.md — o frontmatter e o bloco YAML entre --- no topo, # que da nome e descricao a skill (e o que o Claude Code le pra saber que ela existe) cat > ~/.claude/skills/<nome-da-skill>/SKILL.md <<'EOF' --- name: <nome-da-skill> description: <quando usar, em uma frase, com as palavras que voce realmente usa> --- # <Nome da skill> <cole aqui o bloco procedimental que estava no CLAUDE.md, sem mudar nada> EOF # 3. remover o bloco do CLAUDE.md (agora ele vive na skill) # edite o arquivo e apague as linhas movidas — deixe UM ponteiro curto se precisar: # "Procedimento de <assunto>: /<nome-da-skill>" # 4. registrar o antes/depois wc -l ~/.claude/CLAUDE.md git -C ~/.claude add -A && git -C ~/.claude commit -m "move: <assunto> do CLAUDE.md para skill"
How to verify: restart the session, call /<nome-da-skill> and confirm that the procedure responds the same way it did before. Then run a task that isn’t that one and confirm that the behavior hasn't changed either—that's what proves you moved it rather than lost it.
Watch the pointer: if the “short pointer” in the CLAUDE.md start growing and re-explaining the procedure, you’ve recreated the problem. One line at most—or none if you plan to invoke it directly (topic 4).
✓ Stays in CLAUDE.md — ALWAYS true
- ✓Identity — what this project is, who the audience is, what the domain is
- ✓Guardrails — what never to do, limits that apply to every task
- ✓Sources of truth — where the keys, data, and canonical file live
- ✓Security and compliance — what must not leak, what must not be published
- ✓Internal conventions that the model can’t infer on its own
✗ Exits the CLAUDE.md — becomes a skill
- ✗Procedure — "to do X, follow these steps"
- ✗Format — output spec, document structure, template
- ✗Recipe — sequence of deploy, publish, and build commands
- ✗Integration — how to work with a specific API/tool
- ✗Routing — "when I ask for X, use skill Y" (see section 4)
⌨️ Call the skill directly
A skill is usually triggered by trigger — the model compares your sentence with the field description of the frontmatter and decides whether that skill applies. This works, but it's a lottery: if you wrote "guide" and the description says "landing page," the skill won't trigger. Explicit invocation (/nome-da-skill) eliminates the guesswork entirely: you no longer depend on the description matching your phrasing.
💡 Explicit invocation overrides the routing rule
When several skills compete for the same subject, the reflex is to write in the CLAUDE.md: “when I ask for a guide, use skill X, not Y”. That line is itself another zombie line—read every time it runs, existing only to break a rare tie. Explicit invocation is the tie-breaker, and it’s free: you type /x and the debate is over.
- •Each routing rule you remove gives back context in all the runs
- •If you knows what you want; naming it is always cheaper and more precise than describing it
- •The trigger is still useful for when you no knows the skill exists — but doesn’t need to be reinforced by a global rule
Where the skill lives matters too. A skill in ~/.claude/skills/ applies to everything you do; a skill in .claude/skills/ within the project versioned alongside the code. This changes the maintenance model: the procedure travels with the repo, goes into the pull request, can be reviewed by someone else, and—crucially—doesn’t leak into other projects. A project-specific deploy recipe for project A has no reason to take up context when you’re working on project B.
| Where the instruction lives | Context cost | Scope | Reviewable in a PR |
|---|---|---|---|
~/.claude/CLAUDE.md | every run, in every project | everything | no |
CLAUDE.md of the project | every run in that project | the project | yes |
~/.claude/skills/ | only when invoked/triggered | everything | no |
.claude/skills/ of the project | only when invoked/triggered | the project | yes |
Key concepts
Description matches your phrase — or it doesn’t
/nome — no lottery
Routing in CLAUDE.md is one of them
Version it in the repo; don't leak it
💊 Choose the right remedy
When the model stumbles, the reflex is to dump one more rule into the CLAUDE.md. In Boris’s cycle, there are three remedies, and choosing the right one is what keeps the config from growing again: better prompt (the instruction was unclear) · skill (missing repeatable procedure) · MCP (missing context or access it can’t reach). MCP is the protocol Claude Code uses to communicate with an external source — a database, an API, a remote file system — that it couldn’t see on its own.
What to look at: none of the four paths ends with "write one more line in the CLAUDE.md". And notice the cyan branch on the left: a failure that happened once isn’t a remedy at all—the reintroduction rule says to wait for the same failure to recur before returning any instructions. Half the zombie lines in a config started with a one-off stumble.
Misstep → better prompt
You asked, "improve this text," and got a complete rewrite that lost your tone. The model didn't make a mistake: "improve" doesn't mean anything specific. The fix is in the prompt — "correct the grammar and cut redundancy while preserving the word choices" — not in the config. Fixing an unclear instruction with a global rule turns it into an unclear global rule.
Misstep → skill
Every time you publish a project, you need to remind the model of the same sequence: guide in guia/, never at the root; repo name = folder name; Pages via Actions. This is the third time you’ve explained it. That’s a repeatable procedure with a clear scope—it becomes a skill, and you invoke it /publicar when needed.
Misstep → MCP
You ask for an analysis of requests from the last quarter, and the model invents plausible numbers. No rule can fix this, because the problem isn't behavior — it's that the data is in a database it can't access. The remedy is to provide access (an MCP server for the database), not to write "don't make up data" in the CLAUDE.md.
🧹 A skill is easy to audit—and retire
A skill has boundary, name, and scope. That means it’s a unit you can hold in your hand: you can rename the folder, run for a week without it, and measure whether anything got worse. It’s ablation at the scale of a whole unit.
Disable "that middle paragraph from the CLAUDE.md" is much harder: it has no name, no clear boundary, you don't know which tasks depended on it, and nothing alerts you when it disappears. That's why the same instruction, inside a skill, is cheaper to maintain — not just cheaper to run.
Quick check (doesn't block anything): for the third week in a row, you explain the same 8-step sequence for publishing a project to the model. What's the right remedy?
🛠️ Apply your first 3 changes
This module’s exercise is short and concrete: apply the 3 first changes from the Top 10 of your report, in a new session, with the config under git—and at least one of them being a MOVE of the procedural block of the CLAUDE.md for a skill. One change per commit. Record the before and after using two metrics: number of lines and number of rules.
📏 Copy and run: measure before and after
Objective: have a number, not an impression. “It got leaner” isn’t a record.
# ANTES de aplicar qualquer coisa wc -l ~/.claude/CLAUDE.md grep -c '^[-*] ' ~/.claude/CLAUDE.md # aproximacao do numero de regras (bullets) git -C ~/.claude log --oneline -1 # confirma o commit "antes da ablacao" # ... aplique UMA mudanca, commite, repita ... # DEPOIS das 3 mudancas wc -l ~/.claude/CLAUDE.md grep -c '^[-*] ' ~/.claude/CLAUDE.md git -C ~/.claude diff --stat "antes da ablacao"..HEAD ls ~/.claude/skills/ # a skill nova esta la?
How to verify: git diff --stat gives you the exact count of lines removed and added—and in a MOVE done well, you see lines exiting of the CLAUDE.md e entering in the SKILL.md— almost the same amount. That’s the sign you moved it, rather than accidentally deleting it.
📋 Copy and paste: the application request
Objective: ask a specific change, with the report excerpt pasted in — never “apply the report.”
Sessao de APLICACAO (a auditoria ja foi feita e esta salva em relatorio-ablacao.md — nao rode auditoria de novo, nao releia tudo). Aplique EXATAMENTE UMA mudanca, esta: <cole aqui o trecho do relatorio> Regras desta sessao: - Nao aplique nada alem do que esta no trecho acima. - Nao "aproveite pra melhorar" outras partes do arquivo. - Se for um MOVE: crie ~/.claude/skills/<nome>/SKILL.md com frontmatter (name, description) e mova o bloco INTEGRAL, sem reescrever o conteudo. - Remova do CLAUDE.md exatamente as linhas movidas. - No fim, mostre: (a) o diff, (b) wc -l do CLAUDE.md antes e depois, (c) uma frase dizendo o que EU devo testar pra confirmar que nada mudou. - Nao commite: eu commito depois de ler o diff.
Why “don’t commit”: the commit is your decision point. Reading the diff before committing is the only moment when you compare what asked with what happened — and that’s exactly where the silent rewrite of a block you told it to move without changing it shows up.
✓ This module’s exit criterion
- ✓Commit (or snapshot) “before” e “after” exist and can be located
- ✓
CLAUDE.mdsmaller — based on the number, not the impression - ✓The new skill responds to a direct invocation
/<nome> - ✓The corresponding task behavior didn’t change
✗ It doesn't count as complete if
- ✗The 3 changes went into a single commit
- ✗The moved block was “improved” along the way — so you changed two things at once
- ✗The skill exists, but you’ve never invoked it to check that it responds
- ✗You measured "it feels lighter" instead of
wc -l
📌 Module Summary
TEST. Starting with the nearly zero-risk option keeps you from making a heroic cut that makes you give up.MOVE is the primary tool — rule in the CLAUDE.md is read on every run; the same rule in a skill only costs context when the task calls for it./nome-da-skill breaks the tie without costing a global line. A project skill is versioned in the repo and doesn’t leak.CLAUDE.md"; and a failure that happened once still isn't a remedy.CLAUDE.md — only what is always true: identity, guardrails, sources of truth, security. Everything else is a skill.Next Module:
4.1 — The A/B/C ablation plan: prove through testing, on real tasks, that the minimal version hasn't lost quality.