Merge pull request 'Issues 119 and 122: what a host path is, and what a node's layout would replace' (#130) from issue/119-122-what-a-host-path-is into main

This commit was merged in pull request #130.
This commit is contained in:
2026-09-26 15:21:34 +00:00
2 changed files with 56 additions and 2 deletions
@@ -32,6 +32,57 @@ mount a path its module never declared ([ADR 0091](../../02-DECISIONS/0091-a-mou
Nothing checks the same path where it is retyped as a value: an environment variable, an env-file
line, a literal in module code.
## 2026-09-26 — counted by what the path *is*, and what a node's layout would replace
The count above treats every host path the same. They are not the same, and only one of the
categories is this issue's subject. Recounted by role across the 71 definitions:
| What the path is | Count | Does a definition naming it name *this* machine? |
|---|---|---|
| A module's own data, `/var/lib/<module>/…` | 289 | **Yes** — this issue |
| What the mesh writes for a module, `/var/lib/mesh/<module>/…` | 225 | **Yes** — this issue |
| The operator's shared data, `/services/…` | 166 | Separately answered: an `access`, never created or owned by the mesh ([ADR 0051](../../02-DECISIONS/0051-shared-data-is-the-operators.md)); *where* it is belongs on the assignment |
| A system file the mesh owns, `/etc/…` and a few under `/var/` | 18 | **No.** The path is the fact — that file is at that path on every machine of the kind. Naming it says nothing about this installation |
| A path inside a container | 236 | **No.** The software's own contract, true in any mesh that runs the image |
So the category a node's default layout would replace is **514**, not 789 and not 698: a module's own
data, and what the mesh writes for that module. The rest is either already answered or was never the
problem.
## What the design already says, and what it does not
[ADR 0112](../../02-DECISIONS/0112-a-module-definition-names-no-node-mesh-or-path.md) (proposed)
makes a directory a host provision whose contract is the owner and mode the module needs, and says
where it lands on the machine is the assignment's.
[To-be 27](../../03-DESIGN/01-to-be/27-a-module-requires-the-mesh-resolves.md) (proposed) resolves
that two ways: **a node's default layout — a root per node with one directory per assignment beneath
it** — used when the assignment says nothing, and **a placement** when the assignment puts one
directory elsewhere, such as where an adopted machine's data already is.
That is the reservation model: assigning a module to a node gives it a directory, and the definition
never names one. Three things are not written anywhere:
1. **Where the root comes from.** Nothing says it is a node setting, fixed when the node is installed,
and nothing says what a node that states none falls back to.
2. **What sits beneath it.** To-be 27's own open list ends at exactly this: the layout beneath the
root, beyond one directory per assignment. The catalogue currently keeps two subtrees per module —
its data, and what the mesh writes for it — so this decides whether an assignment's directory holds
both, or the mesh keeps its own.
3. **The order the existing 514 are retired in**, which 0112 also leaves open.
## Why this is not a manifest edit
Every one of those 514 paths names a directory that holds data a service is using. A definition that
changes where it looks, without the data moving with it, does not fail: the mesh creates the new
directory with the right owner and mode, the container starts, and the service comes up **empty**.
The loudest case in this mesh is an object store consumer whose bucket holds 174.9 GiB; a mail spool
and the mesh's own store are the same shape.
So the retirement of these paths is a **data migration with a verification step**, module by module,
not a change to a definition. That is the reason this section documents and stops: the count and the
categories are what someone needs to plan it, and the planning belongs with whoever can see the
machine.
### Where that has already gone wrong
- **A provider that would provision nobody, silently.** One DNS provider mounts its grants
@@ -38,7 +38,7 @@ definitions, for values that could only be true of one installation:
| A public domain, or a name under one | 49 | 26 |
| The node's own name | 58 | 19 |
| A routable IP address | 12 | 1 |
| A **host** path — where a file sits on the machine | 698 | 70 |
| A host path for a module's own files — the node's to decide | 514 | 70 |
| An email address | 0 | 0 |
The path row is [issue 119](../119-a-module-definition-decides-where-its-files-live/00-report.md),
@@ -48,7 +48,10 @@ data in are the software's own contract, true in any mesh that runs it; only the
names where it landed. The first sweep matched path-shaped strings and so counted both halves of every
mount and every in-container location a value mentioned. Counted by role instead — directory and file
resources, the host side of mounts, accesses, and the targets of binds, grants, receives and secrets —
it is 698 across 70 definitions. Issue 119's own figure is role-counted already and close to this; it
it is 698 across 70 definitions — of which **514** are the category at issue. The rest are a system
file the mesh owns (`/etc/…`, where the path is the fact and is the same on every machine) and the
operator's shared data, which ADR 0051 already answers as an access. Issue 119 carries that breakdown
and what a node's default layout would replace. Issue 119's own figure is role-counted already and close to this; it
additionally counts paths written into environment values, a few of which are container-side.
The rest of the table is this issue. **Thirty of the seventy-one definitions name this