Giving Every Agent Its Own Branch: Git Worktrees for Parallel AI Work

Run two coding agents against a single working tree and they will fight. One is halfway through editing app/api/messages/route.ts while the other checks out a different branch underneath it. The index lock flickers. A git stash from one session swallows the other’s uncommitted work. I have lost real edits this way, and every time the root cause was the same: one working tree, one HEAD, two writers.

The InterlinedList repo already had matching agents for the jobs I hand off most: a Next.js implementer, a migrations specialist, unit and e2e testers, a docs writer, security and UX reviewers. They are good at their lanes. What they were missing was a lane in the literal sense. They all drove on one road.

I found the pattern I wanted written up in Augment’s guide to git worktrees for parallel AI execution, and it maps almost one to one onto how I already think about agents. This is the writeup of what I built on top of it for this repo: the directory convention, the seven scripts that manage the lifecycle, and the wiring that makes every agent use them without being reminded.

The one-tree problem

A normal clone gives you a single working directory backed by one .git. That is fine for one person doing one thing. The moment you parallelize, the shared mutable state (the working files, the index, the current branch) becomes the bottleneck. You cannot have the migrations agent on agent/add-webhooks and the docs agent on agent/help-refresh at the same instant, because “the branch” is a property of the whole checkout.

Diagram illustrating 'The one-tree problem' in software development with two agents, A and B, interacting with a mutable checkout and related issues like index.lock flicker and checkout thrash.

Two writers, one mutable checkout. The collisions have nothing to do with the work: an index lock flickers, a git stash swallows the other session’s edits, HEAD thrashes between branches.

Git solved this in 2015 with git worktree. A worktree is a second (third, fourth) working directory attached to the same repository. Each one has its own files, its own index, and its own checked-out branch, while sharing one object store on disk. The object store is the expensive part, so you share it. A directory of files is cheap, so you duplicate it per task. That is exactly the tradeoff you want for parallel agents.

Diagram illustrating a Git object store with multiple worktrees, highlighting shared storage and individual configurations for each task.

Share the expensive part, duplicate the cheap part. The object store lives on disk once; the working files, the index, the checked-out branch, and even the dev-server port are private to each worktree.

The convention

Every agent works in .trees/<task-id> on a branch named agent/<task-id>, cut from origin/develop (this repo integrates on develop, not main). So a task called add-list-webhooks lives at .trees/add-list-webhooks on branch agent/add-list-webhooks. The directory name and the branch name always agree because both are derived from the same sanitized slug.

The .trees/ container is gitignored. Worktrees are workspace, not history:

# .gitignore
# Agent worktrees (see scripts/worktrees/)
.trees/

That single ignore line is the whole footprint the pattern leaves in the tracked tree. Everything else is scripts and instructions.

The scripts

I did not want agents (or me) typing raw git worktree incantations and getting the branch name wrong, or forgetting to copy .env.local, or leaving stale metadata behind. So the lifecycle lives in scripts/worktrees/ as a small set of focused shell scripts. Here is every one of them.

Diagram illustrating the worktree lifecycle in Git, detailing steps for creating, inspecting, removing, and cleaning worktrees. Sections include 'STEP 1' for branch creation, 'WHILE WORKING' for listing and locking, 'WHEN IT LANDS' for removing branches, and 'DAILY SWEEP' for cleanup processes.

The whole lifecycle before the per-script detail. Create, inspect while working, remove when it lands, sweep the merged trees on a schedule.

_lib.sh is the shared library the others source. It holds the functions that keep conventions consistent: wt_repo_root resolves the primary checkout even when you call it from inside a linked worktree (it reads git rev-parse --git-common-dir and walks up), wt_sanitize lowercases a task id and strips it to [a-z0-9._-]wt_resolve_base fetches and prefers origin/<base> over a local branch, wt_port_for hashes a branch name into a stable dev port, and wt_is_locked reads the porcelain worktree list to check lock state. Nothing in it is clever. It exists so the clever bits are written once.

wt-create.sh <task-id> [base] is the one agents call first. It creates the worktree and makes it ready to work in, in one shot:

scripts/worktrees/wt-create.sh add-list-webhooks

Under the hood it resolves the base ref (default develop), ensures .trees/ is in .gitignore, turns on git rerere so repeated conflict resolutions replay across parallel merges, runs git worktree add -b agent/<slug> .trees/<slug> origin/<base>, copies the root .env.local into the worktree, appends a deterministic DEV_PORT derived from the branch name, runs npm ci --prefer-offline, and finally locks the worktree so other sessions can see it is in use. Flags let you opt out where it makes sense: --no-install skips the dependency install for a quick plumbing check, --no-lock leaves it unlocked, and --baseline runs the test suite right after setup so a green baseline proves any later failure came from the agent’s change rather than a pre-existing break.

The port assignment is worth a sentence. Two agents both running next dev on 3000 is another collision, a quieter one. wt_port_for runs the branch name through cksum and maps it into the 3100 to 9998 range, so each worktree gets a stable, distinct port written into its own .env.local. Start the server with npm run dev -- -p "$DEV_PORT" and two dev servers coexist.

