novox/hq issue 153 — an adopted machine's data cannot be placed where it is. Opened on a separate branch as asked; not merged by me, since shanks is working in this area (one conflict hunk in dirsFor, internal/catalogue/dir_into.go, against feat/the-mesh-places-its-own-files — my three lines that let a placement win; trivial to re-apply on either side).
The two assignment halves ADR 0112 decided, validated like endpoints (an id the module does not declare is refused, and the refusal lists what it declares):
places: a declared directory (by id) lands at the given path on this node; an optional owner (uid:gid) overrides the manifest's — the predecessor's data is owned by whoever it ran as. Still the mesh's directory: created, chowned, removed when empty.
accesses: an access may now be declared by id ({"id": "series", "mode": "read-write"}) and named in mounts, env and content as ${access:<id>}; the assignment says where it is. An access nobody placed is refused by name with the setting to write. A definition still carrying a path keeps it as the default the assignment replaces (the existing manifests keep working). Still the operator's: mounted, never created, chowned or removed.
${access:…} naming an undeclared access is refused at parse (module check), like ${dir:…}.
Resolved in composition: the host receives concrete paths and owners exactly as before and learns no field.
Tests: placement_test.go (end-to-end declaration with placed directory + owner + two accesses filled into mounts and env; unplaced access refused by name; validation of ids, absolute paths, owner shape; definition path as default; parse-time refusal). Catalogue package green; both catalogues (mesh-catalog, mesh-media-catalog) pass module check with this binary.
With this, the media catalogue's manifests move their /services/media/* paths out of the definitions into ace's assignments (a follow-up there), and hq 153's fixed-by can name this PR.
novox/hq issue 153 — an adopted machine's data cannot be placed where it is. Opened on a separate branch as asked; **not merged by me**, since shanks is working in this area (one conflict hunk in `dirsFor`, `internal/catalogue/dir_into.go`, against `feat/the-mesh-places-its-own-files` — my three lines that let a placement win; trivial to re-apply on either side).
**The two assignment halves ADR 0112 decided**, validated like `endpoints` (an id the module does not declare is refused, and the refusal lists what it declares):
```
{"places": {"config": "/services/sonarr/config",
"data": {"path": "/mnt/plex/data", "owner": "1000:1000"}},
"accesses": {"series": "/storage/media/series", "downloads": "/storage/downloads"}}
```
- `places`: a declared directory (by id) lands at the given path on this node; an optional `owner` (uid:gid) overrides the manifest's — the predecessor's data is owned by whoever it ran as. Still the mesh's directory: created, chowned, removed when empty.
- `accesses`: an access may now be declared by **id** (`{"id": "series", "mode": "read-write"}`) and named in mounts, env and content as `${access:<id>}`; the assignment says where it is. An access nobody placed is refused by name with the setting to write. A definition still carrying a `path` keeps it as the default the assignment replaces (the existing manifests keep working). Still the operator's: mounted, never created, chowned or removed.
- `${access:…}` naming an undeclared access is refused at parse (`module check`), like `${dir:…}`.
- Resolved in composition: the host receives concrete paths and owners exactly as before and learns no field.
Tests: `placement_test.go` (end-to-end declaration with placed directory + owner + two accesses filled into mounts and env; unplaced access refused by name; validation of ids, absolute paths, owner shape; definition path as default; parse-time refusal). Catalogue package green; both catalogues (`mesh-catalog`, `mesh-media-catalog`) pass `module check` with this binary.
With this, the media catalogue's manifests move their `/services/media/*` paths out of the definitions into ace's assignments (a follow-up there), and hq 153's `fixed-by` can name this PR.
A definition names no host path (ADR 0112); an adopted machine keeps its
data where the predecessor put it. Two settings, validated like endpoints:
places: {<directory id>: <path> | {path, owner}}
accesses: {<access id>: <path>}
An access may now be declared by id (`{"id": "series", "mode": "read-write"}`)
and named in mounts, env and content as ${access:<id>}; the assignment
says where it is on this node, and an access nobody placed is refused by
name. A definition still carrying a path keeps it as the default the
assignment replaces. A placed directory takes the assignment's owner
where it says one. Resolved in composition, so the host receives paths
and owners exactly as before.
An access named by id (issue 153) resolves to the path the definition still carries when the
assignment says nothing, and the proof compares that — the same rule as a placed directory.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
novox/hq issue 153 — an adopted machine's data cannot be placed where it is. Opened on a separate branch as asked; not merged by me, since shanks is working in this area (one conflict hunk in
dirsFor,internal/catalogue/dir_into.go, againstfeat/the-mesh-places-its-own-files— my three lines that let a placement win; trivial to re-apply on either side).The two assignment halves ADR 0112 decided, validated like
endpoints(an id the module does not declare is refused, and the refusal lists what it declares):places: a declared directory (by id) lands at the given path on this node; an optionalowner(uid:gid) overrides the manifest's — the predecessor's data is owned by whoever it ran as. Still the mesh's directory: created, chowned, removed when empty.accesses: an access may now be declared by id ({"id": "series", "mode": "read-write"}) and named in mounts, env and content as${access:<id>}; the assignment says where it is. An access nobody placed is refused by name with the setting to write. A definition still carrying apathkeeps it as the default the assignment replaces (the existing manifests keep working). Still the operator's: mounted, never created, chowned or removed.${access:…}naming an undeclared access is refused at parse (module check), like${dir:…}.Tests:
placement_test.go(end-to-end declaration with placed directory + owner + two accesses filled into mounts and env; unplaced access refused by name; validation of ids, absolute paths, owner shape; definition path as default; parse-time refusal). Catalogue package green; both catalogues (mesh-catalog,mesh-media-catalog) passmodule checkwith this binary.With this, the media catalogue's manifests move their
/services/media/*paths out of the definitions into ace's assignments (a follow-up there), and hq 153'sfixed-bycan name this PR.A definition names no host path (ADR 0112); an adopted machine keeps its data where the predecessor put it. Two settings, validated like endpoints: places: {<directory id>: <path> | {path, owner}} accesses: {<access id>: <path>} An access may now be declared by id (`{"id": "series", "mode": "read-write"}`) and named in mounts, env and content as ${access:<id>}; the assignment says where it is on this node, and an access nobody placed is refused by name. A definition still carrying a path keeps it as the default the assignment replaces. A placed directory takes the assignment's owner where it says one. Resolved in composition, so the host receives paths and owners exactly as before.