Pular para o conteúdo principal
A pilha privada de QA foi criada para exercitar o OpenClaw de uma forma mais realista, moldada por canais, do que um único teste unitário consegue. Peças atuais:
  • extensions/qa-channel: canal de mensagens sintético com superfícies de DM, canal, thread, reação, edição e exclusão.
  • extensions/qa-lab: UI de depuração e barramento de QA para observar a transcrição, injetar mensagens de entrada e exportar um relatório em Markdown.
  • extensions/qa-matrix, futuros plugins de execução: adaptadores de transporte ao vivo que conduzem um canal real dentro de um Gateway de QA filho.
  • qa/: ativos seed mantidos no repo para a tarefa inicial e cenários de QA de linha de base.
  • Mantis: verificação ao vivo antes e depois para bugs que precisam de transportes reais, capturas de tela do navegador, estado de VM e evidência de PR.

Superfície de comandos

Todo fluxo de QA é executado sob pnpm openclaw qa <subcommand>. Muitos têm aliases de script pnpm qa:*; ambas as formas são compatíveis.
ComandoFinalidade
qa runAutoverificação de QA empacotada sem --qa-profile; executor de perfil de maturidade baseado em taxonomia com --qa-profile smoke-ci, --qa-profile release ou --qa-profile all.
qa suiteExecutar cenários mantidos no repo contra a via do Gateway de QA. Aliases: pnpm openclaw qa suite --runner multipass para uma VM Linux descartável.
qa coverageImprimir o inventário YAML de cobertura de cenários (--json para saída de máquina).
qa parity-reportComparar dois arquivos qa-suite-summary.json e gravar o relatório de paridade agêntica, ou usar --runtime-axis --token-efficiency para gravar relatórios de paridade de runtime Codex-vs-OpenClaw e eficiência de tokens a partir de um resumo de par de runtimes.
qa character-evalExecutar o cenário de QA de personagem em vários modelos ao vivo com um relatório julgado. Consulte Relatórios.
qa manualExecutar um prompt avulso contra a via de provedor/modelo selecionada.
qa uiIniciar a UI de depuração de QA e o barramento de QA local (alias: pnpm qa:lab:ui).
qa docker-build-imageCriar a imagem Docker de QA pré-preparada.
qa docker-scaffoldGravar um scaffold docker-compose para o painel de QA + via do Gateway.
qa upCriar o site de QA, iniciar a pilha baseada em Docker, imprimir a URL (alias: pnpm qa:lab:up; a variante :fast adiciona --use-prebuilt-image --bind-ui-dist --skip-ui-build).
qa aimockIniciar apenas o servidor provedor AIMock.
qa mock-openaiIniciar apenas o servidor provedor mock-openai ciente de cenários.
qa credentials doctor / add / list / removeGerenciar o pool compartilhado de credenciais Convex.
qa matrixVia de transporte ao vivo contra um homeserver Tuwunel descartável. Consulte QA Matrix.
qa telegramVia de transporte ao vivo contra um grupo privado real do Telegram.
qa discordVia de transporte ao vivo contra um canal real de guilda privada do Discord.
qa slackVia de transporte ao vivo contra um canal privado real do Slack.
qa whatsappVia de transporte ao vivo contra contas reais do WhatsApp Web.
qa mantisExecutor de verificação antes e depois para bugs de transporte ao vivo, com evidência de reações de status do Discord, teste de fumaça de desktop/navegador do Crabbox e teste de fumaça do Slack em VNC. Consulte Mantis e Runbook do Mantis Slack Desktop.
qa run baseado em perfil lê a associação de taxonomy.yaml e então despacha os cenários resolvidos por meio de qa suite. --surface e --category filtram o perfil selecionado em vez de definir vias separadas. O qa-evidence.json resultante inclui um resumo de scorecard do perfil com contagens por categoria selecionada e IDs de cobertura ausentes; as entradas individuais de evidência continuam sendo a fonte da verdade para os testes, funções de cobertura e resultados. IDs de cobertura de recursos da taxonomia são alvos exatos de prova, não aliases. A cobertura primária de cenário satisfaz IDs correspondentes; a cobertura secundária permanece consultiva. IDs de cobertura usam a forma pontuada namespace.behavior com segmentos alfanuméricos/de hífen em minúsculas; IDs de perfil, superfície e categoria ainda podem usar os IDs de taxonomia existentes com hífen ou pontuação. Evidência enxuta omite execution por entrada e define evidenceMode: "slim"; smoke-ci usa enxuta por padrão, e --evidence-mode full restaura entradas completas:
pnpm openclaw qa run \
  --qa-profile smoke-ci \
  --category channel-framework.conversation-routing-and-delivery \
  --provider-mode mock-openai \
  --output-dir .artifacts/qa-e2e/smoke-ci-profile-dispatch
Use smoke-ci para prova determinística de perfil com provedores de modelo mock e servidores provedores locais Crabline. Use release para prova Stable/LTS contra canais ao vivo. Use all apenas para execuções explícitas de evidência de taxonomia completa; ele seleciona todas as categorias de maturidade ativas e pode ser despachado pelo workflow QA Profile Evidence com qa_profile=all. Quando um comando também precisa de um perfil raiz do OpenClaw, coloque o perfil raiz antes do comando de QA:
pnpm openclaw --profile work qa run --qa-profile smoke-ci

Fluxo do operador

O fluxo atual de operador de QA é um site de QA com dois painéis:
  • Esquerda: painel do Gateway (Control UI) com o agente.
  • Direita: QA Lab, mostrando a transcrição em estilo Slack e o plano de cenário.
