--- 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//…`, 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 `/mesh//` 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:}`? - 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, `/mesh/`, 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}/` 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.