---
name: jd-platform-agentify:clieval
description: >-
  CLI 能力评测+优化 loop（基于 autoloop 引擎 + cli-eval 评分器）。把一个已注册的 o2 CLI
  针对 cli-eval bench 自迭代到通过率达标（100）：每轮读判官失败信号 → 改 CLI 源码/SKILL/卡片
  → 重评 → 分数升则 keep、降则 git revert。Verify=cli-eval 通过率，Guard=单元测试。
  触发词：优化 CLI、评测优化、cli-eval loop、把 jdmail 优化到满分、clieval、benchmark 提分。
  当用户说"用 cli-eval 把 X 优化到达标"、"自动迭代提升某 CLI 的通过率"时触发。
---

# jd-platform-agentify:clieval

CLI 能力**评测+优化** autoloop。目标：让被测 CLI 在 cli-eval bench（agent 真跑 + LLM 判官）上的
通过率达到目标（100）。与 `:cli`（造 webcli 命令、冒烟通过）不同——`clieval` 优化**已存在**的
CLI（源码/SKILL.md/registry 卡片），评分用的是更强的 agent+判官评测，衡量的是**能力质量**。

参数（board 卡片 / 手动均可）：`${CLI}`=被测 CLI 名（默认 jdmail），`${BATCH}`=cli-eval 批次（默认 mail）。

**两种进入路径**：①**流水线 CLI**（平台自动 CLI 化）——由 `collect→scene→cli(graph)→wiki` 后经 `spawn_clieval_card` fan-in 收口进 clieval，须过结构 Guard、走结构回调闭环。②**人工 CLI**（格式人工保证，如 jdmail）——直接 `kanban create --board <cli> --subject <batch> --phase clieval --url <被测仓>` 进入，**跳过 graph/scene 与结构回调**（`worker` 经 `is_pipeline_cli` 判别旁路），只做行为/实用性优化。

## Autonomy Directive

你是自主 CLI 优化 agent。一旦 loop 开始：
- **绝不停下来问**——用户可能不在。
- **每轮只做一个增量**：修一个 bug / 补一处 SKILL 示例 / 改一个卡片描述 / 修正一个入参形态。
- Loop 持续到 Verify ≥ 目标或迭代耗尽/plateau。
- **只优化被测物，评测集只读**：可改 CLI 源码/SKILL.md/registry 卡片；**绝不改 cli-eval 的任务集或答案 key**（那是作弊）。

## Precondition（开跑前必检，任一不满足则停并提示人工）

**一键体检（推荐）**：`bash scripts/clieval_doctor.sh --cli ${CLI} --batch ${BATCH} --scope <被测仓>`。
输出 `READY` 即以下各项就绪；`NOT-READY` 会逐项点名缺什么+修复提示（含 PATH/claude 鉴权/O2_LOCAL_SKILL 本地传播/DeepSeek 等易漏项），按提示修完再起循环。它覆盖：

0. **（流水线 CLI）进阶段前置——让 agent 用上被测的 graph 版**：graph 造的 CLI 未注册，bench agent 的 `o2 list` 看不到、`o2 launch webcli <site>` 跑的是**官方内置版**（命令集不同 → bench 错位全 fail）。
   - **webcli 子站**（graph 产物 `webcli/<site>/*.js`，主线绝大多数）——**symlink + registry 双管**：
     ① **执行挂载**：`webcli/<site>/` 目录通过 symlink 挂载到 `~/.webcli/clis/<site>/`，`.js` 源文件中 `site` 字段须与目录名一致。修改 `.js` 源码后即时生效（无需转译/重部署）。`webcli/<site>/node_modules/@jd/webcli` 须 symlink 到本地 webcli 包（Node.js import 按 realpath 解析）。
     ② **注册发现**：通过 admin API（`curl -u admin:$CLI_HUB_ADMIN_PASSWORD`）注册到测试 registry（o2cli-test.jd.com），使 agent 经 `o2 list` 发现 `webcli:<site>`。首次注册后无需重复注册，改源码即时生效。
   - **独立 CLI 包**（有 install_cmd，如 jdmail 之外的独立 pip 包）：`bash scripts/clieval_register.sh --cli ${CLI} --card <card> ...`（registry 存 install_cmd，o2 按版本拉取）。
   admin 鉴权：`CLI_HUB_ADMIN_PASSWORD`（Basic，admin123）或 `CLI_HUB_ADMIN_TOKEN`（Bearer）；目标**测试平台非生产**。**人工 CLI 跳过**（已在 registry、格式人工保证，如 jdmail）。
