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

4.1 KiB


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), 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.