Free

Trata CLAUDE.md como una constitución

Escribe CLAUDE.md como una constitución: prohibiciones, reglas de conducta, decisiones por defecto. 92 commits en 5 días sin desviarse.


En 5 días hice 92 commits y puse un producto en producción (github.com/defi-io/smarts). Sin desastres, sin rollbacks, sin grandes refactorizaciones. No fue por la genialidad de Claude. Fue por las 565 líneas de CLAUDE.md en la raíz del proyecto.

Este artículo trata de cómo escribir un CLAUDE.md que funcione como una constitución, y qué pasa cuando lo haces.

CLAUDE.md no es un README

Mucha gente escribe CLAUDE.md como si fuera un README — qué es el proyecto, cómo ejecutarlo. Es un desperdicio.

El README es para humanos. CLAUDE.md es para Claude. Claude lo carga automáticamente al inicio de cada sesión. Cada línea que escribas allí se convierte en una precondición para todas sus decisiones posteriores.

Si lo escribes estilo README, obtienes esto: Claude sabe a grandes rasgos qué es el proyecto y cómo correr los tests, pero toma cada decisión técnica desde cero.

Si lo escribes estilo constitución, obtienes esto: Claude sabe qué caminos están cerrados, qué convenciones son obligatorias, hacia dónde inclinarse en cada bifurcación, y cuándo debe parar y preguntar.

La diferencia: el primero te meterá "de paso" una nueva dependencia, una capa de abstracción extra, un retoque al Gemfile. El segundo no.

Cómo es el CLAUDE.md de smarts.md

El proyecto que estoy construyendo se llama smarts.md — una plataforma que genera live docs y servidores MCP para smart contracts. Su CLAUDE.md tiene 565 líneas, en estas secciones:

1.  Identidad del proyecto (5 líneas)
2.  Núcleo del producto (definición en una línea + diferencias estructurales con la competencia)
3.  Stack técnico (restricciones duras, en YAML)
4.  Lista de prohibiciones (ítems ❌ explícitos)
5.  Alcance (límites duros del MVP)
6.  Arquitectura (con diagrama ASCII)
7.  Estructura de directorios (responsabilidades por archivo)
8.  Convenciones de código Ruby (con fragmentos de "haz esto / no esto")
9.  Estrategia de caché (en tabla)
10. Requisitos de testing
11. Detalles de despliegue
12. Flujo Git
13. Reglas de uso de Claude Code (instrucciones de comportamiento)
14. Hitos a 90 días
15. Principios fundamentales

Ninguna sección es decorativa. Abajo escojo algunas y explico por qué están escritas así.

La lista de prohibiciones es la parte más útil de CLAUDE.md

La mía se ve así:

❌ Sin servicios TypeScript / Node.js
❌ Sin ethers.js / web3.js
❌ Sin Sidekiq (usar Solid Queue)
❌ Sin React / Vue / Svelte (usar Hotwire)
❌ Sin Redis (Solid Cache / Solid Queue / Solid Cable cubren todo)
❌ Sin contratos sin verificar (sólo verificados en Etherscan)
❌ Sin Solana / Bitcoin / Move (sólo EVM)

Es un proyecto Web3. El default del mundo Web3 es TypeScript + ethers.js + Redis + React. Yo voy en contra de eso. Tengo mis razones, pero Claude no las conoce. Sin lista de prohibiciones, Claude basa sus recomendaciones en el "sentido común de la industria" enterrado en sus datos de entrenamiento — y eso casi seguro será el camino TypeScript.

Con la lista, Claude deja de preguntar "¿le agregamos un servicio Node para correr web3.js?". Ese camino está cerrado por defecto.

La clave: cada entrada debe ser explícita y absoluta. No escribas "trata de evitar TypeScript". Escribe "sin TypeScript". Lo ambiguo Claude lo lee como negociable.

Las instrucciones de comportamiento importan más que el estilo de código

El último gran bloque de CLAUDE.md es "Reglas de uso de Claude Code":

### Cuando digo "empieza con X"
1. Primero verifica si las restricciones de CLAUDE.md permiten este enfoque
2. Luego revisa si ya existe una implementación relacionada (no reinventes)
3. Antes de escribir código, abre una nueva rama
4. Después de implementar, corre los tests
5. No hagas auto-commit — cuando el código esté escrito y los tests pasen, detente
   y reporta. Espera a que diga explícitamente "commit"

