Tre meccanismi si contendono lo stesso spazio — comandi personalizzati, skill e regole per percorso — e la domanda che li separa non è che cosa contengono, ma quando entrano in contesto. Sbagliare quel criterio non produce un errore visibile: produce sessioni che pagano token per convenzioni che non c’entrano nulla con il task in corso, e un modello che perde di vista le istruzioni che contano.

Un comando personalizzato è una skill

La prima cosa da disimparare: «Custom commands have been merged into skills». Un file in .claude/commands/deploy.md e una skill in .claude/skills/deploy/SKILL.md creano entrambi /deploy e si comportano allo stesso modo; i file esistenti continuano a funzionare, ma se i nomi coincidono «the skill takes precedence». La forma a skill aggiunge una directory per i file di supporto, il frontmatter per decidere chi la invoca e la possibilità che sia Claude a caricarla quando la ritiene pertinente.

Enterprise   impostazioni gestite            tutti gli utenti dell'organizzazione
Personale    ~/.claude/skills/NOME/SKILL.md  tutti i tuoi progetti
Progetto     .claude/skills/NOME/SKILL.md    solo questo progetto
Plugin       PLUGIN/skills/NOME/SKILL.md     dove il plugin è attivo

La precedenza è controintuitiva e va detta in revisione: «enterprise overrides personal, and personal overrides project». Una deploy personale vince su quella committata dal team, quindi una skill locale può silenziosamente sostituire il rilascio ufficiale. Le skill dei plugin usano invece un namespace plugin-name:skill-name e non collidono mai.

Il nome del comando viene dalla directory, non dal campo name del frontmatter, che in una skill personale o di progetto è solo un’etichetta. Le skill annidate seguono la stessa logica dei CLAUDE.md: quelle sotto apps/web/.claude/skills/ non sono disponibili all’avvio, si caricano la prima volta che Claude legge o modifica un file in quella sottodirectory, e se il nome collide compaiono come /apps/web:deploy.

Frontmatter: chi invoca, con quali poteri

---
name: deploy
description: Deploy the application to production
disable-model-invocation: true
allowed-tools: Bash(git add *) Bash(git commit *)
---

La description è il campo che decide tutto, perché è l’unica cosa in contesto finché la skill non viene invocata; la combinazione di description e when_to_use viene troncata a 1.536 caratteri nell’elenco delle skill, quindi il caso d’uso principale va per primo. Due campi controllano l’invocazione: disable-model-invocation: true la rende invocabile solo da te — e la toglie del tutto dal contesto, costo zero fino al momento in cui la digiti — mentre user-invocable: false la riserva a Claude, per conoscenza di sfondo che non è un’azione sensata da lanciare a mano.

allowed-tools merita attenzione da architetto. Concede i permessi per il turno che invoca la skill, e poi «The grant clears when you send your next message»; non restringe nulla, aggiunge soltanto. Il punto delicato è un altro: «Workspace trust doesn’t gate this field». Una skill di progetto applica il suo allowed-tools anche in un’esecuzione con -p dentro una cartella mai dichiarata affidabile, quindi una skill committata in un repo può concedersi accesso ampio agli strumenti. Va letta prima di lanciare Claude Code in un repo altrui.

Restano gli argomenti ($ARGUMENTS, gli indicizzati $0 e $1, oppure i nomi dichiarati nel campo arguments) e l’iniezione dinamica: un comando fra backtick preceduto da punto esclamativo viene eseguito prima che il contenuto arrivi a Claude, e il testo viene sostituito dall’output. In ambienti controllati si disattiva con disableSkillShellExecution nelle impostazioni gestite.

Regole per percorso: convenzioni condizionali

I file markdown in .claude/rules/ vengono scoperti ricorsivamente, uno per argomento. Senza frontmatter paths si caricano all’avvio «with the same priority as .claude/CLAUDE.md». Con paths diventano condizionali.

---
paths:
  - "src/api/**/*.ts"
  - "tests/**/*.test.ts"
---

Il trigger è preciso: «Path-scoped rules trigger when Claude reads files matching the pattern, not on every tool use». Una regola sull’API resta fuori da una sessione che tocca solo documentazione. Le regole personali in ~/.claude/rules/ si caricano prima di quelle di progetto, che quindi hanno priorità più alta.

Due trappole nei glob. Le parentesi graffe moltiplicano i pattern e l’intera lista paths condivide un budget di 1.000 pattern espansi e 4 MiB: un pattern che sfonda il budget viene usato non espanso e le sue graffe letterali non corrispondono a nessun file. E una parentesi quadra che non forma un’espressione valida rende quel pattern invalido — non corrisponde a niente, mentre gli altri pattern della regola continuano a funzionare. In entrambi i casi il fallimento è silenzioso: la regola semplicemente non si carica mai.

Anche le skill accettano paths, con lo stesso formato: utile per una skill che vive nella radice ma vale solo per certi file, per esempio le migrazioni, ovunque si trovino.

Come si sceglie

CLAUDE.md per ciò che serve a ogni sessione, regole per le convenzioni di un linguaggio o di una directory, skill per materiale di riferimento e procedure ripetibili che carichi quando servono. La regola pratica: se una sezione del CLAUDE.md è diventata una procedura invece di un fatto, è una skill.

Un’ultima considerazione operativa. Le regole con paths entrano nella cronologia dei messaggi quando il file corrispondente viene letto, quindi una compaction le riassume via insieme al resto; tornano solo se Claude rilegge un file che le attiva. Se una convenzione deve valere fino alla fine di una sessione lunga, va tolto il frontmatter paths o spostata nel CLAUDE.md di radice.