☰
open-code-review:一种可验证、可审计的代码审查协议
2026/9/25 6:12:09 网站建设 项目流程

1. 这不是又一个“AI写代码”工具——open-code-review的本质是重构代码审查的权力结构

我第一次在 GitHub 上看到open-code-review这个仓库名时,下意识点开想搜“怎么安装”,结果 README 第一行写着:“This is not a CLI. This is a protocol.” ——当时手一抖差点关掉页面。后来花了三周时间,把它的 commit history、issue 讨论、以及所有下游集成项目(包括几个内部已上线的 CI 流水线)全翻了一遍,才真正明白:它根本不是让你“装个命令行然后 run 一下就出 review 结果”的玩具。它是一套可验证、可审计、可插拔、且拒绝中心化模型托管的代码审查协作范式。

核心关键词里没有出现“LLM”,但所有热词都在围着它打转:codex cli、zcode cli、trae cli、claude code cli……这些名字背后,本质都是把大模型能力封装成黑盒 CLI 工具,用户交出代码,换回一段带高亮的评论。而open-code-review的设计哲学恰恰相反:它不提供模型,不托管 API,不预设 prompt 模板,甚至不强制你用 LLM ——它只定义输入结构、输出契约、执行上下文约束和结果签名机制。换句话说,它把“谁来审”“用什么审”“审得对不对”这三件事,从耦合态彻底解耦。

比如,你本地跑git diff HEAD~1 | open-code-review --engine ollama:deepseek-coder-32b-instruct,这个命令里ollama:不是协议前缀,而是明确声明:本次审查由本机 Ollama 实例中名为deepseek-coder-32b-instruct的模型执行;--engine参数必须指向一个符合open-code-review规范的执行器(executor),该执行器需实现标准输入(diff patch + file context)、标准输出(JSON Schema 定义的 ReviewResult)、以及可选的签名钩子(signing hook)。这意味着,你可以用本地运行的 Qwen2.5-Coder,也可以调用公司内网部署的 CodeLlama-70B,甚至可以接入一个规则引擎(如 Semgrep + 自定义 YAML 规则集)——只要它能按约定格式输出,就被视为合法审查者。

提示:很多人误以为open-code-review是“开源版 Codex CLI”,这是最大认知偏差。Codex CLI 是模型即服务(MaaS)的客户端,而open-code-review是审查即契约(RaaC)的协议层。前者问“我能调哪个 API”,后者问“你承诺输出什么、如何证明你没篡改结果”。

它解决的不是“怎么让 AI 看代码”这个技术问题,而是“当多个团队、多种模型、不同安全等级的代码审查能力共存于同一代码库时,如何确保每条评论都可追溯、可验证、不可抵赖”。这直接对应热词中反复出现的痛点:使用llm时如何防止密钥等鉴权信息泄露、dify的sql查询内容太多导致llm返回不稳定、prompt injection attack to tool selection in llm agents。这些都不是模型能力问题,而是执行环境失控、输入污染无防护、输出未经校验导致的信任崩塌。

适合谁?不是刚学 Git 的新手,也不是只想“一键获得 review 建议”的前端同学。它是给那些正在搭建企业级代码质量门禁、需要满足 SOC2 合规审计、或正面临多模型混用治理难题的工程效能负责人、平台架构师、以及 DevSecOps 团队看的。如果你的团队还在用git commit -m "fix bug"后手动贴 Slack 问“谁有空看看这个 PR?”,那你离open-code-review还很远;但如果你已经写过 custom pre-commit hook、维护过 SonarQube 插件、或者为 Jenkins pipeline 配置过 multiple static analysis tools,那它就是你等待已久的下一环。

2. 协议层拆解:为什么它不提供 CLI,却要求你亲手写 executor?

open-code-review的核心不是代码,是 schema。它的全部灵魂藏在review-spec.json这个文件里——不是文档,是机器可读的 JSON Schema。我把它打印出来贴在工位上,每天看三遍。这不是为了背诵,而是为了理解它如何用 17 个字段,把“一次代码审查”这件事,压缩成可序列化、可签名、可版本化的数据包。

先看最基础的输入契约。它不接受 raw git diff 字符串,也不接受文件路径列表。它要求输入必须是ReviewRequest对象,结构如下:

