From 0488bc180191434afa05b9e4fd6f259de54b2167 Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 26 Oct 2026 18:20:51 +0100 Subject: [PATCH 01/10] Design 47 says what a node composes from: placement with the node's decided facts and settings layers, and the node's own record (issue 1126, ADR 0549, ADR 0555) --- .../47-delivery-from-commit-to-delivered.md | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md b/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md index c5a0cd3f..71de04bb 100644 --- a/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md +++ b/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md @@ -4,6 +4,7 @@ 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 decisions: + - "ADR 0555" - "ADR 0551" - "ADR 0550" - "ADR 0549" @@ -663,7 +664,7 @@ backup holder backs up nothing, and the have says so. ## Compositions, wants and the apply -*ADR 0360 §8, §9, ADR 0377, ADR 0429 §4, §6, ADR 0539 §9, §14 to §16, ADR 0547 §2 to §9.* +*ADR 0360 §8, §9, ADR 0377, ADR 0429 §4, §6, ADR 0539 §9, §14 to §16, ADR 0547 §2 to §9, ADR 0549, ADR 0555.* - **Each node composes its own.** For each want `want..` the node agent composes that module for its own node with mesh-sdk's composition from the manifest by digest the indexer wrote, the module's resolved @@ -672,6 +673,36 @@ backup holder backs up nothing, and the have says so. own composition (adoption, firewall openings, accounts, the resolver, identities and groups) from the same inputs. Of other nodes it reads only their public records and the manifests wanted on them, which its firewall and resolver need. Nothing composed crosses the bus, so nothing composed is signed (ADR 0547 §2). +- **What a node composes from, and who writes it.** One composer, mesh-sdk's, has three callers: the node agent for + its own node, the assigner's composition check for every node, and the grants part. Each fills the composition's + input from the bus with its own credential and nothing else (ADR 0547 §2, ADR 0549 §3): + - **placement**, the indexer's state `placement`, one key `placement.` read at each catalogue merge from + the node's placement file and said by `placement-changed` (ADR 0549 §2); + - **the node records**, the node-engine's state `records`, one key `record.` written by that node's own + agent and said by `node-record-changed` (ADR 0555 §3); + - **the manifests**, the indexer's `modules.` 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 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 + 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, and whether it is + adopted with the modules taken on it. No secret and no key material; + - its modules in the order the composition reads them, each with its host ports by the port the software + listens on, its bindings by provision, and its settings 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; + - 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 + once for the mesh held twice, two nodes with one address and more than one hub, each named in one answer. +- **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, its node-engine's contract, the tunnel found on it, and on the hub alone whether the hub adopted + that tunnel and every peer it carries. Written at start and when an observed fact changes, only when it + differs (ADR 0555 §3). - **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). -- 2.54.0 From b5b84fafc631f61fc55543f4a1acae3348b5330a Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 26 Oct 2026 18:21:31 +0100 Subject: [PATCH 02/10] Design 47: config placement, as ADR 0348 words it (issue 1126) --- 03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md b/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md index 71de04bb..c3422466 100644 --- a/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md +++ b/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md @@ -690,7 +690,7 @@ backup holder backs up nothing, and the have says so. routed names are composed under, its operator and agent logins by name with their homes, and whether it is adopted with the modules taken on it. No secret and no key material; - its modules in the order the composition reads them, each with its host ports by the port the software - listens on, its bindings by provision, and its settings placement (`places`, `accesses`, `networks`, + 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; -- 2.54.0 From 68f8a8c1988438ee1b7091635da630ae093f5dae Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 26 Oct 2026 18:26:53 +0100 Subject: [PATCH 03/10] Design 47: the found tunnel is decided at adoption; adoption and enrolled peers are read, not written (issue 1126, ADR 0555) --- .../01-to-be/47-delivery-from-commit-to-delivered.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md b/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md index c3422466..c353f80f 100644 --- a/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md +++ b/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md @@ -687,8 +687,9 @@ backup holder backs up nothing, and the have says so. 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 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, and whether it is - adopted with the modules taken on it. No secret and no key material; + routed names are composed under, its operator and agent logins by name with their homes, whether it is + adopted with the modules taken on it, the tunnel found on it at adoption (no longer there to observe once taken + over), and on the hub the names given to that tunnel's peers. No secret, and keys only as public halves; - its modules in the order the composition reads them, each with its host ports by the port the software 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 @@ -700,9 +701,9 @@ backup holder backs up nothing, and the have says so. once for the mesh held twice, two nodes with one address and more than one hub, each named in one answer. - **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, its node-engine's contract, the tunnel found on it, and on the hub alone whether the hub adopted - that tunnel and every peer it carries. Written at start and when an observed fact changes, only when it - differs (ADR 0555 §3). + and networks, and its node-engine's contract. Written at start and when an observed fact changes, only when it + differs (ADR 0555 §3). Whether the hub took its found tunnel over, and which node enrolled under a carried + peer's key, are read from the placement and the records together, never written. - **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). -- 2.54.0 From d94877479424272ddb21357a65996553fe4c7a48 Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 26 Oct 2026 18:30:28 +0100 Subject: [PATCH 04/10] =?UTF-8?q?Design=2047:=20the=20node=20record=20ride?= =?UTF-8?q?s=20in=20the=20node's=20own=20have=20key=20(issue=201126,=20ADR?= =?UTF-8?q?=200555=20=C2=A73)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md b/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md index c353f80f..a457de1d 100644 --- a/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md +++ b/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md @@ -678,8 +678,8 @@ backup holder backs up nothing, and the have says so. input from the bus with its own credential and nothing else (ADR 0547 §2, ADR 0549 §3): - **placement**, the indexer's state `placement`, one key `placement.` read at each catalogue merge from the node's placement file and said by `placement-changed` (ADR 0549 §2); - - **the node records**, the node-engine's state `records`, one key `record.` written by that node's own - agent and said by `node-record-changed` (ADR 0555 §3); + - **the node records**, each in its node's own have key `.node`, written by that node alone and heard as + the key's change (ADR 0555 §3); - **the manifests**, the indexer's `modules.` 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. -- 2.54.0 From 5bb109e36ea74c7f5bda213650652c7841ca00a1 Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 26 Oct 2026 18:33:46 +0100 Subject: [PATCH 05/10] Design 47: the node-record read is the composer copy's one intended grant beyond the controller's, and what a hand-back means for it (issue 1126, ADR 0555) --- 03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md b/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md index a457de1d..ab3b7847 100644 --- a/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md +++ b/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md @@ -703,7 +703,12 @@ backup holder backs up nothing, and the have says so. 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 differs (ADR 0555 §3). Whether the hub took its found tunnel over, and which node enrolled under a carried - peer's key, are read from the placement and the records together, never written. + peer's key, are read from the placement and the records together, never written. Every node's account reads + every node's `.node`: a grant the grants part's composer gives and the controller's frozen copy does not. + Since the take-over the grants part's list is the one the bus loads; after a `hand-back` the controller's list + holds, without that read, and nodes keep applying while composing their own fails loudly until the next + `take-over`. mesh-sdk's composer test holds the copy to every grant of the controller's golden plus exactly that + read and the bucket-creation advisories of issue 1790. - **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). -- 2.54.0 From b6572acd72e5ca80c9e96eaef54c0b128fae05b5 Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 26 Oct 2026 18:49:09 +0100 Subject: [PATCH 06/10] Design 47: every read a node's account gains to compose, and that a module with an own secret does not move until the vault seals it to the node (issue 1126, ADR 0555) --- .../47-delivery-from-commit-to-delivered.md | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md b/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md index ab3b7847..049451ba 100644 --- a/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md +++ b/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md @@ -703,12 +703,23 @@ backup holder backs up nothing, and the have says so. 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 differs (ADR 0555 §3). Whether the hub took its found tunnel over, and which node enrolled under a carried - peer's key, are read from the placement and the records together, never written. Every node's account reads - every node's `.node`: a grant the grants part's composer gives and the controller's frozen copy does not. + peer's key, are read from the placement and the records together, never written. +- **What a node's account reads to compose.** The grants part's composer gives every node's account these reads, + each read only, and the controller's frozen copy none of them (ADR 0555): + - every node's `.node` of the node-engine's have bucket: the other nodes' records; + - every key of the indexer's `placement`: where modules run and what a person decided of each node; + - every key of the indexer's `modules` and `manifests`: the manifests it composes from; + - every key of the builder's `builds`: the manifest of a build its want names when that is not the trunk's; + - mesh-config's `resolved` values of its own node alone, `.>`. Since the take-over the grants part's list is the one the bus loads; after a `hand-back` the controller's list - holds, without that read, and nodes keep applying while composing their own fails loudly until the next - `take-over`. mesh-sdk's composer test holds the copy to every grant of the controller's golden plus exactly that - read and the bucket-creation advisories of issue 1790. + holds, without these reads, and nodes keep applying while composing their own fails loudly until the next + `take-over`. mesh-sdk's composer test holds the copy, user for user, to every grant of the controller's golden + 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.` 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. Until its own secrets and issued credentials come sealed + from the vault (ADR 0550 §5), a module with an own secret is left out of the node's own composition: it keeps + running what it runs and does not move. - **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). -- 2.54.0 From a6cc3d2e0b684017fd791144f05a2a1451470b64 Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 26 Oct 2026 18:59:06 +0100 Subject: [PATCH 07/10] Design 47: a node never applies a stand-in, and composes nothing of its own until the vault seals its secrets to it (issue 1126) --- .../01-to-be/47-delivery-from-commit-to-delivered.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md b/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md index 049451ba..53052594 100644 --- a/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md +++ b/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md @@ -717,9 +717,11 @@ 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.` 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. Until its own secrets and issued credentials come sealed - from the vault (ADR 0550 §5), a module with an own secret is left out of the node's own composition: it keeps - running what it runs and does not move. + on a node before the seeded placement file reaches it. 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. - **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). -- 2.54.0 From df4ff3d039f25b0262b16fd1ba3b58a821f731dd Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 26 Oct 2026 19:09:16 +0100 Subject: [PATCH 08/10] Design 47: a model-access consumer placed before the vault serves licences is refused by the guard (issue 1126) --- 03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md b/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md index 53052594..7e474066 100644 --- a/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md +++ b/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md @@ -721,7 +721,9 @@ backup holder backs up nothing, and the have says so. 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. + with any module holding one composes nothing of its own. 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. - **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). -- 2.54.0 From 495d740d5ffc8428a83b030c5f4acb8d694f051f Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 26 Oct 2026 19:17:48 +0100 Subject: [PATCH 09/10] =?UTF-8?q?Design=2047:=20a=20placed=20node's=20want?= =?UTF-8?q?=20says=20self=20and=20names=20no=20composition;=20a=20yes=20na?= =?UTF-8?q?mes=20the=20composition=20allowed=20(issue=201126,=20ADR=200547?= =?UTF-8?q?=20=C2=A72,=20=C2=A73)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md b/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md index 7e474066..54c1db81 100644 --- a/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md +++ b/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md @@ -749,7 +749,10 @@ backup holder backs up nothing, and the have says so. and nothing is asserted (ADR 0547 §5). - **The want names the build.** A want `want..` names the fingerprint, the artifact's digest, the source revision and whether the module holds data; the node's own want `want..node` names the node - (ADR 0547 §2). + (ADR 0547 §2). A want to a node the catalogue places says so: it carries `self` and names no composition, + since the node composes it; every other want still names the one composition it allows, so nothing written + before (the controller's bus upgrade among it) reads a want differently. A person's yes to a move the node + judged is written into the want as `yes`, the digest of the composition allowed (ADR 0547 §3). - **The apply, one module at a time.** At its first start the node agent takes the declaration it kept last as what each module runs and writes each have. Then it applies a module only when its want's fingerprint differs from what runs or the composition it composed differs from the one it runs, and only that module, -- 2.54.0 From 7c88f297fc59ef32a2533280f0886753f0ff3b26 Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 26 Oct 2026 19:45:32 +0100 Subject: [PATCH 10/10] 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) --- .../47-delivery-from-commit-to-delivered.md | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md b/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md index 54c1db81..23c68bbb 100644 --- a/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md +++ b/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md @@ -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.` 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.` 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). -- 2.54.0