claude-code: write the agent's home as its own account where it has one (hq ADR 0266) #140

Closed
mesh-admin wants to merge 0 commits from feat/the-agent-runs-as-its-own-account into main
Contributor

Part of hq ADR 0266 (on the control node, agents run under an account of their own, without sudo).

What changes. The module reads the account agents run as and its home from the runtime (MESH_AGENT_ACCOUNT, MESH_AGENT_HOME, composed by the controller from mesh-controller's new node fact), falling back to the operator's, as before, where they are not set. Where the agent's account is not the runtime's:

  • every path under the agent's home (licence token, .claude.json identity, home-scope items, the status and removal tools) is touched by a helper running as that account: this module's own binary as the plugin carries it under /etc/claude-code (root's), started once with sudo -n -u <agent> … home-fs and kept, one JSON request and answer per line. The escalation goes down only.
  • an API-key licence and its key-helper live in ~/.claude/mesh/ of the agent, which can read them; the module's state is not readable by that account.
  • a binding counts as applied only while the agent's account holds it, so the token follows the move at once.
  • what the module placed under the operator's home goes: the access-token-only credentials file (one with a refresh token is a person's login and stays, said), home-scope items unless changed by hand, the key kept in state. The home-scope record is kept per home.
  • the guard refuses every command and file edit of a session not running as the agent's account (rule account, no override) and records to the journal (mesh-claude-code-guard), which the session's account cannot rewrite.

Where no agent account is named (every node today) nothing changes: all paths are the plain filesystem, the guard data carries no account.

Order. Safe to merge before the controller part. The manifest part (declaring the account and claude-agent) is a separate PR, on top of this one, which needs mesh-controller's new machine facts first.

Tests: agent_account_test.go (helper protocol in-process, routing, restart, paths, licence follow, retirement of the operator-home placements, guard account rule, journal record). go test -race passes; words and paths checks pass.

Part of hq ADR 0266 (on the control node, agents run under an account of their own, without sudo). **What changes.** The module reads the account agents run as and its home from the runtime (`MESH_AGENT_ACCOUNT`, `MESH_AGENT_HOME`, composed by the controller from mesh-controller's new node fact), falling back to the operator's, as before, where they are not set. Where the agent's account is not the runtime's: - every path under the agent's home (licence token, `.claude.json` identity, home-scope items, the status and removal tools) is touched by a helper running as that account: this module's own binary as the plugin carries it under `/etc/claude-code` (root's), started once with `sudo -n -u <agent> … home-fs` and kept, one JSON request and answer per line. The escalation goes down only. - an API-key licence and its key-helper live in `~/.claude/mesh/` of the agent, which can read them; the module's state is not readable by that account. - a binding counts as applied only while the agent's account holds it, so the token follows the move at once. - what the module placed under the operator's home goes: the access-token-only credentials file (one with a refresh token is a person's login and stays, said), home-scope items unless changed by hand, the key kept in state. The home-scope record is kept per home. - the guard refuses every command and file edit of a session not running as the agent's account (rule `account`, no override) and records to the journal (`mesh-claude-code-guard`), which the session's account cannot rewrite. **Where no agent account is named (every node today) nothing changes**: all paths are the plain filesystem, the guard data carries no account. **Order.** Safe to merge before the controller part. The manifest part (declaring the account and `claude-agent`) is a separate PR, on top of this one, which needs mesh-controller's new machine facts first. Tests: `agent_account_test.go` (helper protocol in-process, routing, restart, paths, licence follow, retirement of the operator-home placements, guard account rule, journal record). `go test -race` passes; words and paths checks pass.
Author
Contributor

Delivery novox/mesh-catalog@c8fb0016f2d2 — stopped since 2026-10-09T22:00:02Z

Delivery plan — builds claude-code, claude-licence-manager, restic → ace, g14, novox, shanks; no bus step

  • tier 0: claude-code, claude-licence-manager, restic
  • ace: receives claude-code, restic
  • g14: receives claude-code, restic
  • novox: receives claude-code, claude-licence-manager, restic
  • shanks: receives claude-code, restic
  • claude-code keeps data (ADR 0233): what it holds is backed up before it moves
  • restic keeps data (ADR 0233): what it holds is backed up before it moves

Transitions

  • 2026-10-09 09:03 (new) → proposed (announced): novox/mesh-catalog#140's head announced
  • 2026-10-09 09:05 proposed → checked (checked): the verdict names this commit
  • 2026-10-09 09:05 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
  • 2026-10-09 22:00 ready → stopped (closed): the pull request closed unmerged

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

<!-- mesh-delivery:view --> **Delivery** `novox/mesh-catalog@c8fb0016f2d2` — **stopped** since 2026-10-09T22:00:02Z **Delivery plan** — builds claude-code, claude-licence-manager, restic → ace, g14, novox, shanks; no bus step - tier 0: claude-code, claude-licence-manager, restic - ace: receives claude-code, restic - g14: receives claude-code, restic - novox: receives claude-code, claude-licence-manager, restic - shanks: receives claude-code, restic - claude-code keeps data (ADR 0233): what it holds is backed up before it moves - restic keeps data (ADR 0233): what it holds is backed up before it moves **Transitions** - 2026-10-09 09:03 (new) → proposed (announced): novox/mesh-catalog#140's head announced - 2026-10-09 09:05 proposed → checked (checked): the verdict names this commit - 2026-10-09 09:05 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail - 2026-10-09 22:00 ready → stopped (closed): the pull request closed unmerged The commit's note under `refs/notes/mesh-plan` keeps every transition: `git log --notes=mesh-plan`.
Author
Contributor

Merge check at 63101f44

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

Delivery plan — builds claude-code → ace, g14, novox, shanks; no bus step

  • tier 0: claude-code
  • ace: receives claude-code
  • g14: receives claude-code
  • novox: receives claude-code
  • shanks: receives claude-code
  • claude-code keeps data (ADR 0233): what it holds is backed up before it moves

Run by the build seat on shanks as build-1791477316313796046 (builds --log build-1791477316313796046).

--- the gate: claude-code
claude-code: ok, 40 tool(s), keeps state servers, holdings, config, reads claude-licence-manager.bindings, keeps agent-home (valuable)
long-running resources without health: 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-08T16:26:42Z 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-08T16:26:42Z

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): claude-code
--- its merge-check.sh (go toolchain)
ok  	git.novox.be/novox/mesh-catalog/checks/words	0.002s
words: 12 retired words, none in the 31047 strings of 565 files
ok  	git.novox.be/novox/mesh-catalog/checks/paths	0.006s
paths: no module names another's state on its machine (3 known, listed to go)
long-running resources without health: 70, as kept
testing modules/claude-code
ok  	claude-code/cmd/claude-code	1.138s
**Merge check** at `63101f44` - `mesh/merge-gate`: **PASS** — every machine composes with the change as it did without (4 of 4 compose) (modules: claude-code) - `mesh/repo-check`: **PASS** — its merge-check.sh passed **Delivery plan** — builds claude-code → ace, g14, novox, shanks; no bus step - tier 0: claude-code - ace: receives claude-code - g14: receives claude-code - novox: receives claude-code - shanks: receives claude-code - claude-code keeps data (ADR 0233): what it holds is backed up before it moves Run by the build seat on shanks as `build-1791477316313796046` (`builds --log build-1791477316313796046`). ``` --- the gate: claude-code claude-code: ok, 40 tool(s), keeps state servers, holdings, config, reads claude-licence-manager.bindings, keeps agent-home (valuable) long-running resources without health: 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-08T16:26:42Z 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-08T16:26:42Z 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): claude-code --- its merge-check.sh (go toolchain) ok git.novox.be/novox/mesh-catalog/checks/words 0.002s words: 12 retired words, none in the 31047 strings of 565 files ok git.novox.be/novox/mesh-catalog/checks/paths 0.006s paths: no module names another's state on its machine (3 known, listed to go) long-running resources without health: 70, as kept testing modules/claude-code ok claude-code/cmd/claude-code 1.138s ```
jschoubben force-pushed feat/the-agent-runs-as-its-own-account from 63101f447a to 01c5c44249 2026-10-08 18:32:37 +00:00 Compare
Author
Contributor

Merge check at 01c5c442

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

Delivery plan — builds claude-code, claude-licence-manager → ace, g14, novox, shanks; no bus step

  • tier 0: claude-code, claude-licence-manager
  • ace: receives claude-code
  • g14: receives claude-code
  • novox: receives claude-code, claude-licence-manager
  • shanks: receives claude-code
  • claude-code keeps data (ADR 0233): what it holds is backed up before it moves
  • read by no module's build: .gitignore

Run by the build seat on novox as build-1791484368398339631 (builds --log build-1791484368398339631).

--- the gate: claude-code, claude-licence-manager
claude-code: ok, 40 tool(s), keeps state servers, holdings, config, reads claude-licence-manager.bindings, keeps agent-home (valuable)
claude-licence-manager: ok, keeps state bindings, reads claude-code.holdings
long-running resources without health: 0
2 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-08T18:28: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-08T18:28: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 2 module(s) in 1 tier(s): claude-code, claude-licence-manager

notes:
  - .gitignore read by no module's build, and rebuild nothing (issue 280)
--- its merge-check.sh (go toolchain)
ok  	git.novox.be/novox/mesh-catalog/checks/words	0.002s
words: 12 retired words, none in the 31079 strings of 565 files
ok  	git.novox.be/novox/mesh-catalog/checks/paths	0.009s
paths: no module names another's state on its machine (3 known, listed to go)
long-running resources without health: 70, as kept
testing modules/claude-code
ok  	claude-code/cmd/claude-code	1.208s
testing modules/claude-licence-manager
ok  	claude-licence-manager/cmd/claude-licence-manager	1.133s
**Merge check** at `01c5c442` - `mesh/merge-gate`: **PASS** — every machine composes with the change as it did without (4 of 4 compose) (modules: claude-code, claude-licence-manager) - `mesh/repo-check`: **PASS** — its merge-check.sh passed **Delivery plan** — builds claude-code, claude-licence-manager → ace, g14, novox, shanks; no bus step - tier 0: claude-code, claude-licence-manager - ace: receives claude-code - g14: receives claude-code - novox: receives claude-code, claude-licence-manager - shanks: receives claude-code - claude-code keeps data (ADR 0233): what it holds is backed up before it moves - read by no module's build: .gitignore Run by the build seat on novox as `build-1791484368398339631` (`builds --log build-1791484368398339631`). ``` --- the gate: claude-code, claude-licence-manager claude-code: ok, 40 tool(s), keeps state servers, holdings, config, reads claude-licence-manager.bindings, keeps agent-home (valuable) claude-licence-manager: ok, keeps state bindings, reads claude-code.holdings long-running resources without health: 0 2 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-08T18:28: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-08T18:28: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 2 module(s) in 1 tier(s): claude-code, claude-licence-manager notes: - .gitignore read by no module's build, and rebuild nothing (issue 280) --- its merge-check.sh (go toolchain) ok git.novox.be/novox/mesh-catalog/checks/words 0.002s words: 12 retired words, none in the 31079 strings of 565 files ok git.novox.be/novox/mesh-catalog/checks/paths 0.009s paths: no module names another's state on its machine (3 known, listed to go) long-running resources without health: 70, as kept testing modules/claude-code ok claude-code/cmd/claude-code 1.208s testing modules/claude-licence-manager ok claude-licence-manager/cmd/claude-licence-manager 1.133s ```
Author
Contributor

Merge check at 499efa4e

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

Delivery plan — builds claude-code, claude-licence-manager, restic → ace, g14, novox, shanks; no bus step

  • tier 0: claude-code, claude-licence-manager, restic
  • ace: receives claude-code, restic
  • g14: receives claude-code, restic
  • novox: receives claude-code, claude-licence-manager, restic
  • shanks: receives claude-code, restic
  • claude-code keeps data (ADR 0233): what it holds is backed up before it moves
  • restic keeps data (ADR 0233): what it holds is backed up before it moves
  • read by no module's build: .gitignore

Run by the build seat on shanks as build-1791484883674305782 (builds --log build-1791484883674305782).

--- the gate: claude-code, claude-licence-manager, restic
claude-code: ok, 40 tool(s), keeps state servers, holdings, config, reads claude-licence-manager.bindings, keeps agent-home (valuable)
claude-licence-manager: ok, keeps state bindings, reads claude-code.holdings
restic: ok, keeps repository (rebuildable), state (cache)
long-running resources without health: 0
3 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-08T18:28: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-08T18:28: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 3 module(s) in 1 tier(s): claude-code, claude-licence-manager, restic

notes:
  - .gitignore read by no module's build, and rebuild nothing (issue 280)
--- its merge-check.sh (go toolchain)
ok  	git.novox.be/novox/mesh-catalog/checks/words	0.002s
words: 12 retired words, none in the 31100 strings of 565 files
ok  	git.novox.be/novox/mesh-catalog/checks/paths	0.006s
paths: no module names another's state on its machine (3 known, listed to go)
long-running resources without health: 70, as kept
testing modules/claude-code
ok  	claude-code/cmd/claude-code	1.149s
testing modules/claude-licence-manager
ok  	claude-licence-manager/cmd/claude-licence-manager	1.123s
testing modules/restic
ok  	restic/cmd/restic-backups	1.031s
**Merge check** at `499efa4e` - `mesh/merge-gate`: **PASS** — every machine composes with the change as it did without (4 of 4 compose) (modules: claude-code, claude-licence-manager, restic) - `mesh/repo-check`: **PASS** — its merge-check.sh passed **Delivery plan** — builds claude-code, claude-licence-manager, restic → ace, g14, novox, shanks; no bus step - tier 0: claude-code, claude-licence-manager, restic - ace: receives claude-code, restic - g14: receives claude-code, restic - novox: receives claude-code, claude-licence-manager, restic - shanks: receives claude-code, restic - claude-code keeps data (ADR 0233): what it holds is backed up before it moves - restic keeps data (ADR 0233): what it holds is backed up before it moves - read by no module's build: .gitignore Run by the build seat on shanks as `build-1791484883674305782` (`builds --log build-1791484883674305782`). ``` --- the gate: claude-code, claude-licence-manager, restic claude-code: ok, 40 tool(s), keeps state servers, holdings, config, reads claude-licence-manager.bindings, keeps agent-home (valuable) claude-licence-manager: ok, keeps state bindings, reads claude-code.holdings restic: ok, keeps repository (rebuildable), state (cache) long-running resources without health: 0 3 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-08T18:28: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-08T18:28: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 3 module(s) in 1 tier(s): claude-code, claude-licence-manager, restic notes: - .gitignore read by no module's build, and rebuild nothing (issue 280) --- its merge-check.sh (go toolchain) ok git.novox.be/novox/mesh-catalog/checks/words 0.002s words: 12 retired words, none in the 31100 strings of 565 files ok git.novox.be/novox/mesh-catalog/checks/paths 0.006s paths: no module names another's state on its machine (3 known, listed to go) long-running resources without health: 70, as kept testing modules/claude-code ok claude-code/cmd/claude-code 1.149s testing modules/claude-licence-manager ok claude-licence-manager/cmd/claude-licence-manager 1.123s testing modules/restic ok restic/cmd/restic-backups 1.031s ```
Author
Contributor

Merge check at 5718f8a7

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

Delivery plan — builds claude-code, claude-licence-manager, restic → ace, g14, novox, shanks; no bus step

  • tier 0: claude-code, claude-licence-manager, restic
  • ace: receives claude-code, restic
  • g14: receives claude-code, restic
  • novox: receives claude-code, claude-licence-manager, restic
  • shanks: receives claude-code, restic
  • claude-code keeps data (ADR 0233): what it holds is backed up before it moves
  • restic keeps data (ADR 0233): what it holds is backed up before it moves
  • read by no module's build: .gitignore

Run by the build seat on ace as build-1791489422612267778 (builds --log build-1791489422612267778).

--- the gate: claude-code, claude-licence-manager, restic
claude-code: ok, 40 tool(s), keeps state servers, holdings, config, reads claude-licence-manager.bindings, keeps agent-home (valuable)
claude-licence-manager: ok, keeps state bindings, reads claude-code.holdings
restic: ok, keeps repository (rebuildable), state (cache)
long-running resources without health: 0
3 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-08T19:59:18Z 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-08T19:59:18Z

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 3 module(s) in 1 tier(s): claude-code, claude-licence-manager, restic

notes:
  - .gitignore read by no module's build, and rebuild nothing (issue 280)
--- its merge-check.sh (go toolchain)
ok  	git.novox.be/novox/mesh-catalog/checks/words	0.002s
words: 12 retired words, none in the 31100 strings of 565 files
ok  	git.novox.be/novox/mesh-catalog/checks/paths	0.006s
paths: no module names another's state on its machine (3 known, listed to go)
long-running resources without health: 70, as kept
testing modules/claude-code
ok  	claude-code/cmd/claude-code	1.133s
testing modules/claude-licence-manager
ok  	claude-licence-manager/cmd/claude-licence-manager	1.098s
testing modules/restic
ok  	restic/cmd/restic-backups	1.032s
**Merge check** at `5718f8a7` - `mesh/merge-gate`: **PASS** — every machine composes with the change as it did without (4 of 4 compose) (modules: claude-code, claude-licence-manager, restic) - `mesh/repo-check`: **PASS** — its merge-check.sh passed **Delivery plan** — builds claude-code, claude-licence-manager, restic → ace, g14, novox, shanks; no bus step - tier 0: claude-code, claude-licence-manager, restic - ace: receives claude-code, restic - g14: receives claude-code, restic - novox: receives claude-code, claude-licence-manager, restic - shanks: receives claude-code, restic - claude-code keeps data (ADR 0233): what it holds is backed up before it moves - restic keeps data (ADR 0233): what it holds is backed up before it moves - read by no module's build: .gitignore Run by the build seat on ace as `build-1791489422612267778` (`builds --log build-1791489422612267778`). ``` --- the gate: claude-code, claude-licence-manager, restic claude-code: ok, 40 tool(s), keeps state servers, holdings, config, reads claude-licence-manager.bindings, keeps agent-home (valuable) claude-licence-manager: ok, keeps state bindings, reads claude-code.holdings restic: ok, keeps repository (rebuildable), state (cache) long-running resources without health: 0 3 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-08T19:59:18Z 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-08T19:59:18Z 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 3 module(s) in 1 tier(s): claude-code, claude-licence-manager, restic notes: - .gitignore read by no module's build, and rebuild nothing (issue 280) --- its merge-check.sh (go toolchain) ok git.novox.be/novox/mesh-catalog/checks/words 0.002s words: 12 retired words, none in the 31100 strings of 565 files ok git.novox.be/novox/mesh-catalog/checks/paths 0.006s paths: no module names another's state on its machine (3 known, listed to go) long-running resources without health: 70, as kept testing modules/claude-code ok claude-code/cmd/claude-code 1.133s testing modules/claude-licence-manager ok claude-licence-manager/cmd/claude-licence-manager 1.098s testing modules/restic ok restic/cmd/restic-backups 1.032s ```
jschoubben added 3 commits 2026-10-09 09:03:17 +00:00
On the control node agents are to run as an account that cannot become root
(hq ADR 0266). The runtime keeps running as the operator, so the token, the
identity and the home-scope items go to the agent's home through a helper
started as that account; the licence and the account file follow the move,
what was placed in the operator's home goes once the agent holds the licence,
and the guard refuses every tool of a session running as anyone else,
recording to the journal. An API key is taken only from the agent's home and
only when it is one, here and in the licence manager, so the tool cannot carry
off the runtime's credential. Unchanged where no agent account is named.
Root writes a restore beside the live data. In a directory another account
controls, such as the agent's home (hq ADR 0266), that account could put a
symbolic link where root writes and have root write anywhere; such a restore
now goes to the module's state.
Test that a sealed grant hides its words, not two letters
mesh/merge-gate pass: builds claude-code, claude-licence-manager, restic → ace, g14, novox, shanks; no bus step; every machine composes with the change as …
mesh/repo-check pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)
mesh/delivery stopped: the pull request closed unmerged
c8fb0016f2
The check looked for "rt" in a random base64 ciphertext, which holds it
about one time in seventy, and failed mesh-catalog #141's repo check by
chance.
jschoubben force-pushed feat/the-agent-runs-as-its-own-account from 5718f8a75c to c8fb0016f2 2026-10-09 09:03:17 +00:00 Compare
Author
Contributor

Merge check at c8fb0016

  • mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: claude-code, claude-licence-manager, restic)
  • mesh/repo-check: PASS — its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)