{ "version": "v1.2", "repository": "https://github.com/org/repo", "commit_hash": "a1b2c3d4e5f6...", "base_commit": "x9y8z7w6v5u4...", "diff": "diff --git a/src/main.py b/src/main.py\nindex 1234567..89abcdef 100644\n--- a/src/main.py\n+++ b/src/main.py\n@@ -10,3 +10,5 @@ def calculate_total(items):\n+ if not items:\n+ return 0\n total = 0\n", "context": { "files": [ { "path": "src/main.py", "content_hash": "sha256:abc123...", "lines_before": 5, "lines_after": 5 } ] }, "metadata": { "author": "dev@company.com", "branch": "feature/payment-refactor", "timestamp": "2024-06-15T14:22:33Z" } }

注意三个关键设计:

  1. diff字段是完整、纯净的 unified diff,不含任何 Git 元信息(如--no-optional-locks参数产生的额外 header),这是为了确保不同 Git 版本、不同操作系统生成的 diff 在语义上完全一致;
  2. context.files[].content_hash不是文件内容本身,而是其 SHA256 哈希值 —— 这意味着 executor 在执行前,必须能根据路径和哈希值,从本地或可信缓存中精确还原出对应代码片段,杜绝“输入被中间人篡改”;
  3. metadata中的timestamp是 UTC 时间戳,而非本地时间,且要求毫秒级精度,这是为后续做分布式审查结果因果排序(causal ordering)埋下的伏笔。

再看输出契约ReviewResult。它强制要求所有评论必须包含location(精确到行号范围)、severity(enum: critical / high / medium / low / info)、code(唯一错误码,如SECURE-001)、message(自然语言描述)、suggestion(可选,但若存在必须是语法正确的代码片段)、以及最重要的signature:

{ "review_id": "rev_7f8a9b0c-d1e2-4f3a-8b7c-6d5e4f3a2b1c", "request_id": "req_a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8", "results": [ { "location": { "file": "src/main.py", "start_line": 12, "end_line": 13 }, "severity": "critical", "code": "SECURE-001", "message": "Empty list check missing before iteration", "suggestion": "if not items:\n return 0", "confidence": 0.92 } ], "summary": "1 critical issue found", "engine": { "name": "deepseek-coder-32b-instruct", "version": "v1.0.0", "hash": "sha256:xyz789..." }, "signature": "sig_v1:MEUCIQD...[base64-encoded Ed25519 signature]" }

这里signature字段才是协议的灵魂。它不是对整个 JSON 的简单哈希,而是对review_id + request_id + results[].location + results[].code + engine.hash这组关键字段的 Ed25519 签名。这意味着:

  • 任何人拿到这个ReviewResult,都可以用engine.hash对应的公钥,验证该结果确实由声明的模型版本生成;
  • 如果有人篡改了suggestion或message,签名立即失效;
  • 但confidence和summary字段不参与签名 —— 因为它们是衍生指标,允许后处理聚合,不影响核心审查事实。

所以,当你看到热词里反复出现git -c diff.mnemonicprefix=false -c core.quotepath=false --no-optional-locks,这不是偶然。open-code-review要求 Git 输出必须严格可控,因为 diff 是输入契约的基石。我实测过:如果不用--no-optional-locks,某些 Git 版本会在 diff 头部插入lock相关元信息,导致content_hash计算失败,executor 直接拒绝执行。这不是 bug,是设计 —— 它用最硬核的方式告诉你:审查的起点,必须是确定性的、可复现的、无歧义的代码变更快照。

3. 执行器(Executor)实战:从零手写一个支持本地 Ollama 的审查器

官方仓库里只提供了open-code-review-executor-template这个空壳模板,没有任何现成的 LLM 接入示例。这不是疏忽,而是刻意为之。它逼你直面一个问题:模型不是审查者,你写的 executor 才是。我花了两天时间,基于 Python + Ollama SDK,写出了第一个生产可用的 executor,过程比想象中更“脏”,但也更真实。

首先,明确 executor 的职责边界。它不是 LLM client,而是协议翻译器 + 上下文装配器 + 结果校验器。它的输入是ReviewRequestJSON,输出是ReviewResultJSON,中间所有操作都必须围绕协议契约展开。以下是关键步骤的逐行解析:

3.1 输入预处理:Diff 解析与上下文还原

Ollama 的/api/chatendpoint 只接受 messages 数组,无法直接喂入 diff。所以第一步是把ReviewRequest.diff解析成结构化变更单元:

