Code Review Skill
Good reviews catch bugs. Great reviews teach the author something.
Review Priority (What Matters Most)
- Correctness — Does it do what it's supposed to?
- Security — Can it be exploited?
- Maintainability — Will the next person understand this?
- Performance — Will it scale?
- Style — Is it consistent? (ideally enforced by linters, not humans)
3-Pass Review
| Pass |
Focus |
What You're Looking For |
Time |
| 1. Orientation |
Big picture |
Does the approach make sense? Is the scope right? Over-engineered? |
2-3 min |
| 2. Logic |
Deep read |
Edge cases, null handling, error paths, concurrency, off-by-one |
10-15 min |
| 3. Polish |
Surface |
Naming, duplication, test coverage, docs |
3-5 min |
Pass 1 shortcut: Read the PR description and test names first. They reveal intent faster than code.
Comment Prefixes
| Prefix |
Meaning |
Author Response |
[blocking] |
Must fix before merge |
Fix it |
[suggestion] |
Better approach exists |
Consider it, explain if declining |
[question] |
I don't understand |
Clarify (in code, not just in reply) |
[nit] |
Trivial style issue |
Fix if easy, skip if not |
[praise] |
This is well done |
Appreciate it |
Good vs Bad Comment Examples
| Bad |
Why |
Good |
| "This is confusing" |
Vague, unhelpful |
"[suggestion] This nested ternary is hard to follow. Consider extracting to a named function like isEligibleForDiscount()." |
| "Fix this" |
No context |
"[blocking] This accepts user input without sanitization. Use escapeHtml() before rendering." |
| "Why?" |
Sounds hostile |
"[question] What's the motivation for the custom sort here vs Array.sort()? Is there a performance concern?" |
| "LGTM" (on 500-line PR) |
Rubber stamp |
"Pass 1: Approach looks right. Pass 2 comments below. Pass 3: naming is clean." |
Reviewer and Author Posture
Most review friction is posture, not substance. Both sides carry an obligation:
| Reviewer |
Author |
| Assume positive intent |
Be open to feedback |
| Ask questions, don't demand |
Explain your reasoning |
| Focus on the code, not the person |
Don't take feedback personally |
| Offer alternatives, not just criticism |
Acknowledge good suggestions |
A review exists to catch bugs before users do, raise code quality through collaboration, spread knowledge across the team, keep patterns consistent, and leave a written record of why a decision was made. If a comment serves none of those, it is noise.
Review Checklist
Security
Logic
Quality
Architecture
Anti-Patterns
| Anti-Pattern |
What Happens |
Instead |
| Rubber-stamp |
Bugs ship |
Actually read Pass 1-3 |
| Bikeshedding |
Hours on naming, ignore logic bugs |
Spend 80% on Pass 2 |
| Gatekeeping |
Reviewees dread PRs |
Teach, don't block |
| Week-long queue |
PRs go stale, conflicts pile up |
Review within 4 hours, merge within 24 |
| Style wars |
Team friction |
Automate style (ESLint, Prettier, etc.) |
| Everything-is-blocking |
Author overwhelmed |
Use prefix system honestly |
Mission-Critical Review (NASA Standards)
For safety-critical projects, apply NASA/JPL Power of 10 rules during review:
Blocking Violations (Must Fix)
| Rule |
Check For |
Detection |
| R1 |
Recursive function without maxDepth parameter |
grep -rn "function.*\(" | xargs grep -l "walk|traverse|recurse" |
| R2 |
while loop without iteration counter |
Manual review of all while statements |
| R3 |
Unbounded array growth |
push() in loops without size checks |
High Priority (Strong Recommendation)
| Rule |
Check For |
Detection |
| R4 |
Function > 60 lines |
Line count per function |
| R5 |
Missing entry assertions |
Public functions without precondition checks |
| R8 |
Nesting > 4 levels |
Visual inspection of indentation |
Medium Priority (Consider)
| Rule |
Check For |
Detection |
| R6 |
Variable declared far from use |
Manual review |
| R7 |
Unchecked return values |
grep for ignored returns |
| R9 |
Deep property access without ?. |
obj.prop.prop.prop chains |
| R10 |
Compiler warnings |
Build output |
Trigger: User mentions "mission-critical", "NASA standards", "high reliability", or "safety-critical"
Review Timing
| PR Size |
Expected Review Time |
If Larger |
| < 100 lines |
< 30 min |
— |
| 100-400 lines |
30-60 min |
Ideal size |
| 400+ lines |
60+ min |
Ask author to split |
| 1000+ lines |
Don't |
Refuse; request breakdown |
Extension Audit Methodology (VS Code Extensions)
When: Before release, after major refactoring, or on quality concerns
Scope: Multi-dimensional code quality analysis beyond standard code review
5-Dimension Audit Framework
| Dimension |
Focus |
Tools/Methods |
Output |
| Debug & Logging |
Console statements, debug code |
grep -r "console\\.log|console\\.debug" |
Categorize: legitimate vs removable |
| Dead Code |
Unused imports, orphaned files, broken refs |
TypeScript compilation + manual scan |
List dead commands, UI, dependencies |
| Performance |
Blocking I/O, sync operations, bottlenecks |
grep -r "Sync\(" src/, profiling |
Async refactoring candidates |
| Menu Validation |
All commands/buttons work |
Manual testing + error logs |
Broken commands, missing handlers |
| Dependencies |
Unused packages, leftover references |
package.json vs import analysis |
Removable dependencies |
Audit Report Template
## Executive Summary
- Console statements: X remaining (Y legitimate, Z removable)
- Dead code: [commands/UI/dependencies list]
- Performance: [blocking operations count]
- Menu validation: [working/broken ratio]
## Recommendations
1. [Category]: [Issue] → [Action] (Priority: Critical/High/Medium)
2. [Category]: [Issue] → [Action] (Priority: Critical/High/Medium)
Console Statement Categorization
| Category |
Keep? |
Examples |
| Enterprise compliance |
✅ |
Audit logs, security events, GDPR actions |
| User feedback |
✅ |
TTS status, long-running ops, critical errors |
| Debug noise |
❌ |
Setup verbosity, migration logs, info messages |
| Development artifacts |
❌ |
"Entering function X", temporary debugging |
Performance Red Flags
- Synchronous file I/O in UI thread:
fs.readFileSync, fs.existsSync, fs.readdirSync
- Fix: Convert to
fs-extra async: await fs.readFile, await fs.pathExists, await fs.readdir
- Blocking operations in activation: Heavy computation before extension ready
- Fix: Defer to background, show loading state, or lazy-load
- Serial operations that could be parallel: Sequential awaits for independent tasks
- Fix:
Promise.all([op1(), op2(), op3()])
Dead Code Detection Pattern
- Scan command registrations:
vscode.commands.registerCommand('command.id', ...)
- Scan UI references: Search HTML/views for command IDs
- Cross-check: Commands in UI but not registered = broken; registered but unused = dead
- Verify disposables: Removed commands should have disposable cleanup too
Post-Audit Verification
Pattern applies to: VS Code extensions, Electron apps, Node.js services with UI
Would Revise If
Revise if reviews repeatedly miss security or correctness defects that adversarial review (deep-review skill) catches on the same PR, or if the 3-pass model produces consistent false-positive [blocking] comments that authors reasonably decline.
1---2name: code-review-43description: Systematic code review for correctness, security, and growth — not just style enforcement4---56# Code Review Skill78> Good reviews catch bugs. Great reviews teach the author something.910## Review Priority (What Matters Most)11121. **Correctness** — Does it do what it's supposed to?132. **Security** — Can it be exploited?143. **Maintainability** — Will the next person understand this?154. **Performance** — Will it scale?165. **Style** — Is it consistent? (ideally enforced by linters, not humans)1718## 3-Pass Review1920| Pass | Focus | What You're Looking For | Time |21| ---- | ----- | ----------------------- | ---- |22| 1. Orientation | Big picture | Does the approach make sense? Is the scope right? Over-engineered? | 2-3 min |23| 2. Logic | Deep read | Edge cases, null handling, error paths, concurrency, off-by-one | 10-15 min |24| 3. Polish | Surface | Naming, duplication, test coverage, docs | 3-5 min |2526**Pass 1 shortcut**: Read the PR description and test names first. They reveal intent faster than code.2728## Comment Prefixes2930| Prefix | Meaning | Author Response |31| ------ | ------- | --------------- |32| `[blocking]` | Must fix before merge | Fix it |33| `[suggestion]` | Better approach exists | Consider it, explain if declining |34| `[question]` | I don't understand | Clarify (in code, not just in reply) |35| `[nit]` | Trivial style issue | Fix if easy, skip if not |36| `[praise]` | This is well done | Appreciate it |3738### Good vs Bad Comment Examples3940| Bad | Why | Good |41| --- | --- | ---- |42| "This is confusing" | Vague, unhelpful | "[suggestion] This nested ternary is hard to follow. Consider extracting to a named function like `isEligibleForDiscount()`." |43| "Fix this" | No context | "[blocking] This accepts user input without sanitization. Use `escapeHtml()` before rendering." |44| "Why?" | Sounds hostile | "[question] What's the motivation for the custom sort here vs `Array.sort()`? Is there a performance concern?" |45| "LGTM" (on 500-line PR) | Rubber stamp | "Pass 1: Approach looks right. Pass 2 comments below. Pass 3: naming is clean." |4647### Reviewer and Author Posture4849Most review friction is posture, not substance. Both sides carry an obligation:5051| Reviewer | Author |52| --- | --- |53| Assume positive intent | Be open to feedback |54| Ask questions, don't demand | Explain your reasoning |55| Focus on the code, not the person | Don't take feedback personally |56| Offer alternatives, not just criticism | Acknowledge good suggestions |5758A review exists to catch bugs before users do, raise code quality through collaboration, spread knowledge across the team, keep patterns consistent, and leave a written record of why a decision was made. If a comment serves none of those, it is noise.5960## Review Checklist6162### Security6364- [ ] No secrets, tokens, or API keys in code65- [ ] User input validated/sanitized before use66- [ ] Auth checks on protected endpoints67- [ ] No SQL/command injection vectors68- [ ] Sensitive data not logged6970### Logic7172- [ ] Edge cases handled (empty input, null, boundary values)73- [ ] Error paths return meaningful messages74- [ ] Async operations have timeout/cancellation75- [ ] State changes are atomic (no partial updates)76- [ ] All new branches have test coverage7778### Quality7980- [ ] Tests cover the *changed behavior*, not just the changed lines81- [ ] No debug code (console.log, TODO-hacks)82- [ ] Public API changes documented83- [ ] Backward compatibility considered84- [ ] **Every export is called by production** — grep the consumer code for each exported symbol; an exported function tested by unit tests but never called by production is dead weight that lies about what the system does (often surfaces "the feature is promised in CHANGELOG but never wired"). If the test suite passes but production doesn't import the function, either wire it in or remove it.85- [ ] **Filter-style guards have test data that exercises them** — a `filter(x => x !== 'local')` on a list with zero `local` entries is unverified; for mutation-testing coverage seed the input. See [mutation-testing](../mutation-testing/SKILL.md).8687### Architecture8889- [ ] Change is in the right layer (not business logic in the controller)90- [ ] New dependencies justified91- [ ] No unnecessary coupling introduced9293## Anti-Patterns9495| Anti-Pattern | What Happens | Instead |96| ------------ | ------------ | ------- |97| Rubber-stamp | Bugs ship | Actually read Pass 1-3 |98| Bikeshedding | Hours on naming, ignore logic bugs | Spend 80% on Pass 2 |99| Gatekeeping | Reviewees dread PRs | Teach, don't block |100| Week-long queue | PRs go stale, conflicts pile up | Review within 4 hours, merge within 24 |101| Style wars | Team friction | Automate style (ESLint, Prettier, etc.) |102| Everything-is-blocking | Author overwhelmed | Use prefix system honestly |103104## Mission-Critical Review (NASA Standards)105106For safety-critical projects, apply NASA/JPL Power of 10 rules during review:107108### Blocking Violations (Must Fix)109110| Rule | Check For | Detection |111| ---- | --------- | --------- |112| **R1** | Recursive function without `maxDepth` parameter | `grep -rn "function.*\(" \| xargs grep -l "walk\|traverse\|recurse"` |113| **R2** | `while` loop without iteration counter | Manual review of all `while` statements |114| **R3** | Unbounded array growth | `push()` in loops without size checks |115116### High Priority (Strong Recommendation)117118| Rule | Check For | Detection |119| ---- | --------- | --------- |120| **R4** | Function > 60 lines | Line count per function |121| **R5** | Missing entry assertions | Public functions without precondition checks |122| **R8** | Nesting > 4 levels | Visual inspection of indentation |123124### Medium Priority (Consider)125126| Rule | Check For | Detection |127| ---- | --------- | --------- |128| **R6** | Variable declared far from use | Manual review |129| **R7** | Unchecked return values | `grep` for ignored returns |130| **R9** | Deep property access without `?.` | `obj.prop.prop.prop` chains |131| **R10** | Compiler warnings | Build output |132133**Trigger**: User mentions "mission-critical", "NASA standards", "high reliability", or "safety-critical"134135## Review Timing136137| PR Size | Expected Review Time | If Larger |138| ------- | -------------------- | --------- |139| < 100 lines | < 30 min | — |140| 100-400 lines | 30-60 min | Ideal size |141| 400+ lines | 60+ min | Ask author to split |142| 1000+ lines | Don't | Refuse; request breakdown |143144---145146## Extension Audit Methodology (VS Code Extensions)147148**When**: Before release, after major refactoring, or on quality concerns149150**Scope**: Multi-dimensional code quality analysis beyond standard code review151152### 5-Dimension Audit Framework153154| Dimension | Focus | Tools/Methods | Output |155| --------- | ----- | ------------- | ------ |156| **Debug & Logging** | Console statements, debug code | `grep -r "console\\.log\|console\\.debug"` | Categorize: legitimate vs removable |157| **Dead Code** | Unused imports, orphaned files, broken refs | TypeScript compilation + manual scan | List dead commands, UI, dependencies |158| **Performance** | Blocking I/O, sync operations, bottlenecks | `grep -r "Sync\(" src/`, profiling | Async refactoring candidates |159| **Menu Validation** | All commands/buttons work | Manual testing + error logs | Broken commands, missing handlers |160| **Dependencies** | Unused packages, leftover references | package.json vs import analysis | Removable dependencies |161162### Audit Report Template163164```markdown165## Executive Summary166- Console statements: X remaining (Y legitimate, Z removable)167- Dead code: [commands/UI/dependencies list]168- Performance: [blocking operations count]169- Menu validation: [working/broken ratio]170171## Recommendations1721. [Category]: [Issue] → [Action] (Priority: Critical/High/Medium)1732. [Category]: [Issue] → [Action] (Priority: Critical/High/Medium)174```175176### Console Statement Categorization177178| Category | Keep? | Examples |179| -------- | ----- | -------- |180| **Enterprise compliance** | ✅ | Audit logs, security events, GDPR actions |181| **User feedback** | ✅ | TTS status, long-running ops, critical errors |182| **Debug noise** | ❌ | Setup verbosity, migration logs, info messages |183| **Development artifacts** | ❌ | "Entering function X", temporary debugging |184185### Performance Red Flags186187- **Synchronous file I/O** in UI thread: `fs.readFileSync`, `fs.existsSync`, `fs.readdirSync`188 - **Fix**: Convert to `fs-extra` async: `await fs.readFile`, `await fs.pathExists`, `await fs.readdir`189- **Blocking operations** in activation: Heavy computation before extension ready190 - **Fix**: Defer to background, show loading state, or lazy-load191- **Serial operations** that could be parallel: Sequential awaits for independent tasks192 - **Fix**: `Promise.all([op1(), op2(), op3()])`193194### Dead Code Detection Pattern1951961. **Scan command registrations**: `vscode.commands.registerCommand('command.id', ...)`1972. **Scan UI references**: Search HTML/views for command IDs1983. **Cross-check**: Commands in UI but not registered = broken; registered but unused = dead1994. **Verify disposables**: Removed commands should have disposable cleanup too200201### Post-Audit Verification202203- [ ] TypeScript compiles: `npm run compile` → exit 0204- [ ] No orphaned imports: All imports resolve205- [ ] Version aligned: package.json, CHANGELOG, copilot-instructions match206- [ ] Smoke test: Extension activates, 3 random commands work207208**Pattern applies to**: VS Code extensions, Electron apps, Node.js services with UI209210## Would Revise If211212Revise if reviews repeatedly miss security or correctness defects that adversarial review (`deep-review` skill) catches on the same PR, or if the 3-pass model produces consistent false-positive `[blocking]` comments that authors reasonably decline.