Execute com:
pnpm qa:lab:up
Isso cria o site de QA, inicia a via de Gateway baseada em Docker e expõe a página do QA Lab onde um operador ou loop de automação pode dar ao agente uma missão de QA, observar o comportamento real do canal e registrar o que funcionou, falhou ou permaneceu bloqueado. Para iteração mais rápida da UI do QA Lab sem reconstruir a imagem Docker a cada vez, inicie a pilha com um bundle do QA Lab montado por bind:
pnpm openclaw qa docker-build-image
pnpm qa:lab:build
pnpm qa:lab:up:fast
pnpm qa:lab:watch
qa:lab:up:fast mantém os serviços Docker em uma imagem pré-criada e monta por bind extensions/qa-lab/web/dist no contêiner qa-lab. qa:lab:watch recria esse bundle quando há mudanças, e o navegador recarrega automaticamente quando o hash de ativos do QA Lab muda. Para um teste de fumaça de sinal local do OpenTelemetry, execute:
pnpm qa:otel:smoke
Esse script inicia um receptor OTLP/HTTP local, executa o cenário de QA otel-trace-smoke com o plugin diagnostics-otel habilitado e então verifica se traces, métricas e logs são exportados. Ele decodifica os spans de trace protobuf exportados e verifica a forma crítica para o lançamento: openclaw.run, openclaw.harness.run, um span de chamada de modelo da convenção semântica GenAI mais recente, openclaw.context.assembled e openclaw.message.delivery devem estar presentes. O teste de fumaça força OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental, então o span de chamada de modelo deve usar o nome {gen_ai.operation.name} {gen_ai.request.model}; chamadas de modelo não devem exportar StreamAbandoned em turnos bem-sucedidos; IDs diagnósticos brutos e atributos openclaw.content.* devem ficar fora do trace. Os payloads OTLP brutos não devem conter o sentinela de prompt, sentinela de resposta ou chave de sessão de QA. Ele grava otel-smoke-summary.json ao lado dos artefatos da suíte de QA. Para um teste de fumaça do OpenTelemetry com collector, execute:
pnpm qa:otel:collector-smoke
Essa via coloca um contêiner Docker real do OpenTelemetry Collector na frente do mesmo receptor local. Use-a ao alterar a fiação de endpoints, compatibilidade com collector ou comportamento de exportação OTLP que o receptor em processo poderia mascarar. Para o teste de fumaça protegido de scrape do Prometheus, execute:
pnpm qa:prometheus:smoke
Esse alias executa o cenário de QA docker-prometheus-smoke com diagnostics-prometheus habilitado, verifica que scrapes não autenticados são rejeitados e então confere se o scrape autenticado inclui famílias de métricas críticas para a versão sem conteúdo de prompt, conteúdo de resposta, identificadores brutos de diagnóstico, tokens de autenticação ou caminhos locais. Para executar ambos os smoke tests de observabilidade em sequência, use:
pnpm qa:observability:smoke
Para a faixa OpenTelemetry com coletor mais o smoke test de scrape Prometheus protegido, use:
pnpm qa:observability:collector-smoke
O QA de observabilidade permanece apenas para checkout de origem. O tarball npm omite intencionalmente o QA Lab, portanto as faixas de lançamento Docker de pacote não executam comandos qa. Use pnpm qa:otel:smoke, pnpm qa:prometheus:smoke ou pnpm qa:observability:smoke a partir de um checkout de origem compilado ao alterar a instrumentação de diagnósticos. Para uma faixa de smoke Matrix com transporte real que não exige credenciais de provedor de modelo, execute o perfil rápido com o provedor mock OpenAI determinístico:
OPENCLAW_QA_MATRIX_NO_REPLY_WINDOW_MS=3000 \
  pnpm openclaw qa matrix --provider-mode mock-openai --profile fast --fail-fast
Para a faixa de provedor live-frontier, forneça credenciais compatíveis com OpenAI explicitamente:
OPENCLAW_LIVE_OPENAI_KEY="${OPENAI_API_KEY}" \
OPENCLAW_QA_MATRIX_NO_REPLY_WINDOW_MS=3000 \
  pnpm openclaw qa matrix --provider-mode live-frontier --profile fast --fail-fast
A referência completa da CLI, o catálogo de perfis/cenários, as variáveis de ambiente e o layout de artefatos dessa faixa ficam em QA do Matrix. Em resumo: ela provisiona um homeserver Tuwunel descartável no Docker, registra usuários temporários de driver/SUT/observador, executa o Plugin Matrix real dentro de um Gateway QA filho limitado a esse transporte (sem qa-channel) e então grava um relatório Markdown, um resumo JSON, um artefato de eventos observados e um log de saída combinado em .artifacts/qa-e2e/matrix-<timestamp>/. Os cenários cobrem comportamento de transporte que testes unitários não conseguem provar de ponta a ponta: bloqueio por menção, políticas allow-bot, listas de permissões, respostas de nível superior e em threads, roteamento de DM, tratamento de reações, supressão de edições de entrada, desduplicação de replay após reinicialização, recuperação de interrupção do homeserver, entrega de metadados de aprovação, tratamento de mídia e fluxos de bootstrap/recuperação/verificação de E2EE do Matrix. O perfil CLI de E2EE também conduz openclaw matrix encryption setup e comandos de verificação pelo mesmo homeserver descartável antes de verificar as respostas do Gateway. Discord também tem cenários opcionais somente para Mantis para reprodução de bugs. Use --scenario discord-status-reactions-tool-only para a linha do tempo explícita de reações de status, ou --scenario discord-thread-reply-filepath-attachment para criar uma thread real do Discord e verificar que message.thread-reply preserva um anexo filePath. Esses cenários ficam fora da faixa Discord live padrão porque são sondas de reprodução antes/depois, e não cobertura ampla de smoke. O fluxo de trabalho Mantis de anexo em thread também pode adicionar um vídeo testemunha do Discord Web com login quando MANTIS_DISCORD_VIEWER_CHROME_PROFILE_DIR ou MANTIS_DISCORD_VIEWER_CHROME_PROFILE_TGZ_B64 estiver configurado no ambiente de QA. Esse perfil de visualizador serve apenas para captura visual; a decisão de aprovado/reprovado ainda vem do oráculo REST do Discord. A CI usa a mesma superfície de comando em .github/workflows/qa-live-transports-convex.yml. Execuções agendadas e manuais padrão executam o perfil rápido do Matrix com credenciais live-frontier fornecidas pelo QA, --fast e OPENCLAW_QA_MATRIX_NO_REPLY_WINDOW_MS=3000. O matrix_profile=all manual distribui a execução nos cinco shards de perfil. Para faixas de smoke com transporte real de Telegram, Discord, Slack e WhatsApp:
pnpm openclaw qa telegram
pnpm openclaw qa discord
pnpm openclaw qa slack
pnpm openclaw qa whatsapp
Elas miram um canal real preexistente com dois bots ou contas (driver + SUT). Variáveis de ambiente obrigatórias, listas de cenários, artefatos de saída e o pool de credenciais Convex estão documentados na referência de QA para Telegram, Discord, Slack e WhatsApp abaixo. Para uma execução completa em VM desktop do Slack com resgate por VNC, execute:
pnpm openclaw qa mantis slack-desktop-smoke \
  --gateway-setup \
  --scenario slack-canary \
  --keep-lease
Esse comando aluga uma máquina Crabbox desktop/navegador, executa a faixa live do Slack dentro da VM, abre o Slack Web no navegador VNC, captura o desktop e copia slack-qa/, slack-desktop-smoke.png e slack-desktop-smoke.mp4 quando a captura de vídeo estiver disponível de volta para o diretório de artefatos do Mantis. Aluguéis desktop/navegador do Crabbox fornecem de antemão as ferramentas de captura e pacotes auxiliares de navegador/compilação nativa, portanto o cenário só deve instalar fallbacks em aluguéis mais antigos. O Mantis relata tempos totais e por fase em mantis-slack-desktop-smoke-report.md para que execuções lentas mostrem se o tempo foi para aquecimento do aluguel, aquisição de credenciais, configuração remota ou cópia de artefatos. Reutilize --lease-id <cbx_...> depois de fazer login no Slack Web manualmente pelo VNC; aluguéis reutilizados também mantêm aquecido o cache da store pnpm do Crabbox. O padrão --hydrate-mode source verifica a partir de um checkout de origem e executa instalação/compilação dentro da VM. Use --hydrate-mode prehydrated somente quando o workspace remoto reutilizado já tiver node_modules e um dist/ compilado; esse modo pula a etapa cara de instalação/compilação e falha fechado quando o workspace não está pronto. Com --gateway-setup, o Mantis deixa um Gateway Slack persistente do OpenClaw em execução dentro da VM na porta 38973; sem isso, o comando executa a faixa normal de QA Slack bot-para-bot e sai após a captura de artefatos. Para provar a UI nativa de aprovação do Slack com evidência de desktop, execute o modo de checkpoint de aprovação do Mantis:
pnpm openclaw qa mantis slack-desktop-smoke \
  --approval-checkpoints \
  --credential-source convex \
  --credential-role maintainer
