Propiedad
- OpenClaw (
extensions/qa-lab/src/mantis/*): runtime de escenarios, CLIpnpm openclaw qa mantis <command>, esquema de evidencia. - QA Lab (
extensions/qa-lab/src/live-transports/*): arnés de transporte en vivo, bots de controlador/SUT, escritores de informes/evidencia. - Crabbox (
openclaw/crabbox): máquinas Linux preinicializadas, reservas, VNC,crabbox media preview. - GitHub Actions (
.github/workflows/mantis-*.yml): puntos de entrada remotos, retención de artefactos. - ClawSweeper: analiza comandos de PR de mantenedores, despacha workflows, publica el comentario final en el PR.
Comandos 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
en tiempo de build/ejecución (los workflows empaquetados establecen OPENCLAW_BUILD_PRIVATE_QA=1 y
OPENCLAW_ENABLE_PRIVATE_QA_CLI=1 antes de compilar).
| Comando | Propósito |
|---|---|
discord-smoke | Verificar que el bot de Discord de Mantis pueda ver el servidor/canal, publicar y reaccionar. |
run | Ejecutar un escenario antes/después contra referencias base y candidata (solo Discord). |
desktop-browser-smoke | Reservar/reutilizar un escritorio Crabbox, abrir un navegador visible, capturar captura de pantalla + video. |
slack-desktop-smoke | Reservar/reutilizar un escritorio Crabbox, ejecutar QA de Slack dentro de él, abrir Slack Web, capturar evidencia. |
telegram-desktop-builder | Reservar/reutilizar un escritorio Crabbox, instalar Telegram Desktop, configurar opcionalmente un Gateway de OpenClaw. |
visual-task / visual-driver | Captura genérica de escritorio Crabbox con aserciones opcionales de comprensión de imágenes; visual-driver es la mitad controladora lanzada bajo crabbox record --while. |
--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 CLI local
para proveedor/clase son hetzner/beast, salvo que se indique lo contrario; los workflows de CI
normalmente sobrescriben ambos.
discord-smoke
https://discord.com/api/v10) para obtener el usuario
del bot, el servidor, los canales del servidor y el canal objetivo; afirma que el
canal pertenece al servidor; luego (salvo --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, luego OPENCLAW_QA_DISCORD_MANTIS_BOT_TOKEN
(sobrescribir con --token-env), luego un archivo nombrado por OPENCLAW_QA_DISCORD_MANTIS_BOT_TOKEN_FILE
(sobrescribir con --token-file-env). Los IDs de servidor/canal vienen de
OPENCLAW_QA_DISCORD_GUILD_ID / OPENCLAW_QA_DISCORD_CHANNEL_ID (sobrescribir con
--guild-id / --channel-id) y deben ser snowflakes de Discord de 17-20 dígitos. Establece
OPENCLAW_QA_REDACT_PUBLIC_METADATA=1 para reemplazar IDs y nombres de bot/servidor/canal/mensaje
con <redacted> en el resumen y el informe publicados.
run
--transport actualmente solo acepta discord. --scenario es uno de dos
IDs integrados, cada uno con su propia referencia base predeterminada y etiquetas
antes/después esperadas (extensions/qa-lab/src/mantis/run.runtime.ts):
| Escenario | Base predeterminada | La base espera | La candidata espera |
|---|---|---|---|
discord-status-reactions-tool-only | 0bf06e953fdda290799fc9fb9244a8f67fdae593 | queued-only | queued -> thinking -> done |
discord-thread-reply-filepath-attachment | 81349cdc2a9d5143fd0991ed858b739e7d96e05c | la respuesta del hilo omite el adjunto filePath | la respuesta del hilo lo incluye |
--candidate usa HEAD de forma predeterminada. Otros flags: --credential-source
(predeterminado convex), --credential-role (predeterminado ci), --provider-mode
(predeterminado live-frontier), --fast (activado de forma predeterminada), --skip-install, --skip-build.
El runner crea checkouts separados de git worktree para la base y la
candidata bajo <output-dir>/worktrees/, ejecuta pnpm install/pnpm build en
cada uno (salvo que se omitan), y luego ejecuta
pnpm openclaw qa discord --scenario <id> --model openai/gpt-5.4 --alt-model openai/gpt-5.4 --allow-failures
contra cada worktree. Cada carril escribe discord-qa-reaction-timelines.json
más un par <scenario-id>-timeline.html/.png; el runner copia esta
evidencia de vuelta bajo baseline//candidate/, escribe comparison.json,
mantis-report.md y mantis-evidence.json en el directorio de salida, y
sale con código distinto de cero si la comparación no pasó (base fail y candidata
pass).
El segundo escenario de Discord (discord-thread-reply-filepath-attachment) publica
un mensaje padre con el bot controlador, crea un hilo real, llama a la acción
message.thread-reply del SUT con un filePath local del repo y luego sondea el
hilo en busca de la respuesta y del nombre del archivo adjunto. Espera un adjunto
llamado mantis-thread-report.md.
desktop-browser-smoke
--browser-url (predeterminado https://openclaw.ai) o a un
--html-file renderizado, espera, toma capturas con scrot, opcionalmente graba un MP4 con
ffmpeg, y sincroniza mediante rsync desktop-browser-smoke.png / .mp4 / remote-metadata.json
de vuelta a --output-dir.
Flags:
--lease-id <cbx_...>reutiliza un escritorio preinicializado en lugar de crear uno.--browser-profile-dir <remote-path>reutiliza un Chrome user-data-dir remoto para que un escritorio persistente permanezca conectado entre ejecuciones (usado para un perfil de visor de Discord Web de larga duración).--browser-profile-archive-env <name>restaura un archivo de perfil de Chrome.tgzen base64 desde esa variable de entorno antes del lanzamiento (predeterminadoOPENCLAW_MANTIS_BROWSER_PROFILE_TGZ_B64); se usa para testigos con sesión iniciada como Discord Web.--video-duration <seconds>controla la duración de captura del MP4 (predeterminado 10s).--keep-lease(oOPENCLAW_MANTIS_KEEP_VM=1) mantiene abierta una reserva creada por esta ejecución para inspección VNC; las ejecuciones fallidas que crearon una reserva también la mantienen por defecto.
qa discord) sigue siendo autoritativo; cuando
OPENCLAW_QA_DISCORD_CAPTURE_UI_METADATA=1 está establecido, el escenario también escribe un
artefacto de URL de Discord Web, y OPENCLAW_QA_DISCORD_KEEP_THREADS=1 deja el
hilo abierto el tiempo suficiente para que el navegador lo abra.
El workflow 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/de arranque, en cambio puede restaurar un
.tgz en base64 desde MANTIS_DISCORD_VIEWER_CHROME_PROFILE_TGZ_B64. Sin
ninguna fuente configurada, el workflow aún publica las capturas de pantalla deterministas
de base/candidata y registra que el testigo con sesión iniciada fue
omitido.
slack-desktop-smoke
pnpm openclaw qa slack dentro de ella, abre Slack Web en el navegador VNC,
captura el escritorio y copia tanto los artefactos de QA de Slack (slack-qa/) como
la captura de pantalla/video de VNC de vuelta localmente. Esta es la única forma de Mantis donde el
Gateway SUT y el navegador se ejecutan ambos dentro de la misma VM.
Con --gateway-setup, el comando crea un home persistente y desechable de OpenClaw
en $HOME/.openclaw-mantis/slack-openclaw en la VM, parchea la configuración de Slack
Socket Mode para el canal objetivo, inicia
openclaw gateway run --dev --allow-unconfigured --port 38973 y deja
Chrome ejecutándose en la sesión VNC; omitir --gateway-setup ejecuta en cambio el
carril normal de QA de Slack bot-a-bot.
Entorno requerido para --credential-source env (el valor local predeterminado es env; el rol
predeterminado 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 carril de modelo remoto (si soloOPENAI_API_KEYestá establecido localmente, Mantis lo copia aOPENCLAW_LIVE_OPENAI_KEYantes de invocar Crabbox)
--credential-source convex, Mantis reserva la credencial SUT de Slack desde
el pool compartido antes de crear la VM y reenvía el ID de canal, el token de app y
el token de bot a la VM como variables de entorno OPENCLAW_MANTIS_SLACK_*, por lo que los workflows de GitHub
solo necesitan el secreto del broker de Convex, no tokens sin procesar de Slack.
Otros flags: --slack-url <url> abre una URL específica (si no, Mantis deriva
https://app.slack.com/client/<team>/<channel> desde 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 VM (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 checkpoints pendientes/resueltos en lugar de configurar el Gateway (mutuamente
excluyente con --gateway-setup); --hydrate-mode source|prehydrated,
--provider-mode, --model, --alt-model y --fast se pasan al
carril en vivo de Slack.
Las capturas de checkpoints de aprobación se renderizan desde el mensaje de la API de Slack que
observó el escenario, no desde la UI en vivo de Slack; slack-desktop-smoke.png es solo
prueba de Slack Web en sí cuando el perfil de navegador de la reserva ya tenía una 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 reservado y luego captura una
captura 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 separada de Telegram
restaurada desde --telegram-profile-archive-env <name> o iniciada manualmente
mediante VNC y mantenida activa con --keep-lease.
Indicadores: --lease-id <cbx_...> vuelve a ejecutar contra una VM que ya tiene sesión iniciada en
Telegram Desktop; --telegram-profile-archive-env <name> restaura un archivo de perfil
.tgz en base64 antes del inicio; --telegram-profile-dir <remote-path>
establece el directorio de perfil remoto (predeterminado: $HOME/.local/share/TelegramDesktop);
--no-gateway-setup solo instala y abre Telegram Desktop;
--credential-source/--credential-role usan de forma predeterminada convex/maintainer.
Manifiesto de evidencia
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 entradas con "required": false cuando
falta el archivo.
Tipos de artefacto: timeline (captura de pantalla determinista de antes/después),
desktopScreenshot (captura de pantalla de VNC/navegador), motionPreview (GIF animado
integrado desde la grabación), motionClip (MP4 recortado por movimiento), fullVideo (grabación
completa), metadata (archivo complementario JSON/log), report (informe Markdown).
Diseño de artefactos en disco de una ejecución:
OPENCLAW_QA_REDACT_PUBLIC_METADATA=1 para 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 llaman con el manifiesto, el PR de destino, la raíz de destino de artefactos, el marcador de comentario,
la URL del artefacto, la URL de ejecución y el origen de la solicitud. Carga los artefactos declarados en
el bucket R2 de Mantis, construye un comentario de PR con el resumen primero, con
imágenes/vistas previas integradas y videos enlazados, y luego actualiza el comentario marcador existente o
crea uno nuevo. Entorno requerido:
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 github-actions[bot], usando un comentario marcador
oculto como clave de upsert.
| Flujo de trabajo | Disparador | Qué hace |
|---|---|---|
Mantis Discord Smoke | despacho manual | Ejecuta discord-smoke contra una referencia elegida. |
Mantis Discord Status Reactions | comentario de PR o despacho manual | Construye árboles de trabajo separados de referencia base/candidata, ejecuta discord-status-reactions-tool-only en cada uno, renderiza la cronología de cada carril en un navegador de escritorio de Crabbox, genera vistas previas GIF/MP4 recortadas por movimiento con crabbox media preview, carga artefactos y publica evidencia integrada en el PR. |
Mantis Scenario | despacho manual | Despachador genérico: toma scenario_id (discord-status-reactions-tool-only, discord-thread-reply-filepath-attachment, slack-desktop-smoke, telegram-live, telegram-desktop-proof), baseline_ref, candidate_ref, pr_number, y lo reenvía al flujo de trabajo de escenario correspondiente. |
Mantis Slack Desktop Smoke | despacho manual | Arrienda un escritorio Linux de Crabbox (predeterminado aws, opción de hetzner), ejecuta slack-desktop-smoke --gateway-setup contra la candidata, graba el escritorio, genera una vista previa de movimiento, carga artefactos y publica evidencia en el PR cuando se proporciona un número de PR. |
Mantis Telegram Live | comentario de PR o despacho manual | Ejecuta el carril de QA en vivo de Telegram mediante la API del bot (openclaw qa telegram), escribe mantis-evidence.json desde el resumen de QA, renderiza HTML de evidencia redactada mediante un navegador de escritorio de Crabbox, genera un GIF de movimiento y publica evidencia en el PR. No se requiere inicio de sesión en Telegram Web para este carril. |
Mantis Telegram Desktop Proof | etiqueta de PR de maintainer (mantis: telegram-visible-proof) más comentario de PR, o despacho manual | Prueba agentic nativa de Telegram Desktop de antes/después. Entrega el PR, las referencias base/candidata y las instrucciones del maintainer a Codex, que ejecuta el carril de prueba de Telegram Desktop con usuario real en Crabbox para ambas referencias y publica una tabla de evidencia de PR de 2 columnas. |
Mantis Discord Status Reactions y 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 lanzamiento (v*) o la cabecera de un PR abierto antes de ejecutarse con
credenciales que contienen secretos.
Disparadores por comentario, desde un PR con acceso de escritura/mantenimiento/administración:
telegram-status-command como escenario; aceptan provider=aws|hetzner y
lease=<cbx_...> para apuntar a un proveedor específico de Crabbox o a 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.
ClawSweeper también puede despachar un escenario directamente:
Máquinas y secretos
Los valores predeterminados de Crabbox en la CLI local son--provider hetzner --class beast; sobrescríbelos
con --provider, --class/--machine-class, o
OPENCLAW_MANTIS_CRABBOX_PROVIDER / OPENCLAW_MANTIS_CRABBOX_CLASS. Los flujos de trabajo de GitHub
suelen sobrescribir ambos (por ejemplo --class standard, y la entrada de elección de proveedor
aws/hetzner del flujo de trabajo de Slack). Si un proveedor es demasiado
lento o no está disponible, agrégalo detrás de la misma interfaz de Crabbox en lugar de
codificar una alternativa.
Base de VM: Linux con Chrome/Chromium apto para escritorio, acceso CDP, VNC/
noVNC, Node 22+ y pnpm, un checkout de OpenClaw y acceso saliente al
transporte de destino, GitHub, proveedores de modelos y el intermediario de credenciales.
Nombres de secretos usados en los flujos de trabajo de Mantis:
OPENCLAW_QA_DISCORD_MANTIS_BOT_TOKENOPENCLAW_QA_DISCORD_DRIVER_BOT_TOKENOPENCLAW_QA_DISCORD_SUT_BOT_TOKENOPENCLAW_QA_DISCORD_GUILD_IDOPENCLAW_QA_DISCORD_CHANNEL_IDOPENCLAW_QA_REDACT_PUBLIC_METADATA=1para cargas públicas de artefactosOPENCLAW_QA_CONVEX_SITE_URL,OPENCLAW_QA_CONVEX_SECRET_CICRABBOX_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)MANTIS_GITHUB_APP_ID,MANTIS_GITHUB_APP_PRIVATE_KEY
Resultados de ejecución
Un escenario falla de una de dos maneras distinguibles, y el informe las separa para que un entorno inestable no se lea como una regresión del producto:- Bug reproducido: la referencia base falló de la forma que espera el escenario.
- Fallo del harness: la configuración del entorno, las credenciales, la API del transporte, el navegador o el proveedor fallaron antes de que el oráculo fuera significativo.
Agregar un escenario
Los escenarios se definen en TypeScript por transporte (consultaMANTIS_SCENARIO_CONFIGS en extensions/qa-lab/src/mantis/run.runtime.ts para
la forma de antes/después de Discord), no en un formato de archivo declarativo independiente.
Cada escenario necesita: id y título, transporte, credenciales requeridas, política de referencia
base, política de referencia candidata, parche de configuración de OpenClaw, pasos de configuración/estímulo,
oráculo esperado de referencia base y candidata, destinos de captura visual, presupuesto de tiempo de espera
y pasos de limpieza.
Prefiere oráculos pequeños y tipados sobre comprobaciones de visión: estado de reacciones de Discord o
referencias de mensajes, ts de hilo de Slack/estado de API de reacciones, ids de mensajes de correo
y encabezados. Usa capturas de pantalla del navegador cuando la UI sea el único observable fiable,
y mantén las comprobaciones de visión como aditivas a un oráculo de API de plataforma cuando exista uno.
Después de Discord, Slack y Telegram, la misma forma de ejecutor se extiende a WhatsApp
(inicio de sesión por QR, reidentificación, entrega, medios, reacciones) y Matrix
(salas cifradas, relaciones de hilo/respuesta, reanudación tras reinicio); ninguno está
implementado todavía.
Preguntas abiertas
- ¿Qué bot de Discord debería ser el controlador frente al SUT cuando se reutiliza el bot existente de Mantis?
- ¿Durante cuánto tiempo debería GitHub conservar los artefactos de Mantis para los PR?
- ¿Cuándo debería ClawSweeper recomendar automáticamente un escenario de Mantis en lugar de esperar un comando de maintainer?
- ¿Deben redactarse o recortarse las capturas de pantalla antes de cargarlas para PR públicos?