diff --git a/04-ISSUES/229-a-rollout-cannot-be-followed-through-the-meshs-tools/00-report.md b/04-ISSUES/229-a-rollout-cannot-be-followed-through-the-meshs-tools/00-report.md new file mode 100644 index 0000000..88b243d --- /dev/null +++ b/04-ISSUES/229-a-rollout-cannot-be-followed-through-the-meshs-tools/00-report.md @@ -0,0 +1,49 @@ +--- +status: open +opened: 2026-10-04 +located-in: [] +fixed-by: +amended-design: +--- + +# 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. Three 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. + +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](../../02-DECISIONS/0154-the-meshs-own-verbs-are-the-controller-seats-tools.md) +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. + +How each is checked belongs to the record that settles it.