--- topic: the mesh status: accepted date: 2026-09-26 deciders: jochen reconstructed: false extends: 02-DECISIONS/0131-everything-on-the-mesh-speaks-to-the-broker-seat.md --- # 128. The mesh bus is required, not ambient > **Pointer repointed, 2026-09-27.** This record was written extending > [ADR 0127](0127-amqp-is-a-provision-not-the-bus.md) (superseded by [ADR 0131](0131-everything-on-the-mesh-speaks-to-the-broker-seat.md)), which > [ADR 0131](0131-everything-on-the-mesh-speaks-to-the-broker-seat.md) has since superseded — AMQP is > not a provision at all. Nothing decided here changes; the frontmatter now rests on the live record, > and the citations below are read with that in mind. ## Context [Design 29](../03-DESIGN/01-to-be/32-what-a-module-declares.md) opened by saying the bus is *ambient*: "No module requires it, the way no module requires a filesystem. Every module gets a connection and an identity whether it asks or not." **Two counts say that is wrong.** Of the 72 modules in the catalogue, **49 declare an own-secret named `broker` and 23 do not.** So the bus is not universal — nearly a third of the catalogue never speaks to it — and an ambient connection would mint an account, a password and a permission set for every one of those 23, each a credential nothing uses and everything must rotate. And the 49 that do take one **each hand-write the path it lands at** (`own-secrets: { broker: "/var/lib//broker" }`). That is a special case doing badly what provisioning already does well: a consumer names where a credential lands, the mesh seals it there, and rotation and removal follow the same path as every other credential. **The argument that made the bus ambient was narrower than it looked.** [ADR 0125](0125-the-bus-is-the-only-broker.md) reasoned that bus accounts cannot be provisioned because a provisioner is itself a module that needs an account before it can run. That is true of a **provisioner process**, and it is not true of a provision: the mesh's bus accounts are composed by the *controller*, into configuration, and the controller is not waiting on a bus account to exist. The circularity is real for one mechanism and absent for the other, and the earlier record applied it to both. ## Considered Options 1. **Keep the bus ambient.** Rejected on the counts above: it over-grants to 23 modules and keeps a hand-written path in 49. 2. **Derive the requirement** from whether a module declares any `emits`, `consumes`, `serves` or `uses`. Rejected: it is the ambient model with extra inference. A reader of a manifest still cannot see that the module holds a bus credential, and the rule would have to be re-derived every time the set of bus-facing declarations grew. 3. **The mesh bus is a provision a module requires**, delivered by the seat that holds it. Adopted. ## Decision **A module that speaks to the mesh requires `mesh-bus`, and receives what it needs to connect.** The contract is an address, a credential sealed to the module, and the trust to verify the server. It lands where the module's manifest says, like any provision. A module that does not require it gets no account, no password and no permissions — and 23 modules in the catalogue should get none. **The `mesh-broker` seat delivers `mesh-bus`.** Its holder is the mesh's own bus, and what holding it delivers is the connection to that bus — which is what a seat delivering a provision has always meant ([design 26](../03-DESIGN/01-to-be/26-the-seats.md)). **The requirement delivers the connection; the declarations shape the authority.** They are two different things and both stay explicit. `requires: mesh-bus` says *this module talks to the mesh*; `emits`, `consumes`, `serves`, `uses` and a declared seat say *what it may say and hear*, and the permission set is derived from those and nothing else ([ADR 0043](0043-a-module-broker-account-is-scoped-by-emits-and-consumes.md)). Requiring the bus grants no subject; declaring a subject without requiring the bus is refused at registration as incoherent. **The `mesh-bus` provision is answered by the controller, not by a provisioner.** This is the surviving kernel of ADR 0125's bootstrap argument, narrowed to what it actually supports: the bus's accounts are configuration the controller composes and the server reloads ([ADR 0106](0106-the-bus-is-nats.md) — never through a management API), so there is no provisioner process in the path and nothing waiting on a bus account to create bus accounts. It is a provision whose provider is the mesh itself. **A module may also provide a NATS server of its own, and that is a different interface.** Exactly as the AMQP broker provides `amqp` ([ADR 0127](0127-amqp-is-a-provision-not-the-bus.md) (superseded by [ADR 0131](0131-everything-on-the-mesh-speaks-to-the-broker-seat.md))), a module may run its own NATS and offer it as a backing service. That interface is **`nats`**; the mesh's own bus is **`mesh-bus`**; the two are never the same name, because a manifest that said `nats` could mean either and the difference is the whole architecture. The rule from 0119 decides which is legitimate: a private bus is a backing service, never a channel to another module. ## Consequences - **Design 29's opening is reversed.** The bus is not ambient; it is required, and the document's first paragraph says the opposite of this. - **The seat's `Delivers` is `mesh-bus`** — corrected twice in one day, which is worth recording rather than tidying: it read `amqp`, which was the old broker's interface; ADR 0125 emptied it, on the reasoning that a bus cannot be provisioned; and it is neither. The seat delivers the mesh's bus. - **`own-secrets: { broker: ... }` is retired** in favour of the provision's own delivery, across 49 manifests. That is a mechanical change, and it belongs with the conversions in step 4 rather than step 1. - **23 modules lose a credential they never used.** Not a regression — an over-grant removed, and the smallest honest statement of what this buys. - **What got harder:** one more line in most manifests. The trade is that the line is true, and its absence is also true. ## How it is checked - **A module with no `requires: mesh-bus` has no account.** A composition test: the derived user list contains exactly the modules that require it, and the 23 that do not appear nowhere in it. - **Declaring a subject without requiring the bus is refused.** A registration test on a manifest with `emits` and no requirement, naming the contradiction. - **Requiring the bus grants no subject on its own.** A composition test: a module that requires `mesh-bus` and declares nothing else gets a connection and an empty permission set. - **`nats` and `mesh-bus` are distinct interfaces.** A resolution test: a module requiring `nats` is answered by a module providing it, never by the seat holder, and vice versa. ## References - [ADR 0125](0125-the-bus-is-the-only-broker.md) — superseded by 0119; its bootstrap argument is narrowed here to the case it supports. - [ADR 0127](0127-amqp-is-a-provision-not-the-bus.md) (superseded by [ADR 0131](0131-everything-on-the-mesh-speaks-to-the-broker-seat.md)) — a broker as a backing service; this applies the same shape to the mesh's own bus and separates the two names. - [ADR 0043](0043-a-module-broker-account-is-scoped-by-emits-and-consumes.md) — authority from declarations, which this leaves untouched. - [design 26](../03-DESIGN/01-to-be/26-the-seats.md) — a seat delivering a provision.