# How to review AI-generated code without reading every line

> We review agent diffs tests first: would each test fail without the change? Then deletions, the diff's edges, secrets, and a run. Our real misses.

Source: https://shuriken.sh/blog/review-ai-generated-code

We review agent diffs tests first: would each test fail without the change? Then deletions, the diff's edges, secrets, and a run. Our real misses.

Story By Shuriken Updated 27 October 2026 5 min read

**Contents**

To review AI-generated code, skip the top-to-bottom read. Start with the tests and ask if each would fail without the change. Then read the minus lines (git diff main...HEAD | grep '^-'), the file list (git diff --stat) and anything near a secret, and run the change once before it merges.

Most of Shuriken is written by coding agents, several at a time, and we read their diffs. From 29 September to 25 October 2026 our main branch took 5,080 commits; 1,114 name the check that guards them, and 538 add "red without", meaning that check failed on the old code. The bugs below are ours, with their dates.

## How we review AI-generated code, in order #

### 1. Tests: would this one fail without the change? #

On 25 October 2026 we found two of our own end-to-end specs that were meant to check what happens when Claude Code fails to install. Both test setups already had Claude Code on the computer. So the app skipped its "Choose your agents" step, nothing was installed, nothing failed, and both specs passed. They had been green while testing nothing. The fix took Claude Code off the test computer and made its installer fail on purpose.

That is why our commit messages say "red without": the new test was run against the old code and failed there. When 3.0.2 fixed 18 verified defects, each one came with a test that fails without its fix.

We also grep the test part of the diff for three things: .skip, toBeTruthy sitting where an exact value used to be, and old expected values rewritten to match whatever the code prints now. When we're not sure about a test, we revert only the source change in a scratch copy and run the test there. If it's green both ways, it isn't testing the fix.

### 2. Everything that was deleted #

bash
git diff --name-status main...HEAD | grep '^D' # deleted files
git diff main...HEAD | grep '^-' | grep -v '^---' # deleted lines

One deletion from our own history: on 29 September 2026 a big change took an old plugin system out of our background service. One plugin test went with it, and so did the createWorkspace helper that lived next to it, which four other tests in the same file still called. Our server typecheck skips test files, so nothing complained until the integration step in CI failed 4 of 4 with ReferenceError: createWorkspace is not defined. The next commit put the helper back.

Every removed line should have a reason you can name. "It was in the way" isn't one.

### 3. The diff's edges #

bash
git diff --stat main...HEAD

We read that file list before any file. If the chat was about the date parser and ci.yml is on the list, that's the first file we open.

The edges also include files other agents are editing. Ours commit only the hunks they wrote, and on 29 September 2026 seven of those commits put a hunk outside the block it came from, so main stopped parsing. scripts/check-staged-parse.mjs went in the same day. It parses the staged copy of each file before the commit, and it refuses anything staged from .secrets/.

### 4. Checks the agent can skip #

Our lefthook.yml formats, lints and typechecks before every commit, but a commit made with --no-verify skips all three, and our agents' lanes commit that way on purpose. On 2 October 2026 CI run 37026618495 failed with 20 unformatted files and 17 lint errors. Since then check-staged-parse.mjs runs oxfmt --check and oxlint on the staged files itself.

For your own repo, search the added lines for keys and tokens:

bash
git diff main...HEAD | grep '^+' | grep -iE 'key|token|secret|passw|authorization|\.env'

