AI and Engineering Leadership

Extend and Improve: The Design You Already Have Is the Job

New code is cheap to draft. The lasting move is older: add to a design someone still understands, or tidy that design until the next change is easy.

18 min read
Extend and Improve: The Design You Already Have Is the Job

Picture a small shop you love. The checkout already knows one kindness. Buy ten things or more, and the price drops by ten percent.

One morning a new request arrives. Five dollars off, as long as the cart is not empty. A little welcome gift.

A helper can draft that change in a minute. Sometimes the helper copies the whole checkout into a second file. Sometimes it squeezes another rule into the middle of the old one. Both versions can look finished. Only one of them keeps the shop tidy for the next kindness.

That is the whole article, really. In 2026 a person can type less of a change by hand. The shop around that change still grows more drafts, more review, and more ways to bruise a design that already works. So here is the idea to carry with you. When a design already exists, and someone can still explain it, start by extending it. If the request is the same job and the shape is awkward, tidy the shape first, then extend it. A different job gets a small new piece beside the old one. And you replace a piece only when you can say why.

This order is my conclusion, stated as mine. I did not find a paper that says, in those words, that extend-and-improve is the job now. The older rules below come from sources. Ranking them into a default is my judgment.

Two earlier notes on this site sit next door. Blueprint Over Bytes is about specifying and reviewing, once typing stops being the center of the work. When Code Gets Cheap, Complexity Moves is about estimates and planning. This one is the choice those notes leave open. You already have a living system. Do you extend it, tidy it, add a small new piece, or replace it?

A tidy corner shop counter with neatly arranged shelves and a small gift box

Four moves, and the one to try first

A change walks in the door. You do not start by writing. You start by asking where it belongs.

A few words first, so the table stays friendly. A commit is a saved snapshot of the work. A pull request is a note that says, “please accept this change.” An agent, or coding helper, is a program that drafts code when you ask. A seam is a plug-in point the design already has. A refactor is a tidy-up of the inside. What the customer sees stays the same.

Move Choose it when What "done" looks like
Buy or call A product the team already trusts, and does not need to own, already does this job You use that product. You do not build a twin
Extend Someone can explain how the new behavior maps onto the current design, and a seam already exists New behavior behind the existing front door. Callers of the stable part stay still
Improve The behavior belongs here, and the current shape would force a special case, a copy, or a messy edit across the file A tidy-up that keeps today's answers, then the small extension. Old checks still pass
Compose Fitting the change inside the old program would make that program worse at its current job A new small piece. Its output feeds the old one, or the other way around
Replace Nobody still holds the story of this part, or another local tweak costs more than a bounded new design A new design for that part, grown beside the old path while the old path still has users

Try them in this order. Buy, if a maintained product already fits. Otherwise extend, then improve, then compose, then replace. Stop at the first move that fits, and write down why you skipped one.

Two little checks keep you honest.

Can someone still tell the story? Somebody on the team should be able to say why this part is shaped this way, and where a new case belongs. Peter Naur called that story the theory. It lives with people. A file can hint at it, but the file cannot hold it alone. If a teammate has the story, learn it before you touch anything. If nobody has it, you are patching, in Naur’s sense, and a fresh design for that part is allowed.

Is the next change easier? After you extend or improve, the design should be easier to change again. Lehman’s second law says complexity rises unless someone works to hold it down. An extension that needs a warning like “do not use this with the other mode” is a tidy-up you postponed. Compose and replace are exits. Do not drag them back into the loop.

One more line, and it is my judgment, not a study result. Helpers are fluent once the plug-in point is obvious. They are just as fluent at inventing a second copy when that point is hidden. Your job is to choose the move before the helper fills the page. Review then asks a smaller question. Does this change match the move we chose?

flowchart TD
  Start["A change is requested"] --> Owned{"Does a maintained product already do this job?"}
  Owned -- "Yes" --> Buy["Buy or call it"]
  Owned -- "No" --> Theory{"Does someone still hold the theory?"}
  Theory -- "Yes, you do" --> Fit{"How does the change fit?"}
  Theory -- "A teammate does" --> Learn["Learn the theory, then continue"]
  Learn --> Fit
  Theory -- "Nobody does" --> Replace["Replace this part"]
  Fit -- "Existing seam" --> Extend["Extend"]
  Fit -- "Same job, awkward shape" --> Improve["Improve, then extend"]
  Fit -- "Different job" --> Compose["Compose a new small piece"]
  Fit -- "Another increment costs more" --> Replace
  Extend --> Easier{"Is this design easier to change again?"}
  Improve --> Easier
  Easier -- "Yes" --> Ship["Ship"]
  Easier -- "No, same job" --> Improve
  Compose --> Ship
  Replace --> Ship
  Buy --> Ship