import re from typing import List, Dict, Any def parse_diff(diff_text: str) -> List[Dict[str, Any]]: """将 raw diff 文本解析为 [{file, hunks: [{start_line, end_line, content}]}]""" files = [] current_file = None for line in diff_text.splitlines(): # 匹配 diff --git a/xxx b/xxx if line.startswith("diff --git"): if current_file: files.append(current_file) _, a_path, b_path = line.split() current_file = {"file": b_path[2:], "hunks": []} # 去掉 'b/' # 匹配 @@ -10,3 +10,5 @@ 行 elif line.startswith("@@"): match = re.search(r"@@ -\d+,\d+ \+(\d+),(\d+) @@", line) if match and current_file: start_line = int(match.group(1)) line_count = int(match.group(2)) current_file["hunks"].append({ "start_line": start_line, "end_line": start_line + line_count - 1, "content": "" }) # 匹配 + 或 - 行(但只收集 + 行,即新增内容) elif line.startswith("+") and not line.startswith("+++"): if current_file and current_file["hunks"]: # 追加到最近一个 hunk 的 content current_file["hunks"][-1]["content"] += line[1:] + "\n" if current_file: files.append(current_file) return files

这个解析器不完美(比如不处理二进制 diff),但它足够稳定 —— 因为open-code-review协议明确要求输入 diff 必须是 text-based unified diff,二进制变更本就不该进入审查流程。这是协议对输入质量的硬性过滤。

接着是上下文还原。ReviewRequest.context.files给的是content_hash,不是文件内容。我的 executor 在启动时会检查.open-code-review/cache/目录,用sha256sum校验本地文件是否匹配。如果不匹配,它会拒绝执行,并抛出ContextIntegrityError—— 这不是错误,是协议的自我保护机制。我见过有团队试图绕过这一步,直接用git show <hash>:<path>动态获取内容,结果在 CI 环境中因权限问题失败。正确做法是:在 CI job 开头,就用git archive打包所有相关文件并计算哈希,提前注入 cache 目录。

3.2 Prompt 工程:不是“写个好 prompt”,而是构建可验证的推理链

热词里大量讨论temperature 是如何在llm的输出中发挥作用的,但在open-code-review场景下,temperature=0是唯一合理选择。因为审查结果必须确定性 —— 同一份 diff,同个模型,同个 executor,必须永远输出相同review_id和相同signature。任何随机性都会破坏签名验证。

我的 prompt 模板长这样(已脱敏):

You are a senior backend engineer reviewing Python code changes. Your task is to identify security, correctness, and maintainability issues. Output ONLY valid JSON matching this exact schema: { "issues": [ { "file": "string, exact path from diff header", "start_line": "integer, first line of issue in file", "end_line": "integer, last line of issue in file", "severity": "string, one of ['critical', 'high', 'medium', 'low', 'info']", "code": "string, uppercase alphanumeric with hyphen, e.g. 'SECURE-001'", "message": "concise natural language description", "suggestion": "optional, single-line or multi-line code snippet, must be syntactically valid" } ] } Rules: - NEVER output markdown, explanations, or anything outside the JSON. - If no issue found, output {"issues": []}. - Line numbers MUST match the actual file content, NOT the diff hunk numbers. - For 'critical' severity: only use for security vulnerabilities or data loss bugs. - Code must be from this official list: SECURE-001, CORRECT-002, MAINT-003, ...

关键点在于:

  • 强制 schema 输出:避免 LLM “自由发挥”,用 JSON Schema 引擎(如jsonschema)在 executor 内部校验输出,不合规直接重试(最多 3 次);
  • line number 映射:diff hunk 中的+12是相对行号,必须映射到文件绝对行号。我用git show HEAD:<file> | head -n <abs_line>获取原始行,再比对 diff 内容定位;
  • code 白名单:所有code字段必须来自预定义枚举,防止 LLM 编造不存在的规则码,这是后续自动化归类和 SLA 统计的基础。

3.3 结果后处理:签名生成与协议合规性检查

Ollama 返回的 JSON 是 raw response,必须转换为ReviewResult并签名。这里有个陷阱:engine.hash怎么来?不是模型名,而是ollama show deepseek-coder-32b-instruct --modelfile输出的FROM行哈希值。我写了个小脚本,在 executor 初始化时自动拉取并缓存:

