0003 is now superseded by 0056. Nothing is left proposed. Applied: - 06 corrected from ten contexts to seven plus the api, each row now stating why it passes the more-than-one-node test. work, knowledge and stream are named as mesh-hosted rather than dropped; `ai` folds into config; `record` is deferred explicitly rather than listed. Its frontmatter now cites 0055. - how-we-build §4 amended per 0054, and the derived page republished by playbook 05. The sync found the drift the playbook exists to catch: the published §4 and the source did not say the same thing. The source said "four accidents, not four boundaries"; the published page said "one intent expressed four times", and only the published page carried the scope caveat. Same rule, two texts, already diverging. Verified the republish by reading back -- the new rule is present and the old section's body returns nothing -- rather than trusting the success message. The two smaller findings: - 0051 separated the transport identity from the declaring authority. It said the token carries "an address" and "the identity to expect" without saying what the node dials. It dials the broker, so pinning only that would make the control plane's authority transitive and let a compromised broker forge declarations -- which, since the host applies whatever the link delivers, is the whole machine. The token now carries four things, and declarations are signed and verified per declaration. Cost recorded: rotating the signing identity is fleet-wide. - 0026 no longer restates 0022's rule about generated views. 0022's own words are "prose does not restate status; one place, and two is one too many", which is what 0026 was doing to it.
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 0020 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.