Asembris/ReleaseCourt
GitHub: Asembris/ReleaseCourt
ReleaseCourt 是一个由多智能体协调驱动的 AI Agent 部署前评审法庭,在安全红队测试、能力评估和裁决之后由人类完成最终签核。
Stars: 0 | Forks: 0
# ReleaseCourt
**没有评审裁决,任何 Agent 都无法发布。**









ReleaseCourt 是一个由 Band 驱动的评审室,用于在部署前对 AI Agent 进行审查。它接受通用的 Release Packet v1 YAML/JSON 上传,冻结发布身份,依次运行 Security Red-Team -> Evaluation Agent -> Release Judge,并记录确定性的裁决以及随后的人类决策。
旗舰演示候选者是 RefundBot,但已实现的 packet 流程也通过内置、mock 和 HTTP adapter 支持通用候选者。Band/Thenvoi 是启用时真实的 Agent 间协调层;本地 event store 会同步处理脱敏后的事件,用于重放、UI、幂等性和持久化。
## 核心功能
- 支持以 YAML 或 JSON 格式上传 Release Packet v1,包含严格校验和 256 KiB 大小限制。
- 不可变的 packet hash 和 release id;重复的 packet 上传将返回现有的 release。
- 内置、mock 和 HTTP candidate adapter;HTTP 执行是有界的,并受到 SSRF 防护。
- Security Red-Team、Evaluation Agent 和 Release Judge 通过 Thenvoi SDK worker 实现真实的 Band Review Room 协调。
- 确定性的裁决权威;可选的 OpenAI 自适应/补救丰富化仅作为建议参考。
- 当 Band 性能下降时提供有界的本地续接,不会重新运行已完成的阶段。
- 可见的 Review Room 重放,本地使用 JSONL,生产环境使用 Postgres。
- 人类处置选项:`APPROVE`、`REJECT` 和 `REQUEST_CHANGES`。
- Cycle 2 固定重审保留了原始的 case、room 和 `candidate_release_id` 血缘。
- 针对 packet release、评审启动、交接、签核和重审的幂等性和防重复机制。
## 架构
```
flowchart LR
Judge["Human judge"] --> UI["React/Vite Review Room"]
UI --> API["FastAPI backend"]
Packet["Release Packet v1 YAML/JSON"] --> API
API --> Identity["Immutable packet + release identity"]
Identity --> Runner["Candidate runner: built-in / mock / HTTP"]
API --> Band["Band/Thenvoi room"]
Band --> Security["Security Red-Team"]
Security --> Eval["Evaluation Agent"]
Eval --> Verdict["Release Judge"]
Runner --> Security
Verdict --> Engine["Deterministic verdict engine"]
API --> OpenAI["Optional OpenAI advisory enrichment"]
Engine --> Store["JSONL local mirror or Postgres"]
OpenAI --> Store
Band --> Store
Store --> UI
UI --> Human["APPROVE / REJECT / REQUEST_CHANGES"]
```
## 评审可以快速验证的内容
- 上传 `examples/release_packets/travel_agent_vulnerable.yaml`,创建一个 release 并从 `/packets/releases/{release_id}/review` 启动评审。
- 确认相同的 packet 上传两次后会返回相同的不可变 `release_id`。
- 确认无效的 fixture 会被干净地拒绝,且不会创建 release:
`invalid_embedded_secret.yaml` 和 `invalid_unsupported_adapter.yaml`。
- 观察 Security -> Evaluation -> Judge 事件在 Review Room 时间轴中的重放。
- 记录 `REQUEST_CHANGES`,然后运行修复后的 Cycle 2 路径,并验证相同的 case/room 血缘依然可见。
- 停止一个 Band worker,并验证本地降级续接仅恢复缺失的阶段。
## Windows 快速开始
```
cd D:\ReleaseCourt\backend
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -e ".[dev]"
python -m uvicorn app.main:app --reload
```
打开 `http://localhost:8000/health` 和 `http://localhost:8000/docs`。
```
cd D:\ReleaseCourt\frontend
npm install
npm run dev
```
打开 `http://localhost:5173`。
## 真实演示命令
从仓库根目录开始:
```
.\scripts\run_demo_band.ps1
.\scripts\stop_demo_band.ps1
.\scripts\reset_demo.ps1
```
`run_demo_band.ps1` 会使用共享的演示 JSONL runtime 启动后端、所有三个 Band worker 和前端。它需要从 `agent_config.yaml.example` 复制 `backend\.env`、`backend\.venv` 和 `backend\agent_config.yaml`。
## Packet 示例
- `examples/release_packets/travel_agent_vulnerable.yaml`
- `examples/release_packets/travel_agent_fixed.yaml`
- `examples/release_packets/http_travel_agent.yaml`
- `examples/release_packets/invalid_embedded_secret.yaml`
- `examples/release_packets/invalid_unsupported_adapter.yaml`
支持的 packet adapter 包括 `builtin`、`mock` 和 `http`。
## 测试
当前测试套件总数:
- Backend:`947 passing`
- Frontend:`128 passing`
本地运行:
```
cd D:\ReleaseCourt\backend
python -m pytest -v
python -m ruff check .
```
```
cd D:\ReleaseCourt\frontend
npm run test
npm run lint
```
## 重要 API Endpoints
| Method | Path | Purpose |
| --- | --- | --- |
| `GET` | `/health` | 存活状态 |
| `GET` | `/health/ready` | 持久化就绪状态 |
| `GET` | `/demo/templates` | 演示候选者模板和 Band 模式 |
| `POST` | `/demo/cases` | 创建演示 case |
| `POST` | `/demo/cases/{case_id}/review` | 启动活跃的评审周期 |
| `POST` | `/demo/reset` | 当 `DEMO_MODE=true` 时受防护的演示重置 |
| `POST` | `/packets/validate` | 校验 Release Packet v1 且不进行持久化 |
| `POST` | `/packets/releases` | 持久化不可变的 packet release |
| `GET` | `/packets/releases/{release_id}` | 获取 release 和规范化后的 packet |
| `POST` | `/packets/releases/{release_id}/review` | 启动 packet 评审 |
| `GET` | `/cases/{case_id}/timeline` | Review Room 重放 |
| `POST` | `/cases/{case_id}/signoff` | 人类 `APPROVE`、`REJECT` 或 `REQUEST_CHANGES` |
| `POST` | `/cases/{case_id}/rereview` | 启动固定的 Cycle 2 重审 |
| `POST` | `/candidate-manifests/validate` | 校验旧版 AUT manifest |
| `POST` | `/candidates` | 注册候选者身份 |
| `POST` | `/candidates/{candidate_id}/releases` | 注册不可变的 AUT release |
## 仓库结构
```
backend/ FastAPI app, Band workers, packet pipeline, persistence
frontend/ React/Vite Review Room cockpit
examples/release_packets Release Packet v1 examples and invalid fixtures
scripts/ Windows demo, worker, stop, restart, and reset scripts
docs/ Supporting project notes
render.yaml Render backend deployment template
```
## 部署与持久化
本地开发默认使用 `PERSISTENCE_BACKEND=jsonl` 并写入到 `.releasecourt/` 目录下。生产环境使用带 `DATABASE_URL` 的 `PERSISTENCE_BACKEND=postgres`;当选择 Postgres 时,应用不会静默回退到 JSONL。
`render.yaml` 会从 `backend/` 部署后端,在 `$PORT` 上运行 Uvicorn,并使用 `/health/ready`。前端部署应将 `VITE_API_BASE_URL` 设置为后端 URL,并将后端的 `CORS_ALLOWED_ORIGINS` 配置为生产环境的前端 origin。
## 客观局限性
- 目前还没有身份验证或经过验证的评审者身份。
- 没有实时订阅层;前端通过轮询后端时间轴获取更新。
- 没有 PDF 导出、RAG、部署自动化或额外的业务/隐私审查 Agent。
- JSONL 仅用于本地/演示持久化,不适用于多 worker 的生产存储。
- OpenAI 丰富化可以改善建议性上下文,但不能覆盖确定性的裁决。
标签:AI安全, Chat Copilot, Python, React, Syscalls, 代码审查, 发布管理, 多智能体, 无后门, 时序数据库