code-review-excellence

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Code Review Excellence

卓越代码审查

Transform code reviews from gatekeeping to knowledge sharing through constructive feedback, systematic analysis, and collaborative improvement.
通过建设性反馈、系统性分析和协作改进,将代码审查从把关转变为知识共享。

When to Use This Skill

何时使用此技能

  • Reviewing pull requests and code changes
  • Establishing code review standards for teams
  • Mentoring junior developers through reviews
  • Conducting architecture reviews
  • Creating review checklists and guidelines
  • Improving team collaboration
  • Reducing code review cycle time
  • Maintaining code quality standards
  • 审查Pull Request和代码变更
  • 为团队制定代码审查标准
  • 通过审查指导初级开发人员
  • 开展架构审查
  • 创建审查清单和指南
  • 改善团队协作
  • 缩短代码审查周期
  • 维护代码质量标准

Core Principles

核心原则

1. The Review Mindset

1. 审查心态

Goals of Code Review:
  • Catch bugs and edge cases
  • Ensure code maintainability
  • Share knowledge across team
  • Enforce coding standards
  • Improve design and architecture
  • Build team culture
Not the Goals:
  • Show off knowledge
  • Nitpick formatting (use linters)
  • Block progress unnecessarily
  • Rewrite to your preference
代码审查的目标:
  • 发现bug和边缘情况
  • 确保代码可维护性
  • 在团队内共享知识
  • 执行编码标准
  • 改进设计和架构
  • 构建团队文化
非审查目标:
  • 炫耀知识
  • 纠结格式问题(使用linters)
  • 不必要地阻碍进度
  • 按照个人偏好重写代码

2. Effective Feedback

2. 有效的反馈

Good Feedback is:
  • Specific and actionable
  • Educational, not judgmental
  • Focused on the code, not the person
  • Balanced (praise good work too)
  • Prioritized (critical vs nice-to-have)
markdown
❌ Bad: "This is wrong."
✅ Good: "This could cause a race condition when multiple users
access simultaneously. Consider using a mutex here."

❌ Bad: "Why didn't you use X pattern?"
✅ Good: "Have you considered the Repository pattern? It would
make this easier to test. Here's an example: [link]"

❌ Bad: "Rename this variable."
✅ Good: "[nit] Consider `userCount` instead of `uc` for
clarity. Not blocking if you prefer to keep it."
优质反馈的特点:
  • 具体且可操作
  • 具有教育意义,而非评判性
  • 聚焦代码而非个人
  • 平衡兼顾(也要表扬优秀工作)
  • 区分优先级(关键问题 vs 锦上添花的建议)
markdown
❌ 糟糕示例:"这是错的。"
✅ 优秀示例:"当多个用户同时访问时,这可能会导致竞态条件。考虑在此处使用mutex。"

❌ 糟糕示例:"你为什么不使用X模式?"
✅ 优秀示例:"你是否考虑过Repository模式?它会让这段代码更易于测试。这里有一个示例:[链接]"

❌ 糟糕示例:"重命名这个变量。"
✅ 优秀示例:"[小建议] 为了清晰起见,考虑将`uc`重命名为`userCount`。如果您想保留原命名,不会阻碍合并。"

3. Review Scope

3. 审查范围

What to Review:
  • Logic correctness and edge cases
  • Security vulnerabilities
  • Performance implications
  • Test coverage and quality
  • Error handling
  • Documentation and comments
  • API design and naming
  • Architectural fit
What Not to Review Manually:
  • Code formatting (use Prettier, Black, etc.)
  • Import organization
  • Linting violations
  • Simple typos
需要审查的内容:
  • 逻辑正确性和边缘情况
  • 安全漏洞
  • 性能影响
  • 测试覆盖率和质量
  • 错误处理
  • 文档和注释
  • API设计与命名
  • 架构适配性
无需手动审查的内容:
  • 代码格式(使用Prettier、Black等工具)
  • 导入组织
  • Lint违规问题
  • 简单拼写错误

Review Process

审查流程

Phase 1: Context Gathering (2-3 minutes)

阶段1:收集上下文(2-3分钟)

markdown
Before diving into code, understand:

1. Read PR description and linked issue
2. Check PR size (>400 lines? Ask to split)
3. Review CI/CD status (tests passing?)
4. Understand the business requirement
5. Note any relevant architectural decisions
markdown
在深入查看代码前,先了解:

1. 阅读PR描述和关联的问题
2. 检查PR规模(超过400行?要求拆分)
3. 查看CI/CD状态(测试是否通过?)
4. 理解业务需求
5. 记录相关的架构决策

Phase 2: High-Level Review (5-10 minutes)

阶段2:高层次审查(5-10分钟)

markdown
1. **Architecture & Design**
   - Does the solution fit the problem?
   - Are there simpler approaches?
   - Is it consistent with existing patterns?
   - Will it scale?

2. **File Organization**
   - Are new files in the right places?
   - Is code grouped logically?
   - Are there duplicate files?

3. **Testing Strategy**
   - Are there tests?
   - Do tests cover edge cases?
   - Are tests readable?
markdown
1. **架构与设计**
   - 解决方案是否匹配问题需求?
   - 是否有更简单的实现方式?
   - 是否与现有模式保持一致?
   - 是否具备可扩展性?

2. **文件组织**
   - 新文件是否放在正确位置?
   - 代码分组是否符合逻辑?
   - 是否存在重复文件?

3. **测试策略**
   - 是否有测试用例?
   - 测试是否覆盖边缘情况?
   - 测试是否易读?

Phase 3: Line-by-Line Review (10-20 minutes)

阶段3:逐行审查(10-20分钟)

markdown
For each file:

1. **Logic & Correctness**
   - Edge cases handled?
   - Off-by-one errors?
   - Null/undefined checks?
   - Race conditions?

2. **Security**
   - Input validation?
   - SQL injection risks?
   - XSS vulnerabilities?
   - Sensitive data exposure?

3. **Performance**
   - N+1 queries?
   - Unnecessary loops?
   - Memory leaks?
   - Blocking operations?

4. **Maintainability**
   - Clear variable names?
   - Functions doing one thing?
   - Complex code commented?
   - Magic numbers extracted?
markdown
针对每个文件:

1. **逻辑与正确性**
   - 是否处理了边缘情况?
   - 是否存在差一错误?
   - 是否有Null/Undefined检查?
   - 是否存在竞态条件?

2. **安全性**
   - 是否验证了输入?
   - 是否存在SQL注入风险?
   - 是否存在XSS漏洞?
   - 是否存在敏感数据泄露?

3. **性能**
   - 是否存在N+1查询?
   - 是否有不必要的循环?
   - 是否存在内存泄漏?
   - 是否存在阻塞操作?

4. **可维护性**
   - 变量名称是否清晰?
   - 函数是否单一职责?
   - 复杂代码是否有注释?
   - 魔法数字是否已提取?

Phase 4: Summary & Decision (2-3 minutes)

阶段4:总结与决策(2-3分钟)

markdown
1. Summarize key concerns
2. Highlight what you liked
3. Make clear decision:
   - ✅ Approve
   - 💬 Comment (minor suggestions)
   - 🔄 Request Changes (must address)
4. Offer to pair if complex
markdown
1. 总结关键问题
2. 突出你认可的部分
3. 给出明确决策:
   - ✅ 批准
   - 💬 评论(小建议)
   - 🔄 请求修改(必须解决)
4. 如果问题复杂,提出结对编程的提议

Review Techniques

审查技巧

Technique 1: The Checklist Method

技巧1:清单法

markdown
undefined
markdown
undefined

Security Checklist

安全审查清单

  • User input validated and sanitized
  • SQL queries use parameterization
  • Authentication/authorization checked
  • Secrets not hardcoded
  • Error messages don't leak info
  • 用户输入已验证和清理
  • SQL查询使用参数化
  • 已检查身份验证/授权
  • 密钥未硬编码
  • 错误信息未泄露敏感信息

Performance Checklist

性能审查清单

  • No N+1 queries
  • Database queries indexed
  • Large lists paginated
  • Expensive operations cached
  • No blocking I/O in hot paths
  • 无N+1查询
  • 数据库查询已建立索引
  • 大型列表已分页
  • 昂贵操作已缓存
  • 热点路径中无阻塞I/O

Testing Checklist

测试审查清单

  • Happy path tested
  • Edge cases covered
  • Error cases tested
  • Test names are descriptive
  • Tests are deterministic
undefined
  • 正常流程已测试
  • 边缘情况已覆盖
  • 错误情况已测试
  • 测试名称具有描述性
  • 测试具有确定性
undefined

Technique 2: The Question Approach

技巧2:提问法

Instead of stating problems, ask questions to encourage thinking:
markdown
❌ "This will fail if the list is empty."
✅ "What happens if `items` is an empty array?"

❌ "You need error handling here."
✅ "How should this behave if the API call fails?"

❌ "This is inefficient."
✅ "I see this loops through all users. Have we considered
the performance impact with 100k users?"
不直接指出问题,而是通过提问引导思考:
markdown
❌ "如果列表为空,这段代码会失败。"
✅ "如果`items`是空数组会发生什么?"

❌ "这里需要错误处理。"
✅ "如果API调用失败,这段代码应该如何表现?"

❌ "这效率很低。"
✅ "我看到这段代码遍历了所有用户。我们是否考虑过用户量达到10万时的性能影响?"

Technique 3: Suggest, Don't Command

技巧3:建议而非命令

markdown
undefined
markdown
undefined

Use Collaborative Language

使用协作性语言

❌ "You must change this to use async/await" ✅ "Suggestion: async/await might make this more readable:
typescript     async function fetchUser(id: string) {         const user = await db.query('SELECT * FROM users WHERE id = ?', id);         return user;     }     
What do you think?"
❌ "Extract this into a function" ✅ "This logic appears in 3 places. Would it make sense to extract it into a shared utility function?"
undefined
❌ "你必须改成使用async/await" ✅ "建议:使用async/await可能会让这段代码更易读:
typescript     async function fetchUser(id: string) {         const user = await db.query('SELECT * FROM users WHERE id = ?', id);         return user;     }     
你觉得怎么样?"
❌ "把这段代码提取成函数" ✅ "这段逻辑出现在3个地方。把它提取成共享工具函数是否有意义?"
undefined

Technique 4: Differentiate Severity

技巧4:区分严重程度

markdown
Use labels to indicate priority:

🔴 [blocking] - Must fix before merge
🟡 [important] - Should fix, discuss if disagree
🟢 [nit] - Nice to have, not blocking
💡 [suggestion] - Alternative approach to consider
📚 [learning] - Educational comment, no action needed
🎉 [praise] - Good work, keep it up!

Example:
"🔴 [blocking] This SQL query is vulnerable to injection.
Please use parameterized queries."

"🟢 [nit] Consider renaming `data` to `userData` for clarity."

"🎉 [praise] Excellent test coverage! This will catch edge cases."
markdown
使用标签指示优先级:

🔴 [阻塞] - 合并前必须修复
🟡 [重要] - 应该修复,如有异议可讨论
🟢 [小建议] - 锦上添花,不阻塞合并
💡 [建议] - 可考虑的替代方案
📚 [学习] - 教育性评论,无需操作
🎉 [表扬] - 做得好,继续保持!

示例:
"🔴 [阻塞] 这个SQL查询存在注入漏洞。请使用参数化查询。"

"🟢 [小建议] 考虑将`data`重命名为`userData`以提升清晰度。"

"🎉 [表扬] 测试覆盖率很棒!这能发现边缘情况。"

Language-Specific Patterns

特定语言模式

Python Code Review

Python代码审查

python
undefined
python
undefined

Check for Python-specific issues

检查Python特有的问题

❌ Mutable default arguments

❌ 可变默认参数

def add_item(item, items=[]): # Bug! Shared across calls items.append(item) return items
def add_item(item, items=[]): # 漏洞!所有调用共享同一个列表 items.append(item) return items

✅ Use None as default

✅ 使用None作为默认值

def add_item(item, items=None): if items is None: items = [] items.append(item) return items
def add_item(item, items=None): if items is None: items = [] items.append(item) return items

❌ Catching too broad

❌ 捕获范围过宽

try: result = risky_operation() except: # Catches everything, even KeyboardInterrupt! pass
try: result = risky_operation() except: # 捕获所有异常,包括KeyboardInterrupt! pass

✅ Catch specific exceptions

✅ 捕获特定异常

try: result = risky_operation() except ValueError as e: logger.error(f"Invalid value: {e}") raise
try: result = risky_operation() except ValueError as e: logger.error(f"无效值: {e}") raise

❌ Using mutable class attributes

❌ 使用可变类属性

class User: permissions = [] # Shared across all instances!
class User: permissions = [] # 所有实例共享!

✅ Initialize in init

✅ 在__init__中初始化

class User: def init(self): self.permissions = []
undefined
class User: def init(self): self.permissions = []
undefined

TypeScript/JavaScript Code Review

TypeScript/JavaScript代码审查

typescript
// Check for TypeScript-specific issues

// ❌ Using any defeats type safety
function processData(data: any) {  // Avoid any
    return data.value;
}

// ✅ Use proper types
interface DataPayload {
    value: string;
}
function processData(data: DataPayload) {
    return data.value;
}

// ❌ Not handling async errors
async function fetchUser(id: string) {
    const response = await fetch(`/api/users/${id}`);
    return response.json();  // What if network fails?
}

// ✅ Handle errors properly
async function fetchUser(id: string): Promise<User> {
    try {
        const response = await fetch(`/api/users/${id}`);
        if (!response.ok) {
            throw new Error(`HTTP ${response.status}`);
        }
        return await response.json();
    } catch (error) {
        console.error('Failed to fetch user:', error);
        throw error;
    }
}

// ❌ Mutation of props
function UserProfile({ user }: Props) {
    user.lastViewed = new Date();  // Mutating prop!
    return <div>{user.name}</div>;
}

// ✅ Don't mutate props
function UserProfile({ user, onView }: Props) {
    useEffect(() => {
        onView(user.id);  // Notify parent to update
    }, [user.id]);
    return <div>{user.name}</div>;
}
typescript
// 检查TypeScript特有的问题

// ❌ 使用any会破坏类型安全
function processData(data: any) {  // 避免使用any
    return data.value;
}

// ✅ 使用正确的类型
interface DataPayload {
    value: string;
}
function processData(data: DataPayload) {
    return data.value;
}

// ❌ 未处理异步错误
async function fetchUser(id: string) {
    const response = await fetch(`/api/users/${id}`);
    return response.json();  // 如果网络失败会怎样?
}

// ✅ 正确处理错误
async function fetchUser(id: string): Promise<User> {
    try {
        const response = await fetch(`/api/users/${id}`);
        if (!response.ok) {
            throw new Error(`HTTP ${response.status}`);
        }
        return await response.json();
    } catch (error) {
        console.error('获取用户失败:', error);
        throw error;
    }
}

// ❌ 变更props
function UserProfile({ user }: Props) {
    user.lastViewed = new Date();  // 变更了props!
    return <div>{user.name}</div>;
}

// ✅ 不要变更props
function UserProfile({ user, onView }: Props) {
    useEffect(() => {
        onView(user.id);  // 通知父组件更新
    }, [user.id]);
    return <div>{user.name}</div>;
}

Advanced Review Patterns

高级审查模式

Pattern 1: Architectural Review

模式1:架构审查

markdown
When reviewing significant changes:

1. **Design Document First**
   - For large features, request design doc before code
   - Review design with team before implementation
   - Agree on approach to avoid rework

2. **Review in Stages**
   - First PR: Core abstractions and interfaces
   - Second PR: Implementation
   - Third PR: Integration and tests
   - Easier to review, faster to iterate

3. **Consider Alternatives**
   - "Have we considered using [pattern/library]?"
   - "What's the tradeoff vs. the simpler approach?"
   - "How will this evolve as requirements change?"
markdown
审查重大变更时:

1. **先看设计文档**
   - 对于大型功能,先要求提供设计文档再看代码
   - 在实现前与团队一起审查设计
   - 就方案达成一致,避免返工

2. **分阶段审查**
   - 第一个PR:核心抽象和接口
   - 第二个PR:实现细节
   - 第三个PR:集成和测试
   - 更易于审查,迭代更快

3. **考虑替代方案**
   - "我们是否考虑过使用[模式/库]?"
   - "与更简单的方案相比,权衡是什么?"
   - "随着需求变化,这将如何演进?"

Pattern 2: Test Quality Review

模式2:测试质量审查

typescript
// ❌ Poor test: Implementation detail testing
test('increments counter variable', () => {
    const component = render(<Counter />);
    const button = component.getByRole('button');
    fireEvent.click(button);
    expect(component.state.counter).toBe(1);  // Testing internal state
});

// ✅ Good test: Behavior testing
test('displays incremented count when clicked', () => {
    render(<Counter />);
    const button = screen.getByRole('button', { name: /increment/i });
    fireEvent.click(button);
    expect(screen.getByText('Count: 1')).toBeInTheDocument();
});

