# `CMDC.Plugin.Builtin.HumanApproval`
[🔗](https://github.com/tupleyun/cmdc/blob/v0.5.3/lib/cmdc/plugin/builtin/human_approval.ex#L1)

P0 人类审批插件 — 高风险工具执行前等待人类确认（HITL）。

拦截 `before_tool` 事件，对指定工具（默认 `"shell"`）的非白名单命令
广播 `{:approval_required, approval_map}` 事件并阻止工具执行。

审批信息直接以 map 形式内嵌在事件 payload 中，无需独立 struct：

```elixir
%{
  id: "a1b2c3d4",
  tool: "shell",
  args: %{"command" => "rm /tmp/test"},
  session_id: "...",
  hint: "请回复「确认执行：rm /tmp/test」...",
  requested_at: 1_700_000_000_000
}
```

## 两种审批模式（共存）

### 模式 A — 外部 API 审批（管理后台推荐）

```
HumanApproval 拦截 {:before_tool, "shell", args}
    │  广播 {:approval_required, approval_map}
    │  block_tool → Agent 回到 idle
    │
外部系统收到事件，管理员审批
    │
向 Pipeline 发送 {:tool_approved, approval_id} 事件
    └── 放行 → 命令进入 pending_approvals，下次 before_tool 自动通过
```

### 模式 B — 用户 re-prompt 审批（Bot 对话场景）

```
用户: "帮我删除 /tmp/test"
    │  block_tool，hint 提示用户回复确认前缀
    │
用户: "确认执行：rm /tmp/test"
    │  before_prompt 识别 confirm_prefix → 命令进入 pending_approvals
    │  下次 before_tool 自动放行
```

## 配置

    {CMDC.Plugin.Builtin.HumanApproval,
      require_approval_for: ["shell"],     # 需要审批的工具名列表
      safe_commands: [                     # 免审批命令（正则或字符串前缀）
        ~r/^curl\s/,
        ~r/^ls(\s|$)/,
        ~r/^pwd$/,
        "echo "
      ],
      confirm_prefix: "确认执行：",         # 模式 B 的确认前缀
      timeout_ms: 120_000                  # 审批超时（默认 2 分钟，0 表示不超时）
    }

---

*Consult [api-reference.md](api-reference.md) for complete listing*
