51 lines
3.5 KiB
Markdown
51 lines
3.5 KiB
Markdown
---
|
|
status: resolved
|
|
opened: 2026-10-01
|
|
located-in: [mesh-tools src/broker-nats.ts (one subject, one queue group per module), mesh-tools src/mcp.ts (no way to name a machine), mesh-tools src/runtime.ts (a claimed seat's verbs served by nobody), mesh-controller internal/broker/nats.go (the grant for a tool named one subject)]
|
|
fixed-by: mesh-tools PR (feat/a-tool-call-names-the-machine) and mesh-controller PR (same branch) — see ADR 0159; the store seat's verbs and postgres's tools follow in the catalogue
|
|
amended-design: [03-DESIGN/01-to-be/33-the-tools-the-mesh-answers.md, 03-DESIGN/01-to-be/34-the-console.md]
|
|
---
|
|
|
|
# 182 — A tool call reaches whichever instance answers first, and a claimed seat's verbs are served by nobody
|
|
|
|
## What was observed
|
|
|
|
Asked how to list the databases of the store on one machine, the mesh had no answer. A module's tools
|
|
are served on one subject per module, `mesh.mod.<module>.tool.<name>`, and every instance of the
|
|
module joins one queue group on it, so a call to the database engine's tool while it runs on two
|
|
machines reaches whichever answered first, and the answer does not say which. There is no way to ask
|
|
the instance on one machine. The console lists the tool once and offers no machine.
|
|
|
|
And the seat half was missing too. Design 33 §3 says holding a seat means serving its tools, and
|
|
ADR 0154 built that for the controller's own seat alone. A module that holds a seat — the database
|
|
engine on the control node holding `mesh-store` — served none of the seat's verbs, because no seat
|
|
but the controller's declares any and no runtime knew which seats its module claimed.
|
|
|
|
## Why this is here
|
|
|
|
Both are the same omission: the tool surface was built as if every module ran on one machine and
|
|
held no seat. A queue group is the right default for a stateless module answering anywhere, and the
|
|
wrong only choice for a module whose instances are different things — two stores with different
|
|
databases. The architecture had the distinction: a module is a thing that runs on machines, a seat is
|
|
a role one of them holds. The tool surface did not carry it.
|
|
|
|
## Resolved, 2026-10-01
|
|
|
|
[ADR 0159](../../02-DECISIONS/0159-a-tool-call-names-the-machine-and-a-holder-serves-its-seats-verbs.md).
|
|
Every instance serves its module's subject twice: in the queue group as before, and with its own
|
|
machine as the subject's last token. `<module>.<tool>@<node>` reaches one machine's instance; the
|
|
console lists `node` on every module tool and puts it in the subject, never in the module's
|
|
arguments; every answer carries the machine that gave it, and the console appends it as its own line.
|
|
The grant for a tool covers both subjects.
|
|
|
|
A holder's runtime serves its seat's verbs: the credential the mesh writes names the seats the module
|
|
claims and the verbs each promises, the runtime serves each verb with the module's tool of the same
|
|
name on the seat's own subject, flat for a mesh seat and with the machine for a node-scoped one, and
|
|
the bus admits the subscription only where the module holds the seat. The store seat's first verbs
|
|
and the database engine's tools for them are the catalogue's next step, recorded in the decision.
|
|
|
|
*How it is checked:* against a real bus, a module on two machines answers each by name and says who
|
|
answered when unnamed, and a claimant answers a seat's verb on the seat's subject; the console lists
|
|
`node` on a module's tool and not on a seat's; the grant for a tool covers both subjects; and, live,
|
|
the store's databases listed from one named machine through the console.
|