Cristian Carreño

QA que los agentes pueden invocar

QA Console

Claude escribe el script de Playwright, la consola lo ejecuta y solo una aserción que se cumplió hace pasar un criterio.

Rol
Único autor
Período
oct. 2026
Estado
En uso, v0.11
Código
Privado, proyecto personal
commits en 3 días
24
versiones, de 0.1 a 0.11
18
pruebas
136
herramientas MCP
11
  • Python
  • FastAPI
  • Playwright
  • SQLite
  • MCP
  • OAuth 2.1
  • bubblewrap
  • Claude Code

01 Contexto

Por qué existe

Los agentes dicen que el trabajo de interfaz está listo, y comprobarlo a mano no escala. Preguntarle a otro modelo si se ve bien es una opinión, no una prueba. Quería un veredicto que fuera evidencia: un criterio pasa solo si una aserción sobre él se cumplió en un navegador real.

Dos problemas más le dieron forma. «Falló» abarca dos hallazgos distintos, que se rompió la prueba o que se rompió el producto, y un reporte tiene que mantenerlos separados. Y ejecutar solicitudes de QA de otras personas es peligroso: sin cercos, una consola así es una shell remota y un proxy hacia tu red, con una interfaz bonita.

02 Arquitectura

Cómo funciona

Una spec son instrucciones en texto libre más criterios de aceptación. La consola agrupa los criterios por perfil, hace que una sesión headless de Claude Code escriba un script de Playwright por grupo, revisa el script, lo ejecuta ella misma en un proceso nuevo y califica cada criterio a partir de lo que registró su propio harness. Ningún modelo participa en la calificación.

Ciclo de vida de una ejecución en QA Console Los clientes entran por una sola puerta, cada uno con su token y sus límites. El modelo solo escribe scripts; la consola les pasa el lint, los ejecuta en un proceso nuevo, en sandbox si la solicitud es externa, y califica a partir de las verificaciones registradas. Las preguntas que solo una persona puede responder van a la bandeja del operador. Clientes Operador Consola Sandbox, para solicitudes externas Agentes request_qa CI, claude.ai MCP, token propio Bandeja en Agents Control Puerta política + cupo Recepción valida, sin IA Lint deben poder fallar Calificador sin IA, enmascara Autor claude -p con tope Ejecutor proceso nuevo spec spec + token uno por perfil script aceptado registros preguntar a alguien
Los clientes entran por una sola puerta, cada uno con su token y sus límites. El modelo solo escribe scripts; la consola les pasa el lint, los ejecuta en un proceso nuevo, en sandbox si la solicitud es externa, y califica a partir de las verificaciones registradas. Las preguntas que solo una persona puede responder van a la bandeja del operador.
  1. Recepción, sin modelo

    La spec se valida. Las solicitudes externas no pueden definir comandos ni variables de entorno para los perfiles, y su destino tiene que estar en una lista de permitidos. Un solo módulo escribe el estado enviado.

  2. Los perfiles definen los grupos

    Un perfil es una identidad nueva que el script registra, o una entrada del catálogo local del operador; solo el catálogo puede leer secretos o ejecutar un comando de aprovisionamiento. Hay un script por perfil, y elegirlos es determinista.

  3. El modelo escribe, dentro de un cerco

    Un claude -p headless corre sin configuración de usuario, sin servidores MCP, sin sesión guardada, con un tope de gasto y un esquema JSON para su respuesta. Escribe el script sobre un harness pequeño y puede ensayarlo contra el destino real, pero un ensayo nunca es el veredicto.

  4. Lint antes de ejecutar

    Una pasada por el árbol sintáctico del script rechaza toda verificación sin aserción, todo try dentro de una verificación y todo acceso al registro propio del harness. Un script rechazado es una prueba rota: sus criterios quedan bloqueados y recibe un intento de reparación.

  5. Ejecutar, repetir, calificar

    La consola ejecuta el script en un proceso nuevo y muestra el avance en vivo. Si algo falló, ejecuta el mismo script una vez más: fallar dos veces es fallido, fallar una vez es intermitente. La calificación es una función pura que lleva de las verificaciones registradas a aprobado, fallido, intermitente, bloqueado, requiere una persona o no probado.

  6. Las personas deciden lo que las aserciones no pueden

    Un criterio que solo una persona puede juzgar se convierte en una pregunta con capturas en la bandeja del operador en Agents Control Center. La respuesta se guarda junto al estado del harness, nunca encima de él.

03 Decisiones

