🛠️ Manos a la obra
Del diagnóstico a la prueba, con los scripts reales del kit agente-claude-codex: medir el entorno, separar el CLAUDE.md en portátil y residuo, instalar el núcleo, portar una skill con fuente única, probar en una sesión nueva en los dos runtimes y cerrar con handoff. Cada paso es reversible y deja evidencia.
Lee la escalera de izquierda a derecha: los dos primeros peldaños solo leen (audit); del tercero en adelante cada paso es reversible; el readback brilla porque es la prueba; la flecha cian muestra el handoff alimentando la próxima sesión.
Mapa de la ruta
🩺 Diagnóstico del entorno
doctor.sh y audit.sh
✂️ CLAUDE.md → AGENTS.md
Portátil de un lado, residuo del otro
🧱 Instalar el núcleo portátil
init-core.sh sin sobrescribir
🧩 Skills canónicas con polyskill
Una fuente, N runtimes
✅ Readback: probar en una sesión nueva
Cinco preguntas, dos runtimes
🔁 Handoff y prime: el ciclo diario
Sesión → handoff → Markdown → prime → sesión
Prerrequisito de esta ruta: tener el kit clonado (git clone https://github.com/inematds/agente-claude-codex) y al menos uno de los dos runtimes instalado. El módulo 2.1 lo verifica por ti con scripts/doctor.sh.
Contenido detallado
🩺 Diagnóstico del entorno
Antes de mover cualquier cosa, mide: el kit agente-claude-codex trae un diagnóstico del entorno (ok / aviso / falta) y un inventario de solo lectura que clasifica cada skill, hook, MCP e instrucción. Nada en ~/.claude ni en ~/.codex se toca.
El repo inematds/agente-claude-codex reúne scripts, prompts y la plantilla del núcleo portátil. Lo clonas una vez y ejecutas todo desde adentro.
Sin el kit rehaces a mano lo que ya está automatizado y probado en esta máquina (readback aprobado en Claude y Codex).
git clone https://github.com/inematds/agente-claude-codex, carpeta scripts/, prompts/, template/.
Un script de solo lectura que verifica git, python3, node, Claude Code, Codex CLI (skills, config, sandbox, MCP), polyskill y los propios archivos del kit. Cada ítem sale como [ok], [aviso] o [FALTA] con el comando para resolverlo.
Responde "¿mi entorno está listo?" en segundos y sale con código 1 si falta algo esencial, lo que permite automatizar.
scripts/doctor.sh, código de salida, aviso ≠ falta, sin Claude ni Codex el paso queda como "no ejecutado".
Lista versiones, skills, comandos, subagentes, hooks, plugins y MCP de los dos runtimes y guarda un informe Markdown en relatorios/auditoria-<data>.md.
Es el paso 2 de los mega-prompts (MODE: audit): ves lo que existe antes de decidir qué migra.
scripts/audit.sh, brecha Claude → Codex, informe fechado, separación proyecto × global.
La auditoría clasifica por heurística (grep) cada skill que solo existe en Claude: reutilizable (Markdown puro), adaptador (depende de MCP o de un plugin de Claude), nativo (depende de hook) o no resuelto. En esta máquina: 72 / 15 / 2 / 1.
La matriz dice dónde está el esfuerzo: 72 skills migran sin cambios; el bloqueo real son los 15 MCP, no el formato.
Clasificación heurística, revisar caso por caso, MCP como cuello de botella, subagentes y plugins no migran.
En este host, AppArmor restringe los user namespaces y el bwrap de Codex falla ("loopback: RTM_NEWADDR"). El readback que forzaba -s read-only se rompió; la corrección mínima fue respetar el sandbox_mode del config.toml.
Te vas a topar con esto en cualquier máquina Linux parecida; el doctor.sh ya lo avisa y la falla está en FALHAS.md con la corrección mínima.
bwrap, AppArmor, sandbox_mode = "danger-full-access", FALHAS.md (fecha, qué se rompió, corrección mínima, prompt o infra).
El informe en relatorios/ no es el final: cada línea se convierte en una decisión (portar, adaptar, dejar como residuo Claude) que alimenta el plan de migración por fases.
Sin transformar el inventario en plan solo tienes una lista bonita; el texto fuente insiste en que un archivo existir no es prueba de nada.
Informe fechado, matriz → fases, pasó / falló / no ejecutado, evidencia versionada.
✂️ CLAUDE.md → AGENTS.md
El único archivo realmente atado al proveedor es el CLAUDE.md. Aquí separas lo que es regla portátil (va al AGENTS.md, leído por Codex, Gemini y OpenCode) de lo que es específico de Claude Code, y haces que Claude importe lo portátil con @AGENTS.md.
Reglas de publicación, autor del commit, dónde están las keys, versionado semver, destino de los artefactos: todo eso es texto que cualquier agente entiende.
Es la mayor parte de tu CLAUDE.md (71 de 78 líneas en el global de esta máquina) y viaja sin cambios.
Regla estable, ruta, convención, AGENTS.md como fuente.
Las menciones a AskUserQuestion, superpowers, context-mode, claude-mem, fable-mindset, Artifact, advisor y hooks solo tienen sentido en Claude Code.
Si eso va al AGENTS.md, Codex lee instrucciones que no puede cumplir y el ruido crece.
Residuo, plugin, hook, herramienta exclusiva, 7 líneas en el global.
El script lee el CLAUDE.md del proyecto y guarda AGENTS.proposto.md y CLAUDE.proposto.md al lado, para revisión. No se toca nada existente.
Reversible por construcción: revisas, renombras y solo entonces el proyecto cambia.
scripts/adapt-instructions.sh ~/projetos/meu-projeto, --dry-run, .proposto.md.
El nuevo CLAUDE.md empieza con la línea @AGENTS.md y solo después trae el residuo. Claude lee los dos; Codex lee solo el AGENTS.md.
Una sola fuente de verdad para las reglas portátiles, sin copias divergentes.
Import @, una fuente, residuo separado, sin duplicación.
El AGENTS.md abre con "lee 1) este archivo, 2) context/overview.md, 3) context/current-state.md, 4) tasks/current.md, 5) handoffs/latest.md". Esos nombres son convención del repo, no se cargan solos.
El prompt B es explícito: dile al agente qué leer; no asumas auto-load.
Orden de lectura, convención ≠ auto-load, briefing pequeño al inicio.
El script cambia toda mención "CLAUDE.md" por "AGENTS.md" en la parte portátil, incluso cuando el texto habla del CLAUDE.md de otro proyecto. Eso cambia el sentido.
Por eso la salida es .proposto.md: la revisión humana atrapa ese caso.
Renombrado ciego, revisar referencias, sed es tonto, el humano aprueba.
🧱 Instalar el núcleo portátil
El núcleo portátil es un conjunto de archivos Markdown con dueño definido: AGENTS.md, context/, tasks/current.md, handoffs/latest.md. El init-core.sh copia la plantilla al proyecto y lista lo que creó y lo que mantuvo.
Copia template/ al proyecto archivo por archivo; si ya existe, lo mantiene y avisa [mantido]; si no, lo crea y avisa [criado].
La primera versión del kit usaba cp -r y sobrescribía README y CLAUDE.md; la corrección fue la regla "nunca sobrescribir".
scripts/init-core.sh ~/projetos/meu-projeto, creado, mantenido, reversible.
El context/overview.md tiene encabezado (ID, alcance, fuente, fecha, estado, revisar en) y secciones: qué es, hechos verificados, preferencias, hipótesis.
Separar hecho de hipótesis es lo que resuelve después "cuál de las versiones es la correcta".
ID, alcance, fuente, fecha de observación, estado, hecho × preferencia × hipótesis.
Un archivo que dice qué se está haciendo ahora, quién es el dueño, cuál es el criterio de terminado verificable y la próxima acción concreta.
Es lo que hace que el agente entienda el trabajo actual, no solo el historial.
Objetivo, dueño, criterio de terminado, próxima acción, bloqueos.
Cada decisión aceptada se convierte en un archivo fechado en context/decisions/ con contexto, decisión y consecuencias. Estado: propuesta, aceptada, revocada.
La decisión aceptada le gana al timestamp: es el criterio de conflicto del plan.
Decisión fechada, estado, provenance, nunca borrar, revocar.
Un check de 8 líneas: los archivos obligatorios existen y no están vacíos. Sale con 0 o 1.
Un check pequeño y real vale más que una estructura bonita que nadie valida.
bash scripts/check.sh, [ok] / [FALTA], código de salida.
Clona el proyecto solo en una carpeta limpia y ejecuta el check. El prompt B lo exige: contexto esencial dentro del proyecto, sin depender de ../../knowledge.
Prueba de portabilidad: si depende de la carpeta madre, no es portátil.
Clon limpio, sin dependencia de la carpeta madre, el check pasa, evidencia.
🧩 Skills canónicas con polyskill
En vez de skill-claude, skill-codex, skill-dsh copiadas a mano, una skill canónica genera las copias por runtime. El sync-skills.sh envuelve el polyskill: import, build, install con backup, drift.
En esta máquina el dsh-sandbox tiene 3 skills copiadas a mano desde formato-curso-inema. Cada edición en el origen no llega a las copias: drift garantizado.
Cuatro consumidores (Claude 117, Codex 27, dsh 3, openpcbotv3 16) sin fuente única divergen por sí solos.
Drift, copia manual, fuente canónica, adaptador en los bordes.
scripts/sync-skills.sh import session-handoff lee ~/.claude/skills/session-handoff y escribe skills/session-handoff/ en el formato portátil.
La skill deja de ser "de Claude" y se convierte en fuente neutral.
polyskill import --from claude, definition.md, polyskill.yaml, extensiones preservadas o avisadas.
scripts/sync-skills.sh build genera skills/*/dist/<runtime>/. Con FORCE=1 sobrescribe el destino editado a mano.
La copia por runtime es derivada, nunca editada: editar la fuente y volver a hacer build.
dist/, derivado, --force, nunca editar la copia.
scripts/sync-skills.sh install session-handoff --both copia a ~/.claude/skills y ~/.codex/skills (y lo replica en ~/.agents/skills), haciendo backup .nombre.bak-<ts> si ya existía.
Instalar es la única acción que toca el home de los runtimes; por eso backup antes.
--both, --claude, --codex, backup al lado, ~/.agents/skills.
scripts/sync-skills.sh drift compara cada dist/ con lo que está instalado. Sale con 1 si hay diferencia.
Es la prueba de que nadie editó la copia por fuera; entra en el criterio de aceptación.
diff -rq, [ok], [DRIFT], [no instalada], código de salida.
Las 15 skills "adaptador" (heygen, magnific, printing-press…) citan herramientas MCP. En Codex solo funcionan después de registrar el servidor con codex mcp add.
Portar antes del MCP genera una skill que no corre; el orden importa.
MCP en Codex, codex mcp add, keys referenciadas desde el .env, nunca copiar el valor.
✅ Readback: probar en sesión nueva
Que el archivo exista no es prueba. El readback abre una sesión nueva en Claude (claude -p) y en Codex (codex exec) dentro del proyecto y hace cinco preguntas. Aprobación: las respuestas citan los archivos correctos.
Objetivo actual y criterio de terminado; una regla con el archivo exacto de origen; última decisión aceptada; próxima acción concreta; conflictos, hechos viejos o acceso faltante. Separar lo que los archivos establecen de lo que el agente infiere.
Es la prueba de continuidad del prompt B: ¿encontró, leyó, entendió, usó?
Fresh-session readback, sin conversación anterior, citar fuente, inferencia marcada.
scripts/readback-test.sh ~/projetos/meu-projeto both ejecuta los dos y guarda la respuesta cruda en relatorios/readback-<runtime>-<data>.md.
Automatiza la recolección; el veredicto sigue siendo tuyo.
claude -p, codex exec --skip-git-repo-check, reporte por runtime, sandbox del config.toml.
Criterio: AGENTS.md, tasks/current.md y handoffs/latest.md aparecen citados y la "próxima acción" coincide con la tarea.
Prosa bonita sin citas es alucinación de contexto; la cita es evidencia.
Cita de archivo, próxima acción coincide, pasó / falló.
En el primer readback aprobado, Codex encontró un handoff faltante, una suma errada en el audit y una frase contradictoria en el plan. Todas corregidas en el momento.
El readback no solo prueba, también audita: un agente nuevo lee sin el sesgo de quien escribió.
Inconsistencia, auditoría por sesión nueva, corrección registrada.
Dos fallas reales: sandbox forzado (-s read-only) y conteo del audit. Cada una se vuelve una línea: fecha, qué se rompió, menor corrección, prompt o infra.
Después de unas 10 líneas el patrón aparece y dejas de reconstruir lo que solo necesitaba una protección.
FALHAS.md, menor corrección, prompt × infra, una línea por falla.
Pasó: citó los archivos y la acción coincide. Falló: se ejecutó y no citó. No ejecutado: runtime ausente, el sandbox se rompió, o nadie lo ejecutó. Sin evidencia cuenta como no ejecutado.
El PDF fuente lo admite: los autores no hicieron ninguna prueba en vivo. Tu readback es la primera evidencia real.
Tres estados, evidencia guardada, nunca "probablemente pasó".
🔁 Handoff y prime: el ciclo diario
El flujo que hace que todo funcione en el día a día: al cerrar la sesión, el agente escribe un handoff en Markdown; al abrir la siguiente, en cualquier runtime, lee ese handoff antes de actuar. Las sesiones JSONL se vuelven historial, no fuente.
Proyecto y alcance, objetivo, estado aceptado, archivos modificados, checks ejecutados con resultado, preguntas abiertas, próxima acción exacta. Sin credenciales, sin "está en otro worktree".
Un buen handoff reemplaza releer 2,3 GB de JSONL.
Decisión, pendiente, próximo paso, ruta de archivo, sin secretos.
La plantilla del kit tiene 7 secciones fijas. latest.md es siempre el más reciente; las versiones antiguas pueden quedar en handoffs/AAAA-MM-DD.md.
La estructura fija es lo que permite que otro runtime (u otra persona) retome sin adivinar.
latest.md, secciones fijas, fechado, una estructura para todos.
Prime es la lectura de AGENTS.md → context → tasks → handoffs al inicio. En Claude se vuelve una skill; en Codex, una instrucción en el AGENTS.md; en dsh, una skill de prime.
Sin prime, el handoff es un archivo que nadie lee.
Prime, orden de lectura, skill × instrucción, briefing pequeño.
La prueba final: handoff escrito en una sesión de Claude, retomado en una sesión nueva de Codex, y viceversa, en un proyecto real.
Ese es el criterio de terminado del sistema entero.
Handoff cruzado, mismo Markdown, ejecutores intercambiables.
En esta máquina: 6.859 sesiones de Claude (2,3 GB) y 209 de Codex. Después de que el ciclo corre, archivar las de más de 90 días.
La memoria cruda es materia prima; lo que vale es lo que fue promovido a overview o handoff.
JSONL, archivar, promover hecho, materia prima × fuente.
Ninguna sesión termina sin handoffs/latest.md y tasks/current.md actualizados. El readback del día siguiente es la verificación.
Es la única disciplina que hace que el cambio de modelo sea indoloro.
Fin de sesión, actualizar dos archivos, readback como auditoría.