### Cuando digo "tengo una idea"
No escribas código de inmediato. Primero:
1. Confirma que entendiste (parafrasea de vuelta)
2. Evalúa contra las restricciones de CLAUDE.md
3. Señala problemas potenciales o mejores alternativas
4. Espera mi confirmación antes de actuar

### Cuando enfrentes una bifurcación técnica
Cuando CLAUDE.md no especifica:
1. Elige por defecto la opción más "Rails-nativa"
2. Elige por defecto la opción con menos dependencias
3. Elige por defecto la opción que deje al solo dev iterar más rápido
4. Si dudas, detente y pregunta

Esta parte importa diez veces más que "usa snake_case".

El estilo de código Claude lo aprende leyendo el código. Pero "cuándo detenerse a preguntar", "cuando escuches 'tengo una idea', primero parafrasea en lugar de escribir código" — son patrones de comportamiento. El código solo no los enseña.

La línea más importante: hacia dónde inclinarse en una bifurcación. Esa sola regla decide qué hace Claude cuando no estás en la sala (cuando dices "empieza con X" y te vas). Escríbela claramente y podrás dejarlo trabajar sin supervisión.

Cambia CLAUDE.md antes de cambiar el código

La cabecera de CLAUDE.md dice:

Este documento es la "fuente primaria" del proyecto. Se carga automáticamente al inicio de cada sesión de Claude Code. Cuando cambies decisiones técnicas, cambia esto primero; el código sigue después.

Es un contrato de flujo de trabajo. Cuando decido cambiar alguna elección técnica — digamos, subir el modelo principal de IA de gpt-5-mini a gpt-5 — el primer paso no es tocar el initializer. El primer paso es editar este fragmento de CLAUDE.md:

ai:
  fast: gpt-5-mini      # antes
  fast: gpt-5           # después

Después dejo que Claude lea CLAUDE.md y actualice el código para que coincida.

¿Por qué? Porque si cambias un valor en el código y CLAUDE.md no se actualiza, la próxima vez que Claude lea CLAUDE.md verá el valor viejo y "amablemente" revertirá tu código. El conflicto nace de un único punto de fallo — CLAUDE.md desactualizado. Cuando la constitución se atrasa respecto a la realidad, empiezan las guerras civiles.

Tratar CLAUDE.md como constitución significa: siempre va por delante del código.

Qué pasó después

smarts.md, 5 días, 92 commits:

  • Día 1: Esqueleto Rails 8 + despliegue Kamal en vivo
  • Día 2: MVP de docs de contratos + enriquecimiento con IA + adaptador Uniswap V3
  • Día 3: Servidor MCP + 5 MCP tools + slugs amigables
  • Día 4: SEO + tarjetas OG + featured contracts + GenericErc20Adapter
  • Día 5: Discovery AI-nativo (llms.txt + .well-known/mcp.json) + adaptación móvil

Vida media de cada PR: 30 minutos. Sin grandes refactors. Sin "esa dirección estaba mal, rollback".

No porque Claude sea mágico. Porque cada sesión corrió sobre 565 líneas de raíles. Sabía que no debía meter TypeScript, sabía que Solid Queue era la cola por defecto, sabía que las funciones view se cachean 60 segundos, sabía que cada service implementa un método de clase call, sabía que debía esperar mi confirmación antes de hacer commit.

Quítale la mitad de esas restricciones y obtienes: 30 minutos al día explicando "por qué no usamos X", 5 minutos revisando la dependencia que metió "de paso", y un Gemfile que se va cayendo solo.

Cómo empezar a escribir el tuyo

No empieces de un archivo en blanco. Empieza por la decisión más reciente que te dolió.

Si lo último que hizo Claude fue "meter dependencias nuevas todo el tiempo", escribe la lista de prohibiciones.
Si fue "cambia la arquitectura por cualquier cosa", escribe el diagrama de arquitectura + "agregar microservicios, cambiar de DB, etc. requiere confirmación".
Si fue "no escribe tests", escribe "qué debe tener tests unitarios obligatoriamente".
Si fue "commits demasiado agresivos", escribe "no auto-commit, esperar instrucción explícita".

Cada dolor, una entrada. Lo demás, por ahora, no.

Tres meses después tendrás un CLAUDE.md de 500 líneas, donde cada línea está respaldada por un "no quiero que vuelva a hacer esto" concreto. Ese documento le gana a cualquier plantilla, porque está afinado a tu proyecto, tu flujo, tu equipo (aunque seas tú solo).

Una constitución no se escribe de una. Cristaliza, conflicto a conflicto.


Fuente: github.com/defi-io/smarts