Skip to content

Commit 7eda4e1

Browse files
committed
feat(examples): add code-review checker scripts, rule docs, and diff fixtures
1 parent e5dc1e2 commit 7eda4e1

19 files changed

Lines changed: 542 additions & 0 deletions
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--- a/app/worker.py
2+
+++ b/app/worker.py
3+
@@ -5,6 +5,9 @@ async def start():
4+
config = load_config()
5+
+ session = aiohttp.ClientSession()
6+
+ asyncio.create_task(poll_updates())
7+
+ f = open("data.txt")
8+
return config
9+
--- a/tests/test_worker.py
10+
+++ b/tests/test_worker.py
11+
@@ -1,2 +1,3 @@
12+
def test_start():
13+
+ assert True
14+
pass
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--- a/app/repository.py
2+
+++ b/app/repository.py
3+
@@ -8,6 +8,10 @@ def reset_balances():
4+
logger.info("resetting balances")
5+
+ conn = sqlite3.connect("app.db")
6+
+ cur = conn.cursor()
7+
+ cur.execute("UPDATE accounts SET balance = 0")
8+
+ conn.commit()
9+
return True
10+
--- a/tests/test_repository.py
11+
+++ b/tests/test_repository.py
12+
@@ -1,2 +1,3 @@
13+
def test_reset():
14+
+ assert True
15+
pass
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--- a/app/dynamic.py
2+
+++ b/app/dynamic.py
3+
@@ -3,5 +3,6 @@ def run_snippet(snippet, use_eval):
4+
logger.debug("running snippet")
5+
+ result = eval(snippet) if use_eval else exec(snippet)
6+
return result
7+
--- a/tests/test_dynamic.py
8+
+++ b/tests/test_dynamic.py
9+
@@ -1,2 +1,3 @@
10+
def test_run():
11+
+ assert True
12+
pass
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
--- a/app/service.py
2+
+++ b/app/service.py
3+
@@ -5,6 +5,9 @@ def process(order):
4+
validate(order)
5+
+ if order.total < 0:
6+
+ raise ValueError("negative total")
7+
+ order.status = "processed"
8+
return order
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--- a/app/misc.py
2+
+++ b/app/misc.py
3+
@@ -1,3 +1,4 @@
4+
def greet(name):
5+
+ # trivial change used by the sandbox-failure scenario
6+
return "hello " + name
7+
--- a/tests/test_misc.py
8+
+++ b/tests/test_misc.py
9+
@@ -1,2 +1,3 @@
10+
def test_greet():
11+
+ assert True
12+
pass
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--- a/app/settings.py
2+
+++ b/app/settings.py
3+
@@ -1,4 +1,7 @@
4+
APP_NAME = "demo"
5+
+API_KEY = "sk-fakefakefakefakefakefake123456"
6+
+DB_PASSWORD = "prod-db-pass-2026"
7+
+aws_key = "AKIA0123456789ABCDEF"
8+
DEBUG = False
9+
--- a/tests/test_settings.py
10+
+++ b/tests/test_settings.py
11+
@@ -1,2 +1,3 @@
12+
def test_settings():
13+
+ assert True
14+
pass
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--- a/app/handler.py
2+
+++ b/app/handler.py
3+
@@ -10,6 +10,9 @@ def handle(request):
4+
data = request.get("data", "")
5+
+ result = eval(data)
6+
+ subprocess.run(cmd, shell=True)
7+
+ row = cursor.execute(f"SELECT * FROM users WHERE name = '{name}'")
8+
return result
9+
--- a/tests/test_handler.py
10+
+++ b/tests/test_handler.py
11+
@@ -1,2 +1,3 @@
12+
def test_handle():
13+
+ assert True
14+
pass
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Async Resource Leak Rule
2+
3+
Detects resource management issues in async Python code.
4+
5+
## Patterns
6+
7+
| Pattern | Severity | Confidence | Guidance |
8+
|---------|----------|------------|----------|
9+
| `aiohttp.ClientSession()` without `async with` | high | 0.8 | Use `async with aiohttp.ClientSession() as session:` or ensure session.close() is awaited. |
10+
| `asyncio.create_task()` without storing reference | medium | 0.7 | Store the task and await/cancel it; unreferenced tasks may be garbage collected mid-flight. |
11+
| `open()` assigned without `with` context manager | medium | 0.7 | Use `with open(...) as f:` so the handle is always closed. |
12+
13+
## Rationale
14+
15+
Resources created inside async functions must be properly managed. Leaked sessions,
16+
fire-and-forget tasks, and unclosed file handles can cause connection pool exhaustion,
17+
memory leaks, and unpredictable behavior under load.
18+
19+
## Remediation
20+
21+
Wrap resources in context managers (`async with` / `with`) or ensure explicit cleanup
22+
in `finally` blocks.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Database Lifecycle Rule
2+
3+
Detects database connections, cursors, and transactions opened without proper lifecycle management.
4+
5+
## Patterns
6+
7+
| Pattern | Severity | Confidence | Guidance |
8+
|---------|----------|------------|----------|
9+
| `.connect()` without context manager or close() | high | 0.8 | Use `with ...connect(...) as conn:` or close the connection in a finally block. |
10+
| `.cursor()` without context manager | low | 0.5 | Close the cursor or use a context manager. |
11+
| `.commit()` without rollback handling | medium | 0.65 | Wrap the transaction in try/except and roll back on failure. |
12+
13+
## Rationale
14+
15+
Unclosed database connections leak file descriptors and connection pool slots.
16+
Transactions committed without rollback handling can leave data in an inconsistent
17+
state on error.
18+
19+
## Remediation
20+
21+
- Use context managers (`with conn:` / `with conn.cursor()`) wherever possible.
22+
- Always wrap transactions in `try/except` and call `rollback()` on failure.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Missing Test Rule
2+
3+
Detects source code changes that lack corresponding test file changes.
4+
5+
## Trigger
6+
7+
Fires when a diff contains added lines in `.py` source files but no changes in:
8+
- Files under `tests/` directories
9+
- Files whose name starts with `test_` or ends with `_test.py`
10+
11+
## Findings
12+
13+
| Condition | Severity | Confidence | Guidance |
14+
|-----------|----------|------------|----------|
15+
| Source .py changed, no test files touched | medium | 0.8 | Add or update unit tests covering the changed behavior. |
16+
17+
## Rationale
18+
19+
Every behavior change should include or reference a test. Without test coverage,
20+
regressions go undetected.
21+
22+
## Remediation
23+
24+
Add or update unit tests that exercise the changed code paths.

0 commit comments

Comments
 (0)