// Review questions for tests:
// - Do tests describe behavior, not implementation?
// - Are test names clear and descriptive?
// - Do tests cover edge cases?
// - Are tests independent (no shared state)?
// - Can tests run in any order?
typescript
// ❌ 糟糕的测试:测试实现细节
test('increments counter variable', () => {
    const component = render(<Counter />);
    const button = component.getByRole('button');
    fireEvent.click(button);
    expect(component.state.counter).toBe(1);  // 测试内部状态
});

// ✅ 优秀的测试:测试行为
test('displays incremented count when clicked', () => {
    render(<Counter />);
    const button = screen.getByRole('button', { name: /increment/i });
    fireEvent.click(button);
    expect(screen.getByText('Count: 1')).toBeInTheDocument();
});

// 测试审查问题:
// - 测试是否描述行为而非实现?
// - 测试名称是否清晰且具有描述性?
// - 测试是否覆盖边缘情况?
// - 测试是否独立(无共享状态)?
// - 测试是否可以按任意顺序运行?

Pattern 3: Security Review

模式3:安全审查

markdown
undefined
markdown
undefined

Security Review Checklist

安全审查清单

Authentication & Authorization

身份验证与授权

  • Is authentication required where needed?
  • Are authorization checks before every action?
  • Is JWT validation proper (signature, expiry)?
  • Are API keys/secrets properly secured?
  • 需要身份验证的地方已启用?
  • 每个操作前都已检查授权?
  • JWT验证是否正确(签名、过期时间)?
  • API密钥/密钥是否已妥善保管?

Input Validation

输入验证

  • All user inputs validated?
  • File uploads restricted (size, type)?
  • SQL queries parameterized?
  • XSS protection (escape output)?
  • 所有用户输入都已验证?
  • 文件上传已受限(大小、类型)?
  • SQL查询已参数化?
  • 已启用XSS防护(转义输出)?

Data Protection

数据保护

  • Passwords hashed (bcrypt/argon2)?
  • Sensitive data encrypted at rest?
  • HTTPS enforced for sensitive data?
  • PII handled according to regulations?
  • 密码已哈希(使用bcrypt/argon2)?
  • 敏感数据已加密存储?
  • 敏感数据传输已强制使用HTTPS?
  • PII处理符合法规要求?

Common Vulnerabilities

常见漏洞

  • No eval() or similar dynamic execution?
  • No hardcoded secrets?
  • CSRF protection for state-changing operations?
  • Rate limiting on public endpoints?
undefined
  • 无eval()或类似的动态执行?
  • 无硬编码密钥?
  • 状态变更操作已启用CSRF防护?
  • 公共端点已启用速率限制?
undefined

Giving Difficult Feedback

给出困难的反馈

Pattern: The Sandwich Method (Modified)

模式:改良版三明治法

markdown
Traditional: Praise + Criticism + Praise (feels fake)

Better: Context + Specific Issue + Helpful Solution

Example:
"I noticed the payment processing logic is inline in the
controller. This makes it harder to test and reuse.

[Specific Issue]
The calculateTotal() function mixes tax calculation,
discount logic, and database queries, making it difficult
to unit test and reason about.

[Helpful Solution]
Could we extract this into a PaymentService class? That
would make it testable and reusable. I can pair with you
on this if helpful."
markdown
传统版:表扬 + 批评 + 表扬(显得虚假)

更优版:上下文 + 具体问题 + 有用的解决方案

示例:
"我注意到支付处理逻辑内联在控制器中,这使得它更难测试和复用。

[具体问题]
calculateTotal()函数混合了税费计算、折扣逻辑和数据库查询,使得单元测试和逻辑理解变得困难。

[有用的解决方案]
我们可以把它提取到PaymentService类中吗?这样会让它更易于测试和复用。如果需要,我可以和你结对完成这件事。"

Handling Disagreements

处理分歧

markdown
When author disagrees with your feedback:

1. **Seek to Understand**
   "Help me understand your approach. What led you to
   choose this pattern?"

2. **Acknowledge Valid Points**
   "That's a good point about X. I hadn't considered that."

3. **Provide Data**
   "I'm concerned about performance. Can we add a benchmark
   to validate the approach?"

