The tool runner joins the own groups of the modules whose tools it runs, and own directories may keep their group (hq ADR 0334, issue 567) #97

Merged
mesh-admin merged 2 commits from feat/334-the-runner-joins-own-groups into main 2026-10-12 22:22:15 +00:00
Contributor

Why: hq ADR 0334 (small design limit under ADR 0328): a joining module's own directories belong to its own group with setgid, and the tool runner joins those groups so the modules' tools keep reading their state. Found by the review of ADR 0328's controller half. Issue 567.

What

  • Identity entries may carry runner (an account name); the engine puts it in mesh-<module> via the ADR 0252 join path, records only what it gave, takes it back when nothing names it, and marks identity:<module> changed so the tool runner restarts once on a gain or a loss. Contract 7 (link.OwnGroupContract).
  • A refused runner (missing, uid 0, root-group primary) is a warning of its own (runner:<module>, runner:library:<name>), never an apply or module failure; library runners now go through the same refusal.
  • Directory modes may carry setgid (2xxx; setuid and sticky still refused), set on every directory path, kept across applies and compared with it; applied only to directories the mesh made or was handed over, never to an access or a library root.
  • Old shapes unchanged.

Checked: merge-check.sh green (race). Independent review: APPROVE at c7b534a0 after two rounds; every finding fixed with a failing-first test (mutation-checked).

Delivery effects: node-engine restarts on every node; nothing changes until the controller sends contract-7 fields.

**Why**: hq ADR 0334 (small design limit under ADR 0328): a joining module's own directories belong to its own group with setgid, and the tool runner joins those groups so the modules' tools keep reading their state. Found by the review of ADR 0328's controller half. Issue 567. **What** - Identity entries may carry `runner` (an account name); the engine puts it in `mesh-<module>` via the ADR 0252 join path, records only what it gave, takes it back when nothing names it, and marks `identity:<module>` changed so the tool runner restarts once on a gain or a loss. Contract 7 (`link.OwnGroupContract`). - A refused runner (missing, uid 0, root-group primary) is a warning of its own (`runner:<module>`, `runner:library:<name>`), never an apply or module failure; library runners now go through the same refusal. - Directory modes may carry setgid (2xxx; setuid and sticky still refused), set on every directory path, kept across applies and compared with it; applied only to directories the mesh made or was handed over, never to an access or a library root. - Old shapes unchanged. **Checked**: `merge-check.sh` green (race). Independent review: APPROVE at c7b534a0 after two rounds; every finding fixed with a failing-first test (mutation-checked). **Delivery effects**: node-engine restarts on every node; nothing changes until the controller sends contract-7 fields.
mesh-admin added 2 commits 2026-10-12 22:13:00 +00:00
A joining module's own directories belong to its own group, and its tools run in the
tool runner, which could not read them. An identity may now name the tool runner's
account: the engine puts it in mesh-<module> as it puts it in a library's group,
says the change as identity:<module> for the runner's unit to restart once, takes
it back when no identity names it, and refuses an account that is missing or root's.
The engine states contract 7.
Keep a module directory's setgid bit, warn about a refused runner, and restart the runner when it leaves (hq ADR 0334 review)
mesh/merge-gate head c7b534a08c98 merged into trunk 6fe82c61bd32 — pass: builds mesh-host → ace, g14, novox, shanks; no bus step; every machine composes wi…
mesh/repo-check head c7b534a08c98 merged into trunk 6fe82c61bd32 — pass: its merge-check.sh passed
mesh/delivery delivered
c7b534a08c
A module's own directories need setgid so what is made beneath keeps its own group,
and a mode of 2750 refused the whole declaration while every apply dropped the bit:
a directory's mode now carries setgid (never setuid or sticky), set, kept and said.
A tool runner's account that is missing or root's failed the whole apply and dropped
the library's outcome: it is now a warning, said as runner:<module> or
runner:library:<name>. And a runner that leaves a group is taken out before the
resources apply, so its unit is restarted in that apply to lose it.
Author
Contributor

Delivery novox/mesh-host@c7b534a08c98 — delivered since 2026-10-12T22:36:45Z

Delivery plan — builds mesh-host → ace, g14, novox, shanks; no bus step

  • tier 0: mesh-host
  • ace: receives mesh-host
  • g14: receives mesh-host
  • novox: receives mesh-host
  • shanks: receives mesh-host
  • grants step: if this changes what the bus's user list says (a new tool, subject or user), novox is sent that list alone, every build there kept, before mesh-host is judged on its first machine

Machines

  • mesh-host on ace: passed — healthy 3 times over 2m27s
  • mesh-host on the rest running it: sent

