A warrant named the ask by id and the option by id, and the asker acted on whatever its record held
for them. Now the ask carries, for every option above acknowledge, the digest of exactly what it
performs (Option.Binds, ActDigest), the router puts the digest of the ask it took in the warrant
(Warrant.AskDigest), For refuses a warrant whose digest is not that of the ask the asker keeps, and
Option.Performs refuses an act the option did not bind. A warrant then authorises one act, as the
person was shown it, once.
mesh/repo-check pass: THE CHANGE ALTERS ITS OWN CHECK (merge-check.sh): main's version judged it; the change's judges the pull requests after it merges; it…
Review of hq ADR 0272: a line whose answer did not come in time may have
run, and saying "nothing ran" there is a lie. Answer.Unknown and NotKnown
say it may have run and name the call to look at.
The SDK's repo-check ran in the TypeScript toolchain only and said
"NOT TESTED HERE: go/". go/merge-check.sh now runs the Go binding in the Go
toolchain, declared by the root check (mesh-check-also), as the lab does.
Released as go/v0.1.9 (go/v0.1.8 is mesh-sdk #12's).
mesh-cli holds no credential: it asks the node-engine on its own machine
over a socket, and the node-engine reads the account from the kernel. The
socket's path, the request and the answer are shared by the program and the
node-engine, so they live here once (ADR 0039: a local protocol a module's
program speaks to its runtime). The bus request the node-engine then makes
is the transport's, and stays out of the SDK.
A handler takes an event by returning and asks for it again by throwing;
any mesh/event answer but an error is taken. Written down in the README
where event handling is, with what follows for a handler: throw only when
the work was not done, and be safe to run twice.
Both SDKs added the handler before asking the runtime and kept it when the
runtime refused, so a module that asks again until it is taken (every Go
consumer does) ran its handler once per attempt for every event. A refused
subscribe now removes its handler; one the Go runtime did not answer in
time is kept, since the runtime may have bound it.
state(name) / stdio.State(name): get, put, delete, keys and watch over the
runtime's mesh/state verbs. A watch's handler is registered under the id it
is asked with, so its current values — which arrive before the watch is
answered — and its changes reach it and no other watch.
Subscribe(pattern, handler) asks the runtime for the module's events and answers each mesh/event
only after the matching handlers returned nil, so the runtime acknowledges it on the bus then and
not before; Ask(key, body) calls a tool as the module. Topic matching is the TypeScript SDK's.
What the TypeScript SDK's stdio loop does, in Go: an empty name serves as MESH_SERVED_MODULE; each
call runs beside the loop so a tool waiting on the runtime does not deadlock it; Emit asks the
runtime (mesh/publish) with the same envelope and headers. README says how to install it and how
releases are tagged.
The node's runtime launches a tools bundle as a process and speaks MCP over stdio to it, so a tool
may be written in any language and the transport stays in the runtime (ADR 0039's refusal, kept).
Each SDK is the loop and the tool type and nothing else: `@novox/mesh-sdk/stdio` (serveStdio, and
serveRegisteredOverStdio for a bundle that already registers the in-process way), python/, go/,
rust/ and c/ beside it, each with an example answering `greet` and the seat verb `node-lamp.on`.
Skeletons, by the operator's direction: the bare minimum one bundle per language needs to be built
and answer, proven here by each example answering tools/list and tools/call on stdio.