Files
hq/04-ISSUES/343-the-controllers-terminal-has-no-command/00-report.md
T
jschoubben 418261213c
mesh/merge-gate pass: the change touches no module of the mesh's graph
mesh/repo-check pass: THE CHANGE ALTERS ITS OWN CHECK (merge-check.sh): main's version judged it; the change's judges the pull requests after it merges; it…
mesh/delivery superseded: a newer head of the same pull request
Remove the decision records and research efforts, which the knowledge base now holds whole (issue 426)
ADR 0290 rule 9: once the import is checked record by record, hq keeps no copy.
The records and efforts are removed; every link or path to them reads "ADR NNNN" or
"research NNN"; a design's decisions: lists "ADR NNNN". 02-DECISIONS keeps a pointer
README with the reading order's six topics, which the knowledge base reads through the
records module; 01-RESEARCH keeps a pointer README. The checks drop the rules that
judged records (the knowledge base holds each at propose; checks/README.md says where)
and refuse a record written here again. Playbooks 01 and 02 and the skills write and
read records with the knowledge base's verbs.
2026-10-11 12:56:09 +02:00

3.3 KiB

opened
opened
2026-10-09

343. The controller's terminal has no command

Symptom

On 2026-10-09 the operator, on the control-node in their own shell, typed a mesh-controller command line to make a change the records say is made at the controller's terminal. The shell answered:

zsh: command not found: mesh-controller

The same day, read through the mesh's tools: the controller runs on the control-node as the unit mesh-controller.service, which the mesh declared and wrote (the control-node's node-service-manager.status: active, running, FragmentPath /etc/systemd/system/mesh-controller.service, mesh_declared true).

Why it is an issue

The records name a command that does not exist. Issue 339, issue 340, ADR 0266 (hq pull request 225, not yet merged) and the agent module's README say that certain changes are made "at the controller's terminal" alone, and some give the line to type, such as "mesh-controller settings set claude-code '<json>'" and "mesh-controller node agent-account <node> <account>". None of them says how the operator reaches that terminal, and nothing in the mesh provides it:

  • The controller is a mesh process. The node-engine unpacks its bundle under the mesh's own directory and writes a unit that runs it as the mesh-controller account, with an environment composed from the controller's module: the files holding its stores' credentials, under a directory only that account may enter, and the ports of the store and the bus as the mesh resolved them. No module puts a command on any PATH.
  • Run by hand, the binary needs that account and that environment, rebuilt by hand under sudo. That is a work-around, and the operator rejects it.
  • In the controller's code the terminal is only a negative: a command line that did not come through a verb (no MESH_VERB). Nothing says who the terminal is.

Impact on the operator. Every terminal-only change waits: the agent module's managed settings, tool servers and shared text (issue 340's steps), the places and accesses of issue 339, and a node's agent account (ADR 0266). The refusals the controller gives through a verb send the operator to a terminal they cannot open.

Acceptance test (the operator's view)

On the control-node, in my own shell and without sudo, I type nox settings set zsh '{"execute":"withhold"}' --node <node> (or any other command line) and it runs against the live controller as the terminal. On any other node the same terminal-only line is refused and says why. An agent session cannot use it to get round a terminal-only refusal: as agent on the control-node it is refused, and on a node where agents run as the operator that account is not the terminal.

The fix

ADR 0272 (accepted 2026-10-09): a module mesh-cli on every node places /usr/local/bin/mesh-cli, with the alias nox in interactive zsh. It asks the node-engine over a local socket; the node-engine reads the account from the kernel and asks the controller on its own node's subject; the controller runs the line as the terminal for the control-node's operator account, and as an ordinary call for every other account and node. The diagnosis says what was read and what each repository does.

How it will be checked

The checks ADR 0272 lists, and the acceptance test above, run live on the control-node and on one other node.