<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>Unlockers.ai blog</title><description>What we learn making teams AI-first: field notes, methods, numbers.</description><link>https://unlockers.ai/en/blog</link><language>en</language><atom:link href="https://unlockers.ai/en/blog/rss.xml" rel="self" type="application/rss+xml"/><item><title>A 10,000-line vibe-coded project, fully refactored in 1h45 with a single prompt</title><link>https://unlockers.ai/en/blog/refactoring-9580-vibe-coded-lines-in-one-prompt</link><guid isPermaLink="true">https://unlockers.ai/en/blog/refactoring-9580-vibe-coded-lines-in-one-prompt</guid><description>How a fifteen-minute prompt put an untested project under the strictest quality control: a goal the agent checks itself, coverage first, a ratchet against shortcuts.</description><pubDate>Wed, 28 Oct 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;Translated from French with AI. &lt;a href=&quot;https://unlockers.ai/blog/refactorer-9580-lignes-vibe-codees-en-un-prompt&quot;&gt;Read the original&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;figure&gt;
  &lt;img src=&quot;https://unlockers.ai/blog/refactorer-9580-lignes-vibe-codees-en-un-prompt/before-after-en.png&quot; alt=&quot;On the left, a single large file of 2,065 lines in a project of 14 files and 9,580 lines. On the right, 156 files organised by responsibility, the largest at 379 lines. Below, five indicators before and after: 680 tests, 99% of lines covered, 99% of mutants killed, 0 violations, Code Health from 6.0 to 9.8.&quot; /&gt;
  &lt;figcaption&gt;Before and after a fifteen-minute prompt and 1h45 of autonomous agent work.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I have a vibe-coded Java command-line project: 14 files, 9,580 lines, no tests, one 2,065-line file and about 870 static-analysis violations. I gave it a prompt that took me fifteen minutes to write. The agent worked alone for 1h45, from 00:42 to 02:27. The project now has 156 files, the largest at 379 lines, 680 tests, 99% of lines covered, and it passes a single command, &lt;code&gt;./verify&lt;/code&gt;, that chains eight automated checks.&lt;/p&gt;
&lt;p&gt;Before starting the agent, I was certain of two things: nothing would be broken, and the result would go where I wanted. This article explains where that certainty came from.&lt;/p&gt;
&lt;aside class=&quot;tldr&quot;&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; I gave the agent a goal it can check itself (one command that must turn green) and a safe process (tests first, refactoring second). With that, it converges without breaking anything and stays free to choose its own implementation. The same approach works for any change in legacy code: that is the idea behind the 3P skill, presented below.&lt;/aside&gt;
&lt;h2 id=&quot;the-starting-point-14-files-9580-lines-no-tests&quot;&gt;The starting point: 14 files, 9,580 lines, no tests&lt;/h2&gt;
&lt;p&gt;The project audits GitLab repository activity using SonarQube data. It works, but everything sits in a few large files, including &lt;code&gt;GitlabActivityAudit&lt;/code&gt; at 2,065 lines, and nothing checks that a change doesn’t damage something else. Static analysis reported about 870 violations.&lt;/p&gt;
&lt;h2 id=&quot;what-i-asked-for-one-command-that-must-turn-green&quot;&gt;What I asked for: one command that must turn green&lt;/h2&gt;
&lt;p&gt;The prompt describes, above all, a final state: the &lt;code&gt;./verify&lt;/code&gt; command must pass entirely. It chains Spotless for formatting, Checkstyle, Error Prone with NullAway, PMD, the tests with a coverage threshold of 90% of lines and 85% of branches, and a ratchet described below. The &lt;code&gt;--full&lt;/code&gt; option adds CPD for duplicated code and PIT, a mutation test, with an 85% threshold.&lt;/p&gt;
&lt;p&gt;Here is the prompt, shortened for reading (the original is longer):&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;Cover the project with tests that allow a major refactoring.&lt;/li&gt;
&lt;li&gt;Use mutation testing to check that coverage.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;./verify&lt;/code&gt; to bring out every violation.&lt;/li&gt;
&lt;li&gt;Fix them in whatever order you judge most relevant.&lt;/li&gt;
&lt;li&gt;Install &lt;code&gt;./verify&lt;/code&gt; as git hooks and validate that they work.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Save to &lt;code&gt;QUALITY_LOG.md&lt;/code&gt; any questionable choice you have to make to pass the checks. Provide proof: coverage before, coverage after, any diff on the rules, the &lt;code&gt;./verify&lt;/code&gt; report.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The order matters: coverage first, structure second. The &lt;code&gt;QUALITY_LOG.md&lt;/code&gt; log lets the agent flag its questionable choices to me, more on that below. As for the proof requested at the end of the prompt, it fits on one page and is enough for me to review: the diff on the rules shows immediately whether the agent loosened a check.&lt;/p&gt;
&lt;h2 id=&quot;what-came-out-of-the-night&quot;&gt;What came out of the night&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Before&lt;/th&gt;
&lt;th&gt;After&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Files&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;156 (largest: 379 lines)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tests&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;680&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lines covered&lt;/td&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;td&gt;99% (97% of branches)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mutants killed (PIT)&lt;/td&gt;
&lt;td&gt;not measured&lt;/td&gt;
&lt;td&gt;99% (3,392 of 3,433)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Static-analysis violations&lt;/td&gt;
&lt;td&gt;about 870&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Code Health (CodeScene)&lt;/td&gt;
&lt;td&gt;6.0&lt;/td&gt;
&lt;td&gt;9.8&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The agent also found about twenty behaviours that look like bugs. I didn’t want them fixed during a refactoring. It documented them and pinned them with named tests, the behaviour stays unchanged, and I decide later.&lt;/p&gt;
&lt;h2 id=&quot;why-i-was-sure-nothing-would-break&quot;&gt;Why I was sure nothing would break&lt;/h2&gt;
&lt;p&gt;Refactoring starts only once the behaviour is protected. The tests written first are characterization tests: they run the tool end to end against fake GitLab and SonarQube servers and compare its output with snapshots (using the Selfie library). If the refactoring changes one line of what the tool produces, a snapshot breaks.&lt;/p&gt;
&lt;p&gt;99% coverage doesn’t prove those tests check anything: an executed line is not a verified line. That is the job of mutation testing. PIT modifies the code in small ways (a &lt;code&gt;&amp;gt;&lt;/code&gt; becomes &lt;code&gt;&amp;gt;=&lt;/code&gt;, a &lt;code&gt;return&lt;/code&gt; is removed) and checks that at least one test fails. Out of 3,433 mutations, 3,392 were detected. The safety net was therefore tested before the first refactoring.&lt;/p&gt;
&lt;p&gt;This is the method I call 3P and put into a &lt;a href=&quot;https://github.com/unlockers-ai/unlockers-skills-library/tree/main/skills/legacy-3p&quot;&gt;skill&lt;/a&gt;: Protect the existing behaviour with quick and dirty tests, check the net by deliberately breaking something small, Prepare the ground with a refactoring that changes no behaviour, then Produce the feature with TDD. Here I only used the first two steps. But nothing stops you from using it to add a feature to any legacy code in the same way: protection first, novelty second.&lt;/p&gt;
&lt;h2 id=&quot;why-the-agent-went-where-i-wanted&quot;&gt;Why the agent went where I wanted&lt;/h2&gt;
&lt;p&gt;The goal can be evaluated by the agent itself. It doesn’t need me to know where it stands: it runs &lt;code&gt;./verify&lt;/code&gt;, reads what fails, fixes it, and starts again. I described no target structure. The split into 156 files, with packages such as &lt;code&gt;matching&lt;/code&gt;, &lt;code&gt;sonar&lt;/code&gt;, &lt;code&gt;gitlab&lt;/code&gt;, &lt;code&gt;csv&lt;/code&gt;, &lt;code&gt;console&lt;/code&gt;, &lt;code&gt;naming&lt;/code&gt;, &lt;code&gt;parallel&lt;/code&gt; or &lt;code&gt;exclusions&lt;/code&gt;, came from the agent. What I fixed were the thresholds: Checkstyle’s and PMD’s, coverage, mutation.&lt;/p&gt;
&lt;p&gt;Each iteration brings it closer to the final state or makes a test fail, and the agent chooses the path freely.&lt;/p&gt;
&lt;h2 id=&quot;the-ratchet-existing-problems-may-stay-no-new-ones-may-enter&quot;&gt;The ratchet: existing problems may stay, no new ones may enter&lt;/h2&gt;
&lt;p&gt;A measurable goal has a loophole: the agent can reach green by loosening the measure, by lowering a coverage threshold, adding a &lt;code&gt;@SuppressWarnings&lt;/code&gt;, or disabling a test. The ratchet closes that door. The name comes from the ratchet wrench, which turns in one direction only. The rule fits in one sentence: existing problems may stay, no new ones are allowed, and nobody loosens a check quietly.&lt;/p&gt;
&lt;p&gt;Concretely, a small tool compares the working tree with a git reference. A minimum threshold cannot go down, a maximum threshold cannot go up, a check cannot disappear. The number of suppression markers (&lt;code&gt;@SuppressWarnings&lt;/code&gt;, &lt;code&gt;NOPMD&lt;/code&gt;, &lt;code&gt;CHECKSTYLE:OFF&lt;/code&gt;, &lt;code&gt;@Disabled&lt;/code&gt;) cannot grow. An Error Prone rule switched off or downgraded to a warning is detected. A commit carrying a &lt;code&gt;Ratchet-Override:&lt;/code&gt; line turns the failure into a warning: the exception stays possible, but it is a human decision, visible in the history.&lt;/p&gt;
&lt;p&gt;During the night, the ratchet refused three new &lt;code&gt;@SuppressWarnings&lt;/code&gt; that the agent had added.&lt;/p&gt;
&lt;h2 id=&quot;the-quality-log-the-agent-flags-its-questionable-choices&quot;&gt;The quality log: the agent flags its questionable choices&lt;/h2&gt;
&lt;p&gt;An agent working alone for 1h45 makes many decisions I will never see. The &lt;code&gt;QUALITY_LOG.md&lt;/code&gt; section of the prompt asks it to record those that are questionable: a compromise, a shortcut, a place where it wasn’t sure. I read that log instead of 156 files.&lt;/p&gt;
&lt;p&gt;The log served a second time. I ran an automated review on the result (CodeScene, a “clean coder” agent, an “architect” agent and a behaviour-change experiment) and compared its findings with the log. The gap between the two gave me new design rules: an &lt;code&gt;ARCHITECTURE.md&lt;/code&gt; file and ArchUnit tests that enforce layers, isolation between slices of the code, no cycles between packages, and a single public class, the command. They are tests, so they run in &lt;code&gt;./verify&lt;/code&gt; like everything else. That second wave deserves its own article.&lt;/p&gt;
&lt;h2 id=&quot;what-this-certainty-doesnt-cover&quot;&gt;What this certainty doesn’t cover&lt;/h2&gt;
&lt;p&gt;The tests pin the behaviour as my fake servers simulate it. Of 3,433 mutants, 41 survived. And the twenty or so suspected bugs are still there, on purpose. The framework guarantees that the behaviour the tests observe doesn’t change. It doesn’t guarantee that the program is right.&lt;/p&gt;
&lt;h2 id=&quot;they-apply-the-same-recipe&quot;&gt;They apply the same recipe&lt;/h2&gt;
&lt;p&gt;I’m not the only one seeing this. These published reports follow the same recipe: a goal the agent checks itself, and rules it cannot get around.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.anthropic.com/engineering/building-c-compiler&quot;&gt;Anthropic&lt;/a&gt;: a 100,000-line C compiler written by 16 agents, guided by existing test suites. The verifier must be almost perfect, otherwise the agent solves the wrong problem.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://openai.com/index/harness-engineering/&quot;&gt;OpenAI&lt;/a&gt;: a million lines in five months by three engineers, bounded by mechanical rules.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://claude.com/customers/rakuten&quot;&gt;Rakuten&lt;/a&gt;: seven hours of autonomy on vLLM, 99.9% numerical accuracy against the reference.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.infoq.com/news/2026/03/stripe-autonomous-coding-agents/&quot;&gt;Stripe&lt;/a&gt; (via InfoQ): more than 1,300 pull requests a week, with deterministic lint and tests and at most two rounds of continuous integration.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.infoq.com/news/2025/03/airbnb-llm-test-migration/&quot;&gt;Airbnb&lt;/a&gt; (via InfoQ): 3,500 test files migrated in six weeks instead of 18 months.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2501.12862&quot;&gt;Meta&lt;/a&gt;: 49% of tests generated from mutants add no line coverage, hence the value of mutation testing.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;which-piece-of-work-becomes-reasonable-now&quot;&gt;Which piece of work becomes reasonable now?&lt;/h2&gt;
&lt;p&gt;Turning 10,000 untested lines into tested, split and controlled code used to take a team weeks, so we didn’t do it. It took fifteen minutes of prompt and 1h45 of waiting. The physical laws of software development have changed, and our idea of what is worth attempting hasn’t caught up.&lt;/p&gt;
&lt;p&gt;In your backlog, look for the jobs whose final state can be described in a verifiable way: every test of the new version green, a module covered at 90%, no violations left. Migrations, version upgrades, covering a legacy module and bringing old code into compliance often fall into that category. Tomorrow, what could you do with your backlog using this approach?&lt;/p&gt;
&lt;h2 id=&quot;going-further&quot;&gt;Going further&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;a href=&quot;https://github.com/unlockers-ai/unlockers-skills-library/tree/main/skills/legacy-3p&quot;&gt;legacy-3p&lt;/a&gt; skill: Protect, Prepare, Produce.&lt;/li&gt;
&lt;li&gt;In the same series: &lt;a href=&quot;https://unlockers.ai/en/blog/reviewing-ai-written-prs-sucks&quot;&gt;Reviewing AI-written PRs sucks&lt;/a&gt;, &lt;a href=&quot;https://unlockers.ai/en/blog/why-we-dont-delegate-code-review&quot;&gt;Why we don’t delegate code review&lt;/a&gt; and &lt;a href=&quot;https://unlockers.ai/en/blog/how-to-delegate-code-review-to-agents&quot;&gt;How to delegate code review to agents&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Johan Martinsson&lt;/p&gt;
</content:encoded><dc:creator>Johan Martinsson</dc:creator></item><item><title>How to delegate code review to agents</title><link>https://unlockers.ai/en/blog/how-to-delegate-code-review-to-agents</link><guid isPermaLink="true">https://unlockers.ai/en/blog/how-to-delegate-code-review-to-agents</guid><description>How to feed an AI reviewer, test it on past PRs, and decide when a human should look.</description><pubDate>Fri, 23 Oct 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;Translated from French with AI. &lt;a href=&quot;https://unlockers.ai/blog/deleguer-la-revue-de-code-aux-agents&quot;&gt;Read the original&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;figure&gt;
  &lt;img src=&quot;https://unlockers.ai/blog/deleguer-la-revue-de-code-aux-agents/micromanager-vs-deleguer.png&quot; alt=&quot;On the left, a human reads the output of eight agents one by one. On the right, they hand everything they know to a team of reviewers and fixers, which produces merged code, and they watch quality from a distance.&quot; /&gt;
  &lt;figcaption&gt;Reading every line, or delegating to a team of reviewers and fixers and watching the quality of the process.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Imagine a CTO whose team of developers grows every day, and who plans to read every line of code themselves to stay in control. Nobody would believe that will hold up for long. Yet that is what many teams do with agents: they produce more and more code, and humans review all of it.&lt;/p&gt;