Delivery plan — builds claude-code, claude-licence-manager, restic → ace, g14, novox, shanks; no bus step

  • tier 0: claude-code, claude-licence-manager, restic
  • ace: receives claude-code, restic
  • g14: receives claude-code, restic
  • novox: receives claude-code, claude-licence-manager, restic
  • shanks: receives claude-code, restic
  • claude-code keeps data (ADR 0233): what it holds is backed up before it moves
  • restic keeps data (ADR 0233): what it holds is backed up before it moves
  • read by no module's build: .gitignore

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

--- the gate: claude-code, claude-licence-manager, restic
claude-code: ok, 41 tool(s), keeps state servers, holdings, config, reads claude-licence-manager.bindings, keeps agent-home (valuable); WARNING: settings ask(s) for a setting and do(es) not say whether it is trusted, so it counts as trusted: set at the terminal alone; say "trusted" false where nothing trusts it (novox/hq issue 339)
claude-licence-manager: ok, keeps state bindings, reads claude-code.holdings; WARNING: settings ask(s) for a setting and do(es) not say whether it is trusted, so it counts as trusted: set at the terminal alone; say "trusted" false where nothing trusts it (novox/hq issue 339)
restic: ok, keeps repository (rebuildable), state (cache)
long-running resources without health: 0
files asking for a setting without saying whether it is trusted: 2
3 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-09T08:07:39Z 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-09T08:07:39Z

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 3 module(s) in 1 tier(s): claude-code, claude-licence-manager, restic

