The agent kept running ssh <machine> journalctl while the journal verb existed.
Table. The module asks the controller (tools, modules, nodes, node) at start, every 10 minutes and on claude_code_render, keeps it in mesh-tools.json, and renders into the managed CLAUDE.md an "Instead of a shell command" table: one row per seat/module, each verb with the commands it replaces; rows ranked by what the guard here refused most. Empty (no section) until the controller answers replaces.
Guard. A PreToolUse hook (Bash|Edit|Write|MultiEdit|NotebookEdit), first in the nox-mesh plugin: this module's own binary (claude-code guard) copied root's into /etc/claude-code/marketplace/plugins/nox-mesh/guard/ with guard.json, run by absolute path so a session cannot alter it. Refuses ssh/scp/sftp/rsync/mosh/autossh to a mesh machine (name, domain, *.internal, address, ssh -G alias, jump), writing /etc/hosts or /etc/resolv.conf (shell or Edit/Write), HOSTALIASES, and any command naming the override. The message names the tool on that machine, or says a missing tool is created in its owning module. Stated allowance: an ssh login as git (the forge account) passes; git remotes are never an ssh command line anyway.
Override.MESH_GUARD_OVERRIDE=<why> in the operator's own shell before the session starts; read from /proc/<agent pid>/environ (fixed at exec — no export, settings env or nested session can set it). Every refusal and override is a line in the module's guard.log; an override that cannot be recorded is not honoured. New tool claude_code_guard shows rules, data, table and record.
Also fixed:nodesRunningMe read printed lines from what is a JSON answer (module list --json), so every register tool's "also on" hint and every nodes: "all" named no machine. Now read from the JSON (the printed form still read), with a test.
Tests: guard matches and non-matches (git push/clone/fetch over ssh://, GIT_SSH_COMMAND, ssh -T git@forge, ssh beyond the mesh, commands mentioning ssh), local work-arounds, override from start env + recorded, table generation/order/cut, controller answers parsed. checks/words passes.
A module's own replaces (e.g. docker_logs → docker logs) needs mesh-controller#118 live first — the manifest is read strictly — so docker's declaration is a follow-up.
hq ADR 0245.
The agent kept running `ssh <machine> journalctl` while the journal verb existed.
**Table.** The module asks the controller (`tools`, `modules`, `nodes`, `node`) at start, every 10 minutes and on `claude_code_render`, keeps it in `mesh-tools.json`, and renders into the managed `CLAUDE.md` an "Instead of a shell command" table: one row per seat/module, each verb with the commands it `replaces`; rows ranked by what the guard here refused most. Empty (no section) until the controller answers `replaces`.
**Guard.** A PreToolUse hook (`Bash|Edit|Write|MultiEdit|NotebookEdit`), first in the `nox-mesh` plugin: this module's own binary (`claude-code guard`) copied root's into `/etc/claude-code/marketplace/plugins/nox-mesh/guard/` with `guard.json`, run by absolute path so a session cannot alter it. Refuses ssh/scp/sftp/rsync/mosh/autossh to a mesh machine (name, domain, `*.internal`, address, `ssh -G` alias, jump), writing /etc/hosts or /etc/resolv.conf (shell or Edit/Write), HOSTALIASES, and any command naming the override. The message names the tool on that machine, or says a missing tool is created in its owning module. **Stated allowance:** an ssh login as `git` (the forge account) passes; git remotes are never an ssh command line anyway.
**Override.** `MESH_GUARD_OVERRIDE=<why>` in the operator's own shell before the session starts; read from `/proc/<agent pid>/environ` (fixed at exec — no `export`, settings `env` or nested session can set it). Every refusal and override is a line in the module's `guard.log`; an override that cannot be recorded is not honoured. New tool `claude_code_guard` shows rules, data, table and record.
**Also fixed:** `nodesRunningMe` read printed lines from what is a JSON answer (`module list --json`), so every register tool's "also on" hint and every `nodes: "all"` named no machine. Now read from the JSON (the printed form still read), with a test.
Tests: guard matches and non-matches (git push/clone/fetch over ssh://, GIT_SSH_COMMAND, ssh -T git@forge, ssh beyond the mesh, commands mentioning ssh), local work-arounds, override from start env + recorded, table generation/order/cut, controller answers parsed. `checks/words` passes.
A module's own `replaces` (e.g. docker_logs → `docker logs`) needs mesh-controller#118 live first — the manifest is read strictly — so docker's declaration is a follow-up.
hq ADR 0245.
Deliverynovox/mesh-catalog@f72a43548756 — delivered since 2026-10-07T19:11:56Z
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
Machines
claude-code on ace: passed — healthy 3 times over 3m30s
claude-code on novox: judging — carried by release-1791400043872652570
claude-code on the rest running it: sent
Transitions
2026-10-07 18:36 (new) → proposed (announced): novox/mesh-catalog#110's head announced
2026-10-07 18:38 proposed → checked (checked): the verdict names this commit
2026-10-07 18:38 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
2026-10-07 19:05 ready → published (merged): on the trunk its modules follow: merged there, and its walk opened — or nothing for a walk to move
2026-10-07 19:05 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
2026-10-07 19:11 delivering → delivered (done): its walk is done: 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-catalog@f72a43548756` — **delivered** since 2026-10-07T19:11:56Z
**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
**Machines**
- claude-code on ace: passed — healthy 3 times over 3m30s
- claude-code on novox: judging — carried by release-1791400043872652570
- claude-code on the rest running it: sent
**Transitions**
- 2026-10-07 18:36 (new) → proposed (announced): novox/mesh-catalog#110's head announced
- 2026-10-07 18:38 proposed → checked (checked): the verdict names this commit
- 2026-10-07 18:38 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
- 2026-10-07 19:05 ready → published (merged): on the trunk its modules follow: merged there, and its walk opened — or nothing for a walk to move
- 2026-10-07 19:05 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
- 2026-10-07 19:11 delivering → delivered (done): its walk is done: 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/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
Change 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 g14 as build-1791395177788852355 (builds --log build-1791395177788852355).
--- the gate: claude-code
claude-code: ok, 36 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 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-07T17:23: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-07T17:23:39Z
modules the change moves:
- claude-code (changed)
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-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)
long-running resources without health: 70, as kept
testing modules/claude-code
ok claude-code/cmd/claude-code 1.079s
**Merge check** at `79d52beb`
- `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
**Change 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 g14 as `build-1791395177788852355` (`builds --log build-1791395177788852355`).
```
--- the gate: claude-code
claude-code: ok, 36 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 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-07T17:23: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-07T17:23:39Z
modules the change moves:
- claude-code (changed)
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-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)
long-running resources without health: 70, as kept
testing modules/claude-code
ok claude-code/cmd/claude-code 1.079s
```
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
Change 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-1791396015490585591 (builds --log build-1791396015490585591).
--- 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 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-07T17:59:41Z 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-07T17:59:41Z
modules the change moves:
- claude-code (changed)
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-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)
long-running resources without health: 70, as kept
testing modules/claude-code
ok claude-code/cmd/claude-code 1.171s
**Merge check** at `f1f4bea8`
- `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
**Change 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-1791396015490585591` (`builds --log build-1791396015490585591`).
```
--- 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 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-07T17:59:41Z 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-07T17:59:41Z
modules the change moves:
- claude-code (changed)
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-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)
long-running resources without health: 70, as kept
testing modules/claude-code
ok claude-code/cmd/claude-code 1.171s
```
mesh-admin
changed title from claude-code: an "instead of" table and a guard on the agent's shell (hq ADR 0242) to claude-code: an "instead of" table and a guard on the agent's shell (hq ADR 0245)2026-10-07 18:28:44 +00:00
The agent kept running ssh <machine> journalctl while the journal verb existed. The managed
instructions now carry an "instead of" table generated from what each verb says it replaces, and
the plugin carries a PreToolUse guard that refuses ssh to a mesh machine and local work-arounds for a
mesh name, naming the tool or saying one must be created. The operator's override is read from the
session's start environment and recorded.
mesh/merge-gate pass: builds claude-code → ace, g14, novox, shanks; no bus step; every machine composes with the change as it did without (4 of 4 compose)
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-1791398199311558812 (builds --log build-1791398199311558812).
--- 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 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-07T18:27:34Z 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-07T18:27:34Z
modules the change moves:
- claude-code (changed)
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-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)
words: 12 retired words, none in the 27208 strings of 508 files
long-running resources without health: 70, as kept
testing modules/claude-code
ok claude-code/cmd/claude-code 1.128s
**Merge check** at `f72a4354`
- `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-1791398199311558812` (`builds --log build-1791398199311558812`).
```
--- 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 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-07T18:27:34Z 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-07T18:27:34Z
modules the change moves:
- claude-code (changed)
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-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)
words: 12 retired words, none in the 27208 strings of 508 files
long-running resources without health: 70, as kept
testing modules/claude-code
ok claude-code/cmd/claude-code 1.128s
```
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.
The agent kept running
ssh <machine> journalctlwhile the journal verb existed.Table. The module asks the controller (
tools,modules,nodes,node) at start, every 10 minutes and onclaude_code_render, keeps it inmesh-tools.json, and renders into the managedCLAUDE.mdan "Instead of a shell command" table: one row per seat/module, each verb with the commands itreplaces; rows ranked by what the guard here refused most. Empty (no section) until the controller answersreplaces.Guard. A PreToolUse hook (
Bash|Edit|Write|MultiEdit|NotebookEdit), first in thenox-meshplugin: this module's own binary (claude-code guard) copied root's into/etc/claude-code/marketplace/plugins/nox-mesh/guard/withguard.json, run by absolute path so a session cannot alter it. Refuses ssh/scp/sftp/rsync/mosh/autossh to a mesh machine (name, domain,*.internal, address,ssh -Galias, jump), writing /etc/hosts or /etc/resolv.conf (shell or Edit/Write), HOSTALIASES, and any command naming the override. The message names the tool on that machine, or says a missing tool is created in its owning module. Stated allowance: an ssh login asgit(the forge account) passes; git remotes are never an ssh command line anyway.Override.
MESH_GUARD_OVERRIDE=<why>in the operator's own shell before the session starts; read from/proc/<agent pid>/environ(fixed at exec — noexport, settingsenvor nested session can set it). Every refusal and override is a line in the module'sguard.log; an override that cannot be recorded is not honoured. New toolclaude_code_guardshows rules, data, table and record.Also fixed:
nodesRunningMeread printed lines from what is a JSON answer (module list --json), so every register tool's "also on" hint and everynodes: "all"named no machine. Now read from the JSON (the printed form still read), with a test.Tests: guard matches and non-matches (git push/clone/fetch over ssh://, GIT_SSH_COMMAND, ssh -T git@forge, ssh beyond the mesh, commands mentioning ssh), local work-arounds, override from start env + recorded, table generation/order/cut, controller answers parsed.
checks/wordspasses.A module's own
replaces(e.g. docker_logs →docker logs) needs mesh-controller#118 live first — the manifest is read strictly — so docker's declaration is a follow-up.hq ADR 0245.
Delivery
novox/mesh-catalog@f72a43548756— delivered since 2026-10-07T19:11:56ZDelivery plan — builds claude-code → ace, g14, novox, shanks; no bus step
Machines
Transitions
The commit's note under
refs/notes/mesh-plankeeps every transition:git log --notes=mesh-plan.Merge check at
79d52bebmesh/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 passedChange plan — builds claude-code → ace, g14, novox, shanks; no bus step
Run by the build seat on g14 as
build-1791395177788852355(builds --log build-1791395177788852355).79d52beb4ctof1f4bea857Merge check at
f1f4bea8mesh/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 passedChange plan — builds claude-code → ace, g14, novox, shanks; no bus step
Run by the build seat on shanks as
build-1791396015490585591(builds --log build-1791396015490585591).claude-code: an "instead of" table and a guard on the agent's shell (hq ADR 0242)to claude-code: an "instead of" table and a guard on the agent's shell (hq ADR 0245)f1f4bea857tof72a435487Merge check at
f72a4354mesh/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 passedDelivery plan — builds claude-code → ace, g14, novox, shanks; no bus step
Run by the build seat on shanks as
build-1791398199311558812(builds --log build-1791398199311558812).