El mismo PR, dos reviews distintas
Un desarrollador de mi red configuró Claude Code como reviewer de código en su CI. “Haz que Claude revise el PR”, me dijo. “Detecta cosas que yo no vería.” Le pedí que pasara el mismo PR por Claude dos veces.
La primera review dijo que el manejo de errores parecía completo. La segunda lo marcó como insuficiente y sugirió tres cambios. Se quedó cinco minutos mirando la pantalla preguntándose cuál de los Claude tenía razón.
Ninguno tenía razón. Ninguno estaba equivocado. El LLM estaba haciendo suposiciones probabilísticas, no aplicando reglas deterministas. Y ese es el problema fundamental de usar IA para verificación: la verificación exige dos propiedades que los LLM no tienen. Determinismo: la misma entrada siempre produce la misma salida. Completitud: todos los modos de fallo se detectan, siempre.
El problema del determinismo
Pasa el mismo código por Claude Code dos veces y quizá recibas dos reviews distintas. La temperatura, la ventana de contexto, la forma del prompt: todo introduce variación. Para brainstorming, la variación es una ventaja. Para verificación, es un bug. No puedes construir software confiable sobre quality gates probabilísticos.
Las comprobaciones deterministas no tienen este problema. tsc --noEmit siempre produce los mismos errores. ESLint con la misma config siempre marca los mismos problemas. Estas herramientas aplican reglas, no probabilidades. Son aburridas. Por eso funcionan.
El stack de guardas O(1)
Así se ve nuestro stack de pre-commit. Cada comprobación es determinista. Cada comprobación corre en milisegundos. A ninguna le importa si el código lo escribió una persona o Claude Code:
# Pre-commit (< 1 second total)
TypeScript strict mode # tsc --noEmit
ESLint boundary rules # module isolation
Import restrictions # dependency direction
dependency-cruiser # graph analysis
Unit tests # contract verification
# CI (< 30 seconds)
Full test suite
Bundle size checks
Fresh clone launch test
La métrica clave es O(1) en relación con el tamaño de la codebase. El type checking es incremental. El linting es por archivo. dependency-cruiser analiza el grafo de imports de forma lineal. Ninguna de estas comprobaciones se vuelve más lenta a medida que tu app hecha con vibe coding crece. Las reviews de Claude Code sí se vuelven más lentas y menos precisas conforme tu codebase supera la ventana de contexto.
Lo que sí detectan las comprobaciones deterministas
La semana pasada, dependency-cruiser detectó un PR en el que un componente de pantalla importaba directamente desde una implementación de servicio en lugar de hacerlo desde el barrel. El PR compilaba bien. Los tests pasaban. Cursor había generado la importación automáticamente. Pero violaba nuestra regla de arquitectura: solo la composition root importa implementaciones.
Una review de LLM podría haber detectado esto. O podría haberlo pasado por alto porque el PR era grande y el import estaba enterrado a mitad del archivo. dependency-cruiser nunca se lo pierde porque no está leyendo código, está analizando un grafo:
// .dependency-cruiser.cjs
// 8 lines. 100ms. Catches this every time, forever.
{
name: 'no-deep-service-imports',
comment: 'Only service barrels are public.',
severity: 'error',
from: { pathNot: '^src/services/' },
to: {
path: '^src/services/[^/]+/',
pathNot: '^src/services/[^/]+/index\.ts$',
}
}
Ocho líneas. Menos de cien milisegundos. En cada PR. Para siempre. Una review de Claude Code cuesta tokens, tarda segundos y puede pasarlo por alto. La comparación ni se acerca.
Dónde sí encaja la IA
No estoy en contra de la IA. Uso Cursor y Claude Code a diario para redactar código, explorar enfoques, escribir tests y depurar. Pero no les doy un papel de verificación. La verificación debe ser determinista. Debe ser aburrida. Debe ser la misma cada vez.
Los guardrails deben ser invisibles e inevitables. Deben atrapar problemas sin que nadie tenga que recordar ejecutarlos. Eso es lo que te dan las comprobaciones deterministas: una red de seguridad que nunca duerme, nunca se cansa y nunca pierde el contexto a medida que tu codebase crece.
El Autotomy Expo Starter Pack incluye TypeScript strict mode, reglas de boundaries en ESLint, configuración de dependency-cruiser y hooks de pre-commit, todo preconfigurado. Obtienes la velocidad de Cursor para generar. Obtienes precisión de máquina para verificar. Así haces vibe coding sin romper producción.