From 39c802cbd408ebdfb1d67ca99fc69405b2af14d0 Mon Sep 17 00:00:00 2001 From: jochen Date: Sat, 26 Sep 2026 21:40:02 +0200 Subject: [PATCH] Step 2: adoption recreates the bus once, on purpose MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2.3 was already true and is now proved — the seat refusal is generic, and three tests pin what matters: a second bus is refused by name, a different bus implementation is refused too (which is what makes the bus replaceable), and the AMQP broker no longer contends so both run on one mesh. 2.1/2.2 turned out not to be a no-op. The host keeps a container only when its spec matches exactly; genesis raises the upstream image and the module declares the mesh-built one carrying the entrypoint, so assigning it recreates the container. That is ADR 0067's pivot and it is safe only because the bus carries nothing yet — which is why step 2 comes before anything speaks NATS. After it, never again: the config is a directory mount, so accounts change without touching the container's spec. --- 03-DESIGN/01-to-be/28-building-the-bus.md | 34 +++++++++++++++++++---- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/03-DESIGN/01-to-be/28-building-the-bus.md b/03-DESIGN/01-to-be/28-building-the-bus.md index 5d68c57..0310675 100644 --- a/03-DESIGN/01-to-be/28-building-the-bus.md +++ b/03-DESIGN/01-to-be/28-building-the-bus.md @@ -180,11 +180,35 @@ and it is what makes steps 3 and 4 safe to develop against a live mesh. A runnin a foundation module by being raised again; it adopts one in place ([ADR 0100](../../02-DECISIONS/0100-a-node-in-use-is-adopted-before-it-is-converged.md)). -- [ ] 2.1 the server raised beside the existing broker on its own ports, carrying nothing -- [ ] 2.2 the `nats` module adopted onto it in place, holding the data and configuration it was - raised with -- [ ] 2.3 the seat claim, and the resolver's refusal of a second holder mesh-wide -- [ ] 2.4 the adoption bed +- [ ] 2.1 the server raised beside the existing broker on its own ports, carrying nothing — + installer-side, from the upstream image +- [ ] 2.2 the `nats` module assigned, which **recreates the container once, deliberately** (see + below), keeping its JetStream directory +- [x] 2.3 the seat claim, and the resolver's refusal of a second holder mesh-wide — **already + true and now proved**: the refusal is generic to any mesh-scoped seat, and three tests pin + what matters for this one — a second bus anywhere is refused naming the seat, a *different* + bus implementation is refused for the same reason (which is what lets the bus be replaced + at all), and the AMQP broker no longer contends for it, so both run on one mesh +- [ ] 2.4 the adoption bed — deferred with the other beds + +> **Adoption here is not a no-op, and pretending it would be is the trap.** The host keeps an +> existing container only when its spec matches the declaration exactly +> ([`apply.go`](https://git.novox.be/novox/mesh-host): *existed && before.Spec == want && running* +> → unchanged; anything else is `rm -f` and recreate). Genesis raises the server from the +> **upstream** image, because nothing has been built yet; the module declares the **mesh-built** +> artifact, which carries the entrypoint that reloads configuration in place. Those two specs +> differ, so assigning the module recreates the container. +> +> That is correct, and it is [ADR 0067](../../02-DECISIONS/0067-genesis-is-a-pivot.md)'s pivot +> exactly: raise a temporary thing, then reinstall it as an ordinary module. It is safe **only +> because it happens while the bus carries nothing** — which is what 2.1 means by "carrying +> nothing", and why step 2 comes before anything speaks NATS rather than after. One recreate, at +> the one moment it costs nothing. +> +> **After that, never again.** The configuration is a directory mount rather than a file, so +> rewriting accounts does not change the container's spec and the entrypoint reloads the server in +> place. That is the whole point of task 1.2, and this is the moment it pays: every later account, +> permission or person's access change touches a running bus with connections on it. **Done when.** A mesh already running has the server adopted, holding `mesh-broker`; a second assignment anywhere is refused at resolution — *one per mesh*; and every node is still on the old