Skip to content
Back to skills

Peer Pr Review

ASecurity

用户要求审查 PR、分支、worktree 或本地改动,或实现完成需自审时使用;只读核对完整 diff、需求与证据,并用具体 Case 解释结论。

  • 2 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 22, 2026
ai-agentstypescriptjavagitapi

Works with

  • cli
  • api
  • mcp

Security analysis

A100/100

Pro scans all 10 files and shows the line behind each finding

Scanned October 2, 2026

npx -y skills add Zhangs-11/zs-skills --skill peer-pr-review --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Peer Pr Review?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Peer Pr Review
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/zhangs-11-peer-pr-review/badge)](https://www.skillsdirectory.com/skills/zhangs-11-peer-pr-review)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: peer-pr-review
description: 用户要求审查 PR、分支、worktree 或本地改动,或实现完成需自审时使用;只读核对完整 diff、需求与证据,并用具体 Case 解释结论。
---

# 代码改动第一性审查

目标不是替改动者证明方案正确,也不是为了显得严格而强行找问题。先把自己放在“需求交给我实现”的位置,独立形成一份开发方案,再让这份方案和改动者方案互相补漏、互相证伪。无论审查同事还是自己的代码,都要在有限时间内回答七件事:这块功能负责什么、实际出了什么问题、根因是什么、如果由我开发会怎样解决、改动者怎样解决、两套方案谁遗漏了什么、最终代码是否合理。

默认把读者视为第一次接触该项目的新手。报告主体只保留会影响理解、提交、合并决定或后续验证方式的信息;不要用一串术语和方法名代替解释。具体 Case 走读不设机械字数上限,以读者能沿真实输入、判断、状态变化和下游结果完整听懂为准,但不要重复粘贴同一份图、表和代码。

## 输入与边界

最低输入是一个可定位的审查对象,例如:

- CodeUp PR 链接;
- 当前仓库的 staged、unstaged 和 untracked 改动;
- 指定 worktree 路径或本地分支;
- 明确的 commit、patch 或比较范围。

需求背景通常应提供,但若当前对话、关联工作项、提交说明或代码能可靠恢复,就先自行整理;无法恢复时仍可做实现质量审查,但要明确“需求符合性未验证”。可选输入包括 OA 需求/缺陷 ID、project ID、Chat ID、环境、复现步骤、日志、改动者判断的根因和修复方案。

缺少可选输入时继续做能完成的静态审查,不把可自行检查的问题反问用户。只有审查对象无法访问、仓库或 worktree 无法定位、比较基线存在多个合理选择,或某个缺失选择会实质改变审查范围时才请求补充。

本 Skill 默认只读:

- 不修改代码、配置、数据库或文档;
- 不在 CodeUp 上评论、通过、关闭或合并 PR;
- 不 commit、push 或部署;
- 数据库只允许 SELECT;日志和配置只读取与当前假设有关的最小范围;
- 不在报告中回显 Token、Cookie、凭据、完整 Prompt 或未脱敏业务数据。

## 事实获取顺序

按成本从低到高取证,证据足够支撑结论就停止,不为低风险改动制造不成比例的调查。

### 1. 固定审查对象

先识别审查模式并在报告顶部写明“审查对象、基线、终点和包含范围”:

- **CodeUp PR**:解析仓库、源分支、目标分支、当前 patch set 和 commit。优先通过已登录页面、只读 OpenAPI 或对应 Git 远端锁定不可变 diff;先只记录范围和需求入口,把 patch hunk、改动者方案、讨论结论和测试结论留到独立方案冻结后再读。
- **当前未提交改动**:默认审查 `HEAD → 当前工作区`。分别读取 `git diff --cached`、`git diff` 和 `git ls-files --others --exclude-standard`;相关 untracked 文件必须读取,不能因普通 `git diff` 看不到就漏审。生成物、二进制或明确无关文件可以排除,但要在范围中说明。
- **worktree 或本地分支**:先用 `git worktree list`、`git status`、当前分支、HEAD 和远端信息确认实际路径。默认以用户指定目标分支为基线;未指定时只在仓库默认分支明确时使用其最新远端引用,并以 merge-base 为起点,审查 `merge-base → HEAD`,再叠加该 worktree 的 staged、unstaged 和相关 untracked 改动。基线不唯一时不要擅自选择。
- **commit 或 patch**:按用户明确给出的不可变范围审查,并记录两端 commit 或 patch 来源。

若 PR 与本地改动同时存在,默认把 PR 作为主审查对象;检查本地分支是否还有未进入 PR 的提交或工作区改动,并单独标为“PR 外本地改动”,不要混入 PR 结论。用户明确要求审查发布前全部内容时,再合并两部分范围。

涉及远端基线或 PR 时,先检查 `git status`、分支和 worktree,再 `git fetch`,使用最新远端引用判断;只审查当前工作区相对 `HEAD` 的未提交内容时不必为了形式强制 fetch。全程不得切换分支、改 index、stash、commit 或清理文件。

记录审查开始时的 HEAD、状态和 diff 范围;交付前重新检查。若用户或其他会话在审查中改变了 HEAD、index 或工作区,重新读取受影响 diff,或者明确报告审查基于哪个快照。无法取得真实 diff 时,不根据标题或描述假装完成代码审查。锁定 diff 不等于提前研究改法;同事 Review 和自审都应尽量避免用目标版本的实现反推“自己本来会怎样设计”。

### 2. 还原需求而不是复述需求

用大白话分别写清:

- **需求背景**:哪块功能本来负责什么;
- **问题描述**:在什么条件下,哪一步出现了什么偏离,造成什么实际影响;
- **改动者根因假设**:对同事改动,使用同事明确写出的判断;对自审,使用用户说明的判断。未明示时可从实际改动位置和方案反推,但必须注明“从代码改动反推,原文未明示”。

背景不要提前塞入根因;问题描述不要只写“逻辑有问题”“体验不好”或函数名。

### 3. 建立新手可读的最小词汇

只解释理解本次问题、根因和改动所必需的术语。术语第一次出现时,先给业务白话,再保留原词,例如:“幂等(同一条消息重复处理,也只能产生一次业务结果)”。缩写第一次出现时同时写出全称或实际用途。

对仍可能混淆的 3~6 个关键术语,使用“关键概念”小表格说明:

| 术语 | 白话解释 | 在本次问题里代表什么 |
|---|---|---|
| `<term>` | <不用另一个陌生术语循环解释> | <它在哪一步影响结果> |

不要罗列与结论无关的框架名、设计模式或基础语法。不要照抄注释和文档定义;先通过真实代码、配置或官方契约确认含义。项目自定义词语无法确认时注明“推断,未验证”。

### 4. 建立最小完整机制

从业务目标出发,追踪与改动有关的真实链路:

```text
输入/触发
→ 生产者
→ 状态或数据变更
→ 消费者
→ 用户可见结果
→ 错误恢复、异步回填或终态
```

只检查有真实调用关系的集成点,重点包括:

- 入口、调用方和下游消费者;
- 状态生命周期、缓存、并发、幂等和恢复路径;
- API/schema、数据库脚本、配置、提示词、前后端和跨仓依赖;
- 权限、环境差异、兼容路径、监控、测试和上线配套;
- 项目内同类实现、现行规范和历史修复先例。

如果仓库或所在组织提供了专用开发规范、知识库导航或当前的根因与证据合同,按需读取最新版本;这些资料用于形成和校验假设,不能代替本次审查对象的代码与运行证据。

#### 共享配置 × 构造参数门禁

当一个配置对象或字段被多个构造器、工厂或 wrapper 共用,而调用方还传入 bucket、tenant、region、namespace、资源 ID 等会改变语义的参数时,不能用默认构造器的一条测试推断全部消费者正确。先列出所有生产调用方,记录“共享配置值、构造参数、最终消费者”三者的组合,区分配置归属与当前 client/资源归属;至少覆盖默认消费者、一个非默认消费者和 fallback。若实现会根据当前参数改写共享配置,必须用不同参数的同一配置构造反例,确认不会把默认资源信息带入另一个消费者。

这类检查的完成标准不是“所有构造器都能编译”,而是每个有不同语义参数的可达构造路径都产生正确的最终地址、标识、权限范围或状态。生产调用方中存在未验证的非默认组合时,不能无条件通过;已有真实配置可复现错误时形成正式 finding。

#### 参考优先门禁:先证明为何复用或偏离

审查改动前,必须按风险找出项目中最接近的现有代码、测试和必要历史,理解项目为什么这样设计、曾规避过什么问题。简单局部改动通常对照同模块最邻近的一处实现即可;涉及协议、Schema、序列化、跨服务接口或兼容行为时,再扩大到真实消费者、相同注册点、相关测试和历史修复。

优先选择与本次改动共享真实消费者、协议链路或业务约束的样本,不要只因函数名或字段名相似就类比。现有代码是高价值参考,不是必须照搬的规则:它也可能过时、只覆盖另一场景或本身存在缺陷。若新写法与项目惯例不同,检查差异是否来自明确的新需求、版本变化或消费者差异,并要求用针对性测试证明;不能只以“更标准”“更通用”或外部文档允许为理由。

找不到可靠样本时,记录实际搜索过的模块和关键词,再依据真实消费者、官方当前契约或最小运行探针判断;不要为了凑参考随便找一段不相关代码,也不要仅因项目没有先例就阻塞低风险改动。报告只需在“验证情况”中简要写明真正影响结论的参考样本及其启示,避免展开成代码考古记录。

通过结论前必须形成明确的参考判定:最接近的实现是什么、哪些约束相同、当前改动直接复用了什么、偏离之处为何必要。若现有机制已经能满足同一验收和失败语义,而 diff 另建了一套状态、入口或恢复逻辑,应作为正式 finding;找不到参考时则写清搜索范围,不以“项目里应该没有”代替查询。

#### 等价正常路径与改动归属:先证明“需要改”

当需求新增入口、数据来源、协议或触发方式,不要把“新入口”直接推导为“下游需要新能力”。先找到一条能产生相同业务结果的已知正常路径,并比较两条路径的标准契约和真实消费者:

| 需求变化 | 已有正常路径 | 首次差异点 | 最早可汇合点 | 必须修改的层 | 其他层为何不改 |
|---|---|---|---|---|---|
| `<新入口/新来源>` | `<已运行的等价入口>` | `<第一个不同的字段/状态/分支>` | `<可转成已有契约的位置>` | `<有证据的最小改动层>` | `<已复用什么>` |

如果新路径能在上游转换成消费者已支持的同一契约,下游默认应为零修改,只做必要的联调和回归。只有证明已有契约无法承载新语义,才允许让消费者增加新分支。在“需要前端/后端/Agent/Core 修改”之类责任表中,每一层都必须指出当前哪个输入、状态或消费动作不满足需求;无证据的层不得列为改动方。

出现以下信号时,将“可能在制造第二套逻辑”作为高优先级反证:

- 消费者开始判断数据来自哪个页面、卡片或分享入口;
- 新字段与已有字段表达同一业务对象,只是生产来源不同;
- 同一资产、状态或动作出现两套加载、授权、恢复或幂等逻辑;
- 新增一个入口却要求多个无差异的下游一起修改。

此时优先检查生产者或适配层是否没有完成归一化,而不是立即给消费者添加专用处理。若已有正常路径完整覆盖新需求,应主动告知用户“该层无需修改”,不要为了形式上的分工给每层都分配任务。

代码中的提交标题、测试文件名或注释里出现工单编号,只能证明代码使用了该标签;在 OA 或其他外部系统验证前,不得宣称对应工单真实存在或把代码标签当作需求事实。

### 5. 独立判断根因

不要从“改动者改了这里”倒推“这里一定是根因”。依次确认:

1. **现象**:用户或系统最终看到了什么;
2. **触发条件**:本次什么事件启动了异常链路;
3. **首次有意义的偏离**:最早哪个值、状态、分支或结果偏离预期;
4. **直接原因**:什么机制直接造成问题;
5. **系统根因**:现有约束、门禁、恢复或消费链为什么没有阻止直接原因;
6. **反事实**:若移除候选根因,是否应观察不到当前问题。

至少检查一个竞争解释,例如配置/版本不一致、调用方错误、外部依赖、权限、数据、模型决策或证据不足。结论分为:

- **一致**:改动者判断和独立核验指向同一首次偏离与机制;
- **部分一致**:改动者找对了直接原因,但漏了更早根因或影响范围;
- **不一致**:实际修改点不能解释现象,或证据支持另一原因;
- **无法判断**:缺少会改变因果判断的决定性事实。

最新 `main` 只说明当前设计,不能证明某环境已经部署;代码默认值也不能冒充 Nacos、数据库、Hub 或环境变量的当前值。结论依赖运行时事实而输入未提供环境时,明确写“运行时未验证”。

### 6. 冻结独立开发方案,再与改动者方案对照

完成需求、基线机制、项目参考和独立根因判断后,先假设这个需求现在交给自己开发,形成一份**独立开发方案**。这一阶段不读取 patch hunk,也不采用改动者的根因、文件选择和测试结论;如果 PR 页面把问题与方案写在一起,只抽取可由任务事实核验的问题描述,把方案部分留到下一阶段。若没有独立任务材料,需求只能从 patch 恢复,明确标注“独立方案受 patch 信息影响”,不能把它包装成真正的 diff-blind 方案。

独立方案不是一份脱离项目的架构畅想,而是复用日常开发流程得到的最小交付蓝图:

对于现有代码任务,读取 `$project-aware-coding`,仅复用步骤 1~5 的目标确认、调用链、项目参考、方案设计和验证标准;按实际触发条件组合其他领域 Skill。已有调查材料可复用,但关键主张须独立核验。本轮 Review 自身承担审查职责,不调用该 Skill 的步骤 6,不执行修改、自动修复或外部写操作。

1. **调查与 Skill 路由**:需要哪些诊断、项目开发、协议、安全或领域 Skill;要查哪些代码、配置、日志、数据库、历史和运行证据。只写会改变方案的选择,不罗列形式化工具清单。
2. **机制与改动归属**:首次偏离在哪里,最小应修改哪一层、哪些生产者和消费者,哪些层能复用既有契约所以不改。
3. **实现方案**:需要调整的入口、状态、协议、错误处理和终态;覆盖正常、失败、恢复、重复、并发及权限边界中真实可达的部分。
4. **验证方案**:哪些单元、集成、契约和真实 QA 证据才能证明旧问题被抓住、正常路径未回归、副作用次数正确;配置、工具可见性、部署或环境差异必须指定运行时事实源。
5. **自审闭环**:假设实现完成后,应基于完整 diff 独立自审,修复原需求范围内有证据的必须项,重新验证并全量复审;这里只用它检查改动者方案是否具备同等交付完整性,Review 本身仍不修改代码。

把方案压缩成能用于比较的决策基线,不提前写成正式 finding。随后读取改动者说明、完整 diff、测试、讨论和运行证据,按下表逐项比较:

| 对照维度 | 独立开发方案 | 改动者方案 | 复核动作 |
|---|---|---|---|
| 根因与首次偏离 | 自己从基线推出的机制 | 作者声明或 diff 反映的机制 | 用复现、调用链和反事实判断谁成立 |
| 改动层与责任归属 | 最小应修改的生产者/消费者 | 实际修改的服务、配置和文件 | 检查能否更早汇合或复用已有入口 |
| 正常/失败/恢复 | 应保持的控制流和终态 | 当前实现与测试覆盖 | 寻找双方各自遗漏的可达路径 |
| 契约与副作用 | 字段、状态、次数、权限和兼容约束 | 实际 schema、调用和写入 | 追到真实消费者并核对完整输出 |
| 验证与自审 | 应有的测试、QA 和复审证据 | 作者现有证据 | 判断证据是否真的覆盖风险 |

比较结果允许五种状态:**一致且完整**、**方向一致但改动者遗漏**、**改动者方案更完整**、**两套方案实质不同**、**双方共同遗漏**。独立方案不是标准答案:改动者用更好的项目参考或更强运行证据补上独立方案遗漏时,更新自己的判断,不把差异包装成问题;两套方案不同则分别构造能推翻它们的最短反例。

#### 运行证据反转门禁

当差异涉及部署版本、动态配置、工具可见性、数据库状态、权限、真实调用次数或外部依赖时,局部静态代码通常不足以决定结论。若用户给了环境、project ID、记录 ID 或日志线索,先查询对应运行事实,再形成 finding。

真实请求参数、实际消费者调用和成功/失败结果能直接推翻“工具不可见”“路径不可达”“配置未生效”等静态推断时,应撤回候选问题并说明独立方案漏看了什么。反过来,单个成功样本只能证明它覆盖的入口和状态;若要保留条件性风险,必须再找到另一个真实可达且未被该证据覆盖的上下文,不能用“理论上可能”维持阻塞结论。

审查材料里“没有可用资产”“环境不支持”“无法复现”“等部署后再验”这类说法,同样是待证伪的主张,先自己核实,再决定是否写进“未验证”。依次确认三件事:改动是否已部署到可访问的环境(镜像 tag 对照 commit);库里是否已有同类型的现成资产或测试夹具(只读查询);能否用只读、无副作用的调用走通目标路径。路径可行就当场实测,实测与静态推断冲突时以实测为准;实测需要写数据、新建资产或触及生产时,先说明拟做的操作并取得用户同意。核实后仍不可行,才写进“未验证”,并注明查过哪些途径、卡在哪一步。

### 7. 绘制代码链路与改动对比

先还原真实调用链和数据流,再绘图;不要从文件 diff 拼出一张看似完整但没有调用证据的图。图用于帮助零背景读者理解改动,不代替根因判断和代码证据。

优先使用 Mermaid `flowchart LR` 展示每条代码链路。采用两层结构:

1. **主链路**:把“改动前”和“改动后”拆成两张独立图,改动前在上、改动后在下,形成纵向对比;每张图内部仍按 `LR` 从左到右展示链路。两图使用一致的业务阶段、节点编号和粒度,便于上下逐项比较。每条主链保留 5~8 个节点,只表达入口、关键生产者、状态变化、决定性判断、消费者和最终结果。
2. **关键判断展开**:主链中的判断较复杂时,另画一张局部图,只展开本次修改的判断、造成问题的判断,以及影响成功、失败或恢复路径的判断。未修改且与结论无关的分支合并为“既有校验(未修改)”或“其他正常路径保持不变”。

主图使用以下骨架。必须输出两个独立 Mermaid 代码块,依靠文档顺序实现稳定的上下对比;不要把两个版本合并进同一个 `subgraph` 或泳道图。根据真实代码替换节点,不要照抄示意内容。

#### 改动前

```mermaid
flowchart LR
  B1["① 入口"] --> B2["② 状态生成"] --> B3{"③ 关键判断"} --> B4["④ 下游结果"]
```

#### 改动后

```mermaid
flowchart LR
  A1["① 入口"] --> A2["② 状态生成"] --> A3{"③ 关键判断"} --> A4["④ 下游结果"]
```

每张图最多放 3 个判断节点;超过时拆成主链和一个或多个局部判断图,不画完整控制流图。跨文件、模块或仓库时使用 `subgraph` 标出边界,但仍保持一条从左到右的业务主线。节点标签必须先写业务作用,再换行补真实方法或状态名,例如 `确认支付结果<br/>confirmPayment()`;不能只写陌生代码标识符。

图中用编号 `①②③` 关联后面的代码证据,并保持统一语义:

- 灰色:未修改链路;
- 红色或虚线:原问题路径、被删除路径;
- 绿色:新增或修复路径;
- 黄色菱形:关键判断;
- 虚线边框:根据改动推断但未由调用链或运行证据确认的节点,并明确标“推断,未验证”。

每个关键节点都要能追溯到锁定审查对象中的真实代码。对影响问题链路的 3~6 个关键方法,不能只列方法名;必须根据方法体、调用方和被调用方说明:

- 谁在什么条件下调用它;
- 输入的业务含义,不必机械抄 Java/TypeScript 类型;
- 它做的核心事情;
- 返回值、状态写入、消息发送等输出或副作用;
- 它为什么与本次问题或改动有关。

若方法名与实际行为不一致,以真实实现为准。仅从名字或注释推断用途时标注“推断,未验证”。代码证据注明仓库、文件、函数和行号;改动前引用基线 commit,改动后引用 PR 源 commit、当前 HEAD 或明确标记的工作区快照。片段每段通常 5~12 行、最多 3 段,只截取决定行为的部分。不得把伪代码冒充真实代码;确需简化时标注“伪代码示意”。

若改动只有一个简单条件或单点字段调整,图不会增加理解价值,可以省略主图,直接用链路对比表和代码证据;不要为满足格式强行画图。

### 8. 用一个具体 Case 把链路走通

每次 Review 都选一个最能解释本次问题的具体 Case,直接带读者从入口走到最终结果。审查对象和基线足以继续后,不要为了教学先让用户回答问题,也不要只丢一句“例如某请求会失败”;首次交付应先把这一条完整链路讲清楚。Case 的优先级是:真实复现输入、脱敏日志或运行记录 → 已有测试样例/fixture → 能由代码契约推出的代表性输入 → 明确标注为“假设场景”的示例。不得把构造示例包装成线上真实数据,也不得为了讲故事补造代码中没有的状态、调用或结果。

默认使用同一份输入分别推演改动前和改动后,让读者看到两条链路在哪里第一次分叉、状态怎样变化、修复为何能影响最终结果。即使链路较长,也要保留理解所需的完整因果闭环;只省略与本次结果无关且行为完全相同的内部细节。简单单点改动同样给出一个最小 Case,用一两步讲清条件成立与不成立时的差异,不因“改动小”跳过。

开始前先用白话固定:谁触发、带了什么关键输入、初始状态是什么、预期结果是什么。随后按真实执行顺序逐步说明:

| 步骤 | 进入本步的输入/状态 | 代码位置与方法 | 这一处是做什么的 | 改动前怎样走 | 改动后怎样走 | 交给下一步什么 / 最终结果 |
|---|---|---|---|---|---|---|
| ① | `<关键字段或状态>` | `<repo/path:line>` · `<method()>` | `<先用业务白话解释职责>` | `<判断、状态变化或副作用>` | `<判断、状态变化或副作用>` | `<下游输入或用户可见结果>` |

表中每一步都必须来自锁定版本的真实方法体和调用关系,并与前面的链路图使用相同编号;首次出现的方法要说明“它为什么存在”,不能只翻译方法名。复杂条件写成“满足什么 → 走哪条分支 → 状态从什么变成什么”,必要时在表后附决定分支的短代码片段并注明文件、方法、行号和版本。运行时值不可得时写“基于代码静态推演,运行时未验证”。

走读最后用两句话收束:第一句说明改动前为什么会得到错误结果,第二句说明改动后从哪一步截断问题。若 Case 暴露修复只能覆盖部分路径,应把遗漏升级为正式 finding,而不是在讲解中轻描淡写。

用户看完仍表示“似懂非懂”“这里为什么”或要向别人复述时,再吸收苏格拉底式单问题追问:先定位最上游的理解断点,每轮只问一个能区分理解是否正确的问题,并等待回答。用于补齐审查事实或选择 Case 的澄清问题,能从代码自查就不要问用户;用于检验理解的教学问题,可以询问代码中已有答案的机制,但要写成围绕当前 Case 的预测或推演。回答后只补足当前断点,再让用户沿这个 Case 继续推演,不一次抛出整套问卷。需要系统性掌握和迁移检验时,可继续使用 `$explain-to-master`。

### 9. 审查改动与遗漏

把当前审查范围内的改动视为一个待证伪方案:

- 改动是否截断了已确认的因果链,而不是只隐藏症状;
- 正常路径、失败路径和恢复路径是否都保持正确;
- 设计写到的检查是否全部实现;
- 是否混入无关重构、未来兼容或另一个需求;
- 新增状态、字段、API 或表是否有完整生产者和消费者;
- 测试是否覆盖复现条件、正常路径和关键回归;
- CI 通过是否真的覆盖该风险,还是只有形式上的绿灯。

先寻找能推翻每条候选 finding 的反证。只有满足以下条件才写进正式问题:

- 能指向具体文件、行号、配置、日志或运行事实;
- 有可达路径或明确消费者;
- 能说明触发条件和实际影响;
- 修正它会改变提交、合并决定或验证方式。

不要规定必须找到问题。按“阻塞 / 建议”分级:阻塞问题全部列出,建议只保留会改变提交、合并决定或验证方式的;其余不影响正确性的观察可省略。

#### 专项门禁:按真实风险加载

根据本次完整 diff、需求和调用链判断以下条件;命中多项时分别读取,不把未命中项作为默认阅读材料。条件无法确认时先查入口与消费者,再决定加载;不可因尚未加载而跳过真实风险。各参考文件继承本 Skill 的只读边界。

| 触发条件 | 必读检查 |
|---|---|
| 已产生持久副作用后仍可能返回失败 | [部分成功与同资源恢复](references/partial-success.md) |
| 新增或收紧校验、解析、Schema、序列化、路由或兼容层 | [跨层契约等价性](references/cross-layer-contract.md) |
| 修改 MCP、OpenAPI、RPC 等对外 Schema | [广播必传与运行时校验](references/schema-required.md) |
| 返回或上报 actual/effective/final/runtime 等事实字段 | [实际值来源](references/actual-fields.md) |
| 多入口、角色、协议分支或可共存状态 | [验收覆盖矩阵](references/acceptance-matrix.md) |
| 重试、重连、取消、超时、流式响应或错误正文提取 | [重试与取消](references/retry-cancellation.md) |

复审基于最新完整 diff 重新判断全部触发条件,不能只加载上一轮 finding 对应的检查。

#### 过度设计门禁:先尝试删掉或复用,再逐 hunk 证明范围合理

正确性审查完成后,必须再做一次简化攻击:逐项尝试删除或内联新增抽象,合并重复状态和分支,改用项目现有入口或已经在用的依赖,并重点检查新 manager、helper、后台任务、缓存、兼容层、重试和配置项。若更小方案能保持相同验收、正常/失败/恢复语义及测试保护,多出的设计就是 finding;新增共享状态、并发控制、契约或长期维护面时通常应阻塞,少量纯噪音可列为建议。这里的“更小”不是比较代码行数,必要的权限、并发、资源所有权、错误恢复和可观测性不能为简化而删掉。

正确性通过不代表 diff 可以无限扩张。逐个 diff hunk(同一处连续修改)回答“它直接满足哪条需求、修复哪个已证实问题,或为哪项必要测试提供支撑”;无法给出具体对应关系的改动默认视为范围外,而不是用“顺手优化”“更干净”“以后可能有用”证明合理。

- **禁止无意义格式噪音**:多余空行、无关缩进/换行、引号或 import 排序、全文件格式化、与目标无关的命名调整都会增加冲突并掩盖真实逻辑。只有项目强制格式化工具对本次触碰区域的必要输出才能保留,并说明证据。
- **保护仍正确的注释和文档**:删除或改写注释前,必须证明它已错误、重复、误导,或因对应代码被删除而失效。注释仍准确且对约束、历史原因、调用方或异常策略有解释价值时应保留;“代码已经能看懂”不是删除理由。
- **拒绝顺手重构和未来设计**:无关 helper 抽取、目录搬迁、接口泛化、兼容层、低概率兜底、性能优化和依赖升级,若不是当前需求的必要条件,应从本 PR 移除或拆分并另行授权。不要因已经写完或测试通过就降低范围标准。
- **审查增删两侧**:不仅检查新增代码是否有消费者,也要检查删除的函数、注释、测试、错误处理和兼容行为是否确实无用。删除仍正确内容属于真实回归风险,不是代码精简。

将范围外改动作为正式 finding:纯噪音或少量无关清理通常列为“建议”;会删除正确契约、扩大行为边界、增加维护面或显著提高冲突风险时列为“阻塞”。通过结论前应能把所有保留 hunk 映射到需求、根因、必要测试或强制工具输出。

### 10. 形成可执行的建议改动

在报告最末尾输出“建议改动”,用编号逐条写完整文案,默认最多 3 条。每条通常写 2~4 句话,并包含:

1. **改哪里**:指出文件、方法、配置或测试场景;
2. **为什么改**:说明当前行为、触发条件和实际风险;
3. **怎么改**:给出符合项目现有结构的最小调整方向,必要时附少量伪代码;
4. **改完怎样算正确**:写清预期行为和最短验证方式。

建议与正式 finding 一一对应时标明“对应问题 1/2/3”,不要重复大段问题描述。不要只写“补测试”“加判空”“优化逻辑”或“注意幂等”这类过度精简的短句,也不要在只读 Review 中直接修改代码。

输出前把每条建议按审查改动的同一标准过一遍:估算触发概率和实际损失,衡量它新增的状态、依赖和维护面,低概率边角隐患按“过度设计门禁”搁置。与本轮已确认的设计口径、需求条目或上一轮自己给出的结论冲突的建议直接撤回,不靠新增一层机制去补上一轮刚删掉的东西。

若没有必须修改的问题,仍保留本节并明确写“本次未发现必须修改项”,不要为了填满模板制造建议;可以补充一条有证据且明显降低风险的验证建议。若证据不足,优先建议获取哪项事实或执行哪项测试,不要在根因未确认时建议猜测性改代码。

## 结论口径

- **合理**:未发现阻塞问题,根因和改动链路有足够证据;
- **基本合理,需补充**:主体正确,但有非阻塞遗漏、测试或说明需要补齐;
- **需要修正**:存在可复现或可达的正确性问题,提交或合并前应修复;
- **证据不足**:真实 diff 不可得、比较基线不明确,或缺少会实质改变根因判断的运行时事实。

“证据不足”不是找不到问题时的兜底。静态证据足以判断的内容仍要给出明确结论,只把依赖缺失事实的部分标记未验证。

## 输出格式

使用下面结构,但让内容自然、紧凑。没有正式问题时删除“发现的问题”;没有必要代码片段时不贴代码;“建议改动”始终作为最后一节保留。

```markdown
# Review 结论

结论:合理 / 基本合理,需补充 / 需要修正 / 证据不足
仓库:<repo>
审查对象:<CodeUp PR / 当前工作区 / worktree / 分支 / commit / patch>
范围:<base commit → head commit;staged / unstaged / untracked;必要时注明排除项>
PR:<url;没有则删除本行>

## 需求背景
<两三句话,让不了解需求的人知道是哪块功能>

## 问题描述
<触发条件 → 哪一步出错 → 实际影响>

## 关键概念
<按步骤 3 解释必要术语;无则省略。>

## 根因判断
<按步骤 5 给出独立结论、与改动者判断的关系及证据缺口。>

## 独立方案与改动者方案对照
<按步骤 6 比较最小方案、遗漏和验证;简单一致时压缩成一段。>

## 代码链路与改动对比

### 主链路

#### 改动前

<独立的 `flowchart LR` Mermaid 图;简单单点改动可省略,并说明原因>

#### 改动后

<独立的 `flowchart LR` Mermaid 图;与改动前使用相同阶段、编号和粒度>

### 关键判断展开

<仅在主链包含复杂判断时绘制局部横向图;否则删除本节>

| 链路 | 改动前 | 改动后 | 判断 |
|---|---|---|---|
| <关键节点> | <原逻辑> | <新逻辑> | <是否截断根因及副作用> |

### 关键方法与代码证据

| 节点 / 方法及来源 | 谁调用、何时调用 | 输入 | 白话作用 | 输出或副作用 | 为什么与问题有关 |
|---|---|---|---|---|---|
| <① `method()` · `repo/path:line` · 版本> | <上游与触发条件> | <业务含义> | <这个方法实际做什么> | <返回、写状态、发消息等> | <它决定了哪一步结果> |

<按需附最多 3 段关键代码;每段注明来源和版本>

## 具体 Case 走读

Case:<一个真实复现、测试样例、代表性输入或明确标注的假设场景>
来源:<日志 / 测试 / PR 描述 / 基于代码静态构造;注明是否经过运行验证>
初始状态与预期:<谁触发、关键输入、初始状态、正常应得到什么>

| 步骤 | 进入本步的输入/状态 | 代码位置与方法 | 这一处是做什么的 | 改动前怎样走 | 改动后怎样走 | 交给下一步什么 / 最终结果 |
|---|---|---|---|---|---|---|
| ① | <关键值/状态> | `<repo/path:line>` · `<method()>` | <业务白话> | <原判断或状态变化> | <新判断或状态变化> | <下游输入或最终结果> |

<两句话收束:改动前为什么出错;改动后从哪一步截断问题。>

## 发现的问题

1. [阻塞/建议] `<file:line>`:<问题、触发条件和影响>。建议:<最小修正或验证方式>。

## 验证情况
已验证:<diff、调用链、规范、测试、日志或配置;按需注明参考的同类实现及其启示>
参考与简化:<最接近的项目实现、复用或偏离结论;尝试过的更小方案及保留当前设计的必要理由>
未验证:<只列可能改变结论的缺口,每项注明已排查的验证途径和卡点;没有则写“无关键缺口”>

## 建议改动

1. [必须/建议,对应问题 N] 建议调整 `<file:line / method()>`。<当前行为在什么条件下会造成什么影响>。<推荐采用的最小改法及其与现有实现的关系>。完成后应通过 <测试或可观察结果> 确认问题已解决且正常路径未回归。

<没有必须修改项时写:本次未发现必须修改项。现有实现已覆盖……;如需进一步降低风险,建议……,验证标准是……。>
```

先给结论,不复述调查过程,不罗列完整检查清单。专业词第一次出现时立即用白话解释;finding 也要说明业务影响,不能只写技术名词。图、表和代码片段只服务于理解根因与改动;除“具体 Case 走读”需要贯穿同一输入外,如果其他模块表达的是同一件事,保留最清楚的一种,不重复堆砌。

## 完成检查

交付前按步骤 1~10 核对本轮适用要求与门禁是否完成,不另起一轮相同调查。结论必须对应锁定的完整 diff 和证据强度,关键未知不能包装成通过;报告应让零背景读者借助具体 Case 理解改动,并据此决定通过、退回或补证。

Files in this skill

  • LICENSE1 KB
  • README.md8.9 KB
  • SKILL.md34.7 KB
  • evals/evals.json17.3 KB
  • references/acceptance-matrix.md2.5 KB
  • references/actual-fields.md1.2 KB
  • references/cross-layer-contract.md2 KB
  • references/partial-success.md1.6 KB
  • references/retry-cancellation.md2.2 KB
  • references/schema-required.md1.6 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.