跳转至

Mantis

Mantis 为 OpenClaw 行为发布可视化 CI 证据和 PR 评论。 实时传输场景将一个已知存在问题的基线与候选引用进行对比; 聚焦的浏览器通道则可以改用确定性的模拟传输来验证单个候选。 Discord 率先上线,支持真实的机器人认证、公会频道、表情回应、线程和浏览器见证。 Slack 和聚焦的 Control UI 聊天通道也已存在;WhatsApp 和 Matrix 尚未实现。

所有权

  • OpenClaw(extensions/qa-lab/src/mantis/*):场景运行时、pnpm openclaw qa mantis <command> CLI、证据 schema。
  • QA Lab(extensions/qa-lab/src/live-transports/*):实时传输 harness、驱动/SUT 机器人、报告/证据写入器。
  • Crabbox(openclaw/crabbox):预热的 Linux 机器、租约、VNC、crabbox media preview。
  • GitHub Actions(.github/workflows/mantis-*.yml):远程入口点、制品保留。
  • ClawSweeper:独立审查证据,并负责审查/就绪策略。Mantis 工作流调度和证据发布与常规审查发布是分开的;Mantis 结果本身并不授予就绪或合并权限。

CLI 命令

所有命令均为 pnpm openclaw qa mantis <command>,定义在 extensions/qa-lab/src/mantis/cli.ts 中。构建/运行时需要设置 OPENCLAW_ENABLE_PRIVATE_QA_CLI=1 (内置工作流会在构建前设置 OPENCLAW_BUILD_PRIVATE_QA=1 和 OPENCLAW_ENABLE_PRIVATE_QA_CLI=1)。

命令 用途
discord-smoke 验证 Mantis Discord 机器人能否看到公会/频道、发帖并进行反应。
run 针对基线和候选引用运行前后对比场景(仅限 Discord)。
desktop-browser-smoke 租用/复用 Crabbox 桌面,打开可见的浏览器,捕获截图 + 视频。
slack-desktop-smoke 租用/复用 Crabbox 桌面,在其中运行 Slack QA,打开 Slack Web,捕获证据。
visual-task / visual-driver 通用 Crabbox 桌面捕获,支持可选的图像理解断言;visual-driver 是在 crabbox record --while 下启动的驱动端。

每个命令都接受 --repo-root <path> 和 --output-dir <path>;Crabbox 命令还接受 --crabbox-bin、--provider、--machine-class/--class、 --lease-id、--idle-timeout、--ttl 和 --keep-lease。除非另有说明, 本地 CLI 的 provider/class 默认为 hetzner/beast;CI 工作流通常会覆盖这两者。

discord-smoke

pnpm openclaw qa mantis discord-smoke \
  --output-dir .artifacts/qa-e2e/mantis/discord-smoke

调用 Discord REST API(https://discord.com/api/v10)获取机器人 用户、公会、公会的频道以及目标频道,断言该频道属于该公会,然后(除非 指定 --skip-post)发送一条消息并添加 👀 表情回应。写入 mantis-discord-smoke-summary.json 和 mantis-discord-smoke-report.md。

Token 解析顺序:--token-file 的值,然后是 OPENCLAW_QA_DISCORD_MANTIS_BOT_TOKEN (可用 --token-env 覆盖),之后是由 OPENCLAW_QA_DISCORD_MANTIS_BOT_TOKEN_FILE 指定的文件(可用 --token-file-env 覆盖)。公会/频道 ID 来自 OPENCLAW_QA_DISCORD_GUILD_ID / OPENCLAW_QA_DISCORD_CHANNEL_ID(可用 --guild-id / --channel-id 覆盖),并且必须是 17-20 位的 Discord snowflake。设置 OPENCLAW_QA_REDACT_PUBLIC_METADATA=1 可在发布的摘要和报告中将机器人/公会/频道/消息的 ID 和名称替换为 <redacted>。

run

pnpm openclaw qa mantis run \
  --transport discord \
  --scenario discord-status-reactions-tool-only \
  --baseline origin/main \
  --candidate HEAD \
  --output-dir .artifacts/qa-e2e/mantis/local-discord-status-reactions

--transport 目前仅接受 discord。--scenario 是两个内置 ID 之一,每个 ID 都有自己的默认基线引用和预期的前后 标签(extensions/qa-lab/src/mantis/run.runtime.ts):

场景 默认基线 基线预期 候选预期
discord-status-reactions-tool-only 0bf06e953fdda290799fc9fb9244a8f67fdae593 queued-only queued -> thinking -> done
discord-thread-reply-filepath-attachment 81349cdc2a9d5143fd0991ed858b739e7d96e05c 线程回复省略 filePath 附件 线程回复包含该附件

--candidate 默认为 HEAD。其他标志:--credential-source (默认 convex)、--credential-role(默认 ci)、--provider-mode (默认 live-frontier)、--fast(默认开启)、--skip-install、--skip-build。

运行器将 --output-dir 视为一个稳定的容器。它必须指定 仓库内的相对子目录;仓库根目录(.)、绝对路径以及逃逸出仓库的路径都会被拒绝。分离的 git worktree 检出位于 <output-dir>.worktrees/ 下。每个检出都有 唯一的 <lane>-<run-id> 名称,因此中断的运行不会与后来的基线或候选发生冲突。 运行器会在每个检出中运行 pnpm install/pnpm build(除非跳过),然后针对每个 worktree 运行 pnpm openclaw qa discord --scenario <id> --model openai/gpt-5.4 --alt-model openai/gpt-5.4 --allow-failures。 每个通道会写入 discord-qa-reaction-timelines.json 以及一对 <scenario-id>-timeline.html/.png 文件。在请求 Git 删除 检出之前,运行器会将通道证据复制到 <output-dir> 下的私有暂存目录中。

在两个测试通道及其清理完成后,runner 会将 comparison.json、mantis-report.md 和 mantis-evidence.json 添加到暂存集合中,然后替换这五个稳定条目,并在发布失败时进行回滚。失败的尝试会保留此前的完整证据集并写入 error.txt;成功的尝试会移除旧的 error.txt。现有自动化继续直接读取这些稳定路径。每个并发运行的命令应使用独立的输出目录;向同一个共享输出目录发布的操作不会被序列化。已有的无关顶层文件会保留。如果比较未通过(baseline 为 fail,candidate 为 pass),命令将以非零状态退出。

第二个 Discord 场景(discord-thread-reply-filepath-attachment)使用 driver bot 发布一条父消息,创建一个真实线程,以仓库本地的 filePath 调用 SUT 的 message.thread-reply 操作,然后轮询该线程以获取回复和附件文件名。它期望得到一个名为 mantis-thread-report.md 的附件。

desktop-browser-smoke

pnpm openclaw qa mantis desktop-browser-smoke \
  --output-dir .artifacts/qa-e2e/mantis/desktop-browser

租用或复用一台 Crabbox 桌面,在 VNC 会话内启动浏览器,指向 --browser-url(默认 https://openclaw.ai)或渲染后的 --html-file,等待后使用 scrot 截图,可选择使用 ffmpeg 录制 MP4,并通过 rsync 将 desktop-browser-smoke.png / .mp4 / remote-metadata.json 回传到 --output-dir。

选项:

  • --lease-id <cbx_...> 复用已预热的桌面,而不是新建一个。
  • --browser-profile-dir <remote-path> 复用远程 Chrome user-data-dir,使持久化桌面在多次运行之间保持登录状态(用于长期存活的 Discord Web 查看器配置文件)。
  • --browser-profile-archive-env <name> 在启动前从该环境变量恢复 base64 编码的 .tgz Chrome 配置文件归档(默认 OPENCLAW_MANTIS_BROWSER_PROFILE_TGZ_B64);用于 Discord Web 等已登录的见证方。
  • --video-duration <seconds> 控制 MP4 录制时长(默认 10 秒)。
  • --keep-lease(或 OPENCLAW_MANTIS_KEEP_VM=1)将本次运行创建的租约保持打开状态,以便进行 VNC 检查;创建了租约的失败运行默认也会保留该租约。

对于 Discord Web 证据,Mantis 使用专用查看器账户,而不是 bot token。Discord REST oracle(通过 qa discord)仍然具有权威性;当设置了 OPENCLAW_QA_DISCORD_CAPTURE_UI_METADATA=1 时,该场景还会写入一个 Discord Web URL 产物;而 OPENCLAW_QA_DISCORD_KEEP_THREADS=1 会让线程保持打开足够长的时间,以便浏览器打开它。

GitHub 工作流优先通过 MANTIS_DISCORD_VIEWER_CHROME_PROFILE_DIR 使用持久化查看器配置文件(完整的配置文件归档可能超出 GitHub 的 secret 大小限制);对于小型/引导用配置文件,它可以改为从 MANTIS_DISCORD_VIEWER_CHROME_PROFILE_TGZ_B64 恢复 base64 编码的 .tgz。如果两个来源均未配置,工作流仍会发布确定性的基线/候选截图,并记录已跳过登录见证方。

slack-desktop-smoke

pnpm openclaw qa mantis slack-desktop-smoke \
  --output-dir .artifacts/qa-e2e/mantis/slack-desktop \
  --gateway-setup \
  --scenario slack-canary \
  --keep-lease

租用或复用一台 Crabbox 桌面,将 checkout 同步到 VM 中,在其中运行 pnpm openclaw qa slack,在 VNC 浏览器中打开 Slack Web,捕获桌面,并将 Slack QA 产物(slack-qa/)和 VNC 截图/视频一起复制回本地。这是唯一一种 SUT gateway 和浏览器都运行在同一个 VM 内的 Mantis 形态。

使用 --gateway-setup 时,该命令会在 VM 中的 $HOME/.openclaw-mantis/slack-openclaw 创建一个持久的、可随时丢弃的 OpenClaw home,为目标频道修补 Slack Socket Mode 配置,启动 openclaw gateway run --dev --allow-unconfigured --port 38973,并让 Chrome 在 VNC 会话中保持运行;省略 --gateway-setup 则改为运行普通的 bot 对 bot Slack QA 通道。

--credential-source env 所需的环境变量(本地默认为 env;角色默认为 maintainer):

  • OPENCLAW_QA_SLACK_CHANNEL_ID
  • OPENCLAW_QA_SLACK_DRIVER_BOT_TOKEN
  • OPENCLAW_QA_SLACK_SUT_BOT_TOKEN
  • OPENCLAW_QA_SLACK_SUT_APP_TOKEN
  • OPENCLAW_LIVE_OPENAI_KEY 用于远程模型通道(如果本地只设置了 OPENAI_API_KEY,Mantis 会在调用 Crabbox 之前将其复制到 OPENCLAW_LIVE_OPENAI_KEY)

使用 --credential-source convex 时,Mantis 会在创建 VM 之前从共享池中租用 Slack SUT 凭据,并将频道 ID、app token 和 bot token 作为 OPENCLAW_MANTIS_SLACK_* 环境变量转发到 VM 中,因此 GitHub 工作流只需要 Convex broker secret,而不需要原始 Slack token。

其他选项:--slack-url <url> 打开指定的 URL(否则 Mantis 从 auth.test 推导出 https://app.slack.com/client/<team>/<channel>);--slack-channel-id <id> 设置 gateway 允许列表频道;OPENCLAW_MANTIS_SLACK_BROWSER_PROFILE_DIR 控制 VM 内的持久化 Chrome 配置文件(默认 $HOME/.config/openclaw-mantis/slack-chrome-profile);--approval-checkpoints 运行原生 Slack 审批场景(slack-approval-exec-native、slack-approval-plugin-native),并渲染 pending/resolved 检查点截图,而不是进行 gateway 设置(与 --gateway-setup 互斥);--hydrate-mode source|prehydrated、--provider-mode、--model、--alt-model 和 --fast 会透传给 Slack live 通道。

审批检查点截图是根据场景观察到的 Slack API 消息渲染的,而不是实时 Slack UI;只有当租约的浏览器配置文件已经登录时,slack-desktop-smoke.png 才是 Slack Web 本身的证明。

证据清单

发布器要求报告旁的 mantis-evidence.json 使用 schema 版本 2。每个被包含的通道都必须声明 expectationMet;当通道的期望未得到满足时,发布器会对声称的 pass 进行降级。例如:

{
  "schemaVersion": 2,
  "id": "discord-status-reactions",
  "title": "Mantis Discord Status Reactions QA",
  "summary": "Human-readable top summary for the PR comment.",
  "scenario": "discord-status-reactions-tool-only",
  "comparison": {
    "baseline": {
      "sha": "<baseline-sha>",
      "status": "fail",
      "expected": "queued-only",
      "expectationMet": true
    },
    "candidate": {
      "sha": "<candidate-sha>",
      "status": "pass",
      "expected": "queued -> thinking -> done",
      "expectationMet": true
    },
    "pass": true,
    "outcome": "pass"
  },
  "artifacts": [
    {
      "kind": "timeline",
      "lane": "baseline",
      "label": "Baseline queued-only",
      "path": "baseline/timeline.png",
      "targetPath": "baseline.png",
      "alt": "Baseline Discord timeline",
      "width": 420
    }
  ]
}

此 manifest 是一份呈现契约,而非经认证的证明收据。它不能独立确立仓库/PR 归属、当前 HEAD 的新鲜度、执行授权或某个断言的真实性。仅凭视频、进程退出码或声明的预期结果不足以构成行为证明。在依赖其结果之前,请审查底层观测数据和执行溯源。基础设施故障和缺失的观测均无法得出明确结论,不能作为基线复现了该 bug 的证据。

本地 qa mantis run 生产者仍然输出 schema 版本 1,发布者会拒绝该版本。除非从观测中推导出其 lane(通道)预期,否则不要将该输出重新标记为版本 2;工作流生产者输出的才是版本 2。

工件的 path 相对于 manifest 所在目录;targetPath 相对于已配置的 R2/S3 工件前缀。scripts/mantis/publish-pr-evidence.mjs 会拒绝路径穿越,并在文件缺失时跳过 "required": false 的条目。

工件种类:timeline(确定性的前后对照截图)、desktopScreenshot(VNC/浏览器截图)、motionPreview(来自录制的内嵌动画 GIF)、motionClip(按动作裁剪的 MP4)、fullVideo(完整录制)、metadata(JSON/日志 sidecar 文件)、report(Markdown 报告)。

对于 qa mantis run,稳定的输出容器布局如下:

.artifacts/qa-e2e/mantis/<run-id>/
  error.txt # failures only
  mantis-report.md
  mantis-evidence.json
  baseline/
  candidate/
  comparison.json
.artifacts/qa-e2e/mantis/<run-id>.worktrees/
  baseline-<pid>-<uuid>/
  candidate-<pid>-<uuid>/

运行完成后,worktree 根目录通常为空。通道目录在活动期间或清理过程特意保留某个目录用于诊断时出现。发生中断时,命令收尾和工件暂存会与 Git 移除共用同一清理预算。如果该预算耗尽,或无法确认命令子进程已停止,Mantis 会保留 worktree 以供检查。默认的本地命令运行器要求 Linux 或 macOS 的进程树所有权。它在生成命令之前会拒绝 Windows 阶段,因为目前无法在 Windows 上验证子进程是否已终止;任何已准备好的目录都会被保留。如果 git worktree add 在注册之前失败,Mantis 可能会留下其空的、具有唯一名称的已准备目录,而不是通过一个可能已被替换的路径名进行删除。

每次失败的尝试都会写入 <output-dir>/error.txt。抛出的错误,或预期 CLI 中断的简明 stderr 诊断信息,会报告该确切路径。当 Git 不再拥有其注册信息后,Mantis 不会递归删除 worktree:如果清理失败,请结合所报告的 error.txt 检查 <output-dir>.worktrees/ 下保留的唯一目录,并在解决失败原因后通过 Git 将其移除。如果某个受管路径在 Git 注册仍然存在时消失,清理会以 fail closed 方式失败,而不是重新创建该路径。启动时,Mantis 还会检查确切的历史路径 <output-dir>/worktrees/baseline 和 <output-dir>/worktrees/candidate,如果它们仍处于已注册且存在状态,则通过 Git 将其移除。该遗留目录中的其他已注册或未注册条目将保持原样,不予处理。

截图是证据而非机密,但仍需遵守脱敏规范:截图中可能出现私密频道名称、用户名或消息内容。对于公开工件上传,请设置 OPENCLAW_QA_REDACT_PUBLIC_METADATA=1;在 Discord 和 Slack 的 GitHub 工作流中,该选项默认启用。

GitHub 自动化

scripts/mantis/publish-pr-evidence.mjs 是可复用的发布器。工作流调用它时会传入 manifest、目标 PR、工件目标根目录、评论标记、工件 URL、运行 URL 和请求来源。它会将声明的工件上传到 Mantis R2 存储桶,生成一条摘要优先的 PR 评论,其中包含内嵌图片/预览和视频链接,然后更新已有的标记评论或创建新的标记评论。所需环境变量:

  • MANTIS_ARTIFACT_R2_ACCESS_KEY_ID
  • MANTIS_ARTIFACT_R2_SECRET_ACCESS_KEY
  • MANTIS_ARTIFACT_R2_BUCKET(工作流设置为 openclaw-crabbox-artifacts)
  • MANTIS_ARTIFACT_R2_ENDPOINT
  • MANTIS_ARTIFACT_R2_REGION(工作流设置为 auto)
  • MANTIS_ARTIFACT_R2_PUBLIC_BASE_URL(工作流设置为 https://artifacts.openclaw.ai)

评论通过 Mantis GitHub App(MANTIS_GITHUB_APP_ID / MANTIS_GITHUB_APP_PRIVATE_KEY)发布,而非 github-actions[bot],并使用隐藏的标记评论作为更新键(upsert key)。

工作流 触发方式 功能说明
Mantis Discord Smoke 手动触发 针对所选 ref 运行 discord-smoke。
Mantis Discord Status Reactions 手动触发 构建独立的 baseline/candidate worktree,在每个 worktree 上运行 discord-status-reactions-tool-only,在 Crabbox 桌面浏览器中渲染每个通道的时间线,使用 crabbox media preview 生成按动作裁剪的 GIF/MP4 预览,上传工件并发布内嵌 PR 证据。
Mantis Scenario 手动触发 通用调度器:接收 scenario_id(discord-status-reactions-tool-only、discord-thread-reply-filepath-attachment、slack-desktop-smoke、web-ui-chat-proof)、baseline_ref、candidate_ref、pr_number,并将其转发到匹配的场景工作流。
Mantis Slack Desktop Smoke 手动触发 租用一台 Crabbox Linux 桌面(默认为 aws,可选择 hetzner),对候选版本运行 slack-desktop-smoke --gateway-setup,录制桌面,生成动态预览,上传工件,并在提供 PR 编号时发布 PR 证据。
Mantis Web UI Chat Proof 手动触发 对候选版本运行针对性的 OpenClaw Control UI 聊天 Playwright 验证,验证浏览器通过模拟 Gateway 发送流量,捕获截图/视频工件,并发布 PR 证据。该测试通道仅为 Web 聊天验证,不涵盖 WinUI/原生应用或任意可视化验证。

Mantis Discord Status Reactions 接受 baseline_ref/candidate_ref,并在使用携带机密的凭据运行前,验证解析后的 SHA 要么是 origin/main 的祖先,要么是发布标签(v*),要么是未关闭 PR 的 head。

上述旧版场景工作流仍可通过手动 Actions 分发使用。

不要依赖之前的 @clawsweeper mantis ... 示例作为专用分发命令。ClawSweeper 当前的命令解析器会将无法识别的提及路由到通用帮助,而不是一条键入的 Mantis 分发命令。

ClawSweeper #1425 和 OpenClaw #138953 中的独立请求绑定集成让审阅者可以在完成其原始审阅之前选择相关验证。它不会恢复审阅后自动记录,也不要求在每个 PR 上运行每个检查。

托管执行需要 main 上的受信任生产者工作流,以及匹配的 ClawSweeper Worker/运行时部署;合并文档不会激活它。

仍然需要现有的 Convex 凭据服务,但其 API 会被复用,无需更改 Convex schema 或进行部署。

一旦该集成部署完成,人类维护者可以在不提供 SHA 的情况下请求一次包含可用验证的审阅:

@clawsweeper proof
@clawsweeper proof web-ui-chat-proof
@clawsweeper proof telegram-bot-e2e-proof
@clawsweeper proof web-ui-chat-proof,telegram-bot-e2e-proof

不带参数的命令让审阅者选择有用的检查;显式选择则请求每个指定的检查。审阅会解析当前 PR 的 head。

Control UI 支持针对模拟 Gateway 的固定聊天冒烟测试;Telegram 支持有界、仅数据的 Test Server 方案。旧版 Crabline 配方不是第三种内联工具。

缺失、延迟或不完整的观测结果仍视为无结论。审阅者会在同一审阅中评估结果;仅成功执行并不能清除验证、其他就绪阻塞项或合并要求。

所选检查共享 20 分钟的验证上限,并进一步受原始审阅剩余时间减去最终决策预留时间的约束。使用默认的 20 分钟审阅超时和 90 秒预留时间,如果立即调用,则最多为 18 分 30 秒;经过分析后时间会更少。

这是上限,不是固定的等待时间,也不是每个检查的独立新预算。消费者超时本身不会取消已分发的生产者;生产者清理和凭据/租约限制仍然是独立的。

Telegram 验证是独立的 QA 入口点

Telegram 不是 mantis-scenario.yml 或 qa mantis run 中的选项。

pnpm openclaw qa telegram 使用 QA Lab Telegram 适配器,以及位于 .agents/skills/telegram-e2e-userbot/SKILL.md 的仓库技能。

该技能还通过自己的运行器支持针对性的真实用户录制。

该技能使用 TDLib 对接 Telegram 的 Test Server,并搭配独占租用的 Convex QA 凭据、全新的 Gateway 和独立的用户观察者。

前置条件包括依赖就绪的 exact-ref 运行时、固定版本的 TDLib 设置、经过认证的 broker 访问权限,以及互不相同且未被占用的 Gateway/提供方端口。

其 doctor 命令会获取租约并联系 Telegram:这是实时操作,而非离线就绪检查。

未经测试账户活动授权,请勿运行它。

录制器可以观察消息、编辑、删除、反应和正在输入等状态。

判断所选 SUT 在记录刺激之后产生的事件,将消息 ID 与预期提供方请求关联,并验证清理情况。

QA 适配器当前驱动暴露的消息/编辑流较窄;请选择观测实际上能覆盖所声明内容的入口点。

通用的成功回复并不能证明格式、反应、生命周期或线程行为。

在进行 Telegram 演练之前,请阅读该技能及其功能验证映射。

凭据租约不是方案沙箱:自定义命令操作可以使用租用的测试身份。

将凭据处理和执�行保存在明确授权且隔离的 worker 中,绝不要在普通只读审阅中进行。

ClawSweeper 审阅中的所选验证

请求绑定的验证集成让 ClawSweeper 可以在完成当前审阅之前选择相关检查。它不会在每个 PR 上运行所有检查。

确切的 PR head 由审阅解析,而不是由维护者输入。

@clawsweeper proof 请求一次包含可用验证的审阅,作为手动覆盖方式;结果会在该审阅中评估,而不是生成第二次审阅。

自动验证入口包括:

  • Telegram Test Server:一个有界、仅数据的测试者消息与按钮点击方案,包含确定性模型回复、流式/原生命令设置,以及审阅者需要观察的行为。这可以覆盖的范围不止是通用问候,还包括选定的格式或命令行为。
  • Control UI:针对模拟 Gateway 的现有固定聊天冒烟测试配方。这不是任意的浏览器任务运行器,也不是对所有 UI 行为的验证。

独立的固定 Crabline 配方仍是一个生产者入口点;它不是第三个自动工具,也不是强制的三项检查批次。

受信任的外部控制器拥有 Telegram userbot 和真实 bot Token。候选者会收到一次性 Token 别名和受限 DM API 代理,而不是 QA 租约、Telegram 会话、GitHub Token 或部署凭据。候选者运行在没有 Docker socket 的内部网络上的一个一次性 Crabbox 本地容器中。部署需要一个已验证此隔离 Crabbox SSH 生命周期的 Linux/Podman 环境;通用的 Docker 冒烟运行不能证明该兼容性。

控制器复用现有的 Convex acquire、heartbeat、payload 和 release API。不需要 Convex schema 更新、隔离端点或 broker 部署。审查所有权和单次运行授权由 ClawSweeper 服务使用受信任工作流的 GitHub Actions OIDC 身份进行检查。过期或已撤销的权限会停止特权发送和代理转发。记录器父进程死亡守卫会在其控制器退出时停止记录器。这些安全措施并不声称原生 TDLib 后台流量为零。

Telegram 工件包含有界的完整时间线、provider 请求、格式实体和按钮标签,并已将已知的私有值脱敏。超大或不完整的观测会失败关闭。其断言结果保持为 inconclusive:原始审查者必须根据声明评估这些观测。绿色的进程退出、预设回复或视频不会自动清除证明或其他就绪阻塞项。Bot 注册/webhook 操作是模拟的;实时生产 Telegram、群组、媒体和无限制 agent 命令不在此有界计划范围内。传输 profile 显示名称是合成的,而路由 ID 和所选 bot 用户名在需要时保留。消息文本不会被此投影重写。对真实 profile 名称或基于用户名的 tester 路由的测试不在此证明范围内。

Machines and secrets

本地 CLI Crabbox 默认值为 --provider hetzner --class beast;使用 --provider、--class/--machine-class 或 OPENCLAW_MANTIS_CRABBOX_PROVIDER / OPENCLAW_MANTIS_CRABBOX_CLASS 进行覆盖。GitHub 工作流通常会同时覆盖两者(例如 --class standard,以及 Slack 工作流的 aws/hetzner provider 选择输入)。如果某个 provider 太慢或不可用,请在相同的 Crabbox 接口后面添加它,而不是硬编码回退。

VM 基线:Linux,具备桌面能力的 Chrome/Chromium、CDP 访问、VNC/noVNC、Node 24.16+ 或 26.1+ 和 pnpm、一个 OpenClaw checkout,以及对目标传输、GitHub、模型 provider 和凭据 broker 的出站访问。

在 Mantis 命令和工作流中使用的凭据和环境名称:

  • OPENCLAW_QA_DISCORD_MANTIS_BOT_TOKEN
  • OPENCLAW_QA_DISCORD_GUILD_ID
  • OPENCLAW_QA_DISCORD_CHANNEL_ID
  • 本地 qa mantis run --credential-source env 还需要 OPENCLAW_QA_DISCORD_DRIVER_BOT_TOKEN、OPENCLAW_QA_DISCORD_SUT_BOT_TOKEN 和 OPENCLAW_QA_DISCORD_SUT_APPLICATION_ID。GitHub 工作流通常使用 --credential-source convex 以及下面的 broker 凭据,而不是原始 Discord bot Token。
  • 用于公共工件上传的 OPENCLAW_QA_REDACT_PUBLIC_METADATA=1
  • OPENCLAW_QA_CONVEX_SITE_URL、OPENCLAW_QA_CONVEX_SECRET_CI
  • OPENAI_API_KEY
  • CRABBOX_COORDINATOR / CRABBOX_COORDINATOR_TOKEN(工作流也接受 OPENCLAW_QA_MANTIS_CRABBOX_COORDINATOR / _TOKEN 作为回退,并在调用 Crabbox 之前将它们映射到普通名称)
  • CRABBOX_ACCESS_CLIENT_ID、CRABBOX_ACCESS_CLIENT_SECRET
  • MANTIS_GITHUB_APP_ID、MANTIS_GITHUB_APP_PRIVATE_KEY

Mantis runner 绝不能打印 Discord 或 Slack bot Token、provider API 密钥、浏览器 cookies、auth profile 内容、VNC 密码或原始凭据负载。如果 Token 泄漏到 issue、PR、聊天或日志中,请在替换密钥存储后轮换它。

Run outcomes

传输前/后场景区分这些结果,以便不稳定的环境不会被误读为产品回归:

  • Bug 已复现:基线以场景预期的方式失败。
  • Harness 失败:在 oracle 有意义之前,环境设置、凭据、传输 API、浏览器 或 provider 失败。

仅候选者的浏览器证明报告候选者是否通过了模拟 Gateway 和可见 UI 断言;它不声称基线复现。

Adding a scenario

实时传输场景按传输以 TypeScript 定义(参见 extensions/qa-lab/src/mantis/run.runtime.ts 中的 MANTIS_SCENARIO_CONFIGS, 了解 Discord 前/后形状),而不是独立的声明式文件格式。 每个场景需要:id 和标题、传输、所需凭据、基线 ref 策略、候选者 ref 策略、 OpenClaw 配置补丁、设置/刺激步骤、预期的基线和候选者 oracle、视觉捕获目标、 超时预算以及清理步骤。

聚焦的仅候选者浏览器证明可以使用专用的确定性 E2E 测试和工作流。保持其范围明确, 在执行前验证候选者 ref,隔离基于密钥的发布,并输出相同的证据 manifest 契约。

优先使用小型、类型化的 oracle,而不是视觉检查:Discord 反应状态或消息引用、 Slack 线程 ts/reaction API 状态、电子邮件消息 id 和 headers。当 UI 是唯一可靠 的可观测项时使用浏览器截图,并在存在平台 API oracle 时保持视觉检查作为其附加项。

在 Discord 和 Slack 之后,相同的 runner 形状扩展到 WhatsApp(QR 登录、 重新识别、投递、媒体、反应)和 Matrix(加密房间、线程/回复关系、重启恢复); 两者都尚未实现。

Open questions

  • 当复用现有 Mantis bot 时,哪个 Discord bot 应作为 driver,哪个作为 SUT?
  • GitHub 应为 PR 保留 Mantis 工件多久?
  • 对于公共 PR,截图在上传前是否应脱敏或裁剪?

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw