MÓDULO 2.2

✂️ CLAUDE.md → AGENTS.md

Portátil de un lado, residuo del otro. Tu archivo de instrucciones tiene dos naturalezas mezcladas: reglas que sirven para cualquier agente y comandos que solo Claude Code entiende. En este módulo separas las dos con el adapt-instructions.sh, revisas el corte a mano y dejas que Claude siga leyendo todo mediante un @AGENTS.md.

6
Temas
~30
Minutos
Básico
Nivel
Práctica
Tipo
1

🧳 Qué es portátil en una instrucción

Abre tu CLAUDE.md y léelo línea por línea haciéndote una sola pregunta: ¿esta frase seguiría siendo verdadera si el ejecutor fuera Codex, Gemini CLI o un modelo local? Si la respuesta es sí, la línea es portátil. Habla de tu mundo — de tu manera de publicar, de tus rutas, de tus convenciones — y no del programa que la está leyendo.

En el CLAUDE.md global de esta máquina, la inmensa mayoría del archivo es portátil. Reglas como "publicar = commit + push al git, nunca tocar Vercel directamente", "el autor del commit sigue la cuenta de GitHub de destino del repo", "versionado semver vX.XX.YY: el minor incrementa el XX y conserva el YY, nunca lo pone en cero", "las API keys siempre están en ~/projetos/openpcbotv2/.env o ~/projetos/wifi/.env, cargarlas en runtime y nunca imprimir el valor" — ninguna de ellas menciona a Claude. Son política de trabajo. Cualquier agente que las lea se comporta mejor.

CLAUDE.md 78 líneas todo mezclado reglas + residuo adapt-instructions grep -vE / grep -E AGENTS.proposto.md 71 líneas portátiles git, autor, semver, rutas de las keys CLAUDE.proposto.md @AGENTS.md + 7 líneas AskUserQuestion, plugins, hooks nunca sobrescribe el original guarda *.proposto.md al lado

Mira los dos números de la derecha: en el CLAUDE.md global de esta máquina el corte dio 71 líneas portátiles contra 7 de residuo. Casi todo lo que escribiste nunca fue sobre Claude — era sobre tu trabajo.

✓ Portable (va al AGENTS.md)

  • Reglas de publicación: "publicar = commit + push; el deploy es del webhook, no mío".
  • Autoría de commit: qué cuenta y qué e-mail por repositorio de destino.
  • Versionado: el esquema vX.XX.YY y cuándo se reinicia cada dígito.
  • Rutas: dónde están las keys, dónde salen los artefactos, dónde vive el portal.
  • Idioma, tono y formato de respuesta esperado.

✗ No portable (se queda en el residuo)

  • Nombre de herramienta exclusiva: AskUserQuestion, Artifact, advisor.
  • Nombre de plugin: superpowers, context-mode, claude-mem.
  • Configuración de hook y precedencia sobre inyecciones de hook.
  • Slash commands que solo existen en un runtime (/code-review).
  • Cualquier valor de secreto — eso no entra en ningún lado.

💡 ¿Nuevo por aquí?

Runtime es el programa que ejecuta al agente: Claude Code, Codex CLI, Gemini CLI, OpenCode. Instrucción es el archivo Markdown que el runtime lee antes de actuar — CLAUDE.md en Claude, AGENTS.md en el resto. Portable quiere decir que el texto no depende de qué programa lo está leyendo. Residuo es lo que sobra después de quitar lo portable: pequeño, específico y descartable cuando cambias de ejecutor.

Conceptos clave

Portable

Vale para cualquier ejecutor; habla de tu trabajo.

Residuo

Solo tiene sentido dentro de un runtime específico.

Prueba del cambio

"¿Sigue siendo verdad con otro ejecutor?"

Proporción real

71 portables por 7 de residuo en esta máquina.

2

🧪 Qué es el residuo Claude

El residuo no es basura. Son instrucciones legítimas y útiles — solo que atadas a un programa. El script del kit reconoce el residuo por una lista de palabras clave, que es literalmente una expresión regular dentro del archivo: AskUserQuestion, superpowers, context-mode, fable-mindset, claude-mem, ultrareview, /code-review, Artifact, advisor, plugin y hook. Toda línea que coincide con uno de esos términos va al residuo; todas las demás van a lo portable.

# dentro de scripts/adapt-instructions.sh — la regla del corte, en una línea:
CLAUDE_ONLY='AskUserQuestion|superpowers|context-mode|fable-mindset|claude-mem|ultrareview|/code-review|Artifact|advisor|plugin|hook'

Fíjate en lo que eso implica. La regla "nunca usar AskUserQuestion (menú interactivo), siempre preguntar en texto libre" es residuo por el nombre de la herramienta — pero la intención ("prefiero responder en texto, no elegir de un menú") es portable. El script no sabe distinguir intención de nombre: corta por palabra. Por eso el resultado es una propuesta, no un archivo final. Cuando revises, reescribe la intención en lenguaje neutro y deja el nombre de la herramienta en el residuo.

🎯 Ver el residuo antes de cortar

Objetivo: descubrir, sin escribir nada, cuántas líneas de tu archivo son específicas de Claude y cuáles son.

cd ~/projetos/<tu-proyecto>

# cuántas líneas en total
wc -l CLAUDE.md

# qué líneas son residuo (misma regex del script)
grep -nE 'AskUserQuestion|superpowers|context-mode|fable-mindset|claude-mem|ultrareview|/code-review|Artifact|advisor|plugin|hook' CLAUDE.md

Cómo verificar: suma las líneas que mostró el grep y compáralas con el wc -l. En el CLAUDE.md global de esta máquina el resultado fue 7 de residuo en 78 líneas — 71 portables. Si en tu proyecto el residuo supera un tercio del archivo, probablemente hay configuración de herramienta donde debería haber regla de trabajo.

1

Herramientas con nombre

AskUserQuestion, Artifact, advisor. Codex no tiene esas herramientas; citar su nombre en un AGENTS.md solo genera confusión.

2

Plugins

superpowers, context-mode, claude-mem, fable-mindset. Un plugin es empaquetado de Claude Code; no existe un concepto equivalente en Codex CLI.

3

Hooks y precedencia

Reglas del tipo "este archivo gana sobre lo que inyecte el hook". Tienen sentido donde existe hook de sesión; en Codex, SessionStart ni siquiera existe.

4

Slash commands

/code-review, /formato-curso-v5. El enrutamiento por barra es convención de interfaz, no contenido. Tradúcelo al nombre de la skill cuando migres.

Conceptos clave

Regex del corte

Once términos deciden qué es residuo. Está en el script, se puede editar.

Intención vs nombre

La intención casi siempre es portable; el nombre de la herramienta no.

Corte por línea

El script trabaja línea por línea, sin entender el párrafo.

Propuesta

El resultado pide revisión humana; no es una entrega.

3

⚙️ adapt-instructions.sh y los .proposto.md

El script recibe la carpeta de un proyecto y busca un CLAUDE.md allí dentro. Si no lo encuentra, avisa y sale con código 0: no es un error, es "nada que adaptar". Si lo encuentra, escribe dos archivos al lado del original, con el sufijo .proposto.md. Ese detalle es la garantía de seguridad de todo el módulo: el script nunca sobrescribe nada. Tú lees, corriges y solo entonces renombras a mano.

🎯 Generar el par de propuestas

Objetivo: producir AGENTS.proposto.md y CLAUDE.proposto.md en un proyecto tuyo, sin tocar el archivo original.

cd ~/projetos/agente-claude-codex

# 1. ensayo: genera, muestra los conteos y borra los archivos
scripts/adapt-instructions.sh ~/projetos/<tu-proyecto> --dry-run

# 2. en serio: deja los dos .proposto.md en la carpeta del proyecto
scripts/adapt-instructions.sh ~/projetos/<tu-proyecto>

# Propuestos (revisar y renombrar manualmente):
#   ~/projetos/<tu-proyecto>/AGENTS.proposto.md  (71 líneas)
#   ~/projetos/<tu-proyecto>/CLAUDE.proposto.md   (7 líneas)