Then read every change to permissions or auth. Claude Code has a /security-review command that runs a security pass over the changes on your branch ([Anthropic's security docs](https://code.claude.com/docs/en/security)). We use passes like that as a second reader, not the only one.

### 5. Run it #

On 30 September and 1 October 2026 we ran two final review passes over the whole app, using it at desktop width and at a phone's 390 pixels. They landed 347 commits. Two of the bugs they found could not have been found by reading a diff:

- A server install command run after its one-hour token expired, piped to sh with wget, printed nothing, ran an empty script and exited 0, as if it had worked. It now prints that the command expired and exits 1.
- Our Arabic buttons were machine-translated as third-person verbs: Cancel read "he cancels" in 12 places, Create used the verb for what God does, and git's Commit became "commits a crime". The diff of a translation file looks fine. The app in Arabic did not.

Open the app, click the button the task was about, call the endpoint with curl.

## A second reader that didn't write it #

We stopped asking the agent that wrote the code whether it's correct. It tends to agree with itself.

Shuriken's Changes panel has Review with another agent. By default it picks the first ready agent from a different provider than the one that wrote the changes. The reviewer is told to look for bugs, wrong behaviour, missing edge cases, security problems and unclear code, to skip style nits a formatter would fix, and not to change any file. Its comments land on the lines they are about, next to your own, and Address comments sends them to the chat that made the change.

The reviewer comes from a different provider than the agent that wrote the code.

In Shuriken a chat can work on its own branch in its own worktree, and Finish merges it after your checks.

[Try Shuriken](https://shuriken.sh/)

## How Shuriken fits in #

Every Shuriken chat works on its own branch in its own git worktree, so one chat is one task is one diff. (The reasoning is in [every chat gets its own worktree](https://shuriken.sh/blog/worktree-per-chat).) The Changes panel shows only that chat's changes, and its [Activity panel](https://shuriken.sh/features/activity) lists the commands and test runs the agent started, which answers our first question: did it run the tests at all?

The Activity panel lists what the agent started, test runs included.

Finish rebases the branch and runs the commands listed in shuriken.json. A red one goes back to the agent of that chat, three tries at most, then the branch stays unmerged. A branch that adds what looks like a secret is refused ([Finish, step by step](https://shuriken.sh/blog/finish-one-click-merge)).

Checks can't tell you whether a test would have failed without the fix. That part is still yours. If you want one diff per task, a second agent's comments on it and a merge that waits for your checks, [try Shuriken](https://shuriken.sh/).

Share

[X](https://x.com/intent/post?url=https%3A%2F%2Fshuriken.sh%2Fblog%2Freview-ai-generated-code&text=How%20to%20review%20AI-generated%20code%20without%20reading%20every%20line)[LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fshuriken.sh%2Fblog%2Freview-ai-generated-code)[Hacker News](https://news.ycombinator.com/submitlink?u=https%3A%2F%2Fshuriken.sh%2Fblog%2Freview-ai-generated-code&t=How%20to%20review%20AI-generated%20code%20without%20reading%20every%20line)[Reddit](https://www.reddit.com/submit?url=https%3A%2F%2Fshuriken.sh%2Fblog%2Freview-ai-generated-code&title=How%20to%20review%20AI-generated%20code%20without%20reading%20every%20line)[E-mail](mailto:?subject=How%20to%20review%20AI-generated%20code%20without%20reading%20every%20line&body=https%3A%2F%2Fshuriken.sh%2Fblog%2Freview-ai-generated-code)

## Sources

- [Security: related resources, /security-review (Claude Code docs)](https://code.claude.com/docs/en/security) (accessed 22 October 2026)

## Frequently asked questions

**Do I have to read every line an AI agent writes?**

No. We read four things closely: the tests, the minus lines, the file list from git diff --stat and anything near a secret. oxfmt, oxlint and tsc cover formatting and types in our repo, and then we click through the change once.

**What do coding agents most often get wrong?**

Three from our own history, September and October 2026: two install specs that passed because Claude Code was already installed, a createWorkspace helper deleted along with one unwanted test, and an expired install script that exited 0. No check went red for any of them.

**Can an AI review AI-generated code?**

Yes, as a second reader. Pick a different agent from the one that wrote the change and tell it not to edit files. Claude Code also has a /security-review command for the changes on your branch.

**How do I see only what an agent deleted?**

git diff --name-status main...HEAD lists deleted files with a D. For deleted lines inside files, read the minus lines of git diff main...HEAD, or filter them with grep '^-'.

Parallel agents

Agents side by side, each on its own branch if you want.

A new chat gets its own branch and worktree unless you pick the project folder, so agents don't step on each other. Finish runs your checks and merges each one back.

[Try Shuriken](https://shuriken.sh/)

[How it works](https://shuriken.sh/features/parallel-agents)

## Keep reading

- [Prompt injection and coding agents: the risks, plainly: Guide 27 Oct 2026 6 min read Prompt injection turns text a coding agent reads into commands it runs. No model is immune; what limits the damage is what the agent can reach.](https://shuriken.sh/guides/prompt-injection-coding-agents)
- [How Shuriken started: a tool we built for ourselves: Story 27 Oct 2026 4 min read We build software for clients and ourselves. No harness fit how heavily we use AI, so we built our own. Then a programmer asked: why don't we sell this?](https://shuriken.sh/blog/how-shuriken-started)
- [A git workflow for Claude Code that keeps main clean: Story 27 Oct 2026 4 min read The Claude Code git workflow we'd give anyone running several agents: a branch per task, small commits, read the diff, checks before merge, then squash.](https://shuriken.sh/blog/claude-code-git-workflow)
- [Fork a chat from any reply, then merge it back: Update 27 Oct 2026 3 min read Try another approach without losing the first: fork a Shuriken chat from any reply, keep the fork under its parent, then merge its work back in.](https://shuriken.sh/blog/fork-and-merge-into)
- [Run a chat on another computer and keep going: Update 27 Oct 2026 4 min read Move a coding agent chat to another of your computers or a server. It stays the same chat, with its history and uncommitted work, and runs there.](https://shuriken.sh/blog/run-chat-on-another-computer)

## Free tools

- [Claude limit reset tracker](https://shuriken.sh/tools/limit-resets/claude)
- [Codex limit reset tracker](https://shuriken.sh/tools/limit-resets/codex)
