Fundamentals
Visão geral de QA
A pilha privada de QA exercita o OpenClaw de forma realista e semelhante a um canal, algo que um teste unitário não consegue fazer.
Componentes:
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: interface do depurador, barramento de QA, perfis de cenário e adaptadores de transporte em tempo real para observar a transcrição, injetar mensagens recebidas e exportar um relatório em Markdown.qa/: ativos iniciais baseados no repositório para a tarefa de abertura e cenários básicos de QA.- Mantis: verificação em tempo real antes/depois para bugs que exigem transportes reais, capturas de tela do navegador, estado da VM e evidências da PR.
Superfície de comandos
Todo fluxo de QA é executado em pnpm openclaw qa <subcommand>. Muitos têm aliases de script
pnpm qa:*; ambas as formas funcionam.
| Comando | Finalidade |
|---|---|
qa run |
Autoverificação de QA integrada sem --qa-profile; executor de perfil de maturidade baseado em taxonomia com --qa-profile smoke-ci, --qa-profile release ou --qa-profile all. |
qa suite |
Executa cenários baseados no repositório na via do gateway de QA. --runner multipass usa uma VM Linux descartável em vez do host. |
qa coverage |
Exibe o inventário YAML de cobertura de cenários (--json para saída de máquina; --match <query> para encontrar cenários de um comportamento alterado; --tools para cobertura de fixtures de ferramentas de runtime). |
qa parity-report |
Compara dois arquivos qa-suite-summary.json para um gate de paridade no eixo de modelos ou usa --runtime-axis --token-efficiency para gravar relatórios de paridade de runtime e eficiência de tokens entre Codex e OpenClaw. |
qa confidence-report |
Classifica artefatos de evidência de QA em relação a um manifesto, gerando um relatório de confiança com zero itens desconhecidos. |
qa confidence-self-test |
Grava canários de controle negativo com dados iniciais, comprovando que o gate de confiança detecta desvios. |
qa jsonl-replay |
Reproduz transcrições JSONL selecionadas por meio da estrutura de reprodução de paridade de runtime. |
qa character-eval |
Executa o cenário de QA de personagem em vários modelos em tempo real com um relatório avaliado. Consulte Relatórios. |
qa manual |
Executa um prompt avulso na via do provedor/modelo selecionado. |
qa ui |
Inicia a interface do depurador de QA e o barramento de QA local (alias: pnpm qa:lab:ui). |
qa docker-build-image |
Compila a imagem Docker de QA pré-preparada. |
qa docker-scaffold |
Grava uma estrutura inicial do docker-compose para o painel de QA + a via do gateway. |
qa up |
Compila o site de QA, inicia a pilha baseada em Docker e exibe a URL (alias: pnpm qa:lab:up; a variante :fast adiciona --use-prebuilt-image --bind-ui-dist --skip-ui-build). |
qa aimock |
Inicia apenas o servidor do provedor AIMock. |
qa mock-openai |
Inicia apenas o servidor do provedor mock-openai sensível a cenários. |
qa credentials doctor / add / list / remove |
Gerencia o pool compartilhado de credenciais do Convex. |
qa discord |
Via de transporte em tempo real em um canal real de guilda privada do Discord. |
qa matrix |
Perfis do Matrix no QA Lab em um homeserver Tuwunel descartável. Consulte Vias de smoke do Matrix. |
qa slack |
Via de transporte em tempo real em um canal privado real do Slack. |
qa telegram |
Via de transporte em tempo real em um grupo privado real do Telegram. |
qa whatsapp |
Via de transporte em tempo real em contas reais do WhatsApp Web. |
qa mantis |
Executor de verificação antes/depois para bugs de transporte em tempo real, com evidências de reações de status do Discord, smoke de desktop/navegador no Crabbox e smoke do Slack em VNC. Consulte Mantis e o Runbook do Mantis para Slack Desktop. |
qa run baseado em perfil
O qa run baseado em perfil lê a associação em taxonomy.yaml e então encaminha
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 do placar do perfil com contagens
das categorias selecionadas e IDs de cobertura ausentes; as entradas individuais de evidência continuam sendo a
fonte da verdade para os testes, as funções de cobertura e os resultados. Os IDs de cobertura
de recursos da taxonomia são alvos exatos de comprovação, não aliases: a cobertura primária de cenário
atende aos IDs correspondentes, enquanto a cobertura secundária permanece apenas informativa. Os IDs de cobertura usam
o formato pontilhado namespace.behavior, com segmentos alfanuméricos em minúsculas ou com hífen;
os IDs de perfil, superfície e categoria ainda podem usar os IDs de taxonomia existentes,
com hífen ou pontilhados.
A evidência reduzida omite execution por entrada e define evidenceMode: "slim";
smoke-ci usa o formato reduzido por padrão, e --evidence-mode full restaura as 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-dispatchUse smoke-ci para comprovação determinística de perfil com provedores de modelo simulados e
servidores de provedor local Crabline. Use release para comprovação Stable/LTS em
canais em tempo real. Use all somente para execuções explícitas de evidência da taxonomia completa; ele
seleciona todas as categorias de maturidade ativas e pode ser encaminhado pelo fluxo de trabalho
QA Profile Evidence do GitHub Actions com qa_profile=all. Quando um
comando também precisar de um perfil raiz do OpenClaw, coloque o perfil raiz antes do
comando de QA:
pnpm openclaw --profile work qa run --qa-profile smoke-ciFluxo do operador
O fluxo atual do operador de QA é um site de QA com dois painéis:
- À esquerda: painel do Gateway (Control UI) com o agente.
- À direita: QA Lab, exibindo a transcrição semelhante ao Slack e o plano de cenário.
Execute-o com:
pnpm qa:lab:upIsso compila o site de QA, inicia a via do gateway baseada em Docker e disponibiliza a página do QA Lab, na qual um operador ou loop de automação pode atribuir ao agente uma missão de QA, observar o comportamento real do canal e registrar o que funcionou, falhou ou permaneceu bloqueado.
Para iterar mais rapidamente na interface do QA Lab sem recompilar a imagem Docker a cada vez, inicie a pilha com um pacote do QA Lab montado por bind:
pnpm openclaw qa docker-build-imagepnpm qa:lab:buildpnpm qa:lab:up:fastpnpm qa:lab:watchqa:lab:up:fast mantém os serviços Docker em uma imagem pré-compilada e
monta por bind extensions/qa-lab/web/dist no contêiner qa-lab.
qa:lab:watch recompila esse pacote quando há alterações, e o navegador recarrega automaticamente
quando o hash dos ativos do QA Lab muda.
Smokes de observabilidade
| Alias | O que executa |
|---|---|
pnpm qa:otel:smoke |
Receptor OpenTelemetry local mais o cenário otel-trace-smoke com diagnostics-otel habilitado. |
pnpm qa:otel:collector-smoke |
A mesma lane por trás de um contêiner Docker real do OpenTelemetry Collector. Use-a ao alterar a conexão de endpoints ou a compatibilidade com o coletor/OTLP. |
pnpm qa:prometheus:smoke |
O cenário docker-prometheus-smoke com diagnostics-prometheus habilitado. |
pnpm qa:observability:smoke |
qa:otel:smoke seguido por qa:prometheus:smoke. |
pnpm qa:observability:collector-smoke |
qa:otel:collector-smoke seguido por qa:prometheus:smoke. |
qa:otel:smoke inicia um receptor OTLP/HTTP local, executa um turno mínimo
de agente do canal de QA e, em seguida, confirma que rastros, métricas e logs
são exportados. Ele decodifica os spans de rastreamento protobuf exportados e
verifica a estrutura crítica para a versão:
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 todos presentes. O smoke força
OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental, portanto, 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 brutos
de diagnóstico e atributos openclaw.content.* devem permanecer fora do rastro.
O prompt do cenário solicita que o modelo responda com um marcador fixo e
omita uma string secreta fixa; os payloads OTLP brutos não devem conter nenhum
dos dois, nem a chave da sessão de QA derivada do ID do cenário. Ele grava
otel-smoke-summary.json junto aos artefatos da suíte de QA.
qa:prometheus:smoke verifica se coletas não autenticadas são rejeitadas e,
em seguida, confirma que a coleta autenticada inclui famílias de métricas
críticas para a versão sem conteúdo do prompt, conteúdo da resposta,
identificadores brutos de diagnóstico, tokens de autenticação ou caminhos
locais.
Lanes de smoke do Matrix
Para uma lane de smoke do Matrix com transporte real que não exige credenciais do provedor de modelo, execute o perfil de versão com o provedor OpenAI simulado e determinístico:
pnpm openclaw qa matrix --provider-mode mock-openai --profile releasePara a lane do provedor de fronteira ao vivo, forneça explicitamente credenciais compatíveis com OpenAI:
OPENCLAW_LIVE_OPENAI_KEY="${OPENAI_API_KEY}" \ pnpm openclaw qa matrix --provider-mode live-frontier --profile releasepnpm openclaw qa matrix simples executa o perfil all completo e continua
após falhas de cenário. Use --fail-fast para um ciclo de feedback mais
curto ou repita --scenario <id> para selecionar cenários individuais; IDs de
cenário explícitos têm precedência sobre --profile.
| Perfil | Cenários | Finalidade |
|---|---|---|
all |
93 | Catálogo completo (padrão). |
release |
2 | Linha de base de canal crítica para a versão e recarregamento ao vivo da lista de permissões. |
fast |
12 | Cobertura focada de threads, reações, aprovações, políticas, bloqueio de bots e respostas criptografadas. |
transport |
50 | Threads, roteamento de MD/sala, entrada automática, aprovações, reações, reinicializações, políticas de menção/lista de permissões, edições e ordenação de múltiplos atores. |
media |
7 | Cobertura de imagens, imagens geradas, voz, anexos, mídia não compatível e mídia criptografada. |
e2ee-smoke |
8 | Cobertura mínima de resposta criptografada, threads, inicialização, recuperação, reinicialização, redação e falhas. |
e2ee-deep |
18 | Perda de estado, backup, recuperação de chaves, higiene de dispositivos e verificação por SAS/QR/MD. |
e2ee-cli |
9 | openclaw matrix encryption setup, chave de recuperação, múltiplas contas, ida e volta pelo Gateway e comandos de autoverificação por meio do harness. |
A associação aos perfis e os requisitos do canal ficam junto aos cenários
declarativos do Matrix em qa/scenarios/channels/. A execução escolhe o driver
do canal. As implementações ao vivo ficam em
extensions/qa-lab/src/live-transports/matrix/scenarios/.
O adaptador provisiona um homeserver Tuwunel descartável no Docker (imagem
padrão ghcr.io/matrix-construct/tuwunel:v1.5.1, nome do servidor matrix-qa.test,
porta 28008), registra usuários temporários de driver, SUT e
observador, prepara as salas necessárias e registra o limite de
solicitação/resposta com redação. Em seguida, ele executa o Plugin real do
Matrix dentro de um Gateway de QA filho com escopo restrito a esse transporte
(sem qa-channel) e desmonta o ambiente.
Opções comuns:
| Flag | Padrão | Finalidade |
|---|---|---|
--profile <profile> |
all |
Selecionar um dos perfis acima. |
--scenario <id> |
- | Selecionar um cenário; pode ser repetido. |
--fail-fast |
desativado | Parar após a primeira verificação ou o primeiro cenário com falha. |
--allow-failures |
desativado | Gravar artefatos sem retornar um código de saída de falha para falhas de cenário. |
--provider-mode <mode> |
live-frontier |
Usar mock-openai para despacho determinístico ou live-frontier para um provedor ao vivo. |
--model <ref> |
padrão do provedor | Definir a referência provider/model principal. |
--alt-model <ref> |
padrão do provedor | Definir o modelo alternativo usado por cenários que alternam modelos. |
--fast |
desativado | Habilitar o modo rápido do provedor quando compatível. |
--output-dir <path> |
gerado | Escolher o diretório de relatórios; caminhos relativos são resolvidos em relação a --repo-root. |
--repo-root <path> |
diretório atual | Executar a partir de um diretório de trabalho neutro. |
--sut-account <id> |
sut |
Selecionar o ID da conta do Matrix na configuração do Gateway filho. |
O QA do Matrix não aluga credenciais compartilhadas do Matrix: o adaptador cria
usuários descartáveis localmente, portanto, não aceita --credential-source nem
--credential-role. Substitua a imagem do homeserver com
OPENCLAW_QA_MATRIX_TUWUNEL_IMAGE; ajuste as asserções negativas de ausência de resposta com
OPENCLAW_QA_MATRIX_NO_REPLY_WINDOW_MS (padrão 8000, limitado ao tempo limite do
cenário ativo). Normalmente, o comando de execução única força uma saída limpa
após o descarregamento dos artefatos, pois os handles nativos de criptografia
do Matrix podem permanecer ativos após a limpeza; defina
OPENCLAW_QA_MATRIX_DISABLE_FORCE_EXIT=1 apenas para um harness de teste direto que
precise que o comando retorne em vez disso.
Cada execução grava os artefatos normais do QA Lab no diretório de saída
selecionado: qa-suite-report.md, qa-suite-summary.json, qa-evidence.json
e um manifesto matrix-harness-*/matrix-qa-harness.json com redação. Se a
limpeza falhar, execute o comando de recuperação
docker compose ... down --remove-orphans exibido. Em executores lentos, aumente
a janela de ausência de resposta; em CI rápida, uma janela menor pode reduzir
a duração das asserções negativas.
Os cenários cobrem comportamentos de transporte que testes unitários não podem
comprovar de ponta a ponta: bloqueio por menção, políticas de permissão de bots,
listas de permissões, respostas de nível superior e em threads, roteamento de
MD, tratamento de reações, supressão de edições recebidas, eliminação de
duplicatas de repetição após reinicialização, recuperação após interrupção do
homeserver, entrega de metadados de aprovação, tratamento de mídia e fluxos de
inicialização/recuperação/verificação de E2EE do Matrix. O perfil de 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.
matrix-room-block-streaming e subagent-thread-spawn continuam disponíveis por
seleção explícita de --scenario, mas permanecem fora do perfil
all padrão.
A CI usa a mesma superfície de comandos em
.github/workflows/qa-live-transports-convex.yml. Execuções agendadas e de versão
executam os cenários de versão. Despachos manuais de matrix_profile=all
distribuem os perfis transport, media,
e2ee-smoke, e2ee-deep e e2ee-cli;
despachos focados selecionam fast, release ou
transport em um único job.
Cenários Mantis do Discord
O Discord também possui cenários opcionais exclusivos do 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 se message.thread-reply
preserva um anexo filePath. Esses cenários permanecem fora da lane
padrão ao vivo do Discord porque são sondagens de reprodução antes/depois, em
vez de uma ampla cobertura de smoke. O fluxo de trabalho Mantis de anexo em
thread também pode adicionar um vídeo de testemunho do Discord Web com sessão
iniciada 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 aprovação/reprovação ainda vem do oráculo REST do Discord.
Para as outras lanes de smoke com transporte real:
pnpm openclaw qa discordpnpm openclaw qa slackpnpm openclaw qa telegrampnpm openclaw qa whatsappElas têm como alvo um canal real preexistente com dois bots ou contas (driver + SUT). As variáveis de ambiente necessárias, listas de cenários, artefatos de saída e o pool de credenciais Convex para esses quatro transportes estão documentados na referência de QA do Discord, Slack, Telegram e WhatsApp abaixo.
Executores de desktop do Slack e tarefas visuais do Mantis
Para uma execução completa em VM do desktop do Slack com recuperação por VNC, execute:
pnpm openclaw qa mantis slack-desktop-smoke \ --gateway-setup \ --scenario slack-canary \ --keep-leaseEsse comando concede uma máquina Crabbox com desktop/navegador, executa a
pista ao vivo 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 está disponível) de volta para o
diretório de artefatos do Mantis. As concessões de desktop/navegador do Crabbox
fornecem previamente as ferramentas de captura e os pacotes auxiliares do
navegador/build nativo, portanto o cenário só deve instalar alternativas em
concessões mais antigas. O Mantis informa os tempos total e por fase em
mantis-slack-desktop-smoke-report.md, para que execuções lentas mostrem se o tempo foi gasto no
aquecimento da concessão, na obtenção de credenciais, na configuração remota ou
na cópia de artefatos. Reutilize --lease-id <cbx_...> após iniciar sessão
manualmente no Slack Web por meio do VNC; concessões reutilizadas também mantêm
aquecido o cache do armazenamento pnpm do Crabbox. O --hydrate-mode source padrão
faz a verificação a partir de um checkout do código-fonte e executa a
instalação/build dentro da VM. Use --hydrate-mode prehydrated somente quando o espaço
de trabalho remoto reutilizado já tiver node_modules e um
dist/ compilado; esse modo ignora a etapa dispendiosa de
instalação/build e falha de forma segura quando o espaço de trabalho não está
pronto. Com --gateway-setup, o Mantis deixa um Gateway persistente do Slack
do OpenClaw em execução dentro da VM na porta 38973; sem essa
opção, o comando executa a pista normal de QA de bot para bot do Slack e sai
após a captura dos artefatos.
Para comprovar a interface nativa de aprovação do Slack com evidências do desktop, execute o modo de pontos de verificação de aprovação do Mantis:
pnpm openclaw qa mantis slack-desktop-smoke \ --approval-checkpoints \ --credential-source convex \ --credential-role maintainerEsse modo é mutuamente exclusivo com --gateway-setup. Ele executa os
cenários de aprovação do Slack, rejeita IDs de cenários que não sejam de
aprovação, aguarda em cada estado de aprovação pendente e resolvido, renderiza
a mensagem observada da API do Slack em approval-checkpoints/<scenario>-pending.png e
approval-checkpoints/<scenario>-resolved.png e, em seguida, falha se algum ponto de verificação,
evidência de mensagem, confirmação ou captura de tela renderizada estiver
ausente ou vazio. Concessões frias de CI ainda podem mostrar o início de sessão
do Slack em slack-desktop-smoke.png; as imagens dos pontos de verificação de
aprovação são a comprovação visual dessa pista.
A execução padrão dos pontos de verificação mantém os dois cenários padrão de
aprovação do Slack. Para capturar qualquer uma das rotas opcionais de aprovação
do Codex, selecione-a explicitamente com --scenario slack-codex-approval-exec-native ou
--scenario slack-codex-approval-plugin-native; o Mantis aceita ambas e gera o mesmo par de capturas de tela
de estado pendente/resolvido. O executor amplia os prazos dos pontos de
verificação e dos comandos remotos para cada rota do Codex selecionada, para
que a sequência completa de aprovação, conclusão do agente e atualização do
estado resolvido possa terminar.
A lista de verificação do operador, o comando de despacho do fluxo de trabalho do GitHub, o contrato de comentários de evidência, a tabela de decisão do modo de hidratação, a interpretação dos tempos e as etapas de tratamento de falhas estão no Runbook de desktop do Slack no Mantis.
Para uma tarefa de desktop no estilo agente/visão computacional, execute:
pnpm openclaw qa mantis visual-task \ --browser-url https://example.net \ --expect-text "Example Domain" \ --vision-model openai/gpt-5.6-lunavisual-task concede ou reutiliza uma máquina Crabbox com
desktop/navegador, inicia crabbox record --while, controla o navegador visível por
meio de um visual-driver aninhado, captura visual-task.png, executa
openclaw infer image describe na captura de tela 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
solicita um veredito JSON estruturado (visible,
evidence, reason) e só é aprovado quando o modelo informa
visible: true com evidências que citam o texto esperado; uma resposta
visible: false que apenas cita o texto-alvo ainda falha na asserção. Use
--vision-mode metadata para um teste de fumaça sem modelo que comprove o
funcionamento do desktop, navegador, captura de tela e vídeo sem chamar um
provedor de compreensão de imagens. 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 falhará mesmo que o controlador visual tenha sido aprovado. Em caso de
falha, o Mantis mantém a concessão para VNC, exceto se a tarefa já tiver sido
aprovada e --keep-lease não estiver definido.
Verificação da integridade do pool de credenciais
Antes de usar credenciais ao vivo compartilhadas, execute:
pnpm openclaw qa credentials doctorO doctor verifica as variáveis de ambiente do broker Convex
(OPENCLAW_QA_CONVEX_SITE_URL, OPENCLAW_QA_CONVEX_ENDPOINT_PREFIX), valida as configurações do endpoint,
informa apenas o status definido/ausente de OPENCLAW_QA_CONVEX_SECRET_CI e
OPENCLAW_QA_CONVEX_SECRET_MAINTAINER e verifica a acessibilidade de administração/listagem quando
o segredo do mantenedor está presente.
Cobertura canônica de cenários
O taxonomy.yaml raiz define IDs de cobertura semântica. Os arquivos YAML
de cenários em qa/scenarios/ mapeiam cada cenário para esses IDs e
controlam os metadados de execução: channel é o único requisito de
canal, e profiles declaram a associação a execuções nomeadas. O
controlador de canal é uma opção de implementação intercambiável no nível da
execução. Os executores TypeScript consultam esse catálogo; eles não mantêm
inventários paralelos de cenários ou cobertura.
A saída estática de qa coverage informa o mapeamento da taxonomia para
os cenários. A comprovação real vem de qa-evidence.json, que registra o
cenário executado, os IDs de cobertura, o canal, o controlador efetivamente
usado e o resultado. Canal e controlador são dimensões do relatório, não
vocabulários adicionais de IDs de cobertura nem eixos de elegibilidade de
cenários.
Para uma pista de VM Linux descartável sem introduzir o Docker no caminho de QA, execute:
pnpm openclaw qa suite --runner multipass --scenario channel-chat-baselineIsso inicializa um convidado Multipass novo, instala as dependências, compila
o OpenClaw dentro do convidado, executa qa suite e copia o relatório
e o resumo normais de QA de volta para .artifacts/qa-e2e/... no host. Ele
reutiliza o mesmo comportamento de seleção de cenários que
qa suite no host.
Por padrão, as execuções da suíte no host e no Multipass executam vários
cenários selecionados em paralelo, com workers de Gateway isolados.
qa-channel usa por padrão simultaneidade 4, limitada pela quantidade de
cenários selecionados. Use --concurrency <count> para ajustar a quantidade de
workers ou --concurrency 1 para execução serial. Use
--pack personal-agent para executar o pacote de benchmarks do assistente pessoal
(10 cenários). O seletor de pacotes é aditivo com flags
--scenario repetidas: os cenários explícitos são executados primeiro e,
depois, os cenários do pacote são executados na ordem do pacote, com as
duplicatas removidas. Use --pack observability para selecionar os cenários
otel-trace-smoke e docker-prometheus-smoke em conjunto quando um executor de QA
personalizado já fornece a configuração do coletor OpenTelemetry.
O comando sai com código diferente de zero quando qualquer cenário falha. Use
--allow-failures quando quiser os artefatos sem um código de saída de falha.
As execuções ao vivo encaminham as entradas de autenticação de QA compatíveis
que são práticas para o convidado: chaves de provedores baseadas em variáveis
de ambiente, o caminho de configuração do provedor ao vivo de QA e
CODEX_HOME, quando presente. Mantenha --output-dir sob a raiz do
repositório para que o convidado possa gravar de volta por meio do espaço de
trabalho montado.
Referência de QA do Discord, Slack, Telegram e WhatsApp
O adaptador Matrix usa a pista descartável baseada em Docker documentada anteriormente. Discord, Slack, Telegram e WhatsApp são executados em transportes reais preexistentes, portanto sua referência está aqui.
Flags compartilhadas da CLI
Essas pistas são registradas por meio de
extensions/qa-lab/src/live-transports/shared/live-transport-cli.ts e
aceitam as mesmas flags:
| Flag | Padrão | Descrição |
|---|---|---|
--scenario <id> |
- | Executa somente este cenário. Pode ser repetida. |
--output-dir <path> |
<repo>/.artifacts/qa-e2e/<transport>-<timestamp> |
Local onde são gravados relatórios, resumos, evidências, artefatos específicos do transporte e o log de saída. 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 diretório de trabalho neutro. |
--sut-account <id> |
sut |
ID da conta temporária na configuração do Gateway de QA. |
--provider-mode <mode> |
live-frontier |
mock-openai, aimock ou live-frontier. |
--model <ref> / --alt-model <ref> |
padrão do provedor | Referências dos modelos primário/alternativo. |
--fast |
desativado | Modo rápido do provedor, quando compatível. |
--credential-source <env|convex> |
env |
Consulte Pool de credenciais do Convex. |
--credential-role <maintainer|ci> |
ci em CI, caso contrário maintainer |
Função usada quando --credential-source convex. |
--allow-failures |
desativado | Grava artefatos sem retornar um código de saída de falha quando os cenários falham. |
Cada pista sai com código diferente de zero quando qualquer cenário falha.
--allow-failures grava artefatos sem definir um código de saída de falha. O
Telegram também aceita --list-scenarios para exibir os IDs de cenários
disponíveis e sair; as outras pistas não expõem essa flag.
QA do Telegram
pnpm openclaw qa telegramTem como destino um grupo privado real do Telegram com dois bots distintos
(controlador + SUT). O bot SUT deve ter um nome de usuário do Telegram; a
observação de bot para bot funciona melhor quando ambos os bots têm o
Bot-to-Bot Communication Mode ativado em @BotFather.
Variáveis de ambiente obrigatórias quando --credential-source env:
OPENCLAW_QA_TELEGRAM_GROUP_ID- ID numérico do chat (string).OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKENOPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN
O perfil release seleciona os cenários YAML mantidos do Telegram;
all adiciona verificações opcionais de sessão, uso, cadeia de
respostas e estresse de streaming. Valores explícitos de --scenario
substituem o perfil.
channel-canarychannel-mention-gatingtelegram-help-commandtelegram-commands-commandtelegram-tools-compact-commandtelegram-whoami-commandtelegram-status-commandtelegram-repeated-command-authorizationtelegram-other-bot-command-gatingtelegram-context-commandtelegram-current-session-status-tooltelegram-tool-only-usage-footertelegram-reply-chain-exact-markertelegram-stream-final-single-messagetelegram-long-final-reuses-previewtelegram-long-final-three-chunks
O perfil release sempre abrange canário, controle por menção, respostas de comandos
nativos, endereçamento de comandos e respostas entre bots em grupos. mock-openai
também inclui a verificação determinística da prévia final longa.
telegram-current-session-status-tool e
telegram-tool-only-usage-footer continuam opcionais: o primeiro só é estável
quando encadeado diretamente após o canário, e o segundo é uma comprovação no Telegram real
do rodapé /usage em respostas somente de ferramentas. Use pnpm openclaw qa telegram --list-scenarios --provider-mode mock-openai para imprimir a divisão
atual entre padrão/opcional com referências de regressão. Use --profile all em todos os
cenários do adaptador ativo do Telegram.
Artefatos de saída:
qa-suite-report.mdqa-suite-summary.jsonqa-evidence.json- entradas de evidência para as verificações do transporte ativo, incluindo campos de perfil, cobertura, provedor, canal, artefatos, resultado e RTT.
As execuções do pacote para Telegram usam o mesmo contrato de credenciais do Telegram. A medição
repetida de RTT faz parte da faixa ativa normal do pacote para Telegram; a distribuição
de RTT é incorporada a qa-evidence.json em result.timing para a
verificação de RTT selecionada.
OPENCLAW_QA_CREDENTIAL_SOURCE=convex \pnpm test:docker:npm-telegram-liveQuando OPENCLAW_QA_CREDENTIAL_SOURCE=convex está definido, o wrapper ativo do pacote
obtém por concessão uma credencial kind: "telegram", exporta as variáveis de ambiente do grupo, driver e bot
SUT concedidos para a execução do pacote instalado, envia Heartbeats para a concessão e a libera
no encerramento. Por padrão, o wrapper do pacote executa 20 verificações de RTT de
channel-canary, usa um tempo limite de RTT de 30s e a função do Convex
maintainer fora da CI quando o Convex está selecionado. Substitua
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 de RTT separado ou um formato de resumo específico do Telegram.
QA do Discord
pnpm openclaw qa discordTem como alvo um canal privado real de uma guilda 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 do Discord incluído. Verifica o tratamento de menções no canal, se
o bot SUT registrou o comando nativo /help no Discord e
cenários opcionais de evidência do Mantis.
Variáveis de ambiente obrigatórias quando --credential-source env:
OPENCLAW_QA_DISCORD_GUILD_IDOPENCLAW_QA_DISCORD_CHANNEL_IDOPENCLAW_QA_DISCORD_DRIVER_BOT_TOKENOPENCLAW_QA_DISCORD_SUT_BOT_TOKENOPENCLAW_QA_DISCORD_SUT_APPLICATION_ID- deve corresponder ao ID de usuário do bot SUT retornado pelo Discord (caso contrário, a faixa falha imediatamente).
Opcional:
OPENCLAW_QA_DISCORD_VOICE_CHANNEL_IDseleciona o canal de voz/palco paradiscord-voice-autojoin; sem ele, o cenário seleciona o primeiro canal de voz/palco visível para o bot SUT.
Cenários de módulo YAML do Discord (qa/scenarios/channels/discord-*.yaml):
discord-canarydiscord-mention-gatingdiscord-native-help-command-registrationdiscord-voice-autojoin- cenário de voz opcional. É executado isoladamente, habilitachannels.discord.voice.autoJoine verifica se o estado de voz atual do bot SUT no Discord corresponde ao canal de voz/palco de destino. As credenciais do Discord no Convex podem incluirvoiceChannelIdopcionalmente; caso contrário, o adaptador do executor descobre o primeiro canal de voz/palco visível na guilda.discord-status-reactions-tool-only- cenário opcional do Mantis. É executado isoladamente porque muda o SUT para respostas sempre ativas e somente de ferramentas na guilda commessages.statusReactions.enabled=truee, em seguida, captura uma linha do tempo de reações via REST, além de artefatos visuais HTML/PNG. Os relatórios do Mantis de antes/depois também preservam os artefatos MP4 fornecidos pelo cenário comobaseline.mp4ecandidate.mp4.discord-thread-reply-filepath-attachment- cenário opcional do Mantis; consulte Cenários do Mantis no Discord.
Execute explicitamente o cenário de entrada automática em voz do Discord:
pnpm openclaw qa discord \ --scenario discord-voice-autojoin \ --provider-mode mock-openaiExecute 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.6-luna \ --alt-model openai/gpt-5.6-luna \ --fastArtefatos de saída:
qa-suite-report.mdqa-suite-summary.jsonqa-evidence.json- entradas de evidência para as verificações do transporte ativo.discord-qa-reaction-timelines.jsonediscord-status-reactions-tool-only-timeline.pngquando o cenário de reações de status é executado.
QA do Slack
pnpm openclaw qa slackTem 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 do Slack incluído.
Variáveis de ambiente obrigatórias quando --credential-source env:
OPENCLAW_QA_SLACK_CHANNEL_IDOPENCLAW_QA_SLACK_DRIVER_BOT_TOKENOPENCLAW_QA_SLACK_SUT_BOT_TOKENOPENCLAW_QA_SLACK_SUT_APP_TOKEN
Opcional:
OPENCLAW_QA_SLACK_APPROVAL_CHECKPOINT_DIRhabilita pontos de verificação de aprovação visual para o Mantis. O adaptador grava<scenario>.pending.jsone<scenario>.resolved.jsone, em seguida, aguarda os arquivos.ack.jsoncorrespondentes.OPENCLAW_QA_SLACK_APPROVAL_CHECKPOINT_TIMEOUT_MSsubstitui o tempo limite de confirmação do ponto de verificação. O padrão é120000.
Cenários YAML canônicos expostos pelo adaptador ativo do Slack:
thread-follow-upthread-isolation
Cenários de módulo YAML do Slack (qa/scenarios/channels/slack-*.yaml):
slack-canaryslack-mention-gatingslack-allowlist-blockslack-channel-disabled-warning- sondagem opcional no Slack real que confirma que um canal configurado como desabilitado emite um aviso estruturado sem responder.slack-top-level-reply-shapeslack-restart-resumeslack-progress-commentary-true,slack-progress-commentary-false,slack-progress-commentary-omittedeslack-progress-commentary-verbose-dedupe- sondagens opcionais no Slack real para controles independentes de comentários/progresso de ferramentas, o padrão legado quando a chave é omitida e o comportamento de entrega única quando o progresso detalhado durável está ativado.slack-reaction-glyph-native- cenário opcional ativo de reação da ferramenta de mensagens. Instrui o agente a transmitir exatamente o glifo✅e confirma que o Slack armazenouwhite_check_markpara o bot SUT na mensagem de destino.slack-chart-presentation-native- cenário opcional de gráfico portátil que verifica o bloco nativodata_visualizatione o texto acessível exato.slack-table-presentation-native- cenário opcional de tabela portátil que verifica o bloco nativodata_table, as linhas exatas e o texto acessível.slack-table-invalid-blocks-fallback- cenário opcional de transporte direto que envia uma tabela bruta estruturalmente legível acima do limite, com 101 linhas de dados além do cabeçalho, pelo caminho de envio do Slack em produção, comprova que o próprio Slack retornainvalid_blockse verifica se o fallback armazenado com formatação desabilitada está completo e não contém nenhum bloco de dados nativo. Os detalhes do cenário mantêm apenas evidências seguras de código de erro, contagem e valores booleanos.slack-approval-exec-native- cenário opcional de aprovação nativa de execução no Slack. Solicita uma aprovação de execução pelo Gateway, verifica se a mensagem do Slack contém botões nativos de aprovação, resolve a solicitação e verifica a atualização resolvida no Slack.slack-approval-plugin-native- cenário opcional de aprovação nativa de Plugin no Slack. Habilita simultaneamente o encaminhamento de aprovações de execução e de Plugin para que os eventos de Plugin não sejam suprimidos pelo roteamento de aprovações de execução e, em seguida, verifica o mesmo fluxo de interface nativa pendente/resolvido no Slack.slack-codex-approval-exec-native- cenário de aprovação de comandos do Codex Guardian opcional. Habilita o Plugin do Codex no modo Guardian, encaminha um turno de agente do Gateway originado no Slack pelo harness do servidor de aplicativo do Codex, aguarda a solicitação nativa de aprovação do Plugin no Slack paraopenclaw-codex-app-server, resolve-a e verifica se o turno do Codex termina com os marcadores esperados de saída de comando e do assistente.slack-codex-approval-plugin-native- cenário de aprovação de arquivos do Codex Guardian opcional. Usa uma instruçãoapply_patchfora do espaço de trabalho para que o Codex emita a rota de aprovação de alteração de arquivo do servidor de aplicativo e, em seguida, verifica o mesmo fluxo nativo de aprovação pendente/resolvido no Slack, o marcador final do assistente e o conteúdo exato do arquivo antes da limpeza.
Os cenários de aprovação do Codex exigem um openai/* ou codex/* --model, as
credenciais normais do modelo ativo e autenticação do Codex ou autenticação por chave de API aceita pelo Plugin do Codex.
Os detalhes do cenário incluem o método do servidor de aplicativo do Codex, a chave do modelo
Codex selecionado, o status final do turno do Codex e a verificação do marcador de operação, além dos
metadados de aprovação redigidos do Slack.
Artefatos de saída:
qa-suite-report.mdqa-suite-summary.jsonqa-evidence.json- entradas de evidência para as verificações do transporte ativo.approval-checkpoints/- somente quando o Mantis defineOPENCLAW_QA_SLACK_APPROVAL_CHECKPOINT_DIR; contém o JSON do ponto de verificação, o JSON de confirmação e capturas de tela pendentes/resolvidas.
Configuração do workspace do Slack
A faixa precisa de dois aplicativos distintos do Slack em um workspace, além de um canal do qual ambos os bots sejam membros:
channelId- o IDCxxxxxxxxxxde um canal para o qual ambos os bots foram convidados. Use um canal dedicado; a faixa publica mensagens a cada execução.driverBotToken- token do bot (xoxb-...) do aplicativo Driver.sutBotToken- token do bot (xoxb-...) do aplicativo SUT, que deve ser um aplicativo Slack diferente do driver para que seu ID de usuário do bot seja distinto.sutAppToken- token no nível do aplicativo (xapp-...) do aplicativo SUT comconnections:write, usado pelo Socket Mode para que o aplicativo SUT possa receber eventos.
Prefira um workspace do Slack dedicado a QA em vez de reutilizar um workspace de produção.
O manifesto do SUT abaixo restringe intencionalmente a instalação de produção do
Plugin do Slack incluído (extensions/slack/src/setup-shared.ts:12) às
permissões e aos eventos abrangidos pelo conjunto ativo de QA do Slack. Para a
configuração do canal de produção como os usuários a veem, consulte
Configuração rápida do canal do Slack; o par Driver/SUT de QA
é intencionalmente separado porque a faixa precisa de dois IDs distintos de usuários
de bot em um workspace.
1. Crie o aplicativo Driver
Acesse api.slack.com/apps → Create New App → From a manifest → escolha o workspace de QA, cole o manifesto a seguir e, em seguida, selecione Install to Workspace:
{ "display_information": { "name": "OpenClaw QA Driver", "description": "Bot driver de teste para a faixa ativa de QA do Slack no OpenClaw" }, "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 Bot User OAuth Token (xoxb-...) — ele se torna
driverBotToken. O driver só precisa publicar mensagens e identificar
a si mesmo; sem eventos e sem Socket Mode.
2. Crie o aplicativo SUT
Repita Create New App → From a manifest no mesmo workspace. Este aplicativo de QA
usa intencionalmente uma versão mais restrita do manifesto de produção do
Plugin do Slack incluído (extensions/slack/src/setup-shared.ts:12): escopos
e eventos de reação são omitidos porque o conjunto ativo de QA do Slack ainda não abrange
o tratamento de reações.
{ "display_information": { "name": "OpenClaw QA SUT", "description": "Conector OpenClaw QA SUT para o 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 aplicativo, faça duas coisas na página de configurações:
- Install to Workspace → copie o Bot User OAuth Token → ele se torna
sutBotToken. - Basic Information → App-Level Tokens → Generate Token and Scopes → adicione o
escopo
connections:write→ salve → copie o valorxapp-...→ ele se tornasutAppToken.
Verifique se os dois bots têm IDs de usuário distintos chamando auth.test em cada
token. O runtime diferencia o driver e o SUT pelo ID de usuário; reutilizar um aplicativo
para ambos fará o bloqueio por menção falhar imediatamente.
3. Crie o canal
No workspace de QA, crie um canal (por exemplo, #openclaw-qa) e convide os dois
bots de dentro do canal:
/invite @OpenClaw QA Driver/invite @OpenClaw QA SUTCopie o ID Cxxxxxxxxxx em channel info → About → Channel ID — ele
se torna channelId. Um canal público funciona; se usar um canal privado,
ambos os aplicativos já têm groups:history, portanto as leituras de histórico do harness
ainda serão bem-sucedidas.
4. Registre as credenciais
Há 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 inicialize
o pool compartilhado do Convex para que a CI e outros mantenedores possam alugá-las.
Para o pool do Convex, grave 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 shell, registre e verifique:
pnpm openclaw qa credentials add \ --kind slack \ --payload-file slack-creds.json \ --note "Semente do pool de QA do Slack" pnpm openclaw qa credentials list --kind slack --status all --jsonEspere count: 1, status: "active", sem o campo lease.
5. Verifique de ponta a ponta
Execute a lane localmente para confirmar que os dois bots conseguem se comunicar por meio do broker:
pnpm openclaw qa slack \ --credential-source convex \ --credential-role maintainer \ --output-dir .artifacts/qa-e2e/slack-localUma execução bem-sucedida termina em bem menos de 30 segundos, e qa-suite-report.md
mostra slack-canary e slack-mention-gating com o status pass. Se a
lane ficar travada por cerca de 90 segundos e encerrar com Convex credential pool exhausted for kind "slack", o pool está vazio ou todas as linhas estão alugadas — qa credentials list --kind slack --status all --json indicará qual é o caso.
QA do WhatsApp
pnpm openclaw qa whatsappTem como alvo duas contas dedicadas do WhatsApp Web: uma conta de driver controlada pelo harness e uma conta SUT iniciada pelo Gateway filho do OpenClaw por meio do Plugin integrado do WhatsApp.
Variáveis de ambiente obrigatórias quando --credential-source env:
OPENCLAW_QA_WHATSAPP_DRIVER_PHONE_E164OPENCLAW_QA_WHATSAPP_SUT_PHONE_E164OPENCLAW_QA_WHATSAPP_DRIVER_AUTH_ARCHIVE_BASE64OPENCLAW_QA_WHATSAPP_SUT_AUTH_ARCHIVE_BASE64
Opcional:
OPENCLAW_QA_WHATSAPP_GROUP_JIDhabilita cenários de grupo, comowhatsapp-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ções/mídia/enquetes em grupo ewhatsapp-group-allowlist-block.
Cenários YAML do WhatsApp (qa/scenarios/channels/whatsapp-*.yaml):
- Linha de base e bloqueio de 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-reactcomeça em uma DM real do driver, permite que o modelo chame a ferramentamessagee observa a reação nativa do WhatsApp.whatsapp-agent-message-action-upload-fileusa a mesma abordagem paramessage(action=upload-file)e observa mídia nativa do WhatsApp.whatsapp-group-agent-message-action-reactewhatsapp-group-agent-message-action-upload-filecomprovam as mesmas ações visíveis ao usuário em um grupo real do WhatsApp. - Distribuição em grupo:
whatsapp-broadcast-group-fanoutcomeça com uma mensagem de grupo do WhatsApp contendo uma menção e verifica respostas visíveis distintas demaineqa-second. - Ativação de grupo:
whatsapp-group-activation-alwaysaltera uma sessão real de grupo para/activation always, comprova que uma mensagem de grupo sem menção desperta o agente e depois restaura/activation mention.whatsapp-group-reply-to-bot-triggerscria uma resposta inicial do bot, envia uma resposta nativa com citação para ela sem uma menção explícita e verifica se o agente desperta com base nesse 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 driver. - Sondagens diretas do contrato do Gateway:
whatsapp-outbound-media-matrix,whatsapp-outbound-document-preserves-filename,whatsapp-outbound-poll,whatsapp-outbound-send-serialization,whatsapp-group-outbound-media,whatsapp-group-outbound-poll,whatsapp-message-actions,whatsapp-reply-context-isolation,whatsapp-reply-delivery-shape. Elas ignoram intencionalmente o prompting do modelo e comprovam deterministicamente os contratossend,pollemessage.actiondo Gateway/canal. - Cobertura do 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 52 cenários. A lane padrão live-frontier
é mantida pequena, com 8 cenários, para uma cobertura rápida de smoke test. A lane
padrão mock-openai executa deterministicamente 39 cenários pelo transporte real do WhatsApp,
simulando apenas a saída do modelo; os cenários de aprovação e algumas
verificações mais pesadas/bloqueantes continuam explícitos pelo ID do cenário.
O driver de QA do WhatsApp observa eventos estruturados em tempo real (text, media,
location, reaction e poll) e pode enviar ativamente mídia, enquetes,
contatos, localizações e figurinhas. O QA Lab importa esse driver 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 participante remetente.
O conteúdo das mensagens é ocultado por padrão. As sondagens diretas do Gateway de enquete, upload 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 do usuário fez o
agente escolher a mesma ação. A comprovação de ações 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 driver envia uma mensagem
normal do WhatsApp e o QA Lab observa o artefato nativo do WhatsApp resultante.
Os detalhes dos cenários do WhatsApp incluem a abordagem de cada cenário (user-path,
direct-gateway ou native-approval) para que as evidências não sejam confundidas com um
contrato mais forte do que aquele que realmente comprovam.
Artefatos de saída:
qa-suite-report.mdqa-suite-summary.jsonqa-evidence.json— entradas de evidência para as verificações de transporte em tempo real.
Pool de credenciais do Convex
As lanes do Discord, Slack, Telegram e WhatsApp podem alugar credenciais 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 uma locação exclusiva, envia Heartbeats durante a
execução e a libera ao encerrar. Os tipos do pool são "discord", "slack",
"telegram" e "whatsapp".
Formatos de payload que o broker valida em admin/add:
- Discord (
kind: "discord"):{ guildId: string, channelId: string, driverBotToken: string, sutBotToken: string, sutApplicationId: string }. - Telegram (
kind: "telegram"):{ groupId: string, driverToken: string, sutToken: string }—groupIddeve ser uma string numérica de ID de chat. - 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 para comprovação pelo Telegram Desktop do Mantis. As lanes genéricas do QA Lab não devem adquirir esse tipo. - 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 comprovação pelo Telegram Desktop do Mantis mantém uma locação exclusiva
telegram-user do Convex tanto para o driver da CLI do TDLib quanto para a testemunha do Telegram Desktop
e a libera após publicar a comprovação.
Quando um PR precisa de um diff visual determinístico, o Mantis pode usar a mesma resposta
simulada do modelo em main e no head do PR enquanto o formatador ou
a camada de entrega do Telegram muda. Os padrões de captura são ajustados para comentários em PRs: classe
padrão do Crabbox, gravação da área de trabalho a 24fps, GIF de movimento a 24fps e prévia com
1920px de largura. Os comentários de antes/depois devem publicar um pacote limpo que contenha
apenas os GIFs pretendidos.
As lanes do Slack também podem usar o pool. Atualmente, as verificações do formato de payload do Slack ficam
no executor de QA do Slack, e não no broker; use { channelId: string, driverBotToken: string, sutBotToken: string, sutAppToken: string }, com um
ID de canal do Slack como Cxxxxxxxxxx. Consulte
Como configurar o workspace do Slack para o provisionamento
do aplicativo e dos escopos.
As variáveis de ambiente operacionais e o contrato do endpoint do broker do Convex estão em Testes → Credenciais compartilhadas do Telegram via Convex (o nome da seção é anterior ao pool multicanal; a semântica de locação é compartilhada entre os tipos).
Sementes armazenadas no repositório
Os ativos de semente ficam em qa/:
qa/scenarios/index.yamlqa/scenarios/<theme>/*.yaml
Eles são mantidos intencionalmente no git para que o plano de QA seja visível tanto para pessoas quanto para o agente.
qa-lab continua sendo 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:
titleno nível superior- metadados de
scenario - metadados opcionais de categoria, capacidade, lane e risco em
scenario - referências de documentação e código em
scenario - requisitos opcionais de Plugin em
scenario - patch opcional da configuração do Gateway em
scenario flowexecutável no nível superior para cenários de fluxo, ouscenario.execution.kind/scenario.execution.pathpara cenários do Vitest e Playwright
A superfície de runtime reutilizável que sustenta flow permanece genérica e
transversal. Por exemplo, os cenários YAML podem combinar auxiliares do lado
do transporte com auxiliares do lado do navegador que controlam a Control UI
incorporada por meio da interface browser.request do Gateway, sem adicionar
um executor para casos especiais.
Os arquivos de cenário devem ser agrupados por capacidade do produto, e não
pela pasta da árvore de código-fonte. Mantenha os IDs dos cenários estáveis
quando os arquivos forem movidos; use docsRefs e
codeRefs para rastreabilidade da implementação.
A lista de referência deve permanecer ampla o suficiente para abranger:
- DM e conversa em canal
- comportamento de threads
- ciclo de vida das ações de mensagem
- callbacks de Cron
- recuperação de memória
- troca de modelo
- transferência para subagente
- leitura de repositório e documentação
- uma pequena tarefa de compilação, como Lobster Invaders
Faixas de simulação de provedores
qa suite tem duas faixas locais de simulação de provedores:
mock-openaié a simulação do OpenClaw com reconhecimento de cenários. Ela permanece como a faixa de simulação determinística padrão para QA baseada em repositório e verificações de paridade.aimockinicia um servidor de provedor baseado no AIMock para cobertura experimental de protocolo, fixtures, gravação/reprodução e caos. Ela é adicional e não substitui o despachante de cenáriosmock-openai.
A implementação das faixas de provedores fica em extensions/qa-lab/src/providers/.
Cada provedor é responsável por seus padrões, inicialização do servidor local,
configuração do modelo no Gateway, necessidades de preparação do perfil de
autenticação e sinalizadores de capacidade ao vivo/simulada. O código
compartilhado da suíte e do Gateway faz o roteamento pelo registro de
provedores, em vez de criar ramificações com base nos nomes dos provedores.
Adaptadores de transporte
qa-lab fornece uma interface genérica de transporte para cenários de QA em YAML. qa-channel é
o padrão sintético. crabline inicia servidores locais com o formato dos provedores e
executa os plugins de canal normais do OpenClaw contra eles. live é reservado para
credenciais reais de provedores e canais externos.
No nível da arquitetura, a divisão é:
qa-labé responsável pela execução genérica de cenários, concorrência dos workers, gravação de artefatos e geração de relatórios.- O adaptador de transporte é responsável pela configuração do Gateway, prontidão, observação de entrada e saída, ações de transporte e estado normalizado do transporte.
- Os arquivos de cenário YAML em
qa/scenarios/definem a execução do teste;qa-labfornece a superfície de runtime reutilizável que os executa.
Como adicionar um canal
Adicionar um canal ao sistema de QA em YAML exige a implementação do canal,
além de um pacote de cenários que exercite o contrato do canal. Para cobertura
de fumaça em CI, adicione o servidor local do provedor Crabline correspondente
e exponha-o por meio do driver crabline.
Não adicione uma nova raiz de comandos de QA de nível superior quando o host
compartilhado qa-lab puder controlar o fluxo.
qa-lab é responsável pela mecânica do host compartilhado:
- a raiz de comandos
openclaw qa - inicialização e encerramento da suíte
- concorrência dos workers
- gravação de artefatos
- geração de relatórios
- execução de cenários
- aliases de compatibilidade para cenários
qa-channelmais antigos
Os plugins de execução são responsáveis pelo contrato de transporte:
- como
openclaw qa <runner>é montado sob a raiz compartilhadaqa - como o Gateway é configurado para esse transporte
- como a prontidão é verificada
- como os eventos de entrada são injetados
- como as mensagens de saída são observadas
- como as transcrições e o estado normalizado do transporte são expostos
- como as ações baseadas em transporte são executadas
- como a redefinição ou limpeza específica do transporte é tratada
Os requisitos mínimos de adoção para um novo canal:
- Mantenha
qa-labcomo responsável pela raiz compartilhadaqa. - Implemente o executor de transporte na interface de host compartilhada
qa-lab. - Mantenha a mecânica específica do transporte dentro do plugin de execução ou do harness do canal.
- Monte o executor como
openclaw qa <runner>, em vez de registrar uma raiz de comandos concorrente. Os plugins de execução devem declararqaRunnersemopenclaw.plugin.jsone exportar um arrayqaRunnerCliRegistrationscorrespondente deruntime-api.ts. Mantenharuntime-api.tsleve; a CLI com carregamento tardio e a execução do executor devem permanecer atrás de pontos de entrada separados. UmadapterFactoryopcional expõe o transporte aos cenários compartilhados sem alterar o catálogo de cenários existente do comando. - Crie ou adapte cenários YAML nos diretórios temáticos
qa/scenarios/. - Use os auxiliares genéricos de cenário para novos cenários.
- Mantenha os aliases de compatibilidade existentes funcionando, a menos que o repositório esteja realizando uma migração intencional.
A regra de decisão é estrita:
- Se um comportamento puder ser expresso uma única vez em
qa-lab, coloque-o emqa-lab. - Se um comportamento depender do transporte de um canal, mantenha-o no plugin de execução ou no harness desse plugin.
- Se um cenário precisar de uma nova capacidade que possa ser usada por mais de um canal,
adicione um auxiliar genérico em vez de uma ramificação específica do 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 dos auxiliares de cenário
Auxiliares genéricos preferenciais para novos cenários:
waitForTransportReadywaitForChannelReadyinjectInboundMessageinjectOutboundMessagewaitForTransportOutboundMessagewaitForChannelOutboundMessagewaitForNoTransportOutboundgetTransportSnapshotreadTransportMessagereadTransportTranscriptformatTransportTranscriptresetTransport
Os aliases de compatibilidade continuam disponíveis para cenários existentes —
waitForQaChannelReady, waitForOutboundMessage, waitForNoOutbound,
formatConversationTranscript, resetBus —, mas a criação de novos cenários
deve usar os nomes genéricos. Os aliases existem para evitar uma migração
simultânea e disruptiva, não como o modelo a ser seguido daqui em diante.
Relatórios
qa-lab exporta um relatório de protocolo em Markdown a partir da linha do tempo observada no barramento.
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 obter o inventário de cenários disponíveis — útil ao dimensionar o trabalho
de acompanhamento ou conectar um novo transporte —, execute pnpm openclaw qa coverage (adicione --json
para obter saída legível por máquina). Ao escolher uma comprovação focada para um
comportamento ou caminho de arquivo alterado, execute pnpm openclaw qa coverage --match <query>. O
relatório de correspondências pesquisa metadados de cenários, referências da documentação, referências de código, IDs de cobertura,
plugins e requisitos de provedores e, em seguida, exibe os alvos qa suite --scenario ... correspondentes.
Cada execução de qa suite grava os artefatos de nível superior qa-evidence.json,
qa-suite-summary.json e qa-suite-report.md para o conjunto de
cenários selecionado. Os 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. Os cenários que declaram execution.kind: script executam o
produtor de evidências em execution.path por meio de 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 suíte e cujos caminhos de artefatos são resolvidos em relação ao
qa-evidence.json desse produtor. Quando qa suite é alcançado por meio de qa run --qa-profile, o mesmo qa-evidence.json também inclui o resumo
do scorecard do perfil para as categorias de taxonomia selecionadas.
Trate a saída de cobertura como um auxílio de descoberta, não como substituta de uma verificação; o cenário selecionado ainda precisa do modo de provedor, transporte ao vivo, Multipass, Testbox ou faixa de lançamento apropriado para o comportamento em teste. Para obter o contexto do scorecard, consulte Scorecard de maturidade.
Para verificações de personalidade e estilo, execute o mesmo cenário em várias referências de modelos ao vivo e grave um relatório Markdown avaliado:
pnpm openclaw qa character-eval \ --model openai/gpt-5.6-luna,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.6-sol,thinking=xhigh,fast \ --judge-model anthropic/claude-opus-4-8,thinking=high \ --blind-judge-models \ --concurrency 16 \ --judge-concurrency 16O comando executa processos filhos locais do Gateway de QA, não o Docker. Os cenários
de avaliação de personalidade devem definir a persona por meio de SOUL.md e, em seguida, executar interações
comuns do usuário, como conversa, ajuda com o workspace e pequenas tarefas com arquivos. 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, em seguida, solicita aos modelos avaliadores no
modo rápido, com raciocínio xhigh quando houver suporte, que classifiquem as execuções por
naturalidade, estilo e humor. Use --blind-judge-models ao comparar
provedores: o prompt do avaliador ainda recebe todas as transcrições e os status das execuções, mas
as referências dos candidatos são substituídas por rótulos neutros, como candidate-01; o
relatório associa as classificações novamente às referências reais após a análise.
As execuções dos candidatos usam por padrão o raciocínio high, com medium para o GPT-5.6 Luna e
xhigh para referências de avaliação mais antigas da OpenAI que ofereçam suporte. Substitua a configuração de um
candidato específico diretamente com --model provider/model,thinking=<level>; as
opções embutidas também oferecem suporte a fast, no-fast e fast=<bool>. --thinking <level> ainda define uma opção global de fallback, e a forma
mais antiga --model-thinking <provider/model=level> é mantida para compatibilidade. As referências de candidatos da OpenAI
usam o modo rápido por padrão, para que o processamento prioritário seja usado quando o provedor
oferecer suporte. Passe --fast somente quando quiser forçar a ativação do modo rápido para
todos os modelos candidatos. As durações dos candidatos e avaliadores são registradas no
relatório para análise de benchmark, mas os prompts dos avaliadores dizem explicitamente para não classificar
por velocidade. As execuções dos modelos candidatos e avaliadores usam concorrência 16 por padrão.
Reduza --concurrency ou --judge-concurrency quando os limites do provedor ou a pressão sobre o
Gateway local tornarem uma execução ruidosa demais.
Quando nenhuma referência de candidato --model for passada, a avaliação de personalidade usa por padrão
openai/gpt-5.6-luna, 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
--judge-model for passado, os avaliadores usam por padrão
openai/gpt-5.6-sol,thinking=xhigh,fast e
anthropic/claude-opus-4-8,thinking=high.