# 3. mira qué cambió antes de aceptar
diff ~/projetos/<tu-proyecto>/CLAUDE.md \
     ~/projetos/<tu-proyecto>/AGENTS.proposto.md | head -40

Cómo verificar: el CLAUDE.md original sigue idéntico (git status no muestra modificación en él, solo dos archivos nuevos sin rastrear). Los dos conteos sumados, más el encabezado que agrega el script, coinciden aproximadamente con el total del original.

💡 Consejo práctico

Ejecuta siempre el --dry-run primero. Genera, imprime los dos conteos y elimina los archivos enseguida. Así conoces la proporción portátil/residuo del proyecto sin ensuciar la carpeta, algo útil cuando vas a recorrer decenas de proyectos para decidir por dónde empezar.

Vale la pena escalar esto. En esta máquina, 165 proyectos tienen CLAUDE.md, 54 ya tienen AGENTS.md y 39 tienen los dos. Es decir: 15 proyectos tienen AGENTS.md sin CLAUDE.md (nacieron portátiles) y 126 todavía están atados a un solo runtime. Además, 13 proyectos marcados como trusted en Codex no tienen AGENTS.md: son los candidatos obvios a piloto, porque Codex ya puede trabajar en ellos pero todavía no conoce las reglas.

✓ Lo que el script garantiza

  • Nunca sobrescribe CLAUDE.md ni AGENTS.md existentes.
  • Sale con código 0 y un mensaje claro cuando no hay nada que adaptar.
  • Inserta el orden de lectura al inicio del portátil, siempre.
  • Pone @AGENTS.md como primera línea del residuo.
  • --dry-run limpia los archivos que acaba de crear.

✗ Lo que NO hace

  • Entender párrafos: el corte es por línea, sin contexto.
  • Renombrar .proposto.md al nombre final: eso es cosa tuya.
  • Distinguir intención de nombre de herramienta.
  • Preservar menciones a CLAUDE.md de otros proyectos (ver el tema 6).
  • Probar que algún agente leyó el resultado: eso es el readback, en el 2.5.

Conceptos clave

.proposto.md

Salida para revisión, al lado del original. Tú lo renombras.

--dry-run

Mide la proporción sin dejar archivos atrás.

Idempotente

Ejecutarlo dos veces genera el mismo par; nada se acumula.

Escala

165 CLAUDE.md en esta máquina; empieza por los 13 trusted.

4

🔗 @AGENTS.md: Claude importando el portátil

La pregunta que todo el mundo hace en este punto: "si saco las reglas del CLAUDE.md, ¿Claude deja de conocerlas?". No. Claude Code entiende una línea de import: un @ seguido de la ruta de otro archivo Markdown trae el contenido de ese archivo dentro de las instrucciones. Entonces el nuevo CLAUDE.md empieza con @AGENTS.md y sigue con las siete líneas de residuo. Claude lee los dos. Codex lee solo el AGENTS.md. Ninguno de los dos pierde nada que le concierna.

AGENTS.md reglas portátiles · fuente única Codex CLIlee directo Gemini CLIlee directo OpenCodelee directo Claude Code CLAUDE.md @AGENTS.md + 7 líneas de residuo import una fuente, cuatro lectores edita aquí y todos cambian juntos

Compara los dos lados: a la derecha, tres runtimes leyendo el archivo directamente; a la izquierda, Claude llegando al mismo archivo por la flecha punteada del import. Lo que importa es que existe un único bloque central: si hubiera dos, tendrías dos verdades que mantener.

🎯 Aceptar las propuestas con seguridad

Objetivo: promover los .proposto.md a archivos reales, guardando el original como backup con fecha.

cd ~/projetos/<tu-proyecto>

# 1. backup del original, con la fecha en el nombre
cp CLAUDE.md CLAUDE.md.bak-$(date +%Y%m%d)

# 2. promover las propuestas YA REVISADAS
mv AGENTS.proposto.md AGENTS.md
mv CLAUDE.proposto.md CLAUDE.md

# 3. el nuevo CLAUDE.md tiene que empezar con el import
head -1 CLAUDE.md
# @AGENTS.md

