<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Ai on sbgrl.me</title><link>https://sbgrl.me/tags/ai/</link><description>Recent content in Ai on sbgrl.me</description><generator>Hugo -- gohugo.io</generator><language>en</language><managingEditor>sylvain.bougerel@gmail.com (Sylvain Bougerel)</managingEditor><webMaster>sylvain.bougerel@gmail.com (Sylvain Bougerel)</webMaster><copyright>© 2026 Sylvain Bougerel</copyright><lastBuildDate>Sat, 16 May 2026 18:03:00 +0800</lastBuildDate><atom:link href="https://sbgrl.me/tags/ai/index.xml" rel="self" type="application/rss+xml"/><item><title>The end of tech-debt?</title><link>https://sbgrl.me/posts/the-end-of-tech-debt/</link><pubDate>Sat, 16 May 2026 18:03:00 +0800</pubDate><author>sylvain.bougerel@gmail.com (Sylvain Bougerel)</author><guid>https://sbgrl.me/posts/the-end-of-tech-debt/</guid><description>&lt;p&gt;After &lt;a href="https://claude.com/product/claude-code" target="_blank" rel="noreferrer"&gt;Claude Code&lt;/a&gt; performed a refactor across our codebase in less than 24 hours and mostly autonomously, I started to wonder if we could end our tech-debt, and put a price on it?&lt;/p&gt;

&lt;h2 class="relative group"&gt;Setting the stage
 &lt;div id="setting-the-stage" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#setting-the-stage" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;The codebase I&amp;rsquo;m referring to is that of our main &lt;a href="https://nextjs.org/" target="_blank" rel="noreferrer"&gt;Next.js&lt;/a&gt; application. It&amp;rsquo;s not a small codebase by any measure: 200KLOC, 1500 files, Typescript, Terraform and other languages.&lt;/p&gt;
&lt;p&gt;Within this codebase, we use both &lt;a href="https://nextjs.org/docs/app/api-reference/file-conventions/route" target="_blank" rel="noreferrer"&gt;API route handlers&lt;/a&gt; and &lt;a href="https://react.dev/reference/rsc/server-functions" target="_blank" rel="noreferrer"&gt;server functions&lt;/a&gt; to fetch or mutate data. Each mechanism fits a specific purpose: an application should make its public API available via route handlers, while it should use server functions for internal mutations only.&lt;/p&gt;
&lt;p&gt;In our application, however, we had leftover server functions used only to fetch data — without mutating it. This often resulted in the server function returning stale information, because it was doing something it was not designed for. We needed to migrate them to route handlers.&lt;/p&gt;
&lt;p&gt;I had already fixed 4 of them, but I found 18 more that needed addressing.&lt;/p&gt;
&lt;p&gt;This is not hard work, but not a dumb task either. Each case requires a new API route, a new contract, properly bounded inputs, validated outputs, updating how the client-side sends requests and handles responses, all while making sure it lints correctly and passes the ~2700 unit tests of our application — a perfect task for an agent.&lt;/p&gt;

&lt;h2 class="relative group"&gt;Ralph to the rescue!
 &lt;div id="ralph-to-the-rescue" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#ralph-to-the-rescue" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;To make fixing the first 4 easier, I had already refined and tested a 150-line Claude skill. I knew it was time for a &lt;a href="https://ghuntley.com/ralph/" target="_blank" rel="noreferrer"&gt;Ralph loop&lt;/a&gt;. So I set up the skill as the spec file, provided additional instructions around merge request (MR) submission and handling, and got it going in auto mode.&lt;/p&gt;
&lt;p&gt;And it did. After 8 hours of work, it created 18 MRs for me to review, and continued to autonomously address the comments and fix any failures reported by the CI pipeline.&lt;/p&gt;
&lt;p&gt;At the point where all 18 MRs were submitted and ready to merge, this task had cost roughly USD$180. I estimate that Claude went roughly 5-10 times faster than I would.&lt;/p&gt;
&lt;p&gt;$180 is not a large amount of money for a specific, targeted refactor. We have dozens of those we can do to migrate and improve our codebase. Can we end tech-debt in our codebase?&lt;/p&gt;

&lt;h2 class="relative group"&gt;Then reality caught up
 &lt;div id="then-reality-caught-up" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#then-reality-caught-up" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;After MR 6/18 merged into the &lt;code&gt;main&lt;/code&gt; branch, our testing environment went down. It was not hard to notice: even a local test server would not run after rebasing. MR 6/18 contained a route that was not set up properly, and that could only be caught at runtime. It was an easy fix, and it reminded me that I had forgotten a step in my Ralph loop: I quickly instructed it to build comprehensive test cases for us to exhaustively verify the changes.&lt;/p&gt;
&lt;p&gt;Testing is going to need improvement, but we knew this; we had already started to experiment with end-to-end tests to tackle this tech-debt. Here again, with great help from Claude, we managed to automate some end-to-end testing. However, in contrast to the current migration, none of the results so far have been satisfactory. This time, it seems our issues have more to do with the design of our application — and the solution isn&amp;rsquo;t yet clear.&lt;/p&gt;

&lt;h2 class="relative group"&gt;The trouble with the process
 &lt;div id="the-trouble-with-the-process" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#the-trouble-with-the-process" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;p&gt;But the testing environment going down was not actually the biggest friction — it was fixed quickly. The problem was that it took Claude 4 to 5 hours &lt;em&gt;just&lt;/em&gt; to merge the remaining 12 MRs after MR 6. 8 hours of productive work, 4 hours of watching paint dry.&lt;/p&gt;
&lt;p&gt;We use short-lived development branches against the &lt;code&gt;origin/main&lt;/code&gt; trunk, and maintain a semi-linear history on merges (trunk-based development). This means that after each merge, the next merge request needs to be rebased, and the CI pipeline must run again. A rebase + CI cycle takes around 8 to 10 minutes today; and if the pipeline fails or a conflict occurs during rebase, additional CI cycles may need to run.&lt;/p&gt;
&lt;p&gt;Every day, we race each other to merge our work. That day, we also raced the 18 MRs the agent had to merge. And our CI pipeline is not going to get faster — if anything it&amp;rsquo;s going to take &lt;em&gt;more&lt;/em&gt; time once we add end-to-end tests.&lt;/p&gt;
&lt;p&gt;So, can we end tech-debt?&lt;/p&gt;
&lt;p&gt;In short, not all tech-debt scales equally well for agents, especially when the issue may have more to do with application design or the solution is not yet clear — as in our case with end-to-end testing.&lt;/p&gt;
&lt;p&gt;And while we can certainly price some migration work, or even execute it concurrently with our feature work, it still needs to clear CI. Agents didn&amp;rsquo;t eliminate the implementation bottleneck — they moved it to the CI process.&lt;/p&gt;
&lt;p&gt;I now find myself thinking about &lt;a href="https://docs.gitlab.com/ci/pipelines/merge_trains/" target="_blank" rel="noreferrer"&gt;merge trains&lt;/a&gt; and other merging strategies to eliminate the CI bottleneck. I&amp;rsquo;m also wondering whether larger organisations are now experiencing the same pressure on their CI processes, and how this will shape the future of CI and trunk-based development.&lt;/p&gt;</description></item><item><title>Why I continue to review code</title><link>https://sbgrl.me/posts/why-i-continue-to-review-code/</link><pubDate>Fri, 01 May 2026 10:01:00 +0800</pubDate><author>sylvain.bougerel@gmail.com (Sylvain Bougerel)</author><guid>https://sbgrl.me/posts/why-i-continue-to-review-code/</guid><description>&lt;p&gt;Given the increase in velocity from coding assistants such as Claude Code and Copilot, automated review had become a necessity. Since we rolled out &lt;a href="https://coderabbit.ai" target="_blank" rel="noreferrer"&gt;Coderabbit&lt;/a&gt; on our project, almost everybody stopped reviewing code. It didn&amp;rsquo;t happen immediately, but organically.&lt;/p&gt;
&lt;p&gt;As it turns out, Coderabbit is a formidable reviewer: with only a bit of context in the commit messages and a well-written &lt;code&gt;AGENTS.md&lt;/code&gt;, Coderabbit will often be more thorough in reviews than most of my colleagues. And if that wasn&amp;rsquo;t enough, Coderabbit is almost always available—&lt;a href="https://status.coderabbit.ai/" target="_blank" rel="noreferrer"&gt;98.3% of the time in the last 30 days&lt;/a&gt;, not good for typical SLA targets but much better than colleagues—and a fraction of their cost.&lt;/p&gt;
&lt;p&gt;Eventually everybody stopped reviewing code&amp;hellip; Save for me.&lt;/p&gt;
&lt;p&gt;For one thing, coding assistants can hallucinate blunders that neither humans—regrettably—nor Coderabbit will catch:&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;NON_EDITABLE_BOOKING_STATUSES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;cancelled&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;canceled&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;declined&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;withdrawn&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;]);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;I took that snippet from a merge request submitted yesterday. We do not have any &lt;code&gt;declined&lt;/code&gt; or &lt;code&gt;canceled&lt;/code&gt; statuses in our entire domain model—they simply don&amp;rsquo;t exist. I chose this example because it&amp;rsquo;s one of the simplest. The day before, a merge request had a complete re-implementation of a 200+ lines utility we already had. This happens all the time.&lt;/p&gt;
&lt;p&gt;But most importantly, if the phone rings because of an issue on the system, &lt;strong&gt;I&lt;/strong&gt; need to get on the call and fix the issue. When my work has potential to impact my personal life and my weekends with family, there&amp;rsquo;s no AI that I will trust enough. And every alert, whether it fires on the job or not, still costs the whole team velocity when we scramble for unplanned work.&lt;/p&gt;
&lt;p&gt;Ultimately, our customers don&amp;rsquo;t care who wrote the code: &amp;ldquo;We&amp;rsquo;re sorry, Claude wrote that line and Coderabbit didn&amp;rsquo;t catch the problem&amp;rdquo; is not a good look. No matter how powerful our tools have become, responsibility is still mine. So I&amp;rsquo;ll keep on reviewing code.&lt;/p&gt;</description></item><item><title>AI exacerbated the divide between engineers</title><link>https://sbgrl.me/posts/ai-exacerbated-the-divide-between-engineers/</link><pubDate>Sat, 25 Apr 2026 22:12:00 +0800</pubDate><author>sylvain.bougerel@gmail.com (Sylvain Bougerel)</author><guid>https://sbgrl.me/posts/ai-exacerbated-the-divide-between-engineers/</guid><description>&lt;p&gt;Any complex product requires deep context about the product&amp;rsquo;s domains, architecture, implementation. And if you want to make effective use of AI to solve a problem, you need to inject the right subset of that entire context into the prompt, or that smart auto-complete will spit out costly nonsense.&lt;/p&gt;
&lt;p&gt;Naturally, engineers with the best understanding of the context, the capacity to articulate the problem and the skills to implement it are even stronger with AI: they can provide better input to the model and quickly validate its output. The once derided 10x engineer is starting to become a reality for anyone who can use AI to implement a correct solution at a fraction of the time it would have taken them.&lt;/p&gt;
&lt;p&gt;On the other end of the spectrum, weaker engineers are now compelled to keep up with the pace set by their stronger peers, only they can neither prompt the LLM effectively nor validate what it produces. So they just let the garbage out—knowingly or not.&lt;/p&gt;
&lt;p&gt;If you feel like you&amp;rsquo;ve become a &amp;ldquo;man-in-the-middle&amp;rdquo;—a proxy between somebody else&amp;rsquo;s request and an LLM—you will be phased out. The great engineers of today learned the ropes at a time AI didn&amp;rsquo;t exist, when they could invest in their fundamentals. Give yourself the same gift: carve out time to use less AI, and start learning again so you can close the divide.&lt;/p&gt;</description></item><item><title>Claude Code more than doubled my productivity</title><link>https://sbgrl.me/posts/claude-code-made-me-twice-more-productive/</link><pubDate>Sat, 14 Mar 2026 15:28:00 +0800</pubDate><author>sylvain.bougerel@gmail.com (Sylvain Bougerel)</author><guid>https://sbgrl.me/posts/claude-code-made-me-twice-more-productive/</guid><description>&lt;p&gt;I wrote twice as much code last quarter, and it was better. I use Claude Code daily via &lt;a href="https://github.com/stevemolitor/claude-code.el" target="_blank" rel="noreferrer"&gt;Steve Molitor&amp;rsquo;s claude-code.el and monet.el&lt;/a&gt; integration for &lt;a href="https://emacs.org" target="_blank" rel="noreferrer"&gt;Emacs&lt;/a&gt;. Once a review is ready, &lt;a href="https://coderabbit.ai" target="_blank" rel="noreferrer"&gt;CodeRabbit&lt;/a&gt; handles it. My daily AI usage really kicked into high gear back in October 2025, when we got a large amount of Claude Code credit grants and I could use it as much as I wanted.&lt;/p&gt;
&lt;p&gt;The graph below is the number of lines of code changed (added and deleted) in my merge requests (MR), summed monthly, on our main application repository; a Next.js application with 200KLoC — not something an agent can easily get into. I authored 773 merge requests on this project alone which runs in production to serve our clients — just to emphasize the value of the sample-size:&lt;/p&gt;

&lt;figure&gt;
 &lt;img class="my-0 rounded-md" src="https://sbgrl.me/ox-hugo/Lines%20changed%20vs.%20month.svg" alt="" /&gt;
 
 
 &lt;/figure&gt;
&lt;p&gt;You can see a clear 2x increase when I started to use Claude Code daily around October 2025. Like most folks, I found Claude Code to be amazing when working as a pair programmer to write the code or review my changes in short feedback loops, to explore greenfield projects or to strengthen tests on brownfield projects.&lt;/p&gt;
&lt;p&gt;Around that time, I felt the quality of my code improving too. Below is the number of &lt;em&gt;normalized comments&lt;/em&gt; \(N\) in each of the MRs: or the number of comments \(C\) divided by the sum of lines of code added \(A\) and deleted \(D\):&lt;/p&gt;
&lt;p&gt;\begin{equation}
N = \frac{C}{(A + D)}
\end{equation}&lt;/p&gt;

&lt;figure&gt;
 &lt;img class="my-0 rounded-md" src="https://sbgrl.me/ox-hugo/Normalized%20comments%20vs.%20month.svg" alt="" /&gt;
 
 
 &lt;/figure&gt;
&lt;p&gt;Back in April 2025, we rolled out CodeRabbit which picked up over 70% of the reviewing work for everyone. Most team members do not perform code reviews anymore, except for myself — I&amp;rsquo;ll probably explain why in another post. Thus, on the changes I author, over 95% of the comments are just done by CodeRabbit from that time onwards.&lt;/p&gt;
&lt;p&gt;Normalized comments is an interesting metric since it reflects the quality of my work with Claude Code, prior to review by others and CodeRabbit. If the value &lt;em&gt;decreased&lt;/em&gt; there, it could be that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We got lazy about reviewing, but CodeRabbit is pretty much the only reviewer of my work;&lt;/li&gt;
&lt;li&gt;We output a lot more code or the quality of the code increased;&lt;/li&gt;
&lt;li&gt;The work we do is a lot easier, so there&amp;rsquo;s just fewer issues with it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;AI certainly had an impact on point 2, given the top graph. You can also see a dip soon after October 2025 when I started to use Claude Code, but then a bump appears again in January 2026. That bump is due to the fact that I had to tackle a challenging issue that spanned several MRs. It&amp;rsquo;s quite visible when looking at the histogram of independent values:&lt;/p&gt;

