Slack QA
Slack QA¶
该命令以一个真实的私有 Slack 频道为目标,包含两个不同的 Bot:一个由测试框架控制的驱动 Bot,以及一个由子 OpenClaw 网关通过内置 Slack 插件启动的 SUT Bot。
Slack QA 适配器加载后,需要异步代理捕获支持,以便可以在 Gateway 线程上不运行 SQLite 的情况下读取写入证据。如果缺少该能力,适配器创建过程会要求你先升级,然后再获取凭据或联系 Slack。这并不能保证当前 QA CLI 能在较旧主机上加载:请使用匹配的当前源码检出,并参阅旧主机导入限制。
Agent E2E 配方¶
使用被测源码检出中的 .agents/skills/slack-e2e/SKILL.md,获取可复用的原生 fixtures、Gateway 回复以及运行时/配置实验。如果已有能访问 QA broker 的已认证 Convex CLI:
pnpm openclaw qa slack --doctor
pnpm openclaw qa slack \
--scenario-file qa/scenarios/channels/slack-e2e-lifecycle.yaml
这些可选模式会在内存中发现凭据,并默认使用 Convex、CI 角色和 mock-openai。显式标志或凭据环境设置优先;普通 qa slack 的默认行为保持不变。对于声明了 execution.channel: slack 和 execution.config.agentE2e: true 的完整自定义 YAML 流程,请重复使用 --scenario-file。原生写入只执行一次;正数 retryCount 值会被拒绝。
就绪检查会核验实际租约(lease)的身份、共享工作区、频道访问权限、Gateway 连接以及声明的权限范围。完整生命周期还要求 driver 具备 reactions:read、reactions:write、files:read 和 files:write。下面的 driver 清单包含这些能力。现有安装需要应用所有者添加缺失的权限范围并重新安装应用,然后才能重新运行生命周期。缺少某个权限范围会阻塞该操作和完整生命周期验证,但不会影响基本文本流程。运行器不会为了得到通过的结果而授予权限或轮换凭据。这些 fixture 操作由 Bot OAuth 权限范围授权,而非工作区管理员权限。
driver 使用 Web API 调用;只有 SUT 拥有 Socket Mode。已存储的消息/文件/回应(reaction)回读可证明原生状态,而相关联的 SUT 回复可证明 Gateway 的入站与投递。两者都无法证明客户端渲染、人工斜杠命令、按钮点击、Agent View 或人工输入。如需验证这些主张,请使用手动客户端工作流。
清理会在进程关闭之后、临时捕获状态被移除之前,捕获最终的 Gateway 写入回执;然后在释放租约之前,仅移除自己拥有的 fixtures。私有的 <scenario-id>-slack-e2e.json 回执可区分已接受的写入、已存储的状态和未完成的清理。
直接凭据设置¶
当使用 --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_APPROVAL_CHECKPOINT_DIR为 Mantis 启用可视化审批检查点。适配器会写入<scenario>.pending.json和<scenario>.resolved.json,然后等待匹配的.ack.json文件。OPENCLAW_QA_SLACK_APPROVAL_CHECKPOINT_TIMEOUT_MS覆盖检查点确认超时时间。默认值为120000。
通过 Slack 实时适配器公开的标准 YAML 场景:
thread-follow-upthread-isolation
Slack YAML 模块场景(qa/scenarios/channels/slack-*.yaml):
slack-canaryslack-mention-gatingslack-mpim-app-mention-dedupe- 打开一个真实的 C 前缀群组 DM,在消息/app-mention 双投递后验证恰好只有一条 SUT 回复,确认原生线程跟进可以取回该 Bot 回复,然后关闭该 MPIM。slack-allowlist-blockslack-channel-disabled-warning- 一个可选的真实 Slack 探测,确认配置为禁用的频道会发出结构化警告而不进行回复。slack-top-level-reply-shapeslack-restart-resumeslack-progress-commentary-true、slack-progress-commentary-false、slack-progress-commentary-omitted以及slack-progress-commentary-verbose-dedupe/slack-progress-commentary-verbose-full- 这些可选的真实 Slack 探测用于独立的评论/工具进度控制、省略该键时的旧版默认行为,以及持久化 verbose 进度的单次投递行为。on探测需要一个安全的 Exec 摘要,且不含命令文本或输出;full探测要求在单独的工具输出消息中包含精确的 stdout 标记。两者使用同一条命令,并要求一个与最终答案分离的 commentary 身份。完整详细模式允许使用运行时的命令元数据和一个独立的开始摘要,但要求具有唯一的已完成输出身份。Slack 在投递时可能会去除命令摘要头部,因此标识已完成输出的是精确的输出行,而不是工具标签。失败时会保留有边界的展示事实,不包含原始 Slack 消息或平台身份,包括标记格式以及缺少命令标记的sleep摘要。slack-reaction-glyph-native- 一个可选的实时消息工具 reaction 场景。指示 agent 传递精确的✅字形,并确认 Slack 在目标消息上为 SUT Bot 存储了white_check_mark。slack-chart-presentation-native- 一个可选的可移植图表场景,验证原生data_visualization块和精确的无障碍文本。slack-table-presentation-native- 一个可选的可移植表格场景,验证原生data_table块、精确的行以及无障碍文本。slack-table-invalid-blocks-fallback- 一个可选的直接传输场景,它通过生产环境的 Slack 发送路径发送一个结构上可读但超限的原始表格,包含 101 行数据及其表头,证明 Slack 本身会返回invalid_blocks,并验证存储的禁用格式回退内容完整且不包含原生数据块。场景详情只保留安全的错误码、计数和布尔证据。slack-approval-exec-native- 一个可选的原生 Slack exec 审批场景。通过网关请求 exec 审批,验证 Slack 消息带有原生审批按钮,处理该审批,并验证处理后的 Slack 更新。slack-approval-plugin-native- 一个可选的原生 Slack 插件审批场景。同时启用 exec 和插件审批转发,使插件事件不会被 exec 审批路由抑制,然后验证相同的待处理/已解决原生 Slack UI 路径。slack-codex-approval-exec-native- 一个可选的 Codex Guardian 命令审批场景。在 Guardian 模式下启用 Codex 插件,将通过 Slack 发起的 Gateway agent 回合路由到 Codex 应用服务器测试框架(app-server harness)中,等待针对codex的原生 Slack 插件审批提示,处理该审批,并验证 Codex 回合最终产生预期的命令输出和 assistant 标记。slack-codex-approval-plugin-native- 一个可选的 Codex Guardian 文件审批场景。使用工作区外部的apply_patch指令,使 Codex 发出应用服务器文件变更审批路由,然后验证相同的原生 Slack 待处理/已解决审批路径、最终的 assistant 标记,并在清理前验证精确的文件内容。
Codex 审批场景需要一个 openai/* 或 codex/* --model、正常的实时模型凭据,以及 Codex 插件接受的 Codex 认证或 API 密钥认证。
场景详情包括 Codex app-server 方法、所选 Codex 模型键、最终 Codex 回合状态,以及经过脱敏的 Slack 审批元数据旁边的操作标记验证。
输出产物:
qa-suite-report.mdqa-suite-summary.jsonqa-evidence.json- 实时传输检查的证据条目。approval-checkpoints/- 仅当 Mantis 设置OPENCLAW_QA_SLACK_APPROVAL_CHECKPOINT_DIR时;包含检查点 JSON、 确认 JSON,以及待处理/已解决截图。
设置 Slack 工作区¶
该 lane 需要在同一个工作区中有两个不同的 Slack 应用,以及一个两个 bot 都是成员的频道:
channelId- 两个 bot 都已被邀请加入的频道的Cxxxxxxxxxxid。 请使用专用频道;该 lane 每次运行都会发帖。driverBotToken- Driver 应用的 bot token(xoxb-...)。sutBotToken- SUT 应用的 bot token(xoxb-...),它必须与 driver 是不同的 Slack 应用,以便其 bot user id 不同。sutAppToken- SUT 应用的应用级 token(xapp-...),具有connections:write,由 Socket Mode 使用,以便 SUT 应用可以接收事件。
优先使用专用于 QA 的 Slack 工作区,而不是复用生产工作区。
下面的 SUT manifest 有意将捆绑的 Slack 插件的生产安装
(extensions/slack/src/setup-shared.ts:12)缩小到实时 Slack QA 套件覆盖的
权限和事件。对于用户看到的生产频道设置,请参阅
Slack 频道快速设置;QA Driver/SUT
对是有意分开的,因为该 lane 需要在同一个工作区中有两个不同的 bot user
id。
1. 创建 Driver 应用
前往 api.slack.com/apps → 创建新应用 → 从 manifest 创建 → 选择 QA 工作区,粘贴以下 manifest, 然后 安装到工作区:
{
"display_information": {
"name": "OpenClaw QA Driver",
"description": "Test driver bot for OpenClaw QA Slack live lane"
},
"features": {
"bot_user": {
"display_name": "OpenClaw QA Driver",
"always_online": true
}
},
"oauth_config": {
"scopes": {
"bot": [
"channels:history",
"chat:write",
"files:read",
"files:write",
"groups:history",
"reactions:read",
"reactions:write",
"users:read"
]
}
},
"settings": {
"socket_mode_enabled": false
}
}
复制 Bot User OAuth Token(xoxb-...)——它将成为
driverBotToken。driver 可以读写 fixture 消息、reaction 和文件;
它既不需要事件订阅,也不需要 Socket Mode。
2. 创建 SUT 应用
在同一工作区中重复 创建新应用 → 从 manifest 创建。此 QA 应用
有意使用捆绑的 Slack 插件生产 manifest
(extensions/slack/src/setup-shared.ts:12)的更窄版本:
reaction 作用域和事件被省略,因为实时 Slack QA 套件尚未覆盖
reaction 处理。
{
"display_information": {
"name": "OpenClaw QA SUT",
"description": "OpenClaw QA SUT connector for OpenClaw"
},
"features": {
"bot_user": {
"display_name": "OpenClaw QA SUT",
"always_online": true
},
"app_home": {
"home_tab_enabled": true,
"messages_tab_enabled": true,
"messages_tab_read_only_enabled": false
}
},
"oauth_config": {
"scopes": {
"bot": [
"app_mentions:read",
"assistant:write",
"channels:history",
"channels:read",
"chat:write",
"commands",
"emoji:read",
"files:read",
"files:write",
"groups:history",
"groups:read",
"im:history",
"im:read",
"im:write",
"mpim:history",
"mpim:read",
"mpim:write",
"pins:read",
"pins:write",
"usergroups:read",
"users:read"
]
}
},
"settings": {
"socket_mode_enabled": true,
"event_subscriptions": {
"bot_events": [
"app_home_opened",
"app_mention",
"channel_rename",
"member_joined_channel",
"member_left_channel",
"message.channels",
"message.groups",
"message.im",
"message.mpim",
"pin_added",
"pin_removed"
]
}
}
}
Slack 创建应用后,在其设置页面上执行两项操作:
- 安装到工作区 → 复制 Bot User OAuth Token → 它将成为
sutBotToken。 - 基本信息 → 应用级 Token → 生成 Token 和 Scopes → 添加
作用域
connections:write→ 保存 → 复制xapp-...值 → 它 将成为sutAppToken。
通过分别对每个 token 调用 auth.test,验证两个 bot 具有不同的
user id。运行时通过 user id 区分 driver 和 SUT;将同一个应用
复用于两者会立即导致 mention-gating 失败。
3. 创建频道
在 QA 工作区中创建一个频道(例如 #openclaw-qa),并在频道内
邀请两个 bot:
从 频道信息 → 关于 → 频道 ID 复制 Cxxxxxxxxxx id——它
将成为 channelId。公共频道可以工作;如果使用私有频道,
两个应用已经具有 groups:history,因此 harness 的历史读取仍会
成功。
4. 注册凭据
有两种选择。对于单机器调试,使用环境变量(设置四个
OPENCLAW_QA_SLACK_* 变量并传递 --credential-source env),或者向
共享 Convex 池播种,以便 CI 和其他维护者可以借用它们。
对于 Convex 池,将四个字段写入一个 JSON 文件:
{
"channelId": "Cxxxxxxxxxx",
"driverBotToken": "xoxb-...",
"sutBotToken": "xoxb-...",
"sutAppToken": "xapp-..."
}
在你的 shell 中导出 OPENCLAW_QA_CONVEX_SITE_URL 和
OPENCLAW_QA_CONVEX_SECRET_MAINTAINER 后,注册并验证:
pnpm openclaw qa credentials add \
--kind slack \
--payload-file slack-creds.json \
--note "QA Slack pool seed"
pnpm openclaw qa credentials list --kind slack --status all --json
预期 count: 1、status: "active",且没有 lease 字段。
5. 端到端验证
在本地运行该 lane,以确认两个 bot 可以通过 broker 相互通信:
pnpm openclaw qa slack \
--credential-source convex \
--credential-role maintainer \
--output-dir .artifacts/qa-e2e/slack-local
绿色运行会在远小于 30 秒内完成,并且 qa-suite-report.md
显示 slack-canary 和 slack-mention-gating 的状态均为 pass。如果该
lane 挂起约 90 秒,并以 Convex credential pool exhausted
for kind "slack" 退出,要么池为空,要么每一行都已被租约占用 - qa
credentials list --kind slack --status all --json 会告诉你具体是哪种情况。
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw