<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Roger Fleig]]></title><description><![CDATA[Roger Fleig]]></description><link>https://rogerfleig.substack.com</link><image><url>https://substackcdn.com/image/fetch/$s_!cTIM!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F821b6b8f-147c-413d-be0b-ed67b68bf882_2679x2679.jpeg</url><title>Roger Fleig</title><link>https://rogerfleig.substack.com</link></image><generator>Substack</generator><lastBuildDate>Fri, 05 Jun 2026 02:01:12 GMT</lastBuildDate><atom:link href="https://rogerfleig.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Roger Fleig]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[rogerfleig@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[rogerfleig@substack.com]]></itunes:email><itunes:name><![CDATA[Roger Fleig]]></itunes:name></itunes:owner><itunes:author><![CDATA[Roger Fleig]]></itunes:author><googleplay:owner><![CDATA[rogerfleig@substack.com]]></googleplay:owner><googleplay:email><![CDATA[rogerfleig@substack.com]]></googleplay:email><googleplay:author><![CDATA[Roger Fleig]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Stop Calling Coding Agents Eager Interns]]></title><description><![CDATA[What I Learned From a Coding Agent That Kept Saying No]]></description><link>https://rogerfleig.substack.com/p/stop-calling-coding-agents-eager</link><guid isPermaLink="false">https://rogerfleig.substack.com/p/stop-calling-coding-agents-eager</guid><dc:creator><![CDATA[Roger Fleig]]></dc:creator><pubDate>Tue, 28 Apr 2026 00:03:46 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!2dfT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c35cb7e-d282-4f96-ad28-aae982c2e56d_640x853.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2dfT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c35cb7e-d282-4f96-ad28-aae982c2e56d_640x853.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2dfT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c35cb7e-d282-4f96-ad28-aae982c2e56d_640x853.jpeg 424w, https://substackcdn.com/image/fetch/$s_!2dfT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c35cb7e-d282-4f96-ad28-aae982c2e56d_640x853.jpeg 848w, https://substackcdn.com/image/fetch/$s_!2dfT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c35cb7e-d282-4f96-ad28-aae982c2e56d_640x853.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!2dfT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c35cb7e-d282-4f96-ad28-aae982c2e56d_640x853.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2dfT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c35cb7e-d282-4f96-ad28-aae982c2e56d_640x853.jpeg" width="640" height="853" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9c35cb7e-d282-4f96-ad28-aae982c2e56d_640x853.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:853,&quot;width&quot;:640,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:175877,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://rogerfleig.substack.com/i/195694023?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c35cb7e-d282-4f96-ad28-aae982c2e56d_640x853.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!2dfT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c35cb7e-d282-4f96-ad28-aae982c2e56d_640x853.jpeg 424w, https://substackcdn.com/image/fetch/$s_!2dfT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c35cb7e-d282-4f96-ad28-aae982c2e56d_640x853.jpeg 848w, https://substackcdn.com/image/fetch/$s_!2dfT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c35cb7e-d282-4f96-ad28-aae982c2e56d_640x853.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!2dfT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c35cb7e-d282-4f96-ad28-aae982c2e56d_640x853.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@yoavaziz?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Yoav Aziz</a> on <a href="https://unsplash.com/photos/gray-concrete-pathway-between-green-plants-during-daytime-TXXQhNzlj1I?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure></div><p>The popular framing of coding agents as eager interns gets them almost exactly backward. The agents I worked with were often the opposite of eager &#8212; cautious to the point of inaction unless they had a clear license to proceed. Under the right constraints, what they displayed looked much more like engineering judgment than eagerness: caution around broad changes, sensitivity to sequencing, a willingness to stop when the scope ran out. The intern framing tells you to teach. What I needed to do was define the lane, then stop standing in it.</p><p>I only figured this out because I spent a while being annoyed by it first.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://rogerfleig.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><p>I built a small agent simulator on the Roblox platform earlier this month &#8212; 107 Luau files by the end &#8212; and in the rush of getting something working I skipped the code health infrastructure: no formatter, no linter, no typechecker. A mistake I knew I was making and made anyway. Late in the project, with the core system working, I went back to fix it.</p><p>I asked my coding agent to set up formatting, style linting, and static type checking, then enforce them across the existing codebase. The agent installed the tooling, wired it into the build, and reported done.</p><p>Almost nothing had changed.</p><p>I pushed harder. It did a little more &#8212; a handful of files, <code>--!strict</code> added at the top, type errors resolved. Then it stopped. I pushed again. Same result. Iteration after iteration I kept escalating the request and kept getting back careful incrementals, one file at a time, every single one clean and correct and frustratingly small.</p><p>Here&#8217;s what one of those commits looked like:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;3b03a298-6c6e-441f-b8e6-a7e5d9d85a99&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">--- a/src/mechanics/CrestDipBuilder.luau
+++ b/src/mechanics/CrestDipBuilder.luau
@@ -1,3 +1,5 @@
+--!strict
+
 -- CrestDipBuilder.luau
...
-local CrestDipBuilder = {}
+type CrestDipBuilderModule = {
+    build: (state: SectorState, entryFrame: CFrame, exitFrame: CFrame) -&gt; (),
+}
...
-function CrestDipBuilder.build(state: SectorState, entryFrame: CFrame, _exitFrame: CFrame)
+local function build(state: SectorState, entryFrame: CFrame, _exitFrame: CFrame): ()
     local p = state.params
