anatomia-dev/anatrace
GitHub: anatomia-dev/anatrace
anatrace 是一个本地化、确定性的 AI agent 会话合规验证引擎,通过分析 transcript 证明 agent 是否遵守了既定策略。
Stars: 0 | Forks: 0
# anatrace
**你的 AI agent 做了它该做的事吗 —— 而且你究竟能*证明*它没做什么?**
你赋予了一个 agent 访问你 repo 的广泛权限。它编辑了文件,运行了命令,可能
还生成了 sub-agent。anatrace 会读取 harness 已经写好的 session transcript
(如 Claude Code、Codex),并针对 agent 是否遵守了其义务返回一个**确定性结论** —— 而且当证据不完整时,它会回答
**`unverifiable(reason)`**,而绝不会瞎猜“没问题”。
最后这一点才是核心。一个过度声明的验证器比没有验证器更糟糕。
anatrace **以结论为先,并在质量退化时拒绝亮绿灯**:
被删除、压缩、跨存储或版本漂移的 transcript 会被降级为
`unverifiable`,而绝不会是 `satisfied`。
```
anatrace — VERDICT: ⚠ UNVERIFIABLE — 2 of 7 claims could not be proven
✓ satisfied: 5 ✗ violated: 0 ⚠ unverifiable: 2
⚠ 1 unverifiable: codex-blind (verify-independence)
⚠ 1 unverifiable: delegate-coverage-incomplete (no-secret)
session: claude · claude-opus-4-8 · 482 turns · 14 files
cost: ~$27.36 · tokens 36.0M total
```
- **确定性的,已发布的结论路径中零 LLM** —— 相同的输入字节 →
字节完全相同的结果,可以被不信任你的人复现。没有 LLM
去给 LLM 打分。
- **本地化** —— 无网络,无上传。你的 transcript 永远不会离开你的机器。
- **零插桩** —— 在你现有的 Claude Code / Codex session 上运行;
无需 SDK,无需 hooks。
### 典型示例
这正是 diff-reviewer 在结构上无法看到的事情,而且它是一个两行的策略:
```
rules:
- id: no-test-edits
subject: this-agent
never_edit: test/
```
将其在已记录的典型 session(`packages/cli/test/fixtures/hero/`,包含
可重放的 `anatrace.cast`)上运行,anatrace 会率先给出 `✗ VIOLATED — no-test-edits` **并且**,
在同一个 session 中,对于一个它无法证明的 secret-read(因为生成的
sub-agent 的 transcript 从未被捕获),它会如实给出 `⚠ unverifiable`。既捕获了违规,又作出了有原则的弃权。
## 安装
```
npm install anatrace-core
npm install --global anatrace
```
## 它目前已实现的功能
结论为先;成本/token/摩擦 作为页脚附在后面(基本要素,绝不是
头条新闻)。
- **合规结论** — 给定一个 mandate,anatrace 会针对每项声明输出
确定性的结论(`satisfied` / `violated` / `unverifiable`),并附带一个
封闭的、机器可读的原因。**在已发布的结论路径中没有 LLM**:
已发布的 API 或 `--json` 信封中没有 judge,因此结论是
可以被不信任你的人按字节复现的。(消费者*可以*注入他们
自己的模型,来对 anatrace 弃权的残留物发表意见 —— 这是可选的,仅在
已经是 `unverifiable` 的声明上运行,标记为 `source: 'llm'`,并且它永远不会作为门控。确定性
结论路径永远不会调用它。)
缺失或无法比较的信号始终是
`unverifiable`,绝不是猜测 —— 一个过度声明的验证器比没有验证器更糟糕。使用 `--ci` / `--fail-on` 拦截 CI,
或者输出 `--format sarif` 用于代码扫描。**CI 门控仅在
`violated` 时让构建失败:** 在默认的 `--ci` 下(fail-on 为 `error`),`unverifiable` 会映射为
`info` 并且永远不会作为门控 —— 如实的“我无法验证此项”是一个暴露出来的盲点,
而不是策略失败,所以它不会阻止 merge。(如果消费者希望
在盲点处直接强行停止,可以选择启用 `--fail-on info`。)这*并不*矛盾于当
`unverifiable > 0` 时,结论层面拒绝报告“一切正常”:
结论层如实反映了它无法证明的内容,
而门控仅阻止已证实的违规行为 —— 两个不同的维度,这是有意为之的。
*(文件范围的遵守是头条检查项;如今它已在
精心挑选的样本上进行了验证 —— 截至 2026-06,一项经过仔细测量的精确率/召回率基准测试正在进行中,目前尚无公布的数值。)*
- **渠道与谱系覆盖率** — 每次策略运行都会声明检查了多少项声明
并列出已知的盲点。未知工具、不支持的 shell
命令以及不完整的 delegate 捕获会将干净的否定结果降级为
`unverifiable`;而观察到的违规行为仍然是违规。
- **Mandate 检查** — `anatrace mandate show ` 从框架的源文件中提取已声明的
mandate(声明 + 谓词覆盖率)。
- **通用策略加载** — 仓库自有的 `.anatrace.yaml` 无需
框架适配器即可直接编译为 Mandate IR。
- *随附页脚(基本要素,而非头条):* 每个 session 的 token / 轮次 /
工具计数以及预估的**成本**(位冻结的 `ProvenanceCounts`),加上
关于 session 在何处陷入困境的确定性**摩擦**
发现 —— 汇总在结论下方。
此版本是诚实的引擎,而不是最终的审计产物。它
提供了带有明确覆盖限制的确定性 transcript 验证。
带有时间戳和哈希值的便携式证明仍是后续阶段的任务。
## 通用策略
将 `.anatrace.yaml` 放在工作目录中,或传入
`--policy path/to/policy.yaml`:
```
version: 1
rules:
- id: build-files
subject: role:build
delegates: include
only_edit:
- src/output.ts
- id: no-secrets
subject: this-agent-and-all-delegates
never_read:
- secrets/customer.csv
- id: no-destructive-command
subject: this-agent
never_run:
- rm -rf
- id: no-test-edits # the hero check: don't let the agent edit the tests to pass
subject: this-agent
never_edit: test/
- id: no-external-egress
subject: any-agent-in-session
never_egress: external
```
```
anatrace session.jsonl --role build --json
```
策略主体是明确的:`this-agent`、
`this-agent-and-all-delegates`、`any-agent-in-session` 或 `role:`。
`role:` 使用 `delegates: include|exclude`,并且必须由
启动器或 `--role` 绑定。
包含 delegate 的否定判断需要完整的证据边界。anatrace
分三部分对该边界进行建模:
1. 来自 transcript、sidecar 和已捕获 harness hooks 的观察到的谱系;
2. 来自启动器(如 Anatomia)的预期启动记录;
3. 对账后的捕获覆盖率,证明每个预期的 delegate 通道都已被捕获。
Hook 记录可以以 JSONL 格式提供:
```
anatrace session.jsonl \
--policy .anatrace.yaml \
--lineage-hooks hooks.jsonl
```
受信任的启动器也可以提供预期的启动记录。CLI 会在评估结论之前
将它们与观察到的已检查谱系进行对账:
```
anatrace session.jsonl \
--policy .anatrace.yaml \
--lineage-hooks hooks.jsonl \
--capture-manifest capture.json \
--json
```
```
{
"kind": "expected-launch-boundary",
"source": "trusted-launcher",
"lanes": [
{
"agent": { "kind": "root" },
"expectedDelegates": [{ "kind": "subagent", "subagentId": "reviewer" }]
},
{
"agent": { "kind": "subagent", "subagentId": "reviewer" },
"expectedDelegates": []
}
]
}
```
预期的启动记录是意图,而不是捕获的证明。只有当
观察到的谱系显示其 transcript 字节已被检查时,通道才会被标记为
已捕获。如果没有完整的递归捕获覆盖率,缺失会产生一个
原因为 `delegate-coverage-incomplete` 的 `unverifiable` 结论;观察到的 root
或 delegate 违规仍然带有证据。找到一些 sidecar 或 hook
记录本身并不代表完整。参见 [Subject Axis](./docs/SUBJECT-AXIS.md)。
`never_read` 涵盖结构化读取以及通过 `cat`、`sed`、
`head`、`tail`、`grep`、输入重定向和基于文件的 `curl`/`wget`
payload 进行的 shell 读取。`never_egress` 通过 shell 网络
命令、网络工具和 MCP 调用检测粗粒度的外部活动。域名/资源白名单尚未
建模;这将留待资源分类法阶段处理。
未知工具或不支持的 shell 命令永远不会被视为无害。如果
它可能影响到证明干净的否定结果所需的通道,该声明将返回
`unverifiable: channel-coverage-incomplete`,并且覆盖率回执会指出该
缺口。
## 包
- **`anatrace`** — CLI(唯一的 I/O 层):分析 session,检查
mandate,拦截 CI。
- **`anatrace-core`** — 纯引擎和共享类型契约。没有 fs,没有
网络,没有时钟,没有随机性。
- **`anatrace-action`** — CI 拦截 GitHub Action:它在 PR 上运行 anatrace,
将仅包含违规的 SARIF 上传到代码扫描,发布一个以无法验证项打头的置顶结论评论,
并基于产物完整性进行拦截。由真实的 CI 运行构建并验证;
**尚未作为带标签的 action 发布**(这是一个发布步骤 —
参见 `docs/guides/ci-gate.md`)。CLI 也可以直接拦截 CI(`anatrace --ci` /
`--fail-on`,`--format sarif`)。
## 确定性与隐私契约
`anatrace-core` 在构建上是纯粹的 —— 它的 TypeScript 配置在编译时使用了
`"types": []`,因此 `node:fs` / `process` / 网络引用会引发**编译
错误**,而不是代码检查意见。CI 将已发布的 `ProvenanceCounts` /
`TokenCounts` *结构*(确切的字段、键顺序,无 `cost_usd`)锁定在
一个已提交的 golden 文件上,并且“相同字节输入 → 字节完全相同输出”的确定性测试
在每次更改时都会运行。参见 [CONTRIBUTING.md](./CONTRIBUTING.md)。
## 许可证
[MIT](./LICENSE)
标签:AI智能体, MITM代理, 人工智能, 会话验证, 安全合规, 完整性校验, 暗色界面, 用户模式Hook绕过, 确定性分析, 网络代理, 自动化攻击, 行为审计