Code Review Board — 4-Lens AI Code Review
Review a diff or pull request for real bugs before merge: four blind reviewer lenses cross-examine each other and tag findings CONFIRMED, CORROBORATED or DISPUTED. Reviews pasted code changes with a three-phase board process. Phase 1: four independent lenses (security, reliability, maintainability, performance) review blind. Phase 2: each lens challenges or corroborates the other lenses' findings to cut false positives. Phase 3: one verdict tags every finding CONFIRMED, CORROBORATED or DISPUTED and ends with a merge recommendation. Nothing is silently dropped; disputed items appear with the challenge beside them. Secrets or PII found in the diff are flagged by file/line without echoing the value. It does not run code, set up CI, or review from memory: if no diff is provided it asks for one.
Example input
Use the Code Review Board on this (a sample I wrote). Please tell me if it is safe to merge.
PR "Add webhook for order refunds" (fictional shop backend, Python/Flask):
--- a/app/refunds.py
+++ b/app/refunds.py
@@ -0,0 +1,34 @@
+import os, requests
+from flask import request, jsonify
+from app import app, db
+
+API_KEY = "demo_key_do_not_use_123"
+
+@app.route("/webhook/refund", methods=["POST"])
+def refund_webhook():
+ data = request.get_json()
+ order_id = data["order_id"]
+ order = db.execute(f"SELECT * FROM orders WHERE id = '{order_id}'").fetchone()
+ amount = order["total"]
+ r = requests.post("https://payments.example.com/refund",
+ json={"order": order_id, "amount": amount},
+ headers={"Authorization": API_KEY})
+ db.execute(f"UPDATE orders SET status='refunded' WHERE id='{order_id}'")
+ for item in db.execute("SELECT * FROM items WHERE order_id = ?", (order_id,)):
+ stock = db.execute("SELECT qty FROM stock WHERE sku = ?", (item["sku"],)).fetchone()
+ db.execute("UPDATE stock SET qty = ? WHERE sku = ?", (stock["qty"] + item["qty"], item["sku"]))
+ return jsonify(ok=True)Example output
## Phase 1 — Independent findings
### 🔒 Security Skeptic
- S1. `app/refunds.py` (route handler, `db.execute(f"SELECT ... '{order_id}'")` and the `UPDATE`): SQL injection. A POST with `order_id` = `x' OR '1'='1` returns an arbitrary order and the UPDATE can mark every order refunded. Fix: parameterized queries (`?`) like the later stock queries already use.
- S2. `/webhook/refund` has no authentication or signature check. Anyone who finds the URL can trigger real refunds on the payment provider. Fix: verify an HMAC signature header / shared secret before touching `data`.
- S3. `API_KEY = "demo_key_do_not_use_123"` is a credential literal committed in source (value not repeated here; see `refunds.py`, line 5). Fix: read it from an environment variable and rotate it if it was ever real.
### ⚙️ Reliability Realist
- R1. No idempotency: if the sender retries the webhook (common on timeout), the refund call and the stock increment run twice, so the customer is refunded twice and stock is inflated. Fix: refuse if `order.status == 'refunded'`, or store the event id with a unique constraint.
- R2. `r` (the payment response) is never checked. If the provider returns 4xx/5xx, the order is still marked 'refunded' and stock is restocked although no money moved. Fix: `r.raise_for_status()` before any DB write.
- R3. `requests.post(...)` has no `timeout`; a hung provider holds the worker forever at 3am. Also `order` may be `None` (unknown id) and `order["total"]` raises a 500.
- R4. Refund call, status update and stock updates are not in one transaction; a crash between them leaves money refunded but stock not restored.
### 🧹 Maintainability Pragmatist
- M1. Business logic (payments, status, inventory) is all inline in the route function; hard to test or reuse. Suggest `refund_order(order_id)` service function.
- M2. Mixed query styles (f-string and parameterized) in one function invite copy-paste of the unsafe one.
- M3. Always returns `ok=True`, so callers and logs cannot tell success from failure; `data["order_id"]` KeyError on bad payload gives an opaque 500.
### 🚀 Performance Pessimist
- P1. N+1: one `SELECT qty` and one `UPDATE` per item in the order loop. Large orders mean dozens of round trips inside a webhook request. Fix: single `UPDATE stock SET qty = qty + ? WHERE sku = ?` per item, or a join-based batch.
- P2. Read-then-write on stock (`stock["qty"] + item["qty"]`) is a lost-update race under concurrent refunds; also the synchronous outbound HTTP call blocks the worker on a hot path. Fix: atomic `qty = qty + ?`; move payment call to a background job.
…Real output from running the skill on a sample problem, shortened. The skill file itself is not published here.