· 5 min read ·

The Rediscovered Truth That Every New Tool Ignores

Source: lobsters

Ulrich Friedrichsen’s post “It Has Never Been About the Code” lands a punch that should feel obvious by now. The central argument is simple: code is the artifact of software development, not the activity. The work is in understanding problems, aligning on solutions, communicating intent across a team, and making decisions that will still make sense six months later. Writing the code is, comparatively, the easy part.

What makes this worth dwelling on is not that the argument is novel. It is not. The industry has known this for decades, stated it clearly, and then proceeded to build an entire ecosystem optimized for the wrong thing.

The Theoretical Foundation Has Been There Since 1985

Peter Naur put this on paper in “Programming as Theory Building” (1985). His claim was specific and radical: the primary product of programming activity is not the program itself, but the theory the programmers build about the problem. The code is a projection of that theory into a form the machine can execute. When a team disperses, the theory is lost even when the code remains, which is why maintenance is so hard and rewriting from scratch is so tempting.

Fred Brooks made a related argument in “No Silver Bullet” (1986), distinguishing between essential complexity, which is inherent in the problem domain and cannot be engineered away, and accidental complexity, which comes from our tools and representations. The premise was that most of the hard work in software is essential, and no tool can eliminate it. Better editors, faster compilers, and smarter IDEs reduce accidental complexity. They do nothing for the essential kind.

Both of these arguments were written before GitHub, before Stack Overflow, before language servers, and long before large language models. They described the fundamental nature of the problem and predicted, implicitly, that no amount of tooling progress would change it.

Where Time Actually Goes

The empirical picture supports the theory. Multiple studies from Microsoft Research, including “How Do Software Developers Really Use the Internet?” and the broader body of work from their developer productivity group, consistently show that developers spend roughly half their working time on activities that are not writing new code. Reading existing code, debugging, attending meetings, writing documentation, reviewing others’ work, and handling interruptions account for the majority of the working day.

More directly, LaToza, Venolia, and DeLine’s 2006 study found that maintaining mental models, which means understanding what code does and why, consumed around 35% of developer time. The act of composing new syntax was a fraction of that.

The DORA State of DevOps research frames software delivery performance through four metrics: deployment frequency, lead time for changes, change failure rate, and mean time to restore. None of these is a direct function of how fast developers type or how quickly they can produce a function body. The constraints that limit high performers are organizational and architectural: feedback loop latency, testing confidence, deployment safety, and the ability to decompose work into independently shippable units.

This is not a knock on any particular tool or methodology. It is a structural description of where the bottlenecks actually live.

The AI Tools Paradox

GitHub Copilot’s widely cited 2022 productivity study reported that developers completed isolated coding tasks 55% faster with AI assistance. The number is real and meaningful for its context. The context is controlled tasks with clear specifications, where the hard thinking had already been done.

Real software delivery does not look like that. The bottleneck is rarely “we know exactly what to build and need someone to type it.” It is usually some combination of: unclear requirements, competing interpretations of what the user actually wants, architectural choices whose tradeoffs are not obvious, test coverage that does not catch what breaks in production, and review processes that create queues.

Kent Beck observed in 2023 that AI had reduced his value on implementation tasks substantially. His framing, though, was that this made the upstream work, problem framing, decomposition, identifying the right abstractions, more important, not less. The ratio shifts. The ceiling on delivery speed imposed by implementation velocity gets raised, which means the next constraint surfaces more visibly.

This is how constraint-based thinking works in any system. If you have been building Discord bots for a while, you recognize the pattern immediately. The latency in shipping a new feature is almost never about how fast you write the event handler. It is about whether you understood what behavior users would find intuitive, whether you thought through the edge cases in how Discord delivers message events, whether you scoped the change so it does not break the session store. The code itself, once the design is clear, tends to follow quickly.

The Real Work, Concretely

Building a bot that handles moderation taught me more about this than any essay has. The initial implementation of a warning system takes an afternoon. Getting it to behave correctly across channels with different mod policies, understanding the implicit social contract between moderators and users, deciding how escalation should work when the original moderator is offline, handling the edge case where someone is warned in a thread that gets archived before the warning resolves: that is where the weeks go. None of it is hard to code once it is clearly defined. None of it is easy to define clearly.

The same pattern holds in production systems, in compilers, in infrastructure tooling. The moments where you stare at a blank function body are not the slow parts. The slow parts are the conversations, the diagrams, the re-readings of old decisions, and the quiet work of holding the whole system in your head long enough to understand what you actually need to change.

What Follows From This

Friedrichsen’s argument has a practical implication that is easy to miss: optimizing for code production is not just insufficient, it actively misdirects attention. If teams measure productivity by lines committed or tickets closed, they will optimize for those things, and the essential work, the thinking and the communication, will be squeezed into the margins or treated as overhead.

The tools that would genuinely move delivery speed are not faster autocomplete. They are better interfaces for capturing and communicating design decisions, faster feedback loops between a change and its observable effects in production, and organizational structures that reduce the coordination overhead between the person who understands the problem and the person who writes the code. Sometimes those are the same person, but at scale they often are not.

This does not mean AI coding tools are worthless. Reducing accidental complexity has real value. It means treating them as a solution to a delivery bottleneck is a category error. The bottleneck was never the typing.

Was this interesting?