4. **Escalate if Needed**
   "Let's get [architect/senior dev] to weigh in on this."

5. **Know When to Let Go**
   If it's working and not a critical issue, approve it.
   Perfection is the enemy of progress.
markdown
当代码作者不同意你的反馈时:

1. **尝试理解**
   "请帮我理解你的思路。是什么让你选择了这种模式?"

2. **认可合理观点**
   "关于X的观点很好,我之前没有考虑到。"

3. **提供数据支持**
   "我担心性能问题。我们可以添加基准测试来验证这个方案吗?"

4. **必要时升级**
   "我们请[架构师/资深开发]来参与讨论吧。"

5. **知道何时放手**
   如果代码能正常工作且不是关键问题,就批准它。完美是进步的敌人。"

Best Practices

最佳实践

  1. Review Promptly: Within 24 hours, ideally same day
  2. Limit PR Size: 200-400 lines max for effective review
  3. Review in Time Blocks: 60 minutes max, take breaks
  4. Use Review Tools: GitHub, GitLab, or dedicated tools
  5. Automate What You Can: Linters, formatters, security scans
  6. Build Rapport: Emoji, praise, and empathy matter
  7. Be Available: Offer to pair on complex issues
  8. Learn from Others: Review others' review comments
  1. 及时审查:24小时内完成,理想情况是当天
  2. 限制PR规模:有效审查的PR规模建议为200-400行
  3. 分时段审查:每次最长60分钟,适当休息
  4. 使用审查工具:GitHub、GitLab或专用工具
  5. 自动化可自动化的内容:Linters、格式化工具、安全扫描
  6. 建立融洽关系:表情符号、表扬和同理心很重要
  7. 保持可用:主动提出为复杂问题提供结对编程支持
  8. 向他人学习:查看其他人的审查评论

Common Pitfalls

常见陷阱

  • Perfectionism: Blocking PRs for minor style preferences
  • Scope Creep: "While you're at it, can you also..."
  • Inconsistency: Different standards for different people
  • Delayed Reviews: Letting PRs sit for days
  • Ghosting: Requesting changes then disappearing
  • Rubber Stamping: Approving without actually reviewing
  • Bike Shedding: Debating trivial details extensively
  • 完美主义:因微小的风格偏好阻塞PR
  • 范围蔓延:"既然你在做这个,能不能顺便..."
  • 不一致:对不同的人使用不同的标准
  • 延迟审查:让PR搁置数天
  • 消失:要求修改后就不再跟进
  • 橡皮图章:未实际审查就批准
  • 自行车棚效应:过度争论琐碎细节

Templates

模板

PR Review Comment Template

PR审查评论模板

markdown
undefined
markdown
undefined

Summary

总结

[Brief overview of what was reviewed]
[已审查内容的简要概述]

Strengths

优点

  • [What was done well]
  • [Good patterns or approaches]
  • [做得好的地方]
  • [优秀的模式或方案]

Required Changes

必须修改的内容

🔴 [Blocking issue 1] 🔴 [Blocking issue 2]
🔴 [阻塞问题1] 🔴 [阻塞问题2]

Suggestions

建议

💡 [Improvement 1] 💡 [Improvement 2]
💡 [改进建议1] 💡 [改进建议2]

Questions

疑问

❓ [Clarification needed on X] ❓ [Alternative approach consideration]
❓ [需要澄清的X问题] ❓ [对替代方案的考虑]

Verdict

结论

✅ Approve after addressing required changes
undefined
✅ 解决必须修改的内容后批准
undefined

Resources

资源

  • references/code-review-best-practices.md: Comprehensive review guidelines
  • references/common-bugs-checklist.md: Language-specific bugs to watch for
  • references/security-review-guide.md: Security-focused review checklist
  • assets/pr-review-template.md: Standard review comment template
  • assets/review-checklist.md: Quick reference checklist
  • scripts/pr-analyzer.py: Analyze PR complexity and suggest reviewers
  • references/code-review-best-practices.md: 全面的审查指南
  • references/common-bugs-checklist.md: 各语言需注意的常见bug清单
  • references/security-review-guide.md: 安全聚焦的审查清单
  • assets/pr-review-template.md: 标准审查评论模板
  • assets/review-checklist.md: 快速参考清单
  • scripts/pr-analyzer.py: 分析PR复杂度并推荐审查人员