Skip to content

Commit f1d5c8c

Browse files
authored
Merge pull request #3 from Recurse-ML/update-rules
Update rules to use the new format
2 parents 45b28cf + c8a441b commit f1d5c8c

2 files changed

Lines changed: 130 additions & 69 deletions

File tree

content/rules.md

Lines changed: 130 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,26 @@
11
---
22
title: "Custom Semantic Code Checks for PRs"
3-
date: 2025-06-26T17:16:50+01:00
3+
date: 2025-07-09T17:16:50+01:00
44
draft: false
55
toc: false
6-
images:
76
tags:
87
- untagged
98
---
109

11-
# Custom Semantic Code Checks for PRs
10+
_[Find the full docs for Rules here](https://docs.recurse.ml/gh/configs/rules)_
1211

13-
<!-- TODO: add a Recurse screenshot as a header here -->
12+
![Recurse ML PR Comment on a redundant comment with proposed suggestion (removal of comment)](header.png)
1413

1514
Maintaining consistent code quality while scaling the team is difficult.
1615
Well-intentioned Notion style guides are time-consuming to write and are often disregarded as soon as they're written.
17-
In this post I'll describe how you can use Recurse ML's new Custom Rules Feature to put the code style guide inside of your PR process.
16+
In this post I'll describe how you can use Recurse ML's new Rules Feature to put the code style guide inside of your PR process.
1817

1918
Recurse ML is a GitHub App that identifies bugs introduced in PRs.
2019
It focuses on semantic issues that slip past static analysers.
2120

2221
We realised that every team's "source of paranoia" is different.
2322
While some universal bugs exist, the most valuable catches are often team-specific.
24-
That's why we built custom rules - a way to teach Recurse ML about your codebase's unique requirements.
23+
That's why we built rules - a way to teach Recurse ML about your codebase's unique requirements.
2524

2625
## Quickstart
2726

@@ -31,80 +30,121 @@ Then, create a `.recurseml.yaml` file (you can place it anywhere in your project
3130

3231
```yaml
3332
# put this in .recurseml.yaml anywhere in your repo
34-
custom_rules:
35-
- name: "Effective Code Comments" # https://blog.codinghorror.com/code-tells-you-how-comments-tell-you-why/
36-
applicable_files:
37-
- "**/*.js"
38-
- "**/*.ts"
39-
- "**/*.py"
40-
- "**/*.go"
41-
- "**/*.java"
42-
- "**/*.rb"
43-
- "**/*.cs"
44-
description: "Explain WHY not WHAT the code does. Document complex business logic, clarify non-obvious implementations, warn about gotchas, and provide context for maintainers. Use proper documentation comment format for functions/methods. Keep TODO comments specific with assignees. Update comments when code changes."
33+
rules: .cursor/rules
4534
```
4635
47-
The full docs for custom rules can be found [here](https://recurse-ml.notion.site/Custom-Rules-21106defaa718059beabfb583f2ad066).
36+
Recurse ML rules are compatible with [Continue's](https://docs.continue.dev/customize/deep-dives/rules) [Cursor's](https://docs.cursor.com/context/rules) rule formats.
37+
38+
Next, create your rules directory and add your first rule. Create a file called `effective-comments.md` in your `.cursor/rules` directory:
39+
40+
```md
41+
---
42+
Name: effective-comments
43+
Description: Explain WHY not WHAT the code does
44+
Globs:
45+
- "**/*.js"
46+
- "**/*.ts"
47+
- "**/*.py"
48+
- "**/*.go"
49+
- "**/*.java"
50+
- "**/*.rb"
51+
- "**/*.cs"
52+
---
53+
54+
# Effective Code Comments
55+
56+
Explain WHY not WHAT the code does. Document complex business logic, clarify non-obvious implementations, warn about gotchas, and provide context for maintainers. Use proper documentation comment format for functions/methods. Keep TODO comments specific with assignees. Update comments when code changes.
57+
58+
See: https://blog.codinghorror.com/code-tells-you-how-comments-tell-you-why/
59+
```
60+
61+
The full docs for rules can be found [here](https://recurse-ml.notion.site/Custom-Rules-21106defaa718059beabfb583f2ad066).
4862

4963
Now, every time a PR is submitted in your repo, a check will run, that verifies whether comments in the newly introduced code adhere to these guidelines.
5064
If they don't, Recurse ML will leave a review comment.
5165

52-
5366
For tips on how to write high quality rules, I recommend reading [bdougie's](https://x.com/bdougieYO) excellent blogpost [The Anatomy of Rules](https://blog.continue.dev/the-anatomy-of-rules-writing-effective-boundaries-for-ai-agents-in-ruby/).
5467
Even though his examples are in Ruby, the principles are universal.
5568

5669
## Inspiration Gallery
5770

58-
If you're still wondering what custom rules to introduce into your repo, I've gathered some examples.
71+
If you're still wondering what rules to introduce into your repo, I've gathered some examples.
5972

6073
### Performance & Scaling
6174

6275
These rules catch the performance killers that don't show up until you're under real load.
6376
For most applications, they're probably overkill - but if you're one of the lucky few startups with actual users, these patterns become critical.
6477
They're designed to prevent issues that work fine in development but can bring down your entire API when traffic picks up.
6578

66-
```yaml
67-
custom_rules:
68-
- name: "Avoid Blocking Operations in Request Handlers"
69-
applicable_files:
70-
- "routes/**/*.js"
71-
- "api/**/*.js"
72-
- "**/*handler*.js"
73-
description: "Don't use synchronous operations (fs.readFileSync, crypto.pbkdf2Sync) in request handlers as they block the event loop and kill performance under load. Use async alternatives or move to worker threads. One blocking operation can take down your entire API response time."
79+
Create `blocking-operations.md`:
80+
81+
```md
82+
---
83+
Name: avoid-blocking-operations
84+
Description: Don't use synchronous operations in request handlers
85+
Globs:
86+
- "routes/**/*.js"
87+
- "api/**/*.js"
88+
- "**/*handler*.js"
89+
---
90+
91+
# Avoid Blocking Operations in Request Handlers
92+
93+
Don't use synchronous operations (fs.readFileSync, crypto.pbkdf2Sync) in request handlers as they block the event loop and kill performance under load. Use async alternatives or move to worker threads. One blocking operation can take down your entire API response time.
7494
```
7595

76-
```yaml
77-
custom_rules:
78-
- name: "Database Query Optimisation"
79-
applicable_files:
80-
- "**/*.js"
81-
- "**/*.ts"
82-
description: "Avoid N+1 queries and missing database indexes. Use eager loading, batch queries, or data loaders. Flag loops that contain database queries or ORM calls. These issues don't show up in development but will crash production performance as data grows."
96+
Create `database-queries.md`:
97+
98+
```md
99+
---
100+
Name: database-query-optimization
101+
Description: Avoid N+1 queries and missing database indexes
102+
Globs:
103+
- "**/*.js"
104+
- "**/*.ts"
105+
---
106+
107+
# Database Query Optimisation
108+
109+
Avoid N+1 queries and missing database indexes. Use eager loading, batch queries, or data loaders. Flag loops that contain database queries or ORM calls. These issues don't show up in development but will crash production performance as data grows.
83110
```
84111

85112
## Operational Reliability
86113

87-
88114
Production systems have a way of failing in the most inconvenient moments.
89115
These rules focus on the defensive coding practices that make the difference between a system that gracefully handles errors and one that silently loses data or crashes under pressure.
90116
Most codebases won't need this level of rigour, but when reliability matters to your users (and your sleep schedule), these patterns become essential.
91117

92-
```yaml
93-
custom_rules:
94-
- name: "Proper Error Handling in Critical Paths"
95-
applicable_files:
96-
- "**/*.js"
97-
- "**/*.ts"
98-
description: "Critical operations (payments, user registration, data processing) must have comprehensive error handling with logging, monitoring, and graceful degradation. Avoid silent failures that could lose revenue or corrupt user data. Include error context for debugging production issues."
118+
Create `error-handling.md`:
119+
120+
```md
121+
---
122+
Name: proper-error-handling
123+
Description: Critical operations must have comprehensive error handling
124+
Globs:
125+
- "**/*.js"
126+
- "**/*.ts"
127+
---
128+
129+
# Proper Error Handling in Critical Paths
130+
131+
Critical operations (payments, user registration, data processing) must have comprehensive error handling with logging, monitoring, and graceful degradation. Avoid silent failures that could lose revenue or corrupt user data. Include error context for debugging production issues.
99132
```
100133

101-
```yaml
102-
custom_rules:
103-
- name: "Memory Leak Prevention"
104-
applicable_files:
105-
- "**/*.js"
106-
- "**/*.ts"
107-
description: "Clean up event listeners, timers, and streams to prevent memory leaks. Use weak references for caches, clear intervals/timeouts, and properly close database connections. Memory leaks in Node.js can silently kill server performance and require expensive restarts."
134+
Create `memory-leaks.md`:
135+
136+
```md
137+
---
138+
Name: memory-leak-prevention
139+
Description: Clean up resources to prevent memory leaks
140+
Globs:
141+
- "**/*.js"
142+
- "**/*.ts"
143+
---
144+
145+
# Memory Leak Prevention
146+
147+
Clean up event listeners, timers, and streams to prevent memory leaks. Use weak references for caches, clear intervals/timeouts, and properly close database connections. Memory leaks in Node.js can silently kill server performance and require expensive restarts.
108148
```
109149

110150
### Wisdom from the Elders
@@ -114,36 +154,57 @@ Wonder no more.
114154
As you probably noticed, the example rule in Quickstart session was inspired by [Jeff Atwood's](https://blog.codinghorror.com/about-me/) [classic](https://blog.codinghorror.com/code-tells-you-how-comments-tell-you-why/).
115155
I decided to distil some more classic software engineering blogposts into rules.
116156

117-
```yaml
118-
custom_rules:
119-
- name: "Don't DRY Your Code Prematurely" # https://testing.googleblog.com/2024/05/dont-dry-your-code-prematurely.html
120-
applicable_files:
121-
- "**/*.js"
122-
- "**/*.ts"
123-
- "**/*.py"
124-
- "**/*.go"
125-
- "**/*.java"
126-
- "**/*.rb"
127-
- "**/*.cs"
128-
description: "Consider carefully if code duplication is truly redundant or just superficially similar before applying DRY principles. Functions or classes may look the same but serve different contexts and business requirements that evolve differently over time. Avoid premature abstractions that couple behaviours which may need to evolve separately. When in doubt, keep behaviours separate until enough common patterns emerge over time that justify the coupling. Think about long-term evolution, not just making code shorter. Apply YAGNI principle - tolerate a little duplication in early development stages and wait to abstract until clear patterns emerge."
157+
Create `dont-dry-prematurely.md`:
158+
159+
```md
160+
---
161+
Name: dont-dry-prematurely
162+
Description: Consider carefully if code duplication is truly redundant
163+
Globs:
164+
- "**/*.js"
165+
- "**/*.ts"
166+
- "**/*.py"
167+
- "**/*.go"
168+
- "**/*.java"
169+
- "**/*.rb"
170+
- "**/*.cs"
171+
---
172+
173+
# Don't DRY Your Code Prematurely
174+
175+
Consider carefully if code duplication is truly redundant or just superficially similar before applying DRY principles. Functions or classes may look the same but serve different contexts and business requirements that evolve differently over time. Avoid premature abstractions that couple behaviours which may need to evolve separately. When in doubt, keep behaviours separate until enough common patterns emerge over time that justify the coupling. Think about long-term evolution, not just making code shorter. Apply YAGNI principle - tolerate a little duplication in early development stages and wait to abstract until clear patterns emerge.
176+
177+
See: https://testing.googleblog.com/2024/05/dont-dry-your-code-prematurely.html
129178
```
130179

131-
```yaml
132-
custom_rules:
133-
- name: "Make Wrong Code Look Wrong" # https://www.joelonsoftware.com/2005/05/11/making-wrong-code-look-wrong/
134-
applicable_files:
135-
- "**/*.js"
136-
description: "Use naming conventions that make security vulnerabilities and type mismatches immediately visible. For web applications, prefix all user-supplied strings with 'unsafe_' or 'us' and all sanitized strings with 'safe_' or 's'. For coordinate systems, use prefixes like 'window_x' vs 'layout_x' to distinguish semantic differences. Apply Apps Hungarian notation principles - use prefixes that indicate the semantic meaning or origin of data, not just the data type. Make code self-documenting by ensuring that dangerous or incorrect operations look obviously wrong at the point of use. Collocate all information needed to verify correctness in the same line of code."
180+
Create `make-wrong-code-look-wrong.md`:
181+
182+
```md
183+
---
184+
Name: make-wrong-code-look-wrong
185+
Description: Use naming conventions that make security vulnerabilities visible
186+
Globs:
187+
- "**/*.js"
188+
---
189+
190+
# Make Wrong Code Look Wrong
191+
192+
Use naming conventions that make security vulnerabilities and type mismatches immediately visible. For web applications, prefix all user-supplied strings with 'unsafe_' or 'us' and all sanitized strings with 'safe_' or 's'. For coordinate systems, use prefixes like 'window_x' vs 'layout_x' to distinguish semantic differences. Apply Apps Hungarian notation principles - use prefixes that indicate the semantic meaning or origin of data, not just the data type. Make code self-documenting by ensuring that dangerous or incorrect operations look obviously wrong at the point of use. Collocate all information needed to verify correctness in the same line of code.
193+
194+
See: https://www.joelonsoftware.com/2005/05/11/making-wrong-code-look-wrong/
137195
```
138196

139197
Now, the rules act as a JIT learning tool for new-joiners, too!
198+
And if your team is already using Cursor Rules for AI-assisted development, these same patterns will help maintain consistency across both human and AI-generated code.
140199

141200

142201
## Your Usecase Here
143202

144203
Do you have a pet peeve that you fight for like it's the Battle of Verdun?
145204
Is there part of your project that requires extra care during every PR?
146205
Maybe you just found a weird and wacky way to use this feature?
206+
How does this compare to your existing agent rule setup?
147207
I'd like to hear all about it.
148-
My email's my name at recurse.ml.
208+
My email's armin at recurse.ml.
149209
And for higher bandwidth comms, you can find our team on Discord: https://discord.gg/qEjHQk64Z9
210+

content/rules/header.png

203 KB
Loading

0 commit comments

Comments
 (0)