Por qué los errores de código en Windsurf se cuelan en la revisión
La revisión humana escala según la cantidad de líneas que una persona puede retener en la cabeza. Un cambio amplio y mecánico la derrota de una forma muy concreta: cada fragmento es plausible por sí solo, así que la atención se relaja. Apruebas el archivo número doce con menos rigor que el primero, y el defecto casi siempre está al final.
Además, el defecto rara vez está en lo que cambió, sino en lo que no cambió. Un renombrado que se saltó un punto de llamada, un campo obligatorio nuevo que tres constructores no pasan, un handler actualizado en todas partes menos en la ruta de error.
Las tres formas en que se rompe un cambio amplio
Barridos incompletos
Once puntos de llamada actualizados, uno olvidado, y está en una ruta que nadie ejercita a diario.
Los tipos a menudo no lo detectan porque ese punto ya estaba débilmente tipado.
Deriva de supuestos
Dos archivos acaban discrepando sobre el significado de un valor, como si un timestamp está en segundos o en milisegundos.
Cada archivo es coherente internamente, así que nada parece incorrecto por separado.
Cambio silencioso de comportamiento
Una refactorización conserva la interfaz y cambia sin avisar el orden, los valores por defecto o una ruta de error.
Las pruebas escritas contra la implementación anterior siguen pasando porque verifican la interfaz.
Los tres casos comparten algo: se encuentran usando la aplicación, no leyéndola. Eso es lo que los hace caros.
Verifica el comportamiento, no el diff
Ante un cambio amplio, la pregunta útil no es «¿cada edición es correcta?», sino «¿el producto sigue haciendo lo que hacía, más lo nuevo?». Esa es una pregunta de comportamiento, y se responde recorriendo la aplicación desplegada a través de los flujos que el cambio pudo haber tocado de forma plausible.
La cobertura no necesita ser exhaustiva para ser útil. Un cambio que renombra un campo en todo el flujo de checkout necesita que el checkout se ejercite de extremo a extremo una vez, y eso vale más que leer con cuidado doce diffs.
Instala la skill de verificación en el editor para que el agente pueda ejecutar esa comprobación por sí mismo en lugar de esperarte.
Terminal
npm install -g @testsprite/testsprite-cli
testsprite setup
El dashboard hace la misma configuración si prefieres no instalar nada. El resto de la superficie del CLI está en el repositorio del CLI.
Dale al agente el fallo, no tu resumen
Cuando algo se rompe, el ciclo de corrección solo se cierra si la evidencia es utilizable: qué se intentó, qué hizo la aplicación y dónde divergieron. Con eso en la mano, el agente puede volver a esos mismos doce archivos con un objetivo concreto. Con una captura de pantalla, adivina, y vuelves a tener que describirlo todo.
Leer un diff amplio sin autoengaños
Hay una forma honesta de revisar un cambio de doce archivos, y no consiste en leer cada fragmento. Consiste en decidir, antes de abrir el diff, qué tendría que ser cierto para que ese cambio fuera correcto, y comprobar solo eso.
En un renombrado, eso es si se movieron todos los puntos de llamada, algo que el compilador responde en buena medida, y si algo construye el nombre de forma dinámica, algo que no responde. En un campo obligatorio nuevo, es cada ruta que construye el objeto, incluidos los tests y los fixtures que seguirán pasando en silencio una versión incompleta. En una refactorización que conserva la interfaz, es el orden y las rutas de error, porque eso es justo lo que las refactorizaciones cambian sin avisar.
Tres preguntas por cambio rinden más que revisar por encima cuatrocientas líneas, y te dejan la lista honesta de lo que todavía hay que verificar ejecutándolo de verdad.
Elige los flujos por radio de impacto, no por importancia
Por instinto, la gente cubre la funcionalidad más importante. Ante un cambio amplio, la mejor pregunta es qué flujos pudo haber tocado el cambio, ordenados por lo silencioso que sería su fallo.
Un flujo de pago es importante y además está vigilado: si se rompe, te enteras en una hora. Los peligrosos son los flujos que importan pero se usan una vez por semana en lugar de cada hora: una exportación, una invitación, una página de configuración, un resumen programado. Ahí es donde un barrido incompleto se queda sin molestar a nadie durante un mes.
Así que, después de un cambio amplio, ejercita primero las rutas silenciosas. Son baratas de cubrir y son las que nadie más está comprobando.
Ejecútalo en cada pull request
Los cambios amplios son justo los que dan tentación de fusionar rápido porque el diff es aburrido. Ese es el argumento para que la comprobación sea automática en lugar de depender de que alguien se acuerde.
Dos vías, y la elección tiene que ver realmente con quién es el dueño del pipeline. Conectar la GitHub App desde el dashboard no requiere ningún cambio en tu repositorio, porque reacciona al despliegue que tu build ya emite. Añadir un paso de GitHub Actions coloca la comprobación en el repositorio, donde se revisa igual que el resto del build.
Verificar un cambio amplio sin leerlo
TestSprite responde la pregunta que un diff amplio no puede: ¿el producto sigue haciendo lo que hacía, más lo nuevo? Abre la aplicación desplegada, recorre los flujos que el cambio pudo haber tocado de forma plausible e informa sobre el comportamiento en lugar de la estructura.
Esa es la forma correcta de abordar este problema. Los barridos incompletos, los supuestos que se desvían y los cambios silenciosos de comportamiento son invisibles en el código fuente y evidentes en el uso. La cobertura se genera a partir de tu producto en lugar de escribirse a mano, así que los flujos silenciosos, la exportación, la invitación y la página de configuración, quedan incluidos sin que nadie tenga que acordarse de ellos.
Cuando algo se rompe, el fallo vuelve como un único paquete sobre el que tu agente puede actuar, y eso es lo que más importa aquí: señalarle la divergencia concreta funciona mejor que pedirle que vuelva a examinar doce archivos.
¿Por qué los tipos no detectan estos casos?
Detectan buena parte de los barridos incompletos y casi ninguna deriva de supuestos ni cambio silencioso de comportamiento, porque ambos son correctos en cuanto a tipos por construcción.
¿No sería mejor pedir cambios más pequeños?
Ayuda, y a la vez renuncia a buena parte del motivo para usar un editor agéntico. Un paso de verificación te permite conservar esa amplitud y aun así saber si el resultado funciona.
¿Funciona esto cuando el cambio es solo de backend?
Sí, mediante cobertura a nivel de API en lugar de la interfaz. El principio es el mismo: ejercitar el comportamiento en vez de leer el cambio.
¿Cuánto tarda una comprobación así?
Lo suficiente como para que no la ejecutes con cada pulsación de tecla, y lo bastante poco como para que quepa en un pull request. Ese es su lugar adecuado.
¿Y si el agente ya ejecutó las pruebas unitarias?
Sirven, pero las pruebas unitarias suelen estar escritas contra los supuestos que el cambio acaba de alterar. Confirman la coherencia interna, no la corrección externa.
Con doce archivos, leer el diff no es una verificación.
Los errores de código en Windsurf se esconden en barridos incompletos, supuestos que se desvían y cambios silenciosos de comportamiento. Verifica el producto en ejecución en lugar del diff, devuelve los fallos como evidencia y haz que la comprobación se ejecute en cada pull request.