“Always move fast. You never know who’s catching up!”
— Terry Pratchett, Going Postal
A bug doesn’t stop mattering just because you didn’t catch it in review. It keeps existing, quietly, until something breaks. At that point it doesn’t much care whether you skipped review because you were busy, because the PR seemed low-risk, or because you were shipping six pull requests a day and review felt theoretically important but practically impossible.
March 2026: 248 PRs merged across 12 repositories, all via Claude Code. That’s roughly 9 PRs per day. I wasn’t looking for an automated review tool. I was looking for a way to make review possible at all.
How It Started
I build projects entirely through prompt engineering with Claude Code — MCP servers, game tooling, infrastructure automation, mobile apps. Most are pet projects meant to experiment and push the boundaries of what I can achieve through agentic development. Some are heading toward real users. All of them have enough complexity and security surface that cutting corners catches up with you eventually. When you’re working across a portfolio like this, context becomes the scarce resource. You can’t hold the full architecture of twelve codebases in your head simultaneously.
When you work this way, the volume compounds fast. One session might touch configuration, data models, API endpoints, and webhook handling — each as a separate PR because that’s how the agent naturally breaks work down. Multiply that across a dozen active repositories and you’re sitting on dozens of unreviewed PRs in a week. The question stopped being “how do I review better” and started being “how do I make review unavoidable.”
GitHub Copilot’s code review feature, which launched in private preview in October 2024, was the answer I stumbled onto. It’s been generally available since April 2025, so if you’re setting it up now you’ll get the GA product — cleaner and more capable than the early version I started with.
The Four-Agent Workflow
What I ended up with isn’t really “AI-assisted code review.” It’s four distinct AI contexts doing four different jobs, none of which knows what the others are doing.
Stage 1: Exploration (5–30 minutes per issue) Before any code gets written, I open a Claude Code session against the issue. Not to write code — just to scope risk. What parts of the system does this touch? Are there security considerations? What are the known failure modes? I document the findings directly in the GitHub issue. This is the phase that makes everything else work.
Stage 2: Implementation and shipping
A separate Claude Code session implements the feature. It has the issue description and my scoping notes, but it doesn’t carry over the reasoning from the exploration phase. Fresh context, focused on making the code work. When it’s done, a /ship command commits, pushes, and opens the PR.
Stage 3: Review Copilot reviews the PR automatically — I’ve configured it in the GitHub repository settings to trigger on every pull request. Different tool, different perspective, no shared implementation context. It’s looking at the diff from the outside, evaluating it against what the code should be doing rather than what the author was trying to do.
Stage 4: Review response
This is where it evolved. I built a Claude Code skill — /review-pr — that fetches Copilot’s review comments, reads the relevant code context, addresses the feedback, commits the fixes, and pushes. A fourth AI context, separate from both the implementation and the review, triaging and resolving review findings. I still scan the Copilot comments myself, but the skill handles the mechanical work of responding to them.
Context separation isn’t a limitation of this workflow. It’s the whole point. Four agents, four perspectives, none carrying the baggage of the others.
What Copilot Actually Catches
Copilot’s review accuracy isn’t perfect. Roughly half the comments are noise — flagging things that are intentional, already handled elsewhere, or just wrong. That sounds like a mediocre grade until you consider the alternative: at nine PRs a day across twelve repositories, the choice isn’t between perfect review and imperfect review. It’s between imperfect review and no review.
The useful half catches things I genuinely would have missed:
- Subtle logic errors: The kind where you use the wrong rounding function and the code works fine in tests but produces silent calculation errors in edge cases.
- Data consistency issues: Mismatches across related modules that would cause hard-to-debug failures at runtime — easy to miss when you’re context-switching between repositories.
- Security vulnerabilities: This is where it gets interesting.
The Issue That Made Me Take This Seriously
One of my projects needed a webhook endpoint. During the exploration phase, the Claude Code session flagged security handling as a concern — specifically that webhook secret verification needs careful implementation. I added a note to the issue: “Security critical — needs proper HMAC verification.”
The implementation session built the endpoint. It verified the secret. It worked.
What neither I nor the implementation session caught: the verification used == to compare the expected and received HMAC signatures.
# What was implemented
if hmac.new(secret, payload, sha256).hexdigest() == received_signature:
process_webhook()
Copilot flagged it. The correct implementation uses hmac.compare_digest():
# The fix
if hmac.compare_digest(
hmac.new(secret, payload, sha256).hexdigest(),
received_signature
):
process_webhook()
The difference matters. Python’s == short-circuits on the first mismatched character. If an attacker sends thousands of requests with slightly different signatures and measures response times, they can reconstruct a valid signature one byte at a time — a timing attack. hmac.compare_digest() always takes constant time regardless of where the mismatch occurs. The Python standard library includes it specifically for this reason.
The implementation agent didn’t catch it. I didn’t catch it. The review agent — looking at the code with no knowledge of how it was written — caught it.
That’s the context separation paying off. The implementation session optimised for making the code work. The review session asked “what could go wrong here?” Those are different questions, and they benefit from different perspectives.
Because the exploration phase had already flagged this as security-critical, I knew to take the Copilot finding seriously rather than dismiss it as noise. Stakes-based attention: I engaged deeply with this PR because I already knew it mattered.
The Economics
I’m on the Claude Max plan — $200/month — and I use most of it. At this volume, Claude is doing the exploration, the implementation, and now the review response. Asking it to also do the initial review would mean burning context on a task that a different tool handles for $10/month.
Copilot Pro at $10/month gives 300 premium requests. At 248 PRs in March with one review each, that’s around 83% of the quota — tight but within the plan. (Premium request billing enforcement started in June 2025, so this is a live constraint now rather than a theoretical one.)
The economics argument isn’t really about the dollar amounts though. It’s about cognitive load. When you’re working across a dozen repositories, you can’t hold the full architecture of each one in your head. Having implementation and review as separate tools with separate contexts means each one stays focused. I’m not asking the implementation agent to both write the code and critique it — and I’m not asking myself to maintain deep familiarity with every codebase I touched that week.
What Didn’t Work (And What Evolved)
The noise rate is the real challenge to living with this. Roughly half of Copilot’s comments flag things that are intentional, already handled, or just wrong. You build a habit of scanning past unhelpful comments, and habits are blunt instruments. There’s a real risk that you start scanning past the useful ones too.
The /review-pr skill helped here. Having Claude Code triage the review comments means the noise gets filtered through a fourth context that can evaluate each finding against the actual codebase. I still scan the comments myself — especially on PRs where the exploration phase flagged risk — but the skill handles the mechanical work and I focus on judgment calls.
The exploration phase remains the thing this whole system depends on. Skip it, and you lose the stakes information that tells you which PRs deserve careful attention. The workflow degrades significantly without those 5–30 minutes upfront per issue.
I also want to be direct about the context this lives in: this is a solo developer with enough ops background to evaluate security findings. A junior developer might not know why a timing attack matters, or when to override a Copilot suggestion versus act on it. This approach requires the ability to triage, not just the willingness to look.
Open Questions
As Copilot’s review quality improves — and GitHub has processed over 60 million Copilot code reviews as of early 2026, which is a lot of training signal — the noise rate will presumably drop. Does that change anything?
Maybe. If Copilot gets to 80% accuracy, the scanning habit becomes less risky. But I’m not sure the behavioral insight changes: the value isn’t really the accuracy, it’s the visibility. Having review comments visible on GitHub made review unavoidable in a way that a Claude Code review in a terminal session didn’t. That dynamic exists regardless of accuracy.
The volume question is real too. I went from 40 PRs in February to 248 in March as I spun up new projects. That trajectory doesn’t flatten. As context windows grow and agents handle larger chunks of work, the question of what “review” even means will shift. I don’t have an answer for that yet.
A Way, Not The Way
This workflow was born from a specific constraint at a specific volume — one person, twelve repositories, nine PRs a day. I’m not suggesting everyone should run four AI agents in series. I’m suggesting that if you’re shipping at high velocity with an AI coding agent, the question of how you maintain quality is worth taking seriously — and the answer might look different from how it looks at human development speed.
What worked for me: make review unavoidable, separate the implementation and review contexts, automate the review response, use the exploration phase to know which PRs deserve your full attention, and accept that imperfect review beats no review when the alternative is 0%.
Your volume, your codebase, your risk tolerance, and your ops background will push the answer somewhere different. That’s as it should be.
The bug that doesn’t get caught in review doesn’t disappear. It just waits.