wt-list.sh answers “what is running right now.” It prunes stale metadata, then prints one row per worktree with path, branch, lock state, and short HEAD:

PATH BRANCH LOCKED HEAD
/Users/adron/Codez/interlinedlist feature/fix-blog-image - 58afa91562
/Users/adron/Codez/interlinedlist/.trees/add-list-webhooks agent/add-list-webhooks yes b78faf9e21

Before an agent touches a shared file, it can look here and see who else is holding what. Git will not warn you about two branches editing the same file, so this list plus discipline about non-overlapping file domains is the actual safety mechanism.

wt-lock.sh <task-id> [reason] and wt-unlock.sh <task-id> are thin wrappers over git worktree lock/unlock. A lock is advisory: it resists prune and move, and it is the signal in wt-list.sh that says “an agent is live in here, do not reap this.”

wt-remove.sh <task-id> is the teardown. It unlocks if needed, runs git worktree remove, and prunes. This matters more than it looks: deleting a worktree with rm -rf leaves dangling metadata in .git/worktrees/ that haunts you until the next prune. The script never does that. --force discards uncommitted changes on purpose, and --delete-branch drops agent/<task-id> in the same step when the work has landed.

wt-cleanup.sh [base] is the bulk sweep. It walks every worktree physically under .trees/, and for each one whose branch is already an ancestor of origin/develop (in other words, merged), it removes the worktree and deletes the branch. It deliberately skips anything outside .trees/, so the primary checkout and any sibling worktrees I keep elsewhere on disk are never touched. This is the script you point a daily cron or a post-merge hook at.

Each of these is also exposed as an npm script, so npm run wt:create -- add-list-webhooksnpm run wt:list, and npm run wt:remove -- add-list-webhooks all work if you prefer that entry point. There is a scripts/worktrees/README.md documenting the whole set alongside the code.

Wiring it into the agents

Scripts nobody runs are decoration. The point was to make every agent reach for a worktree by default, so I added the instruction in three places at three levels of specificity.

At the top, CLAUDE.md now states the standing rule: every agent works in an isolated worktree, torn down with the lifecycle scripts. That is the repo-wide contract.

In the middle, two shared protocol docs under .claude/workflows/ hold the full detail: worktrees.md spells out the create-work-remove lifecycle, the boundaries (shared object store, non-overlapping files, and the important caveat that the database is shared even though the files are not), and plan-first.md covers the companion habit I wrote about separately. Every agent and skill links to these rather than repeating them.

At the leaf, each of the eight agent definitions in .claude/agents/ got a “Work in an isolated git worktree (required)” section written for its job. The implementers (Next.js, migrations, tests, docs, blog) get the full create-work-remove flow. The two read-only reviewers (security, UX) get a variant that tells them to cd into the worktree under review and read its diff, and explicitly not to create, lock, or remove anything. The migrations agent gets an extra warning in bold, because the worktree isolates schema.prisma and the migration files but not the Postgres instance: db:migrate still hits localhost and db:migrate:deploy still hits production from any worktree. That is the one place the isolation is a lie, and the agent needs to know it.

The five paired skills in .claude/skills/ (the ones that back the implementer agents) got a short “Worktree-first, plan-first” block near the top pointing at the same protocol docs, so whether the work comes in through the agent or the skill, the instruction is there.

Proving it works

I ran the whole lifecycle before committing any of it. Create a worktree from develop, confirm it is locked and has its port, unlock and re-lock it, remove it with the branch, and verify the cleanup pass leaves the sibling worktrees alone:

scripts/worktrees/wt-create.sh wt-smoke-test --no-install
scripts/worktrees/wt-list.sh # shows agent/wt-smoke-test, LOCKED yes
scripts/worktrees/wt-unlock.sh wt-smoke-test
scripts/worktrees/wt-lock.sh wt-smoke-test "smoke re-lock"
scripts/worktrees/wt-remove.sh wt-smoke-test --delete-branch
scripts/worktrees/wt-cleanup.sh develop # safe no-op, siblings untouched

Every step did what it said, the .gitignore guard refused to duplicate the .trees/ line it found already present, and the sibling worktree I keep for feed-perf work was never in scope for cleanup. That last part was the thing I most wanted to confirm, because a cleanup script that reaches outside its sandbox is worse than no cleanup script.

Where agents still get confused

Isolating the filesystem fixes the filesystem. It does nothing about the fact that the work itself overlaps, and there are a handful of ways an agent still gets lost.

The database is one instance, and every worktree writes to it. I flagged this to the migrations agent in bold, but it deserves more than a warning. If the migrations agent adds a column on agent/add-webhooks, that column now exists in the same localhost Postgres every other worktree points at. The docs agent three trees over never sees the changed schema.prisma, yet its queries hit the mutated database anyway. Additive-only migrations keep this survivable most of the time, since an extra column nobody reads is harmless. But the moment two agents touch the same table, or one runs db:migrate:deploy and reaches production from what looked like a sandbox, the isolation is a fiction. The files are private. The database is not.

Green in isolation, red on merge. This is the one that bites. Agent A changes a function signature in lib/lists/queries.ts. Agent B, on its own branch, calls that function from a route it owns. Their files never overlap, so wt-list.sh shows no conflict and git stays quiet. Both test suites pass, because A’s worktree still holds B’s old caller and B’s worktree still holds A’s old signature. It’s all green right up until both branches land on develop, and then the integration is broken in a way neither agent could see from inside its own tree. Worktrees convert a loud, immediate collision into a quiet one that surfaces later. Often a fair trade, but a trade.

Stale base drift. Every worktree is cut from origin/develop the moment it’s created. Agents aren’t always short-lived. Let one run for a few hours while three others merge back, and it’s now building on a develop that no longer exists. It will reintroduce a helper that got deleted upstream, or write against an API another agent already reshaped. The worktree has no idea the ground moved under it. Nothing in the create-work-remove loop forces a re-fetch, so a long-running agent drifts out of date without noticing.

“Does this already exist?” stops having one answer. With five branches in flight, whether feature X is “already built” depends on which tree you grep. An agent that checks the primary checkout won’t see work-in-progress on another branch, and it will happily build a second copy. I’ve watched two sessions independently implement overlapping halves of the same feature, each sure it was first, because neither branch was visible to the other and neither said up front what it was about to touch. wt-list.sh tells you which branches exist. It says nothing about what each one intends to change.

The lock is a suggestion. wt-lock resists prune and move, and it flags a tree as live in the list, but it will not stop another agent from opening the same file on its own branch and editing away. The real guard against two agents clobbering one file is the up-front decomposition plus the discipline to run wt-list.sh and honor what it shows. An agent that skips the check has no seatbelt, just the shape of one.

Abandoned trees pile up. wt-cleanup.sh only sweeps branches already merged into develop. A worktree from a crashed or cancelled session is unmerged, still locked, and invisible to the sweep. It sits on disk with a full node_modules until someone removes it by hand. And an agent resuming a task can trip over a half-finished tree from an earlier run and read its stale state as current work.

Losing the current directory. The workflow says cd .trees/<task-id> and do everything there. Shell state doesn’t always survive between tool calls, and an absolute path into the primary checkout looks identical to one into a worktree. An agent that loses track of where it is can read the main checkout’s copy of a file, reason about it as though it were its branch’s version, and edit the wrong tree. The isolation holds only as long as the agent keeps its bearings.

What this buys

The honest version: worktrees do not make independent tasks independent. If two agents both need to edit the same route, isolating their filesystems just delays the merge conflict, it does not prevent it. The decomposition still has to be real. What the pattern removes is the accidental collision, the kind that has nothing to do with the work and everything to do with sharing one mutable checkout. Those were most of my pain, and now they are gone by construction.

Advantages and disadvantages

Advantages

  • Accidental collisions disappear. Each agent gets its own files, index, and HEAD, so index-lock flicker, a stray git stash eating another session’s edits, and checkout thrash stop happening.
  • Every task lands on its own agent/<task-id> branch, which keeps review and merge clean and stops one task’s half-finished mess from bleeding into another’s diff.
  • The object store is shared, so the costly part of the repo lives on disk once and spinning up another tree is cheap.
  • Each worktree gets a deterministic DEV_PORT, so several next dev servers run side by side instead of fighting over 3000.
  • The lifecycle is scripted and wired into every agent definition, so the right setup and teardown happen without anyone remembering the incantation.
  • git rerere is on by default, so a conflict you resolve once replays across the parallel merges that hit it again.
  • Cleanup is fenced to .trees/, so the bulk sweep never reaches the primary checkout or the sibling worktrees I keep elsewhere.

Disadvantages

  • The database isn’t isolated, and neither is anything else global (production through db:migrate:deploy, OAuth apps, third-party rate limits). File isolation quietly implies an isolation that isn’t there.
  • Overlapping edits on separate branches turn into silent, deferred conflicts and semantic breakage that pass every isolated test and only show up at integration.
  • A long-running worktree drifts from a moving develop, and nothing in the loop forces the re-fetch that would catch it up.
  • Locks are advisory, so the actual protection against two agents editing one file is decomposition plus discipline, not anything git enforces.
  • With several branches live, “does this already exist” has no single answer, and agents duplicate each other’s work when branches can’t see one another.
  • Every worktree carries a full node_modules, so disk use and npm ci time multiply with each active task.
  • Crashed or abandoned sessions leave locked, unmerged trees that the merged-only cleanup won’t reap, so someone clears them by hand.
  • Coordination is still manual: the tooling shows which branches exist, not which files each agent means to touch.

The next habit I want in every agent sits upstream of all of this: stop and plan before touching a single file. That one is worth its own post.

More solutions to the confusion above are coming in the next few posts. Subscribe so you don’t miss ’em: drop your email into the box just below this post, or grab the RSS feed.

I’m Adron, brainstorming and building InterlinedList.

That Gap Is Still Widening, But The Bottleneck Was Never Engineering

