Design 47 and the glossary: a placement change is answered by the nodes it places before it merges (ADR 0559, issue 1126)
The seed and every later placement pull request were to be checked as equal to what runs, which no composition outside the node can show; the nodes now answer a placement candidate.
This commit is contained in:
+7
-1
@@ -237,7 +237,7 @@ every other domain has something to run on. **Recorded by** the controller and t
|
||||
**Purpose.** To decide, send and apply what each node runs, and to say why.
|
||||
**Recorded by** the controller's `inventory` database; from ADR 0549, by the catalogue's placement files, which
|
||||
the indexer reads onto the bus. **Upstream of** Provisioning, Connectivity, Data
|
||||
and Health and repair. **Decided by** ADR 0100, 0126, 0176, 0181, 0207, 0221, 0252, 0261, 0411, 0539, 0549.
|
||||
and Health and repair. **Decided by** ADR 0100, 0126, 0176, 0181, 0207, 0221, 0252, 0261, 0411, 0539, 0549, 0559.
|
||||
**Uses:** node, machine, module, seat, manifest (Module), config value (Config).
|
||||
|
||||
- **assignment** — a module put on a node. Its config values on that node (module-assignment config,
|
||||
@@ -247,6 +247,12 @@ and Health and repair. **Decided by** ADR 0100, 0126, 0176, 0181, 0207, 0221, 02
|
||||
and the indexer reads it at each trunk merge into its state `placement`, one key per node, which every reader
|
||||
of placement watches (ADR 0549 §1 to §3). Until ADR 0547's third milestone the controller's assignments are
|
||||
kept equal to it.
|
||||
- **placement candidate** — a placement file of one node as an open catalogue pull request has it at its head,
|
||||
kept by the indexer in its state `placement-candidates` under `<group>.<node>` while the pull request is open.
|
||||
Every node composes it in **shadow** (composed and compared, never applied) and answers in its own have whether
|
||||
what it would run is the same; the composition check passes only when every placed node has answered the same
|
||||
or differs only where the change intends (ADR 0559). Not the indexer's candidates of a group, which are
|
||||
fingerprints (Delivery).
|
||||
- **pending assignment** — an assignment of a module whose build is still running, kept, and made by the
|
||||
controller when that build registers the module, or ended with why when it does not
|
||||
(ADR 0261).
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
layer: to-be
|
||||
status: in-progress
|
||||
code: [mesh-controller, mesh-catalog modules/mesh-delivery-gate, mesh-delivery, mesh-host, mesh-sdk, mesh-vault, hq 00-META/checks]
|
||||
updated: 2026-10-26
|
||||
updated: 2026-10-27
|
||||
decisions:
|
||||
- "ADR 0559"
|
||||
- "ADR 0555"
|
||||
- "ADR 0551"
|
||||
- "ADR 0550"
|
||||
@@ -129,7 +130,11 @@ source revision is derived from the keys: every **want** equals its module's **f
|
||||
group and the modules of the trunk. At each trunk merge of the catalogue it also reads the catalogue's
|
||||
**placement files**, one per node, into its state `placement`: one key `placement.<node>` with that node's
|
||||
modules, their pins, host ports and bindings, and the source revision. It adds the nodes to `modules.<module>`
|
||||
and says `placement-changed` only for a node whose key differs (ADR 0549 §1, §2).
|
||||
and says `placement-changed` only for a node whose key differs (ADR 0549 §1, §2). While a catalogue pull request
|
||||
that changes a placement file is open, the forge bridge carries its placement files at the head and the indexer
|
||||
keeps, at each head, each node's file that differs from the trunk's as a **placement candidate** in a state of its
|
||||
own, `placement-candidates`, one key `<group>.<node>`, deleting the group's other keys, and all of them when the
|
||||
pull request merges or closes; nothing that composes what runs reads it (ADR 0559 §2, §3).
|
||||
- **The builder** claims a build by creating its key, once per fingerprint, and orders it as an ask on the stream of the artifact's
|
||||
language; it makes no artifact's bytes since R4e and chooses no node, because the build modules pull the asks (ADR 0498 §1, ADR 0525 §1, §4). From R4g it
|
||||
delivers its own module, the build modules and the controller from its keys, and nothing falls back to build-agent, which is removed
|
||||
@@ -165,7 +170,15 @@ source revision is derived from the keys: every **want** equals its module's **f
|
||||
It also runs the **composition check**: whether the machines a change touches still compose with it, read
|
||||
from the keys the indexer and the builder hold and from the machines, settings and grants it reads, with
|
||||
mesh-sdk's composition, the one every node agent composes with (ADR 0446, ADR 0547 §2). Its module was made in
|
||||
R4g with release 5; from release 6 it writes no difference (ADR 0524 §4, ADR 0528, ADR 0539 §8).
|
||||
R4g with release 5; from release 6 it writes no difference (ADR 0524 §4, ADR 0528, ADR 0539 §8). For a
|
||||
change that carries placement candidates it composes the change with them laid over the trunk's placement,
|
||||
counts every node whose placement changes among the machines it touches (ADR 0446 §3, as ADR 0559 §5 changes it), and names each refusal; then it reads each
|
||||
placed node's answer to the candidate and fails on a module that differs where the change does not intend it (on
|
||||
a node the trunk does not place yet, as at the seed, no difference is intended), on
|
||||
a refusal, and on a node that has not answered within 10 minutes, named, so a laptop asleep is never passed;
|
||||
that node's later answer at the same head asks the check again on its event, as for any part of the mesh not
|
||||
heard (ADR 0548 §1, ADR 0559 §1, §5). Its own composition stands in for every sealed value, so only a node's answer can say that
|
||||
what the node would run is the same.
|
||||
- **The node agent**, the node-engine's own process, follows its node's wants, **composes each wanted module for
|
||||
its own node** with mesh-sdk's composition from the manifest by digest, the module's resolved values from
|
||||
mesh-config, its secrets and bus credential asked of the vault sealed to the node's key, its licences and what
|
||||
@@ -691,7 +704,7 @@ backup holder backs up nothing, and the have says so.
|
||||
controller's assignments name on a node, and the grants part composes both, holding a seat held once for the mesh
|
||||
where the placement says.
|
||||
- **The placement file.** One file per node in the catalogue, changed only by a pull request and checked before
|
||||
it merges (ADR 0549 §1, ADR 0555). It holds what a person decides of the node and nothing a machine observes:
|
||||
it merges by the nodes it places (ADR 0549 §1, ADR 0555, ADR 0559). It holds what a person decides of the node and nothing a machine observes:
|
||||
- the node's decided facts: its endpoint and site, whether it is the private network's hub, its address on the
|
||||
private network (a decision written once at enrolment; nothing allocates one at run time), the domain its
|
||||
routed names are composed under, its operator and agent logins by name with their homes, whether it is
|
||||
@@ -707,6 +720,21 @@ backup holder backs up nothing, and the have says so.
|
||||
The catalogue's check refuses a placement naming a module it does not hold or a node not enrolled, two modules
|
||||
of one node on one host port, a pin, binding or holding naming a provider not placed where it says, a seat held
|
||||
once for the mesh held twice, two nodes with one address and more than one hub, each named in one answer.
|
||||
- **A node answers a placement change before it merges.** The node agent watches every placement candidate. For
|
||||
each open group it composes its own node in shadow, from the trunk's placement with the group's candidates laid
|
||||
over it and its own inputs, the sealed values and vault boxes it already holds among them, and applies nothing.
|
||||
It compares the result with what it runs, module by module by composition digest, the bus's user-list resource
|
||||
left out, and writes the answer into its own have key `<node>.node` under `candidates`, by group: the head
|
||||
answered, the modules the same, each module that differs with both digests, each module added or removed, and
|
||||
each refusal. A module the candidate adds is answered as added, naming the values not yet issued for it, since
|
||||
its credential and boxes are made only once it is placed; a refusal is a value missing for a module the node
|
||||
runs. It writes only when the answer changes, removes it when the candidates go, and answers
|
||||
whether or not the node is placed yet, so before the seed it answers against what it runs from the controller's
|
||||
compositions. The candidate's key is the node's event, the answer is a key the node alone writes, and the
|
||||
composition check hears that key's change; nothing polls. `indexer_placement`, served by the status view, also
|
||||
shows each open group's candidates and every node's answer, and the indexer's `indexer_placement_reread` reads
|
||||
placement and the candidates again now, writing only what differs. The contract (the state, its key, the answer,
|
||||
the composition with a given placement and the comparison) is mesh-sdk's (ADR 0559 §4, §6, §7, §8).
|
||||
- **The node record.** What the machine observes of itself: its tunnel's public key, its capabilities, the
|
||||
public halves of its sealing and serving keys, the certificate issued for its internal name, its outward links
|
||||
and networks, and its node-engine's contract. Written at start and when an observed fact changes, only when it
|
||||
@@ -738,8 +766,8 @@ backup holder backs up nothing, and the have says so.
|
||||
mesh-config's and the assigner's reading of placement, and the indexer writing it. Nothing changes on a node by
|
||||
that delivery alone, since no placement file exists yet: the node records appear, and the grants part's list gives
|
||||
the nodes their reads. Then the seed: one catalogue pull request writes each node's placement file from the
|
||||
controller's export, and its composition check composes every node from it with no difference to what the node
|
||||
runs; only then is it merged. The indexer writes `placement`, each node begins composing its own, and the assigner
|
||||
controller's export, and its composition check passes only when every node it places has composed it in shadow
|
||||
and answered that what it would run is the same (ADR 0559 §1); only then is it merged. The indexer writes `placement`, each node begins composing its own, and the assigner
|
||||
writes its wants as the build alone.
|
||||
- **Composed again on events, never on a timer.** A changed input at the same fingerprint (a setting or given
|
||||
value, a secret rotated or moved, a credential issued, a provider's contribution, a peer added to the hub) is
|
||||
@@ -861,6 +889,7 @@ assignments bucket is kept equal to it until ADR 0547's third milestone and is a
|
||||
| want | the fingerprint a node should run of a module, and the digest of the one composition it allows; the node's own want names its node composition | the assigner | `mesh-delivery-assigner_wants` |
|
||||
| have | what the node runs of a module: the fingerprint, the composition's digest, the phase and the health | the node agent | `node-engine_have` |
|
||||
| placement | each node's modules with their pins, host ports and bindings, from the catalogue's placement file of that node at each trunk merge of the catalogue | the indexer | the indexer's state `placement` |
|
||||
| placement candidate | while a catalogue pull request that changes placement is open: one node's placement file at its head, beside the chain and never composed into what runs (ADR 0559 §3) | the indexer | the indexer's state `placement-candidates` |
|
||||
| assignment | until ADR 0547's third milestone: the module and node, pinned or not, ended or not, written by `assign` and `unassign` after a merged placement change, so that it equals the catalogue (ADR 0549 §5) | the controller | `mesh-controller_assignments` |
|
||||
| rollout | read-only from release 6: each plan of releases 1 to 5, its tiers, the builds it carried and the assignments it changed | nobody from release 6 | `mesh-controller_rollouts` |
|
||||
|
||||
|
||||
Reference in New Issue
Block a user