Metadata-Version: 2.4
Name: hermes-approval-engine
Version: 1.0.0
Summary: Approval Engine approval plugin — Feishu card-based human-in-the-loop approval workflow engine
Author-email: Open Source Community <dev@nousresearch.com>
License: MIT
Project-URL: Homepage, https://github.com/jiayoupengpeng/hermes-plugin-approval-v2
Project-URL: Repository, https://github.com/jiayoupengpeng/hermes-plugin-approval-v2
Project-URL: Documentation, https://github.com/jiayoupengpeng/hermes-plugin-approval-v2/docs/api.md
Keywords: hermes,approval,feishu,lark,workflow,human-in-the-loop
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: MIT License
Classifier: Natural Language :: Chinese (Simplified)
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: System :: Systems Administration
Classifier: Topic :: Communications :: Chat
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

<!-- markdownlint-disable MD033 -->

# Hermes Approval Engine v2

[![CI - Approval Engine](https://github.com/jiayoupengpeng/hermes-plugin-approval-v2/actions/workflows/test.yml/badge.svg)](https://github.com/jiayoupengpeng/hermes-plugin-approval-v2/actions/workflows/test.yml)
![Python Versions](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13-blue)
![License](https://img.shields.io/badge/license-MIT-green)

> **飞书卡片审批工作流引擎** — 多容器编排、风险分级、人工审批、审计日志一体化。
>
> Feishu (Lark) card-based human-in-the-loop approval workflow engine. Multi-container orchestration, risk classification, manual approval, and full audit trail.

---

## 项目概述 / Overview

Hermes Approval Engine V2 是一个基于 **飞书消息卡片** 的人机协同审批工作流引擎。它采用 Supervisor + Sub-Agent 多容器架构，通过 SQLite WAL 持久化、状态机校验、三级风险分级、JSONL 审计日志等能力，提供安全可控的命令审批和自动化执行。

**典型场景：** 小美（操作 Agent）提交命令 → 小强（审批 Supervisor）决策 → 鹏老板（管理员）终审高风险操作 → 执行并归档。

**V2 核心升级：** 零外部依赖（stdlib-only）、SQLite WAL 连接池、双重幂等、6 套飞书卡片模板、Docker Compose 多容器编排。

---

## Architecture

```
┌─────────────────────────────────────────────────────────────────────┐
│                           Docker Host                               │
│                                                                     │
│  ┌─────────────────────────────┐   ┌─────────────────────────────┐  │
│  │     Supervisor Container     │   │     Sub-agent Containers    │  │
│  │    (hermes-supervisor)       │   │                             │  │
│  │                              │   │  ┌───────────────────────┐  │  │
│  │  ┌───────────────────────┐   │   │  │  finance-worker       │  │  │
│  │  │  HTTP API Server      │───┼───┼──│  (财务数据分析)        │  │  │
│  │  │  (port 8080)          │   │   │  └───────────────────────┘  │  │
│  │  └───────────────────────┘   │   │                             │  │
│  │         │                    │   │  ┌───────────────────────┐  │  │
│  │  ┌──────▼─────────────────┐  │   │  │  life-assistant       │  │  │
│  │  │  Approval Engine Core  │  │   │  │  (生活学习助理)        │  │  │
│  │  │  ┌───────────────────┐ │  │   │  └───────────────────────┘  │  │
│  │  │  │ SQLite (WAL+Pool) │ │  │   │                             │  │
│  │  │  │ Risk Classifier   │ │  │   │  ┌───────────────────────┐  │  │
│  │  │  │ State Machine     │ │  │   │  │  it-ops-worker        │  │  │
│  │  │  │ Audit Logger      │ │  │   │  │  (IT运维设备)          │  │  │
│  │  │  │ Card Builder (×6) │ │  │   │  └───────────────────────┘  │  │
│  │  │  └───────────────────┘ │  │   │                             │  │
│  │  └────────────────────────┘  │   └─────────────────────────────┘  │
│  │                              │        │                           │
│  │         ▲                    │        │ Poll loop                  │
│  │         │ Feishu Card API    │        ▼ (kanban/HTTP)             │
│  │  ┌──────┴──────────┐        │   ┌────────────────────┐          │
│  │  │  Feishu (Lark)  │◀───────┼──▶│  Shared Volume     │          │
│  │  │  Message Cards  │        │   │  /opt/share        │          │
│  │  └─────────────────┘        │   └────────────────────┘          │
│  └─────────────────────────────┘                                   │
└─────────────────────────────────────────────────────────────────────┘
```

### ASCII 架构简图

```
┌──────────────┐     ┌──────────────────┐     ┌──────────────────┐
│  Sub-Agent   │◀───▶│   Supervisor     │◀───▶│   Feishu Cards  │
│  (operators) │     │  HTTP API:8080   │     │  (approval UI)  │
└──────────────┘     └────────┬─────────┘     └──────────────────┘
                              │
                     ┌────────▼─────────┐
                     │  approval_engine │
                     │  ┌─────────────┐ │
                     │  │ SQLite (WAL)│ │
                     │  │ Risk Engine │ │
                     │  │ State Mach. │ │
                     │  │ Audit Log   │ │
                     │  │ 6 Templates │ │
                     │  └─────────────┘ │
                     └──────────────────┘
```

---

## Features / 功能特性

| Category | Feature | Description | 说明 |
|----------|---------|-------------|------|
| **Persistence** | SQLite WAL + Pool | 64 连接池，WAL 模式，双重幂等，72h 自动过期清理 | 高并发读写不阻塞 |
| **Risk** | 3-Level Classification | 自动识别破坏性操作 + 可信网段降级 + SQL 无 WHERE 检测 | low / medium / high |
| **State** | Finite State Machine | 8 状态 + 12 条合法转换规则，非法转换自动拒绝 | 保证状态一致性 |
| **Feishu** | 6 Card Templates | 待审批 / 已通过 / 已驳回 / 修改重提 / 人工终审 / 归档 | 完整审批生命周期 |
| **Security** | Field Masking | API Key, Token, Password, Secret 自动脱敏 | 审计日志安全 |
| **Audit** | JSONL Full Trail | 每条操作变更都有 JSONL 格式可追溯记录 | 合规审计 |
| **Timeout** | Auto Reject | 1h 告警 + 6h 自动驳回，防止任务卡死 | 兜底安全 |
| **Whitelist** | Hot-reload | 运行时动态更新操作人白名单 | 灵活权限控制 |
| **Deploy** | Multi-Container | Supervisor + 3 Sub-agents, Docker Compose 编排 | 开箱即用 |

---

## Quick Start / 快速开始

### Installation

```bash
pip install hermes-approval-engine
```

Or install from source (editable):

```bash
git clone git@github.com:jiayoupengpeng/hermes-plugin-approval-v2.git
cd hermes-plugin-approval-v2
pip install -e .
```

### Python Usage

```python
from approval_engine import (
    create_task, get_task, update_task,
    build_approval_card, classify_risk,
    TaskStatus, RISK_LOW, RISK_HIGH,
)

# 1. Create an approval task
task = create_task(
    command="systemctl restart nginx",
    description="Restart Nginx service",
    source_ip="10.0.0.52",
)
print(f"Task ID: {task['task_id']}, Risk: {task['risk_level']}")
# Output: Task ID: TASK-0001, Risk: low

# 2. Risk classification
risk, labels = classify_risk("rm -rf /data", source_ip="10.0.0.52")
assert risk == RISK_HIGH
assert "destructive_command" in labels

# 3. Update status (approve)
updated = update_task(task['task_id'],
    status=TaskStatus.APPROVED,
    operator_name="Xiaoqiang",
)
print(f"Status: {updated['status']}")  # approved

# 4. Build Feishu card
card = build_approval_card(task,
    approve_open_id="ou_approver",
    reject_open_id="ou_rejector",
)

# 5. List pending tasks
pending = list_pending_tasks()
print(f"Pending tasks: {len(pending)}")

# 6. Clean expired tasks (older than 72h)
cleaned = clean_expired_tasks()
print(f"Cleaned {cleaned} expired tasks")
```

### Risk Classification Examples

```python
from approval_engine import classify_risk

# High risk — destructive command
risk, reasons = classify_risk("rm -rf /data", source_ip="10.0.0.5")
assert risk == "high"
assert "destructive_command" in reasons

# High risk — cross-network request
risk, reasons = classify_risk("ls -la", source_ip="8.8.8.8")
assert risk == "high"
assert "cross_network" in reasons

# Low risk — safe command from trusted network
risk, reasons = classify_risk("df -h", source_ip="10.0.0.10")
assert risk == "low"
assert reasons == []
```

---

## Docker Deployment / Docker 部署

### Prerequisites

- Docker & Docker Compose v2
- Feishu App (create at [open.feishu.cn](https://open.feishu.cn/app))
- Network: macvlan driver configured

### Step 1: Configure Environment

```bash
cd docker
cp .env.template ../.env
# Edit .env with your Feishu credentials and network settings
vim ../.env
```

Key variables in `.env`:

```bash
# Feishu credentials
FEISHU_APP_ID=cli_your_app_id
FEISHU_APP_SECRET=your_app_secret

# Personnel
FEISHU_ADMIN_ID=ou_admin_open_id    # 鹏老板
COMMANDER_OPEN_ID=ou_commander_id   # 小强
EXECUTOR_OPEN_ID=ou_executor_id     # 小美

# Network (adjust to your environment)
MACVLAN_SUBNET=10.0.0.0/24
SUPERVISOR_IP=10.0.0.100
```

### Step 2: Deploy Supervisor

```bash
cd docker
docker compose --env-file ../.env up -d
```

This starts the **Supervisor** container with:
- HTTP API on port 8080
- SQLite database at `/opt/share/data/`
- Feishu card integration
- Health check at `/health`

### Step 3: Deploy Sub-agents

Build the sub-agent base image first:

```bash
docker build -t hermes-subagent:latest -f docker/subagent.Dockerfile .
```

Then deploy all 3 sub-agents:

```bash
docker compose -f docker/subagent-compose.yml --env-file .env up -d
```

Or deploy a specific sub-agent:

```bash
docker compose -f docker/subagent-compose.yml --env-file .env --profile finance up -d
```

### Container Architecture

| Container | Role | IP | Purpose |
|-----------|------|----|---------|
| `hermes-supervisor` | 审批主管 | `10.0.0.100` | API server + engine + feishu |
| `hermes-finance-worker` | 财务数据分析 | `10.0.0.110` | Finance domain tasks |
| `hermes-life-assistant` | 生活学习助理 | `10.0.0.111` | Life domain tasks |
| `hermes-it-ops-worker` | IT 运维设备 | `10.0.0.112` | IT ops domain tasks |

### Verification

```bash
# Check Supervisor health
curl http://localhost:8080/health

# Check sub-agent logs
docker logs hermes-finance-worker
```

---

## API Quick Reference / API 速查表

| Method | Path | Description |
|--------|------|-------------|
| `GET` | `/health` | 健康检查 |
| `POST` | `/api/tasks` | 创建审批任务 |
| `GET` | `/api/tasks` | 任务列表（支持 `?status=` 过滤） |
| `GET` | `/api/tasks/:id` | 任务详情 |
| `POST` | `/api/tasks/:id` | 更新任务状态 |
| `POST` | `/api/tasks/:id/dispatch` | 下发任务至子 Agent |
| `POST` | `/api/tasks/:id/verify` | 验证执行结果 |
| `POST` | `/api/webhook/feishu` | 飞书卡片回调 |

> 完整 API 参考见 [docs/api.md](docs/api.md)。

---

## Development Guide / 开发指南

### Project Structure

```
hermes-plugin-approval-v2/
├── approval_engine/           # 核心引擎包
│   ├── __init__.py            # 公开 API 导出 + ApprovalEngine 类
│   ├── __main__.py            # Supervisor HTTP 服务入口
│   └── approval_engine.py     # 核心逻辑：CRUD / 状态机 / 风险 / 卡片 / 审计
├── agent/
│   └── poll_loop.py           # 子 Agent 轮询循环
├── docker/
│   ├── Dockerfile             # Supervisor 容器镜像
│   ├── subagent.Dockerfile    # 子 Agent 基础镜像
│   ├── docker-compose.yml     # Supervisor Docker Compose
│   └── subagent-compose.yml   # 子 Agent Docker Compose
├── tests/
│   ├── test_approval_engine_smoke.py  # 冒烟测试（10 项）
│   └── test_phase1_selfcheck.py       # Phase 1 自测（9 项）
├── examples/
│   ├── run_trial_scenario1.py  # 多任务并发 + 跨容器推送
│   ├── run_trial_scenario2.py  # 场景二
│   └── run_trial_scenario3.py  # 场景三
├── docs/
│   └── api.md                 # API 参考文档
├── .github/workflows/
│   └── test.yml               # GitHub Actions CI
├── .env.template              # 环境变量模板
├── pyproject.toml             # 项目配置
└── README.md                  # 本文档
```

### Running Tests

```bash
# Install package (editable)
pip install -e .

# Run smoke tests
python tests/test_approval_engine_smoke.py

# Run phase 1 self-check
python tests/test_phase1_selfcheck.py

# Run with pytest
cd tests
python -m pytest test_approval_engine_smoke.py -v
```

### CI Pipeline

GitHub Actions 矩阵测试（Python 3.10-3.13），自动执行：

1. `pip install -e .` (editable install)
2. 包导入验证 (`from approval_engine import *`)
3. Phase 1 自测
4. 冒烟测试
5. HTTP 服务启动 + `/health` 端点验证

CI 配置见 `.github/workflows/test.yml`。

### Local Development

```bash
# Start Supervisor locally
APPROVAL_HOME=/tmp/hermes-dev python -m approval_engine

# Or with custom port
SUPERVISOR_PORT=9090 python -m approval_engine

# Verify health
curl http://localhost:8080/health
```

### Environment Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `SUPERVISOR_HOST` | `0.0.0.0` | HTTP 监听地址 |
| `SUPERVISOR_PORT` | `8080` | HTTP 端口 |
| `APPROVAL_HOME` | `~/.hermes` | 数据目录 |
| `API_SERVER_KEY` | (empty) | API 鉴权密钥 |
| `TRUSTED_NETWORK` | `10.0.0.0/24` | 可信网段 CIDR |
| `LOG_LEVEL` | `INFO` | 日志级别 |
| `FEISHU_APP_ID` | — | 飞书应用 ID |
| `FEISHU_APP_SECRET` | — | 飞书应用密钥 |
| `APPROVAL_WHITELIST` | (empty) | 操作人 open_id 列表（逗号分隔） |

---

## License

MIT License — see [LICENSE](LICENSE).

---

## Links

- **Repository**: [github.com/jiayoupengpeng/hermes-plugin-approval-v2](https://github.com/jiayoupengpeng/hermes-plugin-approval-v2)
- **API Docs**: [docs/api.md](docs/api.md)
- **Issues**: [github.com/jiayoupengpeng/hermes-plugin-approval-v2/issues](https://github.com/jiayoupengpeng/hermes-plugin-approval-v2/issues)
