Ir al contenido
Volver al blog

IA y automatización

Cómo mantener la calidad del software en un mundo agéntico

Rowin Hernández · 15 de septiembre de 2026

Layers of glass code under a precision inspection bridge, one flaw lit in violet

Los agentes rara vez producen código que esté claramente mal. Producen código verosímil. Esta es la maquinaria que usamos en nuestro propio sitio de producto para que lo verosímil no llegue a producción.

El coste de producir software ha caído en picado en los últimos dos años. El coste de responder por él no se ha movido nada.

El problema está en la distancia entre esos dos costes. La mayoría de los equipos que adoptan el desarrollo agéntico siguen con un proceso de calidad pensado para la proporción antigua, en la que escribir el código era lo caro y revisarlo era barato en comparación. Invierte la proporción y el proceso deja de funcionar. Ahora hay más resultado del que nadie puede leer con atención, y la lectura atenta era el control.

Así construimos nuestro propio sitio de producto, Kalebtec Websites. A continuación está la maquinaria que usamos en ese repositorio y el razonamiento detrás de cada pieza. Nada de esto es exótico. Casi todo es más antiguo que las herramientas de las que ahora nos protege.

Lo verosímil es el modo de fallo

La versión popular de lo que sale mal es engañosa. Los agentes no suelen producir código claramente roto. El código claramente roto es el caso fácil: falla un test o un build, y alguien se da cuenta en diez segundos.

Lo que producen es código verosímil. Compila, se lee bien, usa tus convenciones de nombres y está sutilmente equivocado en algo que un revisor tendría que saber de antemano para detectarlo. Lo mismo pasa con la prosa. Pídele a un agente una página sobre tu garantía y te escribirá un párrafo seguro y fluido sobre una garantía un grado más generosa que la que puedes cumplir.

La revisión humana es una mala defensa contra lo verosímil, y empeora a medida que sube el volumen. Así que el control tiene que moverse. Restringes el entorno que produce el resultado y haces que lo que te importa se pueda comprobar de forma mecánica.

Uno: las reglas viven en el repositorio

Nuestras reglas de trabajo están en un único AGENTS.md en la raíz del repositorio: formato de commits, la regla de design tokens, nombres de archivo en kebab-case, server components por defecto, el mínimo de accesibilidad y la lista de comandos que un agente no puede ejecutar sin autorización. Todos los harness leen ese mismo archivo. Los archivos de configuración de cada herramienta apuntan a él y nunca lo duplican.

Suena a tarea doméstica. Si tus reglas viven en el formato de configuración de un proveedor, tus estándares solo se aplican a quienes usan ese proveedor este mes, y una regla que cambiaste hace seis meses se sigue aplicando en otros tres sitios. Peor aún, un agente no puede seguir una regla que solo existe en la cabeza de un ingeniero sénior.

La prueba útil: ¿podría un desconocido competente, sin acceso a tu equipo, producir trabajo que pase la revisión leyendo solo lo que hay en el repositorio? Si no, lo que le falta se sostiene hoy solo con tu atención.

Dos: todo lo que te importa tiene que ser un gate

Las reglas escritas son necesarias y no bastan. Un agente sigue una regla escrita la mayor parte del tiempo, lo que significa que la regla no se cumple.

Así que los estándares que importan son maquinaria. En este código eso significa:

  • Un gate local que tiene que estar en verde antes de cualquier push: ESLint, tsc --noEmit, Prettier y un build de producción completo.
  • Accesibilidad analizada con axe en cada ruta del barrido, a dos anchos de viewport y en los dos esquemas de color, y cualquier infracción grave o crítica hace fallar el build directamente.
  • Un control de contraste específico por encima del análisis de página completa, limitado a los elementos cuyo contraste ya reparamos. Comprueba que la regla llegó a cada elemento y que el elemento pasa. Un análisis general puede pasar aunque se haya deshecho una corrección concreta.
  • Tests de comportamiento para lo que una comprobación estática no ve: el menú móvil mantiene el foco dentro durante doce pulsaciones de tabulador y lo devuelve al pulsar Escape, y el banner de consentimiento no lanza ninguna petición de analítica antes de que se elija una opción.
  • CI que se ejecuta con todas las variables de entorno sin definir. Sin Stripe, sin analítica, sin backoffice, sin auth. La aplicación está construida para no hacer nada sin ellas, y un test comprueba que es así, de modo que ningún gate puede depender nunca de un tercero en vivo.

Hay un detalle que importa más de lo que parece. Un git hook impone nuestro requisito de consulta, y lo elegimos a propósito. Un git hook obliga a todos los agentes, a todos los harness y a todas las personas que hacen commit en el repositorio. Un hook en una CLI solo obliga a quien use esa CLI. A medida que más de tus colaboradores dejan de ser personas, ese hook cubre cada vez menos trabajo.

Cuando nuestro gate era una constante de texto

Nuestra propia historia tiene un ejemplo.

Teníamos un artículo sobre WCAG 3.0 que no tenía permiso para publicarse. Vivía en un archivo de código que nadie importaba, y el archivo exportaba una constante de texto llamada publishGate cuyo valor explicaba las condiciones que había que cumplir antes. Todos los implicados entendían el acuerdo, y se mantuvo.

Se mantuvo porque todos lo entendían. Nada lo imponía. En cuanto alguien importara ese archivo, ya fuera un agente limpiando módulos sin usar o una persona conectando el índice del blog, el artículo se habría publicado. El texto que explicaba por qué no debía publicarse habría salido con él como código muerto.

