name: smoke-test
description: CloseCrab bot 部署/重启后健康检查。当用户说"体检"、"smoke test"、"health check"、"检查 bot"、"bot 还好吗"、"刚部署完确认下"或部署/重启后想验证状态时触发。覆盖进程、Firestore、worker secrets、日志活性、近期错误,并扫描 ~/.closecrab/smoke-tests.d/ 下用户自定义 drop-in 检查。
CloseCrab Bot Smoke Test
部署/重启 CloseCrab bot 后的一站式健康检查。基于 GBrain smoke-test 设计模式移植 — 但 v1 是 detect-only(不做 auto-fix,因为 production bot 上自动修复风险太高)。
v2(Round 3 沉淀, 2026-05-20): 加入 evolution loop 学到的两项 anti-pattern 检查:
binary_alignment— 比对 bot 进程 lstart vs git HEAD commit time,落后即 FAIL,并打印 SIGHUP 重启命令。防 Round 3 anti-pattern 1(stale binary 跑 fast-path test 测出假 PASS)。fast_path_callbacks— 静态扫closecrab/channels/*.py,所有_make_input_callback必须有is_inbox参数。防 Round 2/3 anti-pattern(inbox 派活走 user-facing 5min × N timeout)。
这两个 check 由 scripts/check-binary-alignment.py + bash 内嵌 grep 实现,无新依赖。
触发条件
- 用户说:"体检 bunny"、"检查 bot 状态"、"smoke test"、"刚重启完确认下"
- 任何 bot deploy / restart 后的自我验证
- Inbox 收到
/health命令(agent 自动回 JSON) - 调度脚本
dispatch-bot.sh之后
用法
# 检查单个 bot(带颜色,人读)
~/CloseCrab/scripts/closecrab-smoke-test.sh bunny
# 检查本机所有跑着的 bot
~/CloseCrab/scripts/closecrab-smoke-test.sh --all
# 只看总结行(适合脚本调用)
~/CloseCrab/scripts/closecrab-smoke-test.sh bunny --quiet
# JSON 输出(适合 agent 自动消费 / inbox 回复)
~/CloseCrab/scripts/closecrab-smoke-test.sh bunny --json
# JSON + 修复建议(skillpack-check 模式,给 agent 看)
~/CloseCrab/scripts/closecrab-smoke-test.sh bunny --json --actions
Exit code = failed check 数(0 = 全过)。任何 caller 都可以拿 exit code 直接决策。
JSON Schema(--json 输出)
{
"status": "ok | warn | fail", // 总状态:fail>0 = fail, skip>0 = warn, all pass = ok
"pass": 8,
"fail": 1,
"skip": 3,
"bots": ["bunny"],
"results": [
{"name": "bot_process", "status": "pass", "detail": "pid=12345 rss=265MB"},
...
],
"actions": [ // 仅 --actions 时填充
{
"check": "bot_process",
"cmd": "cd ~/CloseCrab && nohup ./run.sh bunny > /tmp/bunny.run.log 2>&1 &",
"reason": "Bot process not running; relaunch via run.sh supervisor."
}
]
}
Agent 用法(受 GBrain skillpack-check 启发)
当 agent / inbox / 其他 bot 想问 "这个 bot 还好吗",跑:
~/CloseCrab/scripts/closecrab-smoke-test.sh <bot> --json --actions
然后根据返回的 status + actions[] 决策:
status: "ok"→ 啥都不做status: "warn"→ 把results[]里skip的项目当 review 候选展示给人status: "fail"→ 把actions[]里的cmdpaste 出来让 oncall 决定执行(不要自动跑)
输出语义
| 符号 | 状态 | 含义 |
|---|---|---|
✓ |
pass | 检查通过 |
✗ |
fail | 真问题,需要处理(计入 exit code) |
⊘ |
skip | 检查不适用(如 secret 没设但可能用 ADC)— 不算 fail |
内置检查
| Check | 说明 |
|---|---|
bot_process |
pgrep 找 python3 -m closecrab --bot {name} 进程 |
run_sh_wrapper |
是否有 run.sh supervisor(手动启动是 skip 不是 fail) |
firestore_sa_key |
GOOGLE_APPLICATION_CREDENTIALS 文件可读且 JSON 合法(未设 → skip,假设走 ADC) |
firestore_reachable |
bots/{name} doc 存在(用 8s timeout 防卡) |
worker_type |
显示当前 worker(claude/gemini/openclaw/kilo) |
claude_settings |
~/.claude/settings.json 解析 OK |
worker_secret_* |
按 worker_type 检查 — Claude 看 Vertex/API key;Gemini 看 API key;OpenClaw 看 Gateway :18789;Kilo 看 kilo 二进制 |
bot_log_recent |
bot.log mtime — <1h pass;<24h skip;>24h fail |
recent_errors |
末尾 200 行的 ERROR/CRITICAL/Traceback 计数 |
drop_ins |
扫描自定义检查 |
Drop-in 自定义检查
放在 ~/.closecrab/smoke-tests.d/ 下(所有 bot 通用)或 ~/.closecrab/smoke-tests.d/{bot}/(单 bot 专属)的 *.sh 文件会自动被发现执行。
合约:脚本第一行 stdout 必须以 OK / FAIL / SKIP 开头。BOT 环境变量已注入。
示例:~/.closecrab/smoke-tests.d/bunny/discord-token.sh:
#!/usr/bin/env bash
set -u
token=$(timeout 5 python3 -c "
from google.cloud import firestore
db = firestore.Client(project='chris-pgp-host', database='closecrab')
d = db.collection('bots').document('$BOT').get().to_dict() or {}
print((d.get('discord') or {}).get('token','')[:10])
" 2>/dev/null)
if [ -n "$token" ]; then echo "OK discord token present (${token}...)"; else echo "FAIL no discord token"; exit 1; fi
设计原则(从 GBrain 移植 + CloseCrab 适配)
- Detect-only, no auto-fix — 跑着的 production bot 自动重启会丢用户上下文,先 v1 detect → 让人/agent 决策
- Timeout everything — 所有外部调用都
timeout 5-8s,不卡死 - Skip 不是 fail — 可选能力没配(如 SA key、drop-ins 目录空)只 skip
- JSON-first for agents —
--json输出让 inbox 消息 / cron / 其他 bot 能机器消费 - Drop-in 扩展 — 不改核心脚本就能为某 bot 加专属检查
后续可加(v2 候选)
- 按 worker_type 拉最近一次 firestore log 看
status/error字段 - ✁
--fixflag 启用 careful auto-fix(如重启 cron-daemon、re-mount gcsfuse)— 需要 case-by-case 评估 - Cross-bot
/health聚合面板(Jarvis 一次查所有 teammate)
来源
移植自 gbrain skills/smoke-test/SKILL.md。 GBrain 评估报告:https://cc.higcp.com/assets/gbrain-evaluation-20260519-101510.html