Skip to main content
Glama
66419118nnn
by 66419118nnn
README.md
# Pi-Anvil(pi-sandbox)

> 一个**任务委派型 MCP 服务器**:把编码任务派给跑在加固沙箱里的 coding agent,产出以 diff 形式回来,人审后 apply 或 discard。
>
> 状态:M0–M9 服务端里程碑 + Web M0–M4 已实现,`v0.2.0`。这是个人项目,代码与文档都在持续演进。

## 它解决什么问题

让 AI 写代码的常见困境是:要么让它直接在你的工作区里乱改,要么把它关在门外什么都干不了。Pi-Anvil 走中间那条路——

**agent 在沙箱里干活,宿主文件系统只接受经过审查的变更集。**

具体是四件事:

1. **委派**:通过 MCP 工具下发任务,agent(Pi)在一次性容器里执行,宿主与它之间只走协议
2. **隔离**:Docker + gVisor/Kata 可选,附 seccomp 策略;模型 API 走一条独立的 TCP 桥,用一次性 token 认证,agent 拿不到真凭据
3. **可审**:所有变更以 baseline diff 回来,带风险评估(risk assessment),你可以 apply 或 discard
4. **可查**:HMAC 链式审计日志、指标、会话子系统、备份/恢复

## 架构

```
MCP client (Claude / Pi / 任意 MCP 宿主)
        │  stdio
        ▼
  src/mcp/        工具面:任务下发、状态查询、diff 取回、apply/discard
        │
        ▼
  src/engine/     scheduler → pipeline → reconcile
                  ├─ runners/docker    容器内跑 agent(gVisor/Kata + seccomp)
                  ├─ runners/fake      无 Docker 时的测试替身
                  ├─ baseline-diff     变更集计算
                  ├─ risk              风险评估与分级
                  ├─ apply             落盘(状态机驱动,discard 后不可绕过)
                  ├─ verification      干净性校验(PRD 13.5)
                  ├─ cache             含密钥中毒检测(AKIA/私钥/ghp_ 等模式)
                  └─ sessions          会话生命周期
  src/core/       config · crypto(provider key 加密存储)· secrets · audit(HMAC)
                  fsx(原子写) · backup · events · db · ids · errors
  src/http/       daemon + REST/SSE API(一次性 token 认证)
  runtime/        沙箱镜像构建、pi-adapter、model-bridge、worker
  web/            SPA 控制台:聊天页 / 模型配置页 / 控制台,SSE 实时事件
```

## 快速开始

要求:Node ≥ 22.19,TypeScript 5.9,Docker(可选,无 Docker 时用 `fake` runner 跑测试)。

```bash
npm install
npm run build          # tsc
npm test               # vitest
npm run check          # biome + tsc --noEmit(含 web 的 tsconfig)

npm run build:web      # 前端产物
node dist/cli.js       # 起 MCP 服务器
```

沙箱镜像:

```bash
node runtime/build-image.mjs
```

## 安全设计上的几个取舍

- **agent 永远拿不到 provider 凭据**:模型请求经 runtime 里的 model-bridge 转发到宿主,宿主侧用一次性 token 认证后再打给真端点;配置文件里的 API key 是加密存放的
- **apply 不可绕过状态机**:discard 之后不能直接落盘(这条有专门的回归测试,见 `13914e6`)
- **缓存写入前做密钥中毒检测**:外部内容里出现 AWS AKIA / 私钥块 / GitHub token 形态的字符串会被拦下,避免被投毒的上下文把凭据带进缓存
- **审计是 HMAC 链式的**:事后篡改单条记录会被发现
- **文件系统写入全走原子写**(`fsx`),避免半写状态

## 测试

- `test/unit/` 38 个单元测试文件,覆盖 engine / core / http / policy
- `test/e2e/` + `e2e-state/` 端到端与压力脚本:会话生命周期、协议边界、并发、终态顺序
- 里程碑是按 TDD 推的,提交信息里保留了 red-green 轮次记录

## 与上游 Pi 的关系

本项目的 agent 侧适配的是 [earendil-works/pi](https://github.com/earendil-works/pi)(`runtime/src/pi-adapter.ts`)。**Pi 是别人的开源项目,本仓库不包含它的源码**,只包含对接它的适配层。

## 文档

`docs/` 下是两份设计文档(PRD),记录了里程碑定义、协议细节和验收条件:

- `docs/Pi_Sandbox_MCP_Server_PRD_v1.10.md` — 服务端
- `docs/Pi_Sandbox_Web_Frontend_PRD_v1.0.md` — Web 前端

## License

MIT — 见 [LICENSE](LICENSE)。