redline-review 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +239 -0
- package/adapters/antigravity/redline-review.md +32 -0
- package/adapters/claude/redline-review.md +41 -0
- package/adapters/codex/redline-review.md +38 -0
- package/adapters/copilot/redline-review.md +38 -0
- package/adapters/opencode/redline-review.md +34 -0
- package/bin/redline-review +4 -0
- package/dist/build-context.d.ts +6 -0
- package/dist/build-context.d.ts.map +1 -0
- package/dist/build-context.js +47 -0
- package/dist/build-context.js.map +1 -0
- package/dist/detect-domains.d.ts +2 -0
- package/dist/detect-domains.d.ts.map +1 -0
- package/dist/detect-domains.js +66 -0
- package/dist/detect-domains.js.map +1 -0
- package/dist/redline-review.d.ts +3 -0
- package/dist/redline-review.d.ts.map +1 -0
- package/dist/redline-review.js +171 -0
- package/dist/redline-review.js.map +1 -0
- package/package.json +54 -0
- package/prompts/base-reviewer.md +28 -0
- package/prompts/lightweight-reviewer.md +20 -0
- package/prompts/strict-reviewer.md +24 -0
- package/rules/architecture.yaml +55 -0
- package/rules/auth.yaml +57 -0
- package/rules/concurrency.yaml +62 -0
- package/rules/correctness.yaml +108 -0
- package/rules/frontend.yaml +46 -0
- package/rules/maintainability.yaml +42 -0
- package/rules/observability.yaml +59 -0
- package/rules/performance-algorithmic.yaml +49 -0
- package/rules/performance-db.yaml +44 -0
- package/rules/performance-system.yaml +37 -0
- package/rules/risk-patterns.yaml +58 -0
- package/rules/simplicity.yaml +85 -0
- package/schemas/rule.schema.json +52 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
category: observability
|
|
2
|
+
severity_context: >
|
|
3
|
+
Prioritize observability gaps that make production incidents difficult to diagnose,
|
|
4
|
+
trace, or recover from. Systems should be diagnosable under production failure conditions.
|
|
5
|
+
|
|
6
|
+
rules:
|
|
7
|
+
- id: sensitive_data_in_logs
|
|
8
|
+
severity: critical
|
|
9
|
+
detect: sensitive data leakage into logs
|
|
10
|
+
examples:
|
|
11
|
+
- |
|
|
12
|
+
log(password)
|
|
13
|
+
log(authToken)
|
|
14
|
+
logger.info('User login', { password })
|
|
15
|
+
|
|
16
|
+
- id: missing_error_logging
|
|
17
|
+
severity: high
|
|
18
|
+
detect: errors caught but not logged
|
|
19
|
+
examples:
|
|
20
|
+
- |
|
|
21
|
+
catch error:
|
|
22
|
+
return failed
|
|
23
|
+
|
|
24
|
+
- id: silent_failures
|
|
25
|
+
severity: high
|
|
26
|
+
detect: silent failure paths where errors are swallowed with no logging
|
|
27
|
+
examples:
|
|
28
|
+
- |
|
|
29
|
+
catch error:
|
|
30
|
+
pass
|
|
31
|
+
|
|
32
|
+
- id: missing_tracing_context
|
|
33
|
+
severity: high
|
|
34
|
+
detect: cross-service calls missing tracing or correlation context
|
|
35
|
+
examples:
|
|
36
|
+
- |
|
|
37
|
+
serviceA -> serviceB with no correlation ID
|
|
38
|
+
|
|
39
|
+
- id: useless_logs
|
|
40
|
+
severity: medium
|
|
41
|
+
detect: useless or non-actionable log statements
|
|
42
|
+
examples:
|
|
43
|
+
- |
|
|
44
|
+
log('here')
|
|
45
|
+
log('done')
|
|
46
|
+
|
|
47
|
+
- id: missing_operational_metrics
|
|
48
|
+
severity: medium
|
|
49
|
+
detect: long-running or resource-intensive operations missing metrics
|
|
50
|
+
examples:
|
|
51
|
+
- |
|
|
52
|
+
processLargeJob() with no timing or success/failure metric
|
|
53
|
+
|
|
54
|
+
- id: excessive_logging_noise
|
|
55
|
+
severity: low
|
|
56
|
+
detect: excessive logging that creates noise and degrades log signal
|
|
57
|
+
examples:
|
|
58
|
+
- |
|
|
59
|
+
log('loop iteration ' + i)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
category: algorithmic_performance
|
|
2
|
+
severity_context: >
|
|
3
|
+
Estimate complexity mentally during review. Watch for O(n²) growth patterns and
|
|
4
|
+
unnecessary memory allocations in hot paths.
|
|
5
|
+
|
|
6
|
+
rules:
|
|
7
|
+
- id: nested_loops
|
|
8
|
+
severity: high
|
|
9
|
+
detect: nested loops over collections that produce O(n²) or worse complexity
|
|
10
|
+
examples:
|
|
11
|
+
- |
|
|
12
|
+
foreach users as user:
|
|
13
|
+
foreach roles as role:
|
|
14
|
+
check(user, role)
|
|
15
|
+
|
|
16
|
+
- id: brute_force_solution
|
|
17
|
+
severity: high
|
|
18
|
+
detect: brute-force solutions where a more efficient algorithm exists
|
|
19
|
+
examples:
|
|
20
|
+
- |
|
|
21
|
+
Linear scan to find an item that could use a hash map or index
|
|
22
|
+
|
|
23
|
+
- id: repeated_scans
|
|
24
|
+
severity: medium
|
|
25
|
+
detect: repeated scans or computations over the same data
|
|
26
|
+
examples:
|
|
27
|
+
- |
|
|
28
|
+
array.filter(...) called three times in the same function
|
|
29
|
+
|
|
30
|
+
- id: bad_time_complexity
|
|
31
|
+
severity: high
|
|
32
|
+
detect: algorithms with unnecessarily bad time complexity
|
|
33
|
+
examples:
|
|
34
|
+
- |
|
|
35
|
+
Sorting on every iteration instead of sorting once
|
|
36
|
+
|
|
37
|
+
- id: bad_memory_complexity
|
|
38
|
+
severity: medium
|
|
39
|
+
detect: algorithms with unnecessarily bad memory complexity
|
|
40
|
+
examples:
|
|
41
|
+
- |
|
|
42
|
+
Building a full copy of a large dataset to extract a single field
|
|
43
|
+
|
|
44
|
+
- id: excessive_allocations
|
|
45
|
+
severity: medium
|
|
46
|
+
detect: excessive object or array allocations in tight loops
|
|
47
|
+
examples:
|
|
48
|
+
- |
|
|
49
|
+
new Array() or {} construction inside a hot loop
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
category: database_performance
|
|
2
|
+
severity_context: >
|
|
3
|
+
Prioritize database access patterns that can cause production degradation, scaling
|
|
4
|
+
bottlenecks, or infrastructure overload. Always review ORM-heavy code with scale
|
|
5
|
+
assumptions in mind.
|
|
6
|
+
|
|
7
|
+
rules:
|
|
8
|
+
- id: n_plus_one_queries
|
|
9
|
+
severity: high
|
|
10
|
+
detect: N+1 query patterns in hot paths
|
|
11
|
+
examples:
|
|
12
|
+
- |
|
|
13
|
+
foreach ($orders as $order) {
|
|
14
|
+
$order->user->name;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
- id: unbounded_queries
|
|
18
|
+
severity: high
|
|
19
|
+
detect: unbounded queries without pagination or limits
|
|
20
|
+
examples:
|
|
21
|
+
- |
|
|
22
|
+
User::all()
|
|
23
|
+
SELECT * FROM orders
|
|
24
|
+
|
|
25
|
+
- id: overfetching
|
|
26
|
+
severity: medium
|
|
27
|
+
detect: overfetching by selecting all columns when only a subset is needed
|
|
28
|
+
examples:
|
|
29
|
+
- |
|
|
30
|
+
SELECT * FROM users WHERE id = 1
|
|
31
|
+
|
|
32
|
+
- id: missing_pagination
|
|
33
|
+
severity: high
|
|
34
|
+
detect: missing pagination or chunking on large result sets
|
|
35
|
+
examples:
|
|
36
|
+
- |
|
|
37
|
+
$users = User::where('active', true)->get()
|
|
38
|
+
|
|
39
|
+
- id: repeated_relationship_loading
|
|
40
|
+
severity: medium
|
|
41
|
+
detect: repeated relationship loading that should use eager loading
|
|
42
|
+
examples:
|
|
43
|
+
- |
|
|
44
|
+
$post->author inside a loop without ->with('author')
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
category: distributed_system_performance
|
|
2
|
+
severity_context: >
|
|
3
|
+
Prioritize distributed communication patterns that increase latency, reduce throughput,
|
|
4
|
+
or amplify cascading failures. Latency compounds across distributed systems.
|
|
5
|
+
|
|
6
|
+
rules:
|
|
7
|
+
- id: synchronous_waterfall
|
|
8
|
+
severity: high
|
|
9
|
+
detect: synchronous request waterfalls where parallel execution is possible
|
|
10
|
+
examples:
|
|
11
|
+
- |
|
|
12
|
+
const user = await getUser(id)
|
|
13
|
+
const orders = await getOrders(id)
|
|
14
|
+
const billing = await getBilling(id)
|
|
15
|
+
|
|
16
|
+
- id: serialized_io_bottleneck
|
|
17
|
+
severity: high
|
|
18
|
+
detect: serialized I/O operations that could be parallelized
|
|
19
|
+
examples:
|
|
20
|
+
- |
|
|
21
|
+
await sendEmail()
|
|
22
|
+
await sendSMS()
|
|
23
|
+
await updateAnalytics()
|
|
24
|
+
|
|
25
|
+
- id: excessive_network_roundtrips
|
|
26
|
+
severity: high
|
|
27
|
+
detect: excessive network roundtrips that could be batched
|
|
28
|
+
examples:
|
|
29
|
+
- |
|
|
30
|
+
Fetching user, permissions, and settings as three separate API calls
|
|
31
|
+
|
|
32
|
+
- id: missing_redis_pipelining
|
|
33
|
+
severity: medium
|
|
34
|
+
detect: missing Redis pipelining or batching opportunities
|
|
35
|
+
examples:
|
|
36
|
+
- |
|
|
37
|
+
redis.get() called in a loop instead of mget or pipeline
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
category: risk_patterns
|
|
2
|
+
severity_context: >
|
|
3
|
+
Review systems assuming future misuse, scaling pressure, operator mistakes, and
|
|
4
|
+
evolving complexity. Flag anything that could become a silent footgun.
|
|
5
|
+
|
|
6
|
+
rules:
|
|
7
|
+
- id: architectural_landmine
|
|
8
|
+
severity: high
|
|
9
|
+
detect: small helpers or utilities that have become implicit dependencies of many critical flows
|
|
10
|
+
examples:
|
|
11
|
+
- |
|
|
12
|
+
formatCurrency() now called by billing, invoicing, reporting, and emails
|
|
13
|
+
|
|
14
|
+
- id: operational_footgun
|
|
15
|
+
severity: high
|
|
16
|
+
detect: dangerous operations callable without safeguards or confirmation
|
|
17
|
+
examples:
|
|
18
|
+
- |
|
|
19
|
+
deleteAllUsers() with no confirmation or dry-run mode
|
|
20
|
+
|
|
21
|
+
- id: hidden_blast_radius
|
|
22
|
+
severity: high
|
|
23
|
+
detect: shared utilities or functions with hidden blast radius across critical domains
|
|
24
|
+
examples:
|
|
25
|
+
- |
|
|
26
|
+
normalizeUser() used by auth, billing, and orders without isolation
|
|
27
|
+
|
|
28
|
+
- id: sharp_api_edges
|
|
29
|
+
severity: medium
|
|
30
|
+
detect: API or function signatures that accept unsafe or nullable combinations
|
|
31
|
+
examples:
|
|
32
|
+
- |
|
|
33
|
+
function process(user, config = null, override = false)
|
|
34
|
+
|
|
35
|
+
- id: dangerous_defaults
|
|
36
|
+
severity: critical
|
|
37
|
+
detect: dangerous default values that could cause production issues
|
|
38
|
+
examples:
|
|
39
|
+
- |
|
|
40
|
+
isProduction = false
|
|
41
|
+
skipAuth = true
|
|
42
|
+
dryRun = false
|
|
43
|
+
|
|
44
|
+
- id: fragile_assumptions
|
|
45
|
+
severity: high
|
|
46
|
+
detect: fragile assumptions about system state that will break under scale or concurrency
|
|
47
|
+
examples:
|
|
48
|
+
- |
|
|
49
|
+
assume event ordering
|
|
50
|
+
assume single worker
|
|
51
|
+
assume in-memory cache is current
|
|
52
|
+
|
|
53
|
+
- id: single_point_of_failure
|
|
54
|
+
severity: high
|
|
55
|
+
detect: single points of failure in critical orchestration flows
|
|
56
|
+
examples:
|
|
57
|
+
- |
|
|
58
|
+
One service handles all payment orchestration with no fallback
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
category: simplicity_clarity
|
|
2
|
+
severity_context: >
|
|
3
|
+
Keep implementations cognitively cheap. Optimize for readability and intent clarity.
|
|
4
|
+
|
|
5
|
+
rules:
|
|
6
|
+
- id: redundant_checking
|
|
7
|
+
severity: medium
|
|
8
|
+
detect: redundant null/existence checking
|
|
9
|
+
examples:
|
|
10
|
+
- |
|
|
11
|
+
if x exists:
|
|
12
|
+
if x is not null:
|
|
13
|
+
process(x)
|
|
14
|
+
|
|
15
|
+
- id: redundant_normalization
|
|
16
|
+
severity: low
|
|
17
|
+
detect: redundant normalization or transformation steps
|
|
18
|
+
examples:
|
|
19
|
+
- |
|
|
20
|
+
trim(lowercase(trim(value)))
|
|
21
|
+
|
|
22
|
+
- id: redundant_type_casting
|
|
23
|
+
severity: low
|
|
24
|
+
detect: redundant type casting or conversion
|
|
25
|
+
examples:
|
|
26
|
+
- |
|
|
27
|
+
toInt(parseInt(value))
|
|
28
|
+
|
|
29
|
+
- id: verbose_defensive_programming
|
|
30
|
+
severity: medium
|
|
31
|
+
detect: overly verbose defensive guard chains
|
|
32
|
+
examples:
|
|
33
|
+
- |
|
|
34
|
+
if array exists:
|
|
35
|
+
if length > 0:
|
|
36
|
+
if first item exists:
|
|
37
|
+
|
|
38
|
+
- id: nested_conditionals
|
|
39
|
+
severity: medium
|
|
40
|
+
detect: deeply nested if/else blocks that should be flattened or extracted
|
|
41
|
+
examples:
|
|
42
|
+
- |
|
|
43
|
+
if a:
|
|
44
|
+
if b:
|
|
45
|
+
if c:
|
|
46
|
+
execute()
|
|
47
|
+
|
|
48
|
+
- id: chained_ternaries
|
|
49
|
+
severity: medium
|
|
50
|
+
detect: chained ternaries beyond simple cases
|
|
51
|
+
examples:
|
|
52
|
+
- |
|
|
53
|
+
x = a ? b : c ? d : e ? f : g
|
|
54
|
+
|
|
55
|
+
- id: large_conditional_chains
|
|
56
|
+
severity: medium
|
|
57
|
+
detect: large if/else-if chains that should use switch or a lookup table
|
|
58
|
+
examples:
|
|
59
|
+
- |
|
|
60
|
+
if type == 'A'
|
|
61
|
+
else if type == 'B'
|
|
62
|
+
else if type == 'C'
|
|
63
|
+
|
|
64
|
+
- id: complex_inline_boolean
|
|
65
|
+
severity: medium
|
|
66
|
+
detect: overly complex inline boolean conditions
|
|
67
|
+
examples:
|
|
68
|
+
- |
|
|
69
|
+
if a && b && !c && (d || e) && f:
|
|
70
|
+
|
|
71
|
+
- id: unclear_naming
|
|
72
|
+
severity: medium
|
|
73
|
+
detect: unclear or non-intent-revealing naming for functions, variables, or classes
|
|
74
|
+
examples:
|
|
75
|
+
- |
|
|
76
|
+
processData2()
|
|
77
|
+
doThing()
|
|
78
|
+
handleStuff()
|
|
79
|
+
|
|
80
|
+
- id: accidental_complexity
|
|
81
|
+
severity: high
|
|
82
|
+
detect: accidental complexity through unnecessary abstraction layers
|
|
83
|
+
examples:
|
|
84
|
+
- |
|
|
85
|
+
FactoryManagerResolverBuilder
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"title": "RedlineReviewRuleFile",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"required": ["category", "rules"],
|
|
6
|
+
"properties": {
|
|
7
|
+
"category": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"description": "Snake-case category identifier"
|
|
10
|
+
},
|
|
11
|
+
"severity_context": {
|
|
12
|
+
"type": "string",
|
|
13
|
+
"description": "Guidance for how the LLM should prioritize severity within this category"
|
|
14
|
+
},
|
|
15
|
+
"rules": {
|
|
16
|
+
"type": "array",
|
|
17
|
+
"items": {
|
|
18
|
+
"$ref": "#/definitions/Rule"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"definitions": {
|
|
23
|
+
"Rule": {
|
|
24
|
+
"type": "object",
|
|
25
|
+
"required": ["id", "severity", "detect"],
|
|
26
|
+
"properties": {
|
|
27
|
+
"id": {
|
|
28
|
+
"type": "string",
|
|
29
|
+
"description": "Snake-case unique identifier for the rule"
|
|
30
|
+
},
|
|
31
|
+
"severity": {
|
|
32
|
+
"type": "string",
|
|
33
|
+
"enum": ["critical", "high", "medium", "low"]
|
|
34
|
+
},
|
|
35
|
+
"detect": {
|
|
36
|
+
"type": "string",
|
|
37
|
+
"description": "Human-readable description of what to detect"
|
|
38
|
+
},
|
|
39
|
+
"examples": {
|
|
40
|
+
"type": "array",
|
|
41
|
+
"items": { "type": "string" },
|
|
42
|
+
"description": "Code examples demonstrating the anti-pattern"
|
|
43
|
+
},
|
|
44
|
+
"keywords": {
|
|
45
|
+
"type": "array",
|
|
46
|
+
"items": { "type": "string" },
|
|
47
|
+
"description": "Keywords used for auto domain detection from diffs"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|