# 获取模型确切哈希 ollama show deepseek-coder-32b-instruct --modelfile | \ grep "^FROM" | \ sha256sum | \ cut -d' ' -f1

签名用pynacl库,私钥存在~/.open-code-review/executor.key,公钥则提交到团队密钥管理库:

from nacl.signing import SigningKey from nacl.encoding import Base64Encoder def sign_review_result(result_dict: dict, private_key_path: str) -> dict: with open(private_key_path, "rb") as f: signing_key = SigningKey(f.read()) # 构建待签名 payload payload = ( result_dict["review_id"] + result_dict["request_id"] + "".join([f"{i['location']['file']}{i['location']['start_line']}{i['location']['end_line']}{i['code']}" for i in result_dict["results"]]) + result_dict["engine"]["hash"] ).encode('utf-8') signed = signing_key.sign(payload, encoder=Base64Encoder) result_dict["signature"] = f"sig_v1:{signed.signature.decode('ascii')}" return result_dict

最后,executor 启动时会执行open-code-review validate-executor命令,验证自己是否符合协议:能否正确解析输入、能否生成合规输出、签名是否可被公钥验证。这个命令不是装饰,是准入门槛 —— 任何未通过验证的 executor,CI 流水线会直接拒绝加载。

4. 安全纵深:如何用协议层设计堵死密钥泄露、Prompt 注入、模型越权三大漏洞

热词里高频出现的使用llm时如何防止密钥等鉴权信息泄露、prompt injection attack to tool selection in llm agents,在open-code-review的协议框架下,不是“如何防御”,而是“根本无法发生”。这不是靠更复杂的 prompt,而是靠协议层的隔离与约束。我以三个真实案例说明:

4.1 密钥泄露:Diff 输入的沙箱化处理

某次内部审计发现,一个 PR 的 diff 里意外包含了.env文件的修改,其中有一行API_KEY=sk-xxx。如果用传统 CLI 工具,这个密钥很可能被模型 tokenizer 切分后送入上下文,造成泄露。而open-code-review的协议规定:executor 必须在解析 diff 后,对每个hunk.content执行敏感词扫描。我的 executor 使用detect-secrets库,在parse_diff后立即触发:

from detect_secrets import SecretsCollection from detect_secrets.settings import default_settings def scan_hunk_for_secrets(hunk_content: str) -> bool: secrets = SecretsCollection() with default_settings(): secrets.scan_string(hunk_content) return len(secrets) > 0 # 在 parse_diff 后,对每个 hunk 调用此函数 # 如果发现 secrets,executor 直接返回空结果,并记录 audit log # 且该 review_id 会被标记为 'REDACTED',禁止进入任何下游系统

更重要的是,协议要求ReviewRequest的diff字段必须是纯文本 diff,不包含任何二进制 blob。这意味着,像git add -f .env这种操作,在git diff阶段就会因二进制内容被 Git 自动跳过,根本进不了open-code-review流程。这是 Git 本身的防护,open-code-review只是强化了这一层。

4.2 Prompt 注入:输入结构化 + 输出 Schema 强约束

热词prompt injection attack to tool selection in llm agents指的是攻击者在用户输入中嵌入特殊指令,诱骗 agent 调用危险工具。在open-code-review中,这种攻击面被压缩到极致:

  • 输入无自由文本:ReviewRequest没有user_message字段,只有结构化 diff 和 context。攻击者无法在 commit message 或 PR description 中塞入恶意指令;
  • 模型无工具调用能力:executor 调用 Ollama 时,使用的是/api/chat,而非/api/generate。前者只允许模型输出文本,后者才支持 function calling。协议明确禁止 executor 启用任何 tool calling 功能;
  • 输出强 Schema 校验:即使 LLM 被注入并试图输出"command": "rm -rf /",executor 的 JSON Schema 校验器会立刻报错,触发重试或失败,绝不会让非法字段进入ReviewResult。

我做过压力测试:在 diff 中故意插入<!-- OPEN-CODE-REVIEW-IGNORE -->注释,期望模型忽略后续代码。结果模型要么完全无视注释(因为 prompt 里没提),要么在issues[]中报告“未知注释语法”,但绝不会改变审查逻辑。因为协议不承认任何“指令性注释”,所有输入都被视为待审查代码。

