Skip to content

Commit 9309ba0

Browse files
committed
Release v0.6.0
1 parent 88949f5 commit 9309ba0

File tree

14 files changed

+592
-16
lines changed

14 files changed

+592
-16
lines changed

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.5.9
1+
0.6.0

npx/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

npx/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "asyncreview",
3-
"version": "0.5.8",
3+
"version": "0.6.0",
44
"description": "AI-powered GitHub PR/Issue reviews from the command line",
55
"type": "module",
66
"bin": {
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# Code Quality Checklist
2+
3+
## Error Handling
4+
5+
### Anti-patterns to Flag
6+
- **Swallowed exceptions**: Empty catch blocks or catch with only logging
7+
```javascript
8+
try { ... } catch (e) { } // Silent failure
9+
try { ... } catch (e) { console.log(e) } // Log and forget
10+
```
11+
- **Overly broad catch**: Catching `Exception`/`Error` base class instead of specific types
12+
- **Error information leakage**: Stack traces or internal details exposed to users
13+
- **Missing error handling**: No try-catch around fallible operations (I/O, network, parsing)
14+
- **Async error handling**: Unhandled promise rejections, missing `.catch()`, no error boundary
15+
16+
### Best Practices to Check
17+
- [ ] Errors are caught at appropriate boundaries
18+
- [ ] Error messages are user-friendly (no internal details exposed)
19+
- [ ] Errors are logged with sufficient context for debugging
20+
- [ ] Async errors are properly propagated or handled
21+
- [ ] Fallback behavior is defined for recoverable errors
22+
- [ ] Critical errors trigger alerts/monitoring
23+
24+
### Questions to Ask
25+
- "What happens when this operation fails?"
26+
- "Will the caller know something went wrong?"
27+
- "Is there enough context to debug this error?"
28+
29+
---
30+
31+
## Performance & Caching
32+
33+
### CPU-Intensive Operations
34+
- **Expensive operations in hot paths**: Regex compilation, JSON parsing, crypto in loops
35+
- **Blocking main thread**: Sync I/O, heavy computation without worker/async
36+
- **Unnecessary recomputation**: Same calculation done multiple times
37+
- **Missing memoization**: Pure functions called repeatedly with same inputs
38+
39+
### Database & I/O
40+
- **N+1 queries**: Loop that makes a query per item instead of batch
41+
```javascript
42+
// Bad: N+1
43+
for (const id of ids) {
44+
const user = await db.query(`SELECT * FROM users WHERE id = ?`, id)
45+
}
46+
// Good: Batch
47+
const users = await db.query(`SELECT * FROM users WHERE id IN (?)`, ids)
48+
```
49+
- **Missing indexes**: Queries on unindexed columns
50+
- **Over-fetching**: SELECT * when only few columns needed
51+
- **No pagination**: Loading entire dataset into memory
52+
53+
### Caching Issues
54+
- **Missing cache for expensive operations**: Repeated API calls, DB queries, computations
55+
- **Cache without TTL**: Stale data served indefinitely
56+
- **Cache without invalidation strategy**: Data updated but cache not cleared
57+
- **Cache key collisions**: Insufficient key uniqueness
58+
- **Caching user-specific data globally**: Security/privacy issue
59+
60+
### Memory
61+
- **Unbounded collections**: Arrays/maps that grow without limit
62+
- **Large object retention**: Holding references preventing GC
63+
- **String concatenation in loops**: Use StringBuilder/join instead
64+
- **Loading large files entirely**: Use streaming instead
65+
66+
### Questions to Ask
67+
- "What's the time complexity of this operation?"
68+
- "How does this behave with 10x/100x data?"
69+
- "Is this result cacheable? Should it be?"
70+
- "Can this be batched instead of one-by-one?"
71+
72+
---
73+
74+
## Boundary Conditions
75+
76+
### Null/Undefined Handling
77+
- **Missing null checks**: Accessing properties on potentially null objects
78+
- **Truthy/falsy confusion**: `if (value)` when `0` or `""` are valid
79+
- **Optional chaining overuse**: `a?.b?.c?.d` hiding structural issues
80+
- **Null vs undefined inconsistency**: Mixed usage without clear convention
81+
82+
### Empty Collections
83+
- **Empty array not handled**: Code assumes array has items
84+
- **Empty object edge case**: `for...in` or `Object.keys` on empty object
85+
- **First/last element access**: `arr[0]` or `arr[arr.length-1]` without length check
86+
87+
### Numeric Boundaries
88+
- **Division by zero**: Missing check before division
89+
- **Integer overflow**: Large numbers exceeding safe integer range
90+
- **Floating point comparison**: Using `===` instead of epsilon comparison
91+
- **Negative values**: Index or count that shouldn't be negative
92+
- **Off-by-one errors**: Loop bounds, array slicing, pagination
93+
94+
### String Boundaries
95+
- **Empty string**: Not handled as edge case
96+
- **Whitespace-only string**: Passes truthy check but is effectively empty
97+
- **Very long strings**: No length limits causing memory/display issues
98+
- **Unicode edge cases**: Emoji, RTL text, combining characters
99+
100+
### Common Patterns to Flag
101+
```javascript
102+
// Dangerous: no null check
103+
const name = user.profile.name
104+
105+
// Dangerous: array access without check
106+
const first = items[0]
107+
108+
// Dangerous: division without check
109+
const avg = total / count
110+
111+
// Dangerous: truthy check excludes valid values
112+
if (value) { ... } // fails for 0, "", false
113+
```
114+
115+
### Questions to Ask
116+
- "What if this is null/undefined?"
117+
- "What if this collection is empty?"
118+
- "What's the valid range for this number?"
119+
- "What happens at the boundaries (0, -1, MAX_INT)?"
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Removal and Iteration Plan Template
2+
3+
## Priority Levels
4+
5+
- [ ] **P0**: Immediate removal needed (security risk, significant cost, blocking other work)
6+
- [ ] **P1**: Remove in current sprint
7+
- [ ] **P2**: Backlog / next iteration
8+
9+
---
10+
11+
## Safe to Remove Now
12+
13+
### Item: [Name/Description]
14+
15+
| Field | Details |
16+
|-------|---------|
17+
| **Location** | `path/to/file.ts:line` |
18+
| **Rationale** | Why this should be removed |
19+
| **Evidence** | Unused (no references), dead feature flag, deprecated API |
20+
| **Impact** | None / Low - no active consumers |
21+
| **Deletion steps** | 1. Remove code 2. Remove tests 3. Remove config |
22+
| **Verification** | Run tests, check no runtime errors, monitor logs |
23+
24+
---
25+
26+
## Defer Removal (Plan Required)
27+
28+
### Item: [Name/Description]
29+
30+
| Field | Details |
31+
|-------|---------|
32+
| **Location** | `path/to/file.ts:line` |
33+
| **Why defer** | Active consumers, needs migration, stakeholder sign-off |
34+
| **Preconditions** | Feature flag off for 2 weeks, telemetry shows 0 usage |
35+
| **Breaking changes** | List any API/contract changes |
36+
| **Migration plan** | Steps for consumers to migrate |
37+
| **Timeline** | Target date or sprint |
38+
| **Owner** | Person/team responsible |
39+
| **Validation** | Metrics to confirm safe removal (error rates, usage counts) |
40+
| **Rollback plan** | How to restore if issues found |
41+
42+
---
43+
44+
## Checklist Before Removal
45+
46+
- [ ] Searched codebase for all references (`rg`, `grep`)
47+
- [ ] Checked for dynamic/reflection-based usage
48+
- [ ] Verified no external consumers (APIs, SDKs, docs)
49+
- [ ] Feature flag telemetry reviewed (if applicable)
50+
- [ ] Tests updated/removed
51+
- [ ] Documentation updated
52+
- [ ] Team notified (if shared code)
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# Security and Reliability Checklist
2+
3+
## Input/Output Safety
4+
5+
- **XSS**: Unsafe HTML injection, `dangerouslySetInnerHTML`, unescaped templates, innerHTML assignments
6+
- **Injection**: SQL/NoSQL/command/GraphQL injection via string concatenation or template literals
7+
- **SSRF**: User-controlled URLs reaching internal services without allowlist validation
8+
- **Path traversal**: User input in file paths without sanitization (`../` attacks)
9+
- **Prototype pollution**: Unsafe object merging in JavaScript (`Object.assign`, spread with user input)
10+
11+
## AuthN/AuthZ
12+
13+
- Missing tenant or ownership checks for read/write operations
14+
- New endpoints without auth guards or RBAC enforcement
15+
- Trusting client-provided roles/flags/IDs
16+
- Broken access control (IDOR - Insecure Direct Object Reference)
17+
- Session fixation or weak session management
18+
19+
## JWT & Token Security
20+
21+
- Algorithm confusion attacks (accepting `none` or `HS256` when expecting `RS256`)
22+
- Weak or hardcoded secrets
23+
- Missing expiration (`exp`) or not validating it
24+
- Sensitive data in JWT payload (tokens are base64, not encrypted)
25+
- Not validating `iss` (issuer) or `aud` (audience)
26+
27+
## Secrets and PII
28+
29+
- API keys, tokens, or credentials in code/config/logs
30+
- Secrets in git history or environment variables exposed to client
31+
- Excessive logging of PII or sensitive payloads
32+
- Missing data masking in error messages
33+
34+
## Supply Chain & Dependencies
35+
36+
- Unpinned dependencies allowing malicious updates
37+
- Dependency confusion (private package name collision)
38+
- Importing from untrusted sources or CDNs without integrity checks
39+
- Outdated dependencies with known CVEs
40+
41+
## CORS & Headers
42+
43+
- Overly permissive CORS (`Access-Control-Allow-Origin: *` with credentials)
44+
- Missing security headers (CSP, X-Frame-Options, X-Content-Type-Options)
45+
- Exposed internal headers or stack traces
46+
47+
## Runtime Risks
48+
49+
- Unbounded loops, recursive calls, or large in-memory buffers
50+
- Missing timeouts, retries, or rate limiting on external calls
51+
- Blocking operations on request path (sync I/O in async context)
52+
- Resource exhaustion (file handles, connections, memory)
53+
- ReDoS (Regular Expression Denial of Service)
54+
55+
## Cryptography
56+
57+
- Weak algorithms (MD5, SHA1 for security purposes)
58+
- Hardcoded IVs or salts
59+
- Using encryption without authentication (ECB mode, no HMAC)
60+
- Insufficient key length
61+
62+
## Race Conditions
63+
64+
### Shared State Access
65+
- Multiple threads/goroutines/async tasks accessing shared variables without synchronization
66+
- Global state or singletons modified concurrently
67+
- Lazy initialization without proper locking (double-checked locking issues)
68+
- Non-thread-safe collections used in concurrent context
69+
70+
### Check-Then-Act (TOCTOU)
71+
- `if (exists) then use` patterns without atomic operations
72+
- `if (authorized) then perform` where authorization can change
73+
- File existence check followed by file operation
74+
- Balance check followed by deduction (financial operations)
75+
76+
### Database Concurrency
77+
- Missing optimistic locking (`version` column, `updated_at` checks)
78+
- Missing pessimistic locking (`SELECT FOR UPDATE`)
79+
- Read-modify-write without transaction isolation
80+
- Counter increments without atomic operations
81+
82+
### Questions to Ask
83+
- "What happens if two requests hit this code simultaneously?"
84+
- "Is this operation atomic or can it be interrupted?"
85+
- "What shared state does this code access?"
86+
87+
## Data Integrity
88+
89+
- Missing transactions, partial writes, or inconsistent state updates
90+
- Weak validation before persistence (type coercion issues)
91+
- Missing idempotency for retryable operations
92+
- Lost updates due to concurrent modifications
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# SOLID Smell Prompts
2+
3+
## SRP (Single Responsibility)
4+
5+
- File owns unrelated concerns (e.g., HTTP + DB + domain rules in one file)
6+
- Large class/module with low cohesion or multiple reasons to change
7+
- Functions that orchestrate many unrelated steps
8+
- God objects that know too much about the system
9+
- **Ask**: "What is the single reason this module would change?"
10+
11+
## OCP (Open/Closed)
12+
13+
- Adding a new behavior requires editing many switch/if blocks
14+
- Feature growth requires modifying core logic rather than extending
15+
- No plugin/strategy/hook points for variation
16+
- **Ask**: "Can I add a new variant without touching existing code?"
17+
18+
## LSP (Liskov Substitution)
19+
20+
- Subclass checks for concrete type or throws for base method
21+
- Overridden methods weaken preconditions or strengthen postconditions
22+
- Subclass ignores or no-ops parent behavior
23+
- **Ask**: "Can I substitute any subclass without the caller knowing?"
24+
25+
## ISP (Interface Segregation)
26+
27+
- Interfaces with many methods, most unused by implementers
28+
- Callers depend on broad interfaces for narrow needs
29+
- Empty/stub implementations of interface methods
30+
- **Ask**: "Do all implementers use all methods?"
31+
32+
## DIP (Dependency Inversion)
33+
34+
- High-level logic depends on concrete IO, storage, or network types
35+
- Hard-coded implementations instead of abstractions or injection
36+
- Import chains that couple business logic to infrastructure
37+
- **Ask**: "Can I swap the implementation without changing business logic?"
38+
39+
---
40+
41+
## Common Code Smells (Beyond SOLID)
42+
43+
| Smell | Signs |
44+
|-------|-------|
45+
| **Long method** | Function > 30 lines, multiple levels of nesting |
46+
| **Feature envy** | Method uses more data from another class than its own |
47+
| **Data clumps** | Same group of parameters passed together repeatedly |
48+
| **Primitive obsession** | Using strings/numbers instead of domain types |
49+
| **Shotgun surgery** | One change requires edits across many files |
50+
| **Divergent change** | One file changes for many unrelated reasons |
51+
| **Dead code** | Unreachable or never-called code |
52+
| **Speculative generality** | Abstractions for hypothetical future needs |
53+
| **Magic numbers/strings** | Hardcoded values without named constants |
54+
55+
---
56+
57+
## Refactor Heuristics
58+
59+
1. **Split by responsibility, not by size** - A small file can still violate SRP
60+
2. **Introduce abstraction only when needed** - Wait for the second use case
61+
3. **Keep refactors incremental** - Isolate behavior before moving
62+
4. **Preserve behavior first** - Add tests before restructuring
63+
5. **Name things by intent** - If naming is hard, the abstraction might be wrong
64+
6. **Prefer composition over inheritance** - Inheritance creates tight coupling
65+
7. **Make illegal states unrepresentable** - Use types to enforce invariants

0 commit comments

Comments
 (0)