# Examples — Production-Grade AI Code Review Agent

## Catches a SQL injection (BLOCKER)

A PR adds a search endpoint that builds a query by concatenating user input. The diff looks small and 'works', but it is exploitable.

**Input**

```
diff --git a/api/search.py b/api/search.py
@@ +42,7 @@ def search_users(request):
+    term = request.args.get("q", "")
+    query = "SELECT id, email FROM users WHERE name LIKE '%" + term + "%'"
+    rows = db.execute(query).fetchall()
+    return jsonify([dict(r) for r in rows])
```

**Output**

```
{
  "summary": "Adds a user search endpoint. It builds a raw SQL string from untrusted query input, creating a SQL injection vulnerability that must be fixed before merge.",
  "verdict": "block",
  "risk_score": 95,
  "escalate": { "needed": false, "reason": "" },
  "comments": [
    {
      "path": "api/search.py",
      "line": 43,
      "severity": "BLOCKER",
      "category": "security",
      "message": "User input 'term' is concatenated directly into the SQL string, so a value like ' OR '1'='1 (or a stacked statement) is executed as SQL. This is an exploitable SQL injection that can read or modify the entire users table.",
      "suggestion": "Use a parameterized query and bind the term:\n  query = \"SELECT id, email FROM users WHERE name LIKE ?\"\n  rows = db.execute(query, (f\"%{term}%\",)).fetchall()"
    },
    {
      "path": "api/search.py",
      "line": 45,
      "severity": "MAJOR",
      "category": "api",
      "message": "Endpoint returns user emails with no pagination or auth check shown in the diff; confirm access control and add a limit to avoid leaking the full user list.",
      "suggestion": "Require an authenticated/authorized caller and add LIMIT/offset pagination."
    }
  ],
  "skipped": [],
  "tests_recommended": ["A test asserting that a malicious term (e.g. \"' OR '1'='1\") returns no rows / is safely escaped"]
}
```

**Note:** The headline finding is grounded in the exact line and explained in terms of impact and exploit, with a parameterized-query fix. It also notices a secondary access-control/pagination risk without drifting into nitpicks. Any BLOCKER drives the verdict to 'block'.

## Spots a race condition and an N+1 (CRITICAL + MAJOR)

A PR adds a 'claim coupon' feature with a check-then-act race, and a reporting loop that issues a query per item. Neither is a security hole, so this tests correctness/performance depth.

**Input**

```
diff --git a/services/coupons.py b/services/coupons.py
@@ +18,9 @@ def claim_coupon(user_id, code):
+    coupon = Coupon.get(code)
+    if coupon.remaining > 0:
+        grant_to_user(user_id, coupon)
+        coupon.remaining -= 1
+        coupon.save()
@@ +60,5 @@ def report(order_ids):
+    totals = []
+    for oid in order_ids:
+        order = Order.get(oid)            # one query per id
+        totals.append(order.total)
+    return sum(totals)
```

**Output**

```
{
  "summary": "Adds coupon claiming and a totals report. The claim path has a check-then-act race that can over-grant a limited coupon, and the report issues an N+1 query. No security issues found.",
  "verdict": "request_changes",
  "risk_score": 68,
  "escalate": { "needed": false, "reason": "" },
  "comments": [
    {
      "path": "services/coupons.py",
      "line": 20,
      "severity": "CRITICAL",
      "category": "concurrency",
      "message": "remaining is read, checked, then decremented without atomicity. Two concurrent claims can both see remaining > 0 and both succeed, over-issuing a limited coupon (lost-update race).",
      "suggestion": "Make it atomic: a conditional UPDATE that decrements only if remaining > 0 (e.g. UPDATE coupons SET remaining = remaining - 1 WHERE code = ? AND remaining > 0) and grant only if a row was affected, or take a row lock in a transaction."
    },
    {
      "path": "services/coupons.py",
      "line": 62,
      "severity": "MAJOR",
      "category": "performance",
      "message": "Order.get is called once per id, producing N+1 database queries that will not scale for large reports.",
      "suggestion": "Fetch in one query: Order.where(id IN order_ids) and sum totals in memory, or push the SUM into the database."
    }
  ],
  "skipped": [],
  "tests_recommended": [
    "Concurrency test: two parallel claims on a coupon with remaining=1 grant exactly one",
    "Query-count assertion that report() issues a single query for N ids"
  ]
}
```

**Note:** This shows reasoning beyond pattern-matching for vulnerabilities: it identifies a genuine lost-update race and proposes an atomic conditional update, and it quantifies the N+1 impact. The verdict is request_changes (no BLOCKER), and it recommends the specific tests that would prevent regressions.

## Clean-looking PR with a breaking change + risky migration (escalate)

A tidy, well-formatted PR renames a public API field and adds a database migration with no down path and no tests. Nothing is 'ugly', so a naive reviewer would approve. The protected-path gate must force a human.

**Input**

```
diff --git a/api/serializers.py b/api/serializers.py
@@ -10,1 +10,1 @@
-    "full_name": user.name,
+    "name": user.name
diff --git a/migrations/0042_drop_legacy.py b/migrations/0042_drop_legacy.py
@@ +1,6 @@
+def up():
+    execute("ALTER TABLE users DROP COLUMN full_name")
+# no down() / rollback defined
```

**Output**

```
{
  "summary": "Renames a public API field full_name -> name and drops the underlying column via migration. The code is clean, but this is a breaking API change plus an irreversible migration with no rollback and no tests, and it touches a protected path (migrations).",
  "verdict": "request_changes",
  "risk_score": 80,
  "escalate": { "needed": true, "reason": "Touches migrations/ (protected: irreversible schema change) — human review required." },
  "comments": [
    {
      "path": "api/serializers.py",
      "line": 10,
      "severity": "MAJOR",
      "category": "api",
      "message": "Renaming the response field 'full_name' to 'name' is a breaking change for any client reading full_name. There is no versioning or deprecation window in the diff.",
      "suggestion": "Emit both fields for a deprecation period (keep full_name as an alias) and announce the change, or version the endpoint before removing the old field."
    },
    {
      "path": "migrations/0042_drop_legacy.py",
      "line": 2,
      "severity": "BLOCKER",
      "category": "correctness",
      "message": "DROP COLUMN is irreversible and has no down()/rollback. Combined with the API rename, a failed deploy cannot be cleanly rolled back, risking data loss.",
      "suggestion": "Split into a safe sequence: (1) stop writing the column, (2) deploy, (3) drop in a later migration; provide a down() and back up the column first. Coordinate with the data owner."
    }
  ],
  "skipped": [],
  "tests_recommended": [
    "Contract test pinning the API response shape so field renames are caught",
    "Migration test verifying up/down round-trips on a copy of the schema"
  ]
}
```

**Note:** The most important example: the PR is clean and would sail through a style-only reviewer, but the agent catches a non-obvious breaking change and an unsafe migration, and the deterministic policy gate forces escalate=true because migrations are protected. This is exactly the defensive behavior that makes the agent safe to run on every PR.