Esse modo é mutuamente exclusivo com --gateway-setup. Ele executa os cenários de aprovação do Slack, rejeita ids de cenário que não sejam de aprovação, aguarda em cada estado de aprovação pendente e resolvida, renderiza a mensagem observada da API do Slack em approval-checkpoints/<scenario>-pending.png e approval-checkpoints/<scenario>-resolved.png e então falha se qualquer checkpoint, evidência de mensagem, confirmação ou screenshot renderizado estiver ausente ou vazio. Aluguéis frios de CI ainda podem mostrar o login do Slack em slack-desktop-smoke.png; as imagens de checkpoint de aprovação são a prova visual desta faixa. A checklist do operador, o comando de dispatch do fluxo de trabalho do GitHub, o contrato de comentário de evidência, a tabela de decisão de modo de hidratação, a interpretação de tempos e as etapas de tratamento de falhas ficam no Runbook de Desktop Slack do Mantis. Para uma tarefa desktop em estilo agente/CV, execute:
pnpm openclaw qa mantis visual-task \
  --browser-url https://example.net \
  --expect-text "Example Domain" \
  --vision-model openai/gpt-5.5
visual-task aluga ou reutiliza uma máquina Crabbox desktop/navegador, inicia crabbox record --while, conduz o navegador visível por meio de um visual-driver aninhado, captura visual-task.png, executa openclaw infer image describe contra o screenshot quando --vision-mode image-describe está selecionado e grava visual-task.mp4, mantis-visual-task-summary.json, mantis-visual-task-driver-result.json e mantis-visual-task-report.md. Quando --expect-text está definido, o prompt de visão pede um veredito JSON estruturado e só aprova quando o modelo relata evidência visível positiva; uma resposta negativa que apenas cita o texto-alvo falha a asserção. Use --vision-mode metadata para um smoke sem modelo que prova o encanamento de desktop, navegador, screenshot e vídeo sem chamar um provedor de compreensão de imagem. A gravação é um artefato obrigatório para visual-task; se o Crabbox não gravar um visual-task.mp4 não vazio, a tarefa falha mesmo quando o driver visual aprovou. Em caso de falha, o Mantis mantém o aluguel para VNC, a menos que a tarefa já tenha sido aprovada e --keep-lease não tenha sido definido. Antes de usar credenciais live em pool, execute:
pnpm openclaw qa credentials doctor
O doctor verifica o ambiente do broker Convex, valida configurações de endpoint e verifica a acessibilidade de admin/list quando o segredo de maintainer está presente. Ele relata apenas o status definido/ausente para segredos.

Cobertura de transporte live

Faixas de transporte live compartilham um contrato em vez de cada uma inventar seu próprio formato de lista de cenários. qa-channel é a suíte ampla de comportamento sintético do produto e não faz parte da matriz de cobertura de transporte live. Runners de transporte live devem importar os ids de cenário compartilhados, os auxiliares de cobertura de baseline e o auxiliar de seleção de cenário de openclaw/plugin-sdk/qa-live-transport-scenarios.
FaixaCanárioBloqueio por mençãoBot para botBloqueio por lista de permissõesResposta de nível superiorResposta com citaçãoRetomada após reinícioAcompanhamento em threadIsolamento de threadObservação de reaçãoComando de ajudaRegistro de comando nativo
Matrixxxxxxxxxx
Telegramxxxx
Discordxxxx
Slackxxxxxxxx
WhatsAppxxxxxxxx
Isso mantém qa-channel como a suíte ampla de comportamento do produto, enquanto Matrix, Telegram e outros transportes live compartilham uma checklist explícita de contrato de transporte. Para uma faixa de VM Linux descartável sem trazer Docker para o caminho de QA, execute:
pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline
Isso inicializa um guest Multipass novo, instala dependências, compila o OpenClaw dentro do guest, executa qa suite e então copia o relatório e o resumo normais de QA de volta para .artifacts/qa-e2e/... no host. Ela reutiliza o mesmo comportamento de seleção de cenários que qa suite no host. Execuções da suíte no host e no Multipass executam vários cenários selecionados em paralelo com workers de Gateway isolados por padrão. qa-channel usa concorrência 4 por padrão, limitada pela contagem de cenários selecionados. Use --concurrency <count> para ajustar a contagem de workers, ou --concurrency 1 para execução serial. Use --pack personal-agent para executar o pacote de benchmark de assistente pessoal. O seletor de pacote é aditivo com flags --scenario repetidas: cenários explícitos rodam primeiro, depois os cenários do pacote rodam na ordem do pacote com duplicatas removidas. Use --pack observability quando um runner de QA personalizado já fornece a configuração do coletor OpenTelemetry e quer selecionar juntos os cenários de smoke de diagnósticos OpenTelemetry e Prometheus. O comando sai com código diferente de zero quando qualquer cenário falha. Use --allow-failures quando você quiser artefatos sem um código de saída de falha. Execuções live encaminham as entradas de autenticação de QA compatíveis que são práticas para o guest: chaves de provedor baseadas em ambiente, o caminho de configuração do provedor live de QA e CODEX_HOME quando presente. Mantenha --output-dir sob a raiz do repositório para que o guest consiga gravar de volta pelo workspace montado.

Referência de QA para Telegram, Discord, Slack e WhatsApp

Matrix tem uma página dedicada por causa da contagem de cenários e do provisionamento de homeserver com suporte a Docker. Telegram, Discord, Slack e WhatsApp são executados contra transportes reais preexistentes, portanto sua referência fica aqui.

Flags compartilhadas da CLI

Essas lanes são registradas por meio de extensions/qa-lab/src/live-transports/shared/live-transport-cli.ts e aceitam as mesmas flags:
FlagPadrãoDescrição
--scenario <id>-Executa apenas este cenário. Repetível.
--output-dir <path><repo>/.artifacts/qa-e2e/<transport>-<timestamp>Onde relatórios, resumos, evidências, artefatos específicos do transporte e o log de saída são gravados. Caminhos relativos são resolvidos em relação a --repo-root.
--repo-root <path>process.cwd()Raiz do repositório ao invocar a partir de um cwd neutro.
--sut-account <id>sutID de conta temporário dentro da configuração do Gateway de QA.
--provider-mode <mode>live-frontiermock-openai ou live-frontier (live-openai legado ainda funciona).
--model <ref> / --alt-model <ref>padrão do provedorRefs de modelo primário/alternativo.
--fastdesativadoModo rápido do provedor quando suportado.
--credential-source <env|convex>envConsulte pool de credenciais Convex.
--credential-role <maintainer|ci>ci em CI, caso contrário maintainerFunção usada quando --credential-source convex.
Cada lane sai com valor diferente de zero em qualquer cenário com falha. --allow-failures grava artefatos sem definir um código de saída de falha.

QA do Telegram

pnpm openclaw qa telegram
Tem como alvo um grupo privado real do Telegram com dois bots distintos (driver + SUT). O bot SUT deve ter um nome de usuário do Telegram; a observação bot-a-bot funciona melhor quando ambos os bots têm Bot-to-Bot Communication Mode habilitado em @BotFather. Env obrigatório quando --credential-source env:
  • OPENCLAW_QA_TELEGRAM_GROUP_ID - ID numérico do chat (string).
  • OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN
  • OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN
