Asembris/ReleaseCourt

GitHub: Asembris/ReleaseCourt

ReleaseCourt 是一个由多智能体协调驱动的 AI Agent 部署前评审法庭,在安全红队测试、能力评估和裁决之后由人类完成最终签核。

Stars: 0 | Forks: 0

ReleaseCourt logo

# ReleaseCourt **没有评审裁决,任何 Agent 都无法发布。** ![Python 3.12](https://img.shields.io/badge/Python-3.12-3776AB?logo=python&logoColor=white) ![FastAPI](https://img.shields.io/badge/FastAPI-0.111+-009688?logo=fastapi&logoColor=white) ![React](https://img.shields.io/badge/React-19-61DAFB?logo=react&logoColor=111) ![Vite](https://img.shields.io/badge/Vite-8-646CFF?logo=vite&logoColor=white) ![Band/Thenvoi](https://img.shields.io/badge/Band%2FThenvoi-real%20coordination-111827) ![OpenAI](https://img.shields.io/badge/OpenAI-advisory%20enrichment-412991?logo=openai&logoColor=white) ![License: MIT](https://img.shields.io/badge/License-MIT-green.svg) ![Backend tests](https://img.shields.io/badge/backend%20tests-947%20passing-brightgreen) ![Frontend tests](https://img.shields.io/badge/frontend%20tests-128%20passing-brightgreen) 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, 代码审查, 发布管理, 多智能体, 无后门, 时序数据库