From 0871e6ec11d45de3d83fb9a43c49c924063592a7 Mon Sep 17 00:00:00 2001 From: jochen Date: Tue, 1 Sep 2026 14:24:53 +0200 Subject: [PATCH] =?UTF-8?q?37=20=E2=80=94=20where=20a=20module=20lives,=20?= =?UTF-8?q?proposed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The module descriptions sit in `examples/` inside the control plane, and that name has been doing harm: everything there reads as a sketch, and one shipped naming a container image nothing builds. A directory called the catalogue would have made "does this work" the obvious question. The shape of the answer turns on one measurement. Of the 126 modules in the system being replaced, 47 are software in their own right — the largest is 182 source files, and a speech-capture module carries a whole daemon. Another 44 ship helper scripts. Only 35 are a description and nothing else. So a catalogue cannot be a folder of manifests, because two thirds of modules are programs. That splits them four ways, and only two of the four belong in a catalogue: things the world made that we describe, and packages with some files. What the mesh is made of stays in the repositories that build it. What we wrote keeps its description beside its code, in the same commit, because nothing else can stop the two drifting. The mesh's list of modules is a table, not a repository, and it already records where each module came from and at which commit. Nothing needs inventing for modules from anywhere; a repository of ours is just the source we curate. The check that a description is valid should move to a command on the control plane's binary. Today a test reaches into the control plane's internals to parse manifests, and another reads its build file to check images exist — two jobs tangled. A command would also give the same check to somebody describing their own application, which is the case that matters most and has none. Left open: how a provisioner's image gets published and pinned, and whether thirty-five install-a-package modules deserve to be modules at all. --- 02-DECISIONS/0037-where-a-module-lives.md | 103 ++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 02-DECISIONS/0037-where-a-module-lives.md diff --git a/02-DECISIONS/0037-where-a-module-lives.md b/02-DECISIONS/0037-where-a-module-lives.md new file mode 100644 index 0000000..a697d12 --- /dev/null +++ b/02-DECISIONS/0037-where-a-module-lives.md @@ -0,0 +1,103 @@ +--- +topic: building it +status: proposed +date: 2026-09-01 +deciders: jochen +reconstructed: false +rests-on: 02-DECISIONS/0009-modules-and-the-graph.md +--- + +# 37. Where a module lives + +## The question + +The mesh's own module descriptions currently sit in `examples/` inside the control plane, beside +the small programs that hand out logins. That was fine while there were three of them. It is +wrong now, and the name is doing active harm: everything in `examples/` reads as a sketch, and one +of them shipped naming a container image that nothing in the repository builds. A directory called +*the catalogue* would have made *does this actually work* the obvious question to ask of it. + +So: **one repository holding the modules we ship?** And if so, where does everything that is not +ours go? + +## What a module actually is, counted + +The system being replaced has **126 modules** on its main branch. The shape of them is the whole +argument, so it is measured rather than assumed: + +| | count | what it is | +|---|---|---| +| **the module is software** | 47 | its own source tree lives inside the module — a daemon, a service, a library | +| **helper scripts only** | 44 | no application of its own; scripts it runs at install time or offers to an agent | +| **a description and nothing else** | 35 | a package to install and some files to write | + +**Two thirds of modules contain code.** The largest is a shared library of 182 source files. A +speech-capture module carries a complete daemon — audio capture, mixing, transcription, a model +runner. Treating a module as *a description of something else* is true of barely a quarter of them. + +That kills the simplest answer. A catalogue cannot be "a folder of manifests" when most modules +are programs. + +## The four kinds, which want different homes + +**1. What the mesh is made of.** The control plane, the host, the shared library, the board. +These are not modules that happen to be ours; they are the mesh, expressed as modules so it can +install itself. They belong in the repositories that build them, which already exist. + +**2. Something the world made, that we describe.** A forge, a mail system, an identity provider, +a media server. Nobody upstream ships a description; somebody has to write one, and it is the same +description for everybody who runs it. **This is what a catalogue is for.** It is also where the +small programs that create accounts belong, because such a program is part of describing that +service, not part of the mesh. + +**3. Something we wrote, that runs somewhere.** An application, a site, a side project. The +description belongs **with the code, at the root of its own repository**, because the two change in +the same commit. A repository that gains an environment variable and a description that gains it +elsewhere will drift, and there is no mechanism that could stop it. This is already how it works +and it should stay that way. + +**4. A package and some files.** A tool, a font, a shell. Thirty-five of these, and each is a few +lines. The catalogue. + +## The proposal + +**A `mesh-catalog` repository** holding kinds 2 and 4: descriptions of software we did not write, +and the programs that provision it. Not kind 1, which is the mesh itself. Not kind 3, which lives +with its own code. + +**The mesh's list of modules is not this repository.** It is a table in the control plane, filled +by adding a description to a running mesh. The catalogue is a *source* to add from — one of +several, and the mesh already records which: every module carries where it came from, the branch +followed there, and the commit its description was read at. **Nothing needs inventing to support +modules from anywhere**; a repository of our own is simply the source we curate. + +**A description is checked by the tool, not by a test that imports the tool.** Today a test in the +control plane parses the example manifests by reaching into the control plane's internals, and +another reads the control plane's own build file to check every image a module names can be built. +Two jobs tangled. A `module check` command on the control plane's binary would let the catalogue +hold data validated from outside, and would give the same check to somebody describing their own +application in their own repository — which is the case that matters most and currently has no +check at all. + +## What this costs, and the argument against + +**It is early.** Ten modules exist, four of them ours. Moving ten files is a morning; moving a +hundred is a week — but the hundred is not here yet, and splitting now adds a second repository to +release across before there is anything to release. + +The counter is that the tangle is already producing faults rather than merely threatening to. A +manifest naming an unbuildable image, and a test reading a build file two directories up, are both +symptoms of one repository doing two jobs. And the moment the first module is adopted on a real +machine, the descriptions stop being examples and become the thing deployments come from. **That +is the moment this becomes urgent, and it is close.** + +## What it does not settle + +**Where a provisioning program's image is published**, and how a description pins it. A description +names an image by digest; the image is built from the catalogue; the catalogue must therefore both +produce an image and refer to it, which is the same knot the bootstrap has and solves by writing +the digest down after building. + +**Whether kind 4 deserves a module at all.** Thirty-five descriptions that say *install this and +write these files* may be better as one module with settings than as thirty-five modules. Left +open deliberately; it is a question about the shape of the catalogue, not about whether to have one.