extensions/qa-channel: синтетический канал сообщений с поверхностями DM, канала, темы, реакции, редактирования и удаления.extensions/qa-lab: UI отладчика и шина QA для наблюдения за транскриптом, внедрения входящих сообщений и экспорта Markdown-отчета.extensions/qa-matrix, будущие Plugin раннеров: адаптеры живых транспортов, которые управляют реальным каналом внутри дочернего QA gateway.qa/: seed-ресурсы из репозитория для стартовой задачи и базовых QA-сценариев.- Mantis: проверка до и после live-верификации для ошибок, которым нужны реальные транспорты, скриншоты браузера, состояние VM и доказательства PR.
Поверхность команд
Каждый QA-поток выполняется черезpnpm openclaw qa <subcommand>. У многих есть
алиасы скриптов pnpm qa:*; поддерживаются обе формы.
| Команда | Назначение |
|---|---|
qa run | Встроенная QA самопроверка без --qa-profile; раннер профиля зрелости на основе таксономии с --qa-profile smoke-ci, --qa-profile release или --qa-profile all. |
qa suite | Запускает сценарии из репозитория в QA gateway lane. Алиасы: pnpm openclaw qa suite --runner multipass для одноразовой Linux VM. |
qa coverage | Выводит YAML-инвентарь покрытия сценариев (--json для машинного вывода). |
qa parity-report | Сравнивает два файла qa-suite-summary.json и записывает agentic-отчет о паритете либо использует --runtime-axis --token-efficiency, чтобы записать отчеты о паритете runtime Codex-vs-OpenClaw и эффективности токенов из одной сводки пары runtime. |
qa character-eval | Запускает character QA-сценарий на нескольких live-моделях с оцененным отчетом. См. Отчетность. |
qa manual | Запускает разовый prompt в выбранной provider/model lane. |
qa ui | Запускает UI QA отладчика и локальную QA-шину (алиас: pnpm qa:lab:ui). |
qa docker-build-image | Собирает предварительно подготовленный Docker-образ QA. |
qa docker-scaffold | Записывает docker-compose scaffold для QA dashboard + gateway lane. |
qa up | Собирает QA-сайт, запускает стек на Docker и выводит URL (алиас: pnpm qa:lab:up; вариант :fast добавляет --use-prebuilt-image --bind-ui-dist --skip-ui-build). |
qa aimock | Запускает только сервер провайдера AIMock. |
qa mock-openai | Запускает только сервер провайдера mock-openai, учитывающий сценарии. |
qa credentials doctor / add / list / remove | Управляет общим пулом учетных данных Convex. |
qa matrix | Live transport lane против одноразового Tuwunel homeserver. См. Matrix QA. |
qa telegram | Live transport lane против реальной приватной группы Telegram. |
qa discord | Live transport lane против реального приватного канала гильдии Discord. |
qa slack | Live transport lane против реального приватного канала Slack. |
qa whatsapp | Live transport lane против реальных аккаунтов WhatsApp Web. |
qa mantis | Раннер проверки до и после для ошибок live transport, с доказательствами Discord status-reactions, Crabbox desktop/browser smoke и Slack-in-VNC smoke. См. Mantis и Runbook Mantis Slack Desktop. |
qa run с профилями читает состав из taxonomy.yaml, затем отправляет
разрешенные сценарии через qa suite. --surface и
--category фильтруют выбранный профиль, а не определяют отдельные lane.
Полученный qa-evidence.json включает сводку scorecard профиля с
количеством выбранных категорий и ID отсутствующего покрытия; отдельные записи
доказательств остаются источником истины для тестов, ролей покрытия и результатов.
ID покрытия функций таксономии являются точными целями доказательства, а не псевдонимами. Основное
покрытие сценариев выполняет совпадающие ID; вторичное покрытие остается рекомендационным.
ID покрытия используют dotted-форму namespace.behavior со строчными
буквенно-цифровыми сегментами или сегментами с дефисом; ID профилей, поверхностей и категорий могут по-прежнему использовать
существующие dashed или dotted ID таксономии.
Slim-доказательства опускают execution для каждой записи и задают evidenceMode: "slim";
smoke-ci по умолчанию использует slim, а --evidence-mode full восстанавливает полные записи:
smoke-ci для детерминированного доказательства профиля с mock model providers и
Crabline fake provider servers. Используйте release для доказательства Stable/LTS на live
channels. Используйте all только для явных полных прогонов доказательств по всей таксономии; он выбирает
каждую активную категорию зрелости и может запускаться через workflow QA Profile Evidence с qa_profile=all. Когда команде также нужен корневой профиль OpenClaw,
поместите корневой профиль перед командой QA:
Поток оператора
Текущий поток QA-оператора — это двухпанельный QA-сайт:- Слева: Gateway dashboard (Control UI) с агентом.
- Справа: QA Lab, показывающий Slack-подобный транскрипт и план сценария.
qa:lab:up:fast оставляет Docker-сервисы на предварительно собранном образе и bind-mount
extensions/qa-lab/web/dist в контейнер qa-lab. qa:lab:watch
пересобирает этот bundle при изменениях, а браузер автоматически перезагружается при изменении
asset hash QA Lab.
Для локального OpenTelemetry signal smoke выполните:
otel-trace-smoke
с включенным Plugin diagnostics-otel, затем проверяет, что traces,
metrics и logs экспортированы. Он декодирует экспортированные protobuf trace spans
и проверяет критичную для релиза форму:
openclaw.run, openclaw.harness.run, latest GenAI semantic-convention
model-call span, openclaw.context.assembled и openclaw.message.delivery
должны присутствовать. Smoke принудительно задает
OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental, поэтому model-call
span должен использовать имя {gen_ai.operation.name} {gen_ai.request.model};
model calls не должны экспортировать StreamAbandoned при успешных turns; raw diagnostic IDs и
атрибуты openclaw.content.* не должны попадать в trace. Raw OTLP
payloads не должны содержать prompt sentinel, response sentinel или QA session
key. Он записывает otel-smoke-summary.json рядом с артефактами QA suite.
Для OpenTelemetry smoke через collector выполните:
docker-prometheus-smoke с включенным
diagnostics-prometheus, проверяет, что неаутентифицированные scrape-запросы отклоняются,
а затем проверяет, что аутентифицированный scrape включает критически важные для релиза семейства метрик
без содержимого промптов, содержимого ответов, необработанных диагностических идентификаторов, токенов
аутентификации или локальных путей.
Чтобы запустить оба smoke-теста наблюдаемости подряд, используйте:
qa. Используйте
pnpm qa:otel:smoke, pnpm qa:prometheus:smoke или
pnpm qa:observability:smoke из собранной рабочей копии исходного кода при изменении
диагностической инструментализации.
Для Matrix smoke-пути с реальным транспортом, которому не требуются учетные данные
провайдера моделей, запустите быстрый профиль с детерминированным mock-провайдером OpenAI:
qa-channel), затем записывает Markdown-отчет, JSON-сводку, артефакт наблюдаемых событий и объединенный лог вывода в .artifacts/qa-e2e/matrix-<timestamp>/.
Сценарии покрывают поведение транспорта, которое unit-тесты не могут доказать сквозным образом: фильтрацию по упоминаниям, политики allow-bot, allowlist, ответы верхнего уровня и в тредах, маршрутизацию DM, обработку реакций, подавление входящих правок, дедупликацию воспроизведения после перезапуска, восстановление после прерывания homeserver, доставку метаданных approval, обработку медиа и потоки начальной настройки, восстановления и проверки Matrix E2EE. Профиль CLI для E2EE также прогоняет openclaw matrix encryption setup и команды проверки через тот же одноразовый homeserver перед проверкой ответов Gateway.
У Discord также есть opt-in сценарии только для Mantis для воспроизведения багов. Используйте
--scenario discord-status-reactions-tool-only для явной временной шкалы реакций статуса
или --scenario discord-thread-reply-filepath-attachment, чтобы создать реальный тред Discord
и проверить, что message.thread-reply сохраняет вложение filePath. Эти сценарии не входят в
стандартный live-путь Discord, потому что это пробы воспроизведения до/после, а не широкое smoke-покрытие.
Mantis workflow для вложения в треде также может добавить witness-видео из Discord Web с выполненным входом,
когда MANTIS_DISCORD_VIEWER_CHROME_PROFILE_DIR или
MANTIS_DISCORD_VIEWER_CHROME_PROFILE_TGZ_B64 настроен в QA-окружении. Этот viewer profile предназначен
только для визуального захвата; решение pass/fail по-прежнему поступает от Discord REST oracle.
CI использует ту же командную поверхность в .github/workflows/qa-live-transports-convex.yml.
Запуски по расписанию и стандартные ручные запуски выполняют быстрый профиль Matrix с
live-frontier учетными данными, предоставленными QA, --fast и
OPENCLAW_QA_MATRIX_NO_REPLY_WINDOW_MS=3000. Ручной matrix_profile=all разворачивается
в пять шардов профилей.
Для smoke-путей Telegram, Discord, Slack и WhatsApp с реальным транспортом:
slack-qa/, slack-desktop-smoke.png и slack-desktop-smoke.mp4,
когда доступен видеозахват, обратно в каталог артефактов Mantis. Аренды Crabbox
desktop/browser заранее предоставляют инструменты захвата и helper-пакеты для browser/native-build,
поэтому сценарий должен устанавливать fallback-зависимости только на старых арендах.
Mantis сообщает общие тайминги и тайминги по фазам в
mantis-slack-desktop-smoke-report.md, чтобы медленные запуски показывали, ушло ли время на
прогрев аренды, получение учетных данных, удаленную настройку или копирование артефактов. Повторно используйте
--lease-id <cbx_...> после ручного входа в Slack Web через VNC;
повторно используемые аренды также сохраняют теплым pnpm store cache Crabbox. Стандартный
--hydrate-mode source проверяет из рабочей копии исходного кода и запускает install/build
внутри VM. Используйте --hydrate-mode prehydrated только когда повторно используемое удаленное
workspace уже содержит node_modules и собранный dist/; этот режим пропускает
дорогой шаг install/build и fail-closed, если workspace не готово.
С --gateway-setup Mantis оставляет постоянный OpenClaw Slack Gateway,
работающий внутри VM на порту 38973; без него команда запускает обычный
bot-to-bot Slack QA путь и завершается после захвата артефактов.
Чтобы доказать нативный Slack approval UI с desktop-доказательствами, запустите checkpoint-режим Mantis approval:
--gateway-setup. Он запускает сценарии Slack
approval, отклоняет id сценариев не для approval, ожидает в каждом pending и
resolved состоянии approval, рендерит наблюдаемое сообщение Slack API в
approval-checkpoints/<scenario>-pending.png и
approval-checkpoints/<scenario>-resolved.png, затем завершается с ошибкой, если какой-либо checkpoint,
доказательство сообщения, acknowledgement или отрендеренный screenshot отсутствует или пуст.
Холодные CI-аренды все еще могут показывать вход в Slack в slack-desktop-smoke.png;
изображения approval checkpoint являются визуальным доказательством для этого пути.
Чеклист оператора, команда GitHub workflow dispatch, контракт evidence-comment,
таблица решений hydrate-mode, интерпретация таймингов и шаги обработки сбоев находятся в Mantis Slack Desktop Runbook.
Для desktop-задачи в стиле agent/CV выполните:
visual-task арендует или повторно использует desktop/browser машину Crabbox, запускает
crabbox record --while, управляет видимым браузером через вложенный
visual-driver, захватывает visual-task.png, запускает openclaw infer image describe
для screenshot, когда выбран --vision-mode image-describe, и
записывает visual-task.mp4, mantis-visual-task-summary.json,
mantis-visual-task-driver-result.json и mantis-visual-task-report.md.
Когда задан --expect-text, vision prompt запрашивает структурированный JSON
вердикт и проходит только тогда, когда модель сообщает о положительном видимом доказательстве; отрицательный
ответ, который лишь цитирует целевой текст, не проходит assertion.
Используйте --vision-mode metadata для no-model smoke, который доказывает работу desktop,
browser, screenshot и video plumbing без вызова провайдера распознавания изображений.
Запись является обязательным артефактом для visual-task; если Crabbox не записывает
непустой visual-task.mp4, задача завершается с ошибкой, даже если visual driver
прошел. При сбое Mantis сохраняет аренду для VNC, если только задача уже не
прошла и --keep-lease не был задан.
Перед использованием pooled live credentials выполните:
Покрытие реальных транспортов
Live transport пути используют один контракт вместо того, чтобы каждый изобретал собственную форму списка сценариев.qa-channel — это широкий синтетический набор для поведения продукта, и он не является частью матрицы покрытия live transport.
Live transport runners должны импортировать общие scenario ids, helpers базового
покрытия и helper выбора сценариев из
openclaw/plugin-sdk/qa-live-transport-scenarios.
| Путь | Canary | Фильтрация по упоминаниям | Bot-to-bot | Блокировка allowlist | Ответ верхнего уровня | Ответ с цитатой | Возобновление после перезапуска | Продолжение треда | Изоляция треда | Наблюдение реакций | Help command | Регистрация нативной команды |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Matrix | x | x | x | x | x | x | x | x | x | |||
| Telegram | x | x | x | x | ||||||||
| Discord | x | x | x | x | ||||||||
| Slack | x | x | x | x | x | x | x | x | ||||
| x | x | x | x | x | x | x | x |
qa-channel как широкий набор для поведения продукта, тогда как Matrix,
Telegram и другие live transports используют один явный чеклист транспортного контракта.
Для одноразового Linux VM пути без включения Docker в QA-путь выполните:
qa suite, затем копирует обычный QA-отчет и
сводку обратно в .artifacts/qa-e2e/... на host.
Он повторно использует то же поведение выбора сценариев, что и qa suite на host.
Запуски suite на host и Multipass по умолчанию выполняют несколько выбранных сценариев параллельно
с изолированными gateway workers. qa-channel по умолчанию использует concurrency
4, ограниченную количеством выбранных сценариев. Используйте --concurrency <count>, чтобы настроить
число workers, или --concurrency 1 для последовательного выполнения.
Используйте --pack personal-agent, чтобы запустить benchmark pack персонального помощника. Селектор
pack является additive с повторяющимися флагами --scenario: явные сценарии
запускаются первыми, затем сценарии pack запускаются в порядке pack с удалением дубликатов.
Используйте --pack observability, когда пользовательский QA runner уже предоставляет настройку
OpenTelemetry collector и хочет выбрать smoke-сценарии диагностики OpenTelemetry и Prometheus
вместе.
Команда завершается с ненулевым кодом, когда любой сценарий завершается с ошибкой. Используйте --allow-failures, когда
нужны артефакты без ошибочного exit code.
Live-запуски пробрасывают поддерживаемые QA auth inputs, практичные для
guest: provider keys на основе env, путь к QA live provider config и
CODEX_HOME, когда он присутствует. Держите --output-dir под корнем репозитория, чтобы guest
мог записывать обратно через смонтированное workspace.
Справочник QA для Telegram, Discord, Slack и WhatsApp
Matrix имеет отдельную страницу из-за количества сценариев и подготовки homeserver на базе Docker. Telegram, Discord, Slack и WhatsApp запускаются с уже существующими реальными транспортами, поэтому их справочник находится здесь.Общие флаги CLI
Эти направления регистрируются черезextensions/qa-lab/src/live-transports/shared/live-transport-cli.ts и принимают одинаковые флаги:
| Флаг | По умолчанию | Описание |
|---|---|---|
--scenario <id> | - | Запустить только этот сценарий. Можно повторять. |
--output-dir <path> | <repo>/.artifacts/qa-e2e/<transport>-<timestamp> | Куда записываются отчеты, сводки, доказательства, артефакты конкретного транспорта и выходной лог. Относительные пути разрешаются относительно --repo-root. |
--repo-root <path> | process.cwd() | Корень репозитория при вызове из нейтрального текущего каталога. |
--sut-account <id> | sut | Временный идентификатор учетной записи внутри конфигурации QA gateway. |
--provider-mode <mode> | live-frontier | mock-openai или live-frontier (устаревший live-openai все еще работает). |
--model <ref> / --alt-model <ref> | значение провайдера по умолчанию | Ссылки на основную/альтернативную модель. |
--fast | выключено | Быстрый режим провайдера, где он поддерживается. |
--credential-source <env|convex> | env | См. пул учетных данных Convex. |
--credential-role <maintainer|ci> | ci в CI, иначе maintainer | Роль, используемая при --credential-source convex. |
--allow-failures записывает артефакты без установки кода выхода с ошибкой.
QA для Telegram
@BotFather.
Обязательные env при --credential-source env:
OPENCLAW_QA_TELEGRAM_GROUP_ID- числовой идентификатор чата (строка).OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKENOPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN
extensions/qa-lab/src/live-transports/telegram/telegram-live.runtime.ts):
telegram-canarytelegram-mention-gatingtelegram-mentioned-message-replytelegram-help-commandtelegram-commands-commandtelegram-tools-compact-commandtelegram-whoami-commandtelegram-status-commandtelegram-repeated-command-authorizationtelegram-other-bot-command-gatingtelegram-context-commandtelegram-current-session-status-tooltelegram-reply-chain-exact-markertelegram-stream-final-single-messagetelegram-long-final-reuses-previewtelegram-long-final-three-chunks
mock-openai также включают детерминированные проверки цепочек ответов и потоковой передачи финального сообщения. telegram-current-session-status-tool остается опциональным, потому что он стабилен только при запуске сразу после canary, а не после произвольных ответов на нативные команды. Используйте pnpm openclaw qa telegram --list-scenarios --provider-mode mock-openai, чтобы вывести текущий раздел сценариев по умолчанию/опциональных сценариев со ссылками на регрессии.
Выходные артефакты:
telegram-qa-report.mdqa-evidence.json- записи доказательств для проверок живого транспорта, включая поля профиля, покрытия, провайдера, канала, артефактов, результата и RTT.
qa-evidence.json в result.timing для выбранной проверки RTT.
OPENCLAW_QA_CREDENTIAL_SOURCE=convex, пакетная живая обертка арендует учетные данные kind: "telegram", экспортирует env арендованной группы/драйвера/бота SUT в запуск установленного пакета, отправляет Heartbeat аренды и освобождает ее при завершении. Пакетная обертка по умолчанию использует 20 проверок RTT для telegram-mentioned-message-reply, таймаут RTT 30 с и роль Convex maintainer вне CI, когда выбран Convex. Переопределите OPENCLAW_NPM_TELEGRAM_RTT_SAMPLES, OPENCLAW_NPM_TELEGRAM_RTT_TIMEOUT_MS или OPENCLAW_NPM_TELEGRAM_RTT_MAX_FAILURES, чтобы настроить измерение RTT без создания отдельной команды RTT или специфичного для Telegram формата сводки.
QA для Discord
/help в Discord, а также опциональные сценарии доказательств Mantis.
Обязательные env при --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- должен совпадать с идентификатором пользователя бота SUT, возвращенным Discord (иначе направление быстро завершится ошибкой).
OPENCLAW_QA_DISCORD_CAPTURE_CONTENT=1сохраняет тела сообщений в артефактах наблюдаемых сообщений.OPENCLAW_QA_DISCORD_VOICE_CHANNEL_IDвыбирает голосовой/сценический канал дляdiscord-voice-autojoin; без него сценарий выбирает первый видимый голосовой/сценический канал для бота SUT.
extensions/qa-lab/src/live-transports/discord/discord-live.runtime.ts:36):
discord-canarydiscord-mention-gatingdiscord-native-help-command-registrationdiscord-voice-autojoin- опциональный голосовой сценарий. Запускается отдельно, включаетchannels.discord.voice.autoJoinи проверяет, что текущее голосовое состояние Discord бота SUT соответствует целевому голосовому/сценическому каналу. Учетные данные Convex Discord могут включать необязательныйvoiceChannelId; иначе runner обнаруживает первый видимый голосовой/сценический канал в гильдии.discord-status-reactions-tool-only- опциональный сценарий Mantis. Запускается отдельно, потому что переключает SUT на постоянные ответы гильдии только через инструменты сmessages.statusReactions.enabled=true, затем захватывает временную шкалу реакций REST и визуальные артефакты HTML/PNG. Отчеты Mantis до/после также сохраняют предоставленные сценарием артефакты MP4 какbaseline.mp4иcandidate.mp4.
discord-qa-report.mdqa-evidence.json- записи доказательств для проверок живого транспорта.discord-qa-observed-messages.json- тела редактируются, если не заданоOPENCLAW_QA_DISCORD_CAPTURE_CONTENT=1.discord-qa-reaction-timelines.jsonиdiscord-status-reactions-tool-only-timeline.png, когда запускается сценарий статусных реакций.
QA для Slack
--credential-source env:
OPENCLAW_QA_SLACK_CHANNEL_IDOPENCLAW_QA_SLACK_DRIVER_BOT_TOKENOPENCLAW_QA_SLACK_SUT_BOT_TOKENOPENCLAW_QA_SLACK_SUT_APP_TOKEN
OPENCLAW_QA_SLACK_CAPTURE_CONTENT=1сохраняет тела сообщений в артефактах наблюдаемых сообщений.OPENCLAW_QA_SLACK_APPROVAL_CHECKPOINT_DIRвключает контрольные точки визуального подтверждения для Mantis. Runner записывает<scenario>.pending.jsonи<scenario>.resolved.json, затем ждет соответствующие файлы.ack.json.OPENCLAW_QA_SLACK_APPROVAL_CHECKPOINT_TIMEOUT_MSпереопределяет таймаут подтверждения контрольной точки. Значение по умолчанию:120000.
extensions/qa-lab/src/live-transports/slack/slack-live.runtime.ts):
slack-canaryslack-mention-gatingslack-allowlist-blockslack-top-level-reply-shapeslack-restart-resumeslack-thread-follow-upslack-thread-isolationslack-approval-exec-native- опциональный сценарий нативного подтверждения exec в Slack. Запрашивает подтверждение exec через gateway, проверяет, что сообщение Slack содержит нативные кнопки подтверждения, разрешает его и проверяет обновление Slack после разрешения.slack-approval-plugin-native- опциональный сценарий нативного подтверждения Plugin в Slack. Включает совместную пересылку подтверждений exec и Plugin, чтобы события Plugin не подавлялись маршрутизацией подтверждений exec, затем проверяет тот же путь нативного UI Slack для pending/resolved.
slack-qa-report.mdqa-evidence.json- записи доказательств для проверок живого транспорта.slack-qa-observed-messages.json- тела редактируются, если не заданоOPENCLAW_QA_SLACK_CAPTURE_CONTENT=1.approval-checkpoints/- только когда Mantis задаетOPENCLAW_QA_SLACK_APPROVAL_CHECKPOINT_DIR; содержит JSON контрольных точек, JSON подтверждений и скриншоты pending/resolved.
Настройка рабочей области Slack
Направлению нужны два разных приложения Slack в одной рабочей области, а также канал, участниками которого являются оба бота:channelId- идентификаторCxxxxxxxxxxканала, куда приглашены оба бота. Используйте выделенный канал; направление публикует сообщения при каждом запуске.driverBotToken- токен бота (xoxb-...) приложения Driver.sutBotToken- токен бота (xoxb-...) приложения SUT, которое должно быть отдельным приложением Slack от драйвера, чтобы идентификатор пользователя его бота был другим.sutAppToken- токен уровня приложения (xapp-...) приложения SUT сconnections:write, используемый Socket Mode, чтобы приложение SUT могло получать события.
extensions/slack/src/setup-shared.ts:10) до разрешений и событий, покрытых живым набором QA для Slack. Настройку производственного канала, как ее видят пользователи, см. в быстрой настройке канала Slack; пара QA Driver/SUT намеренно отделена, потому что направлению нужны два разных идентификатора пользователей-ботов в одной рабочей области.
1. Создайте приложение Driver
Перейдите на api.slack.com/apps → Create New App → From a manifest → выберите рабочую область QA, вставьте следующий манифест, затем нажмите Install to Workspace:
xoxb-...) - он станет driverBotToken. Драйверу нужно только публиковать сообщения и идентифицировать себя; события и Socket Mode не нужны.
2. Создайте приложение SUT
Повторите Create New App → From a manifest в той же рабочей области. Это QA-приложение намеренно использует более узкую версию production-манифеста встроенного Slack plugin (extensions/slack/src/setup-shared.ts:10): scopes и события для реакций опущены, потому что live-набор Slack QA пока не покрывает обработку реакций.
- Install to Workspace → скопируйте Bot User OAuth Token → он станет
sutBotToken. - Basic Information → App-Level Tokens → Generate Token and Scopes → добавьте scope
connections:write→ сохраните → скопируйте значениеxapp-...→ оно станетsutAppToken.
auth.test для каждого токена. Runtime различает драйвер и SUT по идентификатору пользователя; повторное использование одного приложения для обоих сразу приведет к сбою gating по упоминаниям.
3. Создайте канал
В рабочей области QA создайте канал (например, #openclaw-qa) и пригласите обоих ботов изнутри канала:
Cxxxxxxxxxx из channel info → About → Channel ID - он станет channelId. Подойдет публичный канал; если вы используете приватный канал, у обоих приложений уже есть groups:history, поэтому чтение истории в harness все равно будет успешным.
4. Зарегистрируйте учетные данные
Есть два варианта. Используйте переменные окружения для отладки на одной машине (задайте четыре переменные OPENCLAW_QA_SLACK_* и передайте --credential-source env) или заполните общий пул Convex, чтобы CI и другие сопровождающие могли арендовать их.
Для пула Convex запишите четыре поля в JSON-файл:
OPENCLAW_QA_CONVEX_SITE_URL и OPENCLAW_QA_CONVEX_SECRET_MAINTAINER в вашей оболочке, зарегистрируйте и проверьте:
count: 1, status: "active", без поля lease.
5. Проверьте end to end
Запустите lane локально, чтобы подтвердить, что оба бота могут общаться друг с другом через брокер:
slack-qa-report.md показывает статусы pass для slack-canary и slack-mention-gating. Если lane зависает примерно на 90 секунд и завершается с Convex credential pool exhausted for kind "slack", значит пул пуст или все строки арендованы - qa credentials list --kind slack --status all --json покажет, какой именно случай.
WhatsApp QA
--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
OPENCLAW_QA_WHATSAPP_GROUP_JIDвключает групповые сценарии, такие какwhatsapp-mention-gatingиwhatsapp-group-allowlist-block.OPENCLAW_QA_WHATSAPP_CAPTURE_CONTENT=1сохраняет тела сообщений в артефактах observed-message.
extensions/qa-lab/src/live-transports/whatsapp/whatsapp-live.runtime.ts):
- Базовые проверки и групповой gating:
whatsapp-canary,whatsapp-pairing-block,whatsapp-mention-gating,whatsapp-top-level-reply-shape,whatsapp-restart-resume,whatsapp-group-allowlist-block. - Нативные команды:
whatsapp-help-command,whatsapp-status-command,whatsapp-commands-command,whatsapp-tools-compact-command,whatsapp-whoami-command,whatsapp-context-command,whatsapp-native-new-command. - Поведение ответов и финального вывода:
whatsapp-tool-only-usage-footer,whatsapp-reply-to-message,whatsapp-group-reply-to-message,whatsapp-reply-context-isolation,whatsapp-reply-delivery-shape,whatsapp-stream-final-message-accounting. - Входящие медиа и структурированные сообщения:
whatsapp-inbound-image-caption,whatsapp-audio-preflight,whatsapp-inbound-structured-messages,whatsapp-group-audio-gating. Они отправляют реальные события WhatsApp для изображений, аудио, документов, местоположений, контактов и стикеров через драйвер. - Покрытие исходящего Gateway и действий с сообщениями:
whatsapp-outbound-media-matrix,whatsapp-outbound-document-preserves-filename,whatsapp-outbound-poll,whatsapp-message-actions. - Покрытие контроля доступа:
whatsapp-access-control-dm-open,whatsapp-access-control-dm-disabled,whatsapp-access-control-group-open,whatsapp-access-control-group-disabled,whatsapp-group-allowlist-block. - Нативные подтверждения:
whatsapp-approval-exec-deny-native,whatsapp-approval-exec-native,whatsapp-approval-exec-reaction-native,whatsapp-approval-plugin-native. - Реакции статуса:
whatsapp-status-reactions.
live-frontier
оставлен небольшим - 10 сценариев для быстрого smoke-покрытия. Стандартный
lane mock-openai запускает 31 детерминированный сценарий через реальный транспорт WhatsApp,
мокируя только вывод модели. Сценарии подтверждений и несколько более тяжелых/блокирующих проверок
остаются явными по идентификатору сценария.
Драйвер WhatsApp QA наблюдает структурированные live-события (text, media,
location, reaction и poll) и может активно отправлять медиа, опросы,
контакты, местоположения и стикеры. QA Lab импортирует этот драйвер через
поверхность пакета @openclaw/whatsapp/api.js, а не обращается к приватным
runtime-файлам WhatsApp. Содержимое сообщений по умолчанию редактируется. Покрытие исходящих
опросов и загрузки файлов проходит через детерминированные gateway-вызовы poll и
message.action, а не только через вызов инструмента из model prompt.
Выходные артефакты:
whatsapp-qa-report.mdqa-evidence.json- evidence-записи для проверок live-транспорта.whatsapp-qa-observed-messages.json- тела редактируются, если не заданоOPENCLAW_QA_WHATSAPP_CAPTURE_CONTENT=1.
Пул учетных данных Convex
Lane для Telegram, Discord, Slack и WhatsApp могут арендовать учетные данные из общего пула Convex вместо чтения переменных окружения выше. Передайте--credential-source convex (или задайте OPENCLAW_QA_CREDENTIAL_SOURCE=convex); QA Lab получает эксклюзивную аренду, отправляет для нее Heartbeat в течение всего запуска и освобождает ее при завершении. Виды пула: "telegram", "discord", "slack" и "whatsapp".
Формы payload, которые брокер проверяет на admin/add:
- Telegram (
kind: "telegram"):{ groupId: string, driverToken: string, sutToken: string }-groupIdдолжен быть числовой строкой chat-id. - Реальный пользователь 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 }- только для proof Mantis Telegram Desktop. Обычные lane QA Lab не должны получать этот вид. - 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 }- номера телефонов должны быть разными строками E.164.
telegram-user и для драйвера TDLib CLI, и для свидетеля Telegram Desktop,
затем освобождает ее после публикации proof.
Когда PR требует детерминированного визуального diff, Mantis может использовать один и тот же mock-ответ модели
на main и на head PR, пока меняется formatter или слой доставки Telegram.
Настройки захвата по умолчанию адаптированы для комментариев PR: стандартный класс Crabbox,
запись рабочего стола 24 fps, motion GIF 24 fps и ширина preview 1920 px.
Комментарии before/after должны публиковать чистый bundle, содержащий только
нужные GIF.
Slack lanes также могут использовать пул. Проверки формы Slack payload сейчас находятся в Slack QA runner, а не в брокере; используйте { channelId: string, driverBotToken: string, sutBotToken: string, sutAppToken: string } с идентификатором Slack-канала вроде Cxxxxxxxxxx. См. Настройка рабочей области Slack для подготовки приложений и scope.
Операционные переменные окружения и контракт endpoint брокера Convex описаны в Тестирование → Общие учетные данные Telegram через Convex (название раздела появилось до многоканального пула; семантика аренды общая для всех видов).
Seeds из репозитория
Seed-ресурсы находятся вqa/:
qa/scenarios/index.yamlqa/scenarios/<theme>/*.yaml
qa-lab должен оставаться универсальным runner YAML-сценариев. Каждый YAML-файл сценария является
источником истины для одного тестового запуска и должен определять:
- верхнеуровневый
title - метаданные
scenario - необязательные метаданные категории, capability, lane и risk в
scenario - ссылки на docs и code refs в
scenario - необязательные требования к plugin в
scenario - необязательный patch конфигурации gateway в
scenario - исполняемый верхнеуровневый
flowдля flow-сценариев илиscenario.execution.kind/scenario.execution.pathдля сценариев Vitest и Playwright
flow, может оставаться обобщенной
и сквозной. Например, YAML-сценарии могут сочетать помощники транспортной стороны
с помощниками браузерной стороны, которые управляют встроенным Control UI через
стык Gateway browser.request, не добавляя специальный runner.
Файлы сценариев следует группировать по продуктовой возможности, а не по папке
дерева исходного кода. Сохраняйте стабильные идентификаторы сценариев при перемещении файлов; используйте docsRefs и codeRefs
для отслеживаемости реализации.
Базовый список должен оставаться достаточно широким, чтобы покрывать:
- чаты DM и каналов
- поведение веток
- жизненный цикл действий с сообщениями
- обратные вызовы cron
- воспоминание памяти
- переключение модели
- передачу subagent
- чтение репозитория и документации
- одну небольшую задачу сборки, например Lobster Invaders
Локальные ветки моков провайдеров
Уqa suite есть две локальные ветки моков провайдеров:
mock-openai— сценарно-ориентированный мок OpenClaw. Он остается стандартной детерминированной веткой моков для QA с привязкой к репозиторию и проверок паритета.aimockзапускает сервер провайдера на базе AIMock для экспериментального покрытия протокола, фикстур, записи/воспроизведения и chaos. Он является добавочным и не заменяет диспетчер сценариевmock-openai.
extensions/qa-lab/src/providers/.
Каждый провайдер владеет своими значениями по умолчанию, запуском локального сервера, конфигурацией модели Gateway,
потребностями подготовки auth-профиля и флагами возможностей live/mock. Общий код suite и
gateway должен маршрутизироваться через реестр провайдеров вместо ветвления по
именам провайдеров.
Транспортные адаптеры
qa-lab владеет обобщенным транспортным стыком для YAML-сценариев QA. qa-channel —
синтетическое значение по умолчанию. crabline запускает локальные серверы в форме провайдеров и выполняет
обычные Plugin каналов OpenClaw против них. live зарезервирован для реальных
учетных данных провайдеров и внешних каналов.
На архитектурном уровне разделение такое:
qa-labвладеет обобщенным выполнением сценариев, параллелизмом worker, записью артефактов и отчетностью.- Транспортный адаптер владеет конфигурацией gateway, готовностью, наблюдением входящих и исходящих сообщений, транспортными действиями и нормализованным транспортным состоянием.
- YAML-файлы сценариев в
qa/scenarios/определяют тестовый прогон;qa-labпредоставляет многоразовую поверхность runtime, которая их выполняет.
Добавление канала
Добавление канала в систему YAML QA требует реализации канала плюс пакета сценариев, который проверяет контракт канала. Для smoke-покрытия в CI добавьте соответствующий фейковый провайдер Crabline и откройте его через драйверcrabline.
Не добавляйте новый корень команды QA верхнего уровня, когда общий хост qa-lab может владеть flow.
qa-lab владеет общими механизмами хоста:
- корнем команды
openclaw qa - запуском и завершением suite
- параллелизмом worker
- записью артефактов
- генерацией отчетов
- выполнением сценариев
- алиасами совместимости для старых сценариев
qa-channel
- как
openclaw qa <runner>монтируется под общим корнемqa - как gateway настраивается для этого транспорта
- как проверяется готовность
- как внедряются входящие события
- как наблюдаются исходящие сообщения
- как предоставляются transcripts и нормализованное транспортное состояние
- как выполняются действия, поддерживаемые транспортом
- как выполняется сброс или очистка, специфичная для транспорта
- Сохраняйте
qa-labвладельцем общего корняqa. - Реализуйте транспортный runner на общем стыке хоста
qa-lab. - Держите механизмы, специфичные для транспорта, внутри Plugin runner или harness канала.
- Монтируйте runner как
openclaw qa <runner>, а не регистрируйте конкурирующую корневую команду. Plugin runner должны объявлятьqaRunnersвopenclaw.plugin.jsonи экспортировать соответствующий массивqaRunnerCliRegistrationsизruntime-api.ts. Держитеruntime-api.tsлегким; ленивое выполнение CLI и runner должно оставаться за отдельными entrypoint. - Создайте или адаптируйте YAML-сценарии в тематических каталогах
qa/scenarios/. - Используйте обобщенные помощники сценариев для новых сценариев.
- Сохраняйте работу существующих алиасов совместимости, если репозиторий не выполняет намеренную миграцию.
- Если поведение можно выразить один раз в
qa-lab, поместите его вqa-lab. - Если поведение зависит от транспорта одного канала, держите его в этом Plugin runner или harness Plugin.
- Если сценарию нужна новая возможность, которую может использовать более чем один канал, добавьте обобщенный помощник вместо ветки, специфичной для канала, в
suite.ts. - Если поведение имеет смысл только для одного транспорта, оставьте сценарий специфичным для транспорта и явно укажите это в контракте сценария.
Имена помощников сценариев
Предпочтительные обобщенные помощники для новых сценариев:waitForTransportReadywaitForChannelReadyinjectInboundMessageinjectOutboundMessagewaitForTransportOutboundMessagewaitForChannelOutboundMessagewaitForNoTransportOutboundgetTransportSnapshotreadTransportMessagereadTransportTranscriptformatTransportTranscriptresetTransport
waitForQaChannelReady, waitForOutboundMessage, waitForNoOutbound, formatConversationTranscript, resetBus, но при создании новых сценариев следует использовать обобщенные имена. Алиасы существуют, чтобы избежать одномоментной миграции, а не как модель на будущее.
Отчетность
qa-lab экспортирует Markdown-отчет протокола из наблюдаемой временной шкалы bus.
Отчет должен отвечать:
- Что сработало
- Что не сработало
- Что осталось заблокированным
- Какие последующие сценарии стоит добавить
pnpm openclaw qa coverage (добавьте --json для машиночитаемого вывода).
При выборе сфокусированного доказательства для затронутого поведения или пути файла выполните pnpm openclaw qa coverage --match <query>.
Отчет match ищет по метаданным сценариев, ссылкам docs, ссылкам code, идентификаторам покрытия, Plugin и требованиям провайдеров, затем печатает подходящие цели qa suite --scenario ....
Каждый прогон qa suite записывает артефакты верхнего уровня qa-evidence.json,
qa-suite-summary.json и qa-suite-report.md для выбранного
набора сценариев. Сценарии, объявляющие execution.kind: vitest или
execution.kind: playwright, запускают соответствующий путь теста и также записывают
логи для каждого сценария. Сценарии, объявляющие execution.kind: script, запускают
производитель evidence по execution.path через node --import tsx (с
подстановкой ${outputDir} и ${scenarioId} в execution.args); производитель
записывает собственный qa-evidence.json, записи которого импортируются в вывод
suite, а пути артефактов разрешаются относительно этого qa-evidence.json
производителя. Когда qa suite достигается через
qa run --qa-profile, тот же qa-evidence.json также включает сводку
scorecard профиля для выбранных категорий таксономии.
Считайте это помощником обнаружения, а не заменой gate; выбранному сценарию все еще нужен правильный режим провайдера, live-транспорт, Multipass, Testbox или release-ветка для проверяемого поведения.
Контекст scorecard см. в Scorecard зрелости.
Для проверок характера и стиля выполните один и тот же сценарий по нескольким live-ссылкам моделей
и запишите оцененный Markdown-отчет:
SOUL.md, затем выполнять обычные пользовательские ходы,
такие как чат, помощь с workspace и небольшие файловые задачи. Кандидатной модели
не следует сообщать, что ее оценивают. Команда сохраняет каждый полный
transcript, записывает базовую статистику прогона, затем просит модели-судьи в fast mode с
рассуждением xhigh, где оно поддерживается, ранжировать прогоны по естественности, вайбу и юмору.
Используйте --blind-judge-models при сравнении провайдеров: prompt судьи все равно получает
каждый transcript и статус прогона, но ссылки кандидатов заменяются нейтральными
метками, такими как candidate-01; отчет сопоставляет ранжирования с реальными ссылками после
парсинга.
Кандидатные прогоны по умолчанию используют thinking high, с medium для GPT-5.5 и xhigh
для старых ссылок eval OpenAI, которые это поддерживают. Переопределите конкретного кандидата inline через
--model provider/model,thinking=<level>. --thinking <level> по-прежнему задает
глобальный fallback, а старая форма --model-thinking <provider/model=level>
сохранена для совместимости.
Кандидатные ссылки OpenAI по умолчанию используют fast mode, чтобы priority processing применялся там,
где провайдер это поддерживает. Добавьте inline ,fast, ,no-fast или ,fast=false, когда
одному кандидату или судье требуется переопределение. Передавайте --fast только когда хотите
принудительно включить fast mode для каждой кандидатной модели. Длительности кандидатов и судей
записываются в отчет для анализа бенчмарков, но prompts судей явно говорят
не ранжировать по скорости.
Прогоны кандидатных моделей и моделей-судей оба по умолчанию используют параллелизм 16. Уменьшите
--concurrency или --judge-concurrency, когда лимиты провайдера или нагрузка на локальный gateway
делают прогон слишком шумным.
Когда кандидатный --model не передан, character eval по умолчанию использует
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 и
google/gemini-3.1-pro-preview, когда --model не передан.
Когда --judge-model не передан, судьи по умолчанию:
openai/gpt-5.5,thinking=xhigh,fast и
anthropic/claude-opus-4-8,thinking=high.