As-is 13: fix five review findings on the mesh MCP server (issue 1008, review round 1)
node-tools still has a manifest (invokes *, waits, the mcp-endpoint provision) — describe it in prose instead of saying it has none. The TypeScript sources remain on main; only the built artifact is Go. The mesh-controller seat answers 63 verbs as its own runtime, not 60-93 per node (that is node-tools' own node-scoped seat verbs). Prefer reading mesh_overview live over a count that drifts. An as-is document amends nothing — reworded accordingly.
This commit is contained in:
@@ -26,12 +26,20 @@ module of that name.
|
|||||||
**The tool runner is one of the mesh's core components**, named `node-tools` beside
|
**The tool runner is one of the mesh's core components**, named `node-tools` beside
|
||||||
`mesh-controller`, `mesh-host` (the node-engine) and `nats` (the bus) — the mesh's own repositories'
|
`mesh-controller`, `mesh-host` (the node-engine) and `nats` (the bus) — the mesh's own repositories'
|
||||||
check treats the four the same way, as the core whose health the mesh itself defines rather than a
|
check treats the four the same way, as the core whose health the mesh itself defines rather than a
|
||||||
module's own. It is not a catalogue module: it has no manifest, is not assigned or unassigned, and
|
module's own. `mesh-host` and `mesh-controller` supervise, compose and account for it as a core
|
||||||
carries no `invokes` grant of its own in a manifest, because there is no manifest. Its code lives
|
process rather than as an ordinary assignment (`ComponentNodeTools`/`BusNodeTools` in both, the
|
||||||
under `node-tools/` in the `mesh-tools` repository (`internal/console`, `internal/announce`,
|
witness and lease code that restarts and rolls it back, the account named `<node>.node-tools` on
|
||||||
`internal/bus`), and `mesh-host` and `mesh-controller` supervise, compose and account for it as a
|
the bus).
|
||||||
core process rather than as an assignment (`ComponentNodeTools`/`BusNodeTools` in both, the witness
|
|
||||||
and lease code that restarts and rolls it back, the account named `<node>.node-tools` on the bus).
|
**It still carries a manifest, `node-tools/module.json` in `mesh-tools`,** and that manifest is
|
||||||
|
where its grants live: `invokes` names `*`, so its account may call every tool on the mesh;
|
||||||
|
`waits` names the five event families `mesh_wait` may subscribe to (the knowledge base's reviews,
|
||||||
|
mesh-delivery's transitions, the forge's status, the controller's checked event, and the operator
|
||||||
|
channel's decision for the agent module) — the bus refuses a subscription outside this list
|
||||||
|
(ADR 0367 §2); and it
|
||||||
|
`provides` one provision, the MCP endpoint, at node scope, and `listens` on the port it serves from,
|
||||||
|
opened only to the machine itself. Its code lives under `node-tools/` in the `mesh-tools`
|
||||||
|
repository (`internal/console`, `internal/announce`, `internal/bus`).
|
||||||
|
|
||||||
**One runtime per node, run by the node-engine as a sibling process, never a container**
|
**One runtime per node, run by the node-engine as a sibling process, never a container**
|
||||||
(ADR 0175). It holds the node's one bus credential and may call every tool on the mesh; its account
|
(ADR 0175). It holds the node's one bus credential and may call every tool on the mesh; its account
|
||||||
@@ -48,9 +56,11 @@ body per request, no session and no event stream (`node-tools/internal/console/m
|
|||||||
|
|
||||||
**It announces seven tools, not five** (ADR 0195, extended by ADR 0367): `mesh_overview`,
|
**It announces seven tools, not five** (ADR 0195, extended by ADR 0367): `mesh_overview`,
|
||||||
`mesh_machine`, `mesh_search`, `mesh_describe`, `mesh_call`, `mesh_runtimes` and `mesh_wait`. The
|
`mesh_machine`, `mesh_search`, `mesh_describe`, `mesh_call`, `mesh_runtimes` and `mesh_wait`. The
|
||||||
handshake's `instructions` text names all seven and the four address forms; measured live, the four
|
handshake's `instructions` text names all seven and the four address forms. `mesh_overview` is
|
||||||
nodes' tool runners between them answer for 103 modules and 645 tools this way, with two module
|
where the mesh-wide count of modules and tools is read live — a number copied into this document
|
||||||
instances (`route-proxy` on two of the nodes) named as not answering rather than silently absent.
|
would drift; asked on 2026-10-17 it answered 103 modules and 645 tools across the whole mesh, with
|
||||||
|
two module instances (`route-proxy` on two of the nodes) named as not answering rather than silently
|
||||||
|
absent.
|
||||||
|
|
||||||
**Addresses, exactly as the handshake states them:** `<seat>.<verb>` for a seat held once for the
|
**Addresses, exactly as the handshake states them:** `<seat>.<verb>` for a seat held once for the
|
||||||
mesh (`mesh-controller.status`); `<node>/<seat>.<verb>` for a seat every machine holds
|
mesh (`mesh-controller.status`); `<node>/<seat>.<verb>` for a seat every machine holds
|
||||||
@@ -74,7 +84,7 @@ answering in under 100ms for hundreds of kilobytes of discovery.
|
|||||||
**The seventh tool, added by ADR 0367**, lets a session wait on the bus for an event instead of
|
**The seventh tool, added by ADR 0367**, lets a session wait on the bus for an event instead of
|
||||||
polling: a call names one or more granted event families and an optional filter, and either answers
|
polling: a call names one or more granted event families and an optional filter, and either answers
|
||||||
the first match or says it timed out. The tool runner's own bus account hears only the families its
|
the first match or says it timed out. The tool runner's own bus account hears only the families its
|
||||||
manifest-equivalent grant names; an event it hears is never taken as the state — a session reads the
|
manifest's `waits` list names; an event it hears is never taken as the state — a session reads the
|
||||||
state from the verb that owns it once woken. It is meant to be called in a loop from a background
|
state from the verb that owns it once woken. It is meant to be called in a loop from a background
|
||||||
command, not inline, because one call blocks until it answers or times out.
|
command, not inline, because one call blocks until it answers or times out.
|
||||||
|
|
||||||
@@ -82,32 +92,41 @@ command, not inline, because one call blocks until it answers or times out.
|
|||||||
|
|
||||||
**These already answer directly, not as a stated future.** Beside every assigned module's tools,
|
**These already answer directly, not as a stated future.** Beside every assigned module's tools,
|
||||||
the tool runner asks the `mesh-controller` seat for its own verbs the same way (ADR 0154): measured
|
the tool runner asks the `mesh-controller` seat for its own verbs the same way (ADR 0154): measured
|
||||||
live, that seat answers between 60 and 93 verbs per node (`status`, `push`, `assign`, `build`,
|
live, the mesh-controller runtime is one instance, mesh-wide, and it answers 63 verbs for that one
|
||||||
`artifacts` and the rest), and the `mesh-controller` *module* answers none of its own — it serves no
|
seat (`status`, `push`, `assign`, `build`, `artifacts` and the rest), and the `mesh-controller`
|
||||||
module tools, only its seat's, exactly as design 33 described while it was still only designed.
|
*module* answers none of its own — it serves no module tools, only its seat's, exactly as design 33
|
||||||
|
described while it was still only designed. The 56-to-93 seat-verb counts each node's tool runner
|
||||||
|
answers (below) are a different thing: the tool runner serves the verbs of whichever node-scoped
|
||||||
|
seats are held on that node (`node-backup`, `node-build-agent`, `node-service-manager` among them),
|
||||||
|
on behalf of the modules holding them, not the mesh-controller seat's — that one is served by the
|
||||||
|
mesh-controller runtime itself, a separate process, and the tool runner only asks it and relays what
|
||||||
|
it answers.
|
||||||
|
|
||||||
## Where it runs
|
## Where it runs
|
||||||
|
|
||||||
**Every node, not a per-operator assignment.** Measured live: all four of the mesh's machines
|
**Every node, not a per-operator assignment.** Measured live: all four of the mesh's machines
|
||||||
answer a `node-tools` runtime, each with its own module and tool count (between 294 and 312 tools,
|
answer a `node-tools` runtime, each with its own module and tool count (between 294 and 312 tools,
|
||||||
56 to 93 seat verbs, in this reading). This is a fact that shipped past the design it came from: the
|
56 to 93 seat verbs, in this reading). This is a fact that shipped past the design it came from: the
|
||||||
to-be document this amends still describes it as assigned to "whichever machines an operator sits
|
to-be document still describes it as assigned to "whichever machines an operator sits at"; what
|
||||||
at"; what actually runs is the opposite — every node the mesh holds carries one, because it is core
|
actually runs is the opposite — every node the mesh holds carries one, because it is core
|
||||||
infrastructure the mesh itself depends on (discovery, the controller's own verbs, every module's
|
infrastructure the mesh itself depends on (discovery, the controller's own verbs, every module's
|
||||||
tools), not a convenience assigned to a workstation. There is accordingly no assign or unassign verb
|
tools), not a convenience assigned to a workstation. There is accordingly no assign or unassign verb
|
||||||
for it: removing it from a node is not an operation the controller or the catalogue exposes.
|
for it: removing it from a node is not an operation the controller or the catalogue exposes.
|
||||||
|
|
||||||
## What this repository's prior text got wrong
|
## What this repository's prior text got wrong
|
||||||
|
|
||||||
The document this replaces described `mesh-console` as a catalogue module with an `invokes: ["*"]`
|
The document this replaces described `mesh-console` as a catalogue module served by a container and
|
||||||
manifest, served by a container, assigned only to workstations, and implemented in TypeScript
|
assigned only to workstations. That module and its container are gone; the manifest is not — it
|
||||||
(`mesh-tools src/mesh.ts`, `src/http.ts`, `src/runtime.ts`). None of that is true of what runs today:
|
moved to `node-tools/module.json`, still declares `invokes: ["*"]`, and gained `waits` and the
|
||||||
the container, the manifest, the per-workstation assignment and the TypeScript implementation are
|
`mcp-endpoint` provision, described above. What also moved is which language builds it: the
|
||||||
all gone, replaced in substance by ADR 0175's host-side, module-agnostic, Go runtime described
|
manifest's `build.artifacts` names a Go binary built from `cmd/node-tools`, and that is what a node
|
||||||
above. The quirks it recorded from the `mesh-console` era (a module registered by hand recording its
|
runs. The repository still carries the earlier TypeScript sources (`node-tools/src/mesh.ts`,
|
||||||
source as a URL; a *record*-policy module staying listed as not-answering until its rebuilt runtime
|
`http.ts`, `runtime.ts`, `announce.ts`, `broker-nats.ts`, `client.ts`, `launch.ts`, `main.ts`,
|
||||||
is pushed) are not re-checked here: they were about the `mesh-console` container's registration path,
|
`mcp.ts`) on main, but the manifest does not build from them. The quirks the prior text recorded
|
||||||
which no longer exists.
|
from the `mesh-console` era (a module registered by hand recording its source as a URL; a
|
||||||
|
*record*-policy module staying listed as not-answering until its rebuilt runtime is pushed) are not
|
||||||
|
re-checked here: they were about the `mesh-console` container's registration path, which no longer
|
||||||
|
exists.
|
||||||
|
|
||||||
## How it is checked
|
## How it is checked
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user