Files
hq/03-DESIGN/01-to-be/34-the-console.md
T
jschoubben ad4a5ea004 ADR 0152: the operator's surface is a module, the console
The work order's group-3 question answered: an ordinary module the mesh assigns to the machine a
person sits at, holding a minted credential, calling tools under a manifest grant (invokes), serving
MCP on loopback. Design 34; pointers in 33, 25 and 0095; module check designed into 12 (issue 148);
README stops claiming an indexing nothing provides (issue 006).
2026-09-30 16:08:52 +02:00

7.2 KiB

layer, status, code, updated, decisions
layer status code updated decisions
to-be in-progress
mesh-catalog
mesh-tools
mesh-controller
2026-09-30
02-DECISIONS/0152-the-operators-surface-is-a-module-the-console.md
02-DECISIONS/0132-a-seat-carries-the-tools-its-holder-must-serve.md
02-DECISIONS/0095-the-control-plane-is-the-way-to-ask-a-module.md
02-DECISIONS/0035-one-implementation-several-surfaces.md
02-DECISIONS/0034-the-local-account-owns-the-mesh.md

34 — The console

The mesh's tools, on the machine a person sits at, served by a module the mesh assigned there. An agent reaches them over MCP on the machine's loopback; a person reaches the same endpoint. Nothing is installed by hand, nothing is configured with an address, and the mesh knows the surface exists because it put it there (ADR 0152).

1. What it is

A module, mesh-console, in the catalogue. Its image is the tool runtime's own — the client that already speaks the bus as a command line and as an MCP server — started in a mode that reads the module's credential and listens on loopback. It has no state, no provision, no seat. What it needs is the bus, which it gets the way every module does: a credential the mesh minted for <node>.mesh-console, sealed to the machine, delivered as the module's own secret.

Its manifest says three things nothing else in the catalogue says together:

  • invokes: ["*"] — it calls every tool on the mesh, and the bus grants exactly that publish side;
  • listens on a port from: machine — the filter opens nothing for it, because loopback is not outside;
  • no emits, no consumes, no tools — it answers nothing on the bus and nobody can address it there.

2. What it serves, and to whom

One endpoint, POST /mcp on the machine's loopback, speaking MCP over HTTP: initialize, tools/list, tools/call. An agent on the machine is pointed at it once — the address is the machine's own and never changes — and sees every tool the mesh can say it has. A person at a terminal uses the same endpoint through the mesh client, or through anything that can make an HTTP request; the client needs no credential, because the console holds it.

The endpoint is the machine's login. It binds 127.0.0.1 and nothing else. Whoever can connect is on the machine, and whoever is on the machine is the account that owns the mesh there (ADR 0034, ADR 0144). There is no token, no login page and no second identity, on purpose: a credential a person had to carry to reach their own machine's console would be the arrangement this replaces, moved one hop.

3. How it knows what the mesh can do

Design 33 §5 splits discovery in two: a role's tools are read from the mesh's records, a module's own are asked of the module. The console builds the second half now and reads the first when it exists.

Every tool runtime answers tools. The runtime that serves a module's tools also serves one verb of its own under that module's name, mesh.mod.<module>.tool.tools, answering the module's tool names, descriptions and argument schemas — the definitions from the code that answers them, and from nowhere else. A module may not name a tool of its own tools; the runtime refuses the collision at load.

The console asks the catalogue which modules the mesh holds, then asks each. catalog_modules answers the roster; one tools request per module, in parallel, answers the list. The bus refuses at once a request nothing serves, so a module that is not running costs nothing and is named in the answer as not answering, rather than silently absent — silence and success must never look alike. The list is kept for a short while and refreshed, so an agent asking on every turn does not fan out on every turn.

A tool that was not listed can still be called. Listing is discovery; calling is the grant. An agent that knows a tool's name asks for it by <module>.<tool> and the module answers or the bus says why not.

What is missing from the list, and until when. A role's tools and the mesh's own verbs — status, push, assign — are the mesh-controller seat's under ADR 0132 and are not served yet; their three prerequisites are listed in that record. When the seat serves them, the console lists them beside the modules' own, and the person stops opening a shell for the mesh's own questions. Until then the console says so in its handshake.

4. Where it runs

On whichever machines an operator sits at, by assignment. It is not on the control node by default and does not need to be: it reaches the bus like any module, from anywhere in the mesh. A machine that is not a node cannot have it, which is the right refusal — the mesh reaches what it declares, and a workstation that wants the console joins first.

The person's credential and the mesh client (design 25 §7) remain the path for a machine that is not a node, and the path to a mesh not yet far enough along to assign anything.

5. Removing it

Unassigning the console from a machine revokes its bus account at the next composition and stops the container; nothing is left on the machine that could still connect. An agent pointed at the loopback address gets a refused connection, which is the truthful answer.

How it is checked

Check Defends
a module invoking one tool may publish that subject and no other tool's; * may publish every one; neither may publish an event or subscribe what it did not consume ADR 0152, the grant
a module registering two tools answers three names to tools, with schemas; a module naming its own tools is refused at load ADR 0152, discovery
against a real bus: two modules up, a third held and not running — the console lists the two and names the third as not answering ADR 0152, silence is not success
a call through the console's endpoint reaches a module over the bus and the answer is the module's own, unshaped ADR 0035, a surface decides nothing
on the live mesh: the console assigned to a workstation answers tools/list on loopback and a call to the forge returns repositories the exit of work-order step 3
the composed filter for a machine carrying the console opens no port for it ADR 0144

What this does not settle

  • Narrowing a console's grant per assignment. ADR 0046 makes it a setting; nothing reads one yet.
  • The mesh's own verbs on the bus. Design 33's third family; this document only says where they appear once they exist.
  • A person's identity behind the console. The mesh sees the console's account; design 15 keeps the question open.

References