Cenários (extensions/qa-lab/src/live-transports/telegram/telegram-live.runtime.ts):
  • telegram-canary
  • telegram-mention-gating
  • telegram-mentioned-message-reply
  • telegram-help-command
  • telegram-commands-command
  • telegram-tools-compact-command
  • telegram-whoami-command
  • telegram-status-command
  • telegram-repeated-command-authorization
  • telegram-other-bot-command-gating
  • telegram-context-command
  • telegram-current-session-status-tool
  • telegram-reply-chain-exact-marker
  • telegram-stream-final-single-message
  • telegram-long-final-reuses-preview
  • telegram-long-final-three-chunks
O conjunto padrão implícito sempre cobre canário, controle por menção, respostas de comandos nativos, endereçamento de comandos e respostas de grupo bot-a-bot. Os padrões de mock-openai também incluem verificações determinísticas de cadeia de respostas e streaming de mensagem final. telegram-current-session-status-tool continua opt-in porque só é estável quando encadeado diretamente após o canário, não após respostas arbitrárias de comandos nativos. Use pnpm openclaw qa telegram --list-scenarios --provider-mode mock-openai para imprimir a divisão atual entre padrão/opcional com refs de regressão. Artefatos de saída:
  • telegram-qa-report.md
  • qa-evidence.json - entradas de evidência para as verificações de transporte ao vivo, incluindo campos de perfil, cobertura, provedor, canal, artefatos, resultado e RTT.
Execuções de pacote do Telegram usam o mesmo contrato de credenciais do Telegram. A medição repetida de RTT faz parte da lane ao vivo normal de pacote do Telegram; a distribuição de RTT é incorporada em qa-evidence.json sob result.timing para a verificação de RTT selecionada.
OPENCLAW_QA_CREDENTIAL_SOURCE=convex \
pnpm test:docker:npm-telegram-live
Quando OPENCLAW_QA_CREDENTIAL_SOURCE=convex é definido, o wrapper ao vivo do pacote aluga uma credencial kind: "telegram", exporta o grupo/driver/bot SUT alugados para o ambiente da execução do pacote instalado, envia Heartbeats para a concessão e a libera no encerramento. O wrapper de pacote usa por padrão 20 verificações de RTT de telegram-mentioned-message-reply, um timeout de RTT de 30s e a função Convex maintainer fora de CI quando Convex é selecionado. Sobrescreva OPENCLAW_NPM_TELEGRAM_RTT_SAMPLES, OPENCLAW_NPM_TELEGRAM_RTT_TIMEOUT_MS ou OPENCLAW_NPM_TELEGRAM_RTT_MAX_FAILURES para ajustar a medição de RTT sem criar um comando RTT separado ou formato de resumo específico do Telegram.

QA do Discord

pnpm openclaw qa discord
Tem como alvo um canal de guilda privado real do Discord com dois bots: um bot driver controlado pelo harness e um bot SUT iniciado pelo Gateway filho do OpenClaw por meio do Plugin Discord empacotado. Verifica o tratamento de menções no canal, se o bot SUT registrou o comando nativo /help no Discord e cenários de evidência Mantis opt-in. Env obrigatório quando --credential-source env:
  • OPENCLAW_QA_DISCORD_GUILD_ID
  • OPENCLAW_QA_DISCORD_CHANNEL_ID
  • OPENCLAW_QA_DISCORD_DRIVER_BOT_TOKEN
  • OPENCLAW_QA_DISCORD_SUT_BOT_TOKEN
  • OPENCLAW_QA_DISCORD_SUT_APPLICATION_ID - deve corresponder ao ID de usuário do bot SUT retornado pelo Discord (caso contrário, a lane falha rapidamente).
Opcional:
  • OPENCLAW_QA_DISCORD_CAPTURE_CONTENT=1 mantém os corpos das mensagens nos artefatos de mensagens observadas.
  • OPENCLAW_QA_DISCORD_VOICE_CHANNEL_ID seleciona o canal de voz/palco para discord-voice-autojoin; sem isso, o cenário escolhe o primeiro canal de voz/palco visível para o bot SUT.
Cenários (extensions/qa-lab/src/live-transports/discord/discord-live.runtime.ts:36):
  • discord-canary
  • discord-mention-gating
  • discord-native-help-command-registration
  • discord-voice-autojoin - cenário de voz opt-in. Executa sozinho, habilita channels.discord.voice.autoJoin e verifica se o estado de voz atual no Discord do bot SUT é o canal de voz/palco alvo. As credenciais Discord do Convex podem incluir voiceChannelId opcional; caso contrário, o executor descobre o primeiro canal de voz/palco visível na guilda.
  • discord-status-reactions-tool-only - cenário Mantis opt-in. Executa sozinho porque alterna o SUT para respostas de guilda sempre ativas e somente por ferramenta com messages.statusReactions.enabled=true, depois captura uma linha do tempo de reações REST mais artefatos visuais HTML/PNG. Relatórios antes/depois do Mantis também preservam artefatos MP4 fornecidos pelo cenário como baseline.mp4 e candidate.mp4.
Execute explicitamente o cenário de entrada automática em voz do Discord:
pnpm openclaw qa discord \
  --scenario discord-voice-autojoin \
  --provider-mode mock-openai
Execute explicitamente o cenário de reações de status do Mantis:
pnpm openclaw qa discord \
  --scenario discord-status-reactions-tool-only \
  --provider-mode live-frontier \
  --model openai/gpt-5.5 \
  --alt-model openai/gpt-5.5 \
  --fast
Artefatos de saída:
  • discord-qa-report.md
  • qa-evidence.json - entradas de evidência para as verificações de transporte ao vivo.
  • discord-qa-observed-messages.json - corpos redigidos, a menos que OPENCLAW_QA_DISCORD_CAPTURE_CONTENT=1.
  • discord-qa-reaction-timelines.json e discord-status-reactions-tool-only-timeline.png quando o cenário de reação de status é executado.

QA do Slack

pnpm openclaw qa slack
Tem como alvo um canal privado real do Slack com dois bots distintos: um bot driver controlado pelo harness e um bot SUT iniciado pelo Gateway filho do OpenClaw por meio do Plugin Slack empacotado. Env obrigatório quando --credential-source env:
  • OPENCLAW_QA_SLACK_CHANNEL_ID
  • OPENCLAW_QA_SLACK_DRIVER_BOT_TOKEN
  • OPENCLAW_QA_SLACK_SUT_BOT_TOKEN
  • OPENCLAW_QA_SLACK_SUT_APP_TOKEN
Opcional:
  • OPENCLAW_QA_SLACK_CAPTURE_CONTENT=1 mantém os corpos das mensagens nos artefatos de mensagens observadas.
  • OPENCLAW_QA_SLACK_APPROVAL_CHECKPOINT_DIR habilita checkpoints de aprovação visual para o Mantis. O executor grava <scenario>.pending.json e <scenario>.resolved.json, depois espera por arquivos .ack.json correspondentes.
  • OPENCLAW_QA_SLACK_APPROVAL_CHECKPOINT_TIMEOUT_MS substitui o timeout de confirmação do checkpoint. O padrão é 120000.
