Commit Graph
4 Commits
Author SHA1 Message Date
jschoubben 99ce1e1252 runtime: an emit primitive, so an events test can put a message on the wire
'mesh-tools emit <type> [json]' connects, emits one ADR 0047 event (awaiting
the publish confirm), and exits. The serve path already runs a module's
on('#') subscription as an import side effect, so the runtime hosts both an
emitter and the audit-logger consumer.

Claude-Session: https://claude.ai/code/session_01LrgweAeERJYBg88c5cKDzF
2026-09-04 00:56:37 +02:00
jschoubben f85d1dc303 broker: the ADR 0047 wire shape, and the event failure paths
The AMQP adapter now honours the full contract: events published
persistent with metadata in headers; a durable per-consumer queue
(<node>.<module>.events) with prefetch and a dead-letter exchange
(mesh.events.dead); manual ack for at-least-once.

Failure paths, not just the happy one:
- a confirm channel, so a publish the broker never accepted fails the
  emit rather than vanishing — at-least-once starts at the emitter;
- a handler that keeps failing is requeued once, then dead-lettered
  (poison set aside, never looping);
- an undecodable body is dead-lettered at once — it never decodes on
  redelivery, and must not wedge the queue.

Binding-conformance tests against a disposable broker (a stand-in for the
mesh-hosted broker, ADR 0001): headers on the wire with a pure body, the
redelivery-limit dead-letter, and the poison-body dead-letter.

Claude-Session: https://claude.ai/code/session_01LrgweAeERJYBg88c5cKDzF
2026-09-04 00:26:09 +02:00
jschoubben 201a413f69 broker: split events (mesh.events) from tool RPC (mesh.rpc)
Per ADR 0047: two topic exchanges kept apart, so a '#' subscription on
mesh.events is a clean audit of module/mesh/node events without the
request/reply tool traffic. Header-in-AMQP, persistent messages, per-
consumer durable dead-lettered queues and prefetch are the remaining
alignment to 0047.

Claude-Session: https://claude.ai/code/session_01LrgweAeERJYBg88c5cKDzF
2026-09-03 23:50:56 +02:00
jschoubben 9eddcdb0a0 mesh-tools — the tool runtime and AMQP broker binding
The per-node process that makes a module's tools serve on the mesh:
- broker-amqp.ts: a concrete AMQP implementation of the sdk's Broker
  contract (request/reply over a reply queue + correlation id, publish/
  subscribe over a topic exchange). Kept here, not in the sdk, so a
  broker-client change never rebuilds a module (ADR 0044).
- runtime.ts: bind the broker, import the assigned modules' tool
  entrypoints (each registers as it loads), serveTools. The thin wrapper.
- main.ts: the entrypoint, configured by MESH_BROKER_URL + MESH_TOOL_MODULES.
- Dockerfile: the container a node runs it as.

Verified over a REAL broker: the test spins LavinMQ (the mesh's broker),
the runtime serves a registered tool, a separate connection invokes it by
name over AMQP and gets the result, and an unknown tool is refused over
the wire. So 'modules can serve' is now running-on-the-mesh, not just
proven in a mock.

Claude-Session: https://claude.ai/code/session_01LrgweAeERJYBg88c5cKDzF
2026-09-03 23:21:01 +02:00