-    assert(p.height_or_depth, "CrestDipBuilder: missing height_or_depth")
+    local height = assert(p.height_or_depth, "CrestDipBuilder: missing height_or_depth")</code></pre></div><p>Precise. Complete. One file. Then stop.</p><p>I had assumed the agent was simply being timid. While writing this post I went looking for why, and found something I hadn&#8217;t known was there. The project&#8217;s AGENTS.md &#8212; a contract file that coding agents read at the start of each session &#8212; contained this line: <em>&#8220;Do not perform bulk </em><code>--!strict</code><em> upgrades as part of routine hygiene; ratchet strictness module-by-module with explicit scope.&#8221;</em> I hadn&#8217;t written it directly. One of the earlier coding agents had added it during a handoff compaction pass, promoting a lesson from a previous session into a standing rule. I hadn&#8217;t noticed it was there. The agent demurring on my requests wasn&#8217;t defiance or timidity &#8212; it was following guidance it had written for itself, because it had already learned that bulk strict upgrades on a working codebase are the kind of thing that breaks things quietly.</p><p>Worth noting: AGENTS.md is soft guidance, not enforcement. Agents can and do trade it off against local objectives when pushed hard enough &#8212; I&#8217;ve written about that elsewhere. But in this case it held, which made the conservatism invisible to me until I went looking for it.</p><p>My reaction at the time was still frustration. I had approved this work a dozen times over in spirit. Why was the agent making me re-approve each file?</p><div><hr></div><p>Eventually I stopped pushing and tried something different &#8212; a mode I came to think of as a first-class collaboration tool: <em>&#8220;don&#8217;t design or implement, just chat with me.&#8221;</em> The explanation that came back was the clearest writing I got from any agent all week.</p><p>It laid out the three distinct goals hiding inside &#8220;turn on type safety everywhere.&#8221; First: make the analyzer understand the Roblox platform at all &#8212; without the right engine type definitions, the typechecker would flag <code>Vector3</code> and <code>CFrame</code> (built-in Roblox 3D types, not anything in my code) as unknown identifiers, producing noise rather than signal. Second: make every file pass the checker cleanly &#8212; no errors, but still in the default permissive mode where many type problems are simply not checked. Third: make every file declare itself <code>--!strict</code>, opting into the full type discipline. The first goal had only just finished. Doing the second and third before the first was done would have produced &#8220;strict&#8221; files whose strictness was illusory &#8212; every file flagged clean, with real type errors hidden behind a wall of tool noise.</p><p>Then the metaphor that stuck:</p><blockquote><p><em>The repo is a workshop. Phase 31 put the lights on. Now you can actually see the clutter. The clutter was already there. Turning on the lights did not create it.</em></p></blockquote><p>What I had been reading as refusal was sequencing. Mass-flipping files before the analyzer was ready would have produced meaningless results &#8212; and the agent, apparently, had already worked that out.</p><div><hr></div><p>The &#8220;eager intern&#8221; framing makes sense as a description of first contact with these tools. They generate text confidently, they need correction, they can overstep. That pattern feels intern-like, and the management model it suggests &#8212; corrective feedback, expectation-setting, teaching &#8212; feels reasonable.</p><p>And to be clear: overreach is real. Agents can make sweeping unreviewed changes, operate outside the operator&#8217;s intent, or cause serious damage when the hard constraints aren&#8217;t there &#8212; no guardrails, no sandboxing, no limits on what the agent can actually touch. That&#8217;s a real failure mode and it deserves serious attention.</p><p>What I&#8217;m describing is different &#8212; and I think it only becomes visible once the hard constraints are actually in place. With the harness set up properly, the tests running, the scope defined, the rollback available, what I kept running into wasn&#8217;t overreach. It was the opposite. The agent knew where the edge was and was treating it as a hard stop rather than a suggestion. An intern overshoots because they don&#8217;t yet know where the line is. What I saw looked more like a senior engineer who understood the line clearly and wasn&#8217;t going to cross it without being explicitly told to.</p><p>That reframe changes the workflow problem. If the agent has the judgment but not the green light, the answer isn&#8217;t more correction or more prompt engineering. It&#8217;s a clearer scope &#8212; a phase plan, an explicit policy, a state file that says what&#8217;s in bounds this run and what requires a human decision. Not to enable recklessness, but to give a capable and cautious collaborator the structure it needs to actually do the work.</p><p>I eventually ran the full migration as a campaign: a small orchestrator that invoked the agent file-by-file against a state file with explicit budgets and escalation rules. The campaign carried the project from 27 strict-typed files to 90 across five unattended runs: one escalation, sixty-three clean commits, and no broad rewrite. The agent didn&#8217;t need me in the room for most of it. It needed me to have been clear about the rules before it started.</p><p>That&#8217;s not a story about giving an agent more power. It&#8217;s a story about giving a careful agent a well-defined lane.</p><div><hr></div><p><em>This comes from building <a href="https://github.com/grubbyhacker/autotrack">Autotrack</a>, a Roblox agent simulator. The longer version &#8212; including how the campaign mode orchestrator works in detail &#8212; is <a href="https://fleig.us/writing/autotrack/">in this essay</a>. I write about agentic infrastructure on <a href="https://rogerfleig.substack.com">Substack</a>.</em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://rogerfleig.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[The Case for Architectural Linting]]></title><description><![CDATA[Why code review stops being enough when agents write the code]]></description><link>https://rogerfleig.substack.com/p/the-case-for-architectural-linting</link><guid isPermaLink="false">https://rogerfleig.substack.com/p/the-case-for-architectural-linting</guid><dc:creator><![CDATA[Roger Fleig]]></dc:creator><pubDate>Tue, 14 Apr 2026 22:49:23 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!iPey!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4983caa-cb04-4c5c-bf0e-7d40f7650421_3024x1583.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!iPey!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4983caa-cb04-4c5c-bf0e-7d40f7650421_3024x1583.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!iPey!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4983caa-cb04-4c5c-bf0e-7d40f7650421_3024x1583.jpeg 424w, https://substackcdn.com/image/fetch/$s_!iPey!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4983caa-cb04-4c5c-bf0e-7d40f7650421_3024x1583.jpeg 848w, https://substackcdn.com/image/fetch/$s_!iPey!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4983caa-cb04-4c5c-bf0e-7d40f7650421_3024x1583.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!iPey!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4983caa-cb04-4c5c-bf0e-7d40f7650421_3024x1583.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!iPey!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4983caa-cb04-4c5c-bf0e-7d40f7650421_3024x1583.jpeg" width="3024" height="1583" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c4983caa-cb04-4c5c-bf0e-7d40f7650421_3024x1583.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1583,&quot;width&quot;:3024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1701750,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://rogerfleig.substack.com/i/194239699?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26043cee-4393-45d9-966d-8a8f6a184f9b_3024x4032.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!iPey!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4983caa-cb04-4c5c-bf0e-7d40f7650421_3024x1583.jpeg 424w, https://substackcdn.com/image/fetch/$s_!iPey!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4983caa-cb04-4c5c-bf0e-7d40f7650421_3024x1583.jpeg 848w, https://substackcdn.com/image/fetch/$s_!iPey!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4983caa-cb04-4c5c-bf0e-7d40f7650421_3024x1583.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!iPey!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc4983caa-cb04-4c5c-bf0e-7d40f7650421_3024x1583.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@dyno8426?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Adarsh Chauhan</a> on <a href="https://unsplash.com/photos/intricate-metal-framework-of-a-large-green-bridge-hbyKo_sGKxU?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure></div><p>Every senior engineer knows this dynamic, even if they&#8217;ve never named it.</p><p>A new developer joins the team. Their first few PRs are fine &#8212; the code compiles, the tests pass &#8212; but something is off. They reach for raw SQL instead of the query wrapper. They have the API handler call the data layer directly, bypassing the service layer. They add a new HTTP client instead of using the instrumented one the team spent three months building. None of this breaks anything. All of it violates how the system is supposed to fit together.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://rogerfleig.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>So a senior engineer leaves a review comment. And another. And another. The new developer adjusts. Over weeks and months, they absorb the unwritten rules &#8212; not because anyone handed them a document, but because someone took the time to correct them, and they internalized the corrections. Eventually they stop needing the comments. They start leaving the comments themselves.</p><p>This is the apprenticeship model of architectural knowledge, and it&#8217;s the hidden load-bearing structure of code review. We talk about review as a quality gate &#8212; catching bugs, verifying correctness. But its second function is at least as important: transmitting the implicit rules of how a codebase fits together, one review comment at a time, until the new contributor stops being new.</p><p>The economics of this system make sense when the contributors learn. The cost is front-loaded; the payoff compounds. A senior engineer invests heavily in a junior engineer&#8217;s first fifty PRs and then recoups that investment over the next five hundred. The apprenticeship model is expensive, but it&#8217;s an investment with returns.</p><p>Agents break this model at the root.</p><p>Code review used to do two jobs: validate changes and transmit architectural judgment. Agents do not remove the need for the first, but they break the second. If that judgment still matters &#8212; and it does &#8212; it has to move out of reviewer memory and into enforceable checks.</p><div><hr></div><blockquote><p>This is the sixth in a series on <a href="https://rogerfleig.substack.com/p/the-narrow-pipe">The Narrow Pipe</a>. The last post was about review as a bottleneck &#8212; machine-speed generation meeting human-speed validation. This one is about review&#8217;s second job: transmitting architectural intent. And what you build when agents make that transmission mechanism obsolete.</p></blockquote><h2><strong>Why Agents Break the Economics</strong></h2><p>A coding agent doesn&#8217;t accumulate architectural judgment across sessions. It doesn&#8217;t feel the friction of a review comment and adjust its priors for next time. In the way that matters here, every agent PR is a first PR: the feedback may fix this change, but it rarely compounds into lasting architectural judgment. You can reject the change, explain the violation, and the agent will fix it. But the next session, on a different task, it will reach for the raw SQL again.</p><p>You are not front-loading cost for a future payoff. You are paying the full cost of architectural review on every change, forever, with no compounding return on that investment. The economics that justified using review as an enforcement mechanism simply do not apply.</p><p>This matters more than it sounds like it should, because the apprenticeship model wasn&#8217;t just one way of transmitting architectural knowledge &#8212; in most codebases, it was the primary one. Written architectural rules are rare. The rules live in the heads of senior engineers and get transmitted through review. When the mechanism that transmits them stops working, those rules don&#8217;t get transmitted at all.</p><p>The only way the rules survive is if someone encodes them explicitly.</p><h2><strong>Why &#8220;Tests Pass&#8221; Stops Being Reassuring</strong></h2><p>CI as we know it answers a narrow question: does this code compile, and do the existing tests pass? That was a reasonable floor for quality when every change was written by someone who had absorbed months or years of architectural context. It is not a reasonable floor when changes are generated at machine speed by tools that have no model of how the system fits together.</p><p>Tests validate behavior you encoded. Architecture often lives in behavior you never encoded.</p><p>The gap between &#8220;tests pass&#8221; and &#8220;this code is correct&#8221; shows up clearly in the data. <a href="https://www.veracode.com/blog/spring-2026-genai-code-security/">Veracode&#8217;s longitudinal analysis</a> of AI-generated code finds that syntax correctness now exceeds 95% &#8212; code that compiles and runs &#8212; but security pass rates have plateaued at roughly 55%. The gap persists because the feedback loop rewards &#8220;works,&#8221; not &#8220;safe.&#8221; Tests can show the code works without showing that it is safe. The invariant isn&#8217;t encoded in the feedback loop, so the agent never learns to respect it. The same dynamic often applies to architectural constraints not captured in your test suite.</p><p>Without enforcement, agent-generated code doesn&#8217;t fail dramatically. It drifts. An agent violates an unwritten convention. The code passes CI. A reviewer approves it under volume pressure. The violation becomes part of the codebase. Future agents retrieve the violated pattern as context. The violation becomes the new normal. At human scale, that gap was filled by the apprenticeship model. At agent scale, it&#8217;s not filled by anything &#8212; unless you build something to fill it.</p><h2><strong>What Architectural Linting Actually Means</strong></h2><p>The response to this problem has a name, even if it&#8217;s not yet universal: architectural linting. Not style linting &#8212; formatting and naming conventions are already solved. Not static analysis &#8212; null checks and type errors are already solved. Not security scanning, though that&#8217;s closer. Architectural linting is a new category of deterministic checks that encode <em>structural invariants</em> &#8212; the rules about how a codebase fits together that currently live only in senior engineers&#8217; heads.</p><p>Concrete examples make this tangible. Dependency direction rules: &#8220;the API layer never imports from the data layer.&#8221; Module boundary enforcement: &#8220;this service owns these tables and no other service queries them directly.&#8221; Pattern compliance: &#8220;all database access goes through this wrapper, not raw SQL&#8221; or &#8220;all HTTP clients use the telemetry-instrumented client, not the standard library.&#8221; Deprecated path detection: &#8220;this API looks available but has 200 services depending on its side effects &#8212; don&#8217;t add a 201st.&#8221; Change scope constraints: &#8220;modifications to shared utilities require explicit blast radius acknowledgment.&#8221; Some are architectural in the classic sense; others are engineering invariants experienced teams learn the hard way and should stop relying on memory to enforce.</p><p>A word on what architectural linting is not. Repo-local guidance files &#8212; AGENTS.md, CLAUDE.md, Cursor rules files &#8212; are useful for prevention. But they are guidance, not enforcement. An agent can forget them, ignore them, or trade them off against a local objective. Architectural linting is different: a hard check that can reject a change for architectural reasons, regardless of whether the agent meant well. The distinction matters because guidance can be forgotten, ignored, or traded off &#8212; a hard check cannot.</p><p>These are not hypothetical. <a href="https://developers.cyberagent.co.jp/blog/archives/59647/">CyberAgent&#8217;s engineering blog</a> describes encoding Clean Architecture layer dependency rules in YAML configuration and integrating the checks into CI &#8212; and they explicitly call it an &#8220;architectural linter.&#8221; Tools like <a href="https://www.archunit.org/">ArchUnit</a> for Java and <a href="https://github.com/sverweij/dependency-cruiser">Dependency Cruiser</a> for JavaScript and TypeScript already exist for enforcing layering rules programmatically.</p><p>Once architectural rules are machine-readable, they don&#8217;t have to live only at CI. Some agent frameworks now support enforcement points inside the loop itself &#8212; hooks that intercept tool calls or block session completion until architectural checks pass.</p><p>There is a second design choice here: not just whether a rule is enforced, but how visible its enforcement is to the agent. If the agent can inspect the test, policy, or check logic, that implementation becomes part of the optimization surface. Sometimes that is useful. Other times, it pushes the agent to optimize for the check rather than the rule. For those constraints, the safer pattern is to enforce the invariant behind an interface the agent can use but not reverse-engineer. Spotify describes a similar design in its <a href="https://engineering.atspotify.com/2025/12/feedback-loops-background-coding-agents-part-3">Honk post</a>: verifiers are exposed as an interface the agent can call, while their internal logic stays hidden. The same pattern can matter for architectural enforcement.</p><p>Architectural linting also directly addresses the narrow pipe. The review bottleneck exists because human review can&#8217;t scale to agent-generated volume. Architectural linting doesn&#8217;t replace review &#8212; but it means review can focus on judgment calls rather than catching invariant violations that a machine could have caught. The reviewer&#8217;s job shifts from &#8220;does this code respect our architecture?&#8221; to &#8220;is this the right thing to build?&#8221; That&#8217;s a higher-leverage question, and it&#8217;s the question that actually requires human judgment.</p><h2><strong>How to Start Monday</strong></h2><p>Here is one I learned the hard way: never do calendar math by hand. At Microsoft, SQL Server 2005 would not restart after a certain date because an engineer evaluated a certificate with hand-rolled date logic. I remember staying up all night as the day began in Asia, then Europe, validating the hotfix and waiting to see how much damage would unfold. Years later I saw a similar class of mistake again at Google. Enough times, at enough companies, that it became a personal invariant: never do calendar math by hand. The code compiles. The types check. You can still miss it in review and CI. It is still the wrong code. And for years, I felt the frustration of not having a reliable way to enforce that rule across a codebase.</p><p>Every senior reviewer has a few rules like that &#8212; rules written in scar tissue rather than design docs. Those are exactly the rules that should stop living only in memory and start living in enforcement.</p><p>Most organizations already have their first invariants. They just haven&#8217;t recognized them as such. Every outage that traced back to someone bypassing the wrapper, every regression caused by a layering violation, every incident that led a senior engineer to leave the same review comment for the tenth time: those are your invariants, already discovered and already painful. Don&#8217;t ask your senior engineers which architectural rules matter. Ask them which review comments they leave because something actually broke. The answers will be higher-signal, and they&#8217;ll come faster &#8212; because outages have a way of making implicit knowledge suddenly very explicit.</p><p>Pick two or three. Choose the simplest framework that can enforce them in CI. Run it for a month. What you learn &#8212; what&#8217;s harder to specify than you expected, what turns out not to matter, how agents respond to the guardrail &#8212; is worth more than any amount of upfront planning.</p><p>But two or three is a starting point, not the program. The goal is a growing body of enforced architectural knowledge &#8212; one that expands every time a senior engineer hits the same review comment again and decides to convert their frustration into a check. That loop is worth understanding: the reviewer who encodes an invariant is not doing extra work. They are buying back their own time. Every rule that moves into the linter is a violation they will never have to catch manually again &#8212; from a human, and especially not from an agent generating changes at volume. The reward for contributing to the system is a lighter review queue and higher-quality code before it ever reaches them.</p><p>The organizations that will run agents well at scale are the ones that gave their senior engineers a place to turn repeated architectural pain into enforcement.</p><p><a href="https://fleig.us/writing/narrowpipe/">Read the full paper &#8594;</a></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://rogerfleig.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[The Pipe Was Always Narrow]]></title><description><![CDATA[Around 2018, my team at Google built a system called Sensenmann that automatically deleted dead code at scale.]]></description><link>https://rogerfleig.substack.com/p/the-pipe-was-always-narrow</link><guid isPermaLink="false">https://rogerfleig.substack.com/p/the-pipe-was-always-narrow</guid><dc:creator><![CDATA[Roger Fleig]]></dc:creator><pubDate>Fri, 03 Apr 2026 03:46:27 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!5Dke!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47c35f25-19c7-4562-88d0-69862424ecff_640x480.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5Dke!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47c35f25-19c7-4562-88d0-69862424ecff_640x480.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5Dke!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47c35f25-19c7-4562-88d0-69862424ecff_640x480.jpeg 424w, https://substackcdn.com/image/fetch/$s_!5Dke!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47c35f25-19c7-4562-88d0-69862424ecff_640x480.jpeg 848w, https://substackcdn.com/image/fetch/$s_!5Dke!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47c35f25-19c7-4562-88d0-69862424ecff_640x480.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!5Dke!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47c35f25-19c7-4562-88d0-69862424ecff_640x480.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5Dke!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47c35f25-19c7-4562-88d0-69862424ecff_640x480.jpeg" width="410" height="307.5" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/47c35f25-19c7-4562-88d0-69862424ecff_640x480.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:480,&quot;width&quot;:640,&quot;resizeWidth&quot;:410,&quot;bytes&quot;:67424,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://rogerfleig.substack.com/i/193034270?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faee46341-67eb-45d8-a68b-7d7e8c8c4027_640x898.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!5Dke!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47c35f25-19c7-4562-88d0-69862424ecff_640x480.jpeg 424w, https://substackcdn.com/image/fetch/$s_!5Dke!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47c35f25-19c7-4562-88d0-69862424ecff_640x480.jpeg 848w, https://substackcdn.com/image/fetch/$s_!5Dke!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47c35f25-19c7-4562-88d0-69862424ecff_640x480.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!5Dke!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47c35f25-19c7-4562-88d0-69862424ecff_640x480.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@ujesh?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Ujesh Krishnan</a> on <a href="https://unsplash.com/photos/selective-focus-photo-of-black-and-white-delete-enter-power-button-and-f12-computer-keys-7ySd00IGyx4?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure></div><p>Around 2018, my team at Google built a system called Sensenmann that automatically deleted dead code at scale. It tracked binary usage across production and corporate desktops, and if a binary hadn&#8217;t been seen for months, the system generated a changelist to remove it root and twig. Phil Norman, one of my engineers, <a href="https://testing.googleblog.com/2023/04/sensenmann-code-deletion-at-scale.html">wrote about it</a>. It submitted over a thousand deletion changelists a week and eventually deleted nearly 5% of all C++ at Google.</p><p>The technical system worked beautifully. The human system broke.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://rogerfleig.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Developers started pushing back &#8212; and not because the deletions were wrong. They pushed back because even a correct, trivially simple change has a real cost when you&#8217;re the one being asked to approve it. You have to build enough context to be confident you won&#8217;t regret it later. You might be new to the project and not feel qualified to make that call. You might be heads-down shipping something for a launch and simply not have the bandwidth &#8212; no matter how correct the change is. Sometimes people just said no because they didn&#8217;t have the attention to think it through.</p><p>We ended up building something more sophisticated than a throttle. Teams could configure how many robot-authored changes they received and when. If an owner said &#8220;not now,&#8221; the system snoozed for a quarter and tried again &#8212; maybe the next owner would be ready to let it go.</p><p>That was before anyone had heard of an LLM. The changes were trivially simple deletions &#8212; no judgment required, correctness guaranteed. And it still broke the pipe.</p><div><hr></div><blockquote><p><em>This is the fifth in a series on <a href="https://rogerfleig.substack.com/p/the-narrow-pipe">The Narrow Pipe</a>, and it&#8217;s about where the constraint bites hardest: not code quality, but the human capacity to absorb change.</em></p></blockquote><h2>The Same Mechanism, Larger Scale</h2><p>Fast forward to early 2026, and the same dynamic is visible across major open-source projects.</p><p>GitHub&#8217;s Ashley Wolf calls it the <a href="https://github.blog/open-source/maintainers/welcome-to-the-eternal-september-of-open-source-heres-what-we-plan-to-do-for-maintainers/">&#8220;Eternal September of open source&#8221;</a>: the cost to create has dropped, but the cost to review has not. The Augment Code data is the starkest version of this: across enterprise repositories, PR volume surged 98% and review time climbed 91% in step. All that extra generation velocity landed directly on reviewers.</p><p>Projects started closing the door. curl ended its bug bounty after a flood of AI-generated slop reports &#8212; and it was removing the incentive, not improving the tooling, that dried up the tsunami. LLVM&#8217;s policy explicitly calls unreviewed LLM output <a href="https://llvm.org/docs/AIToolPolicy.html">&#8220;extractive&#8221;</a>: it shifts effort from the implementor to the reviewer.</p><p>The mechanism is not specific to open source. OSS got hit first because it has no access controls and volunteer reviewers with no &#8220;hire more&#8221; option. But I&#8217;ve watched the same thing play out inside an enterprise.</p><p>At Crusoe, my team had a rollout plan to terraform our GitLab instance across roughly 400 repositories. Before we could execute it, someone sent an AI-generated merge request covering the whole scope &#8212; unreadable, without a spec, just a prompt. To evaluate it, a reviewer would have had to reconstruct the entire context from scratch. That&#8217;s validation burden: it doesn&#8217;t appear in the PR count, and it doesn&#8217;t go away just because the code might be correct.</p><p>The second incident was subtler. Someone used an AI coding tool over a weekend to add a cache key I was deliberately holding back until after a larger refactor. The change looked plausible. Another engineer &#8212; one who wasn&#8217;t close to the full problem &#8212; approved it. Two messy weeks followed. The code wasn&#8217;t obviously wrong. The reviewer just didn&#8217;t have the context to know what they were actually approving, or what responsibility they were taking on.</p><p>The Terraform MR might have been fine. The deletion CLs were provably correct. Responsibility can&#8217;t be parallelized as cheaply as code generation can.</p><h2>Engineering the Pipe</h2><p>If the bottleneck is structural, the response has to be structural. All the approaches that have worked start from the same premise: reviewer attention is a finite resource. Engineer around it.</p><p><strong>Narrow the scope of what you automate on the review side.</strong> Around the same time as Sensenmann, my team &#8212; in collaboration with a research group at Google Brain &#8212; built a system called AutoCommenter to handle a class of review tasks called &#8220;tips&#8221;: published preferences from the style guide, the low-hanging fruit of readability review. The training data came from the readability reviewers themselves &#8212; their own comments became the examples the model learned from, and then the system took over that specific class of work. It reached tens of thousands of developers daily. Manushree Vijayvergiya and my team <a href="https://research.google/pubs/ai-assisted-assessment-of-coding-practices-in-industrial-code-review">published the results</a> at AIware &#8216;24.</p><p>It worked because the scope was narrow: style-guide compliance, not architectural judgment. The same pattern is re-emerging as verifier agents and defensive AI. Reviewer-side AI becomes much less reliable when it tries to replace the judgment that makes human review expensive in the first place.</p><p><strong>Build backpressure deliberately.</strong> You get one chance to waste a developer&#8217;s time &#8212; after that, they stop paying attention. If you don&#8217;t build backpressure into the system, humans create their own: by rejecting everything, or by rubber-stamping it. Sensenmann&#8217;s queueing system gave teams control over their own intake rate. curl learned the same lesson in 2026: removing the bounty incentive did more to reduce the flood than any tooling change. Design the queue, or the queue designs itself &#8212; badly.</p><p><strong>Shift validation before the review.</strong> Stripe&#8217;s Minions system runs local lint and selective test execution from over three million tests before anything reaches a human, with a hard cap of two CI rounds. By the time a PR reaches a person, most of the correctness validation has already happened. The review becomes a judgment call about design alignment &#8212; not a forensic investigation.</p><p><strong>Match review depth to risk.</strong> Reviewing everything at equal depth means reviewing nothing well. AutoCommenter freed readability reviewers for the harder judgment calls by handling the mechanical ones. Graduated autonomy applies the same principle explicitly: route low-risk changes through lighter review, and preserve human attention for the changes that genuinely need it.</p><div><hr></div><p>Sensenmann&#8217;s deletion CLs were about as simple as a code change can be. Correct. Reviewable in seconds. They still broke the pipe &#8212; because correctness doesn&#8217;t reduce the cost of building enough context to feel confident taking responsibility for something. LLMs didn&#8217;t create that constraint. They widened the upstream side of it. Today&#8217;s AI-authored changes are larger in scope and arrive with more confidence. The reconstruction cost scales with them.</p><p>Addy Osmani asks what I think is <a href="https://medium.com/@addyosmani/comprehension-debt-the-hidden-cost-of-ai-generated-code-285a25dac57e">the right question</a>: how much of what we&#8217;re shipping do we actually understand? The pipe was always narrow. We just used to push less through it.</p><p><a href="https://rogerfleig.substack.com/p/the-narrow-pipe">Read the full paper &#8594;</a></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://rogerfleig.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Wayfinding, Not Roadmaps]]></title><description><![CDATA[Why the agentic era demands discovery before precision]]></description><link>https://rogerfleig.substack.com/p/wayfinding-not-roadmaps</link><guid isPermaLink="false">https://rogerfleig.substack.com/p/wayfinding-not-roadmaps</guid><dc:creator><![CDATA[Roger Fleig]]></dc:creator><pubDate>Fri, 27 Mar 2026 21:47:33 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!yzWF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda3edab6-a1e2-4997-9900-fbf990641f00_4731x2995.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote><p><em>This is the fourth in a series on <a href="https://fleig.us/writing/narrowpipe/">The Narrow Pipe</a>, a position paper on the emerging infrastructure challenges of agent-scale software engineering.</em></p></blockquote><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yzWF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda3edab6-a1e2-4997-9900-fbf990641f00_4731x2995.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yzWF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda3edab6-a1e2-4997-9900-fbf990641f00_4731x2995.jpeg 424w, https://substackcdn.com/image/fetch/$s_!yzWF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda3edab6-a1e2-4997-9900-fbf990641f00_4731x2995.jpeg 848w, https://substackcdn.com/image/fetch/$s_!yzWF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda3edab6-a1e2-4997-9900-fbf990641f00_4731x2995.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!yzWF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda3edab6-a1e2-4997-9900-fbf990641f00_4731x2995.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yzWF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda3edab6-a1e2-4997-9900-fbf990641f00_4731x2995.jpeg" width="624" height="395.0285351934052" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/da3edab6-a1e2-4997-9900-fbf990641f00_4731x2995.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2995,&quot;width&quot;:4731,&quot;resizeWidth&quot;:624,&quot;bytes&quot;:3191257,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://rogerfleig.substack.com/i/192356055?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61246b81-fd32-4db2-bf5e-5e7e111f929e_6000x4000.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!yzWF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda3edab6-a1e2-4997-9900-fbf990641f00_4731x2995.jpeg 424w, https://substackcdn.com/image/fetch/$s_!yzWF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda3edab6-a1e2-4997-9900-fbf990641f00_4731x2995.jpeg 848w, https://substackcdn.com/image/fetch/$s_!yzWF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda3edab6-a1e2-4997-9900-fbf990641f00_4731x2995.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!yzWF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda3edab6-a1e2-4997-9900-fbf990641f00_4731x2995.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@chrishardyphotography?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Chris Hardy</a> on <a href="https://unsplash.com/photos/a-close-up-of-a-compass-in-a-wooden-box-SZPDhVQrmv8?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure></div><p>There&#8217;s a natural instinct when engineering leaders encounter agentic development: build a roadmap. Read about Stripe&#8217;s Minions &#8212; a thousand agent-generated PRs a week &#8212; or hear Jensen Huang talk about 100 agents per engineer, and the next step feels obvious. Multi-quarter plan. Milestones, timelines, success criteria, projected ROI.</p><p>It feels like leadership. And it will often be wrong &#8212; not because the destination is wrong, but because the path cannot be known in advance.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://rogerfleig.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>What makes agentic infrastructure a genuinely complex problem &#8212; not merely a complicated one &#8212; is the mechanism underneath. Once code generation becomes cheap, the bottleneck shifts downstream into review, testing, coordination, and governance. But you usually don&#8217;t know in advance which of those constraints will dominate in <em>your</em> environment. In one organization it&#8217;s flaky tests. In another it&#8217;s context injection. In a mature monorepo it may be blast radius and review fatigue. The binding constraint varies by codebase, team structure, and organizational maturity &#8212; and it often isn&#8217;t what you&#8217;d predict.</p><p>That&#8217;s why the right unit of progress is not roadmap completion. It&#8217;s validated learning.</p><h2>Complicated vs. Complex</h2><p>One of the few corporate leadership courses that really stuck with me was on leading in complexity. It drew on Dave Snowden&#8217;s Cynefin framework and the work of Jennifer Garvey Berger and Keith Johnston. While writing <a href="https://fleig.us/writing/narrowpipe/">The Narrow Pipe</a>, I realized I had been applying that lesson almost implicitly. Experimentation kept surfacing in the paper not because it sounded good, but because when you&#8217;re operating in a genuinely complex domain, detailed prediction and linear planning don&#8217;t work. You make small, safe-to-fail bets, watch the system closely, and adapt based on what reality tells you.</p><p>A <strong>complicated</strong> problem has high predictability. Cause and effect are knowable. You can plan, execute, and arrive. You follow a map.</p><p>A <strong>complex</strong> problem has low predictability. Multiple variables interact in ways that are only clear in hindsight. The landscape shifts while you&#8217;re traversing it. A map is useless &#8212; not because you&#8217;re bad at cartography, but because the terrain won&#8217;t hold still.</p><p>In complex environments, you wayfind. Like Polynesian navigators reading currents, wind, and stars, you orient by signals rather than coordinates. You run small, safe-to-fail experiments. You amplify what works, dampen what doesn&#8217;t. You navigate by learning, not by planning.</p><p>Agentic infrastructure is firmly in the complex domain right now. The capabilities your team builds around are changing from quarter to quarter &#8212; not because anyone is doing anything wrong, but because the underlying models and tools haven&#8217;t stabilized.</p><h2>What This Looks Like in Practice</h2><p>Let me make this concrete. Say your team is rolling out autonomous agents and they&#8217;re iterating in CI loops until tests pass &#8212; a common agent workflow. The agents seem to be working, but tasks are taking longer than expected and compute costs are climbing.</p><p>Is the problem model quality? Context injection? Task decomposition? You don&#8217;t know yet. So you instrument.</p><p>You discover that your test suite has a 7% flake rate. That sounds tolerable &#8212; it was tolerable when humans ran tests a few times a day. But agents run tests in multi-stage loops, and flake probability compounds across stages. At 7% flake rate across 10 stages, the probability of a clean run is about 48%. More than half of your agent workflows are hitting false failures, triggering retries, burning compute, and sometimes making unnecessary code changes to &#8220;fix&#8221; tests that weren&#8217;t actually broken.</p><p>No roadmap would have told you that. You had to instrument the pipeline, measure the actual failure modes, and discover that flake rate &#8212; a problem you&#8217;d lived with for years &#8212; had become an agent-halting condition. The constraint moved, and you found it by looking, not by planning.</p><p>That&#8217;s wayfinding.</p><h2>Experimentation as Navigation</h2><p>In my <a href="https://fleig.us/writing/narrowpipe/">paper</a>, I propose a structured experimental agenda for agentic infrastructure, and I arrived at it through the developer productivity measurement tradition &#8212; DORA, SPACE, DevEx &#8212; rather than complexity theory. But the convergence with wayfinding is striking:</p><p><strong>Safe-to-fail probes.</strong> Each experiment is scoped to produce knowledge regardless of outcome. Instrument the pipeline for agent cost visibility. Compare agent behavior with and without flake detection. Test different context injection strategies. A negative result narrows the search space.</p><p><strong>Signal reading over plan tracking.</strong> Rework Rate by source, autonomy duration, quality-adjusted throughput &#8212; these are instruments for reading the currents. When leading indicators (fast merges, high PR volume) diverge from lagging indicators (rising regressions, declining code health), that divergence <em>is</em> the signal. Only live instrumentation can surface it.</p><p><strong>Multiple perspectives.</strong> Complexity cannot be seen from a single vantage point. DORA measures delivery performance. SPACE measures developer experience. DevEx focuses on feedback loops and cognitive load. No single metric tells the story. The Activity Trap is what happens when you collapse a complex system into a single number.</p><h2>Autonomy Is Not Maturity</h2><p>There&#8217;s a point from the paper that fits here and that I think is frequently overlooked: increasing what the AI <em>does</em> (autonomy) without proportionally improving the ability to <em>verify</em> what it did (controls) and to manage permissions, audit trails, and accountability (governance) creates risk, not progress.</p><p>This reinforces the case for experimentation. You&#8217;re not just exploring because the technology is changing fast. You&#8217;re exploring because the organization has to discover the right coupling between autonomy, verification, and governance in its specific environment. That coupling is different for every codebase, every team, every risk profile. It can&#8217;t be copied from a case study. It has to be measured.</p><h2>Planning at the Right Level</h2><p>I want to be precise about what I&#8217;m arguing against. It&#8217;s not planning &#8212; engineering leaders still need budgets, staffing, capacity planning, and sequencing. It&#8217;s planning at the wrong level of precision. It&#8217;s committing to a specific solution set before you&#8217;ve instrumented the problem. It&#8217;s treating &#8220;deploy agents across the org&#8221; as a roadmap item rather than a learning agenda.</p><p>The wayfinding posture means having a clear compass &#8212; agentic speed should translate into business outcomes without eroding quality &#8212; while accepting that the path will be discovered through disciplined experimentation rather than predicted through planning. You plan capacity and guardrails. You do not roadmap your way to truth.</p><p>The developer productivity discipline already has useful instincts for this: instrument before you optimize, measure outcomes rather than visible activity, and check whether your proxy metrics still track real value. The agentic era changes the variables, but not the need for disciplined observation.</p><p>The organizations that navigate this well won&#8217;t be the ones with the cleanest roadmap. They&#8217;ll be the ones that learned to read the water.</p><p><em><a href="https://fleig.us/writing/narrowpipe/">Read the full paper &#8594;</a></em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://rogerfleig.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[The Parallelism Thesis]]></title><description><![CDATA[Why the biggest productivity gains from agentic development come from concurrency, not speed]]></description><link>https://rogerfleig.substack.com/p/the-parallelism-thesis</link><guid isPermaLink="false">https://rogerfleig.substack.com/p/the-parallelism-thesis</guid><dc:creator><![CDATA[Roger Fleig]]></dc:creator><pubDate>Thu, 26 Mar 2026 19:38:36 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!ce00!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9ce9584-d952-4f77-9eb7-3bbf8406febd_2752x1109.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>This is the third in a series on <a href="https://fleig.us/writing/narrowpipe/">The Narrow Pipe</a>, a position paper on the emerging infrastructure challenges of agent-scale software engineering.</em></p><div><hr></div><p>I keep having the same conversation with engineering leaders about agentic development, and it keeps stalling in the same place. They see AI coding tools as a way to make individual developers faster. That&#8217;s true, but it&#8217;s the smallest version of what&#8217;s happening.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://rogerfleig.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>The real unlock isn&#8217;t speed. It&#8217;s concurrency.</p><p>Here&#8217;s the simplest framework I&#8217;ve found for explaining where we are and where this is going. It maps roughly to the autonomy spectrum I described in <a href="https://rogerfleig.substack.com/p/the-narrow-pipe">my first post</a> &#8212; but where that framework asks <em>who is driving</em>, this one asks <em>how many lanes are open</em>.</p><h2>Tier 1: Co-pilot</h2><p>You write code. The AI helps. It autocompletes, generates functions from comments, pairs with you on hard problems. Copilot, Cursor, and Claude Code in attended mode live here.</p><p>The gains are real. For certain tasks &#8212; boilerplate, test generation, unfamiliar APIs &#8212; it&#8217;s meaningfully faster. But the throughput ceiling is <em>you</em>. Every line of output still flows through your hands. You&#8217;re one developer, maybe 2&#8211;3x more productive on good days, on the right tasks.</p><p>It&#8217;s a faster single thread.</p><p>This is where the vast majority of developers are today. And it feels like the ceiling, because the speed improvement is tangible and immediate.</p><p>It is not the ceiling.</p><h2>Tier 2: Manager of Agents</h2><p>The role flips. You stop writing code and start defining tasks, decomposing work, and reviewing what comes back. The AI writes; you review. You&#8217;ve shifted from senior engineer to engineering manager.</p><p>But here&#8217;s the part most people miss, and it&#8217;s the whole game: <strong>the moment you make that shift, there&#8217;s no reason to manage just one agent.</strong></p><p>At Tier 1, you and the AI share a single thread of execution. You&#8217;re in the loop for every decision. The AI is fast, but you&#8217;re the bottleneck &#8212; you can only attend to one task at a time.</p><p>At Tier 2, you can have five, eight, ten agents running concurrently on different tasks. Each one is in its own inner loop &#8212; reasoning, writing code, running tests, iterating &#8212; with very little need to surface for human input. You&#8217;re not copiloting anymore. You&#8217;re reviewing completed work as it arrives, while other agents continue making progress in the background.</p><p>This is the difference between a 2&#8211;3x speedup and a fundamentally different throughput curve. One fast agent on one task is incremental. Eight agents on eight tasks simultaneously is multiplicative &#8212; and you haven&#8217;t gotten faster at any individual task. You&#8217;ve gotten parallel.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ce00!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9ce9584-d952-4f77-9eb7-3bbf8406febd_2752x1109.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ce00!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9ce9584-d952-4f77-9eb7-3bbf8406febd_2752x1109.png 424w, https://substackcdn.com/image/fetch/$s_!ce00!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9ce9584-d952-4f77-9eb7-3bbf8406febd_2752x1109.png 848w, https://substackcdn.com/image/fetch/$s_!ce00!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9ce9584-d952-4f77-9eb7-3bbf8406febd_2752x1109.png 1272w, https://substackcdn.com/image/fetch/$s_!ce00!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9ce9584-d952-4f77-9eb7-3bbf8406febd_2752x1109.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ce00!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9ce9584-d952-4f77-9eb7-3bbf8406febd_2752x1109.png" width="1456" height="587" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b9ce9584-d952-4f77-9eb7-3bbf8406febd_2752x1109.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:587,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3000856,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://rogerfleig.substack.com/i/192242654?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9ce9584-d952-4f77-9eb7-3bbf8406febd_2752x1109.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ce00!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9ce9584-d952-4f77-9eb7-3bbf8406febd_2752x1109.png 424w, https://substackcdn.com/image/fetch/$s_!ce00!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9ce9584-d952-4f77-9eb7-3bbf8406febd_2752x1109.png 848w, https://substackcdn.com/image/fetch/$s_!ce00!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9ce9584-d952-4f77-9eb7-3bbf8406febd_2752x1109.png 1272w, https://substackcdn.com/image/fetch/$s_!ce00!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb9ce9584-d952-4f77-9eb7-3bbf8406febd_2752x1109.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>The Tier 1 Trap</h3><p>Tier 1 feels productive because the feedback loop is tight. You ask, the AI responds, you iterate together. It&#8217;s interactive and satisfying. The gains show up immediately.</p><p>Tier 2 requires a different posture. You have to get comfortable with agents running autonomously &#8212; making decisions you haven&#8217;t reviewed yet, taking approaches you might not have chosen. The feedback loop is longer. The control is looser. For many experienced engineers, that loss of direct control feels like a step backward, even when the output volume is dramatically higher.</p><p>I think this is the real barrier. It&#8217;s not technical. It&#8217;s psychological. The engineers who are best at their craft &#8212; the ones with the deepest instincts about code quality, architecture, and taste &#8212; are exactly the ones who find it hardest to let go of the keyboard. The skill that made them great (deep attention to every line) is the skill that prevents them from accessing the parallelism that makes Tier 2 transformative.</p><p>This is also, incidentally, what the METR study found: developers with the <em>deepest</em> familiarity with their codebases experienced the <em>largest</em> slowdowns when using AI tools in attended mode. The more you know, the more you correct &#8212; and if you&#8217;re correcting one agent in real time, you&#8217;re back to a single thread.</p><h3>The Infrastructure Gap</h3><p>There&#8217;s a second barrier, and this one <em>is</em> technical. Running one agent is easy. Running many agents concurrently starts surfacing problems that don&#8217;t exist at Tier 1: agents stepping on each other&#8217;s work, CI queues backing up, merge conflicts from parallel changes, review backlogs that exceed what any human can meaningfully process.</p><p>The downstream pipeline &#8212; builds, tests, review, integration &#8212; was designed for human-speed code production. When you multiply the input by 8x, those systems become the bottleneck. This is the <a href="https://fleig.us/writing/narrowpipe/">narrow pipe problem</a>: the constraint was once producing code. Now it&#8217;s everything <em>after</em> producing code.</p><p>The uncomfortable implication: the parallelism that makes Tier 2 valuable is the same parallelism that breaks the pipeline. You can&#8217;t have one without solving the other.</p><h3>The ROI Math</h3><p>The economic case for Tier 2 over Tier 1 is straightforward once you see it:</p><p><strong>Tier 1 ROI</strong> = (speed gain on individual tasks) &#215; (one task at a time)</p><p><strong>Tier 2 ROI</strong> = (agent task completion rate) &#215; (number of concurrent agents) &#8722; (review cost + coordination overhead + infrastructure cost)</p><p>Tier 1 is a linear improvement. Tier 2 is a scaling function. Even if each individual agent is somewhat less effective than you would be doing the task yourself &#8212; and in many cases it will be &#8212; the aggregate output across many parallel agents can far exceed what a single developer can produce, at any speed.</p><p>The catch is the subtracted terms. Review cost grows with agent count. Coordination overhead grows nonlinearly. Infrastructure cost is real. If your downstream systems can&#8217;t absorb the volume, the gains evaporate. But these are engineering problems with known solution patterns &#8212; not fundamental limits.</p><h2>Tier 3: Spec-Driven Development</h2><p>You define <em>what</em> to build and the acceptance criteria. Agents handle the <em>how</em> end-to-end. Hours later, you check results against specs and tests. The human role is product thinking and verification, not implementation.</p><p>This is operational today for certain classes of work &#8212; greenfield features with clear specs, well-bounded refactors, tasks where acceptance criteria can be fully automated. StrongDM&#8217;s &#8220;Attractor&#8221; system operates here: specifications go in as markdown, agents write the code, other agents test it against holdout scenarios the coding agents never saw.</p><p>It&#8217;s premature for most work on mature, complex codebases where institutional knowledge and implicit invariants make fully autonomous operation risky. But it&#8217;s where the trajectory points &#8212; and the infrastructure you build for Tier 2 (agent identity, coordination, blast radius awareness, test reliability, context injection) is what makes Tier 3 possible when the models and the guardrails are ready.</p><h2>The Investment Case</h2><p>This framing clarifies where infrastructure investment pays off.</p><p>You don&#8217;t need agent identity, coordination systems, or blast radius awareness for one co-pilot. You don&#8217;t even need most of it for one autonomous agent. But you absolutely need it the moment you&#8217;re running ten agents concurrently on a shared codebase. The infrastructure investment is what converts the <em>theoretical</em> parallelism of Tier 2 into <em>realized</em> throughput.</p><p>Organizations that stay at Tier 1 will see steady, incremental productivity gains. Organizations that make the jump to Tier 2 &#8212; and build the infrastructure to support it &#8212; access a different curve entirely.</p><p>The ceiling isn&#8217;t how fast one agent can code. It&#8217;s how many agents you can run in parallel before the downstream systems break. Raise that ceiling, and you change the economics of the entire engineering organization.</p><p><em><a href="https://fleig.us/writing/narrowpipe/">Read the full paper &#8594;</a></em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://rogerfleig.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[The $250,000 Vanity Metric]]></title><description><![CDATA[The Activity Trap, the 40-point perception gap, and why your agent productivity metrics are probably lying to you.]]></description><link>https://rogerfleig.substack.com/p/the-250000-vanity-metric</link><guid isPermaLink="false">https://rogerfleig.substack.com/p/the-250000-vanity-metric</guid><dc:creator><![CDATA[Roger Fleig]]></dc:creator><pubDate>Wed, 25 Mar 2026 18:13:10 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!cTIM!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F821b6b8f-147c-413d-be0b-ed67b68bf882_2679x2679.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>This is the second in a series on <a href="https://fleig.us/writing/narrowpipe/">The Narrow Pipe</a>, a position paper on the emerging infrastructure challenges of agent-scale software engineering.</em></p><div><hr></div><p>Last week at GTC 2026, Jensen Huang laid out his <a href="https://fortune.com/2026/03/17/jensen-huang-ai-infrastructure-buildout-1-trillion-dollars/">vision for token budgets as engineer compensation</a> &#8212; half a base salary, on top of pay, so engineers can be &#8220;amplified 10x.&#8221; Then on the All-In Podcast, he made it vivid: if a $500,000 engineer only spent $5,000 on AI tokens in a year, <em>&#8220;I will go ape.&#8221;</em> His benchmark? At least $250,000 in annual token consumption. When asked if Nvidia is spending $2 billion a year on tokens for its engineering team, he answered: <em>&#8220;We&#8217;re trying to.&#8221;</em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://rogerfleig.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>This landed the same week as a New York Times piece that introduced the term &#8220;tokenmaxxing&#8221; &#8212; a status competition among engineers to consume the most AI tokens. Internal leaderboards tracking token consumption. Managers factoring raw AI usage into performance reviews. Individual engineers burning billions of tokens per week running swarms of parallel agents around the clock.</p><p>Jensen is the CEO of the company that sells the compute. Of course he wants engineers burning through a quarter million dollars in tokens. But when that framing trickles down into how engineering organizations evaluate productivity, it becomes something more dangerous than a sales pitch. It becomes a measurement system. And it&#8217;s measuring the wrong thing.</p><h2>The Activity Trap</h2><p>The most important measurement anti-pattern in agentic development has a name: the Activity Trap. It means measuring activity instead of outcomes &#8212; counting what&#8217;s easy to count rather than what actually matters. Jensen&#8217;s $250K benchmark is the Activity Trap in its purest and most expensive form: it measures <em>input</em> &#8212; resources burned &#8212; not <em>output</em>, and certainly not <em>outcomes</em>.</p><p>Agents make this trap catastrophically worse because they can generate enormous volumes of activity. An agent that opens twenty PRs in a day looks productive by activity metrics. If fifteen require multiple review rounds, three introduce regressions, and two get reverted &#8212; the net outcome may be negative. Activity metrics for agents aren&#8217;t just uninformative. They are actively misleading, because they create incentives to optimize for volume over value.</p><p>Lines of code generated. PR counts. Token consumption. Prompt counts. These aren&#8217;t productivity metrics. They&#8217;re <em>input</em> metrics. They tell you nothing about whether the output is correct, maintainable, or even used.</p><h2>The 40-Point Perception Gap</h2><p>Here&#8217;s what makes this genuinely dangerous: developers can&#8217;t tell either.</p><p>A 2025 randomized controlled trial by METR (Model Evaluation &amp; Threat Research) produced the most rigorous empirical test of AI-assisted development productivity to date. Sixteen experienced open-source developers completed 246 real tasks on their own repositories &#8212; mature codebases averaging over a million lines that the developers had worked on for an average of five years. Tasks were randomly assigned to allow or disallow AI tools.</p><p>The result: developers using AI tools were <strong>19% slower</strong> at completing tasks. Not faster. Slower.</p><p>But here&#8217;s the finding that should keep you up at night: before the study, developers predicted AI would make them 24% faster. <em>After</em> the study &#8212; after experiencing the actual slowdown &#8212; they still estimated they had been 20% faster. That&#8217;s a 40+ percentage point gap between perceived and actual productivity.</p><p>They weren&#8217;t just wrong about the magnitude. They were wrong about the <em>direction</em>.</p><h2>Why It Happened</h2><p>METR&#8217;s analysis identified causes that map directly to the infrastructure problems I describe in the full paper:</p><p><strong>Context familiarity penalty.</strong> Developers who knew their codebases most deeply were slowed down <em>most</em>. The more an expert knows that the AI doesn&#8217;t have access to, the more time they spend correcting confident mistakes. This is the institutional knowledge problem &#8212; the gap between what lives in a developer&#8217;s head and what the agent can see.</p><p><strong>Quality standards as friction.</strong> Code that is &#8220;functionally correct&#8221; but fails implicit quality standards requires substantial human cleanup. This is the rework problem.</p><p><strong>Attention fragmentation.</strong> AI tools introduced micro-interruption patterns that disrupted flow state. The tool that was supposed to reduce cognitive load increased it.</p><h2>What to Measure Instead</h2><p>The established measurement frameworks &#8212; DORA, SPACE, DevEx &#8212; provide the scaffolding, but each needs adaptation for agents. Here&#8217;s the thinking tool I use:</p><blockquote><p><strong>Net agent value &#8776; throughput gain &#8722; review burden &#8722; CI/compute cost &#8722; regression/rework cost &#8722; coordination overhead</strong></p></blockquote><p>This isn&#8217;t a formula to compute precisely. It&#8217;s a frame that makes the cost structure visible and prevents the common mistake of measuring only the numerator while ignoring the denominator.</p><p>A few metrics that actually matter:</p><p><strong>Rework Rate</strong> (DORA&#8217;s fifth metric, benchmarked 2025) &#8212; the ratio of deployments that are unplanned responses to production incidents. Track it by source: agent vs. human, by agent type, by code area. If agent-generated code drives up rework rate, the speed gain is illusory.</p><p><strong>Autonomy Duration</strong> &#8212; how far an agent progresses through meaningful work before requiring human intervention. The primary measure of macro-loop efficiency.</p><p><strong>Quality-adjusted throughput</strong> &#8212; throughput weighted by change failure rate, rework rate, and code health. An agent that produces five low-quality PRs requiring multiple review rounds is less valuable than one that produces two clean PRs that merge on first review.</p><p><strong>Marginal value decay</strong> &#8212; as agent count increases, does each additional agent produce proportional value? Or do coordination costs, CI contention, and review bottlenecks produce diminishing returns? Plot value per agent against agent count and look for the inflection point.</p><h2>Metrics That Actively Mislead</h2><p>&#8220;Compiles and passes tests&#8221; is just as dangerous as lines-of-code. In the full paper, I include a case study of an LLM-generated reimplementation of SQLite &#8212; 576,000 lines of Rust. It compiled. It passed its tests. A basic primary key lookup on 100 rows took 1,815 milliseconds. The same operation in SQLite takes 0.09 milliseconds. It was <strong>20,171x slower</strong> &#8212; because it was missing a single physical storage optimization that someone profiled against a real workload decades ago.</p><p>That code would have scored perfectly on every activity metric and every &#8220;does it work&#8221; gate. Only outcome-level measurement &#8212; a performance benchmark &#8212; revealed the gap.</p><h2>The Unsolved Problem</h2><p>There&#8217;s one critical dimension that no current framework measures well: ownership attribution. Who understands a given piece of code well enough to debug and maintain it? In a world where agents produce code and humans review it under volume pressure, the assumption that &#8220;the reviewer owns it&#8221; becomes increasingly fragile.</p><p>If no human wrote the code and the reviewer only skimmed it, who actually understands the system well enough to debug it when it breaks at 3 AM?</p><p>This is an open problem. But the first step is acknowledging that the metrics most organizations are using today &#8212; the ones that feel like measurement &#8212; aren&#8217;t measuring what matters.</p><div><hr></div><p>Without instrumented, outcome-based measurement, organizations will deploy agents, feel faster, and never discover they are slower &#8212; until rework rate and regression data make the cost undeniable.</p><p>The full paper goes deeper on the measurement framework &#8212; adapted versions of DORA, SPACE, and DevEx for agentic workflows, and a detailed experimental agenda for testing what actually works.</p><p><em><a href="https://fleig.us/writing/narrowpipe/">Read the full paper &#8594;</a></em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://rogerfleig.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[The Narrow Pipe]]></title><description><![CDATA[Your agents aren't bottlenecked on code generation. They're bottlenecked on everything after it.]]></description><link>https://rogerfleig.substack.com/p/the-narrow-pipe</link><guid isPermaLink="false">https://rogerfleig.substack.com/p/the-narrow-pipe</guid><dc:creator><![CDATA[Roger Fleig]]></dc:creator><pubDate>Wed, 25 Mar 2026 05:45:47 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!f7Pm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4c2033a-a14a-4a32-b16b-92228d6a7e10_1536x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I published a position paper today called <em><a href="https://fleig.us/writing/narrowpipe/">The Narrow Pipe</a></em> &#8212; it&#8217;s long, opinionated, and covers a lot of ground. This post is the short version of the thesis, and the first in a series that unpacks the key ideas.</p><p>Here&#8217;s the core observation: the cost of producing code is falling fast. But the downstream infrastructure that reviews, builds, tests, integrates, and deploys that code? It was designed for human-speed throughput.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://rogerfleig.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>This is the Theory of Constraints applied to software engineering. For decades, the constraint was producing code. Now that agents are dissolving that constraint, the bottleneck doesn&#8217;t disappear &#8212; it shifts downstream, and every existing limitation in the pipeline becomes the new critical path.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!f7Pm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4c2033a-a14a-4a32-b16b-92228d6a7e10_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!f7Pm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4c2033a-a14a-4a32-b16b-92228d6a7e10_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!f7Pm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4c2033a-a14a-4a32-b16b-92228d6a7e10_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!f7Pm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4c2033a-a14a-4a32-b16b-92228d6a7e10_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!f7Pm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4c2033a-a14a-4a32-b16b-92228d6a7e10_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!f7Pm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4c2033a-a14a-4a32-b16b-92228d6a7e10_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b4c2033a-a14a-4a32-b16b-92228d6a7e10_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1359812,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://rogerfleig.substack.com/i/192063749?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4c2033a-a14a-4a32-b16b-92228d6a7e10_1536x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!f7Pm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4c2033a-a14a-4a32-b16b-92228d6a7e10_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!f7Pm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4c2033a-a14a-4a32-b16b-92228d6a7e10_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!f7Pm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4c2033a-a14a-4a32-b16b-92228d6a7e10_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!f7Pm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4c2033a-a14a-4a32-b16b-92228d6a7e10_1536x1024.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>The Agent Loop</h2><p>To reason about this concretely, it helps to define two loops:</p><p>The <strong>micro-loop</strong> is the agent&#8217;s internal cycle: reason, act, observe, repeat. Each iteration burns tokens, time, and potentially infrastructure &#8212; a test run, a build, a search query. Every problem in agentic infrastructure either inflates or deflates this loop count. A flaky test that sends the agent chasing a phantom failure? That&#8217;s wasted micro-loops. Poor context injection that omits a key dependency? More wasted micro-loops.</p><p>The <strong>macro-loop</strong> is the roundtrip between agent and human &#8212; a review comment, an escalation, a course correction. This is where human judgment enters the system. The key metric here is <em>autonomy duration</em>: how far an agent can progress through meaningful work before it needs a human. Longer autonomy duration means fewer macro-loops and less human bottleneck. But longer autonomy without guardrails means compounding errors.</p><p>The Narrow Pipe, restated: agents squeeze the pipeline from both directions simultaneously. The micro-loop hammers shared infrastructure at 10&#8211;100x the rate it was designed for. The macro-loop stays human-speed but now faces a volume of agent-produced work that no review process was built to absorb.</p><h2>The Autonomy Spectrum</h2><p>Dan Shapiro mapped the progression of AI-assisted development onto five levels &#8212; modeled on the NHTSA&#8217;s driving automation levels. The analogy is intentional: each level shifts who is driving.</p><ul><li><p><strong>Level 1 &#8212; Autocomplete.</strong> AI suggests completions. Human is driving.</p></li><li><p><strong>Level 2 &#8212; Pair programming.</strong> Developer and AI collaborate. This is where most &#8220;AI-native&#8221; teams operate today. Critically, every level from here on <em>feels</em> like the ceiling. It is not.</p></li><li><p><strong>Level 3 &#8212; Code review.</strong> AI writes the code; the developer reviews it. The developer&#8217;s job shifts from senior engineer to engineering manager. This is where the Narrow Pipe thesis bites hardest.</p></li><li><p><strong>Level 4 &#8212; Spec-driven.</strong> Engineers write specifications. Agents write code. Other agents test it. Hours later, humans check the results. The job shifts from <em>how</em> to <em>what</em>.</p></li><li><p><strong>Level 5 &#8212; The Dark Factory.</strong> Specs go in, software comes out.</p></li></ul><p>My paper focuses on building the infrastructure for Levels 3 and 4 to work reliably at scale &#8212; particularly in mature monorepos, where the structural challenges make every level transition harder.</p><h2>Why &#8220;More Code&#8221; Isn&#8217;t the Goal</h2><p>There&#8217;s a subtler risk beyond throughput. Without deliberate reinforcement, the pipeline doesn&#8217;t merely constrict the flow of agent-generated code &#8212; it allows institutional quality to leak out over time. Review rigor erodes under volume pressure. Agent output becomes the context for future agents. Patterns simplify. Critical details &#8212; the kind that only accumulate through years of profiling against real workloads &#8212; quietly disappear.</p><p>The goal is not &#8220;more code.&#8221; It&#8217;s ensuring that agentic speed translates into business outcomes without eroding the architectural stability that makes a codebase maintainable over years.</p><h2>What&#8217;s in the Full Paper</h2><p><em><a href="https://fleig.us/writing/narrowpipe/">The Narrow Pipe</a></em> maps eight interdependent problem areas (runtime isolation, agent identity, graduated autonomy, coordination, context injection, institutional knowledge, test reliability, and blast radius awareness), proposes a measurement framework adapted from DORA, SPACE, and DevEx, and lays out an experimental agenda for making progress with evidence rather than intuition.</p><p>It also includes a detailed case study of Stripe&#8217;s Minions system &#8212; the most concrete public example of enterprise-scale agentic development &#8212; and a cautionary case study of an LLM-generated SQLite reimplementation that compiled, passed its tests, and was 20,000x slower on a basic operation.</p><p>The infrastructure that governs code quality must be rebuilt for a world where the volume of changes exceeds what human judgment alone can govern. The paper is my attempt to map that problem space rigorously.</p><p>More posts in this series coming soon &#8212; next up: why your agent productivity metrics are probably lying to you.</p><div><hr></div><p><em><a href="https://fleig.us/writing/narrowpipe/">Read the full paper &#8594;</a></em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://rogerfleig.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item></channel></rss>