Skip to content

Articles

Practical engineering articles, newest first. Each article lists its publication date, author, categories, and estimated reading time. You can also browse by tag or subscribe to the RSS feed.

New here?

Start with Why I'm Finally Starting This Blog — the first post, on why this publication exists and how it's written.

The Best Idea Wasn't Mine. It Wasn't the AI's Either.

What happens when we stop directing AI and start thinking together?

For years, we've been learning how to give AI better instructions.

We write more detailed prompts. We establish requirements, define constraints, and describe exactly what we expect.

When the output isn't quite right, we refine our instructions and try again.

And when AI finally produces what we envisioned, we call that success.

But I've started questioning something fundamental about this approach.

What if we're limiting what AI can contribute by insisting that we already know what the solution should look like?

Recently, I had an experience that changed how I think about working with AI.

It involved a technical project, several challenging conversations, and two different AI models.

What made the experience remarkable wasn't the technology itself.

It was how the thinking evolved.

When AI Gets Better at the Wrong Thing

I've been wondering why some AI development efforts become remarkably productive and strangely underwhelming at the same time.

You know the pattern. An agent creates a plan, writes the code, runs the tests, reviews its own work, finds more things to improve, and starts another iteration. Perhaps a second agent critiques the first. The implementation gets more sophisticated. The test count grows. The progress reports are encouraging.

Then you try the result.

Everything seems to work. Yet it isn't quite what you had in mind.

That's the rabbit hole I've been thinking about: not an AI going off task in some spectacular way, but an AI making steady, defensible improvements to something that never quite becomes the thing you wanted.

I Don't Want AI to Just Build What I Ask

I've noticed something interesting about the way I work with AI. Increasingly, the part I value most isn't watching an agent finish a task. It's the conversation we have before either of us knows exactly what the task should be.

There's an appealing model for AI-assisted software development: describe a feature, let the agent work, and inspect the result. Sometimes that's exactly right. If I need a straightforward implementation and can describe the outcome clearly, I don't need a philosophical discussion with my compiler's new best friend.

But some of my most valuable work with AI has happened when I didn't start with a settled answer.

I've come to think of this less as delegating to an unusually fast developer and more as collaborating with another participant in the reasoning. Not because the AI and I are identical, or bear the same responsibility, but because the ideas move in both directions.

The Right to See What AI Is Building

As autonomous agents become capable of building complete software systems, architectural visibility may become more important than architectural control.

I've been questioning something about the role of software architecture in an age of autonomous AI.

For most of my career, architecture has been something we do to guide implementation. We examine requirements, identify boundaries, define responsibilities, make technology decisions, and establish the constraints that developers are expected to respect.

The assumption is that good architecture helps us build better software.

But I've been experimenting with autonomous coding agents, and some of the results have challenged that assumption.

In one experiment, I asked two AI agents to build the same application. One had access to a formal architecture system that could model the design, bind it to technology choices, and verify its implementation. The other worked without it.

Both produced remarkably similar results. Both made sound architectural decisions. Both built polished, working applications. Both successfully handled a significant change to the original requirements.

The architecture tooling produced better traceability and caught a real structural problem. But it didn't produce noticeably better software.

At first, that was disappointing.

Then I realized I might have been measuring the wrong thing.

Who Takes the Controls?

I've been thinking about the pilot sitting in the cockpit of a modern airliner.

For much of a commercial flight, automated systems can manage the aircraft's path with extraordinary precision. The pilots aren't just passengers. They monitor, communicate, anticipate, decide, and intervene. But the relationship between the expert and the machine has changed. The person with the greatest responsibility is no longer necessarily the one performing most of the routine work.

That reminded me of something I recently saw in software engineering.

I gave two AI coding agents the same product vision: build a small application that helps people lend belongings to one another. One agent had access to a formal architectural modelling and verification system. The other worked independently, using code, tests, and ordinary engineering documents. Both built complete applications. Both handled a substantial follow-up change. Both produced software that was remarkably close in quality.

I had expected the architecture tools to make a more noticeable difference. Instead, I found myself questioning something larger than architecture.

If an AI can do the work of an expert, what is the expert for?

The Architecture Was Correct. The Software Wasn't.

What happens when we build a perfectly well-architected system that nobody actually wants?

Software architects have a peculiar talent.

Give us a sufficiently complicated problem, and we'll find a way to turn it into boxes and arrows. We'll identify bounded contexts, establish dependency rules, define interfaces, and debate whether two services should communicate synchronously or asynchronously.

Eventually, someone will ask the question we've been carefully avoiding.

"Does it actually work?"

Of course it works. Look at the diagram.

The boundaries are clean. The dependencies flow in the right direction. The services are independently deployable. There's even a message bus.

It's beautiful.

Unfortunately, the users hate it.

The Context That Lets an Agent Work Alone

I've noticed something about the way I work with Claude Code. I tend to spend a considerable amount of time at the beginning of a session talking through what I'm trying to accomplish, sometimes before I have a clear idea of the implementation. Once the agent starts implementing, I rarely need to correct its direction.

That might sound like I'm writing unusually detailed instructions. I don't think that's quite what's happening. Often I don't know what the implementation should look like yet. If I did, there would be much less to explore. I'm trying to give the agent enough relevant context to find the shape of a good solution on its own.

Agents Can Only Fix What They Can Detect

I've been spending a lot of time building Continuum Atlas, a deterministic renderer for software architecture diagrams.

One of the challenges is getting diagrams to look good without compromising their accuracy. That's harder than it sounds.

Atlas evaluates different layouts using measurable properties: how many lines cross, how many bends they contain, how elements align, how they're spaced, and how well the diagram fits within its available space.

The idea is straightforward. Generate several candidates, measure them, and select the best one.

At least, that's what I thought.

I had a diagram where none of the five layouts generated using ELK's connector routing passed validation. After replacing that routing with Atlas's own obstacle-avoiding A* algorithm, all five passed.

That was a significant improvement.

But when I looked at the results, one of the newly valid layouts was actually worse. It had less measurable clutter, yet it was noticeably harder to read.

The measurements weren't wrong. The algorithm had genuinely improved the results according to the properties we were measuring.

The problem was that we weren't measuring everything that mattered.

I've been thinking about that experience because it highlights something important about agentic AI.

An agent can only correct a problem if something in its feedback loop can recognize that the problem exists.

Better Questions, Not Better Prompts

The advice for getting more out of AI has been remarkably consistent for a few years now. Be specific. Give it context. Define the role. State the constraints. Say how you want the answer formatted. All of that genuinely helps, and I still do most of it.

But when I look back at the sessions where an AI coding assistant was actually useful — where it found the real problem rather than a plausible one — almost none of them turned on the opening prompt. They turned on what I asked next.

I'm starting to think we've been naming the wrong skill.

From Prompt to Platform: Why Modern AI Code Review Needs an Architecture

When most people imagine an AI code reviewer, they picture a single prompt: hand the model a pull request, ask for a review, read what comes back. For small changes, that works surprisingly well — which is what makes the failure on larger ones interesting. As a pull request grows, the model starts losing context. Behavioral defects become harder to find. Security, correctness, architecture, and testing all compete for the same limited attention, and the review quietly becomes shallower even though the model hasn't changed.

I wrote recently about the correctness problem in AI code review, and ended with a suspicion: that the next generation of reviewers would be defined less by larger models than by harnesses built around them. This article is my attempt to describe what I think that harness looks like. Because the limitation I keep running into isn't model intelligence.

It's architecture.