1. **backend 在线**：`bash scripts/eval_clihub.sh ${BATCH}` 能返回数字（内部已探针 `/api/harnesses`）。
2. **被测 CLI 已登录**：`${CLI} --json doctor` 的 `ready=true`；否则 eval 会打印 `NEEDS_LOGIN`，**暂停等人工登录**（CDP 登录需人工，见 references/ops-runbook.md）。
3. **Scope 仓干净 git 树**（`git status --porcelain` 为空），revert 式回滚才可靠。
4. **Guard 基线绿**：先跑一次 Guard（单测）确认起点通过。

## 流程（每轮）

1. **Review**：读 `git log --oneline -20` + 上一轮 `git diff HEAD~1`（git 历史=记忆）；读上一轮 eval 的判官失败信号。
2. **定位**：看 cli-eval 判官的 `checklist/evidence` + agent 轨迹，判断哪条任务挂、为什么。对照 `references/what-to-change.md` 把失败特征映射到改动位置。
3. **Modify**：做**一处**原子改动（源码/SKILL/卡片）。
   - **webcli 子站**：改 `webcli/<site>/*.js` 源码后即时生效（symlink 挂载，无需转译/重部署）；修命令 bug（如参数缺失 errCode）时，先用 `o2 launch webcli browser <session> open <平台URL>` + `... network` 抓平台**真实请求**学正确调用（如实测得 `/v1/settings?key=bgPublicOrgCodeNameList`），再改源码补参数。
   - **独立 CLI / SKILL / 卡片**：editable 安装即时生效；SKILL 类走 `O2_LOCAL_SKILL` 传播。
4. **Commit**：`git commit -m "experiment: <one-line>"`。
5. **Guard**：跑单测；不过则无条件 `git revert HEAD --no-edit`。**流水线 CLI 额外两道 Guard**（防过拟合/防打碎，人工 CLI 跳过）：
   - **结构 Guard**：`bash scripts/clieval_struct_guard.sh --site ${CLI} --cli-dir webcli/${CLI} --scenes <scenes.yaml> [--min <上轮结构分>] [--record]`——结构分退化（exit 1）则 revert。
   - **smoke Guard**：关键命令跑一遍（`--help`/基础只读调用）非错；断链/报错则 revert。
6. **Verify**：`bash scripts/eval_clihub.sh ${BATCH} --run --tasks <本轮受影响任务>`（内层只重跑受影响子集，快）。
   **每次 Verify 后必看 stderr**：若出现 `NEEDS_LOGIN` 或 `BACKEND_DOWN`，说明是环境中断（登录过期/后端挂），**立即停止循环、最后一行输出 `BLOCKED: <原因>`**——不要把当次数字当作代码质量信号、不要 revert、不要据此改代码（那次分数是环境导致的降级，不是你改坏了）。
   > **断点续跑**：因 `NEEDS_LOGIN`/`BACKEND_DOWN` 被 block 的 clieval 卡是**可恢复**的——人工恢复登录后，worker 再次启动时会自动把它重新置 ready（`_resume_login_blocked`）。**你被重新领取时（resume）**：先读 `git log --oneline` + `.agentify/autoloop-clieval/results.tsv`，从**上一个 keep 的 commit** 处继续，已通过的题不重做。experiment commit = 天然 checkpoint。
7. **Decide**：分数↑且 Guard 过 → keep；↓/崩溃/非数字 → `git revert HEAD --no-edit`。
8. **Log**：记一行到 `.agentify/autoloop-clieval/results.tsv`（iteration/commit/metric/status/note）。

## 闭环反馈：失败分类 + 写 gap ledger（仅流水线 CLI）

对每条判官失败，**先分类再决定去向**（人工 CLI 无上游 graph/scene，只做用法类就地修，跳过本节回调）：

- **用法/引导类**（命令齐备、结构合理，只是 agent 没用对 / SKILL 引导不足）→ **clieval 就地修**（改 SKILL/源码/卡片），并记审计：
  `python -m agents.gap_ledger add --site ${CLI} --type usage --detail "<一句话>" --stage clieval`
- **结构类**（完成任务所需能力缺失 / 命令粒度不对 / 一个意图要串很多碎片命令）→ **不在 clieval 就地补命令**（那会打碎 graph 约束好的结构、且是过拟合），改写入台账触发回调：
  `python -m agents.gap_ledger add --site ${CLI} --type structural --detail "<缺什么能力/哪个粒度不对>" --stage clieval`
  —— worker 在本卡完成后据台账 `request_reoptimize` 回调：重跑 scene（补能力场景/节点）→ cli(graph) 重造/约束 → 再到 clieval。

