Harness published — no results yetThe apparatus is built and reproducible. It has not been run here, so there are no measurements on this page and none are implied.
Original research
A Seeded-Defect Corpus for Testing AI Code Review
Ten deliberately planted defects with a machine-readable answer key and a scoring harness, so claims about what AI review catches can be checked rather than asserted.
The question
Of ten deliberately seeded defects across seven categories, how many does an AI code reviewer find — and how many of its findings come with a reproduction rather than a hedge?
Environment
- Python 3.11+
- Corpus: projects/copilot-code-review-corpus/ in this repository
- Answer key: ANSWER_KEY.json, 10 defects, 7 categories
The problem with “it catches security issues”
Claims about AI code review are almost always unfalsifiable. There is no corpus, no ground truth, and no way to check. This is the apparatus that makes the claim testable, and it is deliberately unglamorous.
What is in the corpus
src/orders.py — one file, ten seeded defects across seven categories:
| ID | Category | Severity | Defect |
|---|---|---|---|
| D01 | Injection | Critical | SQL built by concatenation |
| D02 | Path traversal | Critical | User segment joined into a path unchecked |
| D03 | Crypto | High | Secret compared with == |
| D04 | Injection | Critical | Shell command concatenated with shell=True |
| D05 | Crypto | Medium | MD5 for an identifier — arguable, scored separately |
| D06 | Concurrency | High | Check-then-act without the lock |
| D07 | Correctness | High | Decimal round-tripped through float |
| D08 | Resource | Medium | File handle leaked on the error path |
| D09 | Authorization | Critical | user_id accepted and never checked |
| D10 | Error handling | Medium | Bare except returns a valid-looking 0 |
Every trigger in the answer key has been executed and confirmed, except D06, which is timing-dependent by nature and marked as such.
That verification mattered. The first draft of D07 claimed
Decimal("0.70") less 10% would not yield exactly 0.63. Running it showed it
does — the float round-trip happens to land exactly there. A sweep of 4,000
values found real divergences, and the key now reads
Decimal("0.01") less 10% → 0.009000000000000001. A corpus with an
untriggerable answer is a broken corpus, and the only way to know is to run it.
The three scoring rules
A finding without a trigger is not a hit. “This may be vulnerable to SQL
injection” and “an order_id of ' OR '1'='1 returns every row” cost the same
to produce and differ entirely in usefulness. Requiring the trigger is what
separates a review from a list of adjectives.
Recall and precision are reported separately, never folded into one score. A reviewer that finds everything and flags twelve non-issues is a different problem from one that finds half and flags nothing, and one number hides which you have.
D05 is excluded from the headline. Whether MD5 for a non-security identifier is a defect is genuinely arguable. Counting it either way bakes an opinion into the ground truth, so it is reported on its own line.
Running it
cd projects/copilot-code-review-corpus
# point your reviewer at src/orders.py, then:
python score.py findings.jsonSample output, from a deliberately partial run used to test the scorer itself:
Scored defects: 9 (excluded as arguable: ['D05'])
Found with a trigger 4 / 9 recall 44%
Reported without one 1 ['D03']
Not in the answer key 1 (false positives, or real defects we did not seed)
Precision 80%That output is the scorer being tested, not a code review tool being measured. It used hand-written findings to confirm the harness rejects an unsupported claim and flags an unknown id.
What a good result looks like
Not 10/10. The interesting signal is which defects a reviewer misses.
The three injection and traversal defects are pattern-matchable and most tools find them. D06, D07 and D08 are the discriminating ones — a race condition, a decimal round-trip and a leaked handle on an error path all require reasoning about execution rather than recognising a shape.
A reviewer that finds the four critical defects and misses all three of those is a reviewer that reads code the way a linter does, which is worth knowing before you put it in front of a pull request.
Limitations
What this cannot tell you. Stated in the frontmatter so it cannot be dropped in an edit.
- No results are published on this page. GitHub Copilot is not available in the environment where this site is built, so the experiment has not been run here and no measurement is implied.
- Ten defects in one file is a small corpus. It is enough to distinguish a reviewer that reads error paths from one that does not; it is not enough to rank two reviewers that both score well.
- The defects are seeded, which means they are findable by construction. Real defects hide in code someone believed was correct.
- D06 (a check-then-act race) is timing-dependent and may not reproduce on a single run. It is marked as such in the answer key.
- Scoring rewards a stated trigger. A reviewer that identifies a real defect but cannot say how to reproduce it scores as unsupported, which is a deliberate editorial choice rather than a neutral measurement.
Reproduce this
Clone projects/copilot-code-review-corpus/, point any reviewer at src/orders.py, ask for findings with a concrete triggering input for each, write them to findings.json in the documented shape, then run `python score.py findings.json`. The harness reports recall and precision separately and lists what was missed.
Raw results: /research-data/code-review-answer-key.json
Sources
Every version-sensitive claim on this page was checked against first-party documentation. Only sources actually used are listed.
Primary sources
Cite this research
Free to use, republish and build on. A link back is appreciated and is not a condition. The one thing we ask is that theverification date travels with the numbers — several of these figures change monthly, and a table with no date on it becomes misinformation within a quarter however accurate it was when copied.
Plain citation
The Copilot Stack. "A Seeded-Defect Corpus for Testing AI Code Review." Version 2026-09-04. https://thecopilotstack.com/research/code-review-corpus/ (verified 2026-09-04).Markdown
[The Copilot Stack — A Seeded-Defect Corpus for Testing AI Code Review](https://thecopilotstack.com/research/code-review-corpus/) (verified 2026-09-04)BibTeX
@misc{copilotstack_research-code-review-corpus_2026,
title = {A Seeded-Defect Corpus for Testing AI Code Review},
author = {{The Copilot Stack}},
year = {2026},
note = {Version 2026-09-04. Maintained research, not peer reviewed},
howpublished = {\url{https://thecopilotstack.com/research/code-review-corpus/}},
urldate = {2026-09-04}
}@misc rather than @article or@dataset, and the note records that this is a maintained research that has not been peer reviewed. Formatting it as a journal reference would imply a review process that did not happen.
Licence. Free to reuse for any purpose, including commercially. This is original work by The Copilot Stack — the method, the harness and the results — and it has not been peer reviewed.
Share this
https://thecopilotstack.com/research/code-review-corpus/
Was this lesson helpful?
We record which lesson you rated and whether it helped. Nothing identifies you — no account, no cookie, no session.