Files
hq/02-DECISIONS/0056-the-authority-is-the-control-plane-not-a-database.md
T
jschoubben 5e83ac2c22 Consolidate: 65 decision records to 52
Jochen: a normal application has 3-5 ADRs, maybe 10 for a large one, and we are
at 65. Fair, and the cause is mine -- I recorded every FINDING as a decision
rather than every fork in the road.

Two merges, both cases where one decision had been split across many records
because it was taken over several days rather than at once.

0019 absorbs ten records about how this repository works: what it is and that
it is public, the folder flow, the two design layers, the issue front door,
status in frontmatter, playbooks, the naming rule, the product name. Those were
never ten decisions -- they were one, seen from ten angles as the repository
took shape.

0016 absorbs the five about the lab: a node is a virtual machine, a router is
scenery, a scenario declares the underlay, a scenario is a closed address
space, and the two scenario classes. Same pattern -- one design, split by the
order it was worked out in.

The consolidated 0019 also raises the bar for what earns a record, since that
is what produced 65: a record is warranted when there is a genuine fork -- a
direction reversed, an alternative that will be proposed again, something
contested. A finding is not a decision, and a bug is certainly not. Everything
else belongs in the design document where the reasoning is actually read.

The checker earned its place here. Deleting nine records left 13 dangling links
across the repository and it named every one, including in AGENTS.md. Nothing
was found by reading.

Remaining clusters worth the same treatment: the host (8 records), delivery
(5), modules (6), connectivity (4), substrate and control plane (4). That would
be 52 down to roughly 30.
2026-08-28 18:53:19 +02:00

5.8 KiB

status, date, deciders, reconstructed, supersedes, extends
status date deciders reconstructed supersedes extends
accepted 2026-08-27 jochen false 0003-the-mesh-database-is-the-source-of-truth.md 0045-a-context-owns-its-store.md

56. The authority is the control plane, not a database

Context

ADR 0003 is still accepted and still cited as live by two as-is documents. Its decision says:

A single database holds every binding... The runtime loads its configuration from that database at startup and falls back to a local cache when the database is unreachable.

Every clause has since been decided against, in four separate records, none of which marked it superseded:

0003 says contradicted by
a single database holds every binding ADR 0045 — a context owns its store exclusively; three contexts must move out of the registry database, taking thirteen tables
the runtime loads from that database ADR 0037 — the host does not query the mesh database
— ADR 0039 — a node holds no credential to it
it falls back to a local cache ADR 0043 — the host has its own store, which is not a cache of anything

The two modules that still made 0003 literally true — wireguard and traefik, the only direct database connections left — are removed by ADR 0049 and ADR 0050. When those land, nothing on any node reads the mesh database at all, and 0003 will describe a mechanism with no remaining implementation.

The error underneath is a category error, and it is the same one ADR 0054 corrects elsewhere: source of truth named a storage location when what it meant was an authority. Once the store is the answer, "which database" becomes the question, and shared schemas follow — which is precisely the thirteen-table tangle ADR 0045 exists to undo.

Decision

The control plane is the authority for what runs where. A database is where one context keeps its state.

Three consequences of that sentence, replacing 0003's three clauses:

  • There is no single mesh database. Each context owns its store exclusively (ADR 0045). "The mesh database" is not a thing that exists; the registry database is inventory's store, and other contexts have their own.
  • No node reads any of them. A node is told what to own, over the link, in a bounded vocabulary (ADR 0037, ADR 0039). Reading the authority's storage is not how anything learns anything.
  • A node runs from its own store, always — not as a fallback. The host records what it owns and reconciles against it (ADR 0043). That store is the node's own record of what it applied, not a copy of somebody else's state.

What survives from 0003, unchanged

The half that was right, and it is the half everything else cites:

The repository defines what exists. The mesh defines what runs where. No node-to-module mapping is ever committed, and a node is described nowhere in source.

That is what makes the repositories node-agnostic and it is why anything about the mesh can be published at all (ADR 0019). Nothing here weakens it — this record changes where the authority lives and how it is reached, not whether bindings are committed.

Consequences

  • The cache mode disappears, and with it the fault it created. The as-is records the sharp edge: "a node running from cache looks identical to a node running from the database. There is no age on the cache and nothing reports divergence, so a node can be running yesterday's assignment set indefinitely without any signal that it is." Under this record there is no second mode to be mistaken for the first — a node always runs from its own store, and whether it has heard from the mesh recently is a separate, reportable fact rather than an invisible one.
  • "The mesh database" should stop being said, including in conversation. It names a thing that will not exist, and it is the phrase that makes a shared schema sound reasonable.
  • This closes the set of records that made nodes hold database credentials. 0037 decided it, 0039 named the exposure, 0049 and 0050 remove the two offenders, and this one removes the record that still authorised the arrangement — which was the last thing anybody could have cited in its defence.
  • Two as-is documents cite 0003 and describe today's behaviour accurately. They are not wrong and should not be changed: ADR 0019 keeps the layers separate, and as-is describing a superseded decision is exactly what as-is is for. What changes is the citation's status, not its content.
  • It does not say how today's mesh gets there. Thirteen tables move, two modules are rewritten, and nothing here costs that. Research 006 already lists the migration as unaddressed, and this record adds to what must migrate rather than explaining it.

References