Cómo verificar: abre una sesión nueva de Claude en esa carpeta y pide "cita la regla de autoría de commit y di de qué archivo salió". La respuesta tiene que citar AGENTS.md. Si cita CLAUDE.md, el import no se resolvió: revisa si la ruta está bien y si el @ está en la primera línea.

Conceptos clave

Import (@)

Una línea trae otro Markdown a las instrucciones de Claude.

Fuente única

Las reglas existen en un solo archivo; nadie duplica.

Backup con fecha

Antes de promover, guarda el original con la fecha.

Prueba de lectura

Preguntar de dónde salió la regla revela qué archivo entró.

5

🧭 Orden de lectura explícito en la parte superior

Aquí está el detalle que separa un workspace que funciona de uno que solo parece organizado: nada se carga solo. El runtime lee el archivo de instrucciones, y nada más. Las carpetas context/, tasks/ y handoffs/ son convención humana; ningún programa las va a abrir por su cuenta. Si quieres que el agente las lea, escribes que debe leerlas, al inicio del AGENTS.md. Por eso el script inyecta esa línea automáticamente en todo portátil que genera.

# AGENTS.md — instrucciones portátiles del proyecto

> Orden de lectura para cualquier agente: 1) este archivo, 2) context/overview.md,
> 3) context/current-state.md, 4) tasks/current.md, 5) handoffs/latest.md.
> Estos nombres son convención: nada se carga automáticamente fuera de
> AGENTS.md/CLAUDE.md.
1

AGENTS.md

Las reglas. Cómo trabajar, qué nunca hacer, dónde están las cosas. El único archivo que el runtime realmente carga por sí solo.

2

context/overview.md

Qué es este proyecto, para quién, con qué hechos fechados. Estable: cambia en semanas, no en horas.

3

context/current-state.md

Dónde está la cosa ahora: qué ya corre, qué está roto, qué se decidió y todavía no se implementó.

4

tasks/current.md

Objetivo, responsable, criterio de terminado, próxima acción concreta, bloqueos. Una tarea a la vez, con nombre de archivo de verdad.

5

handoffs/latest.md

Qué hizo la última sesión y qué debe saber la siguiente. Es el puente entre runtimes: Claude escribe, Codex retoma.

💡 Consejo práctico

El orden es jerarquía de confianza, no solo secuencia. Cuando tasks/current.md contradice al overview.md, el que está equivocado es el overview: envejeció. Escribe eso en el AGENTS.md: "en caso de conflicto, gana lo más específico y más reciente, y avisa del conflicto en vez de elegir en silencio". Un agente que señala una contradicción vale más que un agente que adivina.

Conceptos clave

Nada se carga solo

Fuera de AGENTS.md/CLAUDE.md, nadie abre nada por su cuenta.

Convención

Los nombres de las carpetas son un acuerdo entre humanos.

Orden = confianza

Lo más específico y reciente gana en el conflicto.

Inyectada por el script

Todo AGENTS.proposto.md ya nace con el orden en la parte superior.

6

🪤 La trampa del sed

A la hora de armar el portátil, el script hace dos cosas: filtra las líneas de residuo y, en lo que queda, ejecuta sed 's/CLAUDE\.md/AGENTS.md/g'. El reemplazo es global y ciego. No distingue "el CLAUDE.md de este proyecto" de "el CLAUDE.md de aquel otro proyecto", y la segunda mención no debería cambiar, porque aquel otro proyecto sigue teniendo un CLAUDE.md de verdad en el disco. El propio encabezado del script lo advierte en una línea de comentario.

# lo que el script hace con la parte portátil:
grep -vE "$CLAUDE_ONLY" "$SRC" | sed 's/CLAUDE\.md/AGENTS.md/g'

# antes (correcto):
#   Ver el `CLAUDE.md` del portal para el paso a paso de actualización.
#   Cada proyecto puede tener su propio `CLAUDE.md` diciendo qué cuenta usar.
# después (roto — esos archivos no existen):
#   Ver el `AGENTS.md` del portal para el paso a paso de actualización.
#   Cada proyecto puede tener su propio `AGENTS.md` diciendo qué cuenta usar.

