Files
hq/04-ISSUES/049-a-module-can-serve-tools-and-nothing-can-call-them/00-report.md
T
jschoubben 0aa8f62e0c Issue 049 — a module serves tools and nothing may call them
A module's broker account is scoped to what it declares it emits and consumes. A
tool call needs a reply queue, which that scope does not cover and should not. So
the account is right, the request is reasonable, and no account exists that can
make it — asking a module its own question, from its own container, with its own
credential, is refused.

It matters because a module's tools are its operator-facing surface: the
catalogue serves the five questions it exists to answer and nothing can reach
them. It is also why a running module keeps being mistaken for a working one — a
test that cannot ask anything checks a container is up, and that substitution has
hidden two faults this week.

Claude-Session: https://claude.ai/code/session_01D6qtiYU3P9jk3pnAXyAFyx
2026-09-14 22:08:40 +02:00

3.4 KiB

status, opened, located-in, fixed-by, amended-design
status opened located-in fixed-by amended-design
open 2026-09-14

049 — A module can serve tools, and nothing is allowed to call them

Symptom

A module serves tools over the broker. Asking it one, from inside that same module's own container, using its own credential, is refused:

Error: Channel closed by server: 403 (ACCESS-REFUSED) with message
"ACCESS_REFUSED - User '<node>-<module>' doesn't have permissions to queue 'amq.gen-...'"

A module's broker account is scoped to what it declares it emits and consumes. A tool call is a request and a reply, and the reply arrives on a temporary queue the caller creates — which that scope does not cover, and should not: a module that only publishes events has no business declaring queues.

So the account is right and the request is reasonable, and there is no account that can make it.

Why this matters

A module's tools are its operator-facing surface, and nothing can reach it. The catalogue serves five: what this mesh holds, what a module is made of, what provides a given provision, what depends on a module, and what is stale. Those are the questions the catalogue exists to answer, and today the answer to "how does anyone ask one" is that they run a container joined to the broker's network namespace and authenticate as the substrate's bootstrap admin.

It is why a running module gets mistaken for a working one. A test that cannot ask a module anything checks that its container is up, and a container being up is not a claim about function. That substitution has now hidden two separate faults in one week — a crash-looping runtime beside a healthy container of a similar name, and a catalogue that was never installed at all.

The mesh already has the shape for this. An account scoped to a purpose, minted by the mesh and sealed to a holder, is exactly what provisioning does. What is missing is the recognition that asking is a use of a module, the way pulling is a use of the artifact store (042) rather than something that happens beneath it.

Evidence

The refusal above, from a module invoking its own tool with the credential the mesh gave it. The working alternative, which is the measure of the gap:

docker run --rm --network container:<the broker> \
  -e MESH_BROKER_URL=amqp://<bootstrap admin>@127.0.0.1:<port>/ \
  <the module's image> invoke <module> <tool> '{}'

That is the bootstrap credential, host-local, with no scope at all. It works, and nothing about it should be how a mesh is asked a question.

Open questions

  • Who is the caller? An operator at a terminal, an agent acting for one, and another module are three different holders with three different scopes, and only the last resembles anything the mesh mints today.
  • Should calling be a grant like any other — a module declares it may be asked, and a consumer is issued an account that may create a reply queue and publish to that module's request queue?
  • Should the control plane be the way in? It holds an admin connection already, and a mesh-control subcommand for asking a module a question would need no new account — at the cost of routing every question through one process and its privileges.
  • What does a module declare about being asked? Serving a tool is already declared. Whether it may be asked by anyone who can reach the broker, or only by named holders, is not.