QA 专用运行器
面向 QA 的专用运行器¶
当您需要 QA 实验室级的真实感时,这些命令与主测试套件并列使用。
CI 在专用工作流中运行 QA Lab。Agentic parity(代理级一致性)归属于 QA-Lab - All Lanes 和发布验证之下,而不是独立的 PR 工作流。广泛验证应使用 Full Release Validation,并使用 rerun_group=qa-parity 进行 parity 验证,或使用 rerun_group=qa-live 进行实时 QA。单独的 OpenClaw Release Checks 子项可直接使用 rerun_group=qa 作为两个组的手动聚合。Stable/full、启用 soak 以及显式 qa-live 的发布检查包含 QA-live Matrix 和 Telegram 通道。有界 beta-publish all 在不进行 soak 的情况下运行 parity,但会将那些实时通道推迟到 postpublish-confidence 阶段。QA-Lab - All Lanes 在 main 上每晚运行,也可通过手动派发运行,其中 mock parity 通道、实时 Matrix 通道、Convex 管理的实时 Telegram 通道以及 Convex 管理的实时 Discord 通道作为并行作业运行。定时 QA 和选定的发布检查通过共享的实时适配器运行由目录派生的 Matrix 选择。发布传输检查使用 mock-openai/gpt-5.6-luna,以保持确定性并避免常规 provider 插件启动。这些实时传输网关禁用记忆搜索;记忆行为仍由 QA parity 套件覆盖。
完整发布版的实时媒体分片使用 ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04,该镜像已包含 ffmpeg 和 ffprobe。Docker 实时模型/后端分片使用共享的 ghcr.io/openclaw/openclaw-live-test:<sha> 镜像,该镜像为每个选定的提交构建一次,然后使用 OPENCLAW_SKIP_DOCKER_BUILD=1 拉取它,而不是在每个分片内重新构建。
pnpm openclaw qa suite- 直接在主机上运行仓库支持的 QA 场景。
- 为选定的场景集写入顶层
qa-evidence.json、qa-suite-summary.json和qa-suite-report.md工件,包括混合流程、Vitest 和 Playwright 场景选择。 - 当通过
pnpm openclaw qa run --qa-profile <profile>派发时,会将选定的分类法配置文件记分卡嵌入到同一个qa-evidence.json中。smoke-ci写入精简证据(evidenceMode: "slim",无逐条execution)。release覆盖精选的发布就绪切片;all选择所有活跃的成熟度类别,并在需要完整记分卡工件时面向显式的 QA Profile Evidence 工作流派发。 - 默认情况下,使用隔离的 gateway worker 并行运行多个选定场景。
qa-channel默认并发数为 4(以选定场景数为上限)。使用--concurrency <count>调整 worker 数量,或使用--concurrency 1使用较旧的串行通道。 每个 worker 拥有一个稳定的命名 profile,以及独立的 home、state 和 config 路径,因此其 CLI 引导无法选择操作员已安装的 Gateway 服务。父级 profile 和运行时环境补丁不会覆盖该 worker 身份。 子进程临时文件和默认编译器缓存保留在 worker 的临时根目录中,并在其进程停止后移除。父级临时路径和运行时环境补丁不会重定向该临时存储。OPENCLAW_QA_KEEP_TEMP=1会保留该根目录以供调试。 如果 controller 退出,当前 Gateway 的父级 watchdog 会退出,但不会删除后代可能仍在使用的运行时文件。存活的 owner 或主机维护人员必须确认这些写入方已停止,然后才能移除保留的根目录。 - 当任何场景失败时,命令以非零退出码退出。使用
--allow-failures可在不返回失败退出码的情况下生成工件。 - 支持 provider 模式
live-frontier、mock-openai和aimock。aimock会启动一个由本地 AIMock 支持的 provider 服务器,用于实验性 fixture 和协议 mock 覆盖,而不会替换可感知场景的mock-openai通道。 pnpm openclaw qa coverage --match <query>- 搜索场景 ID、标题、surface、覆盖 ID、文档引用、代码引用、插件和 provider 要求,然后打印匹配的套件目标。
- 在 QA Lab 运行之前,当您知道受影响的 behavior 或文件路径但不知道最小场景时使用此命令。仅供参考——仍需根据被更改的 behavior 选择 mock、live、Multipass、Matrix 或 transport 证明。
pnpm test:plugins:kitchen-sink-live- 通过 QA Lab 运行实时 OpenAI Kitchen Sink 插件 gauntlet(全套严苛测试)。安装外部 Kitchen Sink 包,验证插件 SDK surface 清单,探测
/healthz和/readyz,记录 gateway CPU/RSS 证据,运行一次实时 OpenAI 对话,并检查对抗性诊断。需要实时 OpenAI 认证,例如OPENAI_API_KEY。在已注入环境的 Testbox 会话中,当存在openclaw-testbox-env辅助工具时,它会自动获取 Testbox 实时认证 profile。 pnpm test:gateway:cpu-scenarios- 运行 gateway 启动基准测试以及一个小型 mock QA Lab 场景包(
channel-chat-baseline、memory-failure-fallback、gateway-restart-inflight-run),并在.artifacts/gateway-cpu-scenarios/下写入合并的 CPU 观测摘要。 - 默认仅标记持续的高 CPU 观测(
--cpu-core-warn,默认0.9;--hot-wall-warn-ms,默认30000),因此短暂的启动突发会作为指标记录,而不会看起来像是长达数分钟的 gateway CPU 占用回归。 - 针对构建好的
dist工件运行;如果当前检出还没有新的运行时输出,请先执行构建。 pnpm openclaw qa suite --runner multipass- 在一次性 Multipass Linux VM 中运行相同的 QA 套件,保持与
qa suite相同的场景选择和 provider/model 标志。 - 实时运行会转发适合 guest 的 QA 认证输入:基于 env 的 provider 密钥、QA 实时 provider 配置路径,以及存在时的
CODEX_HOME。 - 输出目录必须保持在仓库根目录内,以便 guest 可以通过挂载的工作区写回。
- 将常规 QA 报告 + 摘要以及 Multipass 日志写入
.artifacts/qa-e2e/...。 pnpm qa:lab:up- 启动 Docker 支持的 QA 站点,用于操作员风格的 QA 工作。
pnpm test:docker:npm-onboard-channel-agent- 从当前检出构建 npm tarball,在 Docker 中全局安装它,运行非交互式 OpenAI API-key 引导,默认配置 Telegram,验证打包的插件运行时无需启动依赖修复即可加载,运行 doctor,并针对模拟的 OpenAI endpoint 运行一次本地 agent 对话轮次。
- 使用
OPENCLAW_NPM_ONBOARD_CHANNEL=discord通过 Discord 运行相同的打包安装通道。 pnpm test:docker:session-runtime-context- 对嵌入式运行时上下文记录运行确定性的已构建应用 Docker 冒烟测试。验证隐藏的 OpenClaw 运行时上下文以非显示的自定义消息形式持久化,而不会泄漏到可见的用户对话轮次中,然后注入一个受影响的损坏会话 JSONL,并验证
openclaw doctor --fix会将其重写为带备份的活动分支。 pnpm test:docker:npm-telegram-live- 在 Docker 中安装一个 OpenClaw 包候选版本,运行已安装包的引导流程,通过已安装的 CLI 配置 Telegram,然后以该已安装包作为被测 SUT Gateway 复用实时 Telegram QA 通道。
- 受信任的检出拥有 QA harness 源码、分类法、场景、依赖项和私有 SDK 构建。已安装的包仍然是实际被测的 CLI、Gateway 和打包插件运行时,其 CLI 会写入包候选版本持久化的认证状态。
- 默认使用
OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@beta;设置OPENCLAW_NPM_TELEGRAM_PACKAGE_TGZ=/path/to/openclaw-current.tgz或OPENCLAW_CURRENT_PACKAGE_TGZ可测试已解析的本地 tarball,而不是从 registry 安装。 - 默认以
OPENCLAW_NPM_TELEGRAM_RTT_SAMPLES=20在qa-evidence.json中输出重复的 RTT 计时。可覆盖OPENCLAW_NPM_TELEGRAM_RTT_SAMPLES、OPENCLAW_NPM_TELEGRAM_RTT_TIMEOUT_MS或OPENCLAW_NPM_TELEGRAM_RTT_MAX_FAILURES来调整运行。OPENCLAW_NPM_TELEGRAM_RTT_CHECKS接受零个或恰好一个规范的 Telegram QA 场景 ID。省略时,常规通道会对channel-canary采样;聚焦的非 RTT 场景运行保持无探针。显式指定的 RTT 场景会自动包含在场景选择中,因此调用方无需在OPENCLAW_NPM_TELEGRAM_SCENARIOS中重复指定。多个 ID 会立即失败,而未知或不适用的 ID 会在规范场景验证中失败。包运行器会将选定的 RTT 场景提升一次到首位,然后再运行其余基于分类法的 fail-fast 发布场景。探针会继续在其最近观察到的会话和线程中进行,使用租用的主要参与者。第一个样本会启动一条新消息;后续样本会串联自己的回复,而不是另一个场景参与者观察到的回复。仅投递类场景使用其观察到的出站路由,无需额外的目录元数据。 - 使用与
pnpm openclaw qa telegram相同的由 Convex 租用的 Test Server userbot 凭据。设置OPENCLAW_QA_CONVEX_SITE_URL以及选定角色的 secret。Docker 包装器默认选择 Convex。 - 包装器会在 Docker 构建/安装工作之前,在主机上验证 Convex 凭据环境变量。仅在刻意调试获取凭据之前的设置时,才设置
OPENCLAW_NPM_TELEGRAM_SKIP_CREDENTIAL_PREFLIGHT=1。 OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci|maintainer仅为此通道覆盖共享的OPENCLAW_QA_CREDENTIAL_ROLE。未设置角色时,包装器在 CI 中使用ci,在 CI 之外使用maintainer。- GitHub Actions 将此通道暴露为手动维护者工作流
NPM Telegram Beta E2E。它不会在合并时运行。该工作流使用qa-live-shared环境和 Convex CI 凭据租约。设置其可选的rtt_scenario输入以选择重复的 RTT 场景,或留空以使用上述默认行为。仅在有意的历史降级或恢复证明时启用allow_older_binary_destructive_actions;它默认保持为 false。 - GitHub Actions 还提供了
Package Acceptance,用于针对一个候选包进行附带运行的产品证明。它接受 Git ref、已发布的 npm spec、HTTPS tarball URL 加 SHA-256、受信任 URL 策略,或来自另一次运行的 tarball 工件(source=ref|npm|url|trusted-url|artifact),将规范化后的openclaw-current.tgz上传为package-under-test,然后使用smoke、package、product、full或custom通道 profile 运行现有的 Docker E2E 调度器。设置telegram_mode=mock-openai或live-frontier可针对同一个package-under-test工件运行 Telegram QA 工作流。 - 对于已发布驱动更新中的旧版 Telegram topic 绑定,请选择
suite_profile=telegram、telegram_mode=mock-openai以及单一场景telegram-published-upgrade-bindings。将package_spec提供为精确的已发布基线版本,例如openclaw@2026.9.6,并通过source=ref或经过验证的 tarball 工件解析候选版本。该场景会先安装基线版本,然后租用 Test Server 凭据,让基线版本派生一个绑定线程的子会话,该子会话接管论坛主题,并针对候选版本运行该安装的常规openclaw update。它会在激活后和另一次 Gateway 重启后检查主题是否路由回父会话,同时确保子会话保持完整,包括全部三次有序关闭。原始凭据、会话和传输状态保留在容器临时存储中;上传的证据仅包含包身份和脱敏结果。 - 最新 beta 产品证明:
gh workflow run package-acceptance.yml --ref main \
-f source=npm \
-f package_spec=openclaw@beta \
-f suite_profile=product \
-f telegram_mode=mock-openai
- 精确 tarball URL 证明需要摘要,并使用公共 URL 安全策略:
gh workflow run package-acceptance.yml --ref main \
-f source=url \
-f package_url=https://registry.npmjs.org/openclaw/-/openclaw-VERSION.tgz \
-f package_sha256=<sha256> \
-f suite_profile=package
- 企业/私有 tarball 镜像使用显式可信源策略:
gh workflow run package-acceptance.yml --ref main \
-f source=trusted-url \
-f trusted_source_id=enterprise-artifactory \
-f package_url=https://packages.example.internal:8443/artifactory/openclaw/openclaw-VERSION.tgz \
-f package_sha256=<sha256> \
-f suite_profile=package
source=trusted-url 从受信任的工作流 ref 读取 .github/package-trusted-sources.json,不接受 URL 凭据或工作流输入中的私有网络绕过。如果命名的策略声明了 Bearer 认证,请配置固定的 OPENCLAW_TRUSTED_PACKAGE_TOKEN 机密。
- 工件证明会从另一个 Actions 运行下载 tarball 工件:
gh workflow run package-acceptance.yml --ref main \
-f source=artifact \
-f artifact_run_id=<run-id> \
-f artifact_name=<artifact-name> \
-f suite_profile=smoke
pnpm test:docker:plugins- 在 Docker 中打包并安装当前 OpenClaw 构建,启动已配置 OpenAI 的 Gateway,然后通过配置编辑启用捆绑的 channel/plugins。
- 验证 setup 发现会保持未配置的可下载插件不存在,首次配置的 doctor 修复会显式安装每个缺失的可下载插件,并且第二次重启不会运行隐藏依赖修复。
- 还会安装一个已知的较旧 npm 基线,在运行
openclaw update --tag <candidate>之前启用 Telegram,并验证候选版本的 post-update doctor 会清理旧版插件依赖残留,而无需 harness 侧的 postinstall 修复。 pnpm test:parallels:npm-update- 跨 Parallels 来宾运行原生打包安装更新冒烟测试。每个选中的平台首先安装请求的基线包,然后在同一来宾中运行已安装的
openclaw update命令,并验证已安装版本、更新状态、gateway 就绪状态以及一次本地 agent 回合。 - 在单个来宾上迭代时,使用
--platform macos、--platform windows或--platform linux。使用--json获取摘要工件路径和每条 lane 的状态。 - OpenAI lane 默认使用
openai/gpt-5.6-luna进行实时 agent 回合证明。传入--model <provider/model>或设置OPENCLAW_PARALLELS_OPENAI_MODEL以验证其他 OpenAI 模型。 -
用主机超时包裹较长的本地运行,以免 Parallels 传输停滞耗尽剩余测试窗口:
-
脚本会在
/tmp/openclaw-parallels-npm-update.*下写入嵌套 lane 日志。在假定外层 wrapper 挂起之前,先检查windows-update.log、macos-update.log或linux-update.log。 - Windows 更新在冷来宾上可能花费 10 到 15 分钟用于 post-update doctor 和包更新工作;只要嵌套的 npm 调试日志在推进,这仍然属于正常。
- 不要将此聚合 wrapper 与单独的 Parallels macOS、Windows 或 Linux 冒烟 lane 并行运行。它们共享 VM 状态,并可能在快照恢复、包服务或来宾 gateway 状态上发生冲突。
-
更新后证明会运行正常的捆绑插件表面,因为诸如语音、图像生成和媒体理解等能力门面会通过捆绑运行时 API 加载,即使 agent 回合本身只检查简单的文本响应。
-
pnpm openclaw qa aimock - 仅启动本地 AIMock provider 服务器,用于直接协议冒烟测试。
pnpm openclaw qa buzz- 使用专用的 driver 和 SUT 身份,针对真实 relay 房间运行 Buzz 实时 QA lane。
- 本地运行使用带有
relayUrl、roomId、driverPrivateKey和sutPrivateKey的--credential-file <path>。封闭 relay 可能还需要driverAuthTag和sutAuthTag。托管 relay 要求wss://;ws://仅接受用于回环开发 relay。 - 默认使用
mock-openai,并通过真实的 Buzz 插件路径运行 canary 和 mention-gating 场景。 - 支持带有池化
kind: "buzz"行的--credential-source convex。两个公钥都必须是 relay/room 成员,并且 SUT 必须具有 Bot 房间角色。切勿使用人类所有者或管理员私钥。 pnpm openclaw qa matrix- 针对一次性的 Docker 支持的 Tuwunel homeserver 运行 Matrix 实时 QA lane。仅限源码检出 - 打包安装不包含
qa-lab。 - 完整 CLI、profile/场景目录、环境变量和工件布局: Matrix 冒烟 lane。
pnpm openclaw qa telegram- 在 Telegram 的 Test Server 上运行 Telegram 实时 QA lane,使用一个 Convex 租用的 SUT bot 和一个独立的 TDLib 用户会话。
- 默认使用
--credential-source convex并拒绝env。提供OPENCLAW_QA_CONVEX_SITE_URL以及所选--credential-role的 secret。 - 默认覆盖 canary、mention gating、命令寻址、
/status、bot-to-bot 提及回复以及核心原生命令回复。mock-openai默认还覆盖确定性 reply-chain 和 Telegram 最终消息流式回归。使用--list-scenarios查看诸如session_status等可选探针。 - 当任何场景失败时以非零退出。使用
--allow-failures生成工件而不产生失败退出码。 - 租用的用户驱动并观察共享的 Test Server 群组。不使用生产 Telegram 账户或 bot-to-bot 观察者。
- 在
.artifacts/qa-e2e/...下写入 Telegram QA 报告、摘要和qa-evidence.json。回复场景包含从 driver 发送请求到观察到 SUT 回复的 RTT。
实时传输通道共享一个标准契约,以确保新传输不会偏离;各通道的覆盖矩阵位于
QA 概览 - 实时传输覆盖。
qa-channel 是广泛的合成测试套件,不属于该矩阵。
共享 Telegram 凭据(通过 Convex)(v1)¶
当为实时传输 QA 启用 --credential-source convex(或 OPENCLAW_QA_CREDENTIAL_SOURCE=convex)时,QA lab 会从基于 Convex 的池中获取一个独占租约,在通道运行期间对该租约进行心跳,并在关闭时释放租约。Telegram 始终使用此来源。该章节名称早于 Buzz、Discord、Slack 和 WhatsApp 支持;租约契约在所有类型之间共享。
参考 Convex 项目脚手架:qa/convex-credential-broker/
必需的环境变量:
OPENCLAW_QA_CONVEX_SITE_URL(例如https://your-deployment.convex.site)- 所选角色的一个密钥:
maintainer使用OPENCLAW_QA_CONVEX_SECRET_MAINTAINERci使用OPENCLAW_QA_CONVEX_SECRET_CI- 凭据角色选择:
- CLI:
--credential-role maintainer|ci - 环境变量默认值:
OPENCLAW_QA_CREDENTIAL_ROLE(在 CI 中默认为ci,否则为maintainer)
可选环境变量:
OPENCLAW_QA_CREDENTIAL_LEASE_TTL_MS(默认1200000)OPENCLAW_QA_CREDENTIAL_HEARTBEAT_INTERVAL_MS(默认30000)OPENCLAW_QA_CREDENTIAL_ACQUIRE_TIMEOUT_MS(默认90000)OPENCLAW_QA_CREDENTIAL_HTTP_TIMEOUT_MS(默认15000)OPENCLAW_QA_CONVEX_ENDPOINT_PREFIX(默认/qa-credentials/v1)OPENCLAW_QA_CREDENTIAL_OWNER_ID(可选 trace id)OPENCLAW_QA_ALLOW_INSECURE_HTTP=1允许仅限本地的开发使用回环http://Convex URL。
OPENCLAW_QA_CONVEX_SITE_URL 在正常运行时应使用 https://。
维护者管理命令(池添加/删除/列表)特别需要
OPENCLAW_QA_CONVEX_SECRET_MAINTAINER。
维护者的 CLI 辅助命令:
pnpm openclaw qa credentials doctor
pnpm openclaw qa credentials add --kind telegram --payload-file qa/telegram-credential.json
pnpm openclaw qa credentials list --kind telegram
pnpm openclaw qa credentials remove --credential-id <credential-id>
在实时运行前使用 doctor 检查 Convex 站点 URL、broker 密钥、端点前缀、HTTP 超时以及 admin/list 可达性,且不打印密钥值。在脚本和 CI 工具中使用 --json 获取机器可读输出。
默认端点契约(OPENCLAW_QA_CONVEX_SITE_URL + /qa-credentials/v1)。
请求使用 Authorization: Bearer <role secret> 请求头进行身份验证;以下请求体省略了该请求头:
POST /acquire- 请求:
{ kind, ownerId, actorRole, leaseTtlMs, heartbeatIntervalMs } - 成功:
{ status: "ok", credentialId, leaseToken, payload, leaseTtlMs?, heartbeatIntervalMs? } - 已耗尽/可重试:
{ status: "error", code: "POOL_EXHAUSTED" | "NO_CREDENTIAL_AVAILABLE", ... } POST /payload-chunk- 请求:
{ kind, ownerId, actorRole, credentialId, leaseToken, index } - 成功:
{ status: "ok", index, data } POST /heartbeat- 请求:
{ kind, ownerId, actorRole, credentialId, leaseToken, leaseTtlMs } - 成功:
{ status: "ok" }(或空2xx) POST /release- 请求:
{ kind, ownerId, actorRole, credentialId, leaseToken } - 成功:
{ status: "ok" }(或空2xx) POST /admin/add(仅限维护者密钥)- 请求:
{ kind, actorId, payload, note?, status? } - 成功:
{ status: "ok", credential } POST /admin/remove(仅限维护者密钥)- 请求:
{ credentialId, actorId } - 成功:
{ status: "ok", changed, credential } - 活动租约保护:
{ status: "error", code: "LEASE_ACTIVE", ... } POST /admin/list(仅限维护者密钥)- 请求:
{ kind?, status?, includePayload?, limit? } - 成功:
{ status: "ok", credentials, count }
Telegram 类型的 payload 结构:
{ groupId: string, driverToken: string, sutToken: string }groupId必须是数字形式的 Telegram 聊天 id 字符串。admin/add会为kind: "telegram"验证此结构,并拒绝格式错误的 payload。
由 broker 验证的多通道 payload:
- Buzz:
{ relayUrl: string, roomId: string, driverPrivateKey: string, sutPrivateKey: string, driverAuthTag?: string, sutAuthTag?: string } - Discord:
{ guildId: string, channelId: string, driverBotToken: string, sutBotToken: string, sutApplicationId: string, voiceChannelId?: string } - WhatsApp:
{ driverPhoneE164: string, sutPhoneE164: string, driverAuthArchiveBase64: string, sutAuthArchiveBase64: string, groupJid?: string }
Slack 通道也可以从池中获取租约,但 Slack payload 验证目前位于 Slack QA runner 中,而不是 broker 中。对于 Slack 行,请使用
{ channelId: string, driverBotToken: string, sutBotToken: string, sutAppToken: string }。
向 QA 添加通道¶
新通道适配器的架构和场景辅助函数名称位于
QA 概览 - 添加通道。
最低要求:在共享的 qa-lab 主机接缝上实现传输 runner,为共享场景添加 adapterFactory,在插件清单中声明 qaRunners,挂载为 openclaw qa <runner>,并在 qa/scenarios/ 下编写场景。
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw