Seamos honestos sobre algo que la mayoría no dice en voz alta: casi no revisamos el código generado por IA.
El diff tiene 600 líneas. El agente tocó 14 archivos. Abres el pull request, haces scroll por los cambios, entrecierras los ojos ante un par de funciones y mergeas. Quizás corres los tests primero. Quizás no. El código se ve razonable. El agente dijo que terminó. A producción.
Esto no es pereza. Es un problema estructural. La revisión de código tradicional fue diseñada para un mundo donde un humano escribió el código y podía explicar su razonamiento cuando se le preguntaba. Donde los diffs eran de 50-200 líneas porque eso es lo que una persona escribe en una sesión concentrada. Donde la descripción del PR decía "Elegí el enfoque X por Y" y podías confiar en ese contexto.
Los agentes de IA no funcionan así. Claude Code puede producir 500 líneas de código funcional en dos minutos. La descripción del PR suele ser simplemente "implementar feature X." El diff te dice qué cambió pero nada sobre el por qué. Sin registro de qué alternativas consideró el agente. Sin explicación de qué compromisos hizo. Sin evidencia de que realmente probó algo. Estás revisando el output de una caja negra, y la herramienta de revisión solo te muestra el output.
Este artículo desglosa por qué la revisión basada en diffs falla para el output de agentes, cuál es la capa realmente faltante, y un patrón concreto que hace el código generado por IA revisable sin triplicar tu tiempo de revisión.
La brecha en la revisión
Los desarrolladores son honestos sobre esto en privado. En hilos de la comunidad, el patrón se repite: "Básicamente solo ojeo los diffs del agente." "Verifico que los tests pasen y mergeo." "Si se ve más o menos bien, apruebo."
Este es un comportamiento racional dadas las restricciones. Cuando un colega humano envía un PR, tienes contexto: sabes en qué estaba trabajando, viste el ticket, quizás discutieron el enfoque en el standup. El diff es complementario. La verdadera revisión ocurrió a través del contexto compartido.
Con un agente, no tienes nada de eso. El agente tomó una tarea, estuvo en silencio tres minutos y produjo un diff. El único contexto es la descripción de una línea que el agente dejó en el PR. Revisar ese diff desde cero, sin contexto sobre intención o razonamiento, toma 5-10x más que revisar un PR humano del mismo tamaño. Así que la gente no lo hace. Verifican por encima algunas áreas críticas y aprueban.
El resultado es predecible. Se cuelan bugs que se habrían detectado con contexto. La deriva arquitectónica se acumula conforme los agentes toman pequeñas decisiones que se componen. La calidad del código se degrada de formas sutiles: no roto, pero tampoco del todo correcto. Manejo de errores inconsistente en un archivo. Una consulta a base de datos que funciona pero escala mal. Una nueva función utilitaria que duplica una existente porque el agente no sabía que existía.
Ninguna de estas fallas es visible en una revisión de diff. Solo son visibles cuando entiendes lo que el agente intentaba hacer y puedes comparar su intención contra su ejecución.
Por qué los diffs no son suficientes
Un diff es un registro de cambios textuales. Eso es todo. Para la revisión de código humana, los diffs funcionan porque el revisor puede inferir intención a partir del reconocimiento de patrones y el contexto compartido. Ves a un colega agregar un bloque try/catch y sabes que está manejando el caso de error del bug report de la semana pasada. Lo ves renombrar una función y sabes que está siguiendo la convención de nombres que el equipo acordó.
Con código generado por agente, no puedes inferir intención porque no fuiste parte del proceso de razonamiento. Esto es lo que un diff de 500 líneas de un agente realmente te dice:
- Qué archivos fueron modificados
- Qué líneas fueron agregadas, cambiadas o eliminadas
- La estructura sintáctica del nuevo código
Esto es lo que no te dice:
Por qué se eligió este enfoque. El agente pudo haber considerado tres implementaciones diferentes. Eligió una. No sabes por qué. Quizás la que eligió es óptima. Quizás fue lo primero que probó y funcionó suficientemente bien. No puedes saberlo por el diff.
Qué alternativas fueron descartadas. Si el agente eligió una estrategia de polling sobre suscripciones WebSocket, ¿fue una decisión arquitectónica deliberada o un accidente? Un diff no lo dice.
Si la implementación coincide con la spec. Necesitarías abrir la spec en una ventana y el diff en otra y cruzar manualmente cada criterio de aceptación. La mayoría no lo hace.
Qué se probó y cómo. El diff puede incluir archivos de test nuevos. ¿Pero el agente los ejecutó? ¿Pasaron? ¿Cubren los casos límite de la spec? Necesitarías hacer checkout del branch y ejecutarlos tú mismo para saberlo.
Si el agente se mantuvo dentro del alcance. Quizás la tarea era "arreglar el bug de login" y el agente también refactorizó el middleware de auth, renombró dos funciones utilitarias y actualizó el esquema de configuración. Todos esos cambios se ven bien de forma aislada. Pero no fueron solicitados, no fueron especificados y no fueron probados contra los criterios de aceptación originales.
Esto no es un problema de una herramienta de diff particular. La interfaz de revisión de GitHub, los merge requests de GitLab, Gerrit, git diff en la terminal. Todos te muestran lo mismo: qué cambió. Para output de agentes, "qué cambió" es la pregunta menos importante. La pregunta importante es: ¿Este cambio hace lo que se suponía que debía hacer, y nada más?
La capa faltante: narrativa de implementación
Lo que los revisores realmente necesitan es el rastro de razonamiento del agente. No el diff. La historia de la implementación: qué planeó el agente, qué hizo realmente y cómo verificó el resultado. Llámalo narrativa de implementación.
Una buena narrativa de implementación responde cinco preguntas:
- ¿Cuál era el plan? Antes de escribir código, ¿qué pretendía hacer el agente? ¿Qué archivos, qué enfoque, qué orden de operaciones?
- ¿Qué pasó durante la implementación? ¿El plan sobrevivió al contacto con la codebase? ¿Hubo sorpresas, pivotes o cambios de alcance?
- ¿Cuál fue el resultado final? No el diff. Un resumen en lenguaje claro de qué cambió y por qué.
- ¿Cómo se verificó? Pasos específicos que el agente tomó para confirmar que la implementación funciona. No "tests pasan" sino "Ejecuté el criterio de aceptación #3 haciendo X y observé Y."
- ¿Qué debería revisar el revisor? La propia recomendación del agente sobre qué merece atención humana. Quizás hay una decisión de diseño que podría ir en cualquier dirección, o un compromiso de rendimiento que merece una segunda opinión.
Nada de esto existe en un workflow de PR estándar. El campo de descripción del PR es texto libre que nadie impone. Los PRs de agentes usan descripciones mínimas por defecto porque al agente se le dijo que implementara, no que documentara su razonamiento.
La brecha no es el tooling. Es el proceso. La infraestructura de revisión existe. Lo que falta es un registro estructurado de la intención del agente que el revisor pueda verificar contra el diff.
Aquí hay un patrón que cierra la brecha sin agregar overhead significativo. Tiene tres partes: el agente comenta un plan antes de escribir código, implementa, y comenta un reporte done estructurado cuando termina.
Paso 1: El comment de plan
Antes de que el agente abra cualquier archivo, escribe lo que pretende hacer. Pasos numerados, archivos que tocará y el enfoque que tomará.
PLAN: Fix WebSocket reconnection dropping messages during
server restart.
1. Add a message buffer to hooks/use-websocket.ts that queues
outbound messages while the connection is in CONNECTING state
2. On successful reconnection, flush the buffer in order
3. Add a 30-second timeout: if reconnection hasn't succeeded,
surface an error to the user via the toast system
4. Update the existing reconnection test to verify buffer
behavior
Files: hooks/use-websocket.ts, components/connection-status.tsx
Test: Unit test for buffer queueing/flushing, manual test by
killing the WS server mid-operation and verifying no messages
are lost on reconnect.
Esto le toma al agente unos 30 segundos. El revisor lo lee en menos de 2 minutos. En esos 2 minutos, detectas problemas que costarían 20 minutos encontrar en una revisión de diff:
- ¿El alcance es correcto? (El plan dice 2 archivos. Si el diff toca 6, algo se desvió.)
- ¿El enfoque es sólido? (Un buffer de mensajes con flush-on-reconnect es razonable. Si el agente hubiera propuesto recargar todo el estado desde el servidor, querrías discutirlo primero.)
- ¿Faltan pasos? (¿Qué pasa con los mensajes enviados durante la ventana de timeout? ¿Deberían descartarse o reintentarse?)
El plan es un checkpoint ligero. Revísalo, apruébalo, y el agente procede con un entendimiento compartido de la intención.
Paso 2: Implementación
El agente escribe el código. Nada cambia aquí. Pero como el plan existe, el agente tiene un roadmap que puede seguir en lugar de tomar decisiones ad hoc sobre la marcha.
Paso 3: El comment done
Cuando el agente termina, publica un reporte de completitud estructurado. No "listo." No "implementé la feature." Un relato detallado de lo que realmente hizo.
DONE: WebSocket reconnection now buffers outbound messages
during CONNECTING state and flushes on successful reconnect.
Changes:
- hooks/use-websocket.ts: Added messageBuffer ref, queue
messages when readyState !== OPEN, flush in FIFO order on
'open' event. Added 30s reconnection timeout.
- components/connection-status.tsx: Shows "Reconnecting..."
badge during buffer state, switches to error toast after
timeout.
QA Verification:
1. Start dev server and WebSocket server
2. Open app, verify connection dot is green
3. Kill WebSocket server process
4. Trigger an action that sends a WS message (e.g., update
a bead status)
5. Restart WebSocket server within 30 seconds
6. Verify: the buffered message is delivered, bead status
updates in the UI
7. Repeat step 3, but wait >30 seconds before restart
8. Verify: error toast appears after timeout
Acceptance criteria:
- [x] Messages sent during reconnection are not lost (step 6)
- [x] Timeout surfaces user-visible error (step 8)
- [x] No behavior change when connection is stable (step 2)
Commit: f4e2a1b
Ahora el revisor tiene todo lo que necesita. Lee el plan (qué se pretendía), lee el comment done (qué se construyó realmente y cómo se verificó), y luego mira el diff con contexto completo. La revisión del diff pasa de "¿qué es todo esto?" a "déjame confirmar que esto coincide con lo que el agente dijo que hizo."
Checklists de revisión para output de agentes
Incluso con la narrativa de implementación, necesitas un enfoque sistemático. Aquí hay un checklist que uso cuando reviso output de Claude Code. Toma 5-10 minutos por revisión y detecta las categorías de bugs que los diffs solos pasan por alto.
Alineación con la spec:
- ¿La implementación aborda cada criterio de aceptación de la spec?
- ¿Hay cambios que van más allá de lo que la spec pedía?
- ¿El comment done mapea cada criterio a un paso de verificación?
Contención de alcance:
- ¿El agente solo modificó archivos listados en su plan?
- Si tocó archivos adicionales, ¿hay una razón declarada?
- ¿Hay cambios de "limpieza" (renombramientos, reformateos, refactorizaciones) que no eran parte de la tarea?
Cobertura de tests:
- ¿Existen tests nuevos para el comportamiento nuevo?
- ¿Los tests realmente prueban lo correcto? (Los agentes a veces escriben tests que pasan trivialmente porque prueban el mock, no la implementación.)
- ¿El agente afirmó haber ejecutado los tests? ¿Hay evidencia?
Consistencia arquitectónica:
- ¿Los cambios siguen patrones existentes en la codebase?
- ¿Hay nuevas abstracciones que duplican las existentes?
- ¿La estrategia de manejo de errores coincide con el resto del proyecto?
Conciencia de dependencias:
- Si el agente agregó dependencias, ¿están justificadas?
- ¿Los cambios rompen funcionalidad existente? (Verifica archivos que importan los módulos modificados.)
- Si la tarea tiene dependencias con otras tareas, ¿están esas dependencias resueltas?
Este checklist funciona con cualquier herramienta de revisión de código. Imprímelo en un post-it, ponlo en tu template de PR, o intégralo en tu CLAUDE.md para que el agente sepa a qué estándar se le medirá. El punto no son los ítems específicos. Es tener un protocolo estructurado en lugar de "se ve bien."
Beads como superficie de revisión
El patrón plan-comment-done necesita un lugar donde vivir. Si los planes y comments done están dispersos entre mensajes de Slack, descripciones de PR y output de terminal, pierdes la conexión entre la spec, el plan, la implementación y la verificación.
Este es el problema que beads resuelve. Beads es un issue tracker Git-nativo y open-source donde cada "bead" lleva el ciclo de vida completo de una tarea: la spec como descripción, planes del agente como comentarios, reportes done como comentarios y resultados de QA como comentarios. Todo adjunto a una entidad, buscable y permanente.
Así se ve el workflow de revisión con el CLI bd:
Crear la tarea con la spec:
bd create --title "Fix WebSocket reconnection message loss" \
--description "## Problem
Messages sent during WebSocket reconnection are silently
dropped...
## Acceptance Criteria
1. Messages queued during CONNECTING state are delivered
on reconnect
2. 30-second timeout surfaces error to user
3. No behavior change when connection is stable" \
--type bug --priority p1
El agente reclama el trabajo y publica un plan:
bd update bb-f4e2 --claim --actor eng1
bd comments add bb-f4e2 --author eng1 "PLAN: Add message
buffer to WebSocket hook...
1. Queue outbound messages when readyState !== OPEN
2. Flush buffer in FIFO order on 'open' event
3. Add 30s timeout with error toast
4. Update reconnection test
Files: hooks/use-websocket.ts, components/connection-status.tsx"
Revisas el plan en 2 minutos:
bd show bb-f4e2 # Leer spec + comment del plan
Si el plan se ve bien, el agente procede. Si no, comentas con correcciones antes de que se escriba código.
El agente completa y publica un reporte done:
bd comments add bb-f4e2 --author eng1 "DONE: WebSocket
reconnection now buffers outbound messages...
QA Verification:
1. Kill WS server, trigger action, restart within 30s...
Acceptance criteria:
- [x] Buffered messages delivered on reconnect
- [x] Timeout error visible
- [x] No regression on stable connection
Commit: f4e2a1b"
bd update bb-f4e2 --status ready_for_qa
QA verifica independientemente:
bd show bb-f4e2 # Leer los pasos de verificación del comment done
# Ejecutar cada paso
bd comments add bb-f4e2 --author qa1 "QA PASS: All 3 criteria
verified. Buffer flushes correctly, timeout fires at 30s,
stable connections unaffected."
Todo el rastro de revisión está en un lugar. Seis meses después, cuando alguien pregunte "¿por qué el WebSocket almacena mensajes en buffer durante la reconexión?", la respuesta está en el bead: la spec explica el problema, el plan explica el enfoque, el comment done explica qué se construyó, y el comment de QA confirma que funciona.
Cuando la revisión en terminal llega a su techo
Ejecutar bd show en una tarea te da todo. Pero cuando estás revisando output de múltiples agentes a través de varios workstreams paralelos, el workflow de CLI escala linealmente: un bd show por tarea, un bd list para ver qué está listo para revisión, un bd show por plan que necesitas aprobar.
Aquí es donde Beadbox encaja. Beadbox es un dashboard en tiempo real que te muestra cada tarea en tu workspace con su estado actual, último comentario y posición en el pipeline de revisión. Ves qué agentes han publicado planes que necesitan tu aprobación. Cuáles han publicado reportes done listos para tu revisión. Cuáles aún están en progreso. Todo actualizándose en vivo conforme los agentes escriben comentarios y cambian estados a través del CLI bd.
No necesitas Beadbox para usar el patrón plan-comment-done. El CLI maneja todo el workflow. Pero cuando tienes cinco agentes produciendo output revisable simultáneamente, poder ver la cola de revisión de un vistazo en lugar de consultar cada tarea individualmente cambia la velocidad a la que avanzas por el pipeline.
Beadbox es gratis durante la beta, y el CLI beads sobre el que corre es open-source.
El problema de revisión no se resolverá solo
El código generado por IA aumenta más rápido que nuestra capacidad de revisarlo. Las herramientas que tenemos fueron construidas para una escala y un workflow diferentes. GitHub PRs, diffs en IDE, incluso análisis estático sofisticado: ninguno aborda el problema fundamental, que es que revisar código sin conocer la intención del autor es dramáticamente más difícil que revisarlo con ella.
La solución no son mejores herramientas de diff. Es intención estructurada: un registro de qué planeó el agente, qué hizo realmente y cómo verificó el resultado. El patrón plan-comment-done te da ese registro sin agregar overhead significativo. El agente pasa 30 segundos escribiendo un plan. Tú pasas 2 minutos revisándolo. El agente pasa 60 segundos escribiendo un reporte done. Tú revisas el diff con contexto completo en lugar de desde cero.
Cinco principios para llevar:
-
Exige planes antes del código. Un comment de plan de 30 segundos ahorra sesiones de revisión de 20 minutos. Si el plan está mal, corrígelo antes de que exista código.
-
Exige reportes done estructurados. "Listo" no es un reporte done. Pasos de verificación, mapeo de criterios de aceptación y hashes de commit son un reporte done.
-
Revisa contra la spec, no contra el diff. El diff muestra qué cambió. La spec dice qué debería haber cambiado. Cruza las referencias.
-
Impón límites de alcance. Si el agente tocó archivos fuera de su plan, es una señal de alerta. Cambios no planificados son cambios no revisados.
-
Trata la revisión como un protocolo, no como un juicio. Un checklist detecta más bugs que la intuición. "Se ve bien" no es una revisión.
Los agentes seguirán siendo más rápidos. Los diffs seguirán siendo más grandes. La pregunta es si tu proceso de revisión escala con ellos, o si sigues entrecerrando los ojos ante diffs de 600 líneas esperando lo mejor.
Si estás construyendo workflows como estos, dale una estrella a Beadbox en GitHub.