The unit of review is the change
Nobody reads a codebase. People read changes. Once you accept that, reviewing generated code stops being impossible and becomes a fifteen-minute habit.
git diff # changes not yet staged
git diff --staged # changes staged for the next commit
git diff --stat # just the file names and how much moved
git diff HEAD~1 # everything since the previous commitYour editor shows the same thing with colours and side-by-side panes. Use whichever you will actually look at.
The anatomy
diff --git a/lib/queries.ts b/lib/queries.ts
@@ -42,7 +42,11 @@ export async function getBookings(userId: string) {
const rows = await db
.select()
.from(bookings)
- .where(eq(bookings.userId, userId))
+ .where(eq(bookings.status, 'confirmed'))
.orderBy(desc(bookings.startsAt))
return rows
}Read it in this order.
The file name. Is this a file you expected to change?
The @@ line. Line 42, and the function name after it. That is context you get for free.
The minus lines. What was removed. This is the half people skip and it is where the damage lives.
The plus lines. What replaced it.
In that example a filter by user was replaced by a filter by status. Every user now sees every confirmed booking in the system. The addition looks perfectly reasonable on its own; only the removal reveals the fault. This exact shape (a where clause swapped rather than extended) is one of the most common serious defects in AI-modified data code.
Start with --stat, always
Before reading a single line, look at the shape:
git diff --stat
components/BookingRow.tsx | 24 ++++++++
app/api/bookings/route.ts | 12 ++--
lib/dates.ts | 118 ++++++++--------------
package.json | 3 +-Four questions, ten seconds:
- Are there files here I did not expect?
lib/dates.tswas not part of the request. - Is anything much bigger than the task? 118 lines for a cancel button is not a cancel button.
- Did
package.jsonchange? A new dependency arrived without being mentioned. - Did any lock file, migration or config change? Those are the ones with consequences beyond this change.
Most problems are visible at this level, before you read any code at all.
Five patterns to catch on sight
A condition removed. Any deleted if, where, or && deserves an explanation. Conditions are usually there because something went wrong once.
An await that disappeared. Removing await makes code look synchronous and finish before the work does. It often appears to work, because the operation completes a few milliseconds later.
A catch block that swallows. catch (e) {} or catch (e) { console.log(e) } turns a failure into silence, and silence looks like success.
A comparison flipped. >= becoming >, or !== becoming !=. One character, and the booking that ends exactly at 14:30 now blocks the one starting at 14:30.
A hardcoded value replacing a variable. A model that could not work out where a value came from will sometimes write the value it saw in your example.
Read the whole file when the diff will not tell you
A diff shows what changed, not what the surrounding code assumed. If a change touches something that matters (money, permissions, deletion) open the file and read the function whole. Ten extra lines of context frequently reverse your reading of a change.
This is the honest limitation of diff review, and it is why “the diff looked fine” is not the same as “the code is correct”.
Make small commits so diffs stay readable
A diff across one task is reviewable. A diff across an afternoon is not, and will be skimmed regardless of intention. Every argument for small commits in the git block is an argument about this: you are protecting your own ability to review.
And if a diff has become unreadable, you have a legitimate move available. Revert it, ask for the same work in three steps, and read three small diffs instead of one large one that you would have approved without understanding.
Every lesson here is open. Your progress is recorded once you pass the Building with AI exam.
Check your understanding
In a diff, a line filtering bookings by user id is removed and a line filtering by status is added. Why is the removal the more important half?
Pick the one you would defend. Your answer stays private.
Stuck on something?Ask Beatriz, your AI tutor