Files
mesh-lab/scenarios/one-node-mesh.yml
T
jschoubben 7641bb2059 A one-node mesh, and twelve things that have to be true of it
The common case, and the one that was never tested as a whole. What existed
asked whether four machines converged; it never asked whether ONE machine ends
up holding a mesh.

The order was wrong too. Three machines were enrolled second, into a mesh that
could not yet produce a single module, and that was reported as though something
had been shown. 17-raising-a-mesh is explicit: genesis ends with a mesh that
RUNS, and what remains after the core modules are built is "adding machines".
So the core comes first and machines arrive last — here, not at all, because a
second node is only meaningful once the first is complete.

Three things were missing entirely and nothing complained, because nothing asked:
the mesh never built its own catalogue, never had a store of its own for that
catalogue to use, and never rebuilt its own control plane through the module
path.

And four checks that were absent rather than failing:

  - it can describe itself — status, module list, plan --json, and the
    catalogue's five tools ASKED rather than observed. A container being up was
    being read as the catalogue working, which is the same error as matching a
    container by substring and finding the wrong one.
  - its networking is what the modules asked for — default closed, ssh open,
    declared ports open, .internal names written, module networks present. Left
    out altogether, which is hard to defend given the firewall work this week.
  - a change to a module's source reaches the machine on its own. The capability
    the migration depends on.
  - it comes back after a reboot. Never once tested; the lab had no way to
    restart a machine, because nothing had ever needed one.

Machines are named by role now — anchor, home-server, workstation, laptop — not
after the operator's own nodes, which made test output and real state hard to
tell apart.

Claude-Session: https://claude.ai/code/session_01D6qtiYU3P9jk3pnAXyAFyx
2026-09-14 21:52:24 +02:00

57 lines
2.7 KiB
YAML

# ONE MACHINE, AND EVERYTHING A MESH HAS TO BE. Nothing is handed to it.
#
# The common case, and the one worth getting right first: a person with a single machine runs the
# installer and ends up with a mesh that works. Not a mesh that *runs* — `17-raising-a-mesh` is
# careful about that difference, and so is this scenario. Genesis ends with a substrate, a registry,
# a built control plane and a builder, and a mesh in that state cannot produce anything and holds no
# record of what it has. Calling that "up" is how the catalogue came to be missing from a test for
# weeks without anything complaining.
#
# So the test driving this asks the harder question: can this machine, given nothing but a container
# runtime and the host binary, end up holding
#
# - a substrate and a registry it pulled from the internet,
# - a control plane it BUILT, and then rebuilt from its own repository through the module path,
# - a builder that takes work over the broker,
# - the shared base every module with code of its own stands on,
# - a store of its own — the substrate's is the control plane's own plumbing, not a provider,
# - a catalogue, so it can say what it has and what a change reaches,
# - and a module of its own, built, provisioned and running.
#
# **There is no `images:` key, and that is the whole point of this file.** The four-machine scenario
# next door loads thirty-four of the mesh's own images from the workstation because it does not
# build them — a shape no real installation has. Here nothing is loaded. What the machine holds it
# either pulled from the internet or made.
#
# EGRESS IS NOT OPTIONAL. With nothing loaded, a sealed machine stops at the installer's first pull.
#
# MESH_LAB_HOST_BINARY=.../mesh-host MESH_LAB_BOOTSTRAP_BINARY=.../mesh-bootstrap
# MESH_LAB_BUNDLE=.../examples/substrate-first-node.lock
# MESH_LAB_CATALOG=.../mesh-catalog/modules
# MESH_LAB_SOURCE=<forge url> MESH_LAB_SOURCE_REF=<commit>
scenario: one-node-mesh
segments:
hosting:
kind: public
cidr: [192.0.2.0/24]
machines:
# The address matters: the substrate template names the broker at a fixed address, and a token
# carries that verbatim as the endpoint an enrolling node dials. With one machine, that machine
# must BE it, or the mesh hands out an endpoint nothing answers on.
#
# Sized for what it actually does: the store, the broker, the registry, two control planes during
# the pivot, the builder, a Node toolchain and an npm cache in the build workspace, and then every
# core module it builds and runs on top of that.
anchor:
at: { segment: hosting, address: [192.0.2.10] }
egress: true
inbound: allow
memory: 12GiB
cpus: 6
disk: 60GiB
place:
all: [host, runtime]