RSS ⧉

Kyle's blyg

Kyle Mathews

Can a Codebase Know Its Own Design?

Software has always needed to be precise about what it does. Computers execute our implementations deterministically. But software has historically been much less precise about what it ought to do.

Much of that knowledge lives in developers' heads: which behaviors are essential, which are accidental, which tradeoffs were deliberate, and what makes one design better than another. Tests and documentation capture some of this, but human engineers have traditionally supplied the missing judgment.

Coding agents expose the limitations of this arrangement. Every fresh session arrives without the accumulated experience of the project's maintainers. It can read the code, but the implementation doesn't necessarily tell it which behaviors are promises and which are mistakes.

This raises what I think is one of the central questions of agentic programming: How can we make a codebase capable of preserving and enforcing its own design knowledge?

Distilling design judgment

Over the past few months, I've been experimenting with an answer while preparing TanStack DB for 1.0: oracles.

An oracle is an executable model of some law the software should obey. It might express how collection change messages should behave, what a query should return, or how optimistic mutations should reconcile with authoritative server data.

Unlike a regression test that checks one reported failure, an oracle can generate thousands of variations and compare the implementation against an independent model.

The models are often remarkably simple. One of ours uses a plain JavaScript Map to predict how a collection should behave across sequences of inserts, updates, and deletes. We compare that prediction against DB's actual behavior and what a subscriber reconstructs from its change messages.

The interesting part is how these models evolve.

Agents find counterexamples that expose weaknesses in our implementation—or sometimes in the oracle itself. We investigate, clarify the underlying law, and strengthen the model. Each iteration captures another distinction we've discovered matters.

I've started thinking of this as distilling design judgment.

The investigation might involve hours of research, experiments, thought experiments, and debate. Both human reasoning and LLM reasoning are imperfect and probabilistic. But the resulting judgment can be captured as a small, precise, deterministic model.

Determinism doesn't imply completeness. These models have blind spots, and the laws themselves can be mistaken. But unlike an informal understanding that drifts between sessions, they can be systematically challenged and refined.

A conversation across generations

Christopher Alexander argued that complex design emerges through an iterative process of discovering and resolving misfits. No designer can hold all the interacting constraints of a sufficiently complicated system in their head.

Coding agents dramatically accelerate this process. An LLM is an extraordinarily fast interface to the accumulated history of software engineering. Almost every question has relevant precedents somewhere in that vast history, but finding the right ideas and fitting them together remains an iterative process.

Oracles let us preserve the results.

An agent proposes a new implementation. An oracle challenges it with a counterexample. The agent investigates, drawing on existing software designs, and proposes another solution. Sometimes we discover that the earlier law itself needs revision.

It's a conversation between different kinds of models: the LLM's broad, approximate knowledge of software; the oracle's narrow, precise knowledge of one subsystem; my own understanding of the product; and the implementation's actual behavior.

Crucially, the participants don't need to share a context window.

An agent session might spend hours improving a single oracle, exhausting much of its available context. The next session inherits the result without reconstructing the investigation. A decision made months ago can speak up precisely when a proposed change conflicts with it.

The repository accumulates design knowledge that no individual agent—or I—could possibly hold in our heads.

Evolution with executable inheritance

Daniel Dennett's account of evolution offers a useful analogy.

Biological evolution accumulates sophisticated designs through countless generations of variation and selection. Each new adaptation must compete against organisms embodying billions of years of previous improvements. Successful designs survive, providing the foundation for further adaptation.

Our agent sessions work similarly. Each proposes variations against a system shaped by hundreds of earlier design decisions. A new implementation must preserve established guarantees while perhaps fixing more bugs, running faster, or achieving the same behavior with less complexity.

Oracles make this competition unusually precise. They preserve what earlier investigations established without necessarily preserving how earlier implementations worked.

And the selection machinery itself improves. Agents discover weaknesses in our oracles, strengthen them, and leave better instruments for their successors.

Dennett calls mechanisms that make increasingly sophisticated adaptations possible cranes. Oracles are cranes: they make it cheaper to explore the enormous space of possible implementations while retaining what earlier explorations taught us.

The important achievement isn't any single oracle. It's the cumulative process.

Software that carries its own theory

This isn't entirely new. Open source has always benefited from thousands of users discovering problems that maintainers couldn't anticipate. Linus's Law captured the power of distributing that discovery across many participants.

What's changing is the speed of exploration and the fidelity with which its results can be preserved.

Users discover misfits in real applications. Agents discover more through generated experiments. LLMs help investigate solutions across the history of computing. Oracles distill the resulting judgments into executable models that constrain subsequent work.

This changes the economics of ambitious software engineering. Projects involving enormous spaces of interacting behaviors—like compiling PostgreSQL queries into reactive client collections and automatically reconciling mutations—begin to look tractable. Not because an agent can understand the entire system, but because thousands of investigations can accumulate into a coherent design without any single participant understanding the whole.

None of this eliminates human judgment. Oracles are much better at enforcing established behavioral promises than deciding which promises are worth making. The human role increasingly involves defining those boundaries, deciding which tradeoffs matter, and reconsidering the rules when exploration reveals something unexpected.

But it suggests a different answer to the debate about whether we must carefully review every line of agent-written code.

Perhaps the more important work is building an environment in which proposed implementations must survive the accumulated design judgment of everything that came before them.

Traditional programming makes the implementation executable. Agentic programming gives us an opportunity to make the design increasingly executable too.

The result isn't software that understands itself perfectly. It's software that can increasingly explain, defend, and improve its own design—even as that design grows beyond what any of its contributors could comprehend alone.

Created: Oct 16, 2026