TLDR; Quality gates are checks that run apart from the session that did the work: a separate review agent, tests, a Stop hook (a script that runs when Claude finishes) that forces a review, and fact-checks against source files. They catch issues a same-session review misses. Separate writing from reviewing, automate every check you can, and keep human approval for the decisions tests cannot settle.
When to use quality gates
- Before you merge code Claude wrote, in a session other than the one that wrote it.
- When a change touches logins, payments or user data: add specialised reviewers or a model from another maker as reviewer. Skip them for day-to-day work, where one fresh-session reviewer is enough.
- When content carries claims: prices, statistics, salary data, product features.
- At the end of significant work, to check your own prompting.
- Not for “should this exist?” That judgement stays with you.
How quality gates work
AI-written code looks right more often than it is right. CodeRabbit’s observational sample of 470 open-source PRs (pull requests: proposed code changes) compared PRs classified as AI-co-authored with those classified as human-only. The AI-co-authored PRs had about 1.7x as many findings overall, 75% more logic and correctness findings, and up to 2.74x as many security findings. The authors could not independently prove the authorship of every PR, so those results describe that sample rather than all AI-generated code. Separately, Veracode’s 2026 GenAI Code Security Report found that when the models it benchmarked got no security-specific guidance, their code failed its security tests nearly 44% of the time. The rate was barely changed from 2025. That is a failure rate, not a 44% increase over human code.
A review in the same session misses what the writer missed. Ask Claude “does this look right?” straight after it builds a feature, and it reviews its own work with the same context (everything in the conversation so far), the same assumptions and the same blind spots. That context can reinforce the assumptions behind the code, so separate the writing from the review: one session writes, and a sub-agent reviews. A sub-agent is a helper session Claude starts for one job, with a fresh context of its own.
Separate review comes in three tiers. The simplest, a fresh-session sub-agent, is enough for most day-to-day work. For anything touching logins, payments or user data, parallel specialised sub-agents or a review by a model from another maker is worth the spend.
- Cross-model reviewAnother makerA second model, from another maker, reviews the same change
- Parallel specialised sub-agentsSpecialist checksOne dimension each: security, performance, style, logic; more expensive
- Fresh-session sub-agentSimplestCommit, /clear, then a review agent with a critical brief
How to build quality gates in Claude Code
1. Commit, clear, then review in a fresh session (the writer/reviewer pattern)
The writer/reviewer pattern is two sessions for one task:
- Generate. Give Claude the task. Let it write the code, run the tests and iterate until the feature works.
- Commit the working code (save it as a checkpoint in git). That gives the reviewer a clean diff: the exact lines that changed.
- Run
/clearto wipe the conversation that built it. - Review. Launch a code-reviewer or security-auditor agent against the committed change (
git diff main...HEADon a feature branch). It may load your project instructions, but it does not receive the transcript of the session that wrote the code, or the decisions made there. It sees the change through a fresh task brief.
Check: git status --short prints nothing before you run /clear, and git diff main...HEAD shows the whole change.
2. Try /code-review before you build a reviewer
Anthropic built a review system for its own engineering team. Claude Code Review dispatches a team of agents to look for bugs in parallel on every PR. Before it was deployed, only 16% of PRs at Anthropic received substantive review comments; after, 54%. On large PRs over 1,000 lines, 84% receive findings, an average of 7.5 issues per PR. Engineers marked less than 1% of findings incorrect.
In one case, a one-line change to a production service looked routine. Code Review flagged it as critical: the change would have broken authentication for the service. The engineer confirmed they would have missed it.
Anthropic offers that kind of review three ways:
/code-reviewis a skill that ships with Claude Code. It runs a review sub-agent in the background against your branch, on your machine. Its effort setting trades false positives against coverage, and options let it apply fixes or leave comments.- The hosted Code Review GitHub App is the system above, run on your PRs for Team and Enterprise organisations. Each repository’s setting decides when it runs: when a PR opens, on every push, or on request. It verifies findings and ranks them by severity, and you tune it through
REVIEW.mdandCLAUDE.md(the instructions file Claude Code loads every session). /code-review ultrahands the review to a group of reviewer agents in the cloud, with a verification pass that filters out false positives before you see them. It needs a claude.ai login.
Reach for the built-in command first. Build a custom review agent when you need criteria the built-in one doesn’t encode: your conventions, your compliance rules, your definition of done.
Check: you can list the review criteria /code-review doesn’t cover for your project. If the list is empty, you don’t need step 3.
3. Write a read-only reviewer for your own criteria
In this example the review agent runs on Opus, which I use for subtle bugs. It has read-only tools, so it reports what it finds and can’t fix it:
Agent (code-reviewer, Opus): "Review the git diff on the current
branch against main. Check for:
1. Security: mass assignment, SQL injection, XSS, auth bypass,
sensitive data exposure
2. Logic errors: off-by-one, nil handling, race conditions
3. Performance: N+1 queries, missing indexes, unbounded queries
4. Convention violations: naming, file structure, test coverage
Be critical. Flag anything questionable. Rank findings by
severity: critical, warning, info."
The read-only limit is deliberate. An agent that can fix the bugs it finds will try to, and it may introduce new issues while it does. The reviewer flags; you weigh each finding and fix it in a separate step. The skills and hooks guide shows how to define an agent and limit its tools.
In my own reviews, AI reviewers catch most mechanical issues: null pointer exceptions, style violations, obvious security patterns and missing error handling. They miss whether the design fits the system, whether the business logic is correct and whether the abstraction is right. Spend your review time on “should this exist?”, “is this the right approach?” and any high-impact decision where accountability can’t be handed to a model.
Check: the agent’s tool list has no Edit or Write, and any Bash access is limited to read-only commands. Its agent file sets no memory field (which turns file editing back on). After its review, git status --short still prints nothing.
4. Make the review a quality gate with a Stop hook
A Stop hook is a script Claude Code runs when Claude finishes its turn. Nick Tune uses one to force a review. When files have changed since the last review, his Stop hook exits with code 2, the code Claude Code treats as blocking for a Stop hook. Claude can’t finish normally: the hook tells it to run a separate review sub-agent with a “very critical mindset” and read its findings. The review no longer depends on someone remembering it. Two limits apply. The hook doesn’t run when you interrupt Claude. And if it blocks eight times in a row with no tool call in between, Claude Code ignores the next block and ends the turn. The skills and hooks guide covers hook configuration and exit codes, and the hook rules guide shows how to test a hook before you rely on it.
Check: have Claude edit a file and finish its turn. Instead of stopping, it runs the review sub-agent and reads its findings.
5. Add specialised and cross-model reviewers for risky code
HAMY runs nine review sub-agents in parallel. Each covers one concern, such as tests, security or performance. The main agent combines their findings into one prioritised verdict: Ready to Merge, Needs Attention, or Needs Work. The payoff: the agents doing the work run the review themselves and act on the feedback before they mark a task done. The multi-agent guide covers running agents in parallel.
Cross-model review hands the work to a model from another maker. Daniil Okhlopkov has Claude write the plan and send it to OpenAI’s Codex for an independent review, then folds in the feedback. Claude reaches Codex through MCP, a connection that gives Claude another program’s tools. A model from another maker adds useful variety, but that does not prove the two models make independent errors. Brief the second model to attack:
Review docs/plan.md as a sceptical staff engineer. Attack the
design's assumptions. Number each finding and cite the file or
section behind it.
Check: every change that touches logins, payments or user data has at least one reviewer that is a specialised agent or a model from another maker.
6. Fact-check content against source files
Blog posts, marketing copy and client deliverables carry claims too. Most errors I catch in AI-written content are near misses. A course price that’s $200 off. A statistic from 2023 cited as 2025. A feature described for the wrong product tier. Each error is small enough to miss in a casual read, but large enough to damage credibility or create compliance issues.
Let Claude draft without interruption: fact-checking during the draft slows the writing and clutters the context. Then check the draft against the files that hold each project’s facts, such as a service catalogue with current pricing, a sitemap with URL patterns and brand guidelines with terminology rules. Salary data, industry statistics and market sizes often have no source document; flag those for a person rather than guess.
Fact-check drafts/course-page.md against sources/pricing.md,
sources/sitemap.md and sources/brand-terms.md. Mark each price,
date, statistic, URL and product name VERIFIED (quote the source
line), WRONG (give the source value) or UNVERIFIED (no source
covers it). Don't edit the draft.
Check: every price, date and statistic in the draft is marked verified against a named source file or flagged for a person to check.
7. Review your own sessions to improve your gates
The gates above check Claude’s output. A session review checks your input: whether your prompts worked, whether the right tools were used, and whether context was wasted on avoidable dead ends. Run one at the end of significant work. Ask Claude to look for patterns like these, taken from my own session reviews:
- Repeated re-explanations. “You explained the test naming convention three times in this session. Add it to CLAUDE.md.”
- Main-session exploration. “You read 14 files in the main session to understand the auth module. An Explore sub-agent would have returned a summary in 1,500 tokens instead of the 22,000 tokens those file reads consumed.” (An Explore agent is a read-only helper; tokens are the units Claude counts text in.)
Turn each finding into something permanent. A repeated re-explanation becomes a CLAUDE.md instruction. An error a person had to catch becomes a hook that catches it automatically.
Check: each finding ends as a CLAUDE.md line, a hook, or a note that it needs neither.
Pitfalls
| Symptom | Cause | Fix |
|---|---|---|
| Claude approves its own code | The review ran in the session that wrote it, with the same context and blind spots | Commit, /clear, and review in a fresh session |
| The review introduces new bugs | The reviewer could edit, so it tried to fix what it found | Give it read-only tools; fix in a separate step |
| A documented gate never runs | It depends on someone remembering it | Trigger it from a Stop hook or from the session that runs the agents |
| Salary or pricing figures are close but wrong | Claude used cross-industry averages | Check the draft against sector-specific source documents |
In practice
On a client project, Claude built a clean invitation feature: model, controller, system test, all green. The test covered the happy path and two edge cases, and I was about to commit. Then the review agent flagged a mass-assignment vulnerability in the controller’s strong parameters (the list of fields a form may change). The update action accepted role as a permitted parameter. That would have let any logged-in user raise their own permissions. I hadn’t asked for role in the params; Claude had inferred from the model’s attributes that it should be updatable. The review agent did not receive that reasoning. It saw that a field controlling access could be changed through a public endpoint, and flagged it.
For the past few months, the gate I’ve used most is cross-model review, with OpenAI’s Codex checking Claude’s work. I tallied about 160 of those runs in what Codex caught in my Claude Code workflow. Which model is smarter is beside the point: in my work, a reviewer that hasn’t seen the transcript has caught issues the first pass missed.
Sometimes Codex runs through OpenAI’s plugin for Claude Code (until September 2026 I used an MCP server), and Claude hands it a diff or a design to attack. On a SwiftUI app it reviewed the PRD (product requirements document) before any code was written, briefed as a sceptical staff engineer told to “attack the design’s assumptions”. Its numbered findings reshaped the plan. On a backend engine I asked for a simplification pass, explicitly not a bug hunt, and it flagged three over-builds with file-level citations and confidence scores.
Other times Codex runs in its own window and I bring its findings back as review notes. On a Rails codebase that produced severity-rated catches Claude had missed: a load-bearing JSON guard, a denial-of-service vector, and a silent wrong-results bug.
I’ve also written cross-model review into a project’s process doc, then found in the logs that I had skipped it every time.
For my marketing work, fact-checking is built into the workflow. My marketing-strategist skill includes a 47-point review checklist that runs on every deliverable. It checks for fabricated statistics, salary data from cross-industry averages, external claims without an inline link, and page analysis based on speculation instead of fetched content.
Google’s NotebookLM holds client-specific facts (course guides, pricing pages, service descriptions), and the fact-checker verifies claims against them. The check is only as good as the source material, but one trusted store of facts beats Claude’s training data for client details.
The error I catch most is salary and pricing data pulled from cross-industry averages. “Service Manager” salaries across all industries differ by $20,000+ from “Service Manager, Community Services” salaries, and Claude doesn’t distinguish unless the source documents force it to.
I have not found long-term evidence that these patterns reduce production defect rates by a specific percentage. Separate review can still catch issues a same-session review would miss. Measure its value in your own workflow, against the defects it finds and the false positives it raises.
Deciding which gates AI-written code must pass before it ships is one of the calls I make as a fractional CTO.
Related reading
- Claude Code skills, hooks, subagents and commands: when to use each, the extensibility primitives that make quality gates automatic
- Multi-agent orchestration, running parallel agents on real projects, parallel execution, including review agent patterns
- Session craft, when to start fresh, resume, or compact, session lifecycle management and the review practice
- The tech-lead pattern, planning before coding, planning as a quality gate that prevents downstream errors
- Evals and drift, keeping agents honest when the model changes, the same grader hierarchy applied to model swaps and agent regressions
- Claude Code hook examples: turning mistakes into tested rules, gates that block a known mistake before it runs
- Claude Code for the full stack: marketing, DevOps, and beyond code, the same gates on a content pipeline
Sources
- State of AI vs Human Code Generation, CodeRabbit. Observational comparison of 470 open-source PRs, including its authorship-classification limitations. Company research
- 2026 GenAI Code Security Report, Veracode. Security-test results across generated code from more than 100 models; source for the 44% failure rate. Company research
- Code Review for Claude Code, Anthropic. Multi-agent PR review system with performance data from internal deployment. Product announcement
- Auto-Reviewing Claude’s Code, Nick Tune, O’Reilly Radar. Stop hook pattern for automatic sub-agent review at session end. Practitioner guide
- 9 Parallel AI Agents That Review My Code, HAMY. Parallel specialised sub-agent architecture for comprehensive code review. Practitioner guide
- My Claude Code Setup After 4 Months of Daily Use, Daniil Okhlopkov. Cross-model review via Codex MCP integration. Practitioner guide
- Code Review, Claude Code Docs, Anthropic. Setup and configuration guide for automated code review. Documentation
Common questions
How do you keep AI-generated code quality high?
Quality gates are checks built into the workflow instead of an inspection at the end. They include a separate reviewer for each change and a hook (a script Claude Code runs automatically) that starts the review when Claude finishes. They also include fact-checks against source files and a review of your own sessions. A check the workflow triggers runs every time; one you have to remember gets skipped.
Why should the reviewer be separate from the writer?
A model marking its own homework misses its own mistakes, the same way a person does. A separate reviewer agent starts with a clean slate and a critical brief. It never saw the reasoning behind the work, so it can catch what the writer missed.
What is the writer/reviewer pattern?
One session writes the code and a second reviews it. Claude builds and tests the feature, and you commit it (save it in git) and clear the conversation. Then a read-only review agent checks the saved change without seeing the conversation that produced it.