关于 pr-review
pr-review 是面向代码审查者的 PR 范围验证技能,依据原始需求判断实现是否符合范围,并将范围外发现转为待办。它结合版本、卫生、设计不变量及知识捕获等检查生成分类报告。
主要功能
- 01建立需求范围基线
- 02检查版本与 PR 卫生
- 03按范围分类审查发现
- 04将待办项转为平台议题
- 05生成报告并捕获知识
适用场景
- 01合并功能分支前验证需求覆盖
- 02审查同事提交的 PR
- 03提交审查前检查自己的改动
- 04整理审查发现的后续改进
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ athola/ claude-night-market --skill pr-review安装后在 Claude Code 中输入/pr-review确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
modules/anti-patterns.mdcomment-guidelines.mdeducational-insights.mdgithub-comments.mdinsight-generation.mdinteractive-review.mdknowledge-capture.mdpr-hygiene.mdscope-classification.mdslop-detection.mdsuggestion-comments.mdversion-validation.md详细介绍
聚焦范围的 PR 评审
严格评审拉取请求/合并请求:对照原始需求进行验证,防止范围蔓延,并将范围外的发现转为检测到的平台上的议题。
平台自动检测,通过 leyline:git-platform 完成。GitHub 使用 gh,GitLab 使用 glab。检查会话上下文中的 git_platform:。
核心原则
PR 评审验证的是范围合规性,而非代码是否完美。
目标是验证实现是否满足既定需求,且没有引入回归问题。超出范围的改进应留待后续 PR。
适用场景
- 合并任何功能分支之前
- 评审队友提交的 PR 时
- 请求评审前验证自己的工作
- 整理评审过程中发现的改进事项,生成待办列表
不适用场景
- 准备 PR——请改用 pr-prep
- 深入代码 评审——请改用 pensive:unified-review
- 准备 PR——请改用 pr-prep
- 深入代码 评审——请改用 pensive:unified-review
范围分类框架
每项发现如何对照 PR 声明的范围进行分类:
modules/scope-classification.md。
工作流程
阶段 1:确定范围基准
在查看任何代码之前,先了解此 PR 应实现的目标。
**注意:**版本验证(阶段 1.5)会在确定范围之后、代码评审之前进行。详情请参阅 modules/version-validation.md。
按以下顺序查找范围相关材料:
-
计划文件:最权威(先检查 spec-kit 位置,再检查根目录)
# Spec-kit feature plans (preferred - structured implementation blueprints) find specs -name "plan.md" -type f 2>/dev/null | head -1 | xargs cat 2>/dev/null | head -100 # Legacy/alternative locations ls docs/plans/ 2>/dev/null # Root plan.md (may be Claude Plan Mode artifact from v2.0.51+) cat plan.md 2>/dev/null | head -100**验证:**运行命令并传入
--help标志,以确认命令可用。 -
规格文件:需求定义(先检查 spec-kit 位置)
find specs -name "spec.md" -type f 2>/dev/null | head -1 | xargs cat 2>/dev/null | head -100 cat spec.md 2>/dev/null | head -100**验证:**运行命令并传入
--help标志,以确认命令可用。 -
任务文件:实现检查清单(先检查 spec-kit 位置)
find specs -name "tasks.md" -type f 2>/dev/null | head -1 | xargs cat 2>/dev/null cat tasks.md 2>/dev/null**验证:**运行命令并传入
--help标志,以确认命令可用。 -
PR/MR 描述:作者的意图
# GitHub gh pr view <number> --json body --jq '.body' # GitLab glab mr view <number> --json description --jq '.description'**验证:**运行命令并传入
--help标志,以确认命令可用。 -
提交消息:逐步决策记录
# GitHub gh pr view <number> --json commits --jq '.commits[].messageHeadline' # GitLab glab mr view <number> --json commits**验证:**运行命令并传入
--help标志,以确认命令可用。
**输出:**清晰说明范围:
“此 PR 按照 plan.md 中的说明实现了[功能 X]。需求如下:
- [需求]
- [需求]
- [需求]”
如果不存在范围相关材料,请将此情况标记为流程问题,但继续以 PR 描述作为基准。
阶段 2:收集变更
# GitHub
gh pr diff <number> --name-only
gh pr diff <number>
gh pr view <number> --json additions,deletions,changedFiles,commits
# GitLab
glab mr diff <number>
glab mr view <number>
**验证:**运行命令并传入 --help 标志,以确认命令可用。
阶段 3:验证需求
在详细代码评审之前,检查范围覆盖情况:
- 每项需求都有对应的实现
- 没有遗漏任何需求
- 实现没有超出需求(过度设计的信号)
阶段 1.5:版本验证(必须执行)
在代码评审之前运行版本验证检查。
详细验证流程请参阅 modules/version-validation.md。
快速参考:
- 检查是否请求跳过验证(
--skip-version-check、标签或 PR 标记) - 检测 PR 差异中是否更改了版本文件
- 如果有更改,运行项目特定的验证:
- Claude marketplace:检查 marketplace.json 与 plugin.json 中的版本是否一致
- Python:检查 pyproject.toml 与 version 是否一致
- Node:检查 package.json 与 package-lock.json 是否一致
- Rust:检查 Cargo.toml 与 Cargo.lock 是否一致
- 验证 CHANGELOG 是否包含新版本的条目
- 检查 README/文档中的版本引用
- 将发现分类为 BLOCKING(如已跳过,则为 WAIVED)
除非维护者明确豁免,否则所有版本不匹配问题均为 BLOCKING。
阶段 3.5:PR 规范检查
在深入代码之前,运行 modules/pr-hygiene.md 中的原子性、Agent 整理和
自我评审检查,并根据其中的严重程度表对发现进行分类。
阶段 4:结合范围上下文进行代码审查
对已更改的文件使用 pensive:unified-review。有关评论质量评估,请参阅 modules/comment-guidelines.md。
关键: 根据范围基线评估每项发现:
**Verification:** Run the command with `--help` flag to verify availability.
Finding: "Function X lacks input validation"
Scope check: Is input validation mentioned in requirements?
- YES → IN-SCOPE
- NO, but it's a security issue → BLOCKING
- NO, and it's a nice-to-have → BACKLOG
验证: 使用 --help 标志运行命令,以验证其是否可用。
阶段 4.5:新增偏差审计
对 PR 更改运行 Skill(imbue:justify),以检测
AI 新增偏差、测试逻辑篡改和不必要的
复杂性。
关键检查:
- 新增偏差分数:标记增删比高(>5:1)且缺乏理由的更改
- 铁律合规性:验证测试断言是否被弱化,以迁就有问题的实现
- 最小干预:确认每个更改的文件都是必需的,且更改是最小修复
使用范围框架对 justify 的发现进行分类:
| Justify 信号 | 可能的分类 |
|---|---|
| 测试逻辑遭篡改 | 阻塞项 |
| 新增偏差高,且无理由 | 范围内 |
| 过早抽象 | 建议 |
| 兼容性垫片 | 待办 |
在阶段 6 报告中包含新增偏差分数和铁律状态。
阶段 4.6:不变量冲突检测
检查 PR 是否触及现有设计不变量。 这是模型经常判断失误的问题:应将冲突呈现给人工审核, 而不是默默接受或拒绝。
快速检测启发式:
- 更改的文件是否跨越了此前并未交互的模块边界?
- 更改是否在现有模式之外引入了新模式(即存在两种实现同一功能的方式)?
- 接口/类型/架构文件的形态是否发生变化?
- 数据流向是否发生变化?
- 是否违背了 ADR 记录的决策?
# Check for structural pattern changes
git diff --name-only HEAD...origin/master 2>/dev/null \
| rg "(interface|types|schema|model|base|core|contract)" \
|| git diff --name-only HEAD...origin/master 2>/dev/null \
| grep -E "(interface|types|schema|model|base|core|contract)"
检测到冲突时:
不要解决冲突。将其作为特殊类别加入报告:
| 类别 | 定义 | 操作 |
|---|---|---|
| 不变量 | 更改与现有设计决策冲突 | 上报人工,并提供 3 种选项分析 |
对每项不变量冲突,请说明:
- 不变量:指出设计决策及其制定原因(如有 ADR,请引用)
- 冲突:说明此 PR 中与之冲突的内容
- 选项 A,保留:不要合并此更改;该不变量在其他方面仍有价值
- 选项 B,分层处理:按原样合并,接受其不够优雅;并非每项功能都必须优雅
- 选项 C,修订:该不变量有误;说明重新设计会是什么样
分类: 不变量类发现始终是阻塞项,并非因为代码有误,而是因为这项判断需要人工输入。只有人工审核者才能决定三种选项中哪一种正确。
使用 --hold-insights 时: 同样的暂存模式适用于所有关于更改方向、架构或差异中未明确问题的发现,而不仅限于与已记录不变量冲突的发现。在聊天中呈现这些发现,然后使用阶段 5 询问待办问题时的提示词提问:“我有 N 条关于方向和设计的观察。发布哪些?[y/n/select]”。只发布选中的内容,其余内容保留在对话中。这样,审核者便能在作者看到这些内容之前运用自己的判断;关于方向的问题就应该在这个阶段处理。
为何重要: 错误的不变量决策会产生累积效应。几次错误判断就可能让代码库变得无法挽救。这不是通过改进文档就能解决的上下文问题,而是需要人类智慧来判断的问题。
阶段 5:待办事项分诊
对于每项待办项,在检测到的平台上创建议题:
# GitHub
gh issue create \
--title "[Tech Debt] Brief description" \
--body "## Context
Identified during PR #<number> review.
..." \
--label "tech-debt"
# GitLab
glab issue create \
--title "[Tech Debt] Brief description" \
--description "## Context
Identified during MR !<number> review.
..." \
--label "tech-debt"
验证: 使用 --help 标志运行命令,以验证其是否可用。
创建前询问用户:“我发现了 N 项待办事项。要创建议题吗?[y/n/select]”
阶段 6:生成报告
按分类组织报告。每项 BLOCKING 和
IN-SCOPE 发现都 MUST 根据
modules/educational-insights.md 包含教育性见解:原因(原则)、
依据(最佳实践链接)和可供学习的经验
(概括性教训)。SUGGESTION 发现需包含原因,并可选包含依据。BACKLOG 项只需简要说明理由。
使用 --concise 时,不会发布上述段落。diff 行上的每项发现都会变成作者可应用的建议块,
旁边仅在需要澄清时附上简短说明。没有可锚定行的发现会在摘要中各占一行。包含教育内容的完整报告仍会写入本地的 --local 路径,不会有任何内容丢失。它只是不发布到 MR 上。发布模式:modules/suggestion-comments.md。
## PR #X: Title
### Scope Compliance
**Requirements:** (from plan/spec)
1. [x] Requirement A - Implemented
2. [x] Requirement B - Implemented
3. [ ] Requirement C - **Missing**
### Blocking (1)
1. [B1] SQL injection via string concatenation
- **Location**: `db/queries.py:89`
- **Anchor**: `cursor.execute("SELECT * FROM t WHERE id = " + uid)`
- **Issue**: User input interpolated directly into SQL
- **Why**: String-interpolated SQL allows attackers to
execute arbitrary queries (CWE-89). This is the #1
web application vulnerability per OWASP Top 10.
- **Proof**: [OWASP SQL Injection](https://owasp.org/www-community/attacks/SQL_Injection)
- **Teachable Moment**: Always use parameterized queries
or an ORM. This applies everywhere user input reaches
a database, cache, or search engine query.
- **Fix**: Use parameterized query:
`cursor.execute("SELECT * FROM t WHERE id = ?", (uid,))`
### In-Scope (1)
1. [S1] Missing validation for edge case
- **Location**: `api.py:45`
- **Anchor**: `def handle_request(payload):`
- **Issue**: Empty input not handled per requirement
- **Why**: Defensive validation at API boundaries
prevents cascading failures in downstream logic.
- **Proof**: [Postel's Law](https://en.wikipedia.org/wiki/Robustness_principle)
- **Teachable Moment**: Validate inputs at system
boundaries (API handlers, CLI args, file parsers)
but trust internal function contracts.
### Suggestions (1)
1. [G1] Consider extracting helper function
- **Why**: The repeated pattern on lines 30-35 and
72-77 violates DRY. Extracting it reduces future
bug surface.
- Author's discretion
### Backlog → GitHub Issues (3)
1. #142 - Refactor authentication module
2. #143 - Add caching layer
3. #144 - Update deprecated dependency
### Recommendation
**APPROVE WITH CHANGES**
Address B1 and S1 before merge.
本地输出(--local)
传入 --local [path] 时,将阶段 6 的报告写入本地 .md 文件,而不是通过 API 发布。默认路径:
.pr-review/pr-<number>-review.md。该文件在一份文档中包含
审查摘要、测试计划和待办事项。跳过创建 Issue 和更新 PR 描述。
知识收集(阶段 7)仍会运行。
阶段 7:知识收集
生成报告后,评分 ≥60 的发现会被收录到项目的审查空间(decisions/、patterns/、standards/、
lessons/),并列在报告的“已收集知识”部分。
完整工作流请参阅 modules/knowledge-capture.md。
阶段 8:理解循环(--interactive)
可选启用。除非审查者传入 --interactive,否则跳过此阶段。
围绕 diff 进行苏格拉底式循环:每轮交流都会评为 pass、
partial 或 fail,并记录到 gauntlet 的共享进度存储中。
探查结果绝不会改变合并建议,而是会在阶段 6 的报告中添加
“理解”部分。
完整的轮次顺序、评分表、类别映射和记录约定:
modules/interactive-review.md。
质量门槛
满足以下条件时,应批准 PR:
- 已实现所有明确提出的需求
- 不存在尚未解决的 BLOCKING 问题
- IN-SCOPE 问题已解决或确认知悉
- BACKLOG 项已作为 GitHub Issue 跟进
- 测试覆盖了新增代码路径
- 如果撤销修复,测试会失败(撤销测试)
- 没有未审查处理的明显 Agent 生成代码
- 作者能够解释每个变更部分的工作方式及其可能的失效方式(检查是否理解,而不只是“测试通过”)
验证发现有依据(pr-review:findings-verified)
将发现写入 .review/findings.json,运行引用验证器
(Skill(imbue:review-core) Step 5),并删除验证器拒绝的发现,或将其标记为 UNVERIFIED。
应避免的反模式
范围蔓延、完美主义、因风格问题阻塞、审查未变更代码、只能证明旧代码有问题的测试、捆绑不相关变更,以及合并你无法解释的代码。每种反模式及其应对方法详见:modules/anti-patterns.md。
与其他工具集成
/fix-pr:审查发现问题后,使用此工具解决问题/pr:在审查前准备 PRpensive:unified-review:进行实际的代码分析pensive:bug-review:如有需要,深入查找 Bugscribe:slop-detector:分析文档和提交消息的质量scribe:doc-generator:编写 PR 描述的指南(避免 AI 腔)
AI 腔检测集成
PR 文案和变更文档中如何检查 AI 生成模式:
modules/slop-detection.md。
退出条件
- 已确定范围基线,并记录在报告中
- 每个变更文件都已归类为范围内、范围外或阻塞
- 每个范围外发现都有已跟踪的问题编号
- 报告给出一项建议:批准、评论或请求更改
- 每个阻塞和范围内发现都包含
Location(文件:行号) 和逐字引用的Anchor,且citation_verifier.py以0退出;否则应删除未经验证的发现,或将其标记为UNVERIFIED - 使用
--interactive时:每个包含阻塞或高风险发现的代码块都已探查,或审查者已结束会话 - 使用
--interactive时:每次评分后的交流都出现在.gauntlet/progress/<developer>.json中,且报告包含一个Comprehension部分,其行数与记录的探查次数一致 - 使用
--concise时:差异行上的每项发现都已作为建议代码块发布,摘要审查已创建,且未发布测试计划评论或描述更新 - 使用
--hold-insights时:发布前已在聊天中展示每项方向或架构发现,且 PR 上只出现了选中的发现