Update README.md
Browse files
README.md
CHANGED
|
@@ -38,42 +38,60 @@ print(obs.code_snippet)
|
|
| 38 |
- `POST /mcp` – minimal MCP endpoint
|
| 39 |
|
| 40 |
## Tasks
|
| 41 |
-
|
| 42 |
-
# Bug ID Description How to inject
|
| 43 |
-
1 null_check Missing if key in dict: guard AST: remove if‑statement
|
| 44 |
-
2 simple_typo Variable name misspelled (users → usres) AST: rename variable
|
| 45 |
-
3 string_index Indexing string with wrong index (off‑by‑one) AST: change constant in index
|
| 46 |
-
4 default_value Not providing a default in dict.get() AST: replace dict[key] with dict.get(key) … but wrongly
|
| 47 |
-
5 empty_return Function returns None in a branch that should return something AST: insert return None or delete a return
|
| 48 |
-
Medium (off‑by‑one, loop logic, simple arithmetic)
|
| 49 |
-
# Bug ID Description How to inject
|
| 50 |
-
6 off_by_one range(x) → range(1, x-1) (skips first and last) AST: modify range args
|
| 51 |
-
7 loop_skip for i in range(len(arr)): missing last element because of off‑by‑one AST: change range length
|
| 52 |
-
8 sign_error sum += item replaced with sum -= item AST: swap Add/Sub
|
| 53 |
-
9 swap_args Calling a function with arguments swapped AST: swap arg order
|
| 54 |
-
10 uninitialised_var Using a variable before assignment in a loop AST: remove assignment line
|
| 55 |
-
Hard (division‑by‑zero, floating‑point, edge‑case handling)
|
| 56 |
-
# Bug ID Description How to inject
|
| 57 |
-
11 division_by_zero_empty Missing check for empty list before averaging AST: remove the if not data: guard
|
| 58 |
-
12 division_by_zero_zero Integer division where denominator can be zero AST: remove a denominator‑checking statement
|
| 59 |
-
13 float_precision Using integer division // instead of / for average AST: change operator
|
| 60 |
-
14 abs_usage Forgetting abs() when comparing differences AST: remove abs() call
|
| 61 |
-
15 round_error Rounding too early causing precision loss AST: insert round() incorrectly
|
| 62 |
-
Harder (race conditions, missing atomic operations)
|
| 63 |
-
# Bug ID Description How to inject
|
| 64 |
-
16 missing_lock Shared counter accessed without a lock Template: remove with lock: from code
|
| 65 |
-
17 double_lock Acquiring the same lock twice (deadlock risk) Template: add extra lock.acquire()
|
| 66 |
-
18 global_nonatomic Compound assignment x = x + 1 instead of atomic += AST: modify assignment node
|
| 67 |
-
19 thread_safe_list Appending to a list from multiple threads without lock Template: remove lock around list operation
|
| 68 |
-
20 volatile_read Reading a shared flag outside a lock Template: remove synchronization block
|
| 69 |
-
Hardest (deadlock, ordering, complex concurrency)
|
| 70 |
-
# Bug ID Description How to inject
|
| 71 |
-
21 deadlock_order Lock A then lock B in one thread, opposite in another Template: swap lock acquisition order
|
| 72 |
-
22 nested_lock_timeout Not using a timeout when acquiring locks, causing hang Template: replace acquire() with acquire(blocking=True) without timeout
|
| 73 |
-
23 fork_join Starting threads and not waiting for them to finish (missing join()) AST: remove thread.join()
|
| 74 |
-
24 mutex_release Releasing a mutex in one thread that was locked by another Template: wrong release logic
|
| 75 |
-
25 race_on_init Initializing a shared resource after threads have started Template: move initialization after thread creation
|
| 76 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 77 |
## Deployment
|
| 78 |
|
| 79 |
```bash
|
|
|
|
| 38 |
- `POST /mcp` – minimal MCP endpoint
|
| 39 |
|
| 40 |
## Tasks
|
| 41 |
+
## 🐛 Bug Taxonomy (25 bugs across 5 difficulty levels)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
|
| 43 |
+
The **RedTeam** randomly selects one bug from the current difficulty level at the start of every episode.
|
| 44 |
+
Your agent must figure out what’s broken, gather evidence, and convince the simulated author – or it won’t stick.
|
| 45 |
+
|
| 46 |
+
### 🟢 Easy – Null‑Checks & Simple Logic Errors
|
| 47 |
+
|
| 48 |
+
| # | Bug ID | What’s wrong | Injection method |
|
| 49 |
+
|---|--------|--------------|------------------|
|
| 50 |
+
| 1 | `null_check` | Missing `if key in dict:` guard → KeyError | AST: remove the if‑statement |
|
| 51 |
+
| 2 | `simple_typo` | Misspelled variable `users` → `usres` | AST: rename variable |
|
| 52 |
+
| 3 | `string_index` | String index shifted by +1 | AST: change constant in index |
|
| 53 |
+
| 4 | `default_value` | `dict.get(key)` used without a fallback | AST: replace `dict.get(key)` with `dict[key]` |
|
| 54 |
+
| 5 | `empty_return` | Function returns `None` prematurely | AST: insert `return None` early |
|
| 55 |
+
|
| 56 |
+
### 🟡 Medium – Off‑By‑One, Loop Logic & Simple Arithmetic
|
| 57 |
+
|
| 58 |
+
| # | Bug ID | What’s wrong | Injection method |
|
| 59 |
+
|---|--------|--------------|------------------|
|
| 60 |
+
| 6 | `off_by_one` | `range(x)` becomes `range(1, x-1)` – skips first & last | AST: modify range arguments |
|
| 61 |
+
| 7 | `loop_skip` | `range(len(arr))` becomes `range(len(arr)-1)` – misses last element | AST: change range length |
|
| 62 |
+
| 8 | `sign_error` | `sum += item` turned into `sum -= item` | AST: swap Add / Sub |
|
| 63 |
+
| 9 | `swap_args` | Function arguments swapped | AST: swap first two arguments |
|
| 64 |
+
|10 | `uninitialised_var` | Variable used before assignment in a loop | AST: remove the assignment statement |
|
| 65 |
+
|
| 66 |
+
### 🟠 Hard – Division‑By‑Zero, Floating‑Point & Edge Cases
|
| 67 |
+
|
| 68 |
+
| # | Bug ID | What’s wrong | Injection method |
|
| 69 |
+
|---|--------|--------------|------------------|
|
| 70 |
+
|11 | `division_by_zero_empty` | Empty‑list guard removed before averaging | AST: delete `if not data:` |
|
| 71 |
+
|12 | `division_by_zero_zero` | Denominator check removed | AST: remove the zero‑check |
|
| 72 |
+
|13 | `float_precision` | True division `/` replaced by integer division `//` | AST: change Div → FloorDiv |
|
| 73 |
+
|14 | `abs_usage` | `abs()` call removed when comparing differences | AST: delete `abs()` wrapper |
|
| 74 |
+
|15 | `round_error` | `round()` placed too early, causing precision drift | AST: inject `round()` prematurely |
|
| 75 |
+
|
| 76 |
+
### 🔴 Harder – Race Conditions & Atomicity Bugs
|
| 77 |
+
|
| 78 |
+
| # | Bug ID | What’s wrong | Injection method |
|
| 79 |
+
|---|--------|--------------|------------------|
|
| 80 |
+
|16 | `missing_lock` | Shared counter incremented without a lock | Template: remove `with lock:` |
|
| 81 |
+
|17 | `double_lock` | Acquiring the same lock twice → deadlock risk | Template: add extra `lock.acquire()` |
|
| 82 |
+
|18 | `global_nonatomic` | `count = count + 1` (read‑modify‑write) instead of `+=` | AST: modify assignment node |
|
| 83 |
+
|19 | `thread_safe_list` | List append across threads without synchronisation | Template: remove lock from list operation |
|
| 84 |
+
|20 | `volatile_read` | Shared flag read outside a lock → stale value | Template: remove synchronisation block |
|
| 85 |
+
|
| 86 |
+
### ⚫ Hardest – Deadlocks, Ordering & Complex Concurrency
|
| 87 |
+
|
| 88 |
+
| # | Bug ID | What’s wrong | Injection method |
|
| 89 |
+
|---|--------|--------------|------------------|
|
| 90 |
+
|21 | `deadlock_order` | Locks acquired in opposite order in two threads | Template: swap lock order |
|
| 91 |
+
|22 | `nested_lock_timeout` | `lock.acquire()` without a timeout → permanent hang | Template: remove timeout logic |
|
| 92 |
+
|23 | `fork_join` | Thread started but not joined (`join()` missing) | AST: remove `thread.join()` |
|
| 93 |
+
|24 | `mutex_release` | Lock released by a thread that never acquired it | Template: incorrect release logic |
|
| 94 |
+
|25 | `race_on_init` | Shared resource initialised after threads have started | Template: move initialisation after `join()` |
|
| 95 |
## Deployment
|
| 96 |
|
| 97 |
```bash
|