5.4 KiB
topic, status, date, deciders, reconstructed, extends
| topic | status | date | deciders | reconstructed | extends |
|---|---|---|---|---|---|
| what runs on it | accepted | 2026-10-03 | jochen | false | 02-DECISIONS/0152-the-operators-surface-is-a-module-the-console.md |
195. The mesh's tools are found by address, not announced whole
Context
The console answers MCP on a machine's loopback (ADR 0152, to-be 34) and announces, at a session's start, every tool the mesh can say it has: 228 on 2026-10-03, 110 KB, taken once. Three things are wrong with that, measured in research 021:
- Size. Only one client's habit of deferring long lists keeps them out of the model's context.
- Ambiguity. A module on two machines is listed once,
nodeoptional, whichever answers — for postgres and mssql, whose instances hold different data, a call that names no machine asks an arbitrary one. - Staleness. A tool that arrives after the session started is not listed until it reconnects.
The mesh already has the structure a caller needs: seats held once for the mesh, seats held once per machine (ADR 0159), and modules assigned to machines, each assignment issued its own subjects (ADR 0160). The operator's direction: tools are discoverable, in layers, and asking novox's postgres is not asking ace's.
Considered Options
- Keep the flat list and rely on the client. Rejected: the ambiguity and the staleness stay, and it is one client's behaviour.
- One tool per assignment, the machine in the name. Rejected: the list multiplies, and an address in
a tool's name meets the API's limit — letters, digits,
_and-, at most 64 characters. - A fixed handful of tools that walk the mesh's structure, the address an argument. Chosen.
- MCP resources or prompts. Rejected: unevenly supported, and an agent acts through tools.
Decision
1. Everything the mesh answers has one address, by the layer it lives in:
| layer | address | answered by |
|---|---|---|
| a seat held once for the mesh | <seat>.<verb> |
that seat's holder |
| a seat held once per machine | <node>/<seat>.<verb> |
that machine's holder |
| a module assigned to a machine | <node>/<module>.<tool> |
that assignment |
| a module whose instances are interchangeable (ADR 0160) | <module>.<tool> as well |
any of them |
A call to a module that is not interchangeable names its machine, or is refused naming the machines it runs on. "Whichever answers" is no longer an answer for state a machine holds.
2. The console announces a fixed set of tools, not the catalogue:
mesh_overview— the mesh's seats with their verbs, and its machines;mesh_machine— one machine: the node seats it holds and the modules assigned to it, each with its tools by name;mesh_search— words in, matching addresses out with one line each, across every layer;mesh_describe— one address in, its description and argument schema out;mesh_call— an address and its arguments in, the answer out, with the machine that gave it.
Each is answered from the mesh when it is asked, so a tool that arrived a minute ago is found without the client reconnecting. The names are the API's kind of name; addresses never have to be.
3. The flat catalogue stays reachable, not announced: the mesh client and a console setting can
still list it whole, for a person reading it or a client that wants it. An agent pointed at the console
sees the five.
Consequences
- An agent spends a call or two finding a tool it does not know, and none on one it does; the context no longer carries 110 KB it mostly never uses.
- The ambiguity is closed by the address, not by a description asking the agent to remember
node. - What got harder: an agent that once saw a tool's schema up front now asks for it.
mesh_describeandmesh_searchanswering with the schema of a close match keep that to one call. - The discovery verbs are the console's; the mesh's own records — seats, machines, assignments — are the controller's, and the console asks it rather than keeping a copy.
How it is checked
| Rule | Checked by |
|---|---|
| The console announces five tools | the console's test: tools/list answers exactly the five |
| An address resolves to one subject per layer | the console's tests: a mesh seat, a node seat, an assignment, an interchangeable module, each called by address over a real bus |
| A non-interchangeable module without a machine is refused, naming its machines | the same tests |
| A tool that arrives after the session started is found | a test registering a module after the console's first answer and finding it by mesh_search |
| Live | from a fresh session, which databases does novox's postgres hold is answered by novox's postgres, found through the five |