In my previous post, The Gap Is Widening and It’s Not Slowing Down, I focused on the growing divide between individuals and teams that have embraced Generative AI and those that have not. That divide is real, measurable, and growing faster than many people seem willing to acknowledge. I’m not walking any of that back.

But after watching organizations over the last year attempt to integrate AI into their engineering practices, I’m increasingly convinced the widening gap isn’t actually about AI – at least not entirely. The technology is only exposing something that has existed for decades. The bottleneck was never engineering. It was never software development. It was never the people building things.

The bottleneck has almost always been the machinery *surrounding* the people building things: the approvals, the reporting structures, the committees, the prioritization processes, the disconnected leadership layers, the bureaucracy, the politics – the endless collection of organizational systems that somehow manage to consume vast amounts of energy while producing remarkably little forward progress. Generative AI didn’t create this problem. It simply made it impossible to hide.

Individual Engineers Are Experiencing a Massive Productivity Expansion

There is very little debate left about whether Generative AI increases the productivity of individual contributors. We’ve moved well past that question. The debate today isn’t whether productivity gains exist – it’s about how *much* gain exists and, more importantly, who is actually capable of capturing it.

Engineers today can create prototypes in hours that once required days or weeks. Architectural alternatives can be explored in an afternoon instead of consuming entire sprints of spike work. Documentation can be generated, revised, and maintained at speeds that would have seemed unrealistic even five years ago. Testing frameworks, infrastructure automation, deployment pipelines, and application scaffolding can all be stood up dramatically faster than before.

Even beyond code generation, AI has become an accelerator for thinking itself. It provides rapid feedback loops, architectural critiques, alternative approaches, and research capabilities that allow engineers to move through uncertainty faster than they ever have before. An engineer operating effectively with modern tooling can often accomplish what previously required several engineers. A small team can frequently deliver what once demanded a much larger one. This isn’t speculation anymore – we’re watching it happen every day.

Yet despite these gains, many organizations report only marginal improvements in overall delivery speed. Why? Because software development was never the slowest part of the process.

The Bottleneck Was Hiding Somewhere Else

For years, organizations convinced themselves that software engineers were the constraint. The logic seemed simple enough: if projects are late, development must be slow; if features take too long, engineering capacity must be insufficient; if delivery struggles, more developers must be needed. So organizations hired more engineers, added process around them, and watched delivery timelines stay roughly the same.

Then AI dramatically accelerated the development side of the equation – and something interesting happened. The overall system didn’t accelerate proportionally. Instead, the delays became easier to identify. Features completed quickly sat for weeks waiting for approval. Product decisions that took months were backed by implementation work that took days. Architecture reviews became calendar-management exercises instead of engineering exercises. Governance processes consumed more time than development itself, and procurement delays stalled technology adoption before it could even begin.

The moment development became faster, every other inefficiency suddenly became visible. The tide went out and revealed the rocks – and there were far more rocks than most organizations were prepared to acknowledge.

We’ve Been Trying To Solve This Problem For Over A Century

One of the most frustrating aspects of this situation is that the underlying problem isn’t new. Some of the most influential thinkers in management spent their entire careers attempting to solve exactly these issues, and we largely ignored them.

Chief among them was W. Edwards Deming. His work fundamentally reshaped manufacturing, quality management, and organizational thinking throughout the twentieth century. His influence helped transform post-war Japanese manufacturing and directly shaped the practices that would eventually become Lean methodology and the Toyota Production System. One of Deming’s most important observations was that organizations routinely blame individuals for failures that are actually caused by systems — the worker gets blamed, the engineer gets blamed, the frontline employee gets blamed, while the actual system producing poor outcomes remains untouched and unexamined.

Deming repeatedly argued that management’s primary responsibility was improving the system itself – not creating more reports, not creating more oversight, not creating more bureaucracy, but actually improving the system. This remains one of the most ignored lessons in modern business. When productivity stalls, organizations add process. When communication breaks down, they add meetings. When delivery slows, they add approvals. When uncertainty increases, they add governance layers. The response is almost always additional complexity, rarely simplification – yet simplification is often exactly what’s needed.

The Toyota Way Was Never About Manufacturing

One of the most persistently misunderstood management concepts in business is the Toyota Production System and the principles described in *The Toyota Way*. Organizations study Toyota and immediately focus on manufacturing techniques, kanban boards, and production flow. That completely misses the point.

The true innovation was not manufacturing. It was the relentless pursuit of removing waste from systems. Toyota became exceptional because it continuously questioned every activity that consumed effort without creating value – every unnecessary handoff, every unnecessary delay, every unnecessary approval, every unnecessary process step. Everything was examined through the lens of whether it actually moved something of value forward. If it didn’t, it was a candidate for elimination.

Modern software organizations often claim to embrace these ideas while operating with approval chains that require six or seven layers of sign-off, organizational structures where decisions travel further than the code itself, and workflows designed to optimize reporting while actively damaging delivery speed. The language of Lean has become extremely popular in tech. The discipline required to actually implement it remains genuinely rare. There’s a meaningful difference between saying “we practice continuous improvement” and operating a system that systematically identifies and eliminates its own waste – most organizations are doing the former and calling it the latter.

