Capítulo 7: Rules: Convenciones Siempre Activas
1. ¿Qué son las Rules en Claude Code?
Las rules son el mecanismo más fundamental del sistema Everything Claude Code (ECC). Representan convenciones y estándares que Claude sigue siempre, en cada interacción, sin necesidad de ser invocadas explícitamente por el usuario.
Para entender qué son las rules, primero hay que distinguirlas de los otros dos artefactos principales del sistema:
Rules vs Skills vs Agentes
El sistema ECC tiene tres tipos de artefactos con roles muy diferentes:
Rules (Reglas) son directivas permanentes. Viven en archivos Markdown dentro de directorios rules/ y Claude las carga automáticamente al inicio de cada conversación. No requieren ningún comando especial para activarse. Definen comportamiento por defecto: cómo nombrar variables, cómo hacer commits, qué validaciones aplicar. Son el “siempre haz esto”.
Skills (Habilidades) son capacidades especializadas que se invocan bajo demanda. El usuario escribe /nombre-del-skill cuando necesita esa capacidad específica. Por ejemplo, /code-review activa el proceso de revisión de código. Los skills pueden ser complejos y tener múltiples pasos, pero solo se ejecutan cuando se les llama. Son el “haz esto cuando te lo pida”.
Agentes son sub-procesos independientes que Claude delega para tareas específicas. Se ejecutan en paralelo o secuencia cuando la tarea lo amerita. El orchestrator principal coordina agentes especializados. Son el “delegá esto a alguien”.
La regla de distinción más práctica: si algo debe aplicarse en toda escritura de código, va en una rule. Si algo requiere un flujo especializado que el usuario activa intencionalmente, va en un skill.
Cómo Claude Carga las Rules en Memoria
Cuando Claude Code inicia una sesión, el sistema carga automáticamente los archivos Markdown de los directorios rules/. Estos archivos se inyectan como parte del contexto del sistema antes de que el usuario escriba su primer mensaje. Esto significa que:
- Las rules nunca consumen tokens del presupuesto de la conversación visible al usuario
- Claude “ya sabe” estas convenciones desde el momento cero
- Las rules se aplican proactivamente, no reactivamente
El mecanismo es conceptualmente similar a un system prompt que se construye dinámicamente a partir de múltiples archivos, donde cada archivo aporta una sección de instrucciones.
2. Cómo Claude Code Carga las Rules
La jerarquía de carga de rules en ECC sigue un modelo de capas con dos niveles principales:
Nivel 1: User-Level Rules (~/.claude/rules/)
Las rules de nivel usuario viven en el directorio home del usuario: ~/.claude/rules/. Estas rules se aplican a todas las sesiones de Claude Code, independientemente del proyecto en el que se esté trabajando.
Son ideales para convenciones personales que el desarrollador quiere en todos sus proyectos:
- Estilo de código preferido
- Formato de commits personal
- Herramientas de testing favoritas
Nivel 2: Project-Level Rules (.claude/rules/)
Las rules de nivel proyecto viven dentro del repositorio, en .claude/rules/. Estas rules solo se aplican cuando Claude Code está trabajando dentro de ese proyecto específico.
Son ideales para convenciones del equipo o requisitos del stack tecnológico:
- Framework específico del proyecto (Next.js, Django, etc.)
- Patrones de arquitectura del equipo
- Estándares de seguridad de la organización
Orden de Precedencia
Cuando hay un conflicto entre una rule de usuario y una rule de proyecto, la rule de proyecto tiene precedencia. La lógica es que las convenciones específicas del proyecto son más relevantes que las preferencias personales del desarrollador cuando se trabaja en ese contexto.
graph TD
A[Claude Code inicia sesión] --> B[Carga rules de ~/.claude/rules/]
B --> C[Carga rules de .claude/rules/ del proyecto]
C --> D{¿Conflicto entre rules?}
D -->|Sí| E[Rule de proyecto tiene precedencia]
D -->|No| F[Ambas se aplican]
E --> G[Claude listo para trabajar]
F --> G
El Rol de common/
Dentro del directorio de rules, existe un subdirectorio especial: common/. Las rules en common/ son universales: se aplican independientemente del lenguaje de programación. Son la base sobre la que se construyen todas las demás rules.
El sistema ECC está diseñado para que common/ sea siempre el primer conjunto de rules que se instala. Sin common/, el agente carece de los principios fundamentales que hacen coherente todo lo demás.
3. Estructura de Directorios del Repo ECC
El repositorio de Everything Claude Code tiene una estructura clara y predecible para sus rules:
graph LR
A[rules/] --> B[common/]
A --> C[typescript/]
A --> D[python/]
A --> E[golang/]
A --> F[swift/]
A --> G[php/]
A --> H[rust/]
A --> I[java/]
A --> J[ruby/]
B --> B1[coding-style.md]
B --> B2[git-workflow.md]
B --> B3[testing.md]
B --> B4[security.md]
B --> B5[performance.md]
B --> B6[development-workflow.md]
B --> B7[patterns.md]
B --> B8[agents.md]
B --> B9[hooks.md]
rules/common/ — Las reglas universales que aplican a todos los proyectos sin importar el lenguaje. Esta es la base fundamental del sistema ECC.
rules/typescript/ — Rules específicas para proyectos TypeScript y JavaScript. Incluyen configuración de tipos estrictos, patrones de async/await, y convenciones de módulos.
rules/python/ — Rules para proyectos Python. Cubren PEP 8, type hints obligatorios, gestión de entornos virtuales, y patrones async con asyncio.
rules/golang/ — Rules para Go. Enfatizan el manejo idiomático de errores, interfaces implícitas, y concurrencia con goroutines.
rules/swift/ — Rules para Swift, especialmente para proyectos iOS/macOS. Cubren Swift 6 concurrency, actors, y protocolos.
rules/php/ — Rules para PHP, con foco en Laravel, seguridad específica de PHP, y patrones modernos.
rules/rust/ — Rules para Rust. Ownership, borrowing, gestión de errores con Result/Option, y patrones seguros.
rules/java/ — Rules para proyectos Java/Kotlin/Spring.
rules/ruby/ — Rules para Ruby y Rails.
4. La Regla de Oro: common/ Siempre Se Instala
Existe una convención fundamental en ECC que se denomina “La Regla de Oro”: las rules de common/ siempre deben estar instaladas. Esta no es una recomendación opcional, sino un requisito del sistema.
Por qué common/ es la Base
Las rules en common/ establecen principios que trascienden cualquier lenguaje de programación. La inmutabilidad de datos es igual de importante en TypeScript que en Python. El formato de commits convencionales aplica a cualquier proyecto. La cobertura mínima de tests del 80% no depende del framework.
Sin common/, el agente puede producir código que:
- Muta estado de forma impredecible
- Tiene mensajes de commit incoherentes
- Carece de tests o los tiene mal estructurados
- Deja vulnerabilidades de seguridad básicas
- Ignora principios de performance fundamentales
Qué Pasa si No Las Tenés
La ausencia de las rules de common/ no genera un error explícito. Claude Code no “falla” si faltan. Lo que ocurre es más sutil y más peligroso: el agente opera sin principios guía, tomando decisiones de estilo y arquitectura ad-hoc según lo que parezca razonable en el momento. Esto genera inconsistencia a lo largo del tiempo y entre diferentes sesiones.
Por ejemplo, sin coding-style.md, Claude puede mutar un array en un lugar y crear un nuevo array en otro, dependiendo de cómo esté formulada la pregunta. Sin testing.md, puede escribir tests después del código o saltearlos cuando parece complicado.
Instalación Correcta
El proceso recomendado para cualquier proyecto nuevo es:
- Instalar primero
common/completo - Instalar las rules del lenguaje principal del proyecto
- Agregar rules específicas del proyecto si se necesitan
Nunca instalar solo las rules de un lenguaje específico sin common/.
5. coding-style.md — Análisis Completo
El archivo coding-style.md es probablemente la rule más importante del sistema. Define cómo debe ser el código en sí mismo, independientemente de qué hace el código.
Principio 1: Inmutabilidad (CRÍTICO)
La rule marca este principio como CRITICAL en mayúsculas por una razón: la mutación de datos es la fuente de una clase entera de bugs que son extremadamente difíciles de debuggear.
El problema con la mutación:
Cuando una función modifica un objeto que recibió como parámetro, cualquier parte del código que tenga una referencia a ese objeto ve el cambio. En sistemas con múltiples funciones, componentes o threads, esto crea dependencias implícitas que no están documentadas en ningún lado.
Código INCORRECTO (mutación en lugar):
function setUserName(user: User, name: string): void {
user.name = name; // Modifica el objeto original
}
const user = { id: 1, name: "Ana" };
setUserName(user, "María");
// user.name ahora es "María" — cualquier otra referencia a este objeto también lo ve
Código CORRECTO (retorna nueva copia):
function setUserName(user: User, name: string): User {
return { ...user, name }; // Retorna nuevo objeto con el cambio
}
const user = { id: 1, name: "Ana" };
const updatedUser = setUserName(user, "María");
// user sigue siendo { id: 1, name: "Ana" }
// updatedUser es { id: 1, name: "María" }
Rationale de la rule: El código inmutable hace que las funciones sean puras — su comportamiento depende solo de los inputs, no de estado externo mutable. Esto hace el debugging mucho más fácil (podés razonar sobre cada función de forma aislada), habilita la concurrencia segura (múltiples threads pueden leer sin coordinación), y facilita el testing (no hay setup de estado previo necesario).
Consecuencias de no seguirlo:
En proyectos medianos, la mutación de estado empieza a generar bugs del tipo “esto funcionaba ayer”. La función A modifica un objeto, la función B asume que ese objeto tiene el valor original, y el bug aparece solo cuando A y B se ejecutan en cierto orden. Estos bugs son especialmente difíciles de reproducir en tests porque los tests usualmente tienen control total del orden de ejecución.
Principio 2: Organización de Archivos
La rule establece una filosofía clara: muchos archivos pequeños son mejores que pocos archivos grandes. Los números concretos son:
- Típico: 200-400 líneas por archivo
- Máximo: 800 líneas
El rationale es alto cohesión y bajo acoplamiento. Un archivo de 800 líneas que hace cinco cosas diferentes es muy difícil de mantener. Cinco archivos de 160 líneas, cada uno con una responsabilidad clara, son mucho más fáciles de entender, testear y modificar.
La directive concreta: cuando un módulo empieza a crecer, extraer utilities a archivos separados antes de llegar al límite.
INCORRECTO — un archivo monolítico:
user-service.ts (1200 líneas con autenticación, perfil, permisos, notificaciones)
CORRECTO — responsabilidades separadas:
user-auth.service.ts (200 líneas — solo autenticación)
user-profile.service.ts (180 líneas — solo perfil)
user-permissions.service.ts (150 líneas — solo permisos)
user-notifications.service.ts (170 líneas — solo notificaciones)
Principio 3: Manejo de Errores
La rule requiere manejo de errores comprehensivo en tres dimensiones:
Explícito en cada nivel: No hay “me olvido de manejar este error porque es poco probable”. Si una función puede fallar, el error se maneja.
INCORRECTO:
async function fetchUser(id: string) {
const response = await fetch(`/api/users/${id}`);
return response.json(); // ¿Qué pasa si fetch falla? ¿Si json() falla?
}
CORRECTO:
async function fetchUser(id: string): Promise<Result<User, ApiError>> {
try {
const response = await fetch(`/api/users/${id}`);
if (!response.ok) {
return { ok: false, error: new ApiError(response.status) };
}
const data = await response.json();
return { ok: true, data };
} catch (error) {
return { ok: false, error: new ApiError(500, String(error)) };
}
}
Mensajes amigables en UI: Los errores que llegan al usuario no deben ser stack traces ni códigos HTTP. Deben ser mensajes que el usuario pueda entender y actuar.
INCORRECTO (UI):
Error: TypeError: Cannot read properties of undefined (reading 'name')
CORRECTO (UI):
No pudimos cargar tu perfil. Por favor, intentá de nuevo más tarde.
Contexto detallado en servidor: En el servidor, los logs de error deben incluir todo el contexto necesario para reproducir y debuggear el problema: ID de usuario, parámetros de la request, timestamp, stack trace completo.
Principio 4: Validación de Inputs
La validación debe ocurrir en los límites del sistema. Un límite es cualquier punto donde datos externos ingresan al sistema: endpoints HTTP, websockets, lectura de archivos, datos de bases de datos.
Este principio previene que datos malformados o maliciosos lleguen a la lógica de negocio. La validación temprana significa errores más claros y seguridad más sólida.
Code Quality Checklist
La rule incluye un checklist de calidad que Claude debe verificar antes de considerar el código completo:
- Código legible y bien nombrado (sin abreviaturas crípticas)
- Funciones pequeñas (menos de 50 líneas)
- Archivos enfocados (menos de 800 líneas)
- Sin anidamiento profundo (máximo 4 niveles)
- Manejo de errores correcto
- Sin valores hardcodeados
- Sin mutaciones
6. git-workflow.md — Análisis Completo
La rule de git workflow estandariza cómo el equipo (y Claude) interactúan con el sistema de control de versiones.
Conventional Commits: El Formato Estándar
El formato establecido por la rule es:
<tipo>: <descripción>
Los tipos válidos y cuándo usar cada uno:
feat — Introduce una nueva funcionalidad visible al usuario.
Ejemplos correctos:
feat: agregar autenticación con Google OAuth
feat: implementar búsqueda en tiempo real
feat: exportar reportes a PDF
fix — Corrige un bug que afectaba el comportamiento esperado.
Ejemplos correctos:
fix: corregir cálculo de descuento para usuarios premium
fix: resolver race condition en actualización de perfil
fix: parsear correctamente fechas en zona horaria UTC-3
refactor — Cambia la estructura del código sin cambiar el comportamiento externo.
Ejemplos correctos:
refactor: extraer lógica de validación a módulo separado
refactor: reemplazar clase UserManager con funciones puras
refactor: simplificar cadena de promesas con async/await
docs — Cambios solo en documentación.
docs: documentar parámetros de la función calcularPrecio
docs: agregar ejemplos de uso a README
test — Agrega o modifica tests sin cambiar código de producción.
test: cubrir casos edge en validación de email
test: agregar tests de integración para endpoint de pagos
chore — Tareas de mantenimiento que no afectan el código de producción.
chore: actualizar dependencias de seguridad
chore: configurar lint en pre-commit hook
perf — Optimizaciones de performance sin cambiar comportamiento.
perf: cachear resultados de queries frecuentes
perf: lazy load de imágenes en feed principal
ci — Cambios en configuración de CI/CD.
ci: agregar step de análisis de cobertura a pipeline
ci: configurar deployment automático a staging
Por Qué Este Formato Importa
Los commits convencionales no son solo estética. Tienen consecuencias funcionales:
-
Generación automática de changelogs: Herramientas como
conventional-changelogpueden generar notas de release automáticamente clasificando los commits por tipo. -
Semantic versioning automático: Con este formato, es posible determinar automáticamente si un cambio requiere incremento de major, minor o patch version.
-
Mejor
git log: La búsqueda y filtrado de commits se vuelve trivial:git log --grep="^feat:"muestra solo features nuevas. -
Claridad para code review: El reviewer inmediatamente sabe qué tipo de cambio esperar.
Pull Request Workflow
La rule establece un workflow de cuatro pasos para PRs:
Paso 1: Analizar el historial completo de commits
El error más común al crear un PR es describir solo el último commit. La rule es explícita: analizar el historial completo desde que el branch divergió del main. El comando correcto es:
git log main...HEAD --oneline
git diff main...HEAD
Paso 2: Usar git diff [base-branch]...HEAD
Este comando específico muestra exactamente qué cambió desde que el branch se creó, sin incluir cambios que llegaron a main después. La diferencia entre .. y ... importa:
git diff main..HEAD— diferencia entre el tip de main y el tip del branchgit diff main...HEAD— diferencia entre el punto donde los branches divergieron y el tip del branch (generalmente lo que queremos para PRs)
Paso 3: Draft de PR summary completo
El summary debe cubrir:
- Qué problema resuelve
- Qué cambios se hicieron y por qué
- Qué no se cambió (scope explícito)
- Dependencias o condiciones previas
Paso 4: Test plan con TODOs
El PR debe incluir un checklist de qué hay que verificar manualmente, automatizar, o revisar después del merge.
7. testing.md — Análisis Completo
La rule de testing es una de las más estrictas del sistema ECC. Establece TDD como workflow obligatorio, no como práctica opcional.
Cobertura Mínima: 80%
El umbral del 80% no es arbitrario. Representa el equilibrio entre:
- Suficiente cobertura para tener confianza en los cambios
- No tanto overhead como para paralizar el desarrollo
El 80% no significa que el 20% restante no importa. Significa que el 20% que no está cubierto debe ser código que genuinamente es difícil de testear (integrations de terceros, UI específica de plataforma, casos edge extremamente raros).
Los Tres Tipos de Tests: Todos Obligatorios
La rule especifica tres tipos de tests, y la palabra “ALL required” es intencional.
Tipo 1: Unit Tests
Los unit tests verifican funciones individuales, utilities y componentes en aislamiento total. Las dependencias externas se mockean.
Cuándo escribirlos: para cada función pura, cada componente UI, cada transformer de datos.
Características de un buen unit test:
- Rápido (millisegundos)
- Determinístico (misma salida siempre para el mismo input)
- Aislado (no depende de estado externo)
- Nombre claro que describe qué se verifica
// Ejemplo de unit test correcto
describe("calcularDescuento", () => {
it("debe aplicar 10% a usuarios premium", () => {
const usuario = { tipo: "premium" };
const precio = 100;
expect(calcularDescuento(usuario, precio)).toBe(90);
});
it("debe retornar el precio original para usuarios standard", () => {
const usuario = { tipo: "standard" };
const precio = 100;
expect(calcularDescuento(usuario, precio)).toBe(100);
});
it("debe lanzar error si el precio es negativo", () => {
const usuario = { tipo: "premium" };
expect(() => calcularDescuento(usuario, -10)).toThrow("Precio inválido");
});
});
Tipo 2: Integration Tests
Los integration tests verifican que múltiples componentes funcionan correctamente juntos. Incluyen base de datos real (o en memoria), llamadas HTTP reales (contra servidor de test), y sistema de archivos real.
Cuándo escribirlos: para cada endpoint de API, para cada operación de base de datos, para cada flujo que cruza múltiples capas de la arquitectura.
// Ejemplo de integration test para endpoint
describe("POST /api/usuarios", () => {
it("debe crear usuario y retornar 201", async () => {
const response = await request(app)
.post("/api/usuarios")
.send({ email: "[email protected]", password: "SecurePass123!" });
expect(response.status).toBe(201);
expect(response.body.data.email).toBe("[email protected]");
// Verificar que realmente se guardó en DB
const usuario = await db.usuarios.findOne({ email: "[email protected]" });
expect(usuario).toBeTruthy();
});
});
Tipo 3: E2E Tests
Los end-to-end tests verifican flujos críticos del usuario completos, desde el browser (o cliente) hasta la base de datos y de vuelta. Son los más lentos pero dan la mayor confianza de que el sistema funciona end-to-end.
La rule especifica: “framework chosen per language”. No hay un framework obligatorio, pero hay que tener E2E para flujos críticos.
Cuándo escribirlos: para el flujo de signup/login, para el flujo de pago, para el flujo principal del negocio.
TDD: El Workflow Obligatorio
La rule establece TDD como MANDATORY. El ciclo Red-Green-Refactor es el único workflow aceptado:
Red — Escribir el test primero:
Antes de escribir una sola línea de código de implementación, el test ya debe existir y debe fallar. Esto es crucial: un test que nunca falló no prueba nada.
// PRIMERO — escribir este test
it("debe enviar email de bienvenida al crear usuario", async () => {
const emailService = mockEmailService();
await crearUsuario({ email: "[email protected]" }, emailService);
expect(emailService.send).toHaveBeenCalledWith({
to: "[email protected]",
subject: "Bienvenido"
});
});
// Ejecutar: DEBE FALLAR (la función no existe todavía)
Green — Implementación mínima:
Escribir el código más simple posible que hace pasar el test. No optimizar, no generalizar, solo hacer pasar ese test específico.
// SEGUNDO — escribir esta implementación
async function crearUsuario(data: { email: string }, emailService: EmailService) {
// Implementación mínima
await emailService.send({
to: data.email,
subject: "Bienvenido"
});
}
// Ejecutar: DEBE PASAR
Refactor — Mejorar la calidad:
Con el test verde, es seguro refactorizar. El test es el net de seguridad que garantiza que los cambios no rompen el comportamiento.
Verify — Verificar cobertura:
Después de cada ciclo, verificar que la cobertura se mantiene en 80%+.
Por Qué TDD No Es Opcional
La resistencia más común a TDD es “tarda más tiempo”. Esta percepción es incorrecta a mediano plazo por varias razones:
- Los bugs encontrados en tests cuestan exponencialmente menos que bugs encontrados en producción.
- Los tests escritos después tienden a testear solo el happy path. Los tests escritos primero obligan a pensar en los edge cases.
- El código diseñado para ser testeable tiende a ser código con bajo acoplamiento, lo que facilita cambios futuros.
8. security.md — Análisis Completo
La rule de seguridad es la única que incluye un protocolo de respuesta explícito: detener todo si se encuentra un issue de seguridad. Esto refleja la severidad del dominio.
Los Checks Obligatorios Pre-Commit
La rule establece que estos checks deben ejecutarse antes de cualquier commit, no solo ante cambios de seguridad.
Check 1: No secrets hardcodeados
INCORRECTO — secret en el código:
const apiKey = "sk-prod-abc123xyz789";
const connection = createConnection("postgresql://admin:MyP@ssw0rd@prod-db:5432/mydb");
CORRECTO — usando variables de entorno:
const apiKey = process.env.API_KEY;
if (!apiKey) throw new Error("API_KEY environment variable is required");
const connection = createConnection(process.env.DATABASE_URL);
El problema con secrets hardcodeados va más allá de “alguien puede verlo en GitHub”. Los secrets en código fuente terminan en:
- Git history (incluso si se eliminan después, siguen en el historial)
- Logs de CI/CD
- Builds de desarrollo compartidas
- Cualquier snapshot o backup del repositorio
Check 2: Validación de todos los inputs del usuario
INCORRECTO — input sin validar:
app.get("/usuarios/:id", async (req, res) => {
const userId = req.params.id;
const usuario = await db.query(`SELECT * FROM usuarios WHERE id = ${userId}`);
res.json(usuario);
});
CORRECTO — validación antes de usar:
app.get("/usuarios/:id", async (req, res) => {
const userId = req.params.id;
if (!isValidUUID(userId)) {
return res.status(400).json({ error: "ID inválido" });
}
const usuario = await db.query("SELECT * FROM usuarios WHERE id = $1", [userId]);
res.json(usuario);
});
Check 3: SQL injection prevention
La regla es simple: nunca interpolar strings en queries SQL. Siempre usar queries parametrizadas o un ORM que lo maneje.
INCORRECTO — interpolación directa (SQL injection):
query = f"SELECT * FROM users WHERE email = '{email}'"
cursor.execute(query)
Si email es "'; DROP TABLE users; --", esta query destruye la tabla.
CORRECTO — query parametrizada:
query = "SELECT * FROM users WHERE email = %s"
cursor.execute(query, (email,))
Check 4: XSS prevention
Cross-Site Scripting ocurre cuando HTML de usuario se renderiza sin sanitizar.
INCORRECTO:
<!-- React con dangerouslySetInnerHTML -->
<div dangerouslySetInnerHTML={{ __html: userProvidedContent }} />
CORRECTO — sanitizar antes de renderizar:
import DOMPurify from "dompurify";
const sanitized = DOMPurify.sanitize(userProvidedContent);
<div dangerouslySetInnerHTML={{ __html: sanitized }} />
O mejor aún, evitar dangerouslySetInnerHTML completamente cuando sea posible.
Check 5: CSRF protection
Los tokens CSRF previenen que sitios maliciosos realicen requests en nombre del usuario autenticado.
// Middleware CSRF en Express
import csrf from "csurf";
app.use(csrf({ cookie: true }));
// Incluir token en forms
app.get("/form", (req, res) => {
res.render("form", { csrfToken: req.csrfToken() });
});
Check 6: Rate limiting en todos los endpoints
Sin rate limiting, los endpoints son vulnerables a brute force, DDoS y scraping.
CORRECTO:
import rateLimit from "express-rate-limit";
const loginLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutos
max: 5, // máximo 5 intentos
message: "Demasiados intentos de login. Intentá más tarde."
});
app.post("/auth/login", loginLimiter, loginHandler);
Check 7: Los mensajes de error no deben revelar información sensible
INCORRECTO — error que revela infraestructura:
Error: connection refused to postgresql://[email protected]:5432/mydb
CORRECTO — error genérico para el usuario:
No se pudo completar la operación. Por favor, intentá más tarde.
El error detallado debe ir al log del servidor, nunca al cliente.
El Protocolo de Respuesta ante Issues de Seguridad
La rule establece tres pasos cuando se encuentra un problema de seguridad:
- STOP immediately — Detener cualquier otra implementación. No continuar con la feature.
- Usar security-reviewer agent — Escalar al agente especializado en seguridad para análisis profundo.
- Fix CRITICAL issues before continuing — Los issues críticos de seguridad son bloqueantes. No hay “lo corrijo después”.
Esta firmeza en la rule refleja que los problemas de seguridad encontrados temprano son órdenes de magnitud más baratos de corregir que los encontrados en producción.
9. performance.md — Análisis Completo
La rule de performance en ECC tiene un enfoque inusual: se centra tanto en la performance del código como en la selección correcta de modelos de IA. Esto refleja que ECC es un framework para desarrollo asistido por IA, y la eficiencia de los modelos impacta directamente el costo operativo.
Estrategia de Selección de Modelos
La rule establece tres perfiles de modelos con criterios claros:
Haiku 4.5 — Para agentes frecuentes y workers
Haiku 4.5 tiene aproximadamente el 90% de la capacidad de Sonnet para tareas de codificación, pero a un costo 3x menor. Esto lo hace ideal para:
- Agentes que se invocan frecuentemente (en cada request, en cada archivo procesado)
- Workers en sistemas multi-agente que realizan tareas repetitivas
- Operaciones simples: formateo, renombrado, generación de boilerplate
La lógica de negocio: si una operación se va a ejecutar 1000 veces por día, la diferencia de costo entre Haiku y Sonnet es significativa. Si la calidad es el 90% equivalente, Haiku es la elección correcta.
Sonnet 4.6 — Para desarrollo principal
Sonnet 4.6 es el modelo de codificación más capaz. La rule lo designa para:
- El trabajo de desarrollo principal del día a día
- Orchestrar workflows multi-agente
- Análisis de código complejo
- Refactoring que requiere entender el contexto amplio
Opus 4.5 — Para decisiones arquitectónicas
Opus 4.5 tiene el razonamiento más profundo pero también el mayor costo. Se reserva para:
- Decisiones de arquitectura con implicaciones a largo plazo
- Análisis de sistemas complejos con muchas interdependencias
- Situaciones donde la profundidad de razonamiento justifica el costo
graph TD
A[Tarea recibida] --> B{¿Tipo de tarea?}
B -->|Worker frecuente, tarea simple| C[Haiku 4.5]
B -->|Desarrollo principal, coding| D[Sonnet 4.6]
B -->|Decisión arquitectónica crítica| E[Opus 4.5]
C --> F[3x más económico que Sonnet]
D --> G[Balance costo/calidad óptimo]
E --> H[Máximo razonamiento, mayor costo]
Context Window Management
La rule establece una guía importante sobre el manejo de la ventana de contexto: evitar el último 20% para tareas complejas.
El motivo es que cuando un modelo está cerca del límite de su contexto, la calidad del output degrada. El modelo empieza a “perder” información del inicio del contexto para acomodar lo nuevo. Las tareas que más sufren de esto son:
- Refactoring a gran escala que requiere recordar el estado inicial del código
- Implementación de features que se extiende por múltiples archivos
- Cualquier tarea que requiere coherencia entre múltiples decisiones a lo largo del tiempo
La estrategia correcta: si se detecta que el contexto está llenándose, iniciar una nueva conversación con el contexto esencial resumido, en lugar de continuar degradando la calidad del trabajo.
Extended Thinking
Para decisiones que requieren razonamiento profundo (usualmente en conjunto con Opus 4.5), la rule menciona el uso de extended thinking. Esta capacidad permite al modelo “pensar” antes de responder, explorando múltiples caminos de razonamiento.
Es apropiado para:
- Análisis de trade-offs entre arquitecturas
- Debugging de bugs muy complejos con múltiples causas posibles
- Diseño de sistemas que deben satisfacer muchos constraints simultáneos
10. development-workflow.md — Análisis Completo
Esta rule establece el proceso completo para implementar una nueva feature, desde cero hasta código listo para review.
Fase 0: Research & Reuse (Obligatorio)
La rule marca esta fase como mandatory y la coloca en el paso 0, antes de cualquier planeamiento o codificación. El principio es: no inventar lo que ya existe.
Búsqueda en GitHub primero:
Antes de escribir una línea de código, buscar si ya existe una implementación open source de calidad. GitHub tiene miles de millones de líneas de código; las probabilidades de que alguien ya resolvió el mismo problema son muy altas.
La búsqueda de GitHub es especialmente valiosa para:
- Patrones de autenticación
- Integraciones con APIs de terceros
- Algoritmos de procesamiento de datos
- Configuraciones de infraestructura
Documentación de librerías con Context7:
Si la tarea involucra una librería conocida, consultar su documentación actualizada con la herramienta Context7 antes de implementar. La razón: las APIs cambian, los patrones recomendados evolucionan. Implementar basándose en documentación desactualizada o en el conocimiento de training del modelo genera código que puede ser incorrecto o subóptimo.
Búsqueda en registros de paquetes:
Para cualquier funcionalidad que parece genérica, verificar que no existe ya una librería de calidad:
- npm/bun para JavaScript/TypeScript
- PyPI para Python
- crates.io para Rust
- pkg.go.dev para Go
El principio es: antes de implementar, responder la pregunta “¿ya existe esto?”. El costo de buscar 5 minutos es mucho menor que el costo de mantener código custom cuando existe una librería mantenida por la comunidad.
Fase 1: Plan First — Usar el Agente Planner
Antes de escribir código, crear un plan. La rule especifica usar el agente planner para esta fase.
El planner produce:
- Descomposición de la feature en tareas atómicas
- Identificación de dependencias entre tareas
- Estimación de complejidad
- Identificación de riesgos y decisiones de diseño clave
Sin un plan, el desarrollo tiende a “extenderse” — empezar por algo, descubrir que falta otro componente, implementarlo, descubrir otro requisito, etc. Este proceso es caótico y produce código menos coherente.
Fase 2: TDD Approach — Usar el Agente tdd-guide
Con el plan en mano, el agente tdd-guide guía la implementación siguiendo el ciclo Red-Green-Refactor ya descripto. Este agente asegura que los tests se escriben antes de la implementación, no después.
Fase 3: Code Review — Usar code-reviewer Inmediatamente
La rule especifica un timing crítico: usar el agente code-reviewer inmediatamente después de escribir código. No al final del día, no antes de hacer el commit, sino durante el proceso de escritura.
El code-reviewer verifica:
- Adherencia a las rules de coding-style
- Posibles bugs o edge cases no manejados
- Oportunidades de simplificación
- Violaciones de principios SOLID
- Issues de seguridad
El feedback temprano es más valioso que el tardío porque hay menos código escrito (menos que cambiar) y menos contexto que reaprender.
Fase 4: Commit & Push
Con código revisado y tests en verde, el commit sigue el formato de conventional commits de git-workflow.md.
11. patterns.md — Análisis Completo
Esta rule captura patrones de alto nivel que aplican a cualquier proyecto.
Skeleton Projects
El concepto de “skeleton project” es central en el workflow de ECC: cuando se empieza un proyecto nuevo, buscar un proyecto esqueleto de alta calidad como punto de partida en lugar de construir desde cero.
El proceso recomendado:
Paso 1 — Buscar skeleton projects battle-tested:
Los mejores skeleton projects son los que tienen:
- Años de uso en producción
- Comunidad activa que mantiene actualizado
- Opiniones bien justificadas sobre las decisiones de arquitectura
- Documentación que explica el “por qué” además del “qué”
Paso 2 — Usar agentes paralelos para evaluar opciones:
En lugar de evaluar cada opción secuencialmente, lanzar múltiples agentes en paralelo donde cada uno evalúa un skeleton diferente según los mismos criterios. Esto reduce el tiempo de investigación.
Paso 3 — Clonar el mejor match como foundation:
El skeleton ganador se clona y se adapta al proyecto específico. Esto es más eficiente que inicializar desde cero porque:
- La arquitectura base ya está pensada
- Las dependencias ya están seleccionadas y verificadas
- Los patterns de seguridad y performance ya están incorporados
Repository Pattern
La rule establece el Repository Pattern como el patrón estándar para acceso a datos.
Concepto: Encapsular todo acceso a datos (base de datos, API externa, filesystem) detrás de una interfaz consistente. El código de negocio no sabe si los datos vienen de PostgreSQL, Redis o una API REST.
Implementación mínima:
// Interfaz del repositorio
interface UserRepository {
findById(id: string): Promise<User | null>;
findByEmail(email: string): Promise<User | null>;
save(user: User): Promise<User>;
delete(id: string): Promise<void>;
}
// Implementación concreta
class PostgresUserRepository implements UserRepository {
async findById(id: string): Promise<User | null> {
const row = await db.query("SELECT * FROM users WHERE id = $1", [id]);
return row ? mapRowToUser(row) : null;
}
// ... demás métodos
}
// Test con mock
class MockUserRepository implements UserRepository {
private users: User[] = [];
async findById(id: string): Promise<User | null> {
return this.users.find(u => u.id === id) ?? null;
}
// ... demás métodos
}
// El servicio de negocio no sabe qué implementación usa
class UserService {
constructor(private repo: UserRepository) {}
async getUser(id: string): Promise<User> {
const user = await this.repo.findById(id);
if (!user) throw new UserNotFoundError(id);
return user;
}
}
Beneficios concretos:
- Los tests de negocio no necesitan base de datos real
- Se puede cambiar de PostgreSQL a MongoDB cambiando solo la implementación del repositorio
- La lógica de mapeo (row → domain object) está encapsulada
API Response Format
La rule establece un formato de envelope consistente para todas las respuestas de API:
interface ApiResponse<T> {
success: boolean;
data?: T;
error?: {
code: string;
message: string;
};
metadata?: {
page?: number;
total?: number;
timestamp: string;
};
}
Respuesta exitosa:
{
"success": true,
"data": { "id": "123", "email": "[email protected]" },
"metadata": { "timestamp": "2024-12-17T10:30:00Z" }
}
Respuesta de error:
{
"success": false,
"error": {
"code": "USER_NOT_FOUND",
"message": "No existe un usuario con el ID especificado"
},
"metadata": { "timestamp": "2024-12-17T10:30:01Z" }
}
La consistencia en el formato de respuesta simplifica el código del cliente: siempre verificar success, luego acceder a data o error según corresponda.
12. agents.md — Análisis Completo
Esta rule define cómo y cuándo delegar trabajo a agentes especializados, y cómo orquestarlos eficientemente.
El Catálogo de Agentes Disponibles
ECC incluye un conjunto de agentes especializados, cada uno con un dominio claro:
| Agente | Especialidad | Cuándo invocar |
|---|---|---|
planner | Descomposición de features en tareas atómicas | Al inicio de cualquier feature no trivial |
architect | Decisiones de arquitectura y diseño de sistemas | Ante decisiones con impacto a largo plazo |
tdd-guide | Guía el ciclo TDD Red-Green-Refactor | Al implementar cualquier feature |
code-reviewer | Revisión de código escrito | Inmediatamente después de escribir código |
security-reviewer | Auditoría de seguridad | Al encontrar posibles issues de seguridad |
build-error-resolver | Resolución de errores de compilación y build | Cuando el build falla |
e2e-runner | Ejecución e interpretación de tests E2E | Al ejecutar y analizar tests |
refactor-cleaner | Refactoring de código con deuda técnica | Al identificar código que necesita limpieza |
doc-updater | Actualización de documentación | Después de cambios de API o arquitectura |
Uso Inmediato: Sin Necesidad de Prompt del Usuario
La rule especifica cuatro situaciones donde los agentes se invocan automáticamente, sin que el usuario lo pida:
1. Feature request compleja → planner agent
Si el usuario pide implementar algo que claramente tiene múltiples componentes o consideraciones de diseño, el planner se invoca antes de empezar a codificar.
2. Código recién escrito → code-reviewer agent
Después de escribir código nuevo, el code-reviewer hace una primera pasada automática. No esperar a que el usuario pida review.
3. Bug fix o nueva feature → tdd-guide agent
Para garantizar que TDD se aplica consistentemente, el tdd-guide se activa automáticamente al empezar a trabajar en un cambio de código.
4. Decisión arquitectónica → architect agent
Cuando hay que elegir entre múltiples enfoques con implicaciones de diseño, el architect analiza los trade-offs.
Ejecución Paralela: El Principio Fundamental
La rule establece que las operaciones independientes siempre deben ejecutarse en paralelo. Esta es una de las optimizaciones más importantes en sistemas multi-agente.
sequenceDiagram
participant O as Orchestrator
participant A1 as Agente 1 (análisis)
participant A2 as Agente 2 (tests)
participant A3 as Agente 3 (docs)
O->>A1: Analizar código
O->>A2: Ejecutar tests
O->>A3: Verificar docs
Note over A1,A3: Ejecución paralela
A1-->>O: Resultado análisis
A2-->>O: Resultado tests
A3-->>O: Resultado docs
O->>O: Integrar resultados
En lugar de esperar a que el análisis termine para ejecutar tests, ambos corren en paralelo. El tiempo total es el del agente más lento, no la suma de todos.
Multi-Perspective Analysis
Para problemas complejos, la rule establece el patrón de “split role sub-agents”: lanzar múltiples agentes con roles explícitamente diferentes para analizar el mismo problema.
Los tres roles más útiles:
Factual Reviewer — Verifica que los hechos sean correctos. ¿Este algoritmo realmente funciona como se describe? ¿Esta configuración es válida?
Senior Engineer — Evalúa desde la perspectiva de mantenibilidad y diseño. ¿Este código va a ser mantenible en 6 meses? ¿Hay una forma más simple de hacer esto?
Security Expert — Evalúa desde la perspectiva de seguridad. ¿Hay algún vector de ataque? ¿Se están manejando correctamente los datos sensibles?
La síntesis de las tres perspectivas produce un análisis más robusto que cualquier perspectiva individual.
13. hooks.md — La Rule sobre Hooks
La rule de hooks define cuándo y cómo usar el sistema de hooks de Claude Code para automatizar verificaciones.
Cuándo Crear Hooks
Los hooks de Claude Code son scripts que se ejecutan automáticamente en momentos clave del workflow. Son diferentes a los git hooks (aunque pueden invocarlos): son hooks del ciclo de vida del agente.
Casos de uso apropiados para hooks:
Pre-tool execution hooks: Verificaciones antes de que Claude ejecute una herramienta. Ejemplo: antes de escribir en un archivo, verificar que el archivo existe y no está en una ubicación restringida.
Post-tool execution hooks: Verificaciones después de que Claude ejecuta una herramienta. Ejemplo: después de escribir código, ejecutar el linter automáticamente.
Notification hooks: Notificar al usuario cuando ocurre algo importante. Ejemplo: cuando se completa un proceso largo.
Cuándo NO Crear Hooks
La rule también establece cuándo los hooks no son la solución correcta:
- Para lógica de negocio principal: los hooks son para verificaciones, no para implementación
- Para features que el usuario debería invocar explícitamente: usar un skill en lugar de un hook
- Para verificaciones que son opcionales: los hooks son siempre activos, usar skills para verificaciones opcionales
Estructura de un Hook
// Estructura básica de un hook en Claude Code
{
name: "lint-after-write",
event: "PostToolUse",
matcher: { tool: "Write", file_extension: [".ts", ".tsx"] },
action: {
type: "command",
command: "bun run lint --fix ${file}"
}
}
Principios de Hooks Efectivos
- Rápidos: Los hooks que tardan más de unos segundos interrumpen el flujo de trabajo
- Seguros ante fallos: Un hook que falla no debe bloquear el trabajo del agente
- Informativos: Si el hook detecta un problema, el mensaje debe ser claro y accionable
- Idempotentes: Ejecutar el hook múltiples veces debe tener el mismo efecto que ejecutarlo una vez
14. TypeScript Rules — Análisis
Las rules de TypeScript en ECC extienden las de common/ con convenciones específicas del ecosistema JavaScript/TypeScript.
Type Safety Estricta
La rule principal de TypeScript es never use any. El tipo any es esencialmente desactivar el sistema de tipos, que es la principal ventaja de TypeScript sobre JavaScript.
INCORRECTO:
function processData(data: any) {
return data.value; // Sin type safety
}
CORRECTO:
interface DataPayload {
value: string;
timestamp: Date;
}
function processData(data: DataPayload): string {
return data.value;
}
Cuando el tipo genuinamente no se conoce (por ejemplo, al parsear JSON externo), usar unknown en lugar de any:
function parseResponse(raw: unknown): ApiResponse {
if (!isApiResponse(raw)) {
throw new Error("Respuesta inválida del servidor");
}
return raw;
}
function isApiResponse(value: unknown): value is ApiResponse {
return (
typeof value === "object" &&
value !== null &&
"success" in value
);
}
Async/Await Sobre Promises Raw
La rule establece usar async/await en lugar de .then().catch() chains para código más legible.
INCORRECTO:
function fetchUser(id: string): Promise<User> {
return fetch(`/api/users/${id}`)
.then(res => res.json())
.then(data => validateUser(data))
.catch(err => { throw new ApiError(err); });
}
CORRECTO:
async function fetchUser(id: string): Promise<User> {
const res = await fetch(`/api/users/${id}`);
if (!res.ok) throw new ApiError(res.status);
const data = await res.json();
return validateUser(data);
}
Strict TypeScript Configuration
La rule requiere configuración estricta en tsconfig.json:
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true
}
}
Estas configuraciones fuerzan patrones correctos:
strictNullChecks: fuerza verificar que un valor no sea null/undefined antes de usarlonoUncheckedIndexedAccess: hace que acceder aarray[i]retorneT | undefined, noTexactOptionalPropertyTypes: distingue entre propiedad ausente y propiedad con valorundefined
Módulos ES vs CommonJS
La rule establece usar módulos ES (import/export) en lugar de CommonJS (require/module.exports) en proyectos nuevos.
CORRECTO:
import { UserService } from "./user.service";
export { createUser } from "./create-user";
Barrel Files con Cuidado
Los barrel files (index.ts que re-exporta todo) son convenientes pero pueden causar problemas de circular dependencies y bundle size. La rule es: usarlos para APIs públicas de módulos, no para todo.
15. Python Rules
Las rules de Python cubren los estándares del ecosistema Python moderno.
PEP 8 Como Base
PEP 8 es el estándar de estilo de Python. Las rules de ECC lo adoptan con algunas adiciones:
- Nombres en snake_case: variables, funciones y módulos
- Nombres en PascalCase: clases
- Constantes en UPPER_SNAKE_CASE
- Líneas máximo 88 caracteres (el estándar de Black formatter)
Type Hints Obligatorios
La rule establece que todos los parámetros y retornos de funciones deben tener type hints.
INCORRECTO:
def calcular_precio(producto, cantidad, descuento):
return producto.precio * cantidad * (1 - descuento)
CORRECTO:
from decimal import Decimal
def calcular_precio(
producto: Producto,
cantidad: int,
descuento: Decimal
) -> Decimal:
return producto.precio * cantidad * (1 - descuento)
Dataclasses y Pydantic
Para modelos de datos, la rule establece preferir dataclasses o Pydantic sobre diccionarios o clases planas:
from dataclasses import dataclass
from datetime import datetime
@dataclass(frozen=True) # frozen=True para inmutabilidad
class Usuario:
id: str
email: str
created_at: datetime
El parámetro frozen=True alinea con la rule de inmutabilidad de common/coding-style.md.
Async Patterns
Para código asíncrono, la rule establece usar asyncio con async/await:
INCORRECTO:
import requests
def fetch_data(url: str) -> dict:
return requests.get(url).json() # Bloqueante
CORRECTO:
import httpx
import asyncio
async def fetch_data(url: str) -> dict:
async with httpx.AsyncClient() as client:
response = await client.get(url)
response.raise_for_status()
return response.json()
Manejo de Errores con Excepciones Específicas
INCORRECTO:
try:
result = procesar(data)
except Exception:
pass # Silenciar todos los errores
CORRECTO:
try:
result = procesar(data)
except ValueError as e:
logger.error("Datos inválidos: %s", e)
raise InvalidDataError(str(e)) from e
except DatabaseError as e:
logger.error("Error de base de datos: %s", e)
raise ServiceUnavailableError() from e
Herramientas del Ecosistema
La rule establece las herramientas estándar para proyectos Python modernos:
- Black: formateo automático de código
- Ruff: linting ultra-rápido (reemplaza flake8, isort, etc.)
- mypy o pyright: verificación estática de types
- pytest: testing framework
- uv o poetry: gestión de dependencias
16. Go Rules
Las rules de Go enfatizan la filosofía idiomática del lenguaje.
Manejo de Errores: El Estilo Go
Go no tiene excepciones. El patrón estándar es retornar el error como segundo valor:
INCORRECTO:
func getUser(id string) User {
// ¿Qué pasa si hay un error?
user, _ := db.Query(id)
return user
}
CORRECTO:
func getUser(id string) (User, error) {
user, err := db.Query(id)
if err != nil {
return User{}, fmt.Errorf("getUser(%s): %w", id, err)
}
return user, nil
}
La rule establece el patrón %w para wrapping de errores, que permite usar errors.Is y errors.As para inspección.
Interfaces Pequeñas
La regla de oro en Go: las interfaces deben ser pequeñas, idealmente de un solo método. Go favorece la composición de interfaces pequeñas sobre jerarquías de herencia complejas.
// INCORRECTO — interfaz demasiado grande
type UserManager interface {
Create(user User) error
Update(user User) error
Delete(id string) error
FindByID(id string) (User, error)
FindByEmail(email string) (User, error)
List(filter Filter) ([]User, error)
}
// CORRECTO — interfaces pequeñas y composables
type UserCreator interface {
Create(user User) error
}
type UserFinder interface {
FindByID(id string) (User, error)
}
type UserRepository interface {
UserCreator
UserFinder
// solo agregar más si es necesario
}
No Usar panic en Código de Producción
panic en Go es equivalente a una excepción no manejada que mata el proceso. La rule establece: nunca usar panic en código de producción. Solo está permitido en:
- Tests (
t.Fatal) - Código de inicialización donde el fallo es irrecuperable
- Validación de invariantes que nunca deberían violarse en producción
Goroutines: Siempre Comunicar por Canales
La regla Go de concurrencia: “Don’t communicate by sharing memory; share memory by communicating.”
INCORRECTO:
var counter int
var mu sync.Mutex
func increment() {
mu.Lock()
counter++
mu.Unlock()
}
CORRECTO para muchos casos:
func counter() chan<- struct{} {
ch := make(chan struct{})
go func() {
count := 0
for range ch {
count++
}
}()
return ch
}
17. Swift Rules
Las rules de Swift están diseñadas para el desarrollo moderno en iOS/macOS con Swift 6.
Swift Concurrency: Actors y async/await
Swift 6 introduce verificación estática de concurrencia. La rule establece usar el modelo de concurrencia nativo:
// Correcto: usar actor para estado compartido
actor UserCache {
private var cache: [String: User] = [:]
func user(for id: String) -> User? {
cache[id]
}
func store(_ user: User) {
cache[user.id] = user
}
}
// Correcto: async/await para operaciones asíncronas
func fetchUser(id: String) async throws -> User {
let url = URL(string: "/api/users/\(id)")!
let (data, _) = try await URLSession.shared.data(from: url)
return try JSONDecoder().decode(User.self, from: data)
}
Protocols Sobre Herencia
Swift favorece protocolos sobre herencia de clases. La rule establece diseñar con Protocol-Oriented Programming:
protocol Displayable {
var displayName: String { get }
}
protocol Identifiable {
var id: String { get }
}
// Composición de protocolos
typealias Entity = Displayable & Identifiable
struct User: Entity {
let id: String
let displayName: String
}
Value Types Sobre Reference Types
Structs y enums son value types en Swift (copiados en asignación). La rule prefiere value types para modelos de datos:
// Correcto: struct para modelos de datos
struct User {
let id: String
var name: String
var email: String
}
// Clase solo cuando se necesita referencia o herencia
class UserSession: ObservableObject {
@Published var currentUser: User?
}
Manejo de Errores con Result
enum NetworkError: Error {
case invalidURL
case noData
case decodingFailed(Error)
}
func fetchUser(id: String) async -> Result<User, NetworkError> {
guard let url = URL(string: "/api/users/\(id)") else {
return .failure(.invalidURL)
}
do {
let (data, _) = try await URLSession.shared.data(from: url)
let user = try JSONDecoder().decode(User.self, from: data)
return .success(user)
} catch is DecodingError {
return .failure(.decodingFailed(error))
}
}
18. PHP Rules
Las rules de PHP están orientadas a proyectos modernos, principalmente con Laravel.
PSR-12 Como Estándar de Estilo
PHP tiene el estándar PSR-12 para estilo de código. La rule lo adopta completamente:
- Clases en PascalCase
- Métodos y propiedades en camelCase
- Constantes en UPPER_SNAKE_CASE
- Uso de espacios, no tabs
Laravel: Service Layer Pattern
La rule establece el patrón de capas para proyectos Laravel:
// Controller: solo coordinación, sin lógica de negocio
class UserController extends Controller
{
public function __construct(
private readonly UserService $userService
) {}
public function store(CreateUserRequest $request): JsonResponse
{
$user = $this->userService->create($request->validated());
return response()->json(['data' => $user], 201);
}
}
// Service: lógica de negocio
class UserService
{
public function create(array $data): User
{
return DB::transaction(function () use ($data) {
$user = User::create($data);
event(new UserCreated($user));
return $user;
});
}
}
Seguridad Específica de PHP
PHP tiene vectores de ataque históricos específicos. La rule establece:
CSRF Protection: Siempre usar el middleware CSRF de Laravel en formularios.
Mass Assignment Protection: Siempre definir $fillable o $guarded en los modelos Eloquent.
INCORRECTO:
class User extends Model
{
// Sin fillable/guarded — vulnerable a mass assignment
}
CORRECTO:
class User extends Model
{
protected $fillable = ['name', 'email', 'password'];
// 'is_admin' y otros campos sensibles NO están en fillable
}
File Upload Validation: Nunca confiar en el tipo MIME reportado por el cliente.
// INCORRECTO
if ($request->file('avatar')->getMimeType() === 'image/jpeg') {
// ...
}
// CORRECTO — validar con Intervention Image o verificación real
$request->validate([
'avatar' => ['required', 'image', 'max:2048', 'mimes:jpg,jpeg,png']
]);
Type Declarations
PHP moderno (8.x) soporta type declarations completos. La rule los hace obligatorios:
// INCORRECTO
function calcularTotal($items, $descuento) {
return array_sum($items) * (1 - $descuento);
}
// CORRECTO
function calcularTotal(array $items, float $descuento): float
{
return array_sum($items) * (1 - $descuento);
}
19. Rules vs CLAUDE.md
Una pregunta frecuente en ECC es: ¿qué va en una rule file y qué va en CLAUDE.md?
El Rol de CLAUDE.md
CLAUDE.md es el archivo de configuración del proyecto para Claude Code. Es el punto de entrada que Claude lee al iniciar una sesión en un proyecto específico. Contiene:
- Contexto del proyecto: qué hace el proyecto, la stack tecnológica, el dominio de negocio
- Comandos de desarrollo: cómo correr el servidor, cómo buildear, cómo testear
- Arquitectura overview: estructura del proyecto, decisiones de diseño importantes
- Guías de contribución: cómo agregar contenido, cómo desplegar
CLAUDE.md es principalmente descriptivo e informativo. Le dice a Claude qué es el proyecto y cómo trabajar con él.
El Rol de las Rules
Las rules son prescriptivas y normativas. Le dicen a Claude cómo debe comportarse, qué estándares debe seguir, qué está prohibido hacer.
La Diferencia Clave
graph LR
A[CLAUDE.md] -->|"Qué es este proyecto"| B[Contexto]
A -->|"Cómo trabajar con él"| C[Comandos]
D[Rules] -->|"Cómo debe comportarse Claude"| E[Directivas]
D -->|"Qué está permitido/prohibido"| F[Restricciones]
CLAUDE.md dice: “Este proyecto usa Next.js 14 con App Router. Los componentes viven en src/components/. Para correr el servidor: bun dev.”
Una rule dice: “Al crear componentes React, siempre colocarlos en el directorio correspondiente a su dominio, no en un directorio genérico components/. Los componentes deben ser menores de 150 líneas.”
Overlap y Prioridad
Cuando hay información en ambos (CLAUDE.md y rules), las rules tienen precedencia para cuestiones de comportamiento y estilo. CLAUDE.md tiene más peso para cuestiones de contexto específico del proyecto.
Si CLAUDE.md dice “usamos Tailwind para estilos” y una rule dice “preferir CSS Modules”, el desarrollador debe resolver el conflicto actualizando la rule o CLAUDE.md para ser coherente. Las inconsistencias confunden al agente.
Cuándo Usar Cada Uno
Usar CLAUDE.md para:
- Descripción de la arquitectura
- Comandos de desarrollo específicos del proyecto
- Convenciones de naming del dominio de negocio
- Información que cambia con el tiempo (versiones, configuraciones)
Usar Rules para:
- Estándares de código que deben aplicarse siempre
- Restricciones de seguridad
- Formato obligatorio de commits
- Procesos que Claude debe seguir (TDD, code review, etc.)
20. Crear Rules Propias
Crear rules propias es una parte fundamental de personalizar ECC para un proyecto o equipo específico.
Template Completo para una Rule
# Nombre de la Rule
## Contexto
[Explicar por qué esta rule existe. Qué problema resuelve. Cuál es el rationale.]
## Reglas
### [Nombre del principio 1] (CRITICAL/IMPORTANT/RECOMMENDED)
[Descripción del principio]
INCORRECTO:
```[lenguaje]
[ejemplo de lo que NO hacer]
CORRECTO:
[ejemplo de lo que SÍ hacer]
Rationale: [Por qué esta es la forma correcta] Consecuencias de no seguirlo: [Qué pasa si se ignora]
[Nombre del principio 2]
[…]
Excepciones
[Cuándo esta rule no aplica, si hay alguna excepción válida]
Referencias
[Links a documentación, artículos, o standards relevantes]
### Qué Hace una Rule Efectiva
**1. Prescriptiva, no descriptiva**: Una rule efectiva dice "SIEMPRE hacer X" o "NUNCA hacer Y", no "considerar hacer X".
Inefectivo: "Es buena práctica validar los inputs"
Efectivo: "SIEMPRE validar inputs en los límites del sistema antes de procesarlos"
**2. Ejemplos concretos de código**: Las abstracciones son difíciles de aplicar consistentemente. Los ejemplos de código CORRECTO vs INCORRECTO eliminan la ambigüedad.
**3. Rationale explícito**: Explicar el "por qué" es tan importante como el "qué". Cuando el agente entiende el principio subyacente, puede aplicarlo correctamente a situaciones no anticipadas.
**4. Granularidad apropiada**: Una rule con 50 principios diferentes es difícil de seguir. Mejor 5 rules con 10 principios cada una, organizadas por tema.
**5. Tono imperativo**: Las rules deben usar imperativo: "Usar", "Nunca", "Siempre", "Evitar". No subjuntivo: "Sería mejor", "Se recomienda", "Podría considerarse".
**6. Sin ambigüedad**: "Funciones pequeñas" es ambiguo. "Funciones de máximo 50 líneas" es una rule accionable.
### Granularidad Correcta
La granularidad de una rule debe ser suficientemente específica para ser accionable pero no tan detallada que cree fricción innecesaria.
**Demasiado vaga:**
```markdown
# Código Limpio
Escribir código limpio y mantenible.
Demasiado detallada:
# Nombramiento de Variables
- Variables booleanas deben empezar con is, has, can, should, will o did
- Variables de arrays deben estar en plural
- Variables de funciones deben ser verbos en infinitivo
- [... 30 reglas más]
Apropiada:
# Naming Conventions
SIEMPRE usar nombres descriptivos que comuniquen intención.
- Variables booleanas: prefijo `is`, `has`, `can`
- Funciones: verbos que describen la acción (`fetchUser`, `validateEmail`)
- No usar abreviaturas excepto las estándar de la industria (url, id, api)
21. Rules en Cursor
Cursor, el editor de código con IA, tiene su propio sistema de rules con algunas diferencias respecto a Claude Code.
Frontmatter Adicional
Las rules en Cursor soportan frontmatter YAML con campos específicos:
---
description: "Estándares de código para proyectos TypeScript"
globs: ["**/*.ts", "**/*.tsx"]
alwaysApply: true
---
# TypeScript Standards
[contenido de la rule]
description: Descripción breve de qué hace la rule. Cursor la usa para determinar cuándo aplicar la rule.
globs: Patrones de archivos a los que aplica la rule. Si se especifica, la rule solo se activa cuando se trabaja con archivos que coinciden con el patrón.
alwaysApply: Cuando es true, la rule se aplica en todas las conversaciones. Cuando es false o se omite, Cursor puede optar por no cargarla dependiendo del contexto.
Diferencias Clave con Claude Code
| Aspecto | Claude Code | Cursor |
|---|---|---|
| Activación | Siempre activas (si están instaladas) | Condicional por globs y alwaysApply |
| Frontmatter | No requerido | Soportado y recomendado |
| Ubicación | ~/.claude/rules/ o .claude/rules/ | .cursor/rules/ |
| Formato | Markdown puro | Markdown con frontmatter YAML |
| Scope | Global o proyecto | Global, proyecto, o por tipo de archivo |
Rules Condicionales por Archivo
La capacidad de Cursor de aplicar rules solo a ciertos tipos de archivos es poderosa:
---
description: "Reglas específicas para componentes React"
globs: ["src/components/**/*.tsx"]
alwaysApply: false
---
# React Component Rules
[reglas específicas para componentes React]
Esta rule solo se activa cuando Cursor está trabajando con archivos .tsx dentro de src/components/. Al trabajar con archivos de servidor o configuración, esta rule no consume espacio en el contexto.
Compatibilidad entre Claude Code y Cursor
Las rules de ECC son compatibles con ambos sistemas. La diferencia principal es que en Cursor se puede agregar el frontmatter opcional. Si se quiere usar la misma rule en ambos sistemas, escribirla para Claude Code (sin frontmatter) funciona en ambos, aunque en Cursor no se beneficia de las capacidades de globs.
22. Conflictos Entre Rules
Los conflictos entre rules son posibles, especialmente cuando se tienen rules de múltiples fuentes (common/ + lenguaje + proyecto).
Tipos de Conflictos
Conflicto directo: Dos rules dicen cosas opuestas sobre el mismo tema.
Ejemplo: common/coding-style.md dice “funciones máximo 50 líneas” y una rule de proyecto dice “funciones máximo 100 líneas”.
Conflicto de omisión: Una rule establece algo pero otra rule relevante lo omite completamente, creando ambigüedad.
Conflicto de prioridad: Ambas rules son correctas pero se aplican a la misma situación y requieren diferentes acciones.
Cómo Claude Resuelve Conflictos
En la jerarquía de precedencia de ECC:
- Rules de proyecto (
.claude/rules/) tienen precedencia sobre - Rules de usuario (
~/.claude/rules/) que tienen precedencia sobre - Comportamiento por defecto del modelo
Dentro del mismo nivel de jerarquía, si hay conflicto:
- Rules más específicas tienen precedencia sobre las más generales
- Si ambas son igual de específicas, Claude debe asumir que hay un error de configuración y seguir la más restrictiva de las dos
Cómo Evitar Conflictos
1. Estructura modular clara: Cada rule cubre un dominio específico sin overlap con otras.
2. Explicitamente referenciar overrides: Si una rule de proyecto necesita sobreescribir algo de common/, decirlo explícitamente.
# Python Specific Rules
## File Length Override
Este proyecto usa notebooks Jupyter donde los archivos pueden ser más largos.
OVERRIDE de common/coding-style.md: archivos de notebook (.ipynb) pueden
superar 800 líneas cuando el contenido educativo lo requiere.
3. Revisión periódica: Al agregar nuevas rules, revisar las existentes para detectar posibles conflictos.
23. Rules y Performance de Tokens
Las rules consumen tokens del contexto de Claude. Este es un trade-off real que hay que gestionar.
Cuántos Tokens Consumen las Rules
Las rules de common/ típicamente suman 2000-4000 tokens en total (todos los archivos combinados). Las rules de un lenguaje específico suman 500-1500 tokens adicionales. En una ventana de contexto de 200K tokens, esto representa menos del 2-3% del contexto total — un costo pequeño por los beneficios.
Sin embargo, si se agregan muchas rules customizadas, el consumo puede escalar.
Cuándo Considerar Deshabilitar Rules
Hay situaciones donde puede ser apropiado deshabilitar algunas rules temporalmente:
Para sesiones de exploración: Cuando se está explorando una idea nueva o haciendo un spike técnico, las rules estrictas pueden ser innecesariamente restrictivas.
Para análisis de código legacy: Al analizar código existente que viola las rules, las rules pueden generar ruido al sugerir cambios constantes cuando el objetivo es entender, no cambiar.
Para tareas muy específicas y acotadas: Si la sesión tiene un objetivo muy específico (por ejemplo, solo generar documentación), las rules de testing y git workflow son irrelevantes.
Estrategia de Selección
La mejor práctica es tener las rules comunes siempre activas y ser selectivo con las rules específicas. No instalar rules de un lenguaje que no se usa en el proyecto.
24. Evolucionar Rules con rules-distill
El skill /rules-distill es uno de los más poderosos del sistema ECC. Analiza el codebase existente para extraer patrones implícitos y generar rules formales.
Cómo Funciona rules-distill
El proceso es:
- El agente analiza el historial de commits del proyecto
- Identifica patrones recurrentes: cómo se nombran las cosas, cómo se estructuran los archivos, cómo se manejan los errores
- Contrasta estos patrones con las rules existentes
- Propone nuevas rules para convenciones que están en el código pero no formalizadas
- Propone actualizaciones a rules existentes donde el código diverge
Cuándo Usar rules-distill
Al onboarding de un proyecto existente: Si un proyecto ya tiene mucho código con convenciones implícitas, rules-distill puede generar un conjunto inicial de rules rápidamente.
Periódicamente en proyectos activos: Las convenciones evolucionan. Las rules deben evolucionar con ellas. Correr rules-distill cada pocos meses asegura que las rules reflejen la realidad actual del codebase.
Cuando las rules parecen desactualizadas: Si Claude frecuentemente sugiere cosas que el equipo rechaza, probablemente las rules no reflejan las convenciones actuales.
El Output de rules-distill
El skill genera un diff de rules: rules nuevas propuestas y modificaciones a las existentes. El desarrollador revisa y aprueba/rechaza cada propuesta. Esto es importante: rules-distill propone, el humano decide.
25. Testing de Rules
Verificar que Claude está siguiendo las rules correctamente es un paso importante del proceso de onboarding y mantenimiento.
Estrategia de Verificación
Método 1: Tests de comportamiento dirigidos
Hacer preguntas o peticiones específicas que deben activar una rule, y verificar que la respuesta es conforme:
- Pedir que escriba código mutable y verificar que Claude lo rechaza o propone la versión inmutable
- Pedir un commit message sin tipo y verificar que Claude usa el formato convencional
- Pedir una función sin tests y verificar que Claude la escribe siguiendo TDD
Método 2: Revisión del razonamiento
Claude puede explicar por qué tomó ciertas decisiones. Pedir explícitamente que justifique una decisión de código revela si está siguiendo las rules o tomando decisiones ad-hoc.
Usuario: "¿Por qué creaste una nueva copia del objeto en lugar de modificarlo?"
Claude: "Siguiendo la rule de inmutabilidad en coding-style.md, siempre retorno
nuevos objetos en lugar de modificar los existentes, para evitar efectos colaterales."
Método 3: Casos edge deliberados
Crear situaciones que pongan a prueba el conflicto entre comodidad y seguimiento de rules:
- Pedir agregar una feature “rápido sin tests”
- Pedir hardcodear una URL en el código
- Pedir usar
anyen TypeScript para “simplificar”
Si las rules están bien cargadas y son claras, Claude debe resistir estas peticiones o al menos señalar la violación.
Debugging Cuando las Rules No Se Siguen
Si Claude no está siguiendo las rules esperadas, las causas posibles son:
-
Las rules no están cargadas: Verificar que los archivos están en los directorios correctos y tienen el formato correcto.
-
La rule es ambigua: Si la rule usa lenguaje vago (“considerar usar X”), Claude puede ignorarla. Hacerla más imperativa.
-
Hay un conflicto no resuelto: Si otra fuente (CLAUDE.md, system prompt) contradice la rule, puede ganar la otra fuente. Resolver el conflicto.
-
La rule está fuera del contexto ventana: En conversaciones muy largas, las rules pueden “perderse” hacia el inicio del contexto. Iniciar una nueva sesión.
26. Jerarquía de Prioridad
Cuando múltiples fuentes de instrucciones existen, ¿cuál gana?
Orden Completo de Prioridad
graph TD
A[System Prompt del modelo] -->|Mayor prioridad| B[Instrucciones de seguridad]
B --> C[Rules de proyecto .claude/rules/]
C --> D[Rules de usuario ~/.claude/rules/]
D --> E[CLAUDE.md del proyecto]
E --> F[Contexto de la conversación]
F --> G[Instrucción del usuario en el turno actual]
G -->|Menor prioridad| H[Comportamiento por defecto del modelo]
Instrucciones de seguridad (máxima prioridad): Los principios de seguridad y ética del modelo nunca pueden ser overrideados por ninguna rule o instrucción.
Rules de proyecto: Tienen la mayor prioridad sobre las fuentes configurables. El razonamiento: las convenciones del equipo son la ley en ese proyecto.
Rules de usuario: Las preferencias personales del desarrollador son relevantes pero ceden ante las del proyecto.
CLAUDE.md del proyecto: El contexto del proyecto es relevante para las decisiones del agente pero no es prescriptivo como las rules.
Contexto de la conversación: El historial de la conversación informa pero no manda.
Instrucción del turno actual: La petición específica del usuario. Importante pero no puede violar reglas de orden superior.
Comportamiento por defecto: Lo que Claude haría sin ninguna instrucción. La base.
Implicaciones Prácticas
Esta jerarquía tiene implicaciones importantes:
-
Si el usuario pide explícitamente “ignora las rules de testing”, Claude puede (y debe) señalar que las rules de testing tienen mayor prioridad que las instrucciones del turno actual para cuestiones de estándares de código.
-
Si CLAUDE.md describe cómo funciona el sistema pero una rule prescribe un comportamiento diferente, la rule gana.
-
Si una rule de usuario y una rule de proyecto se contradicen, la de proyecto gana para todo trabajo en ese proyecto.
27. Rules para Equipos
Cuando múltiples desarrolladores trabajan en el mismo proyecto, las rules de ECC se convierten en el mecanismo de estandarización del equipo.
Project-Level vs User-Level para Equipos
Project-Level (.claude/rules/) — Para todo el equipo:
Las rules de proyecto deben estar versionadas en el repositorio. Todos los miembros del equipo las tienen automáticamente al clonar el repo. Son el equivalente a las convenciones de coding del equipo, pero ejecutadas por el agente.
User-Level (~/.claude/rules/) — Para preferencias individuales:
Las preferencias personales que no afectan al equipo van en el nivel usuario. Por ejemplo, si un desarrollador prefiere un cierto estilo de logging para debugging personal, eso es nivel usuario.
Gobernanza de Rules de Equipo
Las rules de proyecto son tan importantes como el código. Deben seguir el mismo proceso de revisión:
- Proponer cambios a rules via PR (igual que código)
- El equipo revisa y aprueba/rechaza
- Los cambios se documentan (qué cambió y por qué)
- Se comunica al equipo que hay rules nuevas
Onboarding con Rules
Las rules son una parte importante del onboarding de nuevos desarrolladores. En lugar de transmitir convenciones verbalmente (que se pierden), las rules las formalizan. Un nuevo desarrollador que instala Claude Code en el repo automáticamente tiene acceso a todas las convenciones del equipo.
Rules y Code Review
Las rules también ayudan en code review. Si hay una rule que dice “funciones máximo 50 líneas” y el código tiene una función de 80 líneas, el reviewer puede referirse a la rule en lugar de a su preferencia personal. Esto despersonaliza el feedback y lo ancla en estándares acordados por el equipo.
28. Mejores Prácticas
Basado en la experiencia de uso del sistema ECC, estas son las 15 mejores prácticas para rules efectivas:
1. Siempre incluir el rationale. Una rule sin “por qué” es difícil de internalizar y puede parecer arbitraria. El agente (y los humanos) siguen mejor las reglas que entienden.
2. Un archivo por dominio. Agrupar todas las reglas de testing en testing.md, todas las de seguridad en security.md, etc. Evitar archivos catch-all.
3. Usar niveles de criticidad. Marcar algunas reglas como (CRITICAL) para indicar que son no negociables. Las reglas sin marcar pueden tener más flexibilidad.
4. Ejemplos de código en cada regla importante. Las reglas abstractas se interpretan de muchas formas. Los ejemplos de código son unívocos.
5. Mantener las rules versionadas. Las rules son parte del contrato del proyecto. Deben estar en git, con historia de cambios y reviews.
6. Revisar rules periódicamente. El código evoluciona, las rules deben evolucionar con él. Una revisión trimestral es razonable.
7. Empezar con common/ y agregar gradualmente. Instalar todo de golpe es abrumador. Empezar con las rules fundamentales y agregar cuando hay necesidad real.
8. Documentar excepciones explícitamente. Si hay situaciones donde una rule no aplica, documentarlas. Evita que el agente aplique reglas donde no corresponde.
9. Usar tono imperativo. “SIEMPRE usar queries parametrizadas” es mejor que “Se recomienda usar queries parametrizadas”.
10. No duplicar lo que está en CLAUDE.md. Si el contexto del proyecto ya está en CLAUDE.md, no repetirlo en las rules. Cada fuente tiene su rol.
11. Las rules no son sustituto de tests. Las rules guían el agente, pero las reglas de negocio deben tener tests. No confundir los niveles.
12. Testear las rules antes de comitearlas. Antes de agregar una rule al equipo, verificar que Claude la sigue correctamente con algunos casos de prueba.
13. Rules específicas son mejor que rules generales. “Usar Zod para validación de schemas” es más accionable que “Validar datos de entrada”.
14. Considerar el costo de tokens. Más rules = más tokens. Ser selectivo y no agregar rules por las dudas.
15. Las rules más importantes primero. En cada archivo, las reglas más críticas deben estar al principio. Si el contexto se llena, las últimas son las que se pierden.
29. Anti-Patrones
Estos son los 10 errores más comunes al crear o usar rules:
Anti-patrón 1: Rules vagas sin ejemplos de código
“Escribir código limpio” no es una rule accionable. Sin criterios concretos, cada agente interpreta “limpio” de forma diferente.
Anti-patrón 2: Rules que se contradicen sin resolución explícita
Tener “funciones máximo 50 líneas” en common/ y “funciones máximo 100 líneas” en una rule de proyecto sin indicar cuál tiene precedencia crea confusión.
Anti-patrón 3: Rules que dicen “considerar” o “podría ser útil”
El lenguaje condicional hace que las rules sean opcionales. Si algo debe hacerse, usar “SIEMPRE”. Si algo está prohibido, usar “NUNCA”.
Anti-patrón 4: Rules sin rationale
Sin saber por qué existe una rule, es imposible aplicarla correctamente a situaciones no anticipadas.
Anti-patrón 5: Demasiadas rules de bajo nivel
Tener una rule para cada micro-decisión de estilo (dónde va la llave de apertura, cuántos espacios entre parámetros) es mejor manejarlo con un formatter automático (Prettier, Black, gofmt).
Anti-patrón 6: Rules no versionadas
Tener rules locales que no están en el repositorio significa que el resto del equipo no las tiene.
Anti-patrón 7: Rules que no se testean
Agregar una rule y asumir que Claude la sigue sin verificar. El testing de rules es obligatorio.
Anti-patrón 8: Mezclar contexto (CLAUDE.md) con prescripciones (rules)
Poner instrucciones de comportamiento en CLAUDE.md y descripción del proyecto en las rules genera confusión sobre el propósito de cada artefacto.
Anti-patrón 9: Rules que nunca se actualizan
Las rules escritas hace 12 meses para un stack diferente se vuelven ruido. Revisión periódica es obligatoria.
Anti-patrón 10: Instalar rules de lenguajes que no se usan
Instalar las rules de Python, Go, Swift y Ruby en un proyecto TypeScript solo consume tokens sin beneficio.
30. Ejercicios Prácticos
Ejercicio 1: Instalar Rules y Verificar Comportamiento
Objetivo: Experimentar la diferencia entre tener y no tener rules instaladas.
Pasos:
- En un proyecto vacío, pedir a Claude que cree una función que modifique un array
- Anotar el resultado
- Instalar
common/coding-style.mdcon la rule de inmutabilidad - Hacer la misma petición
- Comparar los resultados
Resultado esperado: Sin la rule, Claude puede crear código que muta el array. Con la rule, debe crear una función que retorna un nuevo array.
Ejercicio 2: Crear una Rule para un Proyecto Existente
Objetivo: Formalizar convenciones implícitas en una rule.
Pasos:
- Analizar el código existente de un proyecto
- Identificar tres convenciones que se siguen consistentemente pero no están documentadas
- Escribir una rule con el template de la sección 20
- Verificar que Claude las sigue en la siguiente sesión
Ejercicio 3: Detectar un Conflicto de Rules
Objetivo: Entender cómo los conflictos se manifiestan.
Pasos:
- Crear dos rules que se contradicen sobre el mismo tema
- Pedir a Claude algo que activa ambas rules
- Observar qué hace Claude
- Resolver el conflicto y repetir
Ejercicio 4: Medir el Consumo de Tokens
Objetivo: Entender el trade-off de tener muchas rules.
Pasos:
- Iniciar una sesión con todas las rules de common/ instaladas
- Usar la tool de análisis de tokens para medir el consumo
- Instalar adicionalmente las rules de TypeScript
- Medir el nuevo consumo
- Evaluar si el beneficio justifica el costo
Ejercicio 5: rules-distill en un Proyecto con Historial
Objetivo: Extraer rules de un codebase existente.
Pasos:
- Elegir un proyecto con al menos 3 meses de historial de git
- Invocar
/rules-distill - Revisar las rules propuestas
- Aceptar las que reflejan convenciones reales del proyecto
- Rechazar las que no aplican
- Verificar en la siguiente sesión que las reglas aceptadas se siguen
31. Referencia por Lenguaje
Esta tabla resume todos los lenguajes soportados por ECC con sus rules correspondientes:
| Lenguaje | Directorio | Rules Disponibles | Stack Típico |
|---|---|---|---|
| Universal | rules/common/ | coding-style, git-workflow, testing, security, performance, development-workflow, patterns, agents, hooks | Todos los proyectos |
| TypeScript/JS | rules/typescript/ | types, async, modules, react, node | Next.js, React, Bun, Deno |
| Python | rules/python/ | pep8, types, async, testing, security | Django, FastAPI, Data Science |
| Go | rules/golang/ | idioms, errors, interfaces, concurrency | Backend services, CLIs |
| Swift | rules/swift/ | concurrency, protocols, memory, swiftui | iOS, macOS, watchOS |
| PHP | rules/php/ | psr12, laravel, security, types | Laravel, WordPress |
| Rust | rules/rust/ | ownership, errors, async, traits | Systems, WASM, Embedded |
| Java | rules/java/ | solid, spring, patterns, testing | Spring Boot, Enterprise |
| Ruby | rules/ruby/ | ruby-style, rails, testing | Rails, Sinatra |
Combinaciones Recomendadas por Tipo de Proyecto
Aplicación web moderna (TypeScript + Node.js):
common/ + typescript/
API REST con Python:
common/ + python/
Microservicio en Go:
common/ + golang/
App iOS:
common/ + swift/
Aplicación Laravel:
common/ + php/
Sistema de alta performance:
common/ + rust/
32. Checklist y Resumen
Checklist de Rules para Nuevo Proyecto
- Instalar
rules/common/coding-style.md - Instalar
rules/common/git-workflow.md - Instalar
rules/common/testing.md - Instalar
rules/common/security.md - Instalar
rules/common/performance.md - Instalar
rules/common/development-workflow.md - Instalar
rules/common/patterns.md - Instalar
rules/common/agents.md - Instalar
rules/common/hooks.md - Instalar rules del lenguaje principal del proyecto
- Verificar que no hay conflictos entre rules
- Testear que Claude sigue las rules con 3-5 casos de prueba
- Commitear las rules de proyecto en el repositorio
- Documentar en onboarding que existen rules configuradas
Checklist de Rule Individual
- Tiene nombre descriptivo
- Tiene contexto/rationale explicando el “por qué”
- Usa tono imperativo (SIEMPRE, NUNCA, no “considerar”)
- Tiene ejemplos de código CORRECTO vs INCORRECTO
- Marca niveles de criticidad donde es relevante
- Documenta excepciones explícitamente
- No duplica contenido de otras rules o CLAUDE.md
- Tiene menos de 200 líneas (o está bien justificado si es más larga)
Resumen de Conceptos Clave
Las rules son el mecanismo de estandarización permanente en ECC. A diferencia de los skills (que se invocan) y los agentes (que se delegan), las rules están siempre activas y forman el “background radiation” del comportamiento de Claude en un proyecto.
Las rules de common/ son el núcleo obligatorio. Cubren inmutabilidad, estilo de código, git workflow, testing obligatorio, seguridad, performance, workflow de desarrollo, patrones de diseño y orquestación de agentes.
Las rules de lenguaje extienden common/ con convenciones específicas del ecosistema: TypeScript tiene type safety estricto, Python tiene PEP 8 y type hints, Go tiene manejo idiomático de errores, Swift tiene concurrencia con actors.
La jerarquía de prioridad es clara: rules de proyecto > rules de usuario > CLAUDE.md > contexto de conversación. Esta jerarquía garantiza que las convenciones del equipo siempre prevalecen.
Las mejores prácticas para rules efectivas son: ser prescriptivo (no descriptivo), incluir ejemplos de código, documentar el rationale, mantener las rules versionadas, y revisarlas periódicamente.
Los anti-patrones más comunes son: rules vagas, rules que se contradicen, rules sin rationale, y rules no actualizadas.
El testing de rules es obligatorio: verificar con casos específicos que Claude sigue las convenciones esperadas, debuggear cuando no las sigue, y usar rules-distill para mantener las rules alineadas con la evolución del codebase.
Las rules de ECC son, en última instancia, la forma en que los equipos capturan y transmiten su conocimiento colectivo sobre cómo debe ser el código. Son la diferencia entre tener un agente genérico y tener un agente que realmente entiende cómo trabaja tu equipo.