Transitions

  • 2026-10-12 22:13 (new) → proposed (announced): novox/mesh-host#97's head announced
  • 2026-10-12 22:18 proposed → checked (checked): a verdict names this commit and the trunk's head as its trunk commit
  • 2026-10-12 22:18 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
  • 2026-10-12 22:33 ready → published (merged): on the trunk its modules follow: merged there, and its walk opened — or nothing for a walk to move
  • 2026-10-12 22:33 published → delivering (go): its walk started: let go by this owner in its group's order, by a person, or on the controller's own path — not a failed walk that carried a later commit for it, after which it waits for a walk of its own commit
  • 2026-10-12 22:36 delivering → delivered (done): its walk is done, carrying its own commit: every machine of its deploy plan passed, or was left as its policy says

The commit's note under refs/notes/mesh-plan keeps every transition: git log --notes=mesh-plan.

<!-- mesh-delivery:view --> **Delivery** `novox/mesh-host@c7b534a08c98` — **delivered** since 2026-10-12T22:36:45Z **Delivery plan** — builds mesh-host → ace, g14, novox, shanks; no bus step - tier 0: mesh-host - ace: receives mesh-host - g14: receives mesh-host - novox: receives mesh-host - shanks: receives mesh-host - grants step: if this changes what the bus's user list says (a new tool, subject or user), novox is sent that list alone, every build there kept, before mesh-host is judged on its first machine **Machines** - mesh-host on ace: passed — healthy 3 times over 2m27s - mesh-host on the rest running it: sent **Transitions** - 2026-10-12 22:13 (new) → proposed (announced): novox/mesh-host#97's head announced - 2026-10-12 22:18 proposed → checked (checked): a verdict names this commit and the trunk's head as its trunk commit - 2026-10-12 22:18 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail - 2026-10-12 22:33 ready → published (merged): on the trunk its modules follow: merged there, and its walk opened — or nothing for a walk to move - 2026-10-12 22:33 published → delivering (go): its walk started: let go by this owner in its group's order, by a person, or on the controller's own path — not a failed walk that carried a later commit for it, after which it waits for a walk of its own commit - 2026-10-12 22:36 delivering → delivered (done): its walk is done, carrying its own commit: every machine of its deploy plan passed, or was left as its policy says The commit's note under `refs/notes/mesh-plan` keeps every transition: `git log --notes=mesh-plan`.
Author
Contributor

Merge check at c7b534a0
Judged: head c7b534a08c98 merged into trunk 6fe82c61bd32; read beside it: mesh-catalog 43a9155d5afe, mesh-controller 21ac8fd8586d, mesh-controller-main 21ac8fd8586d, mesh-tools 954e1a53eef9

  • mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: mesh-host)
  • mesh/repo-check: PASS — its merge-check.sh passed

Delivery plan — builds mesh-host → ace, g14, novox, shanks; no bus step

  • tier 0: mesh-host
  • ace: receives mesh-host
  • g14: receives mesh-host
  • novox: receives mesh-host
  • shanks: receives mesh-host
  • grants step: if this changes what the bus's user list says (a new tool, subject or user), novox is sent that list alone, every build there kept, before mesh-host is judged on its first machine
  • read by no module's build: cmd/mesh-host/units_test.go, internal/apply/library_test.go

Run by the build seat on g14 as build-1791843189305159638 (builds --log build-1791843189305159638).

--- the gate: mesh-host
mesh-host: ok
long-running resources without health: 0
files asking for a setting without saying whether it is trusted: 0
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 0 module(s) changed against 4 machine(s), as the snapshot of 2026-10-12T22:09:48Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-12T22:09:48Z

machines:
  - a machine (f35): composes
  - holds mesh-dns-resolver (idt): composes
  - holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
  - a machine (yvbpsm): composes

a merge would rebuild 1 module(s) in 1 tier(s): mesh-host

notes:
  - cmd/mesh-host/units_test.go and internal/apply/library_test.go read by no module's build, and rebuild nothing (issue 280)