&lt;p&gt;I think our role can no longer be to read every line. In the &lt;a href=&quot;https://unlockers.ai/en/blog/reviewing-ai-written-prs-sucks&quot;&gt;first post&lt;/a&gt;, I described this imbalance. In the &lt;a href=&quot;https://unlockers.ai/en/blog/why-we-dont-delegate-code-review&quot;&gt;second&lt;/a&gt;, I looked at what keeps us from delegating review. This one is about what comes next: how to go about it in practice.&lt;/p&gt;
&lt;aside class=&quot;tldr&quot;&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; You can delegate review to agents, as long as you feed them the project&apos;s material and test them on past PRs. A PR without bugs can be merged, and human attention moves to design. In a hurry? Skip to &lt;a href=&quot;https://unlockers.ai/en/blog/how-to-delegate-code-review-to-agents#design-later&quot;&gt;the section on design&lt;/a&gt;.&lt;/aside&gt;
&lt;h2 id=&quot;delegating-means-giving-context&quot;&gt;Delegating means giving context&lt;/h2&gt;
&lt;p&gt;Delegating review is a real act of delegation, as with a colleague: you have to give the agent what it needs to succeed.&lt;/p&gt;
&lt;p&gt;The agent starts with solid general knowledge. It has probably read, during training, most of the books on good design, architecture, security, readability and code smells. That knowledge exists, and you have to bring it out with the right questions. What it can’t guess is your project, your context, your team’s tastes.&lt;/p&gt;
&lt;h2 id=&quot;where-to-find-material-for-a-code-reviewer&quot;&gt;Where to find material for a code reviewer&lt;/h2&gt;
&lt;p&gt;Three techniques complement each other:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Past PRs.&lt;/strong&gt; Let the agent go through all the old PRs, their comments and instructions, and draw applicable rules from them, with examples. The humans on the team have already written down what matters to them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Yourself.&lt;/strong&gt; Sit down and write out everything that’s important, with your priorities. What you know about the project is often written nowhere, and the agent won’t find it on its own.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ongoing reviews.&lt;/strong&gt; In every review you see what the agent missed, what it lacks. Add it to its knowledge base.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;testing-a-reviewer-automatically&quot;&gt;Testing a reviewer automatically&lt;/h2&gt;
&lt;p&gt;Testing a prompt means taking a case, running it, and analyzing the result. For a reviewer, the case already exists in the history.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Run it on past PRs.&lt;/strong&gt; Pick old PRs that were reviewed in depth and replay the reviewer on them. Does it find at least what was flagged back then? That score can be computed. It’s what’s called a verifiable reward, and it’s what makes evaluation simple. You also look at what it finds in addition and what it misses, and judge how relevant the extra findings are. You can go further and let an agent adapt the prompt to correct itself on those cases. These PRs become a test base for improving the reviewer.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Run it alongside the human.&lt;/strong&gt; For a while, the human and the agent review the same PRs, and you add to the reviewer whatever it’s missing.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Keep doing manual reviews until they add nothing more.&lt;/strong&gt; It’s a way to reassure yourself that you have little left to say. The limit: as the level rises, you notice other details, and you can find them endlessly.&lt;/p&gt;
&lt;h2 id=&quot;several-specialized-reviewers-that-agree-and-a-fixer-in-a-loop&quot;&gt;Several specialized reviewers that agree, and a fixer in a loop&lt;/h2&gt;
&lt;p&gt;For a deeper review, I split my single reviewer into several specialized reviewers, each with its own angle (complexity, tests, architecture, security, etc.), coordinated by a main agent. The sweep becomes much deeper. I also had to instruct it to look beyond the git diff: the context, the method, the whole file. It also needs fairly strict instructions so that it doesn’t stop after a few findings and looks for absolutely everything.&lt;/p&gt;
&lt;p&gt;Then I introduced a fixer that loops with the reviewers until a high level of quality is reached. The reviewers see each other’s work and agree, through the main agent, on what needs fixing. This loop raises a few implementation problems, and I’ll probably write a post about that experience.&lt;/p&gt;
&lt;p&gt;In my library, everything starts with &lt;a href=&quot;https://github.com/unlockers-ai/unlockers-skills-library/blob/main/skills/review-all/SKILL.md&quot;&gt;&lt;code&gt;review-all&lt;/code&gt;&lt;/a&gt;, the orchestrator. It reviews nothing itself: it pins the commit, launches five reviewers in parallel (complexity, tests, architecture, security, slop), then publishes their summary on the PR, with one comment and one status per reviewer. They all follow the same protocol: each finding is classified Critical, Major or Minor, with its file and line. If there are things to fix, the same reviewers approve the fix plan and then verify the result, without redoing a full review. Then the merge happens automatically if CI passes.&lt;/p&gt;
&lt;p&gt;If you want to start from something that works, you can help yourself to the &lt;a href=&quot;https://github.com/unlockers-ai/unlockers-skills-library/blob/main/skills/review-all/SKILL.md&quot;&gt;Unlockers Skills Library&lt;/a&gt;, which is open source. To try it, ask your own agent to read this set of skills and apply it to one of your PRs.&lt;/p&gt;
&lt;h2 id=&quot;a-risk-score-to-decide-where-a-human-should-look&quot;&gt;A risk score to decide where a human should look&lt;/h2&gt;
&lt;p&gt;Another technique: have the review produce a risk score, then let an approver decide whether to bring in a human. This scoring mechanism isn’t published in my library yet.&lt;/p&gt;
&lt;p&gt;The question is how to score. Rather than a numeric grade, I recommend three or four levels, for example minor, major, critical. It’s more reliable with an LLM, and it’s already the vocabulary humans use in meetings to rank problems. Several scores can be aggregated to give an overall picture.&lt;/p&gt;
&lt;p&gt;To catch errors in the scoring itself, a human also reviews a few randomly picked PRs, three for example.&lt;/p&gt;
&lt;p&gt;&lt;a id=&quot;design-later&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;a-pr-without-bugs-can-be-merged-design-gets-reviewed-later&quot;&gt;A PR without bugs can be merged, design gets reviewed later&lt;/h2&gt;
&lt;p&gt;In a project like the Linux kernel, only the maintainers who know the project can merge. In my view, this met two needs: avoiding bugs and inconsistencies, and making sure the important details of the project are known to the person who decides.&lt;/p&gt;
&lt;p&gt;Those two needs are now covered differently:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Functional correctness&lt;/strong&gt; is settled upstream. On some projects, it has become easy to reach near-total test coverage, protected by mutation testing.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Knowledge of the project&lt;/strong&gt; is something you supply to the agents. A reviewer that has it goes far beyond what a human can keep in their head.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A PR that passes these two filters probably has no bugs, so it can be merged. What a human eye still brings is design: architecture, bad patterns, code that turns sloppy. The &lt;a href=&quot;https://arxiv.org/abs/2603.24755&quot;&gt;SlopCodeBench&lt;/a&gt; benchmark has 15 agents extend their own code, iteration after iteration: structural erosion increases in 77% of trajectories, and their code is 2.3 times more verbose than that of 473 open-source repositories. It isn’t necessarily representative, because those agents have no quality harness there. In any case, the PR isn’t always the right place to deal with it. Fixing a detected drift can turn a small feature increment into a global refactoring of the codebase.&lt;/p&gt;
&lt;p&gt;This design review can therefore happen on a delay, across several PRs, by looking at recent changes. I have an agent that does this kind of longer-term review: it flags bad smells, problems that appeared recently, and opportunistic refactorings to do given the work done.&lt;/p&gt;
&lt;p&gt;A friend tried the experiment: review no longer blocks the merge. The developers had to ask themselves how to get quality another way, which called on their creativity.&lt;/p&gt;
&lt;p&gt;My view: the role of humans remains important, but it is no longer played out mainly in a PR.&lt;/p&gt;
&lt;h2 id=&quot;the-cost-of-refactoring-has-become-very-low&quot;&gt;The cost of refactoring has become very low&lt;/h2&gt;
&lt;p&gt;There’s also an economic reason. Before, letting untidy code in was expensive: without complete tests, you couldn’t refactor it safely, so you had to block it at the door. With tests in place, changing an implementation costs almost nothing.&lt;/p&gt;
&lt;p&gt;The other day, I took a 9,580-line codebase, entirely vibe-coded and without a single test. With a single prompt and 1h45 of autonomous agent work, I had it covered by tests, split into modules and cleaned of every bad pattern that automated tools detect (&lt;a href=&quot;https://unlockers.ai/en/blog/refactoring-9580-vibe-coded-lines-in-one-prompt&quot;&gt;the details&lt;/a&gt;). Clinging by reflex to the old review rules no longer has any justification.&lt;/p&gt;
&lt;h2 id=&quot;going-further&quot;&gt;Going further&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/unlockers-ai/unlockers-skills-library&quot;&gt;Unlockers Skills Library&lt;/a&gt;: my review agents and skills, with their &lt;a href=&quot;https://github.com/unlockers-ai/unlockers-skills-library/blob/main/docs/review-protocol.md&quot;&gt;shared protocol&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Johan Martinsson&lt;/p&gt;
</content:encoded><dc:creator>Johan Martinsson</dc:creator></item><item><title>Why we don&apos;t delegate code review to AI</title><link>https://unlockers.ai/en/blog/why-we-dont-delegate-code-review</link><guid isPermaLink="true">https://unlockers.ai/en/blog/why-we-dont-delegate-code-review</guid><description>Agents write the code and humans review all of it. Five reasons, mostly psychological, that keep us from starting to delegate review.</description><pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;Translated from French with AI. &lt;a href=&quot;https://unlockers.ai/blog/pourquoi-on-ne-delegue-pas-la-revue-de-code&quot;&gt;Read the original&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;figure&gt;
  &lt;img src=&quot;https://unlockers.ai/blog/pourquoi-on-ne-delegue-pas-la-revue-de-code/camion-faille-critique.png&quot; alt=&quot;A developer with headphones on and a coffee in hand sits in the middle of the road facing a truck labelled &amp;quot;Critical flaw&amp;quot;: &amp;quot;I told my agent to handle the review.&amp;quot;&quot; /&gt;
  &lt;figcaption&gt;Hand the review to an agent and stop watching the road: the critical flaw still comes.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p class=&quot;lead-quote&quot;&gt;&quot;AI code review isn&apos;t reliable. So I do it by hand.&quot;&lt;/p&gt;
&lt;p&gt;That reasoning fits in two sentences and it sounds solid. In the &lt;a href=&quot;https://unlockers.ai/en/blog/reviewing-ai-written-prs-sucks&quot;&gt;previous post&lt;/a&gt;, I described what it leads to: agents writing a lot of code, humans reviewing all of it, and a lot of people not coping well. This time, I’m looking for what keeps us from delegating even part of it. I see five brakes.&lt;/p&gt;
&lt;aside class=&quot;tldr&quot;&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; Five brakes: fear of the error nobody notices, confusing delegating with getting it 100% right, a review we&apos;ve never made explicit, LLMs with jagged abilities, and delegation that has to go through writing.&lt;/aside&gt;
&lt;h2 id=&quot;1-fear-of-the-error-we-wont-see&quot;&gt;1. Fear of the error we won’t see&lt;/h2&gt;
&lt;figure&gt;
  &lt;img src=&quot;https://unlockers.ai/blog/pourquoi-on-ne-delegue-pas-la-revue-de-code/agent-approuve-bombe.png&quot; alt=&quot;A review agent approves a &amp;quot;new payment flow&amp;quot; PR, every check green, while a time bomb sits hidden in the diff&quot; /&gt;
  &lt;figcaption&gt;Fear number one: everything is green, the agent approves, and the serious error slips through silently.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;What scares people is the serious errors the agent might let through: a security hole, a nasty bug, that crosses the review silently and turns up in production weeks later. When my colleagues review a PR, I know their strengths and their blind spots. With an agent, I don’t know when I’ll find out, or how much it will cost me by then.&lt;/p&gt;
&lt;p&gt;For many people, this fear has a precise origin. They tried once, the agent missed something obvious, and they never tried again. One error was enough. And you tell yourself that the next one, you might not see.&lt;/p&gt;
&lt;h2 id=&quot;2-we-confuse-delegating-with-getting-it-100-right&quot;&gt;2. We confuse delegating with getting it 100% right&lt;/h2&gt;
&lt;figure&gt;
  &lt;img src=&quot;https://unlockers.ai/blog/pourquoi-on-ne-delegue-pas-la-revue-de-code/revue-manuelle-vs-automatisee.png&quot; alt=&quot;Sketch: manual review quality plateaus, automated review starts lower but keeps improving and ends up overtaking it&quot; /&gt;
  &lt;figcaption&gt;Manual review plateaus; automated review starts lower but keeps improving. An illustrative sketch, not measurements.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;If the agent approves everything, it has to be right every time. Since it won’t be, we don’t start. That reasoning skips a step: delegating partly doesn’t require 100%. You can let the agent do the review, fixes included, and go over its work until you trust it enough. You can also try several variants of the review on PRs that were already reviewed, and keep only the ones that hold up. More on that in the next post.&lt;/p&gt;
&lt;p&gt;DORA’s research on software delivery performance points the same way. In the &lt;a href=&quot;https://services.google.com/fh/files/misc/state-of-devops-2019.pdf&quot;&gt;Accelerate State of DevOps 2019&lt;/a&gt; report, organisations that required a formal, heavyweight approval process were 2.6 times more likely to be among the low performers. The report doesn’t say why. My interpretation: a manual check plateaus, while an automated one improves with every rule you add to it. Review works the same way: starting to delegate, even badly, gives you something to improve.&lt;/p&gt;
&lt;h2 id=&quot;3-weve-never-made-explicit-how-we-review&quot;&gt;3. We’ve never made explicit how we review&lt;/h2&gt;
&lt;figure&gt;
  &lt;img src=&quot;https://unlockers.ai/blog/pourquoi-on-ne-delegue-pas-la-revue-de-code/intuition-vers-regles-ecrites.png&quot; alt=&quot;From intuition (&amp;quot;gut feeling&amp;quot;, &amp;quot;it depends&amp;quot;, &amp;quot;smells off&amp;quot;) to a list of written review rules an agent can execute&quot; /&gt;
  &lt;figcaption&gt;Making review explicit: from intuition to written rules an agent can execute.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;When we review a PR, we go by intuition. Ask yourself what really matters to you and what you look at first, and the answer doesn’t come right away. And from one PR to the next, we don’t review quite the same way. That’s flexible: you review a critical PR differently from a rename. But it’s also uneven, and a machine following written rules isn’t.&lt;/p&gt;
&lt;p&gt;There’s at least one sign that it helps. In a &lt;a href=&quot;https://arxiv.org/abs/2607.02389&quot;&gt;paper presented at an ICML 2026 workshop&lt;/a&gt;, a small reviewer model inspects a Python codebase with 11 planted backdoors. With no constraints and no tools, it finds 54.5% of them. With constraints enforced on the code by tooling and a small documentation tool, it reaches 90.9%. It’s a small synthetic dataset, but the result is clear: the reviewer does better when you tell it what to check.&lt;/p&gt;
&lt;h2 id=&quot;4-llms-have-jagged-abilities&quot;&gt;4. LLMs have jagged abilities&lt;/h2&gt;
&lt;figure&gt;
  &lt;img src=&quot;https://unlockers.ai/blog/pourquoi-on-ne-delegue-pas-la-revue-de-code/agent-content-faille-ignoree.png&quot; alt=&quot;A delighted agent holds up &amp;quot;naming&amp;quot; and &amp;quot;unused import&amp;quot; and announces &amp;quot;Review done!&amp;quot;, next to a wall smashed open and labelled &amp;quot;Critical flaw&amp;quot;&quot; /&gt;
  &lt;figcaption&gt;Jagged intelligence: the agent shines on the details and misses what matters.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;LLMs are excellent at some tasks and completely off at others, and we can’t yet tell in advance which one we’ll get. Andrej Karpathy calls this &lt;em&gt;jagged intelligence&lt;/em&gt;, after models that solve hard problems but get wrong whether 9.11 is bigger than 9.9 (&lt;a href=&quot;https://x.com/karpathy/status/1816531576228053133&quot;&gt;his original post&lt;/a&gt;). A Harvard, Wharton and BCG study had already described a “jagged technological frontier”, and Ethan Mollick popularised it in &lt;a href=&quot;https://www.oneusefulthing.org/p/centaurs-and-cyborgs-on-the-jagged&quot;&gt;Centaurs and Cyborgs on the Jagged Frontier&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Imagine handing the review to a colleague who, one day out of two, does remarkable work and, the other day, misses the point entirely. You wouldn’t trust them with much.&lt;/p&gt;
&lt;h2 id=&quot;5-delegating-to-an-agent-goes-through-writing&quot;&gt;5. Delegating to an agent goes through writing&lt;/h2&gt;
&lt;p&gt;With a colleague, you can say “do it with me a few times, and then you’ll know”. They watch, they understand what matters to us, and we gradually let go. With an agent, this learning by watching doesn’t exist: what you haven’t written down, it doesn’t know.&lt;/p&gt;
&lt;p&gt;You can work around it in part. Have an agent go through the whole project along with the comments left on past PRs, and ask it to draw from them a model of what matters to us in review. It isn’t perfect, but the agent picks up some of what a colleague would learn by watching us work.&lt;/p&gt;
&lt;h2 id=&quot;what-now&quot;&gt;What now?&lt;/h2&gt;
&lt;p&gt;These five brakes are real, but just making them explicit lets you deal with them, and the agent then does better than a human fairly easily.&lt;/p&gt;
&lt;p&gt;In the next post, I’ll tell you how we do it today, and what I finally have time to do instead.&lt;/p&gt;
</content:encoded><dc:creator>Johan Martinsson</dc:creator></item><item><title>Reviewing AI-written PRs sucks</title><link>https://unlockers.ai/en/blog/reviewing-ai-written-prs-sucks</link><guid isPermaLink="true">https://unlockers.ai/en/blog/reviewing-ai-written-prs-sucks</guid><description>Agents write the code, humans review all of it. An inefficient way to work and needless suffering, and four questions to get out of it.</description><pubDate>Fri, 25 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;Translated from French with AI. &lt;a href=&quot;https://unlockers.ai/blog/relire-des-pr-faites-par-l-ia&quot;&gt;Read the original&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://unlockers.ai/blog/relire-des-pr-faites-par-l-ia/citation-manuscrite.png&quot; alt=&quot;Handwritten quote, in French: “Reviewing AI-written PRs sucks.”&quot;&gt;&lt;/p&gt;
&lt;p&gt;“I loved designing code. Reviewing AI-written PRs sucks.”&lt;/p&gt;
&lt;p&gt;A developer told me that a few weeks ago. Her passion for the job had grown out of creating algorithms. She cared about how code was built and enjoyed shaping that material. The arrival of agents took that pleasure away. Instead, she reviews code she didn’t write, and wouldn’t have written that way.&lt;/p&gt;
&lt;aside class=&quot;tldr&quot;&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; Agents write the code, humans review all of it, and many find it hard to live with. In a hurry? Skip to the &lt;a href=&quot;https://unlockers.ai/en/blog/reviewing-ai-written-prs-sucks#stepping-back&quot;&gt;four questions for stepping back&lt;/a&gt;.&lt;/aside&gt;
&lt;p&gt;I was coaching her team and trying to convince them to use AI more. &lt;strong&gt;My conviction: used well, it lets you produce better code, more easily.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We weren’t on the same page. What they knew of AI was PRs generated by agents with no real guidance. The more AI we used, the more mediocre PRs they would have to swallow. With that volume, they would be tempted to merge as is, because nobody wants to fix it themselves. The code would get more verbose and less well designed, and we would end up accepting a lower bar than before. So they resisted.&lt;/p&gt;
&lt;p&gt;In other teams, I’ve seen the opposite reaction. Generate everything and put up with it. “We spend four times as long reviewing PRs. It sucks, but hey, what can you do?” They’ve accepted it. Their days are made of diffs, and they aren’t going much faster for it.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://unlockers.ai/blog/relire-des-pr-faites-par-l-ia/liste-pr-floutee.png&quot; alt=&quot;A list of 91 pull requests closed in a few days, titles blurred&quot;&gt;&lt;/p&gt;
&lt;p&gt;These two teams aren’t exceptions. In hallway conversations and at the coffee machine, I hear the same questions come back. Developers wonder what is becoming of their job. Managers wonder where the promised productivity gain went.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What I see is a situation that bothers me: an inefficient way of working, topped with needless suffering.&lt;/strong&gt; Needless, because I don’t think anything forces us to stay there. We stay because we simply haven’t thought of getting out, like the frog in slowly heating water that doesn’t jump out of the pot.&lt;/p&gt;
&lt;h2 id=&quot;an-imbalance&quot;&gt;An imbalance&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://unlockers.ai/blog/relire-des-pr-faites-par-l-ia/agent-bombarde-humain.png&quot; alt=&quot;A robot fires PRs in bursts at a developer shielding himself, a pile of PRs at his feet&quot;&gt;&lt;/p&gt;
&lt;p&gt;For writing code, we were handed powerful tools that are easy to pick up. For reviewing and deciding to merge, we were handed nothing.&lt;/p&gt;
&lt;p&gt;The result: the agent writes a large share of the code, but it reviews nothing and decides nothing. In the teams I come across, no PR is accepted by an agent. All the reviewing has stayed human, while the volume to review has exploded.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://unlockers.ai/blog/relire-des-pr-faites-par-l-ia/beaucoup-zero.png&quot; alt=&quot;Code written by an agent: lots. PRs accepted by an agent: 0 (in French)&quot;&gt;&lt;/p&gt;
&lt;p&gt;Review bots don’t change much. They comment on PRs, but as long as a human reviews everything and decides everything, they mostly add comments to read.&lt;/p&gt;
&lt;h2 id=&quot;head-down&quot;&gt;Head down&lt;/h2&gt;
&lt;p&gt;This imbalance has a cost that is less visible. The best reviewers are often the developers who know the code best. While they work through one diff after another, they aren’t building the tests and tooling that would let them review less.&lt;/p&gt;
&lt;p&gt;And nobody looks up. That, in my view, is the main reason nothing changes. There are also real difficulties, which I cover in the next post.&lt;/p&gt;
&lt;h2 id=&quot;stepping-back&quot;&gt;Stepping back&lt;/h2&gt;
&lt;p&gt;Here are four questions to take away and open up the discussion.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Is the current situation the result of a decision, or of the absence of one?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;In what situation would developers, and the rest of the team, thrive the most?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Now that we have agents, what value can only a human bring?&lt;/strong&gt; Make the list, then compare it with your calendar.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;If review, fixes and the merge decision had to be fully delegated to agents, how would you do it?&lt;/strong&gt; Whatever you would need to put in place is probably already missing today.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The next post will cover what stops us from delegating review, and the one after that, concrete setups for doing it without sacrificing quality.&lt;/p&gt;
</content:encoded><dc:creator>Johan Martinsson</dc:creator></item></channel></rss>