Files
hq/03-DESIGN/00-as-is/00-overview.md
T
jschoubben 77f3a4cea7 Consolidate: 65 decision records to 23
Every remaining cluster merged. Each was one design that had been split across
several records because it was worked out over days rather than at once.

  the node host          8 -> 1    applies not decides, depends on nothing,
                                   per operating system, root service, the
                                   launcher, episodic, what a declaration is,
                                   actions from the bundle only
  a node and how it joins 4 -> 1   what a node is, joining, the link as
                                   security boundary, the enrolment token
  modules and the graph   7 -> 1   everything is a module, no domain modules,
                                   three edges, provisioning, the core library
  substrate and control   6 -> 1   the test, seven contexts, one control plane,
    plane                          the authority is not a database, the named
                                   products, the pinned bundle
  connectivity            3 -> 1   a route is a grant, reachability declared,
                                   filter rules
  delivery                5 -> 1   reconciliation not a pipeline, artifacts,
                                   the three silos, a failed step, the verdict
  the lab                 5 -> 1   (earlier)
  how this repository     10 -> 1  (earlier)
    works

Nothing was dropped. Each consolidated record carries the reasoning of the ones
it absorbs -- the measurements, the incidents, the alternatives rejected --
because that reasoning is the only reason to keep a record at all. What is gone
is the fragmentation: eight files to read to understand tier 0, when tier 0 is
one component.

The four superseded records went too. They existed to point at their
successors, and the successors now contain what they said.

The checker made this safe. Each merge left dangling links -- 38 files after
the host merge alone -- and it named every one. Nothing was found by reading,
and a manual pass would certainly have missed some, including references inside
AGENTS.md which every session loads.
2026-08-28 20:03:24 +02:00

5.0 KiB

layer, status, code, updated, decisions
layer status code updated decisions
as-is implemented
hal
2026-08-23
02-DECISIONS/0001-nodes-communicate-over-a-broker.md
02-DECISIONS/0044-modules-and-the-graph.md
02-DECISIONS/0048-the-substrate-and-the-control-plane.md

The mesh as it stands

A set of machines, each running the same runtime, each loading only the parts of the catalogue it has been assigned. They hold no shared filesystem and make no direct connections to one another. What makes them a mesh is a database that knows what should run where, and a message broker that carries everything between them.

Three nouns

A node is a machine that runs the runtime. Nodes differ in what they are assigned and in what they can reach — some carry a public name, some sit behind a household connection with no inbound route at all — and the mesh is designed so that difference stays a property rather than becoming a special case. A node holds no authoritative state: everything it needs is derived onto it and can be regenerated.

A module is a directory with a manifest, and it is the only unit the mesh installs. A containerised service is a module. A set of capabilities with no service behind them is a module. A bare marker whose whole content is that a node has it is a module. The mesh's own components are modules on exactly the same terms as everything else it carries (ADR 0044).

An agent is a participant. Some agents are human. What differs is modality — how the agent acts — and not category: both hold identity, both act, both accumulate memory (ADR 0012).

Where truth lives

The repository defines what exists: the modules, what each declares, how each is built.

The mesh database defines what runs where: which node is assigned which module, at which selection, with which overrides, plus the settings every node reads. No node-to-module mapping is ever committed (ADR 0048).

Everything on a node's disk is derived from those two, and is regenerated rather than edited (ADR 0004). A node that loses its database keeps running from a local cache, which is deliberate and has the obvious cost: the cache carries no indication of its own age.

How anything moves

Nothing dials a node. Every node dials the broker outbound, owns an exchange named for itself, and consumes from its own request queue (ADR 0001). Three message shapes carry everything: requests expecting a reply, commands instructing that a stage of work be done, and events stating that something happened.

A capability that lives on another node is reached the same way a local one is. At startup a node asks its peers what they host and creates a local stand-in for each remote capability, so the caller does not know or care where the work happens. Credentials never travel: the call goes to where the capability is.

How change reaches a node

A push to the forge is the only trigger. What follows is three silos with deliberately different cardinality: compile once, package and upload once, then install-configure-start- verify on every assigned node (ADR 0058). What travels between build and node is a self-contained build output, so a deploy is extract-and-run and touches no network (ADR 0058).

Modules are resolved into dependency levels and a level completes before the next begins, so a module always builds against its dependencies as they were just published.

What the mesh does for a module

A module declares what it provides and what it requires. The mesh satisfies the requirement: it creates the resource, generates the credential, records the grant, and writes the values where the module will read them. The module never learns which node its database lives on, and nobody ever writes a credential by hand (ADR 0044).

This is the property the mesh's whole shape rests on, and it is why provisioning is treated as a core concern rather than as plumbing.

The shape of its failures

Worth stating in an overview, because it is the most consistent thing about the system: the mesh's expensive faults are almost never crashes. They are operations that reported success and did nothing — a download that half-completed, a hook that was never called because it was named for a feature the module does not declare, a stage that reported it had dispatched a message rather than that the effect happened, a package that 404ed from every mirror while the job went green.

ADR 0058 is the response, and it is applied instance by instance rather than enforced by a mechanism. New instances are still being found. That is an as-is fact, not a criticism: it is the single most useful thing to know about this system before changing it.