--- its merge-check.sh (go toolchain)
ok  	github.com/novox/mesh-host/cmd/mesh-bootstrap	1.009s
ok  	github.com/novox/mesh-host/cmd/mesh-host	5.448s
ok  	github.com/novox/mesh-host/examples	1.020s
ok  	github.com/novox/mesh-host/internal/accounts	1.368s
ok  	github.com/novox/mesh-host/internal/apply	2.699s
ok  	github.com/novox/mesh-host/internal/bootstrap	3.280s
ok  	github.com/novox/mesh-host/internal/bundle	1.012s
ok  	github.com/novox/mesh-host/internal/declaration	1.054s
ok  	github.com/novox/mesh-host/internal/firewall	1.656s
ok  	github.com/novox/mesh-host/internal/identity	1.054s
ok  	github.com/novox/mesh-host/internal/image	1.017s
ok  	github.com/novox/mesh-host/internal/inventory	1.039s
ok  	github.com/novox/mesh-host/internal/link	10.516s
ok  	github.com/novox/mesh-host/internal/liveness	2.072s
ok  	github.com/novox/mesh-host/internal/meshcli	1.561s
ok  	github.com/novox/mesh-host/internal/network	1.044s
ok  	github.com/novox/mesh-host/internal/outward	1.031s
ok  	github.com/novox/mesh-host/internal/profile	1.602s
ok  	github.com/novox/mesh-host/internal/reachable	1.018s
ok  	github.com/novox/mesh-host/internal/store	1.076s
ok  	github.com/novox/mesh-host/internal/system	1.012s
ok  	github.com/novox/mesh-host/internal/tunnel	1.014s
ok  	github.com/novox/mesh-host/internal/units	1.010s
ok  	github.com/novox/mesh-host/internal/upgrade	1.041s
ok  	github.com/novox/mesh-host/internal/witness	1.425s
ok  	github.com/novox/mesh-host/packaging	1.011s
?   	github.com/novox/mesh-host/rootsearch	[no test files]
ok  	github.com/novox/mesh-host/validate	1.010s
**Merge check** at `c7b534a0` Judged: head `c7b534a08c98` merged into trunk `6fe82c61bd32`; read beside it: mesh-catalog `43a9155d5afe`, mesh-controller `21ac8fd8586d`, mesh-controller-main `21ac8fd8586d`, mesh-tools `954e1a53eef9` - `mesh/merge-gate`: **PASS** — every machine composes with the change as it did without (4 of 4 compose) (modules: mesh-host) - `mesh/repo-check`: **PASS** — its merge-check.sh passed **Delivery plan** — builds mesh-host → ace, g14, novox, shanks; no bus step - tier 0: mesh-host - ace: receives mesh-host - g14: receives mesh-host - novox: receives mesh-host - shanks: receives mesh-host - grants step: if this changes what the bus's user list says (a new tool, subject or user), novox is sent that list alone, every build there kept, before mesh-host is judged on its first machine - read by no module's build: cmd/mesh-host/units_test.go, internal/apply/library_test.go Run by the build seat on g14 as `build-1791843189305159638` (`builds --log build-1791843189305159638`). ``` --- the gate: mesh-host mesh-host: ok long-running resources without health: 0 files asking for a setting without saying whether it is trusted: 0 1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here judging 0 module(s) changed against 4 machine(s), as the snapshot of 2026-10-12T22:09:48Z says they run composing every machine as the mesh is the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued composing every machine with the change the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose) judged by controller development build against the facts of 2026-10-12T22:09:48Z machines: - a machine (f35): composes - holds mesh-dns-resolver (idt): composes - holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes - a machine (yvbpsm): composes a merge would rebuild 1 module(s) in 1 tier(s): mesh-host notes: - cmd/mesh-host/units_test.go and internal/apply/library_test.go read by no module's build, and rebuild nothing (issue 280) --- its merge-check.sh (go toolchain) ok github.com/novox/mesh-host/cmd/mesh-bootstrap 1.009s ok github.com/novox/mesh-host/cmd/mesh-host 5.448s ok github.com/novox/mesh-host/examples 1.020s ok github.com/novox/mesh-host/internal/accounts 1.368s ok github.com/novox/mesh-host/internal/apply 2.699s ok github.com/novox/mesh-host/internal/bootstrap 3.280s ok github.com/novox/mesh-host/internal/bundle 1.012s ok github.com/novox/mesh-host/internal/declaration 1.054s ok github.com/novox/mesh-host/internal/firewall 1.656s ok github.com/novox/mesh-host/internal/identity 1.054s ok github.com/novox/mesh-host/internal/image 1.017s ok github.com/novox/mesh-host/internal/inventory 1.039s ok github.com/novox/mesh-host/internal/link 10.516s ok github.com/novox/mesh-host/internal/liveness 2.072s ok github.com/novox/mesh-host/internal/meshcli 1.561s ok github.com/novox/mesh-host/internal/network 1.044s ok github.com/novox/mesh-host/internal/outward 1.031s ok github.com/novox/mesh-host/internal/profile 1.602s ok github.com/novox/mesh-host/internal/reachable 1.018s ok github.com/novox/mesh-host/internal/store 1.076s ok github.com/novox/mesh-host/internal/system 1.012s ok github.com/novox/mesh-host/internal/tunnel 1.014s ok github.com/novox/mesh-host/internal/units 1.010s ok github.com/novox/mesh-host/internal/upgrade 1.041s ok github.com/novox/mesh-host/internal/witness 1.425s ok github.com/novox/mesh-host/packaging 1.011s ? github.com/novox/mesh-host/rootsearch [no test files] ok github.com/novox/mesh-host/validate 1.010s ```
mesh-admin merged commit 7a41e12063 into main 2026-10-12 22:22:15 +00:00
mesh-admin deleted branch feat/334-the-runner-joins-own-groups 2026-10-12 22:22:15 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: novox/mesh-host#97