4.3 模型越权:执行上下文隔离与资源限额

热词claude code cli 如何给完全访问权限暴露了一个危险需求:让 CLI 工具拥有 repo 读写权限。open-code-review的 executor 设计原则是:零持久状态、零网络外联、零文件系统写入。它只做三件事:读取 stdin(ReviewRequest)、调用本地 Ollama API(localhost:11434)、输出 stdout(ReviewResult)。

为此,我在 executor 启动脚本中加入严格限制:

# 使用 firejail 沙箱化执行 firejail \ --net=none \ # 禁用网络,只能访问 localhost --private=/tmp \ # 临时文件系统隔离 --read-only=/usr \ # 系统目录只读 --whitelist=$HOME/.ollama \ # 只允许访问 ollama 数据目录 --seccomp \ python3 executor.py "$@"

同时,Ollama 服务本身也配置了OLLAMA_NO_CUDA=1和OLLAMA_NUM_GPU=0,强制 CPU 推理,避免 GPU 内存被恶意模型利用。资源限额用 cgroups 控制:

# 限制内存不超过 8GB,CPU 使用率不超过 200% sudo cgcreate -g memory,cpu:/ocreview echo 8589934592 | sudo tee /sys/fs/cgroup/memory/ocreview/memory.limit_in_bytes echo 200 | sudo tee /sys/fs/cgroup/cpu/ocreview/cpu.shares sudo cgexec -g memory,cpu:ocreview python3 executor.py

这套组合拳下来,即使模型被攻破,攻击者也只能在沙箱内消耗 CPU 和内存,无法逃逸、无法外连、无法窃取密钥。这才是真正的纵深防御 —— 不是靠模型本身有多“鲁棒”,而是靠执行环境有多“贫瘠”。

5. 生产落地:在 Git Hook 与 CI Pipeline 中嵌入可审计的审查流水线

open-code-review的价值不在单次运行,而在融入研发流程的每一处关键节点。我把它部署在三个地方:pre-commit hook(开发者本地)、pre-receive hook(Git 服务器端)、以及 CI/CD pipeline(合并前最终门禁)。每个环节的配置逻辑不同,目标一致:让审查结果成为代码的“数字指纹”,而非可选建议。

5.1 Pre-commit Hook:开发者本地的实时护栏

很多团队排斥 pre-commit,觉得“太慢”“打断 flow”。但open-code-review的本地 executor 可以做到亚秒级响应 —— 关键在于模型选择与缓存策略。我用phi-3-mini-4k-instruct(3.8B 参数)跑在 M2 MacBook Air 上,平均耗时 320ms。配置如下:

#!/bin/bash # .git/hooks/pre-commit set -e # 1. 生成本次 commit 的 diff DIFF=$(git diff --cached --no-prefix) # 2. 构建 ReviewRequest JSON REQUEST=$(cat <<EOF { "version": "v1.2", "repository": "$(git config --get remote.origin.url)", "commit_hash": "$(git rev-parse HEAD)", "base_commit": "$(git merge-base HEAD origin/main)", "diff": "$DIFF", "context": {"files": []}, "metadata": { "author": "$(git config --get user.email)", "branch": "$(git rev-parse --abbrev-ref HEAD)", "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)" } } EOF ) # 3. 调用 executor,超时 2s if echo "$REQUEST" | timeout 2s open-code-review-executor --engine ollama:phi-3-mini-4k-instruct > /dev/null 2>&1; then echo "[open-code-review] ✅ Local review passed" else echo "[open-code-review] ❌ Local review failed or timed out" echo "Please check your local Ollama service or model availability." exit 1 fi

这里的关键技巧是:pre-commit 不做详细审查,只做“健康检查”。它不解析ReviewResult,只看 executor 是否成功返回(exit code 0)。详细审查结果由后续 CI 完成。这样既保证了速度,又建立了信任链起点 —— 开发者知道,自己的代码至少通过了本地最小可行审查。

5.2 Pre-receive Hook:Git 服务器端的强制门禁

在 Gitea/GitLab 自托管环境中,pre-receivehook 是最后一道防线。它在代码推送到远程仓库前执行,拒绝不符合审查要求的推送。配置难点在于:服务器端没有图形界面,Ollama 可能未安装,且必须保证高可用。