notes:
  - .gitignore read by no module's build, and rebuild nothing (issue 280)
--- its merge-check.sh (go toolchain)
ok  	git.novox.be/novox/mesh-catalog/checks/words	0.003s
words: 12 retired words, none in the 34302 strings of 605 files
ok  	git.novox.be/novox/mesh-catalog/checks/paths	0.006s
paths: no module names another's state on its machine (3 known, listed to go)
long-running resources without health: 70, as kept
testing modules/claude-code
ok  	claude-code/cmd/claude-code	1.344s
testing modules/claude-licence-manager
ok  	claude-licence-manager/cmd/claude-licence-manager	1.098s
testing modules/restic
ok  	restic/cmd/restic-backups	1.027s
--- its merge-check-typescript.sh (typescript toolchain)
**Merge check** at `c8fb0016` - `mesh/merge-gate`: **PASS** — every machine composes with the change as it did without (4 of 4 compose) (modules: claude-code, claude-licence-manager, restic) - `mesh/repo-check`: **PASS** — its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript) **Delivery plan** — builds claude-code, claude-licence-manager, restic → ace, g14, novox, shanks; no bus step - tier 0: claude-code, claude-licence-manager, restic - ace: receives claude-code, restic - g14: receives claude-code, restic - novox: receives claude-code, claude-licence-manager, restic - shanks: receives claude-code, restic - claude-code keeps data (ADR 0233): what it holds is backed up before it moves - restic keeps data (ADR 0233): what it holds is backed up before it moves - read by no module's build: .gitignore Run by the build seat on g14 as `build-1791536618371353287` (`builds --log build-1791536618371353287`). ``` --- the gate: claude-code, claude-licence-manager, restic claude-code: ok, 41 tool(s), keeps state servers, holdings, config, reads claude-licence-manager.bindings, keeps agent-home (valuable); WARNING: settings ask(s) for a setting and do(es) not say whether it is trusted, so it counts as trusted: set at the terminal alone; say "trusted" false where nothing trusts it (novox/hq issue 339) claude-licence-manager: ok, keeps state bindings, reads claude-code.holdings; WARNING: settings ask(s) for a setting and do(es) not say whether it is trusted, so it counts as trusted: set at the terminal alone; say "trusted" false where nothing trusts it (novox/hq issue 339) restic: ok, keeps repository (rebuildable), state (cache) long-running resources without health: 0 files asking for a setting without saying whether it is trusted: 2 3 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-09T08:07:39Z 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-09T08:07:39Z 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 3 module(s) in 1 tier(s): claude-code, claude-licence-manager, restic notes: - .gitignore read by no module's build, and rebuild nothing (issue 280) --- its merge-check.sh (go toolchain) ok git.novox.be/novox/mesh-catalog/checks/words 0.003s words: 12 retired words, none in the 34302 strings of 605 files ok git.novox.be/novox/mesh-catalog/checks/paths 0.006s paths: no module names another's state on its machine (3 known, listed to go) long-running resources without health: 70, as kept testing modules/claude-code ok claude-code/cmd/claude-code 1.344s testing modules/claude-licence-manager ok claude-licence-manager/cmd/claude-licence-manager 1.098s testing modules/restic ok restic/cmd/restic-backups 1.027s --- its merge-check-typescript.sh (typescript toolchain) ```
Author
Contributor

