Why I still write code as a product leader
Writing production code as a product leader compresses decision latency: faster iteration, feasibility you can check yourself, AI behaviour you can debug directly, and no organisational telephone.
Writing production code as a product leader compresses decision latency: it shortens the time between a question and a trustworthy answer. Most of what makes product decisions slow is not thinking time. It is the relay between the person who has the question and the person who can answer it.
I want to be precise about what the practice actually changes, because the honest version is narrower and more useful than “leaders should code.”
Faster iteration loops
The loop that matters is question to answer to next question. Every step you cannot take yourself adds a queue.
“Would it feel better if the result streamed in instead of landing all at once?” is a five-minute question if you can change it and look. It is a two-day question if it has to become a ticket, get prioritised, get built, and come back for you to react to, by which point you have lost the thread that made you ask. The cost is not the engineering time. It is the loss of momentum, and the quiet way a slow loop trains you to ask fewer questions.
When you can close the loop yourself, you ask more of them, and you ask sharper ones, because the cost of being curious dropped.
Feasibility you can check before it hits a roadmap
A roadmap is a set of promises. The expensive mistake is promising something whose hard part you have not seen.
Plenty of features look like a week and turn out to be a quarter, and the difference is usually invisible from the outside: the third-party API that rate-limits in a way that breaks the whole flow, the data that does not exist in the shape the design assumes, the latency you only notice once real volume hits it. You find these by building a thin version and watching where it strains. Doing that yourself means feasibility is something you have checked, not something you have been told. The roadmap gets more honest because the person making the promises has touched the part that would break it.
The highest-leverage version of this happens live, in the room. A client or a non-technical stakeholder describes what they want, and because I can see roughly how it would be built, I can think through a couple of implementations on the spot, settle on the leanest one that would actually test the idea, and put a rough timeline on it before the meeting is over. That turns a one-way feature request into a decision we make together: here is what it would take, here is how valuable you actually think it is, and given both, is it worth doing? Far better to have that exchange with the person who knows the value, while the cost is still a cheap estimate, than to carry a vague ask back to a team and return weeks later with a number that reopens the whole question. Value for effort is the call that matters most, and it is the one technical depth lets you make in real time.
AI behaviour you can debug directly
This is the one that has changed most, and it is where a relay does the most damage.
When an LLM does something wrong, the bug is rarely in the code in the ordinary sense. The model invents a field that is not in the schema, or ignores half the context, or behaves perfectly in the demo and falls apart on the input a real user gives it. Diagnosing that means reading the actual prompt that went over the wire, the actual context window, the actual tokens that came back. It is empirical work, and it does not survive translation well.
Through a relay it goes: “it’s giving weird answers” becomes a ticket, becomes an engineer’s best guess at reproducing a vague complaint, becomes a fix for a problem that may not be the real one, comes back, still wrong. Each hop strips detail from a problem that is made of detail. Debugging it yourself collapses that to one person looking at the trace. On the VicRoads number-plate pricing work, the front end was an LLM and the engine behind it was deterministic; the entire art was in where the model was allowed to reason and where it had to defer to the engine. That boundary is not something you can specify from a distance. You find it by watching the model fail and moving the line.
Skipping the organisational telephone
Intent degrades at every handoff, the same way the playground game works. What you meant becomes what you wrote, becomes what they read, becomes what they built. Nobody is incompetent; meaning just leaks at each crossing, and the leak is largest exactly where the nuance matters most.
Code skips the relay. The intent and the artefact are the same object. There is no version of “what I meant” that is separate from “what shipped,” because you wrote the thing that shipped. For the decisions where the nuance is the whole point (the pricing edge case, the model boundary, the interaction that lives or dies on fifty milliseconds) removing the telephone is not a nicety. It is the difference between the decision arriving intact and arriving distorted.
Understand the layer beneath you
Underneath those four reasons sits a more general principle, and it’s the one that makes the habit more than nostalgia. To lead a domain, you have to understand, in detail, the layer directly beneath the one you operate at. Not the bottom of the stack; the next layer down. It holds going up a hierarchy and going down a stack of abstractions, and it’s the same rule both times.
Take the abstractions. A product manager’s decisions are ultimately expressed in code, so code is the layer beneath you, and you have to be able to read it. A programmer doesn’t need to know the binary, but they do need mechanical sympathy: a feel for how their code compiles and runs against the machine, enough to write something performant rather than merely correct. Go one layer below the one beneath you and it’s noise; nobody needs the binary. The hierarchy works the same way. A CEO doesn’t need to know what each individual is doing, but does need to understand, in detail, what each department is doing. A department head who tracks exactly how each person does their work is micromanaging, but one who can’t say which tasks are being done, by whom, and how they ladder up to the goal isn’t leading. One layer down, in detail. Lower than that is either noise or control.
This is the case for coding that actually convinces me. It lets me step into a technical conversation with people far more technical than I am and hold my end of it. Engineers have a depth I don’t; what they often lack is the business context and the strategy that decide which trade-off at their layer is the right one. Understanding their layer is what lets the conversation ladder up to mine. I’ve worked hard to be able to pivot mid-conversation between design, technology, strategy, and the market side, pricing and economics, because each of those rests on the one beside it and none of them is the whole picture alone.
I’m watching the same rule play out from the other side now, as non-technical people start shipping real code with a model’s help. They can describe the business behaviour they want, which gets them further than anyone expected. But they’re missing the layer beneath: branches and rebasing, linting, the tests that tell you something broke, the mental model of how it all fits. So when something goes wrong they’re stuck, at the mercy of the model that wrote it. It is still remarkably powerful, and it is also capped: there’s a ceiling on the complexity, and therefore the value, they can deliver until they learn the domain, because the domain’s own language is exactly what unlocks the next level of performance from these models. The layer beneath still has to be understood, even when the machine is the one typing.
The limits, honestly
This is not always the right use of a leader’s time, and pretending otherwise is its own failure.
The job is leverage, and your hands in the codebase are a narrow lever. Write the code when the decision quality genuinely depends on you having touched the thing: the risky feasibility question, the AI behaviour nobody else can characterise, the prototype that settles an argument faster than a meeting would. Do not write it when an engineer would do it better and faster and the only thing your involvement adds is your ego in the commit history. A leader who is heads-down in a feature that someone else should own is not compressing decision latency; they are creating a bottleneck with their own name on it. The skill is knowing which is which, and the tell is simple: am I the lowest-cost path to a trustworthy answer here, or just the most comfortable one.
The frame that holds all of this together: code is not a claim on territory and it is not a hobby smuggled into the job. It is the shortest path between a question and an answer you can trust, for the specific class of questions where the relay would have wrecked the answer on the way back. Use it there. Everywhere else, your job is still to make other people’s loops faster, not to live inside your own.