051: one lavinmq, not two — the duplication is running, not latent

The lavinmq module raises its own server container and provisions vhosts on it,
separate from the substrate's mesh-broker. A mesh with the module assigned runs
two LavinMQ servers where one belongs — the exact AMQP twin of the two postgres
containers.

The module's own provisioner already assumes one server: it creates a vhost per
consumer, named for the login, isolated by the vhost boundary — the analog of
postgres's database-per-login. So the mesh's own control traffic is the / vhost
and every consumer's broker is a vhost beside it, all on one server.

Adoption therefore means the module does not run a server of its own: its server
is the substrate broker, adopted, and the module contributes the provisioner,
tools, events and bootstrap against it. The isolation model is already built;
what remains to design is only raising the one broker at genesis and then holding
it as a module, over the broker it is.

Claude-Session: https://claude.ai/code/session_01D6qtiYU3P9jk3pnAXyAFyx
This commit is contained in:
2026-09-15 22:31:17 +02:00
parent a062f181ce
commit 03fc13b84b
@@ -62,6 +62,28 @@ legitimate provision and `lavinmq` is one provider of it.
So adoption is not only an upgrade path. It is two rows of a mesh's module list becoming one, So adoption is not only an upgrade path. It is two rows of a mesh's module list becoming one,
twice. twice.
## And it is one SERVER each, not two
**The broker duplication is running today, not just latent.** The lavinmq module raises its own
`server` container and points its provisioner at `http://lavinmq:15672` — a second LavinMQ,
separate from the substrate's `mesh-broker`. A mesh with the module assigned runs both.
This is not how LavinMQ is meant to be used, and the module's own provisioner says so: a consumer
is given a *vhost* named for its login, isolated from every other consumer's by the vhost boundary
— *"the exact analog of postgres's database-per-login"*. One server hosts the mesh's own control
traffic on the `/` vhost and every consumer's broker as a vhost beside it. Two servers is the same
mistake as two postgres containers, wearing AMQP.
So adoption means the lavinmq module does not run a `server` of its own. Its server IS the
substrate broker, adopted; the module contributes the provisioner, the tools, the event consumer
and the run-once bootstrap that configures it — all against the one broker. Same for postgres: one
server, the control plane's records in their databases and every module's database beside them.
**The provisioner already assumes this** — it creates a vhost, not a broker — so the change is
removing the second server, not building a new isolation model. What has to be designed is only the
adoption itself: raising the one broker at genesis because nothing else can, then holding it as the
module, over the broker it is.
## What makes this harder than it looks ## What makes this harder than it looks
**The recursion is real, not incidental.** The control plane learns what modules exist by reading **The recursion is real, not incidental.** The control plane learns what modules exist by reading