Files
hq/02-DESIGN/00-as-is/00-overview.md
T
jschoubben 702efca6bb Base layer: the mesh as it is, under the mesh as it should be
HQ held only the to-be. Every reader had to already know the system the
decisions were about, and an as-is claim had nowhere to live except inside
an intention.

Adds 02-DESIGN/00-as-is — eleven documents written from the implementation
and the operational record, not from intent, including the parts nobody
would choose again. The two existing designs move under 01-to-be. Layers
are declared in frontmatter and never mix: a design that ships does not
move, its as-is counterpart is written, and both stand.

Back-fills adr/0001-0014 for decisions taken in implementation and never
recorded — the broker, the module abstraction, the mesh database, managed
files, provisioning, migrations, the workspace removal, failing loudly,
the constitution, application placement, linking, the employee model, the
artifact, the three silos. Each marked reconstructed, dated from the
history, and citing the evidence it was recovered from. The two existing
records renumber to 0015 and 0016 so the ledger runs oldest first;
0017 extends 0015 to modules outside the core, principle only — the
domain list is deliberately not invented here.

how-we-build.md becomes the source of the mesh constitution, with a sync
playbook, so the enforced copy stops being the only one that is true.

Process becomes explicit: five playbooks, eight thin skills that defer to
them, a repository map, and AGENTS.md with CLAUDE.md as its include.

The five Observations become 04-ISSUES 001-005 where they can be owned and
closed. 006 is new and uncomfortable: HQ is not indexed into the knowledge
base. That claim is what decision 27 rests on, it was never checked, and
the README now says so instead of repeating it.

Also corrects the ADR index into something generated, the "02-DESIGN is
empty" claim, the VISION.md pointer that did not survive the repo split,
and a note asserting the symlink rule was contradicted — it was a
misreading; the rule forbids hand-made links, the installer links by design.
2026-08-23 03:08:26 +02:00

99 lines
5.0 KiB
Markdown

---
layer: as-is
status: implemented
code: [hal]
updated: 2026-08-23
decisions:
- adr/0001-nodes-communicate-over-a-broker.md
- adr/0002-everything-is-a-module.md
- adr/0003-the-mesh-database-is-the-source-of-truth.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 0002](../../adr/0002-everything-is-a-module.md)).
**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](../../adr/0012-agents-are-persistent-employees.md)).
## 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 0003](../../adr/0003-the-mesh-database-is-the-source-of-truth.md)).
Everything on a node's disk is **derived** from those two, and is regenerated rather than
edited ([ADR 0004](../../adr/0004-managed-files-are-generated-never-edited.md)). 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](../../adr/0001-nodes-communicate-over-a-broker.md)). 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 0014](../../adr/0014-build-publish-and-deploy-are-three-silos.md)). What travels between
build and node is a self-contained build output, so a deploy is extract-and-run and touches no
network ([ADR 0013](../../adr/0013-an-artifact-is-build-output.md)).
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 0005](../../adr/0005-capabilities-are-provisioned-on-declaration.md)).
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 0008](../../adr/0008-a-failed-step-fails-the-job.md) 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.