Files
hq/02-DECISIONS/0065-the-core-library-is-the-meshs-domain.md
T
jschoubben 10365f2eae Consolidate the design layer: one place per topic
Jochen: a jungle of specs that slightly contradict or patch each other, and
what matters is a working state rather than history. Both are fair and both are
mine.

Measured rather than assumed. 05-the-node-host and 09-the-node-lifecycle both
covered enrolment, the install commands, the unit file, the launcher and
reconcile -- I wrote 09 without taking anything out of 05, so the same things
were said twice and could drift apart.

Split by what each document IS. 05 is the component: what the host is, its
parts, the declaration vocabulary, the build order, how it is verified. 09 is
what happens to it: install, enrol, run, upgrade, retire. The whole "The
process" section left 05, and the unit file moved to 09 where installing is
described. 05 goes from 338 lines to 245 and now points at 09 rather than
restating it.

09 also carried a 105-line "Resolved" section -- six mechanisms framed as
"these were open and here is the answer". The content is needed; the framing is
history, and history is what makes a document read as a changelog rather than a
description. Renamed to what it actually is and the was-open phrasing removed.

Also added 10-delivery.md, which did not exist: four accepted decisions --
0054, 0063, 0064, 0065 -- had no design document at all, which is the specific
reason the delivery picture felt scattered. It is now one document covering
modules, the three edges, the core library, and how a change becomes a running
thing, with a table of what each property is designed against and what must
exist before it can be built.
2026-08-28 18:40:46 +02:00

88 lines
4.5 KiB
Markdown

---
status: accepted
date: 2026-08-28
deciders: jochen
reconstructed: false
extends: 0064-a-build-edge-is-a-third-kind.md
---
# 65. The core library is the mesh's domain, and types ship with their modules
## Context
[ADR 0030](0030-the-repository-structure.md) describes the shared library as *"contracts shared
across tiers: types, not behaviour"* — a guard against what the current one became, which is a
package holding too much code and, with it, everybody's dependencies.
**The guard is aimed at the wrong thing.** *Types, not behaviour* sounds safe and does not
address the fault: a library everything depends on is a hub whether it holds types or code. The
fan-in is what makes a change expensive, and *types not behaviour* leaves the fan-in exactly
where it was.
[ADR 0064](0064-a-build-edge-is-a-third-kind.md) makes this measurable rather than a matter of
taste: a module's cost is its **inbound build edges**, and a type hub has as many as a code hub.
## Decision
### Types ship with the module they belong to
A type is part of a module's contract, so it travels with the module. A consumer needing
`inventory`'s types depends on **`inventory`** — a real edge, narrow and visible — instead of both
depending on a hub where the relationship cannot be seen.
**This trades one wide edge for several narrow ones, and that is the improvement.** Under
[ADR 0064](0064-a-build-edge-is-a-third-kind.md) a change to one module's types now invalidates
its actual consumers, rather than everything that touched the hub.
### The core library holds the mesh's own domain, and that is the test
Not *shared code*. A drawer labelled shared is a drawer everything goes in, which is how the
current one grew.
> **The core library holds what is true of the mesh regardless of which context you are in.**
[Research 011](../01-RESEARCH/011-the-module-graph/00-overview.md) already found what that is:
**a module, a node, and an assignment.** Those three are the mesh's domain — every context speaks
about them, and none of them belongs to one context.
The test, applied to a candidate: *would this still mean the same thing in a context that had
never heard of the one it came from?* A node does. A pipeline stage does not — that is
delivery's. A grant does not — that is provisioning's.
**Domain-driven is the point rather than the label.** The current library is what happens when
the organising idea is *who else might want this*: the answer is always yes, so everything is
admitted. *Is this the mesh's domain* has a defensible no.
### Why this stays small on its own
A domain model changes when what the mesh **is** changes, which is rare. A shared-code drawer
changes whenever anybody writes something reusable, which is constantly. So the core library
inherits the property the graph is supposed to reveal — **few changes, many dependants** — rather
than fighting for it.
## Consequences
- **[ADR 0030](0030-the-repository-structure.md)'s description of the shared library is
superseded.** *Types, not behaviour* is replaced by *the mesh's domain*, and its types move to
the modules that own them. The rest of 0030 — the naming rule and the repository list — stands.
- **A module now publishes its own contract**, which it does not do today. That is real work and
it is the same work as making a module a self-contained artifact, so it is not additional.
- **The check is not the one that was proposed and is better.** *The build output contains no
runtime code* would have enforced *types, not behaviour* — a rule now withdrawn. What replaces
it is **inbound build edges**, which is a measurement rather than a prohibition: the core
library should have many, and anything else acquiring many is turning into a hub. That is
visible while it happens rather than after.
- **Fewer things will be shared, and some code will be written twice.** That is the trade and it
should be said plainly: the current library exists because sharing felt free. Under this it has
a name, an owner and a visible edge, and two similar functions in two modules is often the
better answer — `how-we-build` §8 already says three similar lines beat a premature
abstraction.
- **Nothing here says how a module publishes its types**, and the answer differs per language.
That belongs with delivery.
## References
- [ADR 0030](0030-the-repository-structure.md) — the description this replaces.
- [ADR 0064](0064-a-build-edge-is-a-third-kind.md) — what makes fan-in measurable.
- [Research 011](../01-RESEARCH/011-the-module-graph/00-overview.md) — module, node, assignment.