Le encargas un bug a Claude Code y una pequeña funcionalidad a Codex, te alejas y, al volver, te encuentras con un archivo que se ve mal. Falta la edición de uno de los agentes. O están las dos ediciones y la compilación falla. O, peor aún, todo compila y una prueba se rompe en algún sitio que ninguno de los dos agentes tocó. Nada se cayó mientras estabas fuera. Los dos agentes hicieron el trabajo que les pediste. El archivo no podía albergar a dos autores a la vez, y nadie te dijo cuál ganó.
Ese silencio es el verdadero problema. Un archivo no es una herramienta de fusión. Cuando dos agentes de programación escriben en auth.ts dentro del mismo directorio en momentos que se solapan, no hay bloqueo, ni cola, ni advertencia; solo queda el proceso que guardó de último. Este artículo recorre la colisión paso a paso, pone nombre al modo de fallo en cada etapa y termina con una lista de verificación que puedes ejecutar antes de tu próxima sesión en paralelo.
También apunta hacia el flujo de trabajo al que conducen esas soluciones. Sharkly es una plataforma integral de comando y gestión de agentes que se sitúa por encima de los agentes de programación que ya usas. Le da a cada Task su propio worktree aislado y mantiene visibles el contexto, el progreso, los bloqueos, los resultados y la revisión humana desde la solicitud hasta el lanzamiento. Puedes construir la misma disciplina a mano con Git a secas, y la mayor parte de este artículo te muestra cómo. La última sección trata sobre cuándo deja de compensar hacerlo a mano.
No hay bloqueo: gana el último que escribe
Empecemos por la peor versión, porque es la más común y la menos visible. Ambos agentes se ejecutan en el mismo directorio de trabajo. El agente A lee auth.ts, planifica un cambio y empieza a escribir. El agente B lee el mismo auth.ts un segundo después, planifica un cambio distinto sobre la versión que leyó y también escribe.
Ninguno leyó la edición del otro, porque la edición aún no se había guardado cuando leyeron. Quien guarde en segundo lugar sobrescribe el archivo en disco con una versión que nunca contuvo el trabajo del primer agente. Esto es «gana el último que escribe», y es silencioso. No hay marcador de conflicto, ni error, ni código de salida. El agente A informa éxito. El agente B informa éxito. Uno de los dos te está mintiendo y no lo sabe.
La carrera por el archivo de bloqueo es el mismo fallo en un lugar más costoso. El agente A ejecuta npm install y reescribe package-lock.json; el agente B, a mitad de su instalación, lo reescribe otra vez desde un estado inicial distinto. El resultado es un archivo de bloqueo que no coincide con ninguno de los dos árboles de dependencias, y el fallo sale a la luz en la máquina de otra persona días después. Los artefactos de compilación compartidos, un único puerto del servidor de desarrollo y una caché global fallan exactamente igual.
La solución no es un agente más listo. Es darle a cada agente su propio espacio.
Una copia de trabajo por agente: el pisoteo silencioso se convierte en un conflicto visible
Un worktree de Git es una segunda copia extraída de un mismo repositorio, en su propia rama, que comparte un único almacén de objetos .git. Cada agente recibe un directorio real donde editar, compilar y probar sin ver el trabajo en curso de los demás.
# From the main repo
git worktree add ../repo-agent-a -b agent/auth-refactor
git worktree add ../repo-agent-b -b agent/session-timeout
Apunta al agente A a ../repo-agent-a y al agente B a ../repo-agent-b. Ahora las ediciones sin guardar de A en auth.ts son invisibles para B, y ningún agente puede sobrescribir el archivo del otro en disco, porque están editando dos archivos distintos en dos ramas distintas. El modelo de worktrees se trata con más profundidad en Git worktrees para agentes de programación con IA y en worktrees para agentes de programación: una copia extraída por tarea.
Fíjate en lo que logró aquí el aislamiento. No impidió que los dos agentes editaran el mismo archivo. Convirtió una pérdida de datos silenciosa en un conflicto de fusión visible en el momento en que las ramas vuelven a juntarse. Eso es una mejora real: Git se detiene y te muestra las líneas exactas en desacuerdo, y las resuelves con plena visión de ambas versiones. Un conflicto que puedes ver es un problema que puedes arreglar. El pisoteo que no podías ver era el que llegaba a producción.
Un límite que conviene dejar claro: los worktrees aíslan archivos, no efectos secundarios. Una base de datos compartida, un único puerto o una ruta de salida codificada de forma fija siguen colisionando entre worktrees. Aísla también esas cosas, o serializa los agentes que las necesiten.
El conflicto que no puedes ver
Aquí está el modo de fallo que sobrevive al aislamiento. El agente A, trabajando en su propio worktree, renombra getUser() a fetchUser() y actualiza cada punto de llamada que le corresponde. El agente B, trabajando en su propio worktree al mismo tiempo, escribe tres nuevos puntos de llamada a getUser(), porque ese era el nombre de la función cuando B leyó el archivo.
Ambas ramas se fusionan sin ningún marcador de conflicto. Git compara líneas, y línea por línea nada se solapó: A cambió sus archivos, B añadió otros nuevos. La fusión es limpia. Entonces la compilación falla por un getUser no definido, o compila y falla en tiempo de ejecución allí donde el verificador de tipos no pudo llegar. Ninguna herramienta lo marcó, porque textualmente no hubo colisión. Las dos ediciones discrepaban sobre el significado del archivo, no sobre su texto.
Por eso «basta con aislar a los agentes» no es la respuesta completa. El aislamiento traslada una colisión en el mismo archivo a una colisión en la misma interfaz, y el segundo tipo se esconde mejor que el primero. La palanca aquí es el alcance de las tareas, no las herramientas. Una regla útil: si no puedes describir las tareas de dos agentes sin nombrar el mismo archivo o la misma función, son una sola tarea, no dos. Dividir el trabajo siguiendo fronteras entre módulos es la mayor parte de lo que evita que Claude Code y Codex trabajen juntos en un mismo código base se convierta en una tarde de depuración. Cuando dos tareas comparten de verdad una interfaz, serialízalas, o fusiona y haz rebase entre pasos para que el segundo agente lea la realidad del primero.
Dónde deja de escalar la configuración casera y qué aporta un tablero de tareas
Dos agentes y un archivo compartido, puedes gestionarlo a mano: dos worktrees, un alcance cuidadoso, una fusión que vigilas. El método aguanta hasta que contar se vuelve difícil. Qué agente está en qué rama. Qué worktree corresponde a qué tarea. Cuál de cinco fusiones limpias cambió en silencio una interfaz compartida. Qué ramas esperan tu revisión y cuáles ya miraste. Los comandos de Git nunca se volvieron más difíciles; la contabilidad alrededor de ellos sí, y esa contabilidad es exactamente donde se cuelan las colisiones en el mismo archivo, porque aprobaste una fusión que no leíste del todo.
Un tablero de tareas cambia lo que estás siguiendo. En lugar de un muro de terminales y worktrees desacoplados, cada unidad de trabajo es una Task con un responsable, una rama y un estado. En Sharkly, una Task obtiene su propio worktree aislado de forma automática, así que el aislamiento a nivel de archivo es lo predeterminado en vez de un comando que debes acordarte de ejecutar. La ejecución, los bloqueos y los resultados vuelven a la Task, así que revisas un cambio contra su alcance declarado en lugar de deducir la intención a partir de un diff. Y el reparto del trabajo se mantiene fijo: los agentes investigan, ejecutan, prueban e informan; las personas marcan la dirección, conceden autoridad y aceptan el resultado. La automatización se detiene donde se requiere el criterio del equipo.
Ese último punto es el que el aislamiento por sí solo nunca resuelve. Mejores herramientas facilitan el aislamiento y la fusión, pero la revisión no escala con el número de agentes; escala con tu atención, y la revisión humana es el verdadero cuello de botella en el trabajo con agentes en paralelo. Cinco agentes producen cinco ramas en el tiempo que tardas en leer una con cuidado. Un tablero de tareas no lee el código por ti. Mantiene la cola ordenada para que la edición que parece plausible no acabe hojeada y fusionada porque perdiste la pista de en qué montón estaba. La misma aritmética de conflictos aparece también a nivel de repositorio, algo que se trata en múltiples agentes de programación en el mismo repositorio.
Puedes construir esto con worktrees y disciplina, o usar Sharkly para gestionar el flujo de trabajo. Si ya estás ejecutando varios agentes, el valor está en tener un único lugar donde vivan sus tareas y resultados en vez de repartidos entre terminales.
La lista de verificación que debes ejecutar antes de tu próxima sesión en paralelo
Ejecútala antes de apuntar dos agentes a cualquier cosa:
- Dale a cada agente su propio worktree. Nunca dos agentes en un mismo directorio de trabajo.
git worktree add ../repo-<task> -b agent/<task>por tarea. Consulta agentes en paralelo en worktrees aislados. - Define el alcance de las tareas para que no nombren el mismo archivo o la misma función. Si tienen que hacerlo, es una sola tarea; serialízala.
- Aísla los efectos secundarios, no solo los archivos. Separa bases de datos, puertos, rutas de salida y cachés, o serializa los agentes que las compartan.
- Haz rebase antes de fusionar cuando dos ramas partieron del mismo commit inicial, para que el trabajo del segundo agente quede encima del primero.
- Ejecuta la verificación de tipos y la suite de pruebas completa después de cada fusión, no solo después de la última. Los conflictos semánticos pasan una fusión limpia y fallan aquí.
- Revisa cada rama contra el alcance de su tarea, de una en una. Un montón de marcas verdes sin leer es donde llega a producción el conflicto invisible.
Que dos agentes editen un mismo archivo no es un caso límite raro; es lo que parece el trabajo en paralelo en el momento en que tus tareas se solapan por un centímetro. Planifica la colisión, hazla visible y mantén a una sola persona decidiendo qué se fusiona.