AI Is Exposing Management Debt

The software industry talks constantly about technical debt, and rightly so – I’ve spent decades fighting it. But I’m increasingly convinced that many organizations suffer more from *management debt* than technical debt, and management debt is considerably harder to see from the inside.

Management debt accumulates when organizations create layers of process that never get removed. It accumulates when reporting structures expand indefinitely, when approval chains grow with every re-org, when every novel problem gets solved by introducing another committee, another meeting, another workflow, or another governance layer. Over time these accumulate into a dense friction system that surrounds every team trying to build and ship something. Unlike technical debt, management debt is often invisible to leadership because leadership frequently created it – and organizations don’t typically build mechanisms for evaluating whether the management decisions made five years ago are still earning their overhead.

Generative AI is now exposing these accumulated liabilities with uncomfortable clarity. If engineers can produce ten times more output and delivery only improves ten percent, leadership should not be asking what’s wrong with the engineers. They should be asking what’s wrong with the system. The answer may be uncomfortable. It may involve examining years of accumulated organizational decisions, questioning structures that have become politically entrenched, and acknowledging that the bureaucracy itself is the liability. But that’s where the actual solution lives.

Systemic Thinking Matters More Than Ever

One of the most valuable disciplines organizations can adopt today is genuine systemic thinking – not as a framework to be installed and presented to the board, but as an actual way of seeing how the organization produces its outputs.

The reason it matters comes down to a simple but uncomfortable idea: organizations are systems, and systems produce exactly what they are designed to produce. Not what leadership intends. Not what the org chart implies. What the actual system, with its real incentives and real workflows, is built to produce. Many organizations want innovation while designing systems optimized for risk avoidance. They want speed while designing systems that optimize for approval coverage. They want accountability while designing systems optimized for blame diffusion. They want creativity while designing systems that reward conformity and punish variance.

The outputs shouldn’t be surprising – the system is behaving exactly as designed. Generative AI doesn’t alter this reality. If anything, it amplifies it. The faster individual contributors become, the more visible systemic dysfunction becomes. You can’t paper over a broken approval process with faster code generation. You just end up with more finished work sitting in queues.

The Competitive Advantage Isn’t AI

Here’s something I genuinely believe will be borne out over the next five years: the next generation of competitive advantage is unlikely to come from simply adopting AI. Everyone will eventually have access to similar models. Everyone will have copilots, agents, and increasingly capable automation. The models will keep getting better and access will continue to become more democratic. Access is not a moat.

The differentiator will be organizational capability – specifically, whether the organization can actually move. Can it make decisions quickly? Can it remove friction from its own processes? Can it empower teams to act without running everything through three layers of approval? Can it identify waste and eliminate it rather than building process around it? Organizations that can answer yes to these questions will compound the productivity gains AI provides and experience something genuinely transformative. Organizations that answer no will continue wondering why expensive AI investments fail to produce the results they see in press releases and conference talks – and they’ll blame the technology.

The Answers Already Exist

What’s remarkable about all of this is that very few of these ideas are new. Deming wrote extensively about them. Lean practitioners have written extensively about them. Systems thinkers like Peter Senge have written extensively about them. Toyota demonstrated them repeatedly over decades. The playbook already exists. It just requires organizational will to actually use it.

Generative AI simply raises the stakes. For decades, organizations could survive despite bureaucratic inefficiencies because software creation itself was difficult enough that organizational dysfunction stayed hidden behind the sheer complexity of engineering work. That cover is disappearing fast. The engineering side of the equation is accelerating rapidly, and the remaining constraints are becoming impossible to ignore.

If I had to estimate — and I’m willing to commit to this number — I’d say the overwhelming majority of organizations, probably 90% or more, still carry enough management debt, process debt, and bureaucratic drag to prevent them from realizing even half of the value Generative AI could deliver. The technology is arriving right on schedule. The organizations are not.

Organizations that fail to introspect, simplify, and dismantle their accumulated management structures will realize only a fraction of what’s possible. Organizations that embrace systems thinking, Lean principles, continuous improvement, and genuine organizational simplification will unlock extraordinary advantages — not because AI magically transformed their business, but because they finally removed the barriers that had been slowing them down all along.

The gap is widening. But the bottleneck was never engineering. It was management. And management now has nowhere left to hide.

Further Reading

These are the thinkers and resources worth going deep on if you want to move beyond reading about these ideas and actually do something about them.

  • W. Edwards Deming — Start with his Fourteen Points for Management, then read *Out of the Crisis*. His work is the foundation for almost everything else on this list.
  • The Deming Institute — The most accessible ongoing resource for understanding and applying Deming’s system of profound knowledge in modern organizations.
  • *The Toyota Way* by Jeffrey Liker — The definitive English-language treatment of Toyota’s actual management philosophy, not just the production tools. The tools without the philosophy are just theater.
  • Toyota Production System — Understanding the origins and evolution of TPS is worthwhile context before diving into the derivative frameworks that have followed it.
  • Lean Enterprise Institute — Practical, applied Lean thinking for people who want to actually implement rather than just read about it.
  • *The Fifth Discipline* by Peter Senge — The foundational text on systems thinking in organizations. If you read one book from this list, make it this one.
  • *The Goal* by Eliyahu Goldratt — Theory of Constraints explained through a novel. Surprisingly readable and genuinely transformative for how you see bottlenecks. The production setting feels dated; the ideas do not.
  • Kaizen / Continuous Improvement — Understanding what kaizen actually means in practice versus how the word gets casually deployed in tech organizations is worth the time. The gap between those two things is significant.