Ese artículo vive ahora en una colección de contenido con un campo holdReason. El hook beforeChange de la colección se niega a publicar cualquier documento que tenga uno, diga lo que diga el campo de estado, así que la condición viaja ahora con el artículo. Sigue sin publicarse, por los motivos que explicamos más abajo.

Tres: el repositorio es la memoria

Un agente empieza cada sesión sin recordar por qué nada es como es. Si lo dejas solo, volverá a deducir una decisión que tomaste a propósito hace seis meses y llegará a la conclusión contraria, con un razonamiento bien argumentado. El razonamiento que descartó la alternativa no está en ningún sitio que pueda leer.

Para eso exactamente llevamos registros de decisiones de arquitectura (ADR): una decisión por archivo, modificada en el mismo archivo, y ahora mismo hay más de 200. Para saber si algo es un ADR basta una pregunta. ¿Lo necesitaría alguien que lo lea dentro de seis meses para no volver a deducir una elección, o para no contradecir algo que hemos publicado?

Lo que mantiene esto usable es saber qué no es un ADR: correcciones de bugs, relatos de merges, qué gates se pusieron en verde, el triaje de tests fallidos, defectos corregidos de paso. Git ya guarda todo eso, de una forma que no se desvía. Nuestros ADR sustituyeron a un registro de solo añadir que había llegado a 9.923 líneas de decisiones mezcladas con relatos de merges, y nadie encontraba nada en él.

La segunda prueba, cuando la primera no está clara: ¿limita el trabajo futuro? Una corrección no. Una regla sí.

Cuatro: cataloga lo que has prometido

La mayoría de los equipos de ingeniería no tienen esta capa. Para nosotros resultó ser la que más importa.

Los agentes escriben ahora textos de marketing. Los textos de marketing contienen promesas. En España, donde tenemos nuestro domicilio, una promesa hecha a un consumidor en una comunicación comercial obliga. Una garantía comercial obliga al comerciante en los términos en que se ofreció, publicidad incluida, y cuando el documento de garantía es menos favorable que la publicidad, prevalece la publicidad. Una promesa que no puedes cumplir es una práctica engañosa, y se puede reclamar sin que ningún cliente tenga que demostrar un perjuicio.

Así que cada promesa de cara al cliente en nuestro sitio está catalogada en un único registro: garantías, reembolsos, precios y congelaciones de precio, plazos de entrega, tiempos de respuesta, cualquier afirmación que contenga las palabras para siempre, ilimitado, en cualquier momento o nunca, promesas de propiedad y exportación, y afirmaciones de calidad y accesibilidad. Añadir una promesa significa actualizar el registro en el mismo ciclo, contrastarla con las promesas que ya hay para detectar conflictos y confirmar que existe un mecanismo para cumplirla.

La última comprobación es la que más importa. Si publicamos una promesa sin forma de cumplirla, quedamos expuestos desde el día en que sale.

Esto es lo que detectó el registro. El borrador de nuestro blog afirmaba que todos los sitios que construimos cumplen WCAG 2.2 AA. Nuestra propia declaración de accesibilidad, escrita en otra sesión y con otro fin, describía este sitio como parcialmente conforme. Ninguna de las dos frases era mentira y ningún paso concreto fue descuidado. No podían ser ciertas las dos tal como las leería un cliente, y nada en un proceso de revisión normal iba a poner esos dos párrafos uno al lado del otro.

El registro lo hizo. El artículo está retenido hasta que exista una comprobación de WCAG 2.2 AA dentro de nuestro proceso de entrega a clientes y las dos afirmaciones estén conciliadas. Retenerlo nos cuesta un artículo. Publicarlo nos habría comprometido con algo para lo que todavía no hemos construido la maquinaria que lo cumpla.

Haz legible la vía de escape

Todo gate necesita una forma de saltárselo, o la gente rodea el propio gate y pierdes la señal. La cuestión es cuánto cuesta saltárselo.

El nuestro pide un motivo. Saltarse el requisito de registro de decisiones implica definir una variable de entorno con una frase que explique por qué este cambio no es una decisión, y esa frase se imprime en la salida del commit, donde la ve quien revisa. El hook no puede verificar que alguien lo haya pensado. Verifica la frase que deja ese pensamiento y hace visible cada salto.

Elegimos una frase en lugar de un booleano porque un flag booleano se activa una vez y nunca se desactiva.

Lo que cuesta

Al principio es más lento. Poner por escrito un estándar que llevabas implícito es trabajo de verdad, y la primera pasada sobre un código existente encontrará contradicciones que preferirías no haber encontrado.

También tiene su propio modo de fallo. Los gates que saltan sin motivo acaban desactivados, y un gate desactivado no protege nada aunque siga en la lista de cosas que haces. Los nuestros son pequeños y deterministas a propósito, para que no salten sin motivo.

A cambio obtienes comprobaciones que escalan. Los gates se ejecutan a velocidad de máquina en cada cambio, lo haga quien lo haga, y no se cansan un viernes a las cinco de la tarde. La atención humana va a las decisiones. Esa siempre fue la parte por la que merecía la pena pagar, y ninguna de estas herramientas se ha acercado a sustituirla.

El desarrollo agéntico sube el listón del rigor en ingeniería. Ahora puedes generar en una tarde más trabajo verosímil del que un equipo cuidadoso podría revisar en una semana, así que la revisión ya no puede ser el control.

El sitio que describe este artículo es Kalebtec Websites, nuestra oferta productizada de sitios web: precios publicados, un alcance publicado y una auditoría de accesibilidad publicada en la que suspendimos algunas partes y que publicamos igualmente. Está construido bajo todas las reglas anteriores, y por eso no nos importa ponerlas por escrito en público.