About this blog

This blog is a place for me to think through software development, architecture, tools, AI assisted work, and the practical judgment required to build useful systems.

Some posts are technical. Some are reflective. Some are about the way software development changes as the tools around us change. I am especially interested in the gap between what a tool can generate and what a developer still has to understand, review, shape, and own.

Recent writing has focused more on AI assisted software development, not as a replacement for engineering judgment, but as something that makes judgment more important. When AI can produce more code, more options, and more confident looking answers, the cost of weak review and unclear thinking can become higher instead of lower.

I also use this site for occasional writing outside of software. The main thread, however, is practical reflection from working with technology over time.

About me

I am a software engineer and architect. Much of my career has been consulting, which meant working across a lot of clients, domains, and systems instead of settling into one of them for very long. Most of my implementation background is C# and .NET, though the work has regularly required other languages and platforms. Lately much of my attention goes to applied AI: AI-assisted software engineering, the tooling around it, and the parts of the work that still have to stay with a person. I have stayed close to the implementation throughout, and I have never wanted the version of architecture that stops at documents.

I keep a shorter engineering overview of current projects and technical writing here.

I tend to write from the perspective of someone who enjoys technology, but does not want to treat every new tool as magic. Tools matter. Architecture matters. Judgment matters. The details of how people use these things in real projects matter even more.

Left to my own devices, I tend to stay with a problem while it is still ambiguous, turning it over until the shape of it is clearer. Contradictions stand out to me, since a system that contradicts itself usually means something upstream was never actually decided. I also follow a design choice into what it will force elsewhere in the system, and that is the part I am least willing to rush.

Ambiguous problems and well-specified plans both suit me. What matters more is whether the decisions that carry consequences have actually been made. I am not opposed to tradeoffs or temporary compromises, but I am reluctant to create structural debt knowingly when the problem is already visible. That does not mean every implementation choice has to be decided in advance, but the design should be complete enough before the code starts that the remaining implementation choices do not require reopening architectural decisions. Once the architecture and the constraints around it are sound enough, I am comfortable moving quickly through the build, or, more often lately, letting agents do much of the implementation from a design I have approved.

For a longer background on how I came to work with computers and technology, see Tech And I.