The Gap Is Widening and It’s Not Slowing Down

Brendan O’Leary wrote a piece this week titled “The AI Coding Revolution Hasn’t Started Yet“. His headline observation: most professional engineers haven’t adopted AI coding tools in any meaningful way. Not even close.

In my experience too, he’s right. I’d push it further.

I’ve been deep in this work – helping companies actually get Generative AI tooling integrated into real development workflows, not just installed, not just “evaluated,” but actually integrated. Running sessions, doing the pairing, reviewing the setups, watching teams try to navigate the gap from “we have Copilot turned on” to “we’re doing something meaningfully different with how we build software.” and what I keep seeing isn’t just that most companies haven’t started. It’s that the gap between the teams that have started and everyone else is compounding. Every week that passes, that gap doesn’t hold steady. It widens.

The Observation from the Inside

The conference Brendan was at, where he made this observation is a good one. You talk to staff engineers, architects, team leads – people who are not amateurs at this craft – and you find out they’re still in the “I’ve heard of Claude Code” phase. That’s a real data point and it matches what I’m seeing at companies I work with. More than a few times they haven’t even gotten to that point.

But here’s the wrinkle that the conference floor view doesn’t fully capture: the gap isn’t just about adoption level. It’s about trajectory. The practitioners who’ve gone deep aren’t standing still. They’re getting faster, refining workflows, building intuition about how to orchestrate agents, where to trust the output, where to keep a tighter leash, and where to let things run. They’re compounding their advantage every single week. Meanwhile, a team that’s still on “tab completion is the whole idea” isn’t sitting on a fixed baseline. They’re falling behind in a relative sense, even if their absolute productivity is unchanged.

That’s a slow-moving disaster in competitive terms.

The Questions That Tell the Story

I’ve had almost the exact same hallway conversations described. The tells are in the questions:

“Wait, so the agent actually runs the tests itself?”

“How are you keeping it from just rewriting everything it touches?”

“Our security team said no to all of this, so we haven’t tried anything.”

None of these are dumb questions. In fact, they’re the correct questions — they mean the person is starting to actually reason about agentic tooling rather than dismissing it. But they’re also questions that someone who’s been working in this space for six months has already burned through, experimented on, and formed opinions about. There’s a widening experiential gap underneath the tooling gap and that part is harder to close quickly.

Why the Lag Is Rational (But Costly)

The reasons Brendan lists for slow adoption from security lockdowns, bad early Copilot experiences, tool landscape churn, team skepticism are all real and I’ve run into every single one of them. Let me add a few more from what I’ve encountered.

The “we tried it and it wasn’t impressive” problem is particularly pernicious, because the delta between the experience of using autocomplete in 2023 and using an agentic coding workflow in 2026 is genuinely massive. But if you hit the bad experience first and walked away, you should probably revisit it now. I know demos that happen at conferences aren’t likely to convince. A well-produced YouTube video either. But get your hands dirty and use it, otherwise the lag is going to send you, or the group you work with into luddite land and made “redundant” as they say in some places (i.e. laid off, unemployed, etc).

That’s one of the core things I try to do when working with teams: get past the “is this real” phase as fast as possible by showing it working on their actual code. Because abstract capabilities don’t move people. Seeing an agent navigate through a service you wrote, flag something you’d have missed, and propose a coherent refactor in thirty seconds — that moves people.

The security lockdown problem is also real but I want to name it more precisely: what organizations actually mean when they say “we can’t use AI tools on our codebase” is usually “we haven’t yet done the work to understand what the actual risk surface is.” Which is a very different thing than a reasoned security position. It’s a deferral masquerading as a decision. And that deferral has a cost that most orgs aren’t properly accounting for on their risk register.

The Vibe Coding Trap Is Real Too

Here’s where I’ll add some nuance that doesn’t always make it into the “you should adopt this” framing: adoption without discipline is its own problem.

There’s a Stanford study that just landed – SWE-chat, (which I have a lot of frustration with how it’s often mis-interpreted, for example the comment I’ve left here the post) looking at 6,000 real coding agent sessions from open-source developers in the wild – and the numbers are sobering. Only 44% of agent-produced code makes it into commits. Vibe-coded sessions (where the agent authors virtually all the code) burn roughly 3x more tokens and dollars per committed line than collaborative sessions. And vibe-coded code introduces about 9x more security vulnerabilities per committed line than code humans write themselves.

