I've always prided myself on the quality of code I produce. I've written my share of garbage code over the years (who hasn't here and there), but performant, clean, readable code has always been deeply satisfying to me, and I've held a high bar for it in my own work and in every PR I've reviewed.
So going entirely hands off on the actual code with AI was a big change, and I'm not going to lie, it took some adjustment. In the early days (crazy to think that was only a year or two ago), I used AI to speed up my output with things like tab autocomplete but I still reviewed every line it wrote. Then it started writing portions of a PR while I reviewed, adjusted, and kept going in parallel. Later it wrote the full PR and I reviewed all of it thoroughly line by line. These days I can't tell you the last time I reviewed every line, or even most of the lines, of a PR I produced with an agent(s).
Getting there took a while though. When I first went completely hands off, AI produced a metric ton of slop for me and the idea of fully trusting it felt almost impossible. Then Context Engineering took off and all of a sudden everyone had a set of core skills to help their agents write better code and follow best practices. That helped for a long while and really helped me 10x my output, and there are still great skills out there that will absolutely improve your agent results (shoutout to Matt Pocock's skill library we all know and love). As the models got better however, I found myself using fewer of those best-practice skills and slimming it down to a select core number of them and just letting the agent rip from there. The results were pretty great overall, and I got more and more comfortable fully trusting the output bit by bit.
I just never truly got there until I dug into what some people have started calling Verification Engineering. To me, it simply means building the right systems and checks to catch an agent before it produces garbage.
Getting to that level of trust has been the single biggest shift in my ability to ship quality code at scale with agents, and in a lot of ways it scratches the same itch clean code always did for me. The care I used to put into every function now goes into those systems.
A lot of this has been trial and error, and I'm still iterating constantly...I don't want to make it sound like it's a "solved" problem because I don't think it fully is for anyone just yet.
Most of my starting points came (and still come) from some of the best engineers in the space who share what they learn in public. Two stand out: Lauren (poteto), who works on Grok Bot at SpaceXSI, and Dillon Mulroy, a principal engineer at Cloudflare. If you take nothing else from this post, give both of them a follow. You'll learn a ridiculous amount from them.
What follows is more a brain dump than a guide. You can think of it as a set of thoughts on verifying agent output and learning to trust it. Some of it covers the checks themselves, and some covers the habits around them, like planning and keeping context lean, that give those checks a fair shot at success.
Be involved at the right steps
Before you fire off an agent (or a swarm of them), you should have a crystal-clear picture of what's going to be built architecturally, and you and your agents should agree on the game plan. Talk the approach through with your agent instead of just saying "go build X." As good as agents are, they won't always pick the right or best approach.
You don't need to plan every little ticket an agent creates or works on. If you're building Feature ABC though, have a real conversation, understand the high-level approach, and approve it before the agent goes off and produces 30 tickets to implement it. A wrong call at the planning stage gets copied into every one of those 30 tickets.
The analogy I keep coming back to is renovating a house.
You start by finding a contractor you trust and spending time agreeing on what you want: the design, the budget, the constraints, and what a successful renovation looks like. All of that happens before any work begins on your home.
Once the plan is clear, you let the contractor do their job and (ideally) get out of their way. They coordinate the trades and make the day-to-day decisions. You're not standing over the electrician telling them where to run every wire.
You're not completely absent though. Sometimes the contractor needs your input: maybe they find something unexpected behind a wall or there's a design decision that will be expensive to change later. Those are the moments to get involved, before the work continues and it gets costly to fix.
Throughout the project, the contractor is responsible for checking the quality of the work, coordinating inspections, and making sure everything meets the requirements and quality bar you both agreed on.
At the end, you do a final walkthrough to make sure the renovation delivers what you originally set out to achieve. You don't pry up the floorboards to check how every nail went in.
Agent-driven development works the same way. You want to be involved in the key decisions that actually matter and stay out of the way of the rest. The single biggest bottleneck in agent-driven workflows will almost always be the human.
So plan well, and plan enough, before you kick off any agent work, whether that's a single task or a full feature spread across multiple PRs. Don't be lazy about it because it can and will bite you later.
Stop spending so much time reviewing
The mindset shift has to start here: stop trying to review every line of code yourself. If you do, you quickly become the biggest bottleneck in your own workflow.
I know not every codebase affords that luxury, but don't fool yourself here. Unless you're working on life-critical or security-critical code, you can probably do this to some degree.
You still want and need review. Have a review skill and use an agent(s) to review another agent's work. If Claude Opus 5.5 wrote the code, have GPT-6 Astra give it a review and address the findings. Don't have the same model just review the work in another thread.
The main steps I'd call critical with reviews these days are having an agent explain the call stack, the blast radius of the change, and any other big related impacts. At a high level, you need to understand the impact of the change and, in some cases, the approach. You are still responsible for any code your agent produces.
Build a strong review and PR flow that helps you understand the change at the right level. What breaks if this goes wrong? Which core logic flows change with this work? Are there risky migrations? Who cares about the individual lines of code beyond those large scale impact areas.
Agents will get your CI green at all costs
Have another agent review your agent's code and it will almost always find issues. That's great, and the findings are always worth looking at, but this is where overengineering and scope creep can sneak in. Every finding becomes one more bar the agent has to clear, the same as a failing check, and it usually clears that bar by adding code.
Think about how you handled this before AI. If someone found a one-in-a-million edge case that might break a loading state, or something with a similarly small consequence, would you add 10 new files and 300 lines to fix it? No, and the same judgment applies to agents. The trouble is how easy it is to tell your agent "make the CI green" and walk away. It will get there, whatever it takes, and what it takes is often an overengineered mess littered in workarounds. The next agent then finds that mess, treats it as the pattern to follow, works within it, and adds its own. Repeat that cycle enough times and your codebase is 10x the size for no reason.
Cap how many review loops an agent gets to correct its work, and be strict about what belongs in the PR versus what gets spun out into a follow-up task (if it's even needed at all). Your goal is to catch legitimate user-impacting bugs, performance issues, security flaws, and so on.
Spend time perfecting your static analysis
My go-tos here are oxlint and oxfmt. For rules, I really like Dillon Mulroy's anti-slop as a starting point. It's an opinionated set of Oxlint rules that reject low-signal patterns and a great way to get started here.
Rules aren't something you set once and forget. Expect to keep adjusting them as you go (the next section covers some examples of what to watch for).
Tests need the same attention. Set clear practices so agents write tests that earn their place, instead of adding thousands of lines of junk tests that slow down CI and your local test runs.
Get a strong oxlint and oxfmt foundation in place (start with anti-slop if you need somewhere to begin), and set clear expectations for how agents write tests.
Agents love workarounds
Static analysis is one of the best tools you have to fight slop but if you're not careful, it can make the problem worse. To an agent chasing a green check, a lint rule is one more obstacle, and if there's a way around it, the agent can and will find it.
Imagine you add a set of strong oxlint rules, things look great, and the slop seems gone. Then a week later you realize you've gone from 0 oxlint-disable comments to about 300. Your agents have been working around the rules the whole time. Unless something re-enables them later, each of those comments switches rules off for the rest of the file, so a lot of the code you thought was covered isn't.
Or maybe imagine you have a rule that bans empty functions, and all of a sudden you have hundreds of empty functions, each with an inline comment to bypass it, while the rule keeps passing.
Rules on their own don't fix anything. You have to check whether the code behind the green check actually got better. A good way to do that is to add a skill to your repo that has an agent audit recent code for slop patterns, including new ways around your rules. That doesn't put you back to reviewing every PR yourself, since you're looking for patterns across the codebase and an agent can do the looking. You'll likely be suprised at the creativity agents use to get around blocks.
However you do it, audit the code your agents produce every so often and check whether they're finding slop workarounds and adjust as needed. Letting poor slop patterns run wild in your codebase will only expand over time like a virus.
Give agents a good, consistent way to test their work
One of the biggest additions to my toolbelt for fighting slop has been a verification skill in all my repos, usually with feature maps, user journeys, and a testing CLI. Full credit to Lauren (poteto) and pstack for introducing me to this one. pstack is Lauren's set of agent skills (Cursor plugin) and I used its create-verification-skill, which generates a project-local verification skill with a feature map. That generated skill is what drives your app the way a user does. It almost completely shifted how I verify agent work.
CI doesn't tell an agent whether the feature works for someone actually using it, so without the right tools it calls the work done as soon as the tests go green (...and sometimes it will write tests that go green a little too easily). Give it a way to walk the real user journey and it can catch its own mistakes before you ever see them.
I've since adjusted how I approach verification skills to fit my needs, but the concept is roughly the same. Keeping the skill up to date as your app changes matters just as much as having one.
Create a verification skill. If you need a starting point, give create-verification-skill from pstack a shot and adjust as you use it.
Too much context is bad
We've all learned how important context is for agents and somehow we've taken that to an extreme and started producing a ton of it. Context should be load bearing. For most things, the code should speak for itself since agents can reason about that quickly. Sometimes agents need critical context about your stack (such as deployment, local runs, etc.), and your md files should be reserved for that and that alone.
The more unneeded context you give an agent, the more likely it is to misread it or add to it. I've seen it countless times: a /docs or /context folder grows to hundreds or thousands of lines of bloated context and each agent run adds a bit more junk to justify its own decisions. In many cases an agent will even change its behaviour based on those docs and often not for the better.
Another idea I've been experimenting with, after seeing Lauren (poteto) share it, is blocking agents from adding code comments. pstack gets to the same place after the fact with a /no-comments skill that strips comments before review. It's a bit of a spicy take depending who you ask, but I have to say, I love it. Comments have historically been for humans to explain the choices in a codebase or point out areas of confusion / friction for other engineers. If we're prioritizing code that an agent can understand on its own, we just shouldn't need them. And I've absolutely seen agents treat a comment as an opportunity to explain and justify a bad workaround of its own.
Start ripping out those internal repo md files and keep only the load-bearing context. I promise you don't need most of them.
It's never perfect
Whatever you do, and no matter how good you get, some slop will still get through. It existed before AI and it still exists now (although at much larger scales unfortunately), and you have to get comfortable with that to some degree. What you can do is keep iterating and learning each model's quirks so your agents produce high-quality code in the overwhelming majority of cases and to ensure you have a strong testing and quality baseline to catch the cases don't meet the quality bar. Get a system in place, watch how your agents work within it, adapt it, and do it again and again.