Files
mesh-lab/scenarios/fresh-mesh.yml
T
jschoubben 5d6e8fbe7a Rename mesh-control -> mesh-controller, substrate -> foundation
One name per thing, per the HQ glossary: the module/container/image/binary/repo
becomes mesh-controller, the seat the-controller, and the store+broker pair the
foundation (embedded base bundles, default template and example lock renamed with
their go:embed directives). No behaviour change — a pure vocabulary rename.

Claude-Session: https://claude.ai/code/session_01D6qtiYU3P9jk3pnAXyAFyx
2026-09-16 18:40:40 +02:00

107 lines
4.6 KiB
YAML

# FOUR FRESH MACHINES AND THE INSTALLER. Nothing is handed to them.
#
# This is `whole-mesh-full`'s topology with `genesis-single`'s honesty. The four-machine bed loads
# thirty-four of the mesh's own images onto its machines from the workstation, because it does not
# build them — they are produced by hand beside the bed and copied in. That is a shape no real
# installation has, and it is the same class of fiction the lab already removed once: it used to
# raise a registry inside the scenario, and a bootstrap that only worked against it went green here
# and would have failed on any real machine.
#
# So this bed hands over NOTHING. There is no `images:` list. Every machine gets a container
# runtime and the host binary, which are prerequisites of the machine rather than parts of the
# mesh, and after that the mesh is on its own:
#
# - the foundation, the registry and the builder's own dependencies are PULLED from the internet,
# which is where a bare machine gets them;
# - the control plane is BUILT, by the builder the installer carries, from a repository and a
# commit it is told to use;
# - every module after that is BUILT by the mesh's own builder and published into the mesh's own
# registry, and a machine that runs one PULLS it from there.
#
# That last clause is the thing no bed has ever checked, and it is why this one has four machines
# rather than one. Genesis puts the builder, the registry and everything they make on ONE machine.
# A second machine running a mesh-built module has to fetch it from a registry that asks who it is,
# and nothing yet gives a joined node an account for it. The bed asks anyway, in its own test, so
# the gap is a named failure rather than an absence.
#
# hosting (public, routable) home (private, behind the access point)
# anchor 192.0.2.20 ── anchor home-server 10.99.1.10 home server
# foundation, registry, workstation 10.99.1.20 workstation
# builder, control plane laptop 10.99.1.30 workstation
#
# EGRESS IS NOT OPTIONAL HERE. With nothing loaded, a sealed machine stops at the installer's first
# pull. Every machine has a way out, and it is a SECOND path: each still reaches the rest of the
# scenario through its declared gateway, and the uplink carries only what leaves the scenario —
# the public images, and the forge the control plane is cloned from.
#
# MESH_LAB_HOST_BINARY=.../mesh-host MESH_LAB_BOOTSTRAP_BINARY=.../mesh-bootstrap
# MESH_LAB_BUNDLE=.../examples/foundation-first-node.lock
# MESH_LAB_CATALOG=.../mesh-catalog/modules
# MESH_LAB_SOURCE=<forge url> MESH_LAB_SOURCE_REF=<commit>
scenario: fresh-mesh
segments:
# The routable segment. anchor lives here; its public address is the broker endpoint every token
# carries and the overlay hub the home nodes dial.
hosting:
kind: public
cidr: [192.0.2.0/24]
# The household segment behind an ordinary home router: masquerades v4 outbound, forwards
# inbound, expires idle mappings after two minutes.
home:
kind: private
cidr: [10.99.1.0/24]
gateway:
to: hosting
address: [192.0.2.50]
nat: [v4]
forwardable: true
mapping_ttl: 120s
machines:
# The anchor. Raised by the installer into a mesh of one, and then asked to build.
#
# Sized for what it actually does here: the store, the broker, the registry, TWO control planes
# during the pivot, the builder, and a build worksphome-server holding a Node toolchain image and an npm
# cache. It is NOT sized for the whole anchor service set, because this bed does not run one — it
# proves the machinery that would produce it.
anchor:
at: { segment: hosting, address: [192.0.2.20] }
egress: true
inbound: allow
memory: 12GiB
cpus: 6
disk: 60GiB
# Three machines that JOIN. Host binary and a token, nothing else — no bootstrap, no foundation,
# no registry. They are deliberately small: what they are here to prove is that a joined machine
# can be given a module the mesh built, which is a question about credentials and not about load.
home-server:
at: { segment: home, address: [10.99.1.10] }
egress: true
inbound: allow
memory: 4GiB
cpus: 2
disk: 25GiB
workstation:
at: { segment: home, address: [10.99.1.20] }
egress: true
inbound: allow
memory: 3GiB
cpus: 2
disk: 20GiB
laptop:
at: { segment: home, address: [10.99.1.30] }
egress: true
inbound: allow
memory: 3GiB
cpus: 2
disk: 20GiB
# **No `images:` key, and that is the whole point of this file.** Anything a machine holds here, it
# pulled or the mesh built. See the header.
plhome-server:
all: [host, runtime]