**收敛前记录双分**（供"双分收敛"判停）：`python -m agents.gap_ledger scores --site ${CLI} --clieval <全批分>`（graph 结构分由 cli 阶段记）。收敛 = 结构分与行为分双双达标、无未解决结构缺口、行为分未回退（`python -m agents.gap_ledger converged --site ${CLI}`，退出码 0=收敛）。

## 防过拟合与收敛确认（对齐 autoloop overfit-guard，控成本）

- 内层循环用**受影响任务子集**驱动改动（`--tasks`）；
- **收敛确认**分两步，避免昂贵的全量重跑：
  1. 受影响任务稳定性：`bash scripts/eval_clihub.sh ${BATCH} --run --tasks <受影响任务> --repeat 2`（只对改动涉及的任务多跑几次、多数通过，抗判官噪声）；
  2. 全量分数：`bash scripts/eval_clihub.sh ${BATCH}`（**不带 --run**，读 DB 现有结果算全批通过率——未受影响任务复用既有结果，秒出）。
- 仅当你的改动**可能波及其他任务**时，才对可能受影响的那几条补 `--run`；**不要**无脑对全量 19 题 `--run --repeat 2`（太慢，易撞超时/登录过期）。

## 安全红线

- **绝不无人值守 push/deploy**；循环产生的 commit 合入主分支前**人工过一眼**。
- bench 的写操作只打**本人账号**（任务集已如此约定）。
- 评测集/答案 key **只读**，只允许改被测 CLI 及其文档/卡片。
- **环境中断即停**：登录过期/后端不可达时，`BLOCKED` 退出交人工，绝不空转到超时。

## 关键工程经验（详见 references/ops-runbook.md）

- backend 环境：PATH 含被测 CLI 的 venv + claude；`PYTHONUTF8=1`；`CLI_HUB_REGISTRY_URL=o2cli-test`；`DEEPSEEK_API_KEY`；`CLAUDE_CODE_BIN`。agent 鉴权继承宿主、勿覆盖 `ANTHROPIC_API_KEY`。
- **SKILL 类改动要生效**：webcli 子站的 SKILL.md 在 `webcli/<site>/SKILL.md`，通过 symlink 挂载后 webcli 本地即可读取；registry skill_md 可指向 coding.jd.com raw URL。独立 CLI 仍需设 `O2_LOCAL_SKILL_<CLI>` 指向被测仓本地 SKILL.md。详见 references/ops-runbook.md。
- 并发=2（Windows 上 =4 易连接抖动；`run-batch` 的 ProcessPool 不可用）。
- 改任务文本需重启 backend 才重载；改 CLI 源码（editable 安装）则即时生效、无需重启。

## 固定配方（发起 autoloop 时贴此块；jdmail/mail 为默认，改 ${CLI}/${BATCH} 即可复用）

```
/autoloop
Goal:       ${CLI} 在 cli-eval ${BATCH} 批次上通过率达 100（流水线 CLI 还须结构分不退化）
Scope:      被测 CLI 源码 + 其 SKILL.md + registry 卡片
            - 流水线 CLI: webcli/${CLI}/** + 该 CLI 的 SKILL + 卡片（cwd=WorkerAgent 仓）
            - 人工 CLI:   被测仓 CLI 源码目录 + SKILL.md + registry 卡片（cwd=被测仓）
Metric:     cli-eval ${BATCH} 批次通过率（higher is better，目标 100）
Verify:     bash .agentify/scripts/eval_clihub.sh ${BATCH} --run --tasks <本轮受影响任务>
Guard:      pytest + smoke +（流水线 CLI）bash scripts/clieval_struct_guard.sh --site ${CLI} \
              --cli-dir webcli/${CLI} --scenes <scenes.yaml>（结构不退化）
Iterations: 8
```
（收敛确认：先 `eval_clihub.sh ${BATCH} --run --tasks <受影响任务> --repeat 2` 确认受影响任务稳定，再 `eval_clihub.sh ${BATCH}`（不带 --run，读 DB）看全批分；勿对全量无脑 `--run --repeat 2`。Verify 后见 `NEEDS_LOGIN`/`BACKEND_DOWN` 立即 `BLOCKED`，不 revert、不改代码。流水线 CLI 收敛须双分达标：`python -m agents.gap_ledger converged --site ${CLI}`。）

> 部署约定（对齐 `:cli`）：真正跑循环时把 `scripts/eval_clihub.sh` 复制到**被测仓**的 `.agentify/scripts/`，在被测仓里发起 autoloop。
