How to Review AI-Generated Code: Counterexamples Beat Green Tests
Vibe Coding has changed how quickly code appears, but review work has not become proportionally easier. A fluent model explanation or a green test suite cannot prove an implementation is safe for production.
This case is a build-time validator for animated terminal SVGs in this blog application. It checks restricted XML/CSS rules, manifest paths and SHA-256 digests, and whether articles in eight locales reference a visible demo image. A fixed canonical SVG is the positive fixture. All four defects were found in isolated pre-merge tests; the evidence covers this validator’s offline scope only.
The original suite passed 8/8, yet independent review found two unsafe acceptances. After the first fix, 10/10 passed and a second review found two more. The final pinned version passed 12/12 top-level tests; four additional independent attack probes were run separately and all rejected. Three JavaScript files also passed node —check.
I use five steps: pin scope and invariants; construct minimal counterexamples; record RED only when a real failing run exists; independently verify positive and negative cases against the exact commit; then decide by risk. Logic tests do not replace builds, platform checks, or runtime verification. For high-risk changes, record scope, Base/Head commits, invariants, positive fixture, counterexample, actual command and environment, open boundaries, and conclusion in a small evidence card. The validator is a build-time component in the blog repository, not a separately packaged general-purpose CLI. No review-time savings have been measured.
The public repository contains only sanitized synthetic counterexamples and runnable teaching tests—not this blog application’s production validator, production fixes, or internal architecture. The 8/8 → 10/10 → 12/12 sequence records the original project’s offline review; the public tests demonstrate the four defect patterns and do not reproduce the production implementation.
Sanitized examples and runnable tests
Why did 8/8 passing tests still accept invalid input?
A green suite only shows that current inputs satisfy current assertions. It does not prove every invalid input will be rejected.
The first counterexample put an allowed image and an unapproved cross-article resource reference on the same line. The old logic found one allowed image tag and passed the whole line. Independent review created a real SVG under another article slug, then appended its Markdown reference beside the valid image in the eight localized articles. The target existed, so the test did not fail merely because a file was missing. The old implementation still returned success with posts_checked=8.
<img src="/assets/terminal-demo.svg" alt="Terminal demo" width="356" height="137" /> 
The second counterexample was a filesystem race: the path checked may not be the file ultimately opened. The test swapped a parent directory at the file-open boundary. The checkout path contained wrong bytes; outside it was a canonical SVG with the expected SHA-256. After the parent became a symlink to the outside directory, the old implementation read and accepted the external file. The bypass was file provenance, not hashing.
The final Linux path opens the trusted checkout root and resolves each component relative to an already-open parent directory descriptor. Intermediate components must be directories and use O_NOFOLLOW; the final file also rejects symlinks. It checks file type, link count and size, compares device, inode and size around the read, then verifies the digest. It uses Linux /proc/self/fd handles and fails closed without procfs. This bounded guarantee assumes a trusted checkout root and available procfs; it does not cover arbitrary same-UID or host-level adversaries. See the Linux openat2(2) documentation.
Round two: the hash is right, but the content is invisible
After the first fix, 10/10 tests passed. The third counterexample involved reduced motion. SVG frames start transparent; animation reveals them. If a reduced-motion rule only stops animation without revealing the final frame, the result can be blank.
.f { opacity: 0; }
@media (prefers-reduced-motion: reduce) {
#f0 { animation: none; opacity: 1; }
#f3 { animation: none; } /* final frame stays transparent */
}
The test recalculated the full SVG SHA-256, byte size, content-addressed filename and canonical manifest so surrounding checks stayed valid. It tested the contract “the final result must be visible,” not merely whether the hash changed. MDN’s prefers-reduced-motion reference explains the preference for less nonessential motion.
The fourth counterexample came from Markdown. The old implementation counted image tags with a regex but did not exclude HTML comments. Wrapping the only image in a comment left the tag in source while rendering no image; the old logic still counted one. CommonMark 0.31.2’s HTML block rules clarify why a commented tag is not visible content.
<!-- <img src="/assets/demo.svg" alt="Terminal demo" /> -->
Bind test results to exact versions
| Code version | Main suite | Independent review that followed |
|---|---|---|
| Initial version | 8/8 passed | SEC-01 and SEC-02 unsafe acceptances |
| First-fix version | 10/10 passed | SEC-03 and SEC-04 unsafe acceptances |
| Final offline-reviewed version | 12/12 top-level tests passed | Four separate attack probes all rejected |
The final suite includes regression groups for SEC-01 through SEC-04. The four independent probes do not count toward 12/12 and must not be combined into 16/16. Three JavaScript files passed node —check, which checks syntax rather than behavior.
The latter two regression tests were committed before the source fix, but the full suite was not run on the test-only commit. There is no recorded full-suite 10/12 RED run. What is supported is that independent review reproduced unsafe acceptance in the old complete validator and the final pinned version passed its main suite plus the four separate probes.
Only after behavior is supported by evidence do I review complexity: trace helpers, branches, configuration and callers; identify each invariant; check for duplication and real consumers. Shorter code is not automatically simpler—a removed path guard can reintroduce a race.
Interactive Evidence Panel
Select a synthetic counterexample to inspect its input, invariant, reproduced failure, and evidence boundary.
Selected case: SEC-01 · Presence is not exclusivity
SEC-01 · Presence is not exclusivity
- Input condition
- An allowed image and an unapproved cross-article reference appear together.
- Invariant to preserve
- Every relevant reference must satisfy the rule; one allowed reference does not make all input safe.
- Failure reproduced by the synthetic example
- The old logic accepted the whole line after finding one allowed image, overlooking the extra reference.
- Expected correct behavior
- Check every reference and reject input if any reference crosses the boundary.
- Original review round
- Found in the first independent review
- Transferable review lesson
- Build a minimal mixed-validity counterexample and verify the entire input is checked.
SEC-02 · Check/use race
- Input condition
- After a path passes validation, a parent directory or symlink is swapped before opening.
- Invariant to preserve
- The validated object must remain the accessed object inside the intended filesystem boundary.
- Failure reproduced by the synthetic example
- Checking a path and reopening it later lets the target change between check and use.
- Expected correct behavior
- Validation and access must preserve the boundary; this synthetic example is not a production fix.
- Original review round
- Found in the first independent review
- Transferable review lesson
- Inspect the gap between validation and use for mutable state.
SEC-03 · Reduced motion must show the final frame
- Input condition
- SVG frames start transparent; reduced-motion mode stops animation.
- Invariant to preserve
- Stopping animation must not hide important final content.
- Failure reproduced by the synthetic example
- Stopping animation without revealing the final frame can leave a blank result.
- Expected correct behavior
- Reduced-motion mode must show the complete readable final state directly.
- Original review round
- Found in the second independent review
- Transferable review lesson
- Treat accessibility preference as an independent input and verify visibility.
SEC-04 · Comments are not visible content
- Input condition
- An HTML comment contains text that looks like a valid image element.
- Invariant to preserve
- Source text differs from elements actually rendered by the browser.
- Failure reproduced by the synthetic example
- Simple tag counting can count an image inside a comment as visible.
- Expected correct behavior
- Parse structure, exclude comment nodes, and assess actual rendered elements only.
- Original review round
- Found in the second independent review
- Transferable review lesson
- Put a fake tag in a comment to test structural rather than textual validation.
Public synthetic teaching evidence
The public repository reproduces synthetic defect patterns only. A passing test reproduces a failure mode; it does not prove a production fix.
Open the pinned synthetic teaching repositoryOriginal engineering offline summary
Original record: 8/8 → 10/10 → 12/12. Four independent probes ran separately and are not part of 12/12.
Verification boundary
Scope is the offline validator on Node.js v22.16.0 / Linux x64. Native macOS hostile-concurrency behavior and the full-site runtime remain unverified.
Related posts cover adjacent questions: Mutation Testing, OpenQodex’s pre-push review fail-open boundary, and Diffle’s review-comment anchors.
What remains between passing tests and production approval?
The final independent review covered the offline validator on Node.js v22.16.0, Linux x64: 12/12 top-level tests passed, four additional attack probes were rejected, canonical SVG/manifest and eight-locale bindings passed, and three JavaScript files passed node —check.
This supports a bounded conclusion: the four known unsafe acceptances were fixed in that environment and under those rules. It does not prove the whole blog is production-ready. Native macOS behavior against hostile concurrent filesystem writers remains unverified; a full site build and final page runtime check were outside the offline review.
A real release gate is layered by risk: unit tests cover asserted behavior, static checks target specific patterns, builds and integration tests verify composition, and platform/runtime checks cover deployment boundaries. If a critical boundary remains unverified, a local pass is not overall production readiness.
The point is to use contracts and counterexamples to identify suspicious behavior, then let exact-version tests and independent evidence decide where to inspect more deeply. This does not remove human judgment; it turns “looks fine” into a review decision with evidence, scope, and reproducibility.