Files
hq/01-RESEARCH/036-everything-over-nats/02-utopia.md
T
jochen 5e9a27a6a3
mesh/merge-gate pass: the change touches no module of the mesh's graph
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered
Research 036: measure where the mesh talks around the bus, so views can be built from it
2026-10-08 15:28:57 +02:00

4.4 KiB

036 — The target: a mesh that happens on the bus

This is where the gaps in 01-evidence.md point. It is a picture to test proposals against, not a design. Each paragraph names the gap it answers.

A module owns its state: its files, its database, its container. It is reached only by its tools, its seat's verbs, its events and its buckets.

  • No module acts on another's container, socket or files. A store module serves its own dump. The registry says what it holds. The resolver's verbs are called over the bus like any other seat's. A download client answers whether it is reachable with a key (G5).
  • Every act is grantable. Because every act is a subject, the bus can refuse it, and the controller can say who may perform it.

The bus is not for bulk bytes, and two kinds of traffic stay off it by name:

  • Bulk bytes stay where they are. The bytes of an artifact and of a git repository, and an app using its database, keep their own protocols.
  • Who reaches them is decided on the bus. Where to reach them is a provision, and what exists is announced on the bus (G4).

Every important state is watchable

For each thing a person would look at, the owner keeps three things on the bus:

  1. A bucket of current state, one key per thing: a node, an assignment, a plan, a build, a delivery, a setting, a licence, an open ask.
  2. An event for each change, naming the thing and what changed. Another module can consume it, and a view can redraw from it.
  3. A history stream, where the past matters, with a retention the owner declares (G8).

The store remains the owner's record where it needs one. The bucket is written from it on change, never instead of it. The open conditions already work this way. Plans, builds, nodes, assignments, settings and licences come next (G2, G6). A verb is still how something is asked or done. It stops being the only way to see.

Views are built from the bus

A view is a web page or a terminal UI that shows part of the mesh. View is proposed here as the glossary word for this. It has no backend of its own:

  • It connects to the bus over WebSocket, through the proxy, as the person using it.
  • It reads the buckets it shows, watches them, and subscribes to the events that explain a change.
  • It acts by calling the same tools and verbs an agent calls. A decision travels as an answer to an ask, carrying its proof, and the controller checks it (the approval flow, §6 of the evidence).

The person is admitted by an auth callout served by a mesh module. That module checks the person's login with the mesh's identity provider and issues a short-lived bus user. The user's grant is derived from the view's declaration: these buckets to read, these events to hear, these tools to call. No password is written into the server's file for a person, and a person's access ends when the credential expires (G1).

The bus survives a machine

Every machine runs a leaf node:

  • Local traffic stays local. A module's connection is local, and tool calls between modules on one machine keep working when the hub is away, as they must on a laptop behind a VPN client.
  • What must not be lost is replicated. The control-node's server is one of three in a cluster, and the declarations, the control stream and the controller's buckets are kept on three disks rather than one. The nightly snapshot remains the guard against our own mistakes, not against a disk (G3).

The bus watches itself

  • Server events become conditions. The nats module holds a system-account user and turns the server's own events into conditions, like any other probe: a slow consumer, a permission refused, a client reconnecting in a loop, a consumer that nothing feeds.
  • Exhausted messages are kept. A message delivered as often as allowed lands in a dead-letter stream that a view can show (G7).
  • Nothing to rescue by paging. Answers stay within one message because views read keys, not whole lists (G9).

What is not wanted

  • No view with a database of its own that copies the mesh's state. That copy drifts, which is the thing the mesh exists to prevent.
  • No HTTP API on the controller beside the bus (G10).
  • No second signing hierarchy for its own sake. The callout issues users under the account the mesh already has, unless a separate account for people turns out to be the simpler grant.