4.8 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/0195-the-meshs-tools-are-found-by-address-not-announced-whole.md |
197. Every tool announces itself on the bus, in the NATS services protocol
Context
ADR 0195 gave every tool an
address and the console five tools to find them. Where the console learns what exists, it inherited
from to-be 34 §3: ask the catalogue for its roster, ask
each module on the roster for its tools, and read the machines and assignments from the
controller's printed node list and module list. Built that way on 2026-10-03, it worked and showed
what is wrong with it:
- It asks what should exist and infers what does. The roster holds every module the catalogue ever registered; 47 of them were reported "not answering" on 2026-10-03, most with no tools at all and several retired.
- It parses prose. Two of the controller's answers are text for a person, and a reworded column breaks discovery.
The bus already knows what answers. NATS has a services protocol for exactly this: a service answers
$SRV.PING and $SRV.INFO — every instance, on one request — with its name, its instance, and every
endpoint's subject and metadata, in a published format the NATS tools read. The operator's direction:
every tool announces itself; the mesh has the full picture, so nothing should be inferred or parsed.
Considered Options
- Keep asking the roster, and give the controller JSON answers. Fixes the parsing, keeps the inference.
- Re-serve every tool through a NATS services library. The announcement for free, but every runtime's serving path rewritten around a library, in two languages, for no change in behaviour.
- Every runtime answers the services protocol's discovery subjects with what it serves; serving is unchanged. Chosen.
Decision
1. What answers announces itself. Every runtime that serves tools — each machine's tool runtime,
the per-module runtimes still in containers, and the controller for the seat it holds — answers
$SRV.PING and $SRV.INFO in the NATS services format: one service per module or seat it serves,
named for it, its instance the machine; one endpoint per tool, its subject and queue exactly as
served, its metadata the tool's description, argument schema, the machine, the seat and scope where
it is a seat's verb, and whether the module's instances are interchangeable.
2. The console finds what exists by asking the bus, one $SRV.INFO request, every answer
gathered for a short window. What it announces through ADR 0195's five tools is what answered.
3. What should exist is the mesh's records, read as data. The controller answers its machines and modules as JSON, and says which modules declare tools; the console names as not answering only an assignment that declares tools and did not announce them. A module with no tools is never listed.
4. The grants say so. Every principal that serves tools may subscribe the services discovery subjects for what it serves; the console's and every runtime's account may publish the discovery request. Replies travel to the asker's own inbox as every reply does.
Consequences
- The standard
nats micro listandnats micro infoshow the mesh's tools, live, to anybody holding a credential — the bus's own view, not the mesh's description of it. - Discovery costs one request and a gathering window, not one request per roster entry.
- What got harder: three runtimes must answer the same format the same way — the Go tool runtime, the TypeScript runtime the containers still run, and the controller. The format is NATS's, so a test reads all three with the NATS services client and nothing of the mesh's.
How it is checked
| Rule | Checked by |
|---|---|
| A runtime announces exactly what it serves | each runtime's test: $SRV.INFO answered with one service per served module or seat, its endpoints' subjects the subjects served |
| The format is NATS's | the same tests read the answer with the NATS services client's own types |
| A module with no tools is never listed; an assignment with tools that did not answer is | the console's test, against controller records with both |
| Nothing is parsed from prose | the console reads only JSON answers (code review; the text parsers are deleted) |
| Live | nats micro list against the mesh's bus lists every machine's tool runtime and the controller |