The Two Things I Actually Want

A few years ago, on a call with other engineers, I said something like: I don't want an AI that helps me write code. Writing code is not my bottleneck. It's a fraction of what I actually do. What I want is something else entirely — and I can see two versions of it.

The first: an AI that helps me understand the codebase. Not generate more of it. Understand what I already have. Where should I add new functionality without breaking something three layers down? What are the hidden dependencies? Where are the problem areas accumulating? Which parts of the system are fragile, and why? This is the reasoning work that consumes most of my time, and it's almost entirely unsupported by current tools.

The second: an AI that makes it unnecessary to look at the code at all. Some kind of AI language — something where the source files express intent rather than specify implementation. Where I can describe what I want the system to do and the implementation is derived from that, rather than the other way around.

At the time, I viewed these as two separate problems. I've spent the years since realising they are the same thing — just viewed from different altitudes.

A tool that genuinely understands your codebase — its structure, its constraints, its history, the dependencies that aren't visible in any single file — already contains a model of that system. It has to. You can't answer "what will break if I change this?" without something that represents the system's semantics, not just its text. The understanding is not separate from the model. It is the model.

And a language for expressing intent at a level above implementation — something declarative, something where you say what rather than how — is exactly that model, made explicit and stable enough to be the source of truth. The two things I wanted are the same thing at two levels of ambition: a model of the system that exists somewhere outside any individual's head, that tooling can reason over, and that humans can inspect, challenge, and evolve.

Once I saw that, the question changed. It stopped being "which tool do I want?" and became: what would that artifact actually need to be?

When I said "AI language" on that call, I was picturing a general-purpose language — but one where the syntax was more declarative, closer to expressing what than how. I still think that's roughly right. What I'm less attached to is the input format: whether someone writes it directly, or an AI transcribes it from a conversation, or a team uses some other mode entirely. The input should adapt to how the team works. The artifact is one crucial part of this — but so is how you specify the program and how it executes. Ideally those are separate problems.

There is a third version of the same collapse. Taking an existing codebase and transforming it into this artifact is just another input mode — a different starting point, the same destination. The structural parts are largely derivable from the code. The intent behind decisions may not always be recoverable, but that gap doesn't make the transition infeasible. What I stated as two separate problems on that call keeps resolving to one thing; it is where they converge.

To understand what this artifact actually is, we have to look at what it must do. And I think it needs to do three things that source code already does, just one level up.

First: it needs to be the source of truth. Not a document that describes the system. Not a diagram that approximates it. The thing the system is derived from. The way source code is the source of truth for a compiled program — the executable is derived from it, not the other way around.

Second: it needs to be versioned. History matters in software for practical reasons — you need to reproduce a problem that was introduced three versions ago, roll back a feature that didn't work, understand why a decision was made so you can judge whether it's still valid. A system that can only show you the current state has thrown away most of what you need to reason about it.

Third: it needs to support concurrent collaborative evolution. Not just "shareable" — that just means multiple people can see it. Different groups, with different concerns, should be able to work in isolation — no shared connection required — and merge their work back into the shared truth. The merge is where separate lines of work become part of the whole. This is a coordination property, not just an access one.

None of these are new requirements. We solved them at the source code level decades ago, and we have two useful models for thinking about how.

The first is version control as we use it today. One canonical source of truth, local copies on each machine, explicit merges when separate lines of work need to be reconciled. The artifact exists independently of any individual working on it. Git didn't invent collaboration — it gave collaboration a stable object to operate on.

The second model is less familiar but equally valid: rather than storing snapshots, you store the sequence of transformations applied to the artifact. To arrive at the current state, you replay the history. The artifact is not the result — it's the sequence of intentional changes that produced it. It's closer to how understanding actually accumulates, and it's how event sourcing works in software systems today. As the system grows, replaying the full history from scratch becomes impractical — which is why snapshots and transformation logs tend to be used together, not as alternatives.

These are precedents, not answers. The mechanisms for managing a shared artifact that evolves collaboratively already exist. What doesn't exist is the artifact they would operate on — the layer above the source code we are familiar with today that captures not just what the system does but why, and that can serve as the thing everything else is derived from.

This is what the rest of this series is about. Not a better tool for working with code as it is. A different artifact — one that takes the same role source code plays today, but at the level where intent lives rather than implementation.

We have been here before. Assembly looked radical until C made it feel like a detail. C felt foundational until higher-level languages made manual memory management feel like archaeology. Each step was still code — just expressed at a different level, with a different set of things made explicit and a different set hidden below. The next step is the same kind of move. Not the end of code. The next rung.

Johan Aludden has been building software since the late nineties. He is currently thinking about what comes next.