Cenários (extensions/qa-lab/src/live-transports/slack/slack-live.runtime.ts):
  • slack-canary
  • slack-mention-gating
  • slack-allowlist-block
  • slack-top-level-reply-shape
  • slack-restart-resume
  • slack-thread-follow-up
  • slack-thread-isolation
  • slack-approval-exec-native - cenário opt-in de aprovação de exec nativa do Slack. Solicita uma aprovação de exec por meio do Gateway, verifica se a mensagem do Slack tem botões de aprovação nativos, resolve-a e verifica a atualização resolvida do Slack.
  • slack-approval-plugin-native - cenário opt-in de aprovação nativa de Plugin do Slack. Habilita o encaminhamento de aprovação de exec e Plugin em conjunto para que eventos de Plugin não sejam suprimidos pelo roteamento de aprovação de exec, depois verifica o mesmo caminho de IU nativa do Slack pendente/resolvido.
Artefatos de saída:
  • slack-qa-report.md
  • qa-evidence.json - entradas de evidência para as verificações de transporte ao vivo.
  • slack-qa-observed-messages.json - corpos redigidos, a menos que OPENCLAW_QA_SLACK_CAPTURE_CONTENT=1.
  • approval-checkpoints/ - somente quando o Mantis define OPENCLAW_QA_SLACK_APPROVAL_CHECKPOINT_DIR; contém JSON de checkpoint, JSON de confirmação e capturas de tela pendente/resolvida.

Configurando o workspace do Slack

A lane precisa de dois apps Slack distintos em um workspace, além de um canal do qual ambos os bots sejam membros:
  • channelId - o ID Cxxxxxxxxxx de um canal para o qual ambos os bots foram convidados. Use um canal dedicado; a lane publica a cada execução.
  • driverBotToken - token de bot (xoxb-...) do app Driver.
  • sutBotToken - token de bot (xoxb-...) do app SUT, que deve ser um app Slack separado do driver para que seu ID de usuário de bot seja distinto.
  • sutAppToken - token no nível do app (xapp-...) do app SUT com connections:write, usado pelo Socket Mode para que o app SUT possa receber eventos.
Prefira um workspace Slack dedicado a QA em vez de reutilizar um workspace de produção. O manifesto SUT abaixo estreita intencionalmente a instalação de produção do Plugin Slack empacotado (extensions/slack/src/setup-shared.ts:10) para as permissões e eventos cobertos pela suíte de QA ao vivo do Slack. Para a configuração do canal de produção como os usuários a veem, consulte configuração rápida do canal Slack; o par Driver/SUT de QA é intencionalmente separado porque a lane precisa de dois IDs de usuário de bot distintos em um workspace. 1. Crie o app Driver Acesse api.slack.com/appsCriar novo appA partir de um manifesto → escolha o workspace de QA, cole o manifesto a seguir e então Instalar no workspace:
{
  "display_information": {
    "name": "OpenClaw QA Driver",
    "description": "Test driver bot for OpenClaw QA Slack live lane"
  },
  "features": {
    "bot_user": {
      "display_name": "OpenClaw QA Driver",
      "always_online": true
    }
  },
  "oauth_config": {
    "scopes": {
      "bot": ["chat:write", "channels:history", "groups:history", "users:read"]
    }
  },
  "settings": {
    "socket_mode_enabled": false
  }
}
Copie o Token OAuth de usuário bot (xoxb-...) - isso se torna driverBotToken. O driver só precisa postar mensagens e identificar a si mesmo; sem eventos, sem Socket Mode. 2. Criar o app SUT Repita Criar novo app → A partir de um manifesto no mesmo workspace. Este app de QA usa intencionalmente uma versão mais restrita do manifesto de produção do Plugin Slack incluído (extensions/slack/src/setup-shared.ts:10): escopos e eventos de reação são omitidos porque a suíte de QA ao vivo do Slack ainda não cobre o tratamento de reações.
{
  "display_information": {
    "name": "OpenClaw QA SUT",
    "description": "OpenClaw QA SUT connector for OpenClaw"
  },
  "features": {
    "bot_user": {
      "display_name": "OpenClaw QA SUT",
      "always_online": true
    },
    "app_home": {
      "home_tab_enabled": true,
      "messages_tab_enabled": true,
      "messages_tab_read_only_enabled": false
    }
  },
  "oauth_config": {
    "scopes": {
      "bot": [
        "app_mentions:read",
        "assistant:write",
        "channels:history",
        "channels:read",
        "chat:write",
        "commands",
        "emoji:read",
        "files:read",
        "files:write",
        "groups:history",
        "groups:read",
        "im:history",
        "im:read",
        "im:write",
        "mpim:history",
        "mpim:read",
        "mpim:write",
        "pins:read",
        "pins:write",
        "usergroups:read",
        "users:read"
      ]
    }
  },
  "settings": {
    "socket_mode_enabled": true,
    "event_subscriptions": {
      "bot_events": [
        "app_home_opened",
        "app_mention",
        "channel_rename",
        "member_joined_channel",
        "member_left_channel",
        "message.channels",
        "message.groups",
        "message.im",
        "message.mpim",
        "pin_added",
        "pin_removed"
      ]
    }
  }
}
Depois que o Slack criar o app, faça duas coisas na página de configurações dele:
  • Instalar no workspace → copie o Token OAuth de usuário bot → isso se torna sutBotToken.
  • Informações básicas → Tokens no nível do app → Gerar token e escopos → adicione o escopo connections:write → salve → copie o valor xapp-... → isso se torna sutAppToken.
