Free

Tratta CLAUDE.md come una costituzione

Scrivi CLAUDE.md come una costituzione: divieti, regole di comportamento, decisioni predefinite. 92 commit in 5 giorni, senza deviazioni.


In 5 giorni ho fatto 92 commit e mandato in produzione un prodotto (github.com/defi-io/smarts). Niente disastri, niente rollback, niente grossi refactor. Il motivo non è che Claude sia un genio. Il motivo sono le 565 righe di CLAUDE.md nella radice del progetto.

Questo articolo parla di come scrivere un CLAUDE.md che funzioni come una costituzione, e di cosa succede dopo.

CLAUDE.md non è un README

Tanti scrivono CLAUDE.md come se fosse un README — cos'è il progetto, come avviarlo. È spreco.

Il README è per gli umani. CLAUDE.md è per Claude. Claude lo carica automaticamente all'inizio di ogni sessione. Vuol dire che ogni riga che scrivi lì diventa una precondizione per ogni sua decisione successiva.

Stile README, ottieni questo: Claude sa più o meno cos'è il progetto, sa eseguire i test, ma prende ogni decisione tecnica da zero.

Stile costituzione, ottieni questo: Claude sa quali strade sono chiuse, quali convenzioni sono obbligatorie, da che parte propendere di default a ogni bivio, e quando fermarsi a chiedere.

Differenza: il primo "già che ci siamo" tira dentro una nuova dipendenza, aggiunge uno strato d'astrazione, ritocca il Gemfile. Il secondo no.

Com'è il CLAUDE.md di smarts.md

Il progetto su cui sto lavorando si chiama smarts.md — una piattaforma che genera live docs e server MCP per smart contract. Il suo CLAUDE.md è di 565 righe, organizzato così:

