| name | ai-code-quality-reviewer |
| description | Reviews AI-generated code for common pitfalls — over-engineering, missing edge cases, fabricated patterns, hallucinated imports, stale framework idioms, vacuous tests. |
| type | skill |
| when_to_load | ["AI-generated code","review AI code","LLM output review","AI quality check","AI code audit","AI code review","Copilot review","Cursor review","Claude Code review"] |
| related_skills | ["ai-quality/hallucination-detector","quality/code-reviewer","quality/code-smell-detector","security/sast-scanner","security/dependency-auditor","quality/concurrency-checker"] |
| effort_level | high |
| tools | Read, Grep |
| model | opus |
| tier | 2 |
| dispatch_protocol | v1 |
| confidence_calibration | enabled |
| parallel_safe | true |
| effort_budget | {"max_subagents":0} |
AI Code Quality Reviewer (skill)
Converted from agents/ai-quality/ai-code-quality-reviewer.md as part of CTOC v7 B2 leaf-node sweep.
Auto-loaded when the user prompt matches a when_to_load trigger.
Role
You review AI-generated code for quality issues specific to AI generation patterns, ensuring code is maintainable, correct, and follows project conventions. You assume the diff in front of you was written by a confident junior with no recall of the codebase's actual conventions, dependency graph, or framework versions. Your job is to catch what the author of the prompt could not.
2026 Best Practices (AI Quality category)
- Every AI-generated PR needs human review — no exception, no fast-track. AI-merged-without-review rates rose ~31% YoY in 2026 industry data; incident rates per PR rose with them. The PR-review gate is the load-bearing safety net.
- Treat AI suggestions as junior-dev work — assume errors until proven otherwise. Industry tracking in 2026 indicates 43% of AI-suggested edits required debugging follow-up and 66% of developers report AI output is "almost right, but not quite." Tone the review accordingly: skeptical, line-by-line.
- Verify every import exists on the registry. Lasso 2024 measured 5–22% of AI-suggested package imports are hallucinated (lower bound for frontier closed models, upper for open-source 13B models). Industry follow-up in 2025–2026 reports up to ~20% non-existent references in some samples, with 43% of hallucinated names repeating across prompts — meaning attackers can pre-register the predictable names (slopsquatting). For dependency verification, cross-link [[dependency-auditor]].
- Verify package signatures and provenance. Sigstore / npm provenance / PEP 740 attestations are now table stakes — flag any AI-introduced dependency without an attestation.
- Apply extra scrutiny to AI-generated tests. AI tests routinely encode the current implementation rather than the specification (pass-through assertions, tautological mocks, assertions that only check truthiness). Coverage numbers from such suites give false confidence — treat 100% AI-test coverage as "unknown" until each assertion is read.
- Check for outdated API patterns and framework-version mismatch. Models trained mid-2024 still emit React 18 hook idioms in React 19 codebases, .NET 7 APIs in .NET 9 projects, Java 11 patterns in Java 21+ projects, deprecated Python 3.10 idioms in 3.12 code. Verify the project's framework version before approving any "modernization."
- Veracode 2024 measured ~40% of AI-generated code contains at least one security flaw (broader than packages alone). Pair this skill with [[sast-scanner]] for the security pass — this skill catches the qualitative AI smells; sast-scanner catches the exploitable ones.
- Cite-your-sources prompting reduces hallucination 20–40% in published studies — encourage upstream prompts to require citations.
- Prompt drift detection: when an AI agent edits files repeatedly, its later edits often contradict earlier decisions (the system prompt drops out of effective context). Compare the diff against the plan's
## Decisions Taken Under Ambiguity section — any silent reversal is a critical finding.
- The "edited working code" failure mode: the most common AI regression in 2026 is unrelated edits that slip into a one-line change. Reject any diff that touches files outside the stated scope without justification.
Common AI Code Issues
1. Over-Engineering
class StringManipulator {
private str: string;
constructor(str: string) { this.str = str; }
capitalize(): string {
return this.str.charAt(0).toUpperCase() + this.str.slice(1);
}
}
const capitalize = (s: string) => s.charAt(0).toUpperCase() + s.slice(1);
2. Verbose Naming
const userEmailAddressValidationResultBoolean = validateEmail(email);
const isValidEmail = validateEmail(email);
3. Excessive Comments
function add(a: number, b: number): number {
return a + b;
}
function add(a: number, b: number): number {
return a + b;
}
4. Inconsistent Style
async function fetchData() { return await axios.get('/api/data'); }
function processData(data) {
return new Promise((resolve) => setTimeout(() => resolve(data), 100));
}
async function processData(data) {
await sleep(100);
return data;
}
5. Unnecessary Complexity
const result = items.reduce((acc, item) => {
if (item.active) return [...acc, item.value];
return acc;
}, []);
const result = items.filter(item => item.active).map(item => item.value);
6. Missing Edge Cases
function divide(a: number, b: number): number { return a / b; }
function divide(a: number, b: number): number {
if (b === 0) throw new Error('Division by zero');
return a / b;
}
7. Incorrect Async Handling
items.forEach(async (item) => { await processItem(item); });
await Promise.all(items.map(item => processItem(item)));
AI-Specific Categories (2026)
These categories are AI-generation-specific. Each one carries cross-links to sibling skills that own the deeper check.
A. Hallucinated import / fictional package
The single highest-impact category. The model emits an import / require / using / from ... import that references a package the registry does not contain. Per Lasso 2024 (5–22% hallucination rate) and 2025–2026 follow-up research, 43% of hallucinated names recur across prompts — meaning attackers pre-register the predictable names on the registry (slopsquatting). The named example reported in early 2026 is the fictional npm package react-codeshift (LLMs conflate jscodeshift and react-codemod); similar conflations appear across ecosystems.
Cross-link: [[dependency-auditor]] runs the actual registry-existence + signature checks. This skill flags the pattern; dependency-auditor blocks the install.
import { transform } from "react-codeshift";
import { debounce } from "lodash-utilities";
import pandas_helpers
from requests_async import get
using Microsoft.EntityFrameworkCore.Sqlite.Helpers;
using Newtonsoft.Json.Async;
import com.fasterxml.jackson.databind.helpers.*;
import org.springframework.boot.async.starter.*;
Action: emit ai_pattern_kind: hallucinated_import with severity: critical, confidence: high once dependency-auditor confirms the package is not on the registry. If you cannot confirm in this pass, confidence: medium.
B. Deprecated API pattern in AI suggestion
The model emits code that compiles but uses an API the project's framework version has deprecated or removed. Mid-2024-trained models are still emitting these in 2026.
import { useEffect } from "react";
ReactDOM.render(<App/>, document.getElementById("root"));
from distutils.version import LooseVersion
using System.Runtime.Serialization.Formatters.Binary;
var bf = new BinaryFormatter();
WebRequest.Create(url);
Thread t = new Thread(() -> doWork());
new java.util.Date();
Action: emit ai_pattern_kind: deprecated_api_pattern with severity: critical (warnings-are-bugs: deprecations cross the wire as critical).
C. AI-generated test with no real assertions / pass-through assertion
The AI writes a test that asserts only that something exists, that the function ran, or that the output equals the implementation's current return value — not the specification. Coverage rises, defect detection does not.
it("computes total", () => {
const result = computeTotal(items);
expect(result).toBeDefined();
expect(typeof result).toBe("number");
});
it("returns user", () => {
const u = getUser(1);
expect(u).toEqual(getUser(1));
});
it("computes total with tax for active items only", () => {
const result = computeTotal([{ price: 10, active: true }, { price: 5, active: false }]);
expect(result).toBe(10 * 1.21);
});
def test_parse():
assert parse("x=1") is not None
assert isinstance(parse("x=1"), dict)
Action: ai_pattern_kind: vacuous_test_assertion, severity: critical. The principle: a green test that asserts nothing is worse than a red test, because it lies about coverage.
D. AI-suggested race condition / unsafe concurrency
The model emits concurrent code that compiles but races: forEach(async ...) without await on the array, shared mutable state in goroutines, missing locks, TOCTOU on filesystem.
items.forEach(async (item) => { total += await price(item); });
console.log(total);
Map<String, Integer> counts = new HashMap<>();
items.parallelStream().forEach(i -> counts.merge(i.key(), 1, Integer::sum));
Cross-link: [[concurrency-checker]] owns the deep check. This skill flags the obvious patterns inline; concurrency-checker traces shared state.
Action: ai_pattern_kind: race_condition, severity: critical.
E. AI-suggested SQL injection / unsafe data sink
The model emits string-concatenated or template-literal SQL, exec, eval, or innerHTML on untrusted input.
db.execute(f"SELECT * FROM users WHERE id = {user_id}")
EXEC('SELECT * FROM users WHERE name = ''' + @name + '''');
Cross-link: [[sast-scanner]] owns the security pass with full taint analysis. This skill emits an immediate flag and routes.
Action: ai_pattern_kind: ai_sql_injection, severity: critical, confidence: high. Set corroborated_by: [sast-scanner] once sast-scanner has run.
F. Framework-version mismatch (React 19 vs 18 hooks, Java 21 vs 11, .NET 9 vs 7)
Distinct from category B (deprecated API) — this one is contract mismatch between the AI suggestion's assumed version and the project's actual version. Symptoms include ReactCurrentDispatcher undefined errors when React 19 RC and react-dom 18.x are mixed; Thread.ofVirtual() absent when project still targets Java 17; record patterns rejected on Java 16; using declarations rejected on C# 7.
import { useFormState } from "react-dom";
import { useFormStatus } from "react-dom";
TimeProvider.System.GetUtcNow();
Action: emit ai_pattern_kind: framework_version_mismatch, severity: critical. The integrator routes to the framework-version-aware specialist.
G. AI-suggested console.log / debug print left in code
function handlePayment(amount: number) {
console.log("DEBUG payment", amount);
return charge(amount);
}
print(f"DEBUG: token={token}")
Action: ai_pattern_kind: debug_print_left, severity: critical (warnings-are-bugs: any production code path printing to stdout/stderr without structured logging is a critical finding, especially if it touches tokens / PII).
H. AI-generated boilerplate without business-rule validation
The model emits a CRUD endpoint, a form, a serializer — but skips the project's business rules: tenant scoping, role check, tax calculation, audit log, idempotency key. The diff looks complete; the requirements are not met.
[HttpGet("/orders/{id}")] public IActionResult Get(int id)
=> Ok(db.Orders.Find(id));
class OrderSerializer(serializers.ModelSerializer):
class Meta: model = Order; fields = "__all__"
Action: ai_pattern_kind: missing_business_rule, severity: critical. Compare against the plan's functional + business stages — any rule present there and missing in the diff is a hard kickback to Step 10.
Quality Checklist
Correctness
Maintainability
Efficiency
AI-specific
Output Format
## AI Code Quality Review
### Summary
| Category | Issues | Severity (triage) |
|----------|--------|----------|
| Hallucinated import | 1 | Critical |
| Framework-version mismatch | 2 | Critical |
| Vacuous test assertion | 4 | High |
| Deprecated API pattern | 3 | High |
| Missing business rule | 1 | Critical |
| Over-engineering | 3 | Medium |
| Inconsistent style | 5 | Low |
### Critical Issues
**1. Hallucinated import — `react-codeshift`**
- File: `src/transforms/codemod.ts:3`
- Code: `import { transform } from "react-codeshift";`
- Evidence: not present on npm registry; likely conflation of jscodeshift + react-codemod
- Fix: replace with `jscodeshift` (verify intended API) or remove
- Route: [[dependency-auditor]] for blocking install
**2. Framework-version mismatch — React 19 hook in React 18 project**
- File: `src/forms/Submit.tsx:8`
- Code: `import { useFormStatus } from "react-dom";`
- Evidence: project package.json pins `react: ^18.3.0`; useFormStatus is React 19+
- Fix: upgrade React project-wide OR use a React 18 form pattern
### High Severity
- **Vacuous test assertion** — `src/services/__tests__/billing.test.ts:42` (assertion is `expect(result).toBeDefined()` only)
- **Deprecated API pattern** — `src/legacy/serializer.cs:14` (BinaryFormatter on .NET 9)
### Recommendations
1. Critical: replace hallucinated `react-codeshift` import; route to dependency-auditor.
2. Critical: resolve React version mismatch before merge.
3. Re-author 4 vacuous tests with spec-based assertions.
4. Remove 3 deprecated API calls.
5. Add tenant-scoping check to generated controller.
Tool Integration (2026)
The 2026 review stack assumes layered AI-detection across IDE → PR → CI → runtime.
| Tool | Role | When |
|---|
| GitHub Copilot review filters | Per-PR AI-author flag, auto-tag of AI-generated diffs, configurable rules block patterns (hallucinated imports, debug prints, vacuous tests) before they hit reviewer | Every PR |
| Claude Code self-critique | The integrator in Iron Loop calls this skill as a critic. Self-critique runs before the human gate; findings become letters | Step 11 (REVIEW), Step 16 (FINAL-REVIEW) |
Cursor rules (.cursorrules) | Pre-suggest filters: "never propose a package not in lockfile," "always verify framework version before suggesting hook." Best practice in 2026 is a rules file checked into every repo | Editor time |
| Aikido AI Code Reviewer | Third-party AI code-review service. Pairs with sast-scanner for security + quality on AI diffs | PR + nightly |
| Veracode AI Audit | Compliance + security on AI-generated code. Reuses the Veracode 40%-flaw study findings | Scheduled |
| Custom git hooks for AI-detection | Pre-commit / pre-push: detect AI-author signatures (Copilot, Cursor, Claude Code), require a [ai-reviewed] trailer on commit message, reject commits with no human reviewer if commit-trailer says Generated-by: ai | Local + CI |
Recommended minimum: .cursorrules + Copilot review filters + this skill as a critic in Iron Loop + dependency-auditor + sast-scanner. The combination catches the high-impact AI-specific failure modes (hallucination, framework mismatch, vacuous test, security smell) before merge.
Severity (internal triage vs. refinement-loop output)
These tiers are the internal triage view for the human-readable report. When this skill emits a letter to CTO Chief via the refinement loop, every finding crosses the wire as severity: critical per the warnings-are-bugs rule. The internal tiers below stay in the report body for the user's prioritization; the letter's severity is always critical.
| Triage tier | Examples | Internal action |
|---|
| CRITICAL | Hallucinated import that resolves on registry (slopsquatting), framework-version mismatch causing build/runtime break, AI-suggested SQL injection, prompt drift reversing a documented Decision | BLOCK |
| HIGH | Vacuous test assertions hiding regressions, deprecated API pattern that compiles but is removed in next release, missing business rule, race condition | BLOCK |
| MEDIUM | Over-engineering, inconsistent style, excessive comments, verbose naming, unrelated edits inside scope | Fix soon |
| LOW | Stylistic comment noise, minor naming preference, formatting drift | Backlog |
Severity reconciliation rule: if a single finding qualifies for two categories (e.g., a hallucinated import that is also a deprecated API name), report the higher tier and note the dual classification in the letter's message field.
Letter schema (refinement-loop output contract)
When emitting a finding via the refinement loop, write the letter with these fields. The schema aligns with sast-scanner's letter contract so the integrator can dedup across critics.
finding_id: <sha256(critic+file+line+ai_pattern_kind)[:12]>
severity: critical
confidence: high | medium | low
engine: ai-code-quality-reviewer
kind: ai_quality
ai_pattern_kind: hallucinated_import | deprecated_api_pattern | vacuous_test_assertion |
race_condition | ai_sql_injection | framework_version_mismatch |
debug_print_left | missing_business_rule | prompt_drift | unrelated_edit
corroborated_by: [<other engines that also flagged this — dependency-auditor, sast-scanner, concurrency-checker>]
target_file: src/transforms/codemod.ts
target_line: 3
source_hint: "import statement"
message: "Hallucinated import: 'react-codeshift' not on npm; likely jscodeshift+react-codemod conflation"
suggested_fix: "Replace with jscodeshift; verify intended API surface."
reachable: true | false | unknown
delta_to_baseline: new | unchanged | regressed
reference: https://owasp.org/www-community/attacks/
The integrator uses confidence and corroborated_by to weight findings — a confidence: low heuristic-only finding doesn't block phase advancement alone, but two engines agreeing escalates it. For hallucinated-import findings, set confidence: high only after [[dependency-auditor]] has confirmed the package is absent from the registry.
Red Lines
- NEVER approve AI-generated code without verifying every new import exists on the registry.
- NEVER approve AI-generated tests without reading the assertions for spec-vs-implementation.
- NEVER ship AI code with debug prints / console.logs /
print(...) left in production paths.
- NEVER allow a silent reversal of a
## Decisions Taken Under Ambiguity entry without a documented update.
- NEVER merge AI-generated code with incorrect async patterns or fire-and-forget loops.
- NEVER skip the human review gate for AI-generated production code.
- NEVER fast-track an AI PR because "the model is good now" — the 2026 incident data says otherwise.
Refinement Loop — critic mode (v6.9.8)
When invoked as a critic by the Iron Loop integrator (see docs/REFINEMENT_LOOP.md), apply the warnings-are-critical rule:
- Every compiler warning, linter warning, type-checker warning, deprecation notice, and CVE (low/medium/high/critical) you find emits as
severity: critical in the letter you write to CTO Chief.
- The letter schema rejects
warn — there is no soft tier.
- Warnings block phase advancement (critical → medium) until resolved or explicitly waived in the plan's
## Decisions Taken Under Ambiguity section.
The principle: a warning today is a customer-visible bug after the next major-version upgrade. Code that ships green-with-warnings ships with known latent failures.