Responsabilidad
- OpenClaw (
extensions/qa-lab/src/mantis/*): entorno de ejecución de escenarios, CLIpnpm openclaw qa mantis <command>, esquema de evidencias. - Laboratorio de QA (
extensions/qa-lab/src/live-transports/*): entorno de pruebas de transporte en vivo, bots controlador/SUT, generadores de informes/evidencias. - Crabbox (
openclaw/crabbox): máquinas Linux preparadas, concesiones, VNC,crabbox media preview. - GitHub Actions (
.github/workflows/mantis-*.yml): puntos de entrada remotos, conservación de artefactos. - ClawSweeper: analiza comandos de mantenedores en PR, ejecuta flujos de trabajo y publica el comentario final en el PR.
Comandos de la CLI
Todos los comandos sonpnpm openclaw qa mantis <command>, definidos en
extensions/qa-lab/src/mantis/cli.ts. Requiere OPENCLAW_ENABLE_PRIVATE_QA_CLI=1
durante la compilación/ejecución (los flujos de trabajo incluidos establecen OPENCLAW_BUILD_PRIVATE_QA=1 y
OPENCLAW_ENABLE_PRIVATE_QA_CLI=1 antes de compilar).
Todos los comandos aceptan
--repo-root <path> y --output-dir <path>; los comandos de Crabbox
también aceptan --crabbox-bin, --provider, --machine-class/--class,
--lease-id, --idle-timeout, --ttl y --keep-lease. Los valores predeterminados de la CLI local
para proveedor/clase son hetzner/beast, salvo que se indique lo contrario; los flujos de trabajo de CI
suelen sustituir ambos.
discord-smoke
https://discord.com/api/v10) para obtener el usuario
del bot, el servidor, los canales del servidor y el canal de destino; comprueba que el
canal pertenezca al servidor y, salvo que se use --skip-post, publica un mensaje y
añade una reacción 👀. Escribe mantis-discord-smoke-summary.json y
mantis-discord-smoke-report.md.
Orden de resolución del token: valor de --token-file, después OPENCLAW_QA_DISCORD_MANTIS_BOT_TOKEN
(sustituible con --token-env) y, por último, un archivo indicado por OPENCLAW_QA_DISCORD_MANTIS_BOT_TOKEN_FILE
(sustituible con --token-file-env). Los identificadores de servidor/canal proceden de
OPENCLAW_QA_DISCORD_GUILD_ID / OPENCLAW_QA_DISCORD_CHANNEL_ID (sustituibles con
--guild-id / --channel-id) y deben ser snowflakes de Discord de 17-20 dígitos. Establezca
OPENCLAW_QA_REDACT_PUBLIC_METADATA=1 para sustituir los identificadores
y nombres del bot/servidor/canal/mensaje por <redacted> en el resumen y el informe publicados.
run
--transport solo acepta discord. --scenario es uno de dos
identificadores integrados, cada uno con su propia referencia base predeterminada y las etiquetas esperadas de antes/después
(extensions/qa-lab/src/mantis/run.runtime.ts):
El valor predeterminado de
--candidate es HEAD. Otras opciones: --credential-source
(valor predeterminado convex), --credential-role (valor predeterminado ci), --provider-mode
(valor predeterminado live-frontier), --fast (activado de forma predeterminada), --skip-install, --skip-build.
El ejecutor crea copias de trabajo git worktree desacopladas para la referencia base y
la candidata en <output-dir>/worktrees/, ejecuta pnpm install/pnpm build en
cada una (salvo que se omita) y después ejecuta
pnpm openclaw qa discord --scenario <id> --model openai/gpt-5.4 --alt-model openai/gpt-5.4 --allow-failures
en cada copia de trabajo. Cada flujo escribe discord-qa-reaction-timelines.json
junto con un par <scenario-id>-timeline.html/.png; el ejecutor vuelve a copiar esta
evidencia en baseline//candidate/, escribe comparison.json,
mantis-report.md y mantis-evidence.json en el directorio de salida, y
finaliza con un código distinto de cero si la comparación no se supera (referencia base fail y candidata
pass).
El segundo escenario de Discord (discord-thread-reply-filepath-attachment) publica
un mensaje principal con el bot controlador, crea un hilo real, llama a la acción
message.thread-reply del SUT con un filePath local del repositorio y, a continuación, consulta
periódicamente el hilo para obtener la respuesta y el nombre de archivo del adjunto. Espera un adjunto
denominado mantis-thread-report.md.
desktop-browser-smoke
--browser-url (valor predeterminado https://openclaw.ai) o a un
--html-file renderizado, espera, toma una captura de pantalla con scrot, graba opcionalmente un MP4 con
ffmpeg y sincroniza mediante rsync desktop-browser-smoke.png / .mp4 / remote-metadata.json
de vuelta a --output-dir.
Opciones:
--lease-id <cbx_...>reutiliza un escritorio preparado en lugar de crear uno.--browser-profile-dir <remote-path>reutiliza un directorio remoto de datos de usuario de Chrome para que un escritorio persistente mantenga la sesión iniciada entre ejecuciones (se utiliza para un perfil de visor de Discord Web de larga duración).--browser-profile-archive-env <name>restaura antes del inicio un archivo de perfil de Chrome.tgzen base64 desde esa variable de entorno (valor predeterminadoOPENCLAW_MANTIS_BROWSER_PROFILE_TGZ_B64); se utiliza para testigos con sesión iniciada como Discord Web.--video-duration <seconds>controla la duración de la captura MP4 (valor predeterminado 10s).--keep-lease(oOPENCLAW_MANTIS_KEEP_VM=1) mantiene abierta para inspección mediante VNC una concesión creada durante esta ejecución; las ejecuciones fallidas que hayan creado una concesión también la mantienen de forma predeterminada.
qa discord) sigue siendo la fuente autoritativa; cuando
se establece OPENCLAW_QA_DISCORD_CAPTURE_UI_METADATA=1, el escenario también escribe un
artefacto con una URL de Discord Web y OPENCLAW_QA_DISCORD_KEEP_THREADS=1 mantiene el
hilo abierto el tiempo suficiente para que el navegador lo abra.
El flujo de trabajo de GitHub prefiere un perfil de visor persistente mediante
MANTIS_DISCORD_VIEWER_CHROME_PROFILE_DIR (los archivos de perfil completos pueden superar
el límite de tamaño de secretos de GitHub); para perfiles pequeños/iniciales, puede restaurar en su lugar un
.tgz en base64 desde MANTIS_DISCORD_VIEWER_CHROME_PROFILE_TGZ_B64. Si no se configura
ninguna de las dos fuentes, el flujo de trabajo sigue publicando las capturas de pantalla deterministas
de la referencia base y la candidata, y registra que se omitió el testigo con sesión iniciada.
slack-desktop-smoke
pnpm openclaw qa slack en ella, abre Slack Web en el navegador VNC,
captura el escritorio y copia localmente tanto los artefactos de QA de Slack (slack-qa/) como
la captura de pantalla/vídeo de VNC. Esta es la única configuración de Mantis en la que el
Gateway del SUT y el navegador se ejecutan en la misma máquina virtual.
Con --gateway-setup, el comando crea un directorio de inicio persistente y desechable de OpenClaw
en $HOME/.openclaw-mantis/slack-openclaw dentro de la máquina virtual, modifica la configuración de
Socket Mode de Slack para el canal de destino, inicia
openclaw gateway run --dev --allow-unconfigured --port 38973 y deja
Chrome ejecutándose en la sesión VNC; si se omite --gateway-setup, se ejecuta en su lugar el flujo normal
de QA de Slack de bot a bot.
Variables de entorno obligatorias para --credential-source env (el valor predeterminado local es env; el valor
predeterminado del rol es maintainer):
OPENCLAW_QA_SLACK_CHANNEL_IDOPENCLAW_QA_SLACK_DRIVER_BOT_TOKENOPENCLAW_QA_SLACK_SUT_BOT_TOKENOPENCLAW_QA_SLACK_SUT_APP_TOKENOPENCLAW_LIVE_OPENAI_KEYpara el flujo de modelo remoto (si solo se estableceOPENAI_API_KEYlocalmente, Mantis lo copia enOPENCLAW_LIVE_OPENAI_KEYantes de invocar Crabbox)
--credential-source convex, Mantis obtiene una concesión de la credencial del SUT de Slack desde
el grupo compartido antes de crear la máquina virtual y reenvía el identificador del canal, el token de la aplicación y
el token del bot a la máquina virtual como variables de entorno OPENCLAW_MANTIS_SLACK_*, de modo que los flujos de trabajo de GitHub
solo necesitan el secreto del intermediario Convex, no los tokens de Slack sin procesar.
Otras opciones: --slack-url <url> abre una URL específica (de lo contrario, Mantis obtiene
https://app.slack.com/client/<team>/<channel> a partir de auth.test);
--slack-channel-id <id> establece el canal de la lista de permitidos del Gateway;
OPENCLAW_MANTIS_SLACK_BROWSER_PROFILE_DIR controla el perfil persistente de Chrome
dentro de la máquina virtual (valor predeterminado $HOME/.config/openclaw-mantis/slack-chrome-profile);
--approval-checkpoints ejecuta los escenarios nativos de aprobación de Slack
(slack-approval-exec-native, slack-approval-plugin-native) y renderiza
capturas de pantalla de puntos de control pendientes/resueltos en lugar de configurar el Gateway (es
mutuamente excluyente con --gateway-setup); --hydrate-mode source|prehydrated,
--provider-mode, --model, --alt-model y --fast se transfieren al
flujo en vivo de Slack.
Las capturas de pantalla de los puntos de control de aprobación se renderizan a partir del mensaje de la API de Slack que
observó el escenario, no de la UI de Slack en vivo; slack-desktop-smoke.png solo es
una prueba de Slack Web cuando el perfil del navegador de la concesión ya tenía la sesión
iniciada.
telegram-desktop-builder
openclaw gateway run --dev --allow-unconfigured --port 38974, publica un
mensaje de disponibilidad del bot controlador en el grupo privado concedido y, a continuación, captura una
imagen de pantalla y un MP4. Un token de bot solo configura OpenClaw; nunca inicia
sesión en Telegram Desktop. El visor de escritorio es una sesión de usuario de Telegram independiente,
restaurada desde --telegram-profile-archive-env <name> o iniciada manualmente
mediante VNC y mantenida activa con --keep-lease.
Opciones: --lease-id <cbx_...> vuelve a ejecutar el proceso en una máquina virtual que ya tiene una sesión iniciada en
Telegram Desktop; --telegram-profile-archive-env <name> restaura antes del inicio un archivo de perfil
.tgz en base64; --telegram-profile-dir <remote-path>
establece el directorio remoto del perfil (valor predeterminado $HOME/.local/share/TelegramDesktop);
--no-gateway-setup únicamente instala y abre Telegram Desktop;
los valores predeterminados de --credential-source/--credential-role son convex/maintainer.
Manifiesto de evidencias
Cada escenario que publica en un PR escribemantis-evidence.json junto a
su informe:
path del artefacto es relativo al directorio del manifiesto; targetPath es
relativo al prefijo de artefactos R2/S3 configurado. scripts/mantis/publish-pr-evidence.mjs
rechaza el recorrido de rutas y omite las entradas con "required": false cuando
falta el archivo.
Tipos de artefactos: timeline (captura de pantalla determinista del antes/después),
desktopScreenshot (captura de pantalla de VNC/navegador), motionPreview (GIF animado
en línea de la grabación), motionClip (MP4 recortado según el movimiento), fullVideo (grabación
completa), metadata (archivo complementario JSON/registro), report (informe Markdown).
Disposición de artefactos de una ejecución en disco:
OPENCLAW_QA_REDACT_PUBLIC_METADATA=1 para las cargas públicas de artefactos; está
habilitado de forma predeterminada en los flujos de trabajo de GitHub de Discord/Slack/Telegram.
Automatización de GitHub
scripts/mantis/publish-pr-evidence.mjs es el publicador reutilizable. Los flujos de trabajo
lo invocan con el manifiesto, el PR de destino, la raíz de destino de los artefactos, el marcador del comentario,
la URL de los artefactos, la URL de la ejecución y el origen de la solicitud. Carga los artefactos declarados en
el bucket R2 de Mantis, crea un comentario de PR que prioriza el resumen con
imágenes/vistas previas en línea y vídeos enlazados y, a continuación, actualiza el comentario con el marcador existente o
crea uno nuevo. Variables de entorno requeridas:
MANTIS_ARTIFACT_R2_ACCESS_KEY_IDMANTIS_ARTIFACT_R2_SECRET_ACCESS_KEYMANTIS_ARTIFACT_R2_BUCKET(los flujos de trabajo establecenopenclaw-crabbox-artifacts)MANTIS_ARTIFACT_R2_ENDPOINTMANTIS_ARTIFACT_R2_REGION(los flujos de trabajo establecenauto)MANTIS_ARTIFACT_R2_PUBLIC_BASE_URL(los flujos de trabajo establecenhttps://artifacts.openclaw.ai)
MANTIS_GITHUB_APP_ID /
MANTIS_GITHUB_APP_PRIVATE_KEY), no mediante github-actions[bot], y utilizan un comentario
marcador oculto como clave de inserción o actualización.
Tanto
Mantis Discord Status Reactions como Mantis Telegram Live aceptan
baseline_ref/candidate_ref (o baseline=/candidate= en un comentario de PR)
y validan que el SHA resuelto sea un ancestro de origin/main, una
etiqueta de versión (v*) o la cabecera de un PR abierto antes de ejecutarse con
credenciales que contienen secretos.
Desencadenadores mediante comentarios desde un PR con acceso de escritura/mantenimiento/administración:
telegram-status-command como escenario; aceptan provider=aws|hetzner y
lease=<cbx_...> para seleccionar un proveedor específico de Crabbox o un
escritorio precalentado. Mantis Telegram Desktop Proof solo responde a un comentario de PR cuando
el PR ya tiene la etiqueta mantis: telegram-visible-proof.
Los desencadenadores mediante comentarios del chat de la interfaz web utilizan de forma predeterminada el SHA de la cabecera del PR como candidato. Ejecutan
la prueba de chat de la interfaz de control con un Gateway simulado y publican artefactos del navegador; para
otras páginas web y superficies de aplicaciones nativas, utilice pruebas normales con Playwright/navegador,
capturas de pantalla del mantenedor, Crabbox o artefactos locales.
ClawSweeper también puede ejecutar un escenario directamente:
Máquinas y secretos
Los valores predeterminados de Crabbox en la CLI local son--provider hetzner --class beast; sustitúyalos
con --provider, --class/--machine-class o
OPENCLAW_MANTIS_CRABBOX_PROVIDER / OPENCLAW_MANTIS_CRABBOX_CLASS. Los flujos de trabajo de
GitHub suelen sustituir ambos (por ejemplo, --class standard y la entrada de elección del proveedor
aws/hetzner del flujo de trabajo de Slack). Si un proveedor es demasiado
lento o no está disponible, añádalo detrás de la misma interfaz de Crabbox en lugar de
codificar una alternativa.
Configuración básica de la máquina virtual: Linux con Chrome/Chromium compatible con escritorio, acceso CDP, VNC/
noVNC, Node 22.22.3+, 24.15+ o 25.9+ y pnpm, un checkout de OpenClaw y
acceso saliente al transporte de destino, GitHub, proveedores de modelos y el
intermediario de credenciales.
Nombres de credenciales y variables de entorno utilizados en los comandos y flujos de trabajo de Mantis:
OPENCLAW_QA_DISCORD_MANTIS_BOT_TOKENOPENCLAW_QA_DISCORD_GUILD_IDOPENCLAW_QA_DISCORD_CHANNEL_ID- El
qa mantis run --credential-source envlocal también requiereOPENCLAW_QA_DISCORD_DRIVER_BOT_TOKEN,OPENCLAW_QA_DISCORD_SUT_BOT_TOKENyOPENCLAW_QA_DISCORD_SUT_APPLICATION_ID. Los flujos de trabajo de GitHub normalmente utilizan--credential-source convexy las credenciales del intermediario indicadas a continuación, en lugar de tokens sin procesar del bot de Discord. OPENCLAW_QA_REDACT_PUBLIC_METADATA=1para cargas públicas de artefactosOPENCLAW_QA_CONVEX_SITE_URL,OPENCLAW_QA_CONVEX_SECRET_CIOPENAI_API_KEY(o el valor específico de las pruebas de Telegram DesktopOPENCLAW_MANTIS_AGENT_OPENAI_API_KEY)CRABBOX_COORDINATOR/CRABBOX_COORDINATOR_TOKEN(los flujos de trabajo también aceptanOPENCLAW_QA_MANTIS_CRABBOX_COORDINATOR/_TOKENcomo alternativa y los asignan a los nombres simples antes de invocar Crabbox)CRABBOX_ACCESS_CLIENT_ID,CRABBOX_ACCESS_CLIENT_SECRETMANTIS_GITHUB_APP_ID,MANTIS_GITHUB_APP_PRIVATE_KEY
Resultados de la ejecución
Los escenarios de transporte del antes/después distinguen estos resultados para que un entorno inestable no se interprete como una regresión del producto:- Error reproducido: la referencia falló de la forma que esperaba el escenario.
- Fallo del entorno de pruebas: la configuración del entorno, las credenciales, la API de transporte, el navegador o el proveedor fallaron antes de que el oráculo fuera significativo.
Adición de un escenario
Los escenarios de transporte en vivo se definen en TypeScript para cada transporte (consulteMANTIS_SCENARIO_CONFIGS en extensions/qa-lab/src/mantis/run.runtime.ts para
la forma del antes/después de Discord), no mediante un formato de archivo declarativo independiente.
Cada escenario necesita: id y título, transporte, credenciales requeridas, política de referencia
de referencia, política de referencia del candidato, parche de configuración de OpenClaw, pasos de configuración/estímulo,
oráculo esperado para la referencia y el candidato, destinos de captura visual, presupuesto de
tiempo de espera y pasos de limpieza.
Las pruebas específicas del navegador solo para el candidato pueden utilizar una prueba E2E determinista dedicada
y un flujo de trabajo. Mantenga explícito su alcance, valide la referencia del candidato antes de
la ejecución, aísle la publicación respaldada por secretos y emita el mismo contrato de
manifiesto de pruebas.
Prefiera oráculos pequeños y tipados en lugar de comprobaciones visuales: estado de reacciones de Discord o
referencias de mensajes, estado de la API de ts/reacciones de hilos de Slack, identificadores
y cabeceras de mensajes de correo electrónico. Utilice capturas de pantalla del navegador cuando la interfaz de usuario sea el único elemento observable fiable
y mantenga las comprobaciones visuales como complemento de un oráculo de la API de la plataforma cuando exista.
Después de Discord, Slack y Telegram, la misma forma de ejecutor se extiende a WhatsApp
(inicio de sesión mediante QR, reidentificación, entrega, contenido multimedia y reacciones) y Matrix
(salas cifradas, relaciones de hilos/respuestas y reanudación tras reinicio); ninguno está
implementado todavía.
Preguntas abiertas
- ¿Qué bot de Discord debe actuar como controlador y cuál como SUT cuando se reutiliza el bot Mantis existente?
- ¿Durante cuánto tiempo debe conservar GitHub los artefactos de Mantis para los PR?
- ¿Cuándo debe ClawSweeper recomendar automáticamente un escenario de Mantis en lugar de esperar una orden de un responsable de mantenimiento?
- ¿Deben ocultarse los datos sensibles de las capturas de pantalla o recortarse antes de subirlas a PR públicos?