I’ve talked about this at length in Hurting or Helping Devs and in my breakdown of the types of code changes that AI agents produce. The tools are genuinely powerful. They’re also genuinely capable of quietly reshaping a codebase into something that looks correct but behaves like it was written by an overly confident intern with root access and no fear of consequences.

The right model isn’t “hand everything to the agent.” It’s orchestration with discipline – scoped prompts, diff limits, human gatekeeping on production deployments, and a clear-eyed understanding of where agent judgment is trustworthy and where it isn’t. That’s a craft skill that takes time to develop. It can’t be skipped.

So I’m not just saying adopt. I’m saying adopt correctly with discipline, which is harder, takes longer, and requires more deliberate investment. But the teams doing it right are building a durable advantage. The teams doing it sloppily are creating technical debt at a rate that will bite them in ways that are currently hard to see.

The Compounding Problem

Here’s the thing about compounding gaps that I keep coming back to: they don’t feel urgent when you’re inside them.

If your team is shipping at more or less the same pace it shipped at a year ago, nothing feels broken. Nothing is on fire. You’re not obviously behind. The gap is invisible to you because the other side of it isn’t in your day-to-day view.

But a team that’s been running agentic workflows for six months has built intuition, muscle memory, and workflow patterns that can’t be copied in a week. They’ve figured out what to scope, what to constrain, where to trust, and where to verify. They’ve failed in some interesting ways and learned from it. They’re operating at a different surface area of the problem than a team that’s starting from scratch — even if both teams have access to the same models and tools.

That’s the part that concerns me most when I work with orgs that are still in “evaluation mode” two years into this transition. The tools aren’t the moat. The practice is the moat. And practice requires time.

The clock is running.

What Needs to Happen

Brendan is optimistic about the diffusion curve tipping soon, and I think that’s probably right. The on-ramp needs to get lower – better model-agnostic tooling, less lock-in, less requirement to reconstruct your entire workflow to get started. Those are the right levers.

But I’d add one more: organizations need someone to physically show them what the other side looks like, in their context, with their problems. Not a demo environment. Not a benchmark. Their actual code. Their actual team. That’s the thing that moves the needle from “heard about it” to “we’re doing this.”

If you’re at a company still sitting on the sidelines on this – not because of a reasoned, deliberate decision, but because it hasn’t risen to the top of the priority stack yet – I’d genuinely encourage you to treat that as a risk and a significant one at that. Not a vague future risk. A significant present, compounding one.

The teams on the other side of that gap are not slowing down.

Hurting or Helping Devs?

This video features me, a Principal Software Engineer, discussing the impact of AI on software development, the risks of “vibe coding,” and the necessary shifts in engineering practices. Adron argues that traditional manual coding is becoming obsolete and that developers must adapt to a new paradigm defined by systems thinking and AI orchestration.

Key Takeaways:

  • The Dangers of “Vibe Coding”: Adron defines “vibe coding” as the practice of relying on AI to generate code without a deep understanding of the system (0:08:31). This often leads to unmaintainable, “disposable” software—a phenomenon he calls the shinification of software—which can cause significant production issues when systems fail (0:00:46, 0:08:31).
  • Managing AI Agents: To maintain code quality, developers must:
    • Rein in Scope: Avoid open-ended prompts; instead, provide specific, well-defined architectural plans to AI agents (0:05:13, 0:06:01).
    • Diff Discipline: Enforce hard limits on diff sizes (e.g., aiming for ~50 lines) to ensure human reviewers can feasibly audit changes (0:52:37, 0:55:00).
    • Human Gatekeeping: Keep humans as the final gatekeepers for production deployments to ensure security and reliability (0:16:50, 0:57:29).
  • The Evolution of the Developer Role: The junior pipeline is changing; instead of focusing on syntax or pixel-pushing, future developers should act as systemic architects who understand how to orchestrate AI tools and manage complex workflows (0:24:05, 0:26:05).
  • The Industry Reckoning: As VC-subsidized AI adoption faces future economic corrections, companies will need to prioritize efficiency, energy production, and true orchestration over simply generating massive amounts of code (1:02:41, 1:05:00).
  • Future Predictions: Adron predicts that AI will eventually develop its own programming language optimized for machine-to-machine communication, further distancing development from manual human typing (1:09:48).

In this episode, you’ll learn:

  1. Why writing code manually means you are already too far behind.
  2. How to manage the six specific types of AI code changes.
  3. The reason Diff Discipline is the only way to survive vibe coding.

Time Sliced Segments

  • (03:14) Why the junior developer pipeline is imploding
  • (05:13) How to reign in agent scope for better results
  • (08:31) The slow creeping dread of vibe coding
  • (12:50) Moving past communication cycles with prototypes
  • (16:50) Why shipping to production needs a human gatekeeper
  • (20:20) How roles shift when agents handle the workflow
  • (24:05) Why slinging individual lines of code is over
  • (29:47) Bringing a generalist approach back to computer science
  • (34:57) Breaking down the six types of code changes
  • (41:40) Why AI optimizes for plausible output instead of correctness
  • (52:37) Enforcing diff limits to keep human reviewers sane
  • (57:29) Setting up no-fly zones for sensitive code
  • (01:02:41) The coming hundred x shock to the tech industry
  • (01:11:27) What it means to be a coder in 2026

