4.1 KiB
topic, status, date, deciders, reconstructed, extends
| topic | status | date | deciders | reconstructed | extends |
|---|---|---|---|---|---|
| the mesh | accepted | 2026-10-02 | jochen | false | 02-DECISIONS/0154-the-meshs-own-verbs-are-the-controller-seats-tools.md |
185. A control plane behind its seat's row serves what it can
Context
The mesh's own verbs are the controller seat's tools, and the seat's row is the store's (ADR 0154). A control plane reads the row at start and installs a handler per verb; a verb the row carries that the binary cannot run was refused at start rather than at the first call, so that a disagreement between the row and the binary was said early. The refusal aborted the start.
On 2026-10-02 a merge added one verb. The new control plane started, widened the row, and ran. A
push a few seconds later recreated its container at the previous image — a stale declaration from
an overlapping wave, issue 201 —
and the older binary read a row naming a word it had never heard. It refused to start, and kept
refusing. The mesh had no voice for ten minutes: no verb answered, no node could be pushed, no build
was dispatched, and status said nothing because status is one of the verbs that had stopped
being served. The way back was a person running the binary by hand outside its service, because the
push that would have replaced it is itself a verb of the control plane that was down.
The check was right about the fact and wrong about the cost. A row ahead of a binary is the ordinary state of a roll-out: the row is widened by whichever control plane starts first, and a mesh with one control plane sees that gap on every merge that adds a verb. Making it fatal turned a transient into an outage with no path out that did not need a human.
Decision
1. A control plane serves the verbs it can run and does not refuse to start for the ones it cannot. The row remains the authority on what the seat serves; this is only about what this binary does when it is behind the row.
2. A verb it cannot run answers the reason. Not silence and not a missing subject: a caller gets a sentence naming the verb, saying this control plane cannot run it and that it is a verb of a newer build. A verb that is simply absent from the row is still not served at all — that is the row deciding, which is unchanged.
3. It says so once at start, naming every verb of the row it cannot run, so the gap is visible in the log of the thing that has it rather than only at the moment somebody calls one.
4. A mesh with no controller seat at all is still a refusal. That is not a version gap, it is a mesh that has not been seeded, and nothing this control plane does would be meaningful.
Consequences
- An overlapping roll-out costs the verbs the newer build added, for as long as the older binary is in place. Everything else — every push, every build, every read — keeps working, and the ordinary machinery that notices a machine is behind is what puts the newer binary back.
- The log gains one line on a control plane that is behind, and nothing on one that is not.
- Issue 201's other half remains: the push that sent a stale declaration is a race worth closing on its own terms. This record makes that race survivable rather than fatal, which is the difference between a transient and an outage, and is deliberately the cheaper half.
How this is checked
| Rule | Checked by |
|---|---|
| A row carrying a verb this build cannot run still serves every verb it can, and names the one it cannot | a controller test over a widened row |
| The unknown verb answers a sentence naming itself and saying this build is behind | the same test |
| A mesh with no controller seat is refused | the existing start-up path |