Files
hq/04-ISSUES/174-the-meshs-own-files-for-a-module-are-placed-by-the-definition/00-report.md
T
jschoubben 36454d7e4a Issues 173 and 174 resolved; the installation check refuses at registration (ADR 0155)
A setting overrides a key a contribution or served fact declares and adds none; a provider that must
tell its consumers an operator's value declares it as ${setting:…} (173). The mesh's own files for a
module are a placed directory, `place: "mesh"`, and forty-eight definitions name no host path for
them (174). Registration refuses a definition naming an installation, the day the list emptied
rather than a release later (0155, progressive insight; 134). Designs 27 and 18 carry the rules.
2026-09-30 22:36:20 +02:00

67 lines
4.1 KiB
Markdown

---
status: resolved
opened: 2026-09-30
located-in: [mesh-controller internal/catalogue/dir_into.go, mesh-controller internal/catalogue/declaration.go, mesh-catalog modules]
fixed-by: mesh-controller PR 175 (`place: "mesh"`, a directory beneath a placed one, the proof test resolving both sides); mesh-catalog PR 197 (48 definitions converted)
amended-design: [03-DESIGN/01-to-be/27-a-module-requires-the-mesh-resolves.md, 03-DESIGN/01-to-be/18-building-a-module.md]
---
# 174 — The mesh's own files for a module are placed by the definition, not by the mesh
## What was observed
After every module's *own* data directory was placed by the mesh
([issue 119](../119-a-module-definition-decides-where-its-files-live/00-report.md)), the catalogue
still carries **232 host paths in 50 definitions**, all of one kind: where the mesh writes what it
makes *for* the module — its sealed bus credential (`own-secrets.broker`), its merged config file, its
bindings — under `/var/lib/mesh/<module>/…`, and the directory resource that creates that subtree.
Not one of those files is the module's. The mesh mints the credential, composes the binding, merges
the config; the definition only says where to put them, and says it the same way seventy times.
## Why this is here
Design 27's answer to *what sits beneath a node's root* (2026-09-26) is that the mesh's writes need no
module-visible reservation: **what the mesh writes for a module is the mesh's plumbing, placed where
the mesh chooses and mounted in, never part of the module's contract.** The definition today names
that place, so a definition is not yet free of host paths — and a node whose root is elsewhere would
place the module's data there and the mesh's files still under `/var/lib/mesh`.
The path-preserving test that let issue 119 close does not cover this: it proves a *placed* directory
resolves to what was named, and these are not placed.
## What it would take
A word for "the mesh's file for this module", or none: `own-secrets` values, a merged config file and
a binding could be named by key alone, with the mesh choosing `<root>/mesh/<module>/<key>` and
mounting it where the container says. The container side of the mount already exists in every
definition (`/run/secrets/broker`, `/run/config/config.json`); only the host side would go. The
change is in the controller, once, and then a mechanical edit of fifty definitions, which the same
test that proved 119 can prove again with the rule extended.
## Open questions
- Does `own-secrets` keep its map shape with the value becoming the *container* path rather than the
host path, or does the mount stay where it is and the host side become a placeholder the mesh
fills, `${mesh:<key>}`?
- A binding file today lands wherever `binds` says; a module's code reads it from an environment
variable naming the container path. If the host side is the mesh's, is the container side still the
definition's to choose? It should be: it is the software's contract.
## Resolved, 2026-09-30
The word is the one issue 119 introduced, with a second place: a directory saying `place: "mesh"` is
the mesh's directory for the module, `<root>/mesh/<module>`, beside the assignment's own root and
under the same node setting. The mesh's files keep their map shape and the container side of every
mount stays the definition's — only the host side changed, to `${dir:mesh-state}/…`. A directory that
sat beneath the mesh's (a forge's runtime state, a manager's output) states its path as
`${dir:mesh-state}/<rest>` and moves with it; one that sits elsewhere by adoption (the registry's data)
keeps its literal path as the exception it is.
Forty-eight catalogue definitions and the controller's own manifest were converted mechanically. The
proof is the same test that let issue 119 close, now resolving *both* checkouts before comparing,
because the earlier manifest already placed its own directories: resolved on the default root, every
converted definition names exactly the paths it named before. Nothing moved.
Both open questions are answered by keeping what exists: the map stays, the host side is placed; the
container side is the software's contract and stays where the definition says.