1.  Identità del progetto (5 righe)
2.  Cuore del prodotto (definizione in una riga + differenze strutturali con i competitor)
3.  Stack tecnico (vincoli rigidi, formato YAML)
4.  Lista dei divieti (voci ❌ esplicite)
5.  Scopo (confini rigidi del MVP)
6.  Architettura (con diagramma ASCII)
7.  Struttura delle directory (responsabilità per file)
8.  Convenzioni Ruby (con snippet do/don't)
9.  Strategia di cache (in tabella)
10. Requisiti di test
11. Dettagli di deploy
12. Workflow Git
13. Regole d'uso di Claude Code (istruzioni di comportamento)
14. Milestone a 90 giorni
15. Principi fondamentali

Nessuna sezione è decorativa. Ne scelgo qualcuna sotto e spiego perché è scritta così.

La lista dei divieti è la parte più utile di CLAUDE.md

La mia ha questa forma:

❌ Niente servizi TypeScript / Node.js
❌ Niente ethers.js / web3.js
❌ Niente Sidekiq (usare Solid Queue)
❌ Niente React / Vue / Svelte (usare Hotwire)
❌ Niente Redis (Solid Cache / Solid Queue / Solid Cable coprono tutto)
❌ Niente contratti non verificati (solo verificati su Etherscan)
❌ Niente Solana / Bitcoin / Move (solo EVM)

È un progetto Web3. Lo standard Web3 è TypeScript + ethers.js + Redis + React. Io vado controcorrente. Ho le mie ragioni, ma Claude non le sa. Senza la lista di divieti, Claude consiglia in base al "buon senso del settore" sepolto nei suoi dati di training — quasi sicuramente la strada TypeScript.

Con la lista, Claude smette di chiedere "aggiungiamo un service Node per far girare web3.js?". Quella strada è chiusa di default.

La chiave: ogni voce dev'essere esplicita e assoluta. Non scrivere "cercare di evitare TypeScript". Scrivi "niente TypeScript". Tutto ciò che è vago Claude lo legge come negoziabile.

Le istruzioni di comportamento contano dieci volte più dello stile di codice

L'ultimo grande blocco di CLAUDE.md è "Regole d'uso di Claude Code":

### Quando dico "inizia con X"
1. Prima controlla se i vincoli di CLAUDE.md permettono questo approccio
2. Poi controlla nel codice esistente se c'è già un'implementazione (non reinventare)
3. Prima di scrivere codice, apri un nuovo branch
4. A implementazione fatta, esegui i test
5. Niente commit automatico — quando il codice è scritto e i test passano,
   fermati e fai rapporto. Aspetta che io dica esplicitamente "commit"

### Quando dico "ho un'idea"
Non scrivere codice subito. Prima:
1. Conferma di aver capito (parafrasa)
2. Valuta rispetto ai vincoli di CLAUDE.md
3. Indica problemi potenziali o alternative migliori
4. Aspetta la mia conferma prima di agire

### Davanti a un bivio tecnico
Quando CLAUDE.md non specifica:
1. Default sull'opzione più "Rails-native"
2. Default sull'opzione con meno dipendenze
3. Default sull'opzione che fa iterare più in fretta uno sviluppatore solo
4. Nel dubbio, fermati e chiedi

Questa parte vale dieci volte più di "usa snake_case".

Lo stile di codice Claude lo impara leggendo il codice. Ma "quando fermarsi a chiedere", "quando senti 'ho un'idea', prima parafrasa invece di scrivere codice" — sono pattern di comportamento. Il codice da solo non li insegna.

La riga più importante: da che parte propendere a un bivio. Quella singola regola decide cosa fa Claude quando non sei in stanza (quando dici solo "inizia con X" e ti allontani). Scrivila chiara e potrai lasciarlo lavorare senza supervisione.

Cambia CLAUDE.md prima di cambiare il codice

In testa a CLAUDE.md c'è questa riga:

Questo documento è la "fonte primaria" del progetto. Caricato automaticamente all'inizio di ogni sessione di Claude Code. Quando cambi decisioni tecniche, modifica prima qui; il codice segue.

È un patto di workflow. Quando decido di cambiare una scelta tecnica — diciamo, alzare il modello AI principale da gpt-5-mini a gpt-5 — il primo passo non è toccare l'initializer. Il primo passo è modificare questo pezzo di CLAUDE.md:

ai:
  fast: gpt-5-mini      # prima
  fast: gpt-5           # dopo

Poi lascio che Claude rilegga CLAUDE.md e allinei il codice.

Perché? Perché se cambi un valore nel codice e CLAUDE.md resta indietro, la prossima volta Claude legge CLAUDE.md, vede il valore vecchio e "gentilmente" rimette a posto il tuo codice. La radice del conflitto è un single point of failure — CLAUDE.md desincronizzato. Una costituzione in ritardo sulla realtà è come iniziano le guerre civili.

Trattare CLAUDE.md come una costituzione significa: corre sempre davanti al codice.

Cos'è successo davvero

smarts.md, 5 giorni, 92 commit:

  • Giorno 1: Scheletro Rails 8 + deploy Kamal in linea
  • Giorno 2: MVP della doc del contratto + arricchimento AI + adapter Uniswap V3
  • Giorno 3: Server MCP + 5 MCP tools + slug "amichevoli"
  • Giorno 4: SEO + card OG + featured contracts + GenericErc20Adapter
  • Giorno 5: Discovery AI-native (llms.txt + .well-known/mcp.json) + adattamento mobile

Vita media di una PR: 30 minuti. Niente refactor giganti. Niente "aspetta, quella direzione era sbagliata, rollback".

Non perché Claude sia magia. Ma perché ogni sessione correva su un binario di 565 righe. Sapeva di non tirar dentro TypeScript, sapeva che Solid Queue è la coda di default, sapeva che le funzioni view sono in cache 60 secondi, sapeva che ogni service deve implementare un metodo di classe call, sapeva di aspettare la mia conferma prima di committare.

Togli metà di quei vincoli e ottieni: 30 minuti al giorno a spiegare "perché non usiamo X", 5 minuti a rivedere la dipendenza che ha aggiunto "già che c'era", e un Gemfile che si sgretola pian piano.

Come iniziare a scrivere il tuo

Non partire da un file vuoto. Parti dalla decisione più recente che ti ha fatto male.

Se ultimamente Claude "tira sempre dentro nuove dipendenze", scrivi la lista dei divieti.
Se è "cambia architettura per niente", scrivi il diagramma di architettura + "aggiungere microservizi, cambiare DB, ecc. richiede conferma".
Se è "non scrive test", scrivi "cosa va testato a livello unitario obbligatoriamente".
Se è "committa troppo aggressivamente", scrivi "niente commit automatico, aspettare istruzione esplicita".

Ogni dolore, una voce. Il resto, per ora, no.

Tre mesi dopo avrai un CLAUDE.md di 500 righe in cui ogni riga ha dietro un concreto "non voglio che lo rifaccia". Quel documento batte qualunque template, perché è tarato esattamente sul tuo progetto, sul tuo workflow, sul tuo team (anche se sei solo tu).

Una costituzione non si scrive in un colpo solo. Si cristallizza, conflitto dopo conflitto.


Sorgente: github.com/defi-io/smarts