Engineering3 min readBy Tim Layton

My hypocrisy about AI coding

Unstructured AI coding left me disconnected from the work. I now delegate more implementation than ever, and I've never enjoyed being an engineer more.

There’s an obvious hypocrisy in what I’m about to say. Writing code through unstructured prompting left me disconnected from the work in a way that felt bad. I disliked it much more than crafting code by hand.

We were trying to build multiple ambitious projects at once, and I built tooling to make that possible. I hadn’t intended the tooling to become a product, but it did.

I’m having AI write more of the code, with less of my involvement in the implementation, and somehow I’ve never enjoyed being an engineer more. From the perspective of how much code I’m personally writing, pointing out the hypocrisy is entirely fair. I’m doing more of the thing I’m saying felt wrong.

But the part that changed for me was how much thinking I was doing, what I was thinking about, and what happened to that thinking once implementation started.

With unstructured prompting, I spent a lot of time steering a session, discovering what it had misunderstood, reconstructing context, and asking it to try again. I was deeply involved, but much of that involvement was cleanup. Producing more code faster had given me more code to inspect without necessarily giving me a better understanding of the solution.

Now I spend more time on system architecture, technical designs, and applying design patterns across larger bodies of work. I can think through where responsibilities belong, how changes fit together, which dependencies we can eliminate, and whether we need to build something at all. I get to refine the solution before there are thousands of lines of implementation making the first plausible approach expensive to reconsider.

That feels much closer to the kind of laziness I’ve always considered a virtue: putting more thought into how to do less work while still solving the whole problem.

The implementation matters just as much. I’m handing that design to a structured, type-driven engineering process that carries requirements through the work and checks evidence against them. It investigates the surrounding system, considers the problem from different perspectives, works through a plan, and subjects the implementation to verification and independent review. The thinking has somewhere to go, and there is machinery to check what happened to it using a system I trust.

That’s a very different thing from giving a model a narrow prompt, setting the thinking effort to “ultra,” and accepting its account of how thoroughly it solved the problem (✋ guilty). The model can put considerable effort into the problem it was given and still miss that the problem was framed too narrowly. And a confident explanation of what it checked still leaves you needing evidence that those checks establish what matters.

I still care about the implementation, and I still want to refine it, but through iterating on an autonomous engineering system so I can scale the refinement. I've hardly become indifferent to the code because something else writes it and still feel a very strong pull to make sure the code it’s writing is something I'm happy with. What changed is that I can put more of my effort into understanding and designing the whole solution, with a process that carries that care into the implementation and the personal benefit of knowing that I'm committed to making that process better every day.

You can still call that hypocrisy, I wouldn't disagree. But to me, it feels like getting back to the virtue of laziness that made it useful in the first place: doing less because you thought more, while still getting the job completely done. And doing real [strategic] engineering again, not babysitting.