Verifique se os dois bots têm ids de usuário distintos chamando auth.test em cada token. O runtime distingue o driver e o SUT pelo id de usuário; reutilizar um app para ambos fará o controle por menções falhar imediatamente. 3. Criar o canal No workspace de QA, crie um canal (por exemplo, #openclaw-qa) e convide ambos os bots de dentro do canal:
/invite @OpenClaw QA Driver
/invite @OpenClaw QA SUT
Copie o id Cxxxxxxxxxx em informações do canal → Sobre → ID do canal - isso se torna channelId. Um canal público funciona; se você usar um canal privado, ambos os apps já têm groups:history, então as leituras de histórico do harness ainda terão sucesso. 4. Registrar as credenciais Duas opções. Use variáveis de ambiente para depuração em uma única máquina (defina as quatro variáveis OPENCLAW_QA_SLACK_* e passe --credential-source env), ou alimente o pool compartilhado do Convex para que CI e outros mantenedores possam reservá-las. Para o pool do Convex, escreva os quatro campos em um arquivo JSON:
{
  "channelId": "Cxxxxxxxxxx",
  "driverBotToken": "xoxb-...",
  "sutBotToken": "xoxb-...",
  "sutAppToken": "xapp-..."
}
Com OPENCLAW_QA_CONVEX_SITE_URL e OPENCLAW_QA_CONVEX_SECRET_MAINTAINER exportados no seu shell, registre e verifique:
pnpm openclaw qa credentials add \
  --kind slack \
  --payload-file slack-creds.json \
  --note "QA Slack pool seed"

pnpm openclaw qa credentials list --kind slack --status all --json
Espere count: 1, status: "active", sem campo lease. 5. Verifique de ponta a ponta Execute a trilha localmente para confirmar que ambos os bots conseguem conversar entre si por meio do intermediador:
pnpm openclaw qa slack \
  --credential-source convex \
  --credential-role maintainer \
  --output-dir .artifacts/qa-e2e/slack-local
Uma execução verde termina em bem menos de 30 segundos, e slack-qa-report.md mostra tanto slack-canary quanto slack-mention-gating com status pass. Se a trilha ficar travada por ~90 segundos e sair com Convex credential pool exhausted for kind "slack", ou o pool está vazio ou todas as linhas estão concedidas por lease - qa credentials list --kind slack --status all --json indicará qual é o caso.

QA do WhatsApp

pnpm openclaw qa whatsapp
Mira duas contas dedicadas do WhatsApp Web: uma conta controladora controlada pela estrutura de teste e uma conta SUT iniciada pelo Gateway OpenClaw filho por meio do Plugin WhatsApp incluído. Env obrigatório quando --credential-source env:
  • OPENCLAW_QA_WHATSAPP_DRIVER_PHONE_E164
  • OPENCLAW_QA_WHATSAPP_SUT_PHONE_E164
  • OPENCLAW_QA_WHATSAPP_DRIVER_AUTH_ARCHIVE_BASE64
  • OPENCLAW_QA_WHATSAPP_SUT_AUTH_ARCHIVE_BASE64
Opcional:
  • OPENCLAW_QA_WHATSAPP_GROUP_JID habilita cenários de grupo como whatsapp-mention-gating, whatsapp-group-pending-history-context, whatsapp-broadcast-group-fanout, whatsapp-group-activation-always, whatsapp-group-reply-to-bot-triggers, cenários de ação/mídia/enquete em grupo e whatsapp-group-allowlist-block.
  • OPENCLAW_QA_WHATSAPP_CAPTURE_CONTENT=1 mantém corpos de mensagens em artefatos de mensagens observadas.
Catálogo de cenários (extensions/qa-lab/src/live-transports/whatsapp/whatsapp-live.runtime.ts):
  • Linha de base e controle de acesso por menção em grupo: whatsapp-canary, whatsapp-pairing-block, whatsapp-mention-gating, whatsapp-group-pending-history-context, whatsapp-group-activation-always, whatsapp-group-reply-to-bot-triggers, whatsapp-top-level-reply-shape, whatsapp-restart-resume, whatsapp-group-allowlist-block.
  • Comandos nativos: whatsapp-help-command, whatsapp-status-command, whatsapp-commands-command, whatsapp-tools-compact-command, whatsapp-whoami-command, whatsapp-context-command, whatsapp-native-new-command.
  • Comportamento de resposta e saída final: whatsapp-tool-only-usage-footer, whatsapp-reply-to-message, whatsapp-group-reply-to-message, whatsapp-reply-to-mode-batched, whatsapp-reply-context-isolation, whatsapp-reply-delivery-shape, whatsapp-stream-final-message-accounting.
  • Ações de mensagem pelo caminho do usuário: whatsapp-agent-message-action-react começa a partir de uma DM real do controlador, permite que o modelo chame a ferramenta message e observa a reação nativa do WhatsApp. whatsapp-agent-message-action-upload-file usa a mesma postura para message(action=upload-file) e observa mídia nativa do WhatsApp. whatsapp-group-agent-message-action-react e whatsapp-group-agent-message-action-upload-file comprovam as mesmas ações visíveis ao usuário em um grupo real do WhatsApp.
  • Distribuição para grupo: whatsapp-broadcast-group-fanout começa a partir de uma mensagem mencionada em grupo do WhatsApp e verifica respostas visíveis distintas de main e qa-second.
  • Ativação em grupo: whatsapp-group-activation-always altera uma sessão real de grupo para /activation always, comprova que uma mensagem de grupo sem menção desperta o agente e então restaura /activation mention. whatsapp-group-reply-to-bot-triggers semeia uma resposta do bot, envia uma resposta nativa citada a ela sem uma menção explícita e verifica que o agente desperta a partir desse contexto de resposta.
  • Mídia recebida e mensagens estruturadas: whatsapp-inbound-image-caption, whatsapp-audio-preflight, whatsapp-inbound-structured-messages, whatsapp-group-audio-gating, whatsapp-inbound-reaction-no-trigger. Esses cenários enviam eventos reais de imagem, áudio, documento, localização, contato, figurinha e reação do WhatsApp por meio do controlador.
  • Sondas diretas de contrato do Gateway: whatsapp-outbound-media-matrix, whatsapp-outbound-document-preserves-filename, whatsapp-outbound-poll, whatsapp-group-outbound-media, whatsapp-group-outbound-poll, whatsapp-message-actions, whatsapp-reply-context-isolation, whatsapp-reply-delivery-shape. Elas ignoram intencionalmente o prompt do modelo e comprovam contratos determinísticos de Gateway/canal para send, poll e message.action.
  • Cobertura de controle de acesso: whatsapp-access-control-dm-open, whatsapp-access-control-dm-disabled, whatsapp-access-control-group-open, whatsapp-access-control-group-disabled, whatsapp-group-allowlist-block.
  • Aprovações nativas: whatsapp-approval-exec-deny-native, whatsapp-approval-exec-native, whatsapp-approval-exec-reaction-native, whatsapp-approval-exec-group-reaction-native, whatsapp-approval-plugin-native.
  • Reações de status: whatsapp-status-reactions, whatsapp-status-reaction-lifecycle.
Atualmente, o catálogo contém 50 cenários. A trilha padrão live-frontier é mantida pequena, com 10 cenários, para cobertura rápida de verificação. A trilha padrão mock-openai executa 44 cenários determinísticos pelo transporte real do WhatsApp enquanto simula apenas a saída do modelo. Cenários de aprovação e algumas verificações mais pesadas/bloqueantes continuam explícitos por ID de cenário. O controlador de QA do WhatsApp observa eventos vivos estruturados (text, media, location, reaction e poll) e pode enviar ativamente mídia, enquetes, contatos, localizações e figurinhas. O QA Lab importa esse controlador pela superfície do pacote @openclaw/whatsapp/api.js, em vez de acessar arquivos privados do runtime do WhatsApp. Para observações de grupo, fromJid é o JID do grupo, enquanto participantJid e fromPhoneE164 identificam o remetente participante. O conteúdo da mensagem é redigido por padrão. Sondas diretas de Gateway para enquete, envio de arquivo, mídia, enquete em grupo, mídia em grupo e formato de resposta são verificações de contrato de transporte/API; elas não são tratadas como prova de que um prompt de usuário fez o agente escolher a mesma ação. A prova de ação pelo caminho do usuário vem de cenários como whatsapp-agent-message-action-react e whatsapp-group-agent-message-action-react, nos quais o controlador envia uma mensagem normal do WhatsApp e o QA Lab observa o artefato nativo do WhatsApp resultante. Relatórios do WhatsApp incluem a postura de cada cenário (user-path, direct-gateway ou native-approval) para que a evidência não seja confundida com um contrato mais forte do que ela de fato comprova. Artefatos de saída:
  • whatsapp-qa-report.md
  • qa-evidence.json - entradas de evidência para as verificações do transporte vivo.
  • whatsapp-qa-observed-messages.json - corpos redigidos, a menos que OPENCLAW_QA_WHATSAPP_CAPTURE_CONTENT=1.

Pool de credenciais do Convex

As trilhas Telegram, Discord, Slack e WhatsApp podem conceder credenciais por lease a partir de um pool compartilhado do Convex em vez de ler as variáveis de ambiente acima. Passe --credential-source convex (ou defina OPENCLAW_QA_CREDENTIAL_SOURCE=convex); o QA Lab adquire um lease exclusivo, envia Heartbeats durante a execução e o libera no encerramento. Os tipos de pool são "telegram", "discord", "slack" e "whatsapp". Formatos de payload que o intermediador valida em admin/add:
  • Telegram (kind: "telegram"): { groupId: string, driverToken: string, sutToken: string } - groupId deve ser uma string numérica de chat-id.
  • Usuário real do Telegram (kind: "telegram-user"): { groupId: string, sutToken: string, testerUserId: string, testerUsername: string, telegramApiId: string, telegramApiHash: string, tdlibDatabaseEncryptionKey: string, tdlibArchiveBase64: string, tdlibArchiveSha256: string, desktopTdataArchiveBase64: string, desktopTdataArchiveSha256: string } - somente prova do Mantis Telegram Desktop. As faixas genéricas do QA Lab não devem adquirir esse tipo.
  • Discord (kind: "discord"): { guildId: string, channelId: string, driverBotToken: string, sutBotToken: string, sutApplicationId: string }.
  • WhatsApp (kind: "whatsapp"): { driverPhoneE164: string, sutPhoneE164: string, driverAuthArchiveBase64: string, sutAuthArchiveBase64: string, groupJid?: string } - os números de telefone devem ser strings E.164 distintas.
O fluxo de trabalho de prova do Mantis Telegram Desktop mantém uma concessão exclusiva telegram-user do Convex para o driver de CLI TDLib e a testemunha do Telegram Desktop, depois a libera após publicar a prova. Quando um PR precisa de um diff visual determinístico, o Mantis pode usar a mesma resposta de modelo simulado em main e na cabeça do PR enquanto o formatador do Telegram ou a camada de entrega muda. Os padrões de captura são ajustados para comentários de PR: classe Crabbox padrão, gravação de desktop a 24 fps, GIF de movimento a 24 fps e largura de pré-visualização de 1920 px. Comentários de antes/depois devem publicar um pacote limpo que contenha somente os GIFs pretendidos. As faixas do Slack também podem usar o pool. As verificações de formato de payload do Slack atualmente ficam no executor de QA do Slack, e não no intermediador; use { channelId: string, driverBotToken: string, sutBotToken: string, sutAppToken: string }, com um id de canal do Slack como Cxxxxxxxxxx. Consulte Configurar o workspace do Slack para provisionar o app e os escopos. As variáveis de ambiente operacionais e o contrato de endpoint do intermediador Convex ficam em Testes → Credenciais compartilhadas do Telegram via Convex (o nome da seção é anterior ao pool multicanal; a semântica de concessão é compartilhada entre os tipos).

Seeds versionados no repositório

Os ativos de seed ficam em qa/:
  • qa/scenarios/index.yaml
  • qa/scenarios/<theme>/*.yaml
Eles estão intencionalmente no git para que o plano de QA seja visível tanto para humanos quanto para o agente. qa-lab deve permanecer um executor genérico de cenários YAML. Cada arquivo YAML de cenário é a fonte da verdade para uma execução de teste e deve definir:
  • title no nível superior
  • metadados de scenario
  • metadados opcionais de categoria, capability, faixa e risco em scenario
  • referências de docs e código em scenario
  • requisitos opcionais de plugin em scenario
  • patch opcional de config do gateway em scenario
  • flow executável no nível superior para cenários de fluxo, ou scenario.execution.kind / scenario.execution.path para cenários de Vitest e Playwright
A superfície de runtime reutilizável que sustenta flow pode permanecer genérica e transversal. Por exemplo, cenários YAML podem combinar helpers do lado do transporte com helpers do lado do navegador que conduzem a Control UI embutida pelo ponto de integração browser.request do Gateway sem adicionar um executor especial. Arquivos de cenário devem ser agrupados por capability do produto em vez de pasta da árvore de código-fonte. Mantenha os IDs de cenário estáveis quando os arquivos forem movidos; use docsRefs e codeRefs para rastreabilidade da implementação. A lista baseline deve permanecer ampla o suficiente para cobrir:
  • chat por DM e canal
  • comportamento de thread
  • ciclo de vida de ações de mensagem
  • callbacks cron
  • recuperação de memória
  • troca de modelo
  • passagem para subagente
  • leitura de repositório e leitura de docs
  • uma pequena tarefa de build, como Lobster Invaders

Faixas de mock de provider

qa suite tem duas faixas locais de mock de provider:
  • mock-openai é o mock do OpenClaw ciente de cenários. Ele continua sendo a faixa de mock determinística padrão para QA versionado no repositório e gates de paridade.
  • aimock inicia um servidor de provider baseado em AIMock para cobertura experimental de protocolo, fixture, gravação/reprodução e caos. Ele é aditivo e não substitui o despachante de cenários mock-openai.
A implementação das faixas de provider fica em extensions/qa-lab/src/providers/. Cada provider é dono de seus padrões, inicialização do servidor local, config de modelo do gateway, necessidades de staging de perfil de autenticação e flags de capability live/mock. O código compartilhado da suite e do gateway deve rotear pelo registro de providers em vez de ramificar em nomes de providers.

Adaptadores de transporte

qa-lab possui um ponto de integração de transporte genérico para cenários QA YAML. qa-channel é o padrão sintético. crabline inicia servidores locais em formato de provider e executa os plugins de canal normais do OpenClaw contra eles. live é reservado para credenciais reais de provider e canais externos. No nível de arquitetura, a divisão é:
  • qa-lab possui execução genérica de cenários, concorrência de workers, escrita de artefatos e relatórios.
  • O adaptador de transporte possui config do gateway, prontidão, observação de entrada e saída, ações de transporte e estado de transporte normalizado.
  • Arquivos de cenário YAML em qa/scenarios/ definem a execução de teste; qa-lab fornece a superfície de runtime reutilizável que os executa.

Adicionar um canal

Adicionar um canal ao sistema de QA YAML exige a implementação do canal mais um pacote de cenários que exercite o contrato do canal. Para cobertura smoke em CI, adicione o servidor local de provider Crabline correspondente e exponha-o pelo driver crabline. Não adicione uma nova raiz de comando QA de nível superior quando o host compartilhado qa-lab puder possuir o fluxo. qa-lab possui a mecânica de host compartilhado:
  • a raiz de comando openclaw qa
  • inicialização e teardown da suite
  • concorrência de workers
  • escrita de artefatos
  • geração de relatórios
  • execução de cenários
  • aliases de compatibilidade para cenários qa-channel mais antigos
Plugins executores possuem o contrato de transporte:
  • como openclaw qa <runner> é montado sob a raiz compartilhada qa
  • como o gateway é configurado para esse transporte
  • como a prontidão é verificada
  • como eventos de entrada são injetados
  • como mensagens de saída são observadas
  • como transcrições e estado de transporte normalizado são expostos
  • como ações com suporte de transporte são executadas
  • como reset ou limpeza específicos do transporte são tratados
O patamar mínimo de adoção para um novo canal:
  1. Mantenha qa-lab como dono da raiz compartilhada qa.
  2. Implemente o executor de transporte no ponto de integração do host compartilhado qa-lab.
  3. Mantenha a mecânica específica do transporte dentro do plugin executor ou harness de canal.
  4. Monte o executor como openclaw qa <runner> em vez de registrar um comando raiz concorrente. Plugins executores devem declarar qaRunners em openclaw.plugin.json e exportar um array qaRunnerCliRegistrations correspondente de runtime-api.ts. Mantenha runtime-api.ts leve; CLI lazy e execução do executor devem permanecer atrás de entrypoints separados.
  5. Crie ou adapte cenários YAML nos diretórios temáticos qa/scenarios/.
  6. Use os helpers genéricos de cenário para novos cenários.
  7. Mantenha os aliases de compatibilidade existentes funcionando, a menos que o repositório esteja fazendo uma migração intencional.
A regra de decisão é estrita:
  • Se o comportamento puder ser expresso uma vez em qa-lab, coloque-o em qa-lab.
  • Se o comportamento depender de um transporte de canal, mantenha-o nesse plugin executor ou harness de plugin.
  • Se um cenário precisar de uma nova capability que mais de um canal pode usar, adicione um helper genérico em vez de uma ramificação específica de canal em suite.ts.
  • Se um comportamento só fizer sentido para um transporte, mantenha o cenário específico do transporte e deixe isso explícito no contrato do cenário.

Nomes de helpers de cenário

Helpers genéricos preferidos para novos cenários:
  • waitForTransportReady
  • waitForChannelReady
  • injectInboundMessage
  • injectOutboundMessage
  • waitForTransportOutboundMessage
  • waitForChannelOutboundMessage
  • waitForNoTransportOutbound
  • getTransportSnapshot
  • readTransportMessage
  • readTransportTranscript
  • formatTransportTranscript
  • resetTransport
Aliases de compatibilidade continuam disponíveis para cenários existentes - waitForQaChannelReady, waitForOutboundMessage, waitForNoOutbound, formatConversationTranscript, resetBus - mas a autoria de novos cenários deve usar os nomes genéricos. Os aliases existem para evitar uma migração em flag day, não como o modelo daqui em diante.

Relatórios

qa-lab exporta um relatório de protocolo em Markdown a partir da linha do tempo observada do bus. O relatório deve responder:
  • O que funcionou
  • O que falhou
  • O que permaneceu bloqueado
  • Quais cenários de acompanhamento vale a pena adicionar
Para o inventário de cenários disponíveis - útil ao dimensionar trabalho de acompanhamento ou conectar um novo transporte - execute pnpm openclaw qa coverage (adicione --json para saída legível por máquina). Ao escolher prova focada para um comportamento ou caminho de arquivo tocado, execute pnpm openclaw qa coverage --match <query>. O relatório de correspondência pesquisa metadados de cenário, refs de docs, refs de código, IDs de cobertura, plugins e requisitos de provider, depois imprime alvos qa suite --scenario ... correspondentes. Cada execução de qa suite grava artefatos qa-evidence.json, qa-suite-summary.json e qa-suite-report.md no nível superior para o conjunto de cenários selecionado. Cenários que declaram execution.kind: vitest ou execution.kind: playwright executam o caminho de teste correspondente e também gravam logs por cenário. Cenários que declaram execution.kind: script executam o produtor de evidências em execution.path por node --import tsx (com ${outputDir} e ${scenarioId} expandidos em execution.args); o produtor grava seu próprio qa-evidence.json, cujas entradas são importadas para a saída da suite e cujos caminhos de artefato são resolvidos em relação a esse qa-evidence.json do produtor. Quando qa suite é alcançado por qa run --qa-profile, o mesmo qa-evidence.json também inclui o resumo do scorecard de perfil para as categorias de taxonomia selecionadas. Trate isso como auxílio de descoberta, não como substituto de gate; o cenário selecionado ainda precisa do modo de provider, transporte live, Multipass, Testbox ou faixa de release corretos para o comportamento em teste. Para contexto do scorecard, consulte Scorecard de maturidade. Para verificações de caráter e estilo, execute o mesmo cenário em múltiplas refs de modelo live e grave um relatório julgado em Markdown:
pnpm openclaw qa character-eval \
  --model openai/gpt-5.5,thinking=medium,fast \
  --model openai/gpt-5.2,thinking=xhigh \
  --model openai/gpt-5,thinking=xhigh \
  --model anthropic/claude-opus-4-8,thinking=high \
  --model anthropic/claude-sonnet-4-6,thinking=high \
  --model zai/glm-5.1,thinking=high \
  --model moonshot/kimi-k2.5,thinking=high \
  --model google/gemini-3.1-pro-preview,thinking=high \
  --judge-model openai/gpt-5.5,thinking=xhigh,fast \
  --judge-model anthropic/claude-opus-4-8,thinking=high \
  --blind-judge-models \
  --concurrency 16 \
  --judge-concurrency 16
O comando executa processos filhos locais do Gateway de QA, não Docker. Cenários de avaliação de personagem devem definir a persona por meio de SOUL.md e então executar turnos comuns do usuário como chat, ajuda no workspace e pequenas tarefas de arquivo. O modelo candidato não deve ser informado de que está sendo avaliado. O comando preserva cada transcrição completa, registra estatísticas básicas da execução e então pede aos modelos juízes, em modo rápido com raciocínio xhigh quando compatível, que classifiquem as execuções por naturalidade, vibe e humor. Use --blind-judge-models ao comparar provedores: o prompt do juiz ainda recebe cada transcrição e status de execução, mas as refs candidatas são substituídas por rótulos neutros como candidate-01; o relatório mapeia as classificações de volta para as refs reais após o parsing. As execuções candidatas usam high como thinking padrão, com medium para GPT-5.5 e xhigh para refs de avaliação OpenAI mais antigas que o suportam. Sobrescreva um candidato específico inline com --model provider/model,thinking=<level>. --thinking <level> ainda define um fallback global, e a forma mais antiga --model-thinking <provider/model=level> é mantida por compatibilidade. Refs candidatas OpenAI usam modo rápido por padrão para que o processamento prioritário seja usado onde o provedor o suporta. Adicione ,fast, ,no-fast ou ,fast=false inline quando um único candidato ou juiz precisar de uma sobrescrita. Passe --fast somente quando quiser forçar o modo rápido para todos os modelos candidatos. As durações de candidatos e juízes são registradas no relatório para análise de benchmark, mas os prompts dos juízes dizem explicitamente para não classificar por velocidade. As execuções dos modelos candidatos e juízes usam concorrência 16 por padrão. Reduza --concurrency ou --judge-concurrency quando limites do provedor ou pressão do Gateway local tornarem uma execução ruidosa demais. Quando nenhum candidato --model é passado, a avaliação de personagem usa por padrão openai/gpt-5.5, openai/gpt-5.2, openai/gpt-5, anthropic/claude-opus-4-8, anthropic/claude-sonnet-4-6, zai/glm-5.1, moonshot/kimi-k2.5 e google/gemini-3.1-pro-preview quando nenhum --model é passado. Quando nenhum --judge-model é passado, os juízes usam por padrão openai/gpt-5.5,thinking=xhigh,fast e anthropic/claude-opus-4-8,thinking=high.

Docs relacionados