Most of the work was always change

Meir M. Lehman spent years watching software that stays in use. In a September 1980 paper he treats maintenance as every change after the first installation, a much wider bucket than bug fixes. He mentions a “generally accepted” split of 1977 U.S. programming spending, about 70 percent maintenance and 30 percent new development. That is a community estimate from that period, not a survey he ran. Leave it in 1977. It is a poor stand-in for costs today.

The argument around it is the keeper. Changing, deleting, and extending a living program is not a distraction from the job. It is the job. Two of his laws still matter on an ordinary Tuesday. Programs that model real human activity must keep adapting, or they go stale. And their complexity rises unless someone works to hold it down.

Shipping the first version starts the work. Every later change fits the design, improves it, or makes the next change harder. Helpers did not invent that fork. They just made it easier to skip the middle path and drop a second design beside the first.

More drafts, fewer finished parcels

A fast draft of the welcome gift tells you how quickly the words appeared. It says nothing about which shelf the gift belongs on. The studies split in exactly that place. Some text got cheaper. The care around it stayed. Longer walks live in When Code Gets Cheap and Is AI Generating a World of Code Slop?.

On one fresh exercise, the draft really did get faster. With GitHub Copilot, people built a sample web server 55.8 percent faster (Microsoft Research, February 2023; arXiv:2302.06590). The paper measures that speed. Whether those servers were easier to extend later sits outside it.

On familiar code, in one early snapshot, the opposite happened. METR’s trial (arXiv:2507.09089, reported 10 July 2025) asked 16 experienced developers to finish 246 real issues on repositories they knew well. With AI allowed, the tasks took 19 percent longer. The authors call it a snapshot of early-2025 tools. Other teams, other editors, and later models sit outside the claim.

Then the big funnel. The September 2026 revision of NBER Working Paper 35275, Writing Code vs. Shipping Code, studies more than 500,000 GitHub developers. It is a working paper, shared for discussion, not peer-reviewed. Extra saved changes add up to about 240 percent with autonomous agents, but that shrinks to about 80 percent more projects and only about 30 percent more shipped releases. More new apps appeared, with no increase in total usage. The authors call it a weak link. Coding speeds up. Human work later still sets the pace. (On 26 September 2026 the public landing page still showed an older summary. These numbers are from the September 2026 PDF.)

The funnel narrows: saved changes vs. what shipped

Saved changes (commits)+240%
New projects+80%
Shipped releases+30%

NBER Working Paper 35275, September 2026 revision. The plain reading: cheaper typing fills the top of the funnel. Review, fitting, and release decide what comes out.

Trust lagged behind the activity. DORA’s 2025 annual survey of nearly 5,000 professionals (fielded 13 June–21 July 2025) says 90 percent use AI at work and more than 80 percent feel more productive, yet 30 percent have little or no trust in the generated code. Adoption lines up with higher throughput and lower stability. Those are survey patterns. (An earlier 2025 DORA note reported worse delivery, including a likely throughput drop. The estimation article cites that one. This article uses the annual report.) Stack Overflow’s 2025 survey (49,009 responses, 29 May–23 June 2025) rhymes: 84 percent using or planning to use AI tools, 51 percent of professionals daily, and more distrusting accuracy (46 percent) than trusting it (33 percent).

Simon Willison puts the practitioner version in one line. New code is almost free; good code is not (Writing code is cheap now, read 26 September 2026). Addy Osmani’s 4 December 2024 note on the “70 percent problem” is a field observation of the same split. Both are judgment. Andrej Karpathy, on 2 February 2025, named the far end of the habit. Accept the changes, skip the diffs, let the code grow past what you understand. He called that not too bad for throwaway weekend projects, and not really coding. The hedge is his.

A cheaper input can raise total use. That picture is an analogy from William Stanley Jevons, The Coal Question (1865). The software evidence is the NBER paper above. The scarce work is review, fitting the pieces together, and choosing where the new behavior belongs. That care is the “do more” half of the idea.

You can skip a line. You should still be able to read it.

