Files
mesh-host/examples
jschoubben 6a3435629e A foundation template that raises the mesh on the bus being built
The same twelve steps, with the difference that matters: the mesh composes its own user
list and at genesis there is none, so this carries the first one — the controller's
account at a bootstrap password, rotated with the store's and replaced by the
controller's own composition from its first start.

The server's settings and the user list are separate files in one directory. Separate
because the settings belong to whoever raises the server and the users belong to the
mesh; in one directory of necessity, because an include path resolves relative to the
including file's own directory, so an absolute one sends the server looking underneath
that directory and it refuses to start.

No `verify` in the TLS block. That makes the server demand a client certificate and
nothing in the mesh presents one — a host pins this server's exact certificate and
authenticates with a password.

The controller's permissions here are checked against what the controller derives, by a
test in its own repository reading this file. They are two statements of one fact, and a
template that granted less than the controller needs would produce a mesh that comes up
and is refused on its first act.
2026-09-27 16:39:32 +02:00
..

Examples

foundation-first-node.lock

What a machine must be before a mesh exists — the bootstrap in novox/hq 07-the-foundation.md, whole:

0  a container runtime
1  the store runs
2  a database per context        `inventory` and `identity`
3  those contexts' schemas       mesh-controller migrate
4  the broker runs               with a certificate it generated itself
5  the control plane runs        mesh-controller serve

A machine that applies this is a mesh — one node, with nothing joined to it yet, which is exactly what the first node is (novox/hq ADR 0004). From here it hands out tokens and everything else joins the ordinary way.

This file said it stopped at step 4 for longer than that was true, which is its own small lesson: a comment about what something does not do is a comment nobody updates.

Build a host carrying it:

make host SYSTEM=arch BUNDLE=examples/foundation-first-node.lock

The registry address and digests have to be replaced before this is useful. They are written as 192.0.2.250:5000/…@sha256:… because a digest belongs to whatever registry serves it — here, one a lab scenario raises, which reports its digests when it comes up. That is not a placeholder to be tidied away: a bundle is built for a target, and which registry that target pulls from is part of the target.

What was verified, and how

On a lab machine confirmed sealed — curl https://example.com times out, the lab registry answers 200 — the whole bundle applied from bare: eight resources, inventory created and mesh nowhere, the node table present with its indexes, the migration recorded, and LavinMQ answering lavinmqctl status with AMQP listening on 5672.

Three consecutive reconciles after that: already matches — 8 resource(s) checked, each time.

Then the machine was rebooted, and everything came back: docker from boot: enabled, both containers because the host creates every container --restart unless-stopped (internal/apply/apply.go), the schema intact in its named volume, and reconcile still finding nothing to do.

The reboot is worth doing rather than assuming. Nothing in the declaration asks for a container to return, so that it does is a property of the host, and the only way to know it holds is to take the machine away and give it back.