⚠️ Por qué esto duele de verdad

Un agente que lee "mira el AGENTS.md del portal" va a intentar abrir ~/projetos/portal/AGENTS.md. El archivo no existe. A partir de ahí hace una de dos cosas malas: inventa el contenido, o declara que no hay instrucciones para el portal y sigue sin ellas — que es exactamente el escenario en que el commit sale con el autor equivocado. Una sustitución de texto inofensiva se convirtió en una regla perdida.

🎯 Revisar el sed antes de renombrar

Objetivo: listar cada mención que el sed cambió y decidir, una por una, si el cambio era correcto.

cd ~/projetos/<tu-proyecto>

# 1. dónde el original hablaba de CLAUDE.md
grep -n 'CLAUDE\.md' CLAUDE.md

# 2. dónde la propuesta pasó a hablar de AGENTS.md
grep -n 'AGENTS\.md' AGENTS.proposto.md

# 3. las dos listas lado a lado: cada línea de más es un cambio a revisar
diff <(grep -c 'CLAUDE\.md' CLAUDE.md) <(grep -c 'AGENTS\.md' AGENTS.proposto.md)

# 4. revertir una mención que era de OTRO proyecto
sed -i 's|AGENTS.md do portal|CLAUDE.md do portal|' AGENTS.proposto.md

Cómo verificar: después del paso 4, grep -n 'do portal' AGENTS.proposto.md vuelve a citar CLAUDE.md. Regla práctica: toda mención que viene acompañada de un nombre de proyecto ("do portal", "do inemavox", "de cada projeto") es referencia externa y debe revertirse; las menciones sueltas ("este archivo", "el CLAUDE.md de este repo") son internas y el cambio es correcto.

✓ Cambio correcto

  • "las reglas de este CLAUDE.md" → habla del archivo local, que se convirtió en AGENTS.md.
  • "escribe en el CLAUDE.md del proyecto actual" → el actual es justamente el que migraste.
  • Títulos de sección que nombran el propio archivo.

✗ Cambio a revertir

  • "el CLAUDE.md del portal" → otro repositorio, que no fue migrado.
  • "cada proyecto puede tener su CLAUDE.md" → habla de proyectos de terceros.
  • Rutas literales como ~/.claude/CLAUDE.md — es una ruta real en el disco.
  • Citas de documentación externa que usan el nombre del archivo de Claude.

💡 Consejo práctico

Cuando termines la revisión, registra la ronda: una línea en FALHAS.md si algo se rompió ("el sed cambió la referencia al CLAUDE.md del portal; menor corrección: revertir la línea; categoría: prompt") y un párrafo en handoffs/latest.md diciendo qué proyectos ya tienen AGENTS.md promovido. Sin eso, dentro de dos semanas no vas a recordar cuáles de los 165 proyectos ya pasaron por aquí.

Conceptos clave

Sustitución ciega

El sed cambia texto, no entiende referencias.

Referencia externa

Mención a un archivo de otro proyecto: no debe cambiar.

Ruta literal

~/.claude/CLAUDE.md existe en el disco; consérvala.

Revisar antes de renombrar

La propuesta solo se convierte en archivo después de tu lectura.

Autoevaluación (opcional): el AGENTS.proposto.md quedó con la frase "consulta el AGENTS.md del portal para actualizar la tarjeta". ¿Qué hacer?

🎯 Resumen del módulo

Portátil vs residuo — la pregunta es "¿seguiría siendo verdadero con otro ejecutor?". En el CLAUDE.md global de esta máquina: 71 portátiles, 7 de residuo.
adapt-instructions.sh — genera AGENTS.proposto.md y CLAUDE.proposto.md junto al original y nunca sobrescribe nada.
@AGENTS.md — Claude importa lo portátil y conserva solo el residuo; Codex, Gemini y OpenCode leen el AGENTS.md directamente.
Orden de lectura y la trampa del sed — nada se carga solo, así que escribe el orden al inicio; y revisa cada mención cambiada antes de renombrar.

Próximo módulo:

2.3 — Instalar el núcleo portátil: init-core.sh sin sobrescribir