name: fresh-eyes-review description: 此技能应在git提交、创建PR或宣布工作完成前作为强制性的最终合理性检查。在触发“commit”、“push”、“PR”、“pull request”、“done”、“finished”、“complete”、“ship”、“deploy”、“ready to merge”时使用。捕获那些尽管通过了测试但仍可能遗漏的安全漏洞、逻辑错误和业务规则缺陷。
全新视角审查
核心原则
“未经全新视角审查,不得提交”
这代表一个在实施完成、通过测试和同行评审之后执行的最终质量关卡。该纪律普遍适用,即使没有明确激活此技能。
关键区别
全新视角审查与测试和代码审查有根本区别:
| 方法 | 重点 | 盲点 |
|---|---|---|
| 测试 | 验证预期行为 | 无法测试未知的边缘情况 |
| 代码审查 | 模式和质量 | 审查者信任作者的意图 |
| 全新视角 | 带着心理距离刻意重读 | 捕获你认为正确的东西 |
关键洞察:“100%测试覆盖率和通过场景”可以与“等待发现的严重缺陷”共存。
必需流程
步骤 1 - 宣布承诺
明确声明:“开始对 [N] 个文件进行全新视角审查。这将需要 2-5 分钟。”
此声明创造了问责制,并将你的心态从实施重新调整为审计。
步骤 2 - 安全漏洞检查清单
审查所有被修改的文件是否存在安全问题:
| 漏洞 | 检查内容 |
|---|---|
| SQL注入 | 所有数据库查询都使用参数化语句,绝不使用字符串拼接 |
| XSS | 所有用户提供的内容在渲染到HTML之前都已转义 |
| 路径遍历 | 文件路径经过验证,../ 序列被拒绝或规范化 |
| 命令注入 | Shell命令不包含未净化的用户输入 |
| IDOR | 资源受访问控制,而不仅仅是不可猜测的ID |
| 认证绕过 | 每个受保护的端点都检查身份验证和授权 |
示例发现:
// 之前:SQL注入漏洞
const user = await db.query(`SELECT * FROM users WHERE id = '${userId}'`);
// 之后:参数化查询
const user = await db.query('SELECT * FROM users WHERE id = $1', [userId]);
步骤 3 - 逻辑错误检查清单
| 错误类型 | 检查内容 |
|---|---|
| 差一错误 | 数组索引、循环边界、分页限制 |
| 竞态条件 | 对共享状态的并发访问、异步操作 |
| 空值/未定义 | 每个 . 链都可能抛出异常;是否存在防御性检查? |
| 类型强制转换 | == 与 ===,隐式转换 |
| 状态突变 | 对输入参数有意外副作用吗? |
| 错误吞没 | 空的catch块、被忽略的Promise拒绝 |
示例发现:
// 之前:分页中的差一错误
const hasMore = results.length < pageSize;
// 之后:正确的边界
const hasMore = results.length === pageSize;
步骤 4 - 业务规则检查清单
| 检查项 | 问题 |
|---|---|
| 计算 | 公式是否完全符合要求?货币舍入是否正确? |
| 条件 | AND 与 OR 逻辑是否正确?否定应用得当吗? |
| 边缘情况 | 空输入、单项、最大值、零值? |
| 错误信息 | 用户友好吗?不泄露敏感信息? |
| 默认值 | 当可选字段省略时,默认值是否合理? |
示例发现:
// 之前:税务计算使用了错误的舍入方式
const tax = price * 0.08;
// 之后:正确的货币舍入
const tax = Math.round(price * 0.08 * 100) / 100;
步骤 5 - 性能检查清单
| 问题 | 检查内容 |
|---|---|
| N+1查询 | 进行数据库调用的循环应进行批处理 |
| 无界循环 | 最大迭代次数、超时保护 |
| 内存泄漏 | 事件监听器已移除、流已关闭、引用已清除 |
| 缺少索引 | 查询是否在索引列上进行过滤/排序? |
| 大负载 | 是否实现了分页?响应大小是否有限制? |
步骤 6 - 立即修复
在宣布完成之前解决问题:
- 进行修复
- 添加覆盖该问题的测试(如果不存在)
- 重新运行完整的测试套件
- 重新运行linter/类型检查器
步骤 7 - 宣布结果
强制性公告:
全新视角审查完成。发现并修复了 [N] 个问题:
- [每个问题和修复的简要描述]
即使零发现也要包含此内容——它证明了执行过程。
时间承诺
| 文件数量 | 预计时长 |
|---|---|
| 1-3 个文件 | 2 分钟 |
| 4-10 个文件 | 3-4 分钟 |
| 10+ 个文件 | 最多 5 分钟 |
警告信号:
- 快于 2 分钟表明深度不足
- 超过 5 分钟表明范围蔓延——专注于已更改的代码
需要拒绝的抗拒模式
必须明确拒绝以下合理化理由:
| 合理化理由 | 现实情况 |
|---|---|
| “测试很全面” | 测试验证的是设计,而不是正确性 |
| “我确信它是正确的” | 信心与缺陷数量成反比 |
| “合作伙伴在等” | 现在的 3 分钟节省了以后调试的 3 小时 |
| “生产环境被阻塞了” | 仓促行事会导致你急于修复的中断 |
| “高级开发人员已经批准了” | 他们审查的是意图,而不是实现细节 |
| “这只是一个小改动” | 小改动会导致大中断 |
这些情况恰恰是严重缺陷逃逸到生产环境的时候。
示例工作流程
用户:“我完成了身份验证功能的实现,让我提交吧”
助手:[触发 fresh-eyes-review 技能]
开始对 4 个文件进行全新视角审查。这将需要 2-5 分钟。
[审查 auth.ts 的安全性]
- 发现:电子邮件字段缺少输入验证
- 修复:添加了电子邮件格式验证
[审查 handler.ts 的逻辑]
- 发现:分页中的差一错误
- 修复:将边界检查中的 < 改为 <=
[审查 db.ts 的性能]
- 未发现问题
[审查 api.ts 的业务规则]
- 未发现问题
重新运行测试... 所有测试通过
全新视角审查完成。发现并修复了 2 个问题。