Security Was Already a Mess. Generative AI Is About to Prove It.

I was thinking about some of the points from the Polyglot Conf list of predictions for Gen AI, titled “Second Order Effects of AI Acceleration: 22 Predictions from Polyglot Conference Vancouver“. One thing that stands out to me, and I’m sure many of you have read about the scenario, of misplaced keys, tokens, passwords and usernames, or whatever other security collateral left in a repo. It’s been such an issue orgs like AWS have setup triggers that when they find keys on the internet, they trace back and try to alert their users (i.e. if a user of theirs has stuck account keys in a repo). It’s wild how big of a problem this is.

Once you’ve spent any serious amount of time inside corporate IT, you eventually come to a slightly uncomfortable realization. Exponentially so if you focus on InfoSec or other security related things. Security, broadly speaking, is not in a particularly great state.

That might sound dramatic, but it’s not really. It is the standard modus operandi of corporate IT. The cost of really good security is too high for more corporations to focus where they should and often when some corporations focus on security they’ll often miss the forrest for the trees. There are absolutely teams doing excellent security work, so don’t get the idea I’m saying there aren’t some solid people doing the work to secure systems and environments. There are some organizations that invest heavily in it. There are people in security roles who take the mission extremely seriously and do very good engineering.

A lot of what passes for security is really just a mixture of documentation, policy, and a little bit of obscurity. Systems are complicated enough that people assume things are protected. Access is restricted mostly because people don’t know where to look. Credentials are hidden in configuration files or environment variables that nobody outside the team sees.

And that becomes the de facto security posture.

Not deliberate protection.

Just… quiet obscurity.

I’ve lost count of the number of times I’ve been pulled into a system review, or some troubleshooting session, where a secret shows up in a place it absolutely shouldn’t be. An API key sitting in a script. A database password in a config file. An environment file committed to a repository six months ago that nobody noticed.

That sort of thing happens constantly. Not out of malice. Out of convenience. But now we’ve introduced something new into the environment.

Generative AI.

More importantly though, the agentic tooling built around it. Tooling that literally takes actions on your behalf. Tools that can read entire repositories, analyze logs, scan infrastructure configuration, generate code, and help debug systems in seconds. Tools that engineers increasingly rely on as a kind of external thinking partner while they work through problems.

All that benefit is coming with AI tools. However AI doesn’t care about the secret. It’s just processing text. But the act of pasting it there matters. Because the moment that secret leaves your controlled environment, you no longer know exactly where it goes, how it’s stored, or how long it persists in the LLM.

The mental model a lot of people are using right now is wrong. They treat AI like a scratch pad or an extension of their own thoughts.

It isn’t.

The more accurate model is this: an AI tool is another resource participating in your workflow. Another staff member, effectively.

Except instead of being a person sitting at the desk next to you, it’s a system operated by someone else, running on infrastructure you don’t control, processing information you send to it. Including keys and secrets.

Once you start looking at it that way, a few things become obvious. You wouldn’t casually hand a contractor your production API keys while asking them to help debug something. You wouldn’t drop a full .env file containing service credentials into a conversation with someone who doesn’t actually need those values.

Yet that is exactly the pattern that is quietly emerging with generative AI tools. Especially among new users of said tools! Developers paste configuration files, snippets of infrastructure code, environment variables, connection strings, and logs directly into prompts because it’s the fastest way to get an answer.

It feels harmless. But secrets have a way of spreading through systems once they start moving.

The real issue here is that generative AI doesn’t create security problems. It amplifies the ones that already exist. Problems that the industry has failed (miserably might I add) at solving. If an organization already has sloppy credential management, AI just gives those credentials another place to leak. If engineers already pass secrets around informally to get work done, AI becomes another convenient channel for that behavior.

And because AI tools accelerate everything, they accelerate the consequences too. What used to take hours of searching through documentation can now happen instantly. A repository full of configuration files can be analyzed in seconds. Systems that were once opaque are now far easier to reason about.

The Takeaway (Including secrets!)

The practical takeaway here isn’t that people should stop using AI tools. That’s not realistic and frankly a career limiting maneuver at this point. The tools are genuinely useful and they’re going to become a permanent part of how software gets built.

What needs to change – desperately – is operational discipline.

Secrets should never be treated casually, and that includes interactions with generative systems. API keys, tokens, passwords, certificates, environment files, connection strings—none of those belong in prompts or screenshots or debugging sessions with external tools.

If you need to ask an AI for help, scrub the sensitive pieces first. Replace real values with placeholders. Remove anything that grants access to a system. Setup ignore for the env files and don’t let production env values (or vault values, whatever you’re using) leak into your Generative AI systems.

Treat every AI interaction the same way you would treat a conversation with another engineer outside your organization, or better yet outside the company (or Government, etc) altogether.

But not someone you hand the keys to the kingdom. Don’t give them to your AI tooling.