---
title: "Just aim the cannon correctly"
date: 2026-05-14
tags: post
---

James Shore [has a post](https://www.jamesshore.com/v2/blog/2026/you-need-ai-that-reduces-your-maintenance-costs) I found myself nodding along to until the very last step, where he loses me. The thesis is clean:

> Your AI coding agent, the one you use to write code, needs to reduce your maintenance costs. Not by a little bit, either.

Productivity over the long haul, he argues, isn't bounded by how fast you can produce code — it's bounded by maintenance cost, which compounds. Any coding agent that accelerates production without taming maintenance is, definitionally, a debt-laundering operation: it lets you skip the bill today and pay it forever afterward.

Each individual claim is, I think, correct. Code is debt; maintenance compounds; an agent that bolts on features faster than your team can absorb them is, given a long enough horizon, an anti-productivity tool. The conclusion Shore stops just short of stating — that current LLM tooling is, on net, bad — is where I get off the train of thought. 

---

A useful frame that I like across a variety of contexts is that of a difficulty score. The idea is straightforward: every recurring operation in your organization has some friction associated with it, and you can roughly approximate that friction with a back-of-the-envelope cost function. For something like *opening a pull request*, my version goes:

- +1 point per ten seconds of wall-clock time spent waiting on tests or CI
- +5 points per tool you have to context-switch into (docs, dashboards, terminals)
- +1 point per click
- +10 points per manual check you run before merging

For support, it might be:

- +5 points per click required to triage a ticket
- +10 points every time the answer isn't simply a link to documentation we already have
- +25 points every time you have to log into the user's account because the relevant data isn't surfaced to support
- ×1.25 per follow-up response from the user

The specific weights don't really matter. The point is that once you have a function, you can take a derivative — you identify the things that are Bad and then you start taking discrete steps towards reducing them, with the overall goal of getting the score down as low as possible.

And LLMs are, in my experience, fantastic at bringing these scores down. The bulk of what I've spent my own LLM-augmented time on at Buttondown in 2026 has been on this axis — [[llm-devprod|squeezing the inner loop]], [[llm-changes|trimming dependencies]], [[llm-advance-team|handing diagnostic and scoping work to agents in the background]] — and the return has been outsized.

Conversely, where I see LLMs deployed in the most deleterious manner — and where I think Shore's argument probably finds the most purchase — is when the relationship between the tool and the codebase is purely additive. LLMs are very, very good at adding features. They are also, more insidiously, very good at *telling you that adding a feature is a great idea.* [^1] You can ask any coding agent whether it should build the thing you just described to it, and the answer will essentially always be yes, with concomitant action plans and bullet points that it will litter throughout the codebase.

The failure case I see in organizations that rhymes with Shore's point is along those lines. If scaffolding a feature took a week, you thought hard about whether to scaffold it. If it takes an afternoon, the answer skews toward yes, and yes, and yes, until you wake up one morning with sixteen new endpoints and no real idea why any of them exist, nor any graceful seams across them. 

But you can simply not use the tool that way, in much the same way you can simply not use Playwright as a full substitute for a testing suite.

---

Here's a rough playbook:

1. Define the difficulty scores for the operations that matter. Write them down somewhere your team can bikeshed (non-derogatory, of course) and flesh them out.
2. Triage the obvious low-hanging fruit (which is always much more than one assumes) against all the other work to do, biasing heavily towards _this_ stuff because it's inner-loop.
3. Ship the improvements.
4. Repeat.

None of this is LLM-specific [^2]. The failure mode of letting maintenance debt accumulate without ever asking *what specifically is making my life hard* predates LLMs and will outlast them. What LLMs do is give people (and organizations) a fast forward button: they let the organizations that were already losing to maintenance debt lose faster, and they let the organizations that have their score-keeping in order pull away further.

All of which is to say: I agree with Shore on the diagnosis. I just don't think the cure is to abandon the tools — it's to point them at the right operations, with eyes open about which ones, and to remember that adding code is the most expensive thing a coding tool can ever do for you.

[^1]: I have, on multiple occasions, tried to talk a coding agent *out* of building something. It is genuinely harder than the opposite, which I find both funny and faintly horrifying.

[^2]: In general, I think a useful framing device for reading essays about LLM-assisted engineering is "how much of this rings differently if they're just talking about all engineering writ large?"