ADR 0095: the control plane is the way to ask a module; issue 049 resolved; design 19 amended
This commit is contained in:
@@ -0,0 +1,60 @@
|
|||||||
|
---
|
||||||
|
topic: the tiers
|
||||||
|
status: accepted
|
||||||
|
date: 2026-09-21
|
||||||
|
deciders: jochen
|
||||||
|
reconstructed: false
|
||||||
|
extends: 02-DECISIONS/0047-a-module-runs-its-code-as-its-own-process-with-its-own-account.md
|
||||||
|
---
|
||||||
|
|
||||||
|
# 95. The control plane is the way to ask a module
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
A module serves tools over the broker under an account scoped to what it emits, consumes and
|
||||||
|
serves ([ADR 0047](0047-a-module-runs-its-code-as-its-own-process-with-its-own-account.md)). A
|
||||||
|
tool call is a request and a reply: the caller creates a reply queue and publishes to the serving
|
||||||
|
module's request key, and no module's scope grants either — nor should it, since a module that
|
||||||
|
only publishes events has no business declaring queues. So a module could serve tools and nothing
|
||||||
|
in the mesh could call them
|
||||||
|
([issue 049](../04-ISSUES/049-a-module-can-serve-tools-and-nothing-can-call-them/00-report.md)):
|
||||||
|
not an operator at a terminal, not an agent acting for one.
|
||||||
|
|
||||||
|
## Considered Options
|
||||||
|
|
||||||
|
1. **Calling is a grant**: 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 key. Deferred: a
|
||||||
|
module-to-module call is the only caller that resembles what the mesh mints today, and none
|
||||||
|
asks for one yet.
|
||||||
|
2. **The control plane is the way in.** Adopted. It holds a connection that may already, so a
|
||||||
|
person or an agent asks through it, and every question passes one process — which is where
|
||||||
|
an audit of who asked what belongs.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
`mesh-controller ask <module> <tool> [json]` publishes the request on the tool exchange under
|
||||||
|
`<module>.<tool>`, with a private reply queue bound under its own name, waits for the answer
|
||||||
|
whose correlation matches, and prints it as the module gave it. A tool that answered with an
|
||||||
|
error has answered: the answer is printed and the exit status says so. A module that never
|
||||||
|
answers is said to have not answered, with where to look.
|
||||||
|
|
||||||
|
A module declares nothing about being asked: serving a tool is being askable through the control
|
||||||
|
plane. A module-to-module call, if one is wanted, is a grant like any other and a later decision.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
Anything with the control plane in reach can ask any module anything it serves. What got
|
||||||
|
harder: nothing outside the control plane can, and the control plane's connection is one more
|
||||||
|
thing on the path of every question — a cost accepted for the audit it buys.
|
||||||
|
|
||||||
|
## How it is checked
|
||||||
|
|
||||||
|
A tools-only bed asks a served tool through the control plane and asserts an answer arrived —
|
||||||
|
an error, since the lab has no upstream and no token, which is an answer where a timeout would
|
||||||
|
not be.
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [issue 049](../04-ISSUES/049-a-module-can-serve-tools-and-nothing-can-call-them/00-report.md)
|
||||||
|
- [ADR 0047](0047-a-module-runs-its-code-as-its-own-process-with-its-own-account.md)
|
||||||
|
- [`03-DESIGN/01-to-be/19-the-module-protocol.md`](../03-DESIGN/01-to-be/19-the-module-protocol.md)
|
||||||
@@ -114,6 +114,7 @@ python3 00-META/checks/index.py fail if stale
|
|||||||
- **0079** — [The foundation seats are named after their servers](0079-the-foundation-seats-are-named-after-their-servers.md)
|
- **0079** — [The foundation seats are named after their servers](0079-the-foundation-seats-are-named-after-their-servers.md)
|
||||||
- **0092** — [An operator delivers a pair credential, and the mesh never replaces it](0092-an-operator-delivers-a-pair-credential.md)
|
- **0092** — [An operator delivers a pair credential, and the mesh never replaces it](0092-an-operator-delivers-a-pair-credential.md)
|
||||||
- **0094** — [A module may hold several secrets from one provider, each a pair of its own](0094-a-module-may-hold-several-secrets-from-one-provider.md)
|
- **0094** — [A module may hold several secrets from one provider, each a pair of its own](0094-a-module-may-hold-several-secrets-from-one-provider.md)
|
||||||
|
- **0095** — [The control plane is the way to ask a module](0095-the-control-plane-is-the-way-to-ask-a-module.md)
|
||||||
|
|
||||||
### What runs on them, and how it gets there
|
### What runs on them, and how it gets there
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,9 @@ code:
|
|||||||
- mesh-sdk src
|
- mesh-sdk src
|
||||||
- mesh-tools src/broker-amqp.ts
|
- mesh-tools src/broker-amqp.ts
|
||||||
- mesh-controller internal/link
|
- mesh-controller internal/link
|
||||||
updated: 2026-09-15
|
updated: 2026-09-21
|
||||||
decisions:
|
decisions:
|
||||||
|
- 02-DECISIONS/0095-the-control-plane-is-the-way-to-ask-a-module.md
|
||||||
- 02-DECISIONS/0074-the-wire-is-specified-not-the-types.md
|
- 02-DECISIONS/0074-the-wire-is-specified-not-the-types.md
|
||||||
- 02-DECISIONS/0039-what-the-sdk-holds-and-refuses.md
|
- 02-DECISIONS/0039-what-the-sdk-holds-and-refuses.md
|
||||||
- 02-DECISIONS/0043-a-module-broker-account-is-scoped-by-emits-and-consumes.md
|
- 02-DECISIONS/0043-a-module-broker-account-is-scoped-by-emits-and-consumes.md
|
||||||
@@ -137,13 +138,15 @@ A module's tools are its operator-facing surface.
|
|||||||
into any queue on the broker.
|
into any queue on the broker.
|
||||||
- A caller needs a **reply queue**, and that is what a module's scoped account may not declare
|
- A caller needs a **reply queue**, and that is what a module's scoped account may not declare
|
||||||
([issue 049](../../04-ISSUES/049-a-module-can-serve-tools-and-nothing-can-call-them/00-report.md)).
|
([issue 049](../../04-ISSUES/049-a-module-can-serve-tools-and-nothing-can-call-them/00-report.md)).
|
||||||
So a module may serve tools and may not call them, and nothing today issues an account to anything
|
So a module may serve tools and may not call them.
|
||||||
that wants to ask.
|
- **The control plane is the way to ask**
|
||||||
|
([ADR 0095](../../02-DECISIONS/0095-the-control-plane-is-the-way-to-ask-a-module.md)):
|
||||||
### Not yet true
|
`ask <module> <tool> [json]` publishes on `mesh.rpc` under `<module>.<tool>` with a private reply
|
||||||
|
queue bound under its own name, and prints the answer as the module gave it. A module declares
|
||||||
The caller's half has no account. Until that is settled, the only thing that can ask a module a
|
nothing about being asked — serving a tool is being askable through the control plane. A
|
||||||
question is the foundation's bootstrap admin, which is not a protocol so much as a way in.
|
module-to-module call, if one is wanted, is a grant like any other and a later decision.
|
||||||
|
*How it is checked:* a tools-only bed asks a served tool through the control plane and asserts
|
||||||
|
an answer arrived, where a timeout would read differently.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
---
|
---
|
||||||
status: located
|
status: resolved
|
||||||
opened: 2026-09-14
|
opened: 2026-09-14
|
||||||
located-in: [mesh-controller cmd/mesh-controller, mesh-tools (the request contract)]
|
located-in: [mesh-controller cmd/mesh-controller (ask), mesh-controller internal/link]
|
||||||
fixed-by:
|
fixed-by: ADR 0095; mesh-controller multiple-fixes (ask: the control plane publishes the request with a private reply queue and prints the answer); proven by the confluence bed
|
||||||
amended-design:
|
amended-design: 03-DESIGN/01-to-be/19-the-module-protocol.md
|
||||||
---
|
---
|
||||||
|
|
||||||
# 049 — A module can serve tools, and nothing is allowed to call them
|
# 049 — A module can serve tools, and nothing is allowed to call them
|
||||||
|
|||||||
@@ -14,5 +14,6 @@
|
|||||||
like any other, and a later decision.
|
like any other, and a later decision.
|
||||||
|
|
||||||
**Located in:** the controller (a command speaking the tool request/reply over its own connection)
|
**Located in:** the controller (a command speaking the tool request/reply over its own connection)
|
||||||
and the tool runtime's request contract. Not fixed here: it is a new command against a protocol
|
and the tool runtime's request contract. Fixed as
|
||||||
the runtime owns, and needs a lab run against a tools-only bed to be proven.
|
[ADR 0095](../../02-DECISIONS/0095-the-control-plane-is-the-way-to-ask-a-module.md): `ask`,
|
||||||
|
proven by the confluence bed asking a served tool and getting its answer.
|
||||||
|
|||||||
Reference in New Issue
Block a user