Files
hq/03-DESIGN/00-as-is/14-a-modules-state.md
T
jschoubben 418261213c
mesh/merge-gate pass: the change touches no module of the mesh's graph
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…
mesh/delivery superseded: a newer head of the same pull request
Remove the decision records and research efforts, which the knowledge base now holds whole (issue 426)
ADR 0290 rule 9: once the import is checked record by record, hq keeps no copy.
The records and efforts are removed; every link or path to them reads "ADR NNNN" or
"research NNN"; a design's decisions: lists "ADR NNNN". 02-DECISIONS keeps a pointer
README with the reading order's six topics, which the knowledge base reads through the
records module; 01-RESEARCH keeps a pointer README. The checks drop the rules that
judged records (the knowledge base holds each at propose; checks/README.md says where)
and refuse a record written here again. Playbooks 01 and 02 and the skills write and
read records with the knowledge base's verbs.
2026-10-11 12:56:09 +02:00

52 lines
3.3 KiB
Markdown

---
layer: as-is
status: implemented
code: [mesh-controller internal/catalogue/state.go, mesh-controller internal/broker/state.go, mesh-controller cmd/mesh-controller/push.go, mesh-tools node-tools/internal/bus/state.go, mesh-tools node-tools/internal/launch/launch.go, mesh-sdk src/state, mesh-sdk go/state.go]
updated: 2026-10-04
decisions:
- "ADR 0201"
---
# A module's state, as it runs
**A module keeps the current value of something on the bus, and every machine sees it — including one
that joins later.** Since 2026-10-04 a manifest may say `state` (buckets the module owns) and `reads`
(another module's, as `<module>.<name>`). The first two modules to use it are the operator's agent on a
machine and its licence manager; on the day this was written, three buckets existed on the bus.
## What runs
- **The controller** creates a key-value bucket `<module>_<name>` for every declared state, from the
catalogue — on every start and, since the first module that declared state found it missing, on every
push before the memberships that name it. A bucket nothing declares any more is reported and kept.
Every bucket carries the mesh's caps: 256 KiB a value, 64 MiB a bucket.
- **The grants**: the machine's runtime is granted, for each bucket a module it carries owns, writing
under the bucket's own subjects and reading; for a bucket it only reads, reading. Measured once built,
with the composed grants loaded into a server: a reader's write is refused by the server.
- **The membership** issued to each assignment lists its buckets by the names the module uses, and
whether it may write.
- **The runtime** answers `mesh/state.get`, `put`, `delete`, `keys` and `watch` on the bundle's channel.
A watch hands the current values — none that is deleted — then every change, each naming the watch it
belongs to; it is answered once the current values are delivered. The runtime refuses, with the
reason, a state the module was not issued, a reader's write, a key the bus cannot hold, and a value
carrying a field named like a credential.
- **The SDKs**: `state(name)` in TypeScript, `stdio.State(name)` in Go (tag `go/v0.1.7` and later).
## What the first live use showed
- **A refused request is a timeout, not a refusal.** The bus reloads a machine's grants a moment after
the push that changed them; a bundle that asks in between waits out its deadline. A module that
watches at start therefore watches beside its handshake and asks again until the state answers — the
agent module needed two to seven attempts on its first start on each machine.
- **A late machine reads the whole set.** A server registered for every machine before one machine was
assigned the module reached that machine from the current values at its start.
- **The secrets guard is partial and works for what it covers**: an entry carrying an `Authorization`
header was refused on the live bus. A sealed value is plain text to an inspector, and is not caught.
## How it is checked
The controller's catalogue and broker tests (names, grants, memberships, a bucket asserted in place
against a real server); the runtime's tests over a real bus (current values without deletions, refusals,
the TypeScript SDK through the runtime); `module check` names a read whose owner on the shelf keeps no
such state.