Design 47: a settings-form module's values in the placement file, the vault's own, both sources' readers, the switch when placed, and the order of the delivery and the seed (issue 1126)
mesh/delivery-group group feat/1126-nodes-compose checking: 4 of 6 member(s) ready
mesh/delivery closed: a newer head of the same pull request
mesh/check checking 7c88f297fc59 on 278ca42b3df2 | novox/hq#482 in group feat/1126-nodes-compose

This commit is contained in:
2026-10-26 19:45:32 +01:00
parent 495d740d5f
commit 7c88f297fc
@@ -682,7 +682,14 @@ backup holder backs up nothing, and the have says so.
the key's change (ADR 0555 §3);
- **the manifests**, the indexer's `modules.<module>` and its manifests by digest, or the digest the composing
node's want names where it runs another build; the private network's manifest comes with mesh-sdk;
- **the config values**, mesh-config's resolved state, the composing node's slice alone for a node agent.
- **the config values**, mesh-config's resolved state, the composing node's slice alone for a node agent; a module
in the settings form (its manifest declares no config, so mesh-config holds none for it) has its values in the
placement file instead;
- **its own secrets and credentials**, from the vault's verb `own`, sealed to the asking node's key and answered to
that node's engine alone, and composed again when the vault says `secret-changed` (ADR 0550 §5).
While both sources stand (ADR 0549 §5), mesh-config resolves values for a module either the placement or the
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:
- the node's decided facts: its endpoint and site, whether it is the private network's hub, its address on the
@@ -694,7 +701,8 @@ backup holder backs up nothing, and the have says so.
listens on, its bindings by provision, and its config placement (`places`, `accesses`, `networks`,
`endpoints`, `expose`, `reach`, `ports`) as two layers: the mesh-wide one, repeated in every node's file so a
node reads its own key alone, and the node's own, with a mark when the node has a layer that holds no placement,
since an empty layer still carries the module's config values;
since an empty layer still carries the module's config values; and, for a module in the settings form only,
the config values a person set in each of those layers (on the day of the seed the media modules of one node);
- its pins by provision, and the seats its modules hold.
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
@@ -717,13 +725,22 @@ backup holder backs up nothing, and the have says so.
plus exactly these reads and the bucket-creation advisories of issue 1790.
- **A node composes its own once the catalogue places it.** Its agent reads its key `placement.<node>` at start:
with one it composes its own, without one it applies the controller's compositions as before, so nothing changes
on a node before the seeded placement file reaches it. A node never applies a stand-in: a composition that stands
on a node before the seeded placement file reaches it; it follows the key, and when it appears the agent begins
again composing its own, with no restart. A node never applies a stand-in: a composition that stands
in for a value its input lacks (an own secret, a credential, a vault box, the certificate) is refused whole, said,
and the node keeps running what it runs; the bus's user list alone is held out of the apply, since the bus node
follows it apart. So until a node's own secrets and credentials come sealed from the vault (ADR 0550 §5), a node
with any module holding one composes nothing of its own. Likewise a consumer of `model-access` answered by a
follows it apart. A secret or credential the vault does not hold is such a gap: the vault names it missing, and
the node composing it keeps what runs until the vault holds it. Likewise a consumer of `model-access` answered by a
licence record, placed before the vault serves licences (ADR 0550 §3, issue 569), is refused by the same guard and
its node keeps what runs; none is placed today.
- **The order a node takes to composing its own.** One delivery group carries every part: the controller's verb
`placement-export`, the node-engine (its record and its own composer), the vault's `own`, the grants part's reads,
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
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
composed again when its event is heard, and applied as a revision of what runs (ADR 0547 §2).