Codex接入GitLab后,MR自动审查会漏掉什么?
Codex Cloud 现在已经能接 GitLab。
OpenAI 8 月 19 日把 GitLab Support 放进 Beta:可以连接 GitLab Project、为项目创建 Codex Cloud Environment,从 Issue 或 Merge Request 里通过 @codex 发起任务,也可以做一次性或自动 Merge Request Review。
真正值得工程团队注意的,不是“终于支持 GitLab”这件事,而是官方明确写出的一个限制:
如果 GitLab 省略了 collapsed diff 或 oversize diff,Codex 就无法完成完整 Review。
这句话非常关键。
因为它揭示了所有 AI Code Review 系统都会遇到的一个边界:
模型没有看到的代码
不可能被可靠审查
但很多团队最后只看一个:
AI Review = PASS
却没记录:
它到底看到了多少 Diff?
Review Coverage必须是一级指标
假设一个 MR:
Changed Files: 42
Changed Lines: 5800
GitLab 为了性能折叠了一些大文件。
Codex 实际看到:
Files: 31
Lines: 3600
如果最终只输出:
No critical issues found.
这句话非常容易被误解成:
5800 行全部审过
所以每次 AI Review 应该附带:
Coverage
例如:
{
"changed_files": 42,
"reviewed_files": 31,
"changed_lines": 5800,
"reviewed_lines": 3600,
"collapsed_files": 7,
"oversize_files": 4
}
然后算:
file_coverage = 31 / 42 = 73.8%
不到阈值,Review 不应该标成:
PASS
而应该:
INCOMPLETE
我会把Review状态拆成四种
public enum ReviewStatus {
PASS,
FAIL,
INCOMPLETE,
ERROR
}
INCOMPLETE 和 PASS 不是一回事。
例如:
PASS:
已经覆盖所有要求审查的文件,未发现阻断问题
INCOMPLETE:
存在未获取的 Diff,不能给出完整结论
UI 里也应该用不同颜色。
GitLab的大Diff为什么会消失
大型代码平台为了避免页面和 API 请求过重,会对:
超大文件
生成文件
二进制
大规模变更
做折叠或截断。
所以 Coding Agent 不能只依赖:
Merge Request Diff API
如果权限和工作流允许,Review Worker 最好有第二条路径:
Checkout Repository
↓
Base Commit
↓
Head Commit
↓
git diff
自己在工作区里算完整 Diff。
例如:
git fetch origin merge-requests/1842/head:mr-1842
git diff \
origin/main...mr-1842 \
-- .
这样至少不受 UI 折叠影响。
但“自己checkout”又引入了新的安全边界
如果 MR 来自不可信分支:
不要直接执行代码
Review 阶段只需要:
read repository
parse diff
static analysis
不要因为 Agent 想“验证一下”,就自动:
npm install
npm test
外部贡献的:
package.json
postinstall
Makefile
test script
都可能执行任意命令。
所以 Review Environment 最好分两级:
Level 1:
Read-only Diff Review
Level 2:
Sandboxed Validation
只有 Level 2 才允许运行构建和测试。
Webhook是另一个容易忽略的攻击面
OpenAI 的 GitLab 集成说明里提到:
GitLab-triggered activity
需要权限配置相应 Webhook
对于 GitLab Self-Managed 或 Dedicated,Workspace Admin 需要先配置连接,而且 Webhook Activity 要求:
GitLab 19.0+
一旦接上 Webhook,就意味着:
外部事件
可以触发 Agent
所以必须验证:
Webhook Signature
Project ID
Event Type
Branch
Actor
不能只看 JSON 里写:
{
"object_kind": "merge_request"
}
就启动 Codex Task。
Webhook必须先去重
GitLab 重试 Webhook 是正常行为。
如果:
同一个 MR Event
触发两次 Agent:
两个 Review
两份评论
两次成本
所以需要:
Inbox
例如:
@Entity
public class GitLabWebhookInbox {
@Id
private String deliveryId;
private String projectId;
private String eventType;
private Instant receivedAt;
}
处理前:
deliveryId 已存在
→ ACK
→ 不重复执行
自动Review不能绑定“每次push都全量重跑”
一个 MR 可能连续 Push:
10 次
如果每次都:
完整仓库 Review
成本很快上升。
可以做 Incremental Review:
previous_reviewed_sha
↓
current_head_sha
↓
git diff old...new
只审新增变化。
但安全相关规则可以全量重新跑。
例如:
Secret Scan
Permission Change
Dependency Change
Workflow Change
这几类应该每次重新检查。
我会把Review拆成三层
Layer 1:确定性规则
Secret
Dependency
License
Protected Path
Schema
Generated File
Binary
Layer 2:静态分析
CodeQL
Compiler
Lint
Type Check
Layer 3:LLM Review
逻辑
可维护性
边界条件
设计问题
这样不会把可以确定性发现的问题全部交给模型。
MR Review的上下文也不能无限塞
如果 5000 行 Diff 全交给模型:
上下文很贵
注意力也会稀释
更合理是先建立 File Risk Score。
例如:
risk = 0
if file in protected_paths:
risk += 5
if touches_auth:
risk += 5
if changes_sql:
risk += 4
if lines_changed > 500:
risk += 2
if test_file:
risk -= 1
优先让 Agent 深审:
高风险文件
低风险格式化变更减少 Token。
一个MR Manifest
public record MergeRequestManifest(
String projectId,
long mergeRequestIid,
String baseSha,
String headSha,
int changedFiles,
int changedLines,
Set collapsedFiles,
Set oversizeFiles,
String diffHash) {
}
Review Report 必须绑定:
baseSha
headSha
diffHash
否则 MR 新 Push 后,旧 Review 很容易继续显示:
通过
实际上已经过期。
Review必须有Stale状态
当:
current_head_sha != reviewed_head_sha
立即:
STALE
不要把旧 AI Review 当成当前版本结论。
public boolean isStale(
ReviewReport report,
String currentHeadSha) {
return !report.headSha()
.equals(currentHeadSha);
}
自动评论不要无限刷线程
AI Code Review 很容易生成大量:
“建议考虑……”
如果每个小问题都单独发评论,MR 会被淹没。
我会设置:
review:
max_inline_comments: 8
min_severity: MEDIUM
low_severity: summary_only
Critical/High:
Inline
Low:
汇总
Review建议还需要“可验证”
好的建议:
AuthFilter.java:91
在 token 为空时这里会 NPE,
因为 line 87 的 getClaim() 可返回 null。
建议新增 test:
missing_subject_claim
差的:
“建议提高代码健壮性。”
生产 Review Agent 应该要求:
File
Line
Evidence
Failure Mode
Suggested Test
没有 Evidence 的评论降级。
自动Review不能拥有Merge权限
我不建议第一阶段让 Review Agent:
review + merge
放在同一个权限主体。
更合理:
Reviewer Agent
只产出 Review Decision
Merge Controller
读取:
CI + Human Approval + Policy
再决定 Merge
避免模型同时当:
裁判
+
执行人
一个最小MR Gate
merge-gate:
ai-review:
required: true
minimum-file-coverage: 0.95
allow-incomplete: false
ci:
required: true
security:
critical-findings: 0
human:
approvals: 1
如果 Diff Coverage 只有:
73%
AI Review 就算没有发现问题,也不能满足 Gate。
GitLab Self-Managed还要多一个版本检查
官方说明:
Webhook activity requires GitLab 19.0 or later
所以 Connector 初始化时就应该检查:
Server Version
不满足直接提示:
Webhook-triggered Codex tasks unavailable
不要等上线后才发现自动触发不工作。
我会做的12个测试
1. 正常 MR
2. Oversize Diff
3. Collapsed Diff
4. MR Push 后旧 Review 变 Stale
5. Webhook 重复投递
6. Webhook 签名错误
7. 外部 Fork 不执行构建脚本
8. 5000+ 行大 Diff
9. Protected Path 修改
10. 自动评论上限
11. GitLab < 19.0
12. AI Review PASS 但 Coverage 不足
Codex 支持 GitLab 以后,最容易产生的误区是:
“MR 已经有 AI 自动 Review 了。”
真正应该问的是:
AI 看到了多少?
Review 对应哪个 Commit?
有没有被折叠的 Diff?
Webhook 是否重复?
不可信代码有没有被执行?
OpenAI 明确写出“collapsed 或 oversize diff 会让 Codex 无法完成 Review”,反而是一件好事。
它提醒我们:
Code Review 的第一指标,不应该是模型写了多少评论,而是 Review Coverage 到底是多少。
没有覆盖率的“自动审查通过”,只能算一个建议,不能算一个发布门禁。
更多企业级 AI 应用、Agent、RAG 与模型工程化内容,我会继续整理在 智元界:
https://www.zyentor.com/