Kirvolque/reviewability
GitHub: Kirvolque/reviewability
通过分析 Git diff 的结构特征来量化评估代码审查的认知负担,作为 CI/CD 门禁防止难以安全审查的 PR 被合并。
Stars: 1 | Forks: 0
# reviewability
**一个 CI/CD 质量门禁,通过评估 Pull Request 的审查难度来进行打分。**
在合并之前,识别出那些过大、过于混乱或过于分散而无法安全审查的 diff。

*AI 生成代码的速度再快也没用——瓶颈在于人工审查者。*
## 安装说明
```
pip install reviewability
```
需要 Python 3.12+。
## 核心理念
一个 Pull Request 可能很难审查,但这不一定是因为代码写得差,而是因为
变更的组合方式。在一个 PR 中混合了重命名、代码移动和逻辑修改,
会让每一项都更难验证。这种情况在 AI 生成的代码中尤为常见。与
Linter 不同,Reviewability 不分析代码本身——只分析变更的结构。
当 diff 的分数较低时,通常的补救措施是将其拆分为多个重点突出的
Pull Request,或者推迟非必要的变更。
Reviewability 在单个 hunk、文件和整个 diff 的层面上计算指标,
从而得出 **Reviewability Scores**(0.0 = 最难,1.0 = 最简单),并
为界定问题行为设定了可配置的阈值。
## 关键概念
- **Hunk** — 单个文件内连续的变更块(最小的分析单元)
- **Metric** — 附加到 hunk、文件或整个 diff 的计算值
- **Score** — 一个 [0.0, 1.0] 的浮点数,表示 hunk、文件或 diff 级别的可审查性
## 扩展性
指标系统旨在支持扩展:
- **添加指标** — 继承 `HunkMetric`、`FileMetric` 或 `OverallMetric`,实现 `calculate()` 方法,通过 `registry.add()` 注册
- **调整评分** — 提供自定义的 `ReviewabilityScorer` 实现
- **调整阈值** — 编辑 `reviewability.toml` 以更改界定问题行为的分数及触发违规的限制
## 使用方法
```
# 分析一系列 commits
reviewability HEAD~1 HEAD
# 从 stdin 分析
git diff HEAD~1 | reviewability --from-stdin
# 使用自定义 config
reviewability --config path/to/reviewability.toml HEAD~1 HEAD
# 包含 per-file 和 per-hunk 细分
reviewability --detailed HEAD~1 HEAD
```
输出为 JSON。如果门禁通过,退出码为 `0`;如果失败,则为 `1`。
## Claude Code Skill
如果您使用 [Claude Code](https://claude.ai/code),其中包含了一个 `/reviewability` 技能。
它会在当前的 diff 上运行该工具,总结结果,并尝试
直接处理任何建议。
## 移动检测
被移动的代码很容易审查——逻辑没有改变,只是位置变了。该工具会检测
何时代码块从一个地方被删除并插入到另一个地方(考虑到
重新缩进和 package/import 的变化),并将这些 hunk 和文件视为重定位。
重定位会获得满分,并且被排除在驱动
整体分数的规模和变动(churn)计算之外。仅因重定位而导致的巨大 diff 不会受到惩罚。
## 指标
指标在三个层面上计算:hunk、文件和整体 diff。
### Hunk 级别
| Metric | Description |
|--------|-------------|
| `hunk.lines_changed` | 一个 hunk 中添加和删除的总行数 |
| `hunk.added_lines` | 一个 hunk 中添加的行数 |
| `hunk.removed_lines` | 一个 hunk 中删除的行数 |
| `hunk.context_lines` | 变更周围未更改的上下文行 |
| `hunk.change_balance` | 添加行与总变更行的比率(0.0 = 纯删除,1.0 = 纯添加) |
| `hunk.is_likely_moved` | 此 hunk 是否是从另一个位置移动过来的代码 |
### 文件级别
| Metric | Description |
|--------|-------------|
| `file.lines_changed` | 一个文件中所有 hunk 添加和删除的总行数 |
| `file.added_lines` | 一个文件中添加的总行数 |
| `file.removed_lines` | 一个文件中删除的总行数 |
| `file.hunk_count` | 一个文件中独立变更区域的数量 |
| `file.max_hunk_lines` | 一个文件中单个最大 hunk 的变更行数 |
| `file.is_likely_moved` | 此文件是否是从另一个路径移动过来的 |
### 整体级别
| Metric | Description |
|--------|-------------|
| `overall.lines_changed` | 整个 diff 中变更的总行数 |
| `overall.added_lines` | 整个 diff 中添加的总行数 |
| `overall.removed_lines` | 整个 diff 中删除的总行数 |
| `overall.files_changed` | 变更的文件数量 |
| `overall.moved_lines` | 被识别为代码移动的 hunk 中的总行数 |
| `overall.change_entropy` | 变更在文件间分布的香农熵(Shannon entropy) |
| `overall.largest_file_ratio` | 变更最多的文件占总 diff 行数的比例 |
| `overall.churn_complexity` | 所有 hunk 中添加和删除交错程度的平均值 |
| `overall.problematic_hunk_count` | 分数低于配置阈值的 hunk 数量 |
| `overall.problematic_file_count` | 分数低于配置阈值的文件数量 |
## 整体评分
整体分数由两个因素驱动:**diff 大小**和**变动复杂度(churn complexity)**。
较大的 diff 更难审查。在同一个 hunk 内添加和删除交错存在的 diff,比
两者分离的 diff 更难审查。该分数会对这两者进行惩罚——
但仅当它们同时发生时。一个巨大但方向单一的 diff(例如批量重命名)得分
良好。一个小但混乱的 diff 得分也良好。最差的分数来自于既巨大
*且*内部混合的 diff。
## 相关研究
这些指标基于关于代码审查有效性的同行评审研究:
- Jureczko et al. — *Code review effectiveness: an empirical study on selected factors influence* (IET Software, 2021)
https://doi.org/10.1049/iet-sen.2020.0134
- McIntosh et al. — *An Empirical Study of the Impact of Modern Code Review Practices on Software Quality* (EMSE, 2015)
https://doi.org/10.1007/s10664-015-9381-9
- Fregnan et al. — *First Come First Served: The Impact of File Position on Code Review* (EMSE, 2022)
https://doi.org/10.1007/s10664-021-10034-0
- Uchôa et al. — *Predicting Design Impactful Changes in Modern Code Review* (MSR, 2020)
https://doi.org/10.1145/3379597.3387480
- Baum et al. — *The Choice of Code Review Process: A Survey on the State of the Practice* (EMSE, 2019)
https://doi.org/10.1007/s10664-018-9657-6
- Hijazi et al. — *Using Biometric Data to Measure Code Review Quality* (TSE, 2021)
https://doi.org/10.1109/TSE.2020.2992169
- Olewicki et al. — *Towards Better Code Reviews: Using Mutation Testing to Prioritise Code Changes* (2024)
https://arxiv.org/abs/2402.01860
- Barnett et al. — *Helping Developers Help Themselves: Automatic Decomposition of Code Review Changesets* (ICSE, 2015)
https://doi.org/10.1109/ICSE.2015.35
- Brito & Valente — *RAID — Refactoring-Aware and Intelligent Diffs* (2021)
https://doi.org/10.1109/ICSME52107.2021.00037
- Hu & Pradel — *CodeMapper: Mapping and Analyzing Code Changes across Commits* (ICSE, 2026)
标签:AI辅助开发, Diff分析, Git Diff, Pull Request, Python, 云安全监控, 代码复杂度, 代码审查, 代码度量, 可维护性, 数据管道, 文档结构分析, 无后门, 研发效能, 网络安全研究, 认知负荷, 质量门禁, 软件工程, 逆向工具, 静态分析