Design docs describe the problem, not the code

Write a design doc that describes your code and you end up with a second copy of your program, less precise than the real one. Write one that describes the problem instead and you get something different. For a long time that wasn't practical, because somebody had to translate it into code by hand. That part has changed.

What happened to UML

A UML class diagram is meant to describe a domain. In practice it gets drawn in code vocabulary: classes, fields, visibility modifiers, multiplicities that are really foreign keys. You end up with a picture of the code you're about to write, and that causes two problems.

It repeats the code

Once the code exists, it says everything the diagram says, and says it more precisely. Keeping both in step is extra work for no new information. So people stopped, and they were right to.

You can't check it

There's no way to ask whether the diagram is true. You can only ask whether the code matches it. When it doesn't, nothing tells you which one to fix.

An ontology makes claims about the problem instead. "A song has exactly one credited artist" is a statement about music. You can agree or disagree with it without reading any code, and no refactor will make it false.

That buys you a few things. Someone who doesn't read code can review it. It survives refactoring, since refactoring changes the code and leaves the problem alone. And when two parts of a system contradict each other, you usually have one disagreement about the domain rather than two bugs, so you can settle it once.

What changed

The gap between the problem and the code was always there. It just cost too much to cross. Somebody had to translate by hand, slowly, once. Given that, you may as well write the spec in code terms and skip a step, and for thirty years that was a reasonable trade.

Models happen to be good at this particular translation. Hand one "a duet is a song with two or more performers, and the credit line lists them in billing order" and you get back the struct, the validation, a test case, and a sensible UI control, in whatever framework you name. It isn't compiling. It's closer to analogy: take the shape of the problem, find the matching shape in the framework.

Two things follow from that. The translation can be run again, so one problem-space doc can land on vanilla JS, on Spring Boot, on something that doesn't exist yet. A code-space spec can't be re-aimed, because it already picked one framework and threw the source away. And if you write the spec in code terms, you've done the easy part for the model while leaving the hard parts vague: what the thing is for, which numbers matter, what must never happen.

People often assume AI coding makes specs less important, since code is cheap now. I think it goes the other way.

If code is cheap to regenerate, it stops being the thing you own and becomes build output. The spec takes its place.

Three jobs it does

A map

Code tells you what exists. It's poor at telling you where anything is, or why it's arranged that way. The practical version: this is the document you read instead of the codebase. A few thousand tokens gets you oriented. Grepping for the same understanding takes much longer.

A touchstone

When two readings are possible, one place settles it. Pairing each rule with its test cases is what keeps that from being talk, since you can run something instead of arguing. And writing down the alternatives means "why not X?" already has an answer.

A guide for changes

With stable IDs, a change arrives as "D-17 is wrong," and that ID points at the rule, its tests, and the code citing it. Tagging what each piece serves is also how things get removed later, since you can show something is no longer needed.

A small worked example

These four pages have an ONTOLOGY.md sitting next to them, and it's the touchstone for the presentation you're reading. It says what each page owes you, what has to hold across all four, the few numbers involved, and the single action on the prompts page. The rule about keeping this tone gentle is in there too, which is why it reads the way it does.

It's short, and a static site is about as simple as a specified thing gets. If you'd like to see the format at small scale before trying it on something that matters, that's probably the cheapest place to look.

Read ONTOLOGY.md — the doc behind this site.

If you'd like to try it, the prompts are the cycle as things you type — nine of them, each with the mistake it's meant to head off. That page reads on its own.

If you're not sold, objections and costs has the two strongest arguments against this, and the one I think is right.