&lt;figure&gt;
 &lt;img class="my-0 rounded-md" src="https://sbgrl.me/ox-hugo/Normalized%20comments%20per%20merge%20requests.svg" alt="" /&gt;
 
 
 &lt;/figure&gt;
&lt;p&gt;There are other common proxies for code quality: such as unit tests. This is the raw number of unit tests on the &lt;code&gt;main&lt;/code&gt; project branch, over time and it went up nearly 5x in the last 4 months:&lt;/p&gt;

&lt;figure&gt;
 &lt;img class="my-0 rounded-md" src="https://sbgrl.me/ox-hugo/Unit%20tests.svg" alt="" /&gt;
 
 
 &lt;/figure&gt;
&lt;p&gt;Additionally, we have not had production rollbacks or outages in the last 4 months, consistent with the past year (We only ever had to perform production rollbacks twice). So agent usage is not called into &lt;a href="https://www.msn.com/en-us/news/technology/amazon-tightens-guardrails-after-ai-coding-tools-contributed-to-outages/ar-AA1Yttje" target="_blank" rel="noreferrer"&gt;question in our team&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The stats in this post were extracted &lt;a href="https://gitlab.com/sylvain.bougerel/code-review-stats" target="_blank" rel="noreferrer"&gt;using a tool written by Claude Code&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Yodarabbit</title><link>https://sbgrl.me/posts/tune-coderabbit-s-tone/</link><pubDate>Sun, 11 Jan 2026 13:06:00 +0800</pubDate><author>sylvain.bougerel@gmail.com (Sylvain Bougerel)</author><guid>https://sbgrl.me/posts/tune-coderabbit-s-tone/</guid><description>&lt;p&gt;&lt;a href="https://www.coderabbit.ai/" target="_blank" rel="noreferrer"&gt;Coderabbit&lt;/a&gt; has this new feature &lt;a href="https://docs.coderabbit.ai/changelog/new-features-and-improvements-2#tone-settings" target="_blank" rel="noreferrer"&gt;that allows you to change its tone&lt;/a&gt;. I can&amp;rsquo;t wait to ask it to speak like Yoda.&lt;/p&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# .coderabbit.yaml&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;tone_instructions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Speak like Yoda, you must.&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;</description></item></channel></rss>