Rebased onto main on 2026-10-09 (head c8fb001). Issue 340 (#149) conflicted in claude-code/node.go, and both intents are kept in one Paths:

  • Home comes from MESH_AGENT_HOME, falling back to the operator's home when there is no agent account.
  • AgentHome and OperatorHome are kept for #149's HomeIsTheAgentsOwn, HomeScopeRefused and HomeChangeRefused.
  • RenderNow reports both #149's left-out shared text and this branch's RetireOperatorHome.

merge-check.sh passed on the rebased head with a main-built controller as the gate (claude-code, claude-licence-manager, restic).

**Rebased onto main on 2026-10-09 (head c8fb001).** Issue 340 (#149) conflicted in `claude-code/node.go`, and both intents are kept in one `Paths`: - `Home` comes from `MESH_AGENT_HOME`, falling back to the operator's home when there is no agent account. - `AgentHome` and `OperatorHome` are kept for #149's `HomeIsTheAgentsOwn`, `HomeScopeRefused` and `HomeChangeRefused`. - `RenderNow` reports both #149's left-out shared text and this branch's `RetireOperatorHome`. `merge-check.sh` passed on the rebased head with a main-built controller as the gate (claude-code, claude-licence-manager, restic).
mesh-admin closed this pull request 2026-10-09 21:59:53 +00:00

Pull request closed

This pull request cannot be reopened because the branch was deleted.
Sign in to join this conversation.
No Reviewers
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: novox/mesh-catalog#140