Las decisiones que le dieron forma

  1. Decisión 01

    El modelo escribe; la consola ejecuta y califica

    Elegí
    Un veredicto sale solo de una aserción que se cumplió en la ejecución propia de la consola.
    En vez de
    Un modelo como juez, extraer veredictos de la prosa o contar el ensayo del modelo como resultado.
    Porque
    Un veredicto debe ser evidencia, no opinión. Ningún modelo puede escribir «aprobado», y nada lo extrae del texto de un modelo.
    Costo
    Escribir los scripts es lento y cuesta dinero, y los criterios que el modelo no logra cubrir con una aserción quedan como no probados o a la espera de una persona.
  2. Decisión 02

    Acotar el código del modelo, y nunca dejar que repare una falla

    Elegí
    Lint, una repetición idéntica sin ningún modelo de por medio e intentos de reparación solo para pruebas rotas.
    En vez de
    Confiar en el script, o dejar que el modelo arregle lo que haya fallado.
    Porque
    Cuando el producto falla, ese es el hallazgo. «Arreglar» una falla del producto es justamente la forma en que un agente finge un aprobado, así que el prompt de reparación prohíbe cambiar lo que exige cualquier aserción.
    Costo
    Un grupo que falla se ejecuta dos veces, y el lint prueba que existe una aserción, no que verifique lo correcto.
  3. Decisión 03

    Dos sandboxes, nunca el mismo

    Elegí
    El proceso que escribe código y tiene el login del modelo corre en una jaula; el script que toca el destino corre en otra, solo con los valores del perfil y con acceso de red únicamente al destino.
    En vez de
    Un sandbox compartido, o correr en silencio sin uno cuando falta la herramienta de sandbox; ese caso, en cambio, falla.
    Porque
    De lo contrario, una spec hostil podría llevar a un script a leer las credenciales del modelo y enviarlas a un destino que controla el solicitante.
    Costo
    Solo Linux, un proxy con lista de permitidos que mantener, y las solicitudes externas se rechazan en máquinas sin el sandbox.
  4. Decisión 04

    Clientes verificados de antemano por MCP, cada uno con sus límites

    Elegí
    Cada cliente tiene su propio token guardado como hash, sus scopes, sus destinos y perfiles permitidos, su presupuesto diario y su concurrencia, y se puede revocar por separado. claude.ai se conecta por OAuth 2.1, donde la invitación es la autorización previa.
    En vez de
    Un secreto compartido, donde revocar a un cliente revoca a todos, y un SDK de MCP completo.
    Porque
    Los clientes van desde jobs de CI hasta otros agentes y claude.ai, y cada uno necesita su propio presupuesto y su propio interruptor de apagado.
    Costo
    Un segundo listener para los clientes remotos, y un servidor OAuth y un servidor MCP que mantener, ambos pequeños.
  5. Decisión 05

    Un solo escritor por tipo de estado

    Elegí
    Estado enviado, observado, derivado y humano en tablas separadas, cada una escrita por un solo módulo. Una persona puede marcar un criterio como problema de la prueba; eso exige una nota y se cuenta aparte, sin tocar el estado del harness.
    En vez de
    Dejar que una persona o un modelo sobrescriba un resultado.
    Porque
    Una repetición no puede borrar lo que escribió una persona, y un modelo no puede escribir una observación.
    Costo
    Solo la marca de problema de la prueba cambia los conteos; el aprobado o fallido que da una persona queda junto al resultado del harness en vez de reemplazarlo.

04 Lo interesante

Vale la pena mirarlo de cerca

  • Los ensayos, expresamente, no son evidencia

    Mientras escribe, el modelo puede explorar la interfaz real todo lo que quiera. Nada de eso alimenta un veredicto; el veredicto sale de volver a ejecutar exactamente el mismo script en un proceso nuevo.

  • Una taxonomía de fallas impuesta como arquitectura

    Fallido significa que el mismo script falló dos veces sin ningún modelo de por medio. Bloqueado significa que se rompió la prueba misma. Las reparaciones solo se permiten para bloqueado, así que un agente no puede convertir una falla del producto en un aprobado.

  • Medir el gasto antes de que la sesión termine

    La CLI informa el costo solo cuando una sesión termina, así que las sesiones se transmiten en streaming y el costo de cada mensaje se calcula apenas llega. Contrastada con una sesión real, la estimación quedó a una fracción de centavo del costo informado.

  • Hecho para que lo llamen agentes

    Cualquier sesión de Agents Control Center puede pedir una ejecución. Esa ejecución corre en sandbox, la paga la propia cuenta de la sesión que la pidió, y la nota de una persona sobre una prueba rota vuelve a la sesión que preguntó.

05 Hecho con agentes

Cómo encajan los agentes

Los 24 commits, escritos en tres días, tienen a Claude como coautor. El primer commit ya traía las reglas en su archivo de reglas, cada una tomada de PR Review Console o de Agents Control Center, donde se había aprendido a costa de un incidente. Una regla dice que hay que afirmar lo que se midió y nunca más que eso, y el CHANGELOG la cumple con ids de ejecución y cifras medidas.

El contrato con Agents Control Center lo acordaron dos sesiones de agentes, una trabajando en cada app, y cada lado entregó su mitad. Un agente supervisor vigila la consola, recupera las ejecuciones atascadas solo a través de la CLI y convierte una falla vista dos veces en una prueba y un pull request. Nunca marca un criterio, nunca debilita una verificación y nunca hace push a la rama principal.

Funciona con mis suscripciones de Claude, nunca con una clave de API. Cada ejecución toma la cuenta a la que más le queda de su cupo semanal y se salta cualquier cuenta que haya pasado el 90%.

Contacto

¿Quieres profundizar en QA Console?

Escríbeme por LinkedIn