Design 29: tools, not serves; WBS 3.9 partly done

The manifest already uses serves for a provision's facts, so a module's
tools take their own key. Declaring them is itself new — until now a
module's tools existed only in a runtime environment variable.
This commit is contained in:
2026-09-26 22:17:17 +02:00
parent 0b8e84334f
commit b759e36bfd
2 changed files with 20 additions and 6 deletions
@@ -29,7 +29,7 @@ those, and a manifest never contains one.
**The requirement delivers the connection; the declarations shape the authority.** `requires:
mesh-bus` says *this module talks to the mesh* and grants no subject by itself. `emits`,
`consumes`, `serves`, `uses` and a declared seat say what it may say and hear. Declaring a subject
`consumes`, `tools`, `uses` and a declared seat say what it may say and hear. Declaring a subject
without requiring the bus is incoherent and refused at registration.
This document is the declaration model. [Design 25](25-the-bus-on-nats.md) is the bus itself —
@@ -49,10 +49,17 @@ the catalogue, and the mesh would have hundreds of copies of a decision it made
|---|---|
| `emits: order.placed` | publish on `mesh.mod.<module>.event.order.placed` |
| `consumes: billing.order.placed` | durable consumer on `mesh.mod.billing.event.order.placed` |
| `serves: status` | queue-group subscription on `mesh.mod.<module>.tool.status` |
| `tools: status` | queue-group subscription on `mesh.mod.<module>.tool.status` |
| seat `telegram-sender`, `accepts: send` | work-queue consumer on `mesh.seat.telegram-sender.accept.send` |
| `uses: telegram-sender` | publish on that seat's `accept` subjects, and nothing else |
**It is `tools:`, not `serves:`.** Revision, found while implementing: the manifest already uses
`serves` for the facts a consumer needs in order to reach a provision, and two meanings under one
key in the file a module author reads most is a footgun. Worth noting that until now a module's
tools were not declared at all — they were known only at runtime, from an environment variable in
its image — so declaring them is new, and is what lets the mesh check that a module claiming a
seat answers what that seat's protocol promises.
**The `event` / `tool` / `accept` token is load-bearing, not decoration.** Revision, found while
defining the streams: a stream is defined by a subject filter, so a namespace holding both a
module's events and its tool calls cannot be filtered into an events stream without capturing