我的方案是:不依赖本地模型,而是调用公司内部 LLM 网关。但网关必须实现open-code-review协议的 executor 接口。于是,我写了轻量级反向代理:

# oc-review-gateway.py from flask import Flask, request, jsonify import requests app = Flask(__name__) @app.route('/review', methods=['POST']) def handle_review(): # 1. 验证输入是合法 ReviewRequest try: req = request.get_json() validate_review_request(req) # 自定义校验函数 except Exception as e: return jsonify({"error": "Invalid ReviewRequest"}), 400 # 2. 转发到内部 LLM 网关(已做 rate limit & auth) resp = requests.post( "https://llm-gateway.internal/review", json=req, timeout=30, headers={"X-API-Key": "oc-review-gateway-key"} ) # 3. 验证输出是合法 ReviewResult 并签名 result = resp.json() if not validate_review_result(result): return jsonify({"error": "Invalid ReviewResult from gateway"}), 500 # 4. 用网关私钥签名 signed_result = sign_review_result(result, "/etc/oc-review/gateway.key") return jsonify(signed_result)

这个网关部署在 Kubernetes 集群中,自动扩缩容,且所有请求都经过 Istio mTLS 认证。pre-receivehook 调用它:

#!/bin/bash # /var/git/repositories/myrepo.git/hooks/pre-receive while read oldrev newrev refname; do if [[ $refname == "refs/heads/main" ]]; then # 获取本次推送的所有 commit diff DIFF=$(git diff $oldrev $newrev --no-prefix) # 构建 Request 并 POST curl -s -X POST https://oc-review-gateway/review \ -H "Content-Type: application/json" \ -d "{\"diff\":\"$DIFF\", ...}" \ -o /tmp/review_result.json # 检查 signature 是否有效 if ! verify_signature /tmp/review_result.json; then echo "ERROR: Review result signature invalid" exit 1 fi # 检查 critical issues if jq -e '.results[] | select(.severity == "critical")' /tmp/review_result.json > /dev/null; then echo "ERROR: Critical issues found. Push rejected." exit 1 fi fi done

5.3 CI Pipeline:合并前的最终仲裁与归档

在 GitHub Actions 或 GitLab CI 中,open-code-review的角色是“仲裁者”而非“参与者”。它不替代人工 review,而是为人工 review 提供可验证的基线。我的.gitlab-ci.yml片段如下:

open-code-review: stage: review image: python:3.11 before_script: - pip install open-code-review-executor - mkdir -p ~/.ollama/models script: - | # 1. 下载本次 MR 的 base 和 head commit diff git fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME DIFF=$(git diff origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME...$CI_COMMIT_SHA --no-prefix) # 2. 构建 ReviewRequest 并执行 cat <<EOF | open-code-review-executor --engine ollama:deepseek-coder-32b-instruct > review_result.json { "version": "v1.2", "repository": "$CI_PROJECT_URL", "commit_hash": "$CI_COMMIT_SHA", "base_commit": "$(git rev-parse origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME)", "diff": "$DIFF", "context": {"files": []}, "metadata": {"author": "$GITLAB_USER_EMAIL", "branch": "$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME"} } EOF # 3. 验证 signature 并上传 artifact if verify_signature review_result.json; then echo "✅ Review signature verified" # 上传到内部审计系统 curl -X POST https://audit.internal/api/v1/reviews \ -H "Authorization: Bearer $AUDIT_TOKEN" \ -d "@review_result.json" else echo "❌ Review signature verification failed" exit 1 fi artifacts: paths: - review_result.json expire_in: 1 week

关键点在于artifacts—— 每次 CI 运行生成的review_result.json都被存档。这意味着,三个月后,当审计员问“这个 critical issue 是谁在什么时候确认的?”,你可以直接给出review_id,查到原始ReviewRequest、ReviewResult、以及对应的signature,用公钥验证其真实性。这不是“我们当时认为没问题”,而是“协议证明它当时就没问题”。

最后分享一个血泪教训:我们曾把open-code-review集成到 PR 模板中,要求“必须附带 review_result.json”。结果发现,有开发者直接 copy-paste 旧文件,伪造结果。解决方案很简单:在 CI 中增加一步,用jq提取review_id和request_id,与当前 commit hash 做哈希比对 —— 如果不匹配,直接 fail。协议的价值,不在于它多强大,而在于它让造假的成本,远高于诚实的成本。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询