bookedsolidtech/rea
GitHub: bookedsolidtech/rea
为 Claude Code 提供零信任治理与审计的 MCP 网关与钩子框架。
Stars: 0 | Forks: 0
# REA
**Agentic governance layer for Claude Code — policy enforcement, hook-based safety gates, audit logging, and Codex-integrated adversarial review.**
[](https://www.npmjs.com/package/@bookedsolid/rea)
[](https://github.com/bookedsolidtech/rea/actions)
[](https://docs.npmjs.com/generating-provenance-statements)
[](./LICENSE)
[](https://developercertificate.org/)
[](https://nodejs.org/)
## 安装
```
npx @bookedsolid/rea init
```
`init` 命令是一个交互式向导。它会检测你的项目,创建
`.rea/policy.yaml`,将钩子和斜杠命令复制到 `.claude/`,将
`.mcp.json` 配置为运行 `rea serve` 作为治理网关,安装
`.husky/commit-msg` 钩器,并将托管片段追加到 `CLAUDE.md`。
需要 Node 22+ 和 pnpm 9+。
## 什么是 REA
REA 是一个用于 Claude Code 的治理层。它是一个单一的 npm 包,
包含四个组件:
1. **钩子层** — 11 个 shell 脚本,集成到 Claude Code 的 `PreToolUse`
和 `PostToolUse` 事件中。钩子强制执行密钥扫描、危险命令拦截、
禁止路径保护、设置保护、归属拒绝以及提交/推送审查门控。
2. **网关层** — 一个 MCP 服务器(`rea serve`),它通过中间件链代理下游
MCP 服务器。每个工具调用 — 原生或代理 — 都会被分类、策略检查、
脱敏、审计,并在执行前进行大小限制。
3. **策略运行时** — `.rea/policy.yaml`,带有严格的 zod 验证
模式。定义自主级别、硬上限(`max_autonomy_level`)、禁止路径、
归属规则、上下文保护,以及可选的 Discord 通知 webhook。
4. **Kill switch** — `.rea/HALT` 是一个单一文件。如果它存在,
每个工具调用都将在中间件和钩子层被拒绝。使用
`rea freeze --reason "..."` 创建它,使用 `rea unfreeze --reason "..."`
移除它。
REA 是一个只做一件事的工具:基于操作员定义的策略来门控和审计
代理工具调用。这就是整个产品。
## REA 不是什么
这些是非目标。添加这些功能的 PR 将被关闭,并指向创建一个与 REA
组合使用的独立包。
- **不是项目管理者。** 没有任务 CRUD,没有 GitHub 问题同步,没有
板子 scaffolding。没有 `task_create`、`task_update`、`repo_scaffold`。
- **不是 Obsidian 集成。** 没有保险库日志记录,没有笔记创建,
没有预压缩摘要,没有预/后压缩 Obsidian 钩子。
- **不是账户管理器。** 没有 `rea account add/list/env/rotate/remove`。
没有 Keychain,没有 OAuth,没有多租户令牌保险库。仅使用环境变量。
- **不是 Discord 机器人。** 没有 Discord MCP 工具。`policy.yaml` 中的
Discord webhook URL 是最大的暴露面 — 仅一个出站 POST,可选择加入。
- **不是守护进程监督器。** `rea serve` 由 Claude Code 通过
`.mcp.json` 启动。Claude Code 拥有生命周期。没有 `rea start`,
没有 `rea stop`,没有 pid 文件,没有 systemd 单元。
- **不是托管服务。** 没有 REA Cloud,没有 SaaS 层级,没有
多令牌工作流,没有工作负载隔离平台。
- **不是 70 个代理的名单。** 10 个精选代理包含在包中。四个
配置文件(`client-engagement`、`bst-internal`、`lit-wc`、`open-source`)
在它们之上叠加了额外的专家。没有大杂烩。
非目标是产品本身。每一个“但如果只是添加 X”的需求都应该放在一个
独立的包中。
## 快速开始
### 1. 编写策略
`.rea/policy.yaml`:
```
version: "1"
profile: "bst-internal"
autonomy_level: L1
max_autonomy_level: L2
promotion_requires_human_approval: true
blocked_paths:
- ".env"
- ".env.*"
- "secrets/**"
block_ai_attribution: true
context_protection:
delegate_to_subagent:
- "pnpm run preflight"
- "pnpm run test"
- "pnpm run build"
max_bash_output_lines: 100
notification_channel: "" # optional Discord webhook
```
`autonomy_level` 可以提升到 `max_autonomy_level`,但不能超过。
如果 `autonomy_level` 超过上限,加载器会在解析时拒绝该文件。
上限由人类操作员设置,永远不会由代理设置。
### 2. 需要停止一切时冻结
```
rea freeze --reason "incident triage; investigate unexpected .env write"
```
`rea freeze` 会写入 `.rea/HALT`。之后的每个工具调用都会被拒绝
直到操作员运行:
```
rea unfreeze --reason "false alarm — resolved"
```
这两个调用都会产生审计条目。中间件不会自行清除 HALT。
### 3. 验证安装
```
rea doctor
```
`rea doctor` 检查钩子覆盖率、策略解析、husky commit-msg 钩子
安装、`.mcp.json` 网关布线、Codex 插件可用性,以及审计哈希链的完整性。
它会返回通过/失败的摘要和具体的修复提示。
## 架构
### 中间件链
每个原生 MCP 工具调用和每个代理下游调用都流经一个链。顺序很重要 —
每一层失败都会关闭。
`.rea/` 被硬编码为始终禁止的路径。它无法从策略中解除阻止。
策略在每次调用时都会重新读取 — 对 `policy.yaml` 的任何编辑都会在下一次工具调用时生效。
### 钩子层
钩子是集成到 `.claude/settings.json` 中的 shell 脚本。它们在 Claude Code
工具调用时运行,与网关独立。两者都失败关闭。绕过其中一个不会禁用另一个。
每个钩子都在顶部引用 `hooks/_lib/halt-check.sh` 和 `hooks/_lib/policy-read.sh`。
每个钩子都使用 `set -euo pipefail`。
### 斜杠命令
五个命令在包中提供,并在 `rea init` 时复制到 `.claude/commands/`。
### 代理名单
包中提供十个精选代理:`rea-orchestrator`、`code-reviewer`、
`codex-adversarial`、`security-engineer`、`accessibility-engineer`、
`typescript-specialist`、`frontend-specialist`、`backend-engineer`、
`qa-engineer`、`technical-writer`。四个配置文件
(`client-engagement`、`bst-internal`、`lit-wc`、`open-source`)
在它们之上叠加了额外的专家。没有大杂烩。
编排器是复杂任务的单一入口点。`rea init` 安装的 `CLAUDE.md` 模板指示宿主代理:
> “对于任何复杂任务,首先委托给 `rea-orchestrator` 代理。”
## 计划 / 构建 / 审查循环
Codex 是 REA 的一等公民。它不是附加组件。BST 工程技术将对抗审查
融入默认流程,REA 开箱即用。
| 阶段 | 主模型 | Codex 角色 | 治理 |
| --- | --- | --- | --- |
| 计划 | Claude Opus | — | 完整中间件链 |
| 实施前审查 | — | `/codex review` — 在代码前审查计划 | 已审计 |
| 构建 | Claude Opus | — | 完整中间件链 |
| 对抗审查 | — | `/codex adversarial-review` 对差异进行审查(独立视角) | 已审计、脱敏、kill-switched |
| 预合并门控 | — | `/codex adversarial-review` 重新运行;记录在 audit.jsonl | 必需的状态检查(推荐) |
三件事使这起作用:
1. 编排器中的 **`codex-adversarial` 代理**封装了
`/codex adversarial-review`。在每次非平凡变更后,编排器会委托给它。
2. **`/codex-review` 斜杠命令**是提供的五个命令之一。
它生成包含请求摘要、响应摘要和通过/失败信号的审计条目。
3. **`push-review-gate.sh` 钩子**检查当前分支上是否有最近的 `/codex-review`
审计条目,如果没有则警告(不阻止)。
Codex 响应被视为不可信输入。它们在时流经 `redact` 和 `injection`
中间件 — 与任何其他下游工具结果相同的处理。Codex 从未在提示中收到 `.rea/policy.yaml`
内容;Codex 审查差异,而不是策略。
如果未安装 Codex,`rea doctor` 会给出安装提示。REA 不需要 Codex 即可运行,
但默认工作流假设其存在。
## 钩子
十一个钩子(从 reagent 的 26 个减少而来)。每个只做一件事。
| 钩子 | 事件 | 一句话目的 |
| --- | --- | --- |
| `dangerous-bash-interceptor` | PreToolUse: Bash | 阻止破坏性 shell 命令类别 |
| `env-file-protection` | PreToolUse: Bash | 阻止读取 `.env*` 文件 |
| `dependency-audit-gate` | PreToolUse: Bash | 运行 `npm audit`;在高级/严重错误时阻止 |
| `commit-review-gate` | PreToolUse: Bash | 拦截 `git commit`;对非平凡差异要求审查 |
| `push-review-gate` | PreToolUse: Bash | 拦截 `git push`;如果最近没有 `/codex-review` 则警告 |
| `attribution-advisory` | PreToolUse: Bash | 阻止包含 AI 归属标记的提交 |
| `secret-scanner` | PreToolUse: Write\|Edit | 扫描文件写入中的凭证模式 |
| `settings-protection` | PreToolUse: Write\|Edit | 阻止代理写入 `.claude/settings.json` |
| `blocked-paths-enforcer` | PreToolUse: Write\|Edit | 强制执行策略中的 `blocked_paths` |
| `changeset-security-gate` | PreToolUse: Write\|Edit | 在安全相关更改时要求 changeset 条目 |
| `architecture-review-gate` | PostToolUse: Write\|Edit | 标记跨越架构边界的编辑 |
第十二个钩子 `security-disclosure-gate` 拦截包含安全敏感关键字的 `gh issue create`
命令并重定向到私人披露。它作为 Bash PreToolUse 集合的一部分安装。
## 斜杠命令
| 命令 | 目的 |
| --- | --- |
| `/rea` | 会话状态 — 自主级别、HALT 状态、最近的审计条目、下一步操作 |
| `/review` | 在当前更改上调用 `code-reviewer` 代理 |
| `/codex-review` | 调用 `codex-adversarial` 代理 → `/codex adversarial-review` |
| `/freeze` | 提示输入原因并写入 `.rea/HALT` |
| `/halt-check` | 验证每个中间件和钩子是否尊重 HALT |
## 策略文件参考
`.rea/policy.yaml` 字段。模式是严格的 zod — 未知字段会被
拒绝,而不是忽略。
| 字段 | 类型 | 目的 |
| --- | --- | --- |
| `version` | 字符串,`"1"` | 架构版本;仅接受 `"1"`(0.1.x) |
| `profile` | 字符串 | `profiles/` 中的配置文件名称(例如 `bst-internal`) |
| `autonomy_level` | `L0`\|`L1`\|`L2`\|`L3` | 当前自主级别。`L0` = 只读;`L3` = 完整工具访问 |
| `max_autonomy_level` | `L0`\|`L1`\|`L2`\|`L3` | 硬上限。`autonomy_level` 不能超过此值 |
| `promotion_requires_human_approval` | 布尔值 | 需要操作员确认才能提升自主性。默认 `true` |
| `blocked_paths` | 字符串数组 | 通配符模式。`.rea/` 始终被禁止,无论此列表如何 |
| `block_ai_attribution` | 布尔值 | 强制提交和 PR 正文不使用 AI 归属 |
| `context_protection.delegate_to_subagent` | 字符串数组 | 需要以子代理上下文运行的命令,以保留父级上下文窗口 |
| `context_protection.max_bash_output_lines` | 数字 | 将长 bash 输出截断为此行数 |
| `notification_channel` | 字符串 | 可选的 Discord webhook URL。空字符串 = 无通知 |
如果 `autonomy_level > max_autonomy_level`,在解析时会被拒绝。设置
`promotion_requires_human_approval: false` 需要 CLI 标志
`--i-understand-the-risks`。
## 从 `@bookedsolid/reagent` 迁移
```
npx @bookedsolid/rea init --from-reagent
```
`--from-reagent`:
- 读取 `.reagent/policy.yaml` 并逐字段转换为 `.rea/policy.yaml`。字段名称相同,因此只是重命名。
- 将 `.reagent/audit.jsonl` 移动到 `.rea/audit.jsonl` 并验证哈希链。
- 从 `.claude/settings.json` 中解除已移除的钩子(Obsidian、PM 层、账户)的绑定。
- 用 REA 等效项替换 `reagent` 斜杠命令和代理。
- 保留 `.reagent/` 文件夹;在验证 `rea doctor` 通过并完成一次试运行后手动删除。
在七天内,`reagent` 将通过 `npm deprecate` 弃用。弃用通知会指向此处。
## 安全
- [SECURITY.md](./SECURITY.md) — 披露策略、支持版本和
范围。不要通过公共 GitHub 问题报告漏洞。
- [THREAT_MODEL.md](./THREAT_MODEL.md) — 攻击面、缓解措施、
剩余风险。这是 REA 自身坚持的合同。
简要说明:网关和钩子层独立运行。两者都失败关闭。`.rea/` 始终被禁止。审计是哈希链式的。策略在每次调用时都会重新读取。npm 发布使用 OIDC 证明性,而非长期令牌。
## 贡献
参见 [CONTRIBUTING.md](./CONTRIBUTING.md)。简要说明:
- 每个提交都需要 DCO 签名(`git commit -s`)。CI 会拒绝未签名的提交。
- 提交消息、PR 正文或代码中不得包含 AI 归属。提交钩子会强制执行此规定。
- 遵循 Conventional Commits、TypeScript 严格模式、ESLint 零警告、Prettier、vitest。
- 安全敏感路径(`src/gateway/middleware/**`、`src/policy/**`、`hooks/**`、`.github/workflows/**`)需要明确的维护者审查和威胁模型更新。
## 许可证
[MIT](./LICENSE)
标签:Agentic治理, Claude Code, Codex集成, DCO, Git钩子, GNU通用公共许可证, HALT开关, JSONLines, Lerna, MCP网关, MITM代理, Node.js, npm包, SEO: Claude插件, SEO: MCP安全网关, SEO: 零信任治理, 上下文保护, 中间件链, 依赖注入, 安全门控, 审查机制, 审核日志, 审计追踪, 对抗性审查, 提交审核, 提示注入防御, 政策框架, 暗色界面, 治理层, 源代码安全, 策略执行, 自主性控制, 路径阻止, 钩子机制, 零信任