Two futures get told as if they were one. They end in different shops.

In the first, people stop reading the notes. The text is a leftover, like machine instructions most of us never open. Karpathy’s February 2025 note is that future, already tried: “forget that the code even exists.” Accept the diff. Let the program grow past comprehension. Simon Willison, on 19 March 2025, keeps the name. Vibe coding means building with a model and skipping review of what it writes. For software he would commit, his test flips. He will not commit what he could not explain exactly to somebody else.

In the second future, you can still read the notes, and a full pass is often unnecessary. The shape tells you what to ignore. The 1985 preface to Structure and Interpretation of Computer Programs already wanted that reader. Programs, it says, must be written for people to read, and only incidentally for machines to run. A good reader knows what not to read, and how to change the program while keeping its spirit and style.

Both futures are available now. Saved changes are up. Trust is limited. The NBER paper counts commits, projects, releases, and usage. It stays silent on how carefully anyone read a diff. Skipping the read is an inference, and it matches how Karpathy described his own weekend practice. Comprehension debt is this site’s name for merged changes nobody can explain. That is the first future winning.

The future I would build is the second one. You skip lines because the shape is honest, and you can still read when the shortcut leaks. One named place for discounts means one rule to change. A tidy-up before the feature keeps that skip list true. A second copy of the checkout rules fails the test. Now you read both, and neither one says which design is real.

Forecasts about losing the ability to read, or reading falling to zero, sit outside these studies. What they show is more notes being produced. Readability is still a choice, and it is still yours.

Older shoulders, in short

Each of these people argues for one move. Each one also stops short of the cartoon.

Extend, while someone still holds the story. In 1985 Peter Naur wrote that the real asset is the programmers’ theory of how the program meets the world. The text is only a trace. In his compiler story, a second team had the source and the notes, and still proposed changes that ignored structure already there. When the theory has died, he says, solve the problem afresh. That is the replace exit.

Improve, and leave what people see alone. On 6 April 2000, Joel Spolsky called a from-scratch rewrite of a working product the worst strategic mistake a software company can make. Repair the mess inside while the behavior people depend on stays. Kent Beck’s line, quoted by Martin Fowler in 2015, gives the step in one sentence. Make the change easy, then make the easy change. A refactoring changes the inside so the software is cheaper to modify, while what users see stays the same.

Add at a seam. Bertrand Meyer’s 1988 principle says a module can be open for extension and closed at the same time. Closed means others may rely on a stable description. Robert C. Martin’s 1996 column draws the working line. Meet a new requirement by adding, rather than by editing what already works. Jeremy Miller’s 2008 damper: treat it as a direction, not a goal, or you will invent plug-in points for changes that never come.

Compose, when the job is actually new. Eric Raymond’s extensibility rule asks you to leave room for later functions without scrapping the architecture, and refuses features nobody needs yet. Doug McIlroy supplies the exit. “To do a new job, build afresh rather than complicate old programs by adding new features.” Same job, extend. Different job, a small new program.

Buy, grow, and replace only what must go. Fred Brooks puts buying first. The most radical way to construct software is to skip the construction. Grow from a running skeleton, so each new function comes out of what already runs. Dan McKinley (2015) says the same about tools. Add one when it changes your chance of solving the problem. When a part really should leave, Martin Fowler’s strangler fig grows the new behavior at the edge until the old path can go. And Jeff Atwood (2007) is the reluctance under every move. Every line you keep has to be read and supported. A second copy of the shop’s rules is not a gift.

Keep the shop you have

It leaves room to add. The welcome gift is still something new. The discipline is where it sits. It leaves room to start something new, too. A problem with no story yet is supposed to grow a design, one running skeleton at a time.

It leaves future plug-in points unbuilt until a real change feels awkward. And it leaves you able to read the rules. Karpathy’s weekend habit is a choice to read less, on purpose, for throwaway work. Treating that skip as the new default, without a shape that makes it safe, is the expensive version.

So extend the designs that already exist. Improve them when an extension would only be a patch. Compose a new piece when the old program would have to change jobs. Replace a part when the story is gone. And keep everything readable enough that a full read is often unnecessary.

The studies say something smaller than the slogans. One bounded task got faster. One familiar-code snapshot got slower. Saved changes rose by more than releases did. The design rules are what you do with that gap.

Sources

Accessed 26 September 2026 unless noted. Working-paper and survey figures are dated because they move.