abm9111/vigil
GitHub: abm9111/vigil
VIGIL 是一款面向 Claude Code 的代码库质量与合规审计技能,通过关联已有扫描工具的发现结果并进行规则化评分来解决代码审计中的质量问题。
Stars: 0 | Forks: 0
# VIGIL
[](https://github.com/abm9111/vigil/actions/workflows/self-audit.yml)
[](LICENSE)
一个专为 [Claude Code](https://claude.com/claude-code) 设计的代码库审计技能。它会运行你的技术栈中已有的确定性工具,关联它们在不同领域发现的问题,并对结果进行评分——所依据的规则旨在确保评级不会暗中与发现的结果相矛盾。
VIGIL 的大部分内容是供 LLM 阅读和遵循的指导性 Markdown。位于 `evals/` 下的两个 Python 框架确保了其可靠性。
```
/vigil # full audit (default)
/vigil scan # 30s triage sweep
/vigil watch --ci # diff-only CI gate
/vigil siege # adversarial, exhaustive
```
## 它的独特之处
三个理念,每一个的存在都是因为显而易见的设计会在特定情况下失效:
**严重性下限。** 加权平均值会将一个严重的发现埋没在低权重的集群中。合规性(6%)中的一个 HIGH 问题对整体分数的影响不到一分——因此,一个破损的交付物可能会得到 A 的评分。现在,评级受到最严重的未解决发现的封顶限制:任何 CRITICAL 问题最高只能评 59 分,任何 HIGH 问题最高评 79 分。该上限始终会显示出来,绝不静默处理。
**N/E——“无证据”,与 N/A 不同。** 扫描器从未运行的集群并不代表它是干净的;它只是未经过检查。N/A 的意思是*不适用*,并会从权重计算中剔除。N/E 的意思是*适用,但无法检查*——它会阻断任何通过的判定,并在 CI 中以退出代码 2 结束。绿色的流水线绝不应该意味着“缺少扫描器”。
**非对抗性关联。** 十个关联模式中有七个假设存在攻击者。三个则不然,因为许多实际的损害根本不需要攻击者——往往是有人基于一个暗中造假的构件善意行事:
| 模式 | 触发条件 |
|---|---|
| `TRUST_LAUNDERING` | 将机器生成的内容作为权威内容呈现,并跨越了边界 |
| `DESTRUCTIVE_BEFORE_VALIDATE` | 在执行可能导致其中止的检查之前,安排了不可逆的步骤 |
| `INTEGRITY_THEATER` | 校验和、清单或审计日志实际上根本无法发挥拦截作用 |
## 安装
将其复制或符号链接到你的 Claude Code 技能目录中:
```
curl -fsSL https://raw.githubusercontent.com/abm9111/vigil/main/install.sh | bash
# 或者,如果你想先阅读脚本的话——对于 auditing tool 来说你应该这么做:
git clone https://github.com/abm9111/vigil.git ~/.claude/skills/vigil
```
然后在任何项目中输入 `/vigil`。工具发现是自动的——有关每个扫描器的清单和安装命令,请参阅 `engines/preflight.md`。
## 布局
| 路径 | 内容 |
|---|---|
| `SKILL.md` | 路由——决定在哪种模式下加载哪些文件 |
| `RULES.md` | 铁律:先有证据后有观点,严重性定义,无误报 |
| `clusters/` | 分领域检查。每个都声明了权重和 ID 前缀 |
| `engines/` | 评分、关联、预检、CI 适配器 |
| `modes/` | scan · audit · siege · watch · score · compare |
| `compliance-maps/` | SOC 2、ISO 27001、OWASP、AI 透明度映射 |
| `evals/` | 自审计和测试用例测量——见下文 |
| `tests/` | 证明每一个自审计检查都可能失败的测试 |
| `lessons/` | VIGIL 犯错记录账本 → [`LEDGER.md`](LEDGER.md) |
## 保持可靠性
一个审计他人证据的工具,理应也能产生自己的证据。
```
python3 evals/check_repo.py # 37 structural checks, <1s, no LLM
python3 evals/check_loadable.py # the skill is actually discoverable
pytest tests/ -q # every check must be able to FAIL
python3 evals/run_eval.py # recall / false positives against fixtures
```
`tests/` 的存在是因为只有通过机器重新检查,“负面测试”才具有持久的意义。每个测试都会复制仓库,精确地破坏一个不变量,并断言相应的检查会被触发——而且有一个测试专门断言*每一个*文档化的检查都有这样的测试,因此添加一个没有测试的检查本身就是一种失败。
`check_repo.py` 的存在是因为,在一个以文为驱动的技能中,内部不一致性就是一个*功能性* bug:两个阅读相同规则的审计员会计算出不同的分数。每一次检查都是在真实的漏洞绕过之前的检查之后添加的——死链接、孤立的集群、自相矛盾的权重表、指向虚无的合规性引用,以及在另一个文件中被隔离的降级规则。
`run_eval.py` 用于衡量在 `evals/fixtures/` 中植入缺陷的召回率。**在引用其中的任何数据之前,请先阅读 `evals/README.md`。** 这是针对两个测试用例中的六个缺陷在单一模型上的冒烟回归测试——它用于检测是否有东西损坏。它并不能证明 VIGIL 能够“捕获生产级别的缺陷类别”。`clean-control` 测试用例(植入*零*缺陷,因此任何发现都是不合理的)是这套测试中最有力的工具。
运行的记录保存在 `evals/results/` 中,包括每次运行暴露出的框架 bug 和测试用例缺陷。这些描述比单纯的分数更有价值。
## 账本
[**LEDGER.md**](LEDGER.md) 是仪表板:谁发现了哪类缺陷,现在是什么捕获了它们,以及——有用的一半——是什么*未能*捕获它们。
[`lessons/`](lessons/README.md) 记录了 VIGIL——或其自身的自审计——**出错**的时候:当时相信什么,谁发现了错误,是什么*未能*捕获它,以及现在采取了什么措施来防止重蹈覆辙。它是该技能的持久记忆。新的会话继承的是推理逻辑,而不仅仅是检查规则。
`L17` 执行了这一点:一个声称已实现自动化的经验教训必须指明一个实际存在的检查,而一个仍然开放的问题必须在 `docs/OPEN-DESIGN.md` 中进行跟踪。
**这里的任何东西都不是自动应用的。** 记录一条经验教训和将其自动化是两个独立审查的行为,且都需要由人来提交。一个重写自身标准的审计工具无异于给自己的作业打分——`lessons/0003` 展示了发生这种情况时的真实写照。
如果你发现 VIGIL 出错了,*那*本身就是一种贡献。一个写着“VIGIL 告诉我 X,这就是为什么 X 是错误的”的 pull request 是一种证据;而仅仅修改规则的 pull request 只是对证据的一种断言。
**但千万不要把你的工作发给我们。** 一条经验教训关注的是某*一类*错误——而不是你的路径、主机、架构或 `.vigil/context.md`(该文件旨在枚举你的关键路径,如果发过来,那将等同于一份印有你名字的攻击路线图)。`L19` 会扫描结构化的特征;它无法理解自然语言,因此维护者在合并前会亲自阅读每一条经验教训。完整的指南见 [`lessons/README.md`](lessons/README.md)。
## 尚未完成的工作
[`docs/OPEN-DESIGN.md`](docs/OPEN-DESIGN.md) 列出了待完成的设计工作——这些是需要做出决策而不是直接修改的项目,每一个都已附带了之前讨论过的论点,以便下一轮工作可以直接从该论点开始。其中最大的问题是:大多数集群仍然没有能够被判定为失败的探针,因此从构建机制上来说,加权平均值的大部分内容都缺乏证据支持。
## 审查本项目
受邀审查者?请从 [REVIEWING.md](REVIEWING.md) 开始阅读——了解已知的问题、有意保留的开放性问题,以及真正的风险所在。
## 状态
实验性。请将其视为带有自检框架的审计助手,而不是带有评级权限的权威工具——并且应将*失败*的运行视为比成功的运行包含更多的有效信息。
## 许可证
Apache-2.0——见 [LICENSE](LICENSE) 和 [NOTICE](NOTICE)。“VIGIL”并未随代码一起授权;分支项目应选择一个不同的名称。
标签:AI辅助开发, Claude Code, 安全规则引擎, 逆向工具, 防御加固