mesh-cli: the operator's command on every node, nox in zsh (hq ADR 0272)
mesh/merge-gate pass: builds claude-code, mounts, route-adapter, new: modules/mesh-cli → ace, g14, novox, shanks; no bus step; every machine composes with …
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 superseded: a newer head of the same pull request

The records send the operator to "the controller's terminal", and on the
control-node nothing answered (hq issue 343). mesh-cli is a module of its
own, assigned to every node and built from its own directory: its program
is unpacked into /usr/local/bin by an archive resource (one file, no link,
no copy), and its zsh contribution makes nox its alias. It holds no
credential: it asks the node-engine on its machine over the SDK's go/cli
socket, and prints the controller's answer with its exit.

The agent module's refusals and README, and the route adapter's README, now
name `mesh-cli settings set …` on the control-node instead of a
mesh-controller command nobody could type; a settings file is passed inline,
since a path would be read where the controller runs.
This commit is contained in:
jochen
2026-10-09 12:11:21 +02:00
parent 7339ce8556
commit 2594a24b35
12 changed files with 282 additions and 11 deletions
+5 -5
View File
@@ -94,8 +94,8 @@ another node. So these tools refuse, and say why and how it is done instead:
- `claude_code_hook_register`, `claude_code_settings_set`, `claude_code_permission_add`, `claude_code_permission_remove`:
the operator sets hooks, permission rules and every other managed setting in this module's `managed_settings`
setting, `mesh-controller settings set claude-code '{"managed_settings": {…}}' [--node <node>]`, typed at the
controller's terminal. The controller refuses `managed_settings`, `mcp_servers` and `role` through any verb: a
setting, `mesh-cli settings set claude-code '{"managed_settings": {…}}' [--node <node>]`, typed at the
controller's terminal (`mesh-cli`, or `nox`, on the control-node; hq ADR 0272). The controller refuses `managed_settings`, `mcp_servers` and `role` through any verb: a
mergeable file asks for every key its own content names;
- `claude_code_mcp_register`: the operator sets tool servers in the `mcp_servers` setting the same way;
- a skill, subagent or command that would run something by itself: a shell line the agent runs when it loads one
@@ -117,7 +117,7 @@ decision of 2026-10-09; a surface of the operator's own may update it later). In
skills, commands and subagents at the `mesh` or `node` scope are refused through the tools, and the import tool is
refused. They are keys of this module's settings, each text a list of its lines, because a setting holds no line
break: `instructions`, `output_styles`, `commands` and `agents` map a name to its text; `skills` maps a name to its
files, each a list of lines. For example `mesh-controller settings set claude-code '{"instructions": {"conventions":
files, each a list of lines. For example `mesh-cli settings set claude-code '{"instructions": {"conventions":
["Commit in the imperative.", "", "Test before pushing."]}}'`. They land where a registration did, laid over what was
registered before; what the operator writes there is not judged, but an item that is not well formed is left out and
said in the render's answer. What was registered before is still rendered and may be unregistered.
@@ -156,8 +156,8 @@ A new session takes a change; a running one at `/reload-plugins`.
## Settings
Per node or for the whole mesh, at the controller's terminal alone: `mesh-controller settings set claude-code '<json>'
[--node <node>]`. The controller refuses all three keys through any verb, `mesh-controller.settings` included, because
Per node or for the whole mesh, at the controller's terminal alone: `mesh-cli settings set claude-code '<json>'
[--node <node>]` on the control-node (in zsh, `nox`; hq ADR 0272). The controller refuses all three keys through any verb, `mesh-controller.settings` included, because
each reaches every session on the node and a verb's caller may be an agent (hq issue 340). Reading them through the
verb still answers.
@@ -86,8 +86,8 @@ var nodeName = regexp.MustCompile(`^[a-z0-9][a-z0-9-]{0,62}$`)
// AtTheTerminal is how a hook, a permission rule or any other managed setting is set now (novox/hq issue 340):
// in this module's `managed_settings` setting, at the controller's terminal, which refuses it through a verb.
const AtTheTerminal = "mesh-controller settings set claude-code '{\"managed_settings\": {...}}' [--node <node>], " +
"typed by the operator at the controller's terminal"
const AtTheTerminal = "mesh-cli settings set claude-code '{\"managed_settings\": {...}}' [--node <node>], " +
"typed by the operator at the controller's terminal: mesh-cli (nox) on the control-node (novox/hq ADR 0272)"
// RunsInASession says why a kind is never registered through this module: what it holds runs in, or is obeyed
// by, every session it reaches, as whoever starts that session (novox/hq issue 340).
@@ -935,7 +935,7 @@ func SharedTextAtTheTerminal(kind string) string {
KindOutputStyle: "output_styles", KindInstructions: "instructions"}[kind]
return "a " + kind + " for every node or some reaches every session there as the mesh's own word, and this tool " +
"cannot tell an agent from the operator. It is set at the controller's terminal only, under `" + key +
"` in this module's settings, its text as a list of lines: mesh-controller settings set claude-code " +
"` in this module's settings, its text as a list of lines, on the control-node: mesh-cli settings set claude-code " +
"'{\"" + key + "\": {\"<name>\": [\"line\", …]}}' [--node <node>] (novox/hq issue 340). The home scope, " +
"one account's own directory, is still registered here. Nothing was registered"
}
+1 -1
View File
@@ -604,7 +604,7 @@ func OnServerChange(v *ServerView, c ServerChange, p Paths, write WriteManaged)
const ServerAtTheTerminal = "a tool server is started, or handed what the agent asks it, by every session on the nodes it " +
"reaches, as whoever starts that session — the operator, whose account holds root — and the tool runner is not " +
"told who called it, so an agent on another node could register one. It is set at the controller's terminal " +
"only, in this module's mcp_servers setting: mesh-controller settings set claude-code '{\"mcp_servers\": {...}}' " +
"only, in this module's mcp_servers setting, on the control-node: mesh-cli settings set claude-code '{\"mcp_servers\": {...}}' " +
"[--node <node>] (novox/hq issue 340). Nothing was registered"
// RegisterServer unregisters a server: a delete per scope in the `servers` state, taken into this node's view at
@@ -130,7 +130,7 @@ func TestWhatASessionRunsIsRefusedThroughEveryTool(t *testing.T) {
// The settings and the tool server refusals name the terminal's line.
text, _ := s.call(t, "claude_code_settings_set", map[string]any{"settings": map[string]any{"model": "x"}})
if !strings.Contains(text, "mesh-controller settings set claude-code") {
if !strings.Contains(text, "mesh-cli settings set claude-code") {
t.Errorf("the refusal does not say how it is done: %s", text)
}
text, _ = s.call(t, "claude_code_mcp_register", map[string]any{"name": "x", "url": "https://x.example"})