Files
hq/04-ISSUES/229-a-rollout-cannot-be-followed-through-the-meshs-tools/00-report.md
T

3.7 KiB

status, opened, located-in, fixed-by, amended-design
status opened located-in fixed-by amended-design
open 2026-10-04

229 — A rollout cannot be followed through the mesh's tools, so an agent goes round them

What was observed

2026-10-04, rolling out to-be 41. An agent drove the rollout through the mesh's MCP tools: the controller seat's status, plans, command, and the forge's merge. Four times it left those tools and posted JSON-RPC by hand to the node console's HTTP endpoint with curl:

  1. To wait for a plan. plans answers once, with prose. Nothing waits for a plan to reach a tier, finish or fail. An agent's tools cannot be called from a shell loop, so the only way to be told when a plan moved was a background curl loop polling the console every twenty seconds and matching the plan's line with grep.
  2. To read status. status answers a paragraph of prose (the bus's user list), then a JSON document, both inside one string. Picking out behind, waiting and reported took a script that cut the string at the first brace and parsed the rest.
  3. To read one module out of module list, whose output was too long to read whole for one line.
  4. To call a tool that arrived after the agent's session began. The modules rolled out in that same session added node-login-shell.execute and zsh.zsh_config to one machine. The agent's MCP connection had been opened before the console moved to discovery (ADR 0195). It still held the flat catalogue the console announced then, which lacks both the new verbs and the five discovery tools (mesh_call among them) the console announces now. Clearing a session does not reconnect its MCP servers, and the console never sends a list-changed notice, so nothing told the client its list was stale. The agent posted mesh_machine and mesh_call by hand. Reconnecting the server would have given it the discovery tools, which reach any tool by address the moment it exists.

The calls were authorised, because the console is the operator's own surface. But each is a raw call the mesh's tools were meant to make unnecessary (ADR 0154 puts the controller's verbs behind the seat). Each is also a script that breaks silently when a sentence in the prose changes.

Why it matters beyond this instance

Every rollout an agent drives has the same shape: merge, wait for a plan, push, wait for reports, check status. When the tools answer only once and only in prose, every agent writes its own poller and its own parser. Those are invisible to review, different each time, and wrong the first time the wording moves. An agent that cannot wait also tends to act early, which is the opposite of what a rollout needs.

What a fix has to settle

  • A way to wait on the mesh's own progress. For example, plans and status could take a plan or node and a bound, and answer when it moves or the bound passes. Or a verb could follow one plan to its end.
  • Structured answers from the controller's verbs, with the prose as a field beside the data, not around it.
  • Whether command's generic answer should take a filter, or whether the verbs it is used for most (module list, node show) deserve verbs of their own.
  • A client is told when the console's own surface changes. The console announces listChanged and sends the notice when what it lists changes, for example after an upgrade that changes its tools. A long-running session then never keeps a list the console no longer serves. Discovery already makes every module's tools reachable without the list changing.

How each is checked belongs to the record that settles it.