Files
hq/01-RESEARCH/006-mesh-from-scratch/00-overview.md
T
jschoubben daf3e17c32 self-hosting, provisioning and delivery efforts, and the dotfiles origin
The identity provider is settled as not-substrate: the mesh does not
require one, tier 2 authenticates natively, and it is a hosted service
like any other. Four substrate services, not five. The tier test's second
step gains the verb that matters — can the control plane START without it,
not function fully without it.

That verb answers the forge and the registries. They are not substrate and
they are not duplicated: the control plane starts and manages nodes
without a forge, it just cannot change itself. One gitea module, tier 4,
and the mesh's own instance is distinguished by what it is bound to rather
than by being a different module — the same answer as postgres, from the
same test. It also buys a property worth having: if the forge dies the
mesh keeps running.

Delivery needing them is not an upward dependency, resolved the way the
constitution already says to: tier 2 declares requirements, tier 4
provides implementations, the binding is data. The mechanism is
provisioning, and the new idea is that the control plane is itself a
consumer.

Self-hosting therefore becomes a state the mesh REACHES, not a
precondition. A first node comes up from pinned external artifacts and
re-binds to internal providers once they exist. Today's mesh assumes the
second state from the first moment, which is why the first-node path needs
a script that papers over an impossibility and is the least-exercised code
in the system. Made explicit, the transition is also reversible.

Research 007 and 008 opened for the two areas flagged as important and
complex, scoped from the weaknesses the as-is layer already documents
rather than started blank.

And the origin: this began as a dotfiles repository. The first two days
adopt dotfiles, add per-node overrides, and introduce service symlinking
with an ignore file. The flat one-directory-per-tool catalogue, linking
over copying, adoption of already-configured machines, per-node overrides
and the desktop modules are all inherited rather than chosen for a mesh.
That is the single most useful fact for anyone changing the catalogue, it
strengthens ADR 0018 — the case for links was never made for a mesh — and
it explains research 005's silent fifty: dotfiles-era entries for one tool
never shared a domain because they never had one.
2026-08-23 20:55:14 +02:00

5.5 KiB

status, initiated, touches, became
status initiated touches became
active 2026-08-23
02-DECISIONS/0015-mesh-brokers-nodes-host-agents-think.md
02-DECISIONS/0017-modules-outside-the-core-are-grouped-by-domain.md
03-DESIGN/00-as-is/00-overview.md
03-DESIGN/01-to-be/00-work-breakdown.md

006 — The mesh designed from nothing

What is being investigated

What the mesh would look like if it were laid out today, with the requirements known and none of the accumulated shape — expressed as a skeleton: repositories at the root, modules inside them, and whatever turns out to be the right leaf unit below that.

The deliverables are skeleton.md — tiers, repositories and the four design moves — and code-skeleton.md — the tier test, what a module looks like on disk, and where today's catalogue lands.

Why

Every structural decision so far has been a correction: eight contexts replacing thirty-three modules (ADR 0015), domains replacing single-function modules (ADR 0017). A correction inherits the frame of the thing it corrects, and two of the mesh's oldest problems look unsolvable from inside that frame:

  • The bootstrap circularity. The mesh needs a database, a bus, a registry and an identity provider. Those are modules the mesh installs. The mesh cannot install them before it exists. This has been worked around repeatedly and never designed away.
  • Participation requires privilege. Everything assumes root on a machine whose packages and services the mesh owns. A phone cannot participate on those terms, and neither can a machine someone else administers.

Designing from nothing is a way to find out which parts of the current shape are requirements and which are residue.

And there is more residue than expected, from a knowable source. This began as a dotfiles repository — the first two days of history adopt dotfiles, add per-node dotfile overrides, and introduce service symlinking with an ignore file. The flat one-directory-per-tool catalogue, linking rather than copying, adoption of already-configured machines, per-node overrides, and the desktop modules are all inherited from that, not chosen for a mesh. Recorded in 03-DESIGN/00-as-is/10-module-catalogue.md.

That makes this effort's question sharper than "what would we do differently": much of what looks like design is a generalisation of place files on my machines, never revisited because it was never stated as an assumption.

The requirements this is designed against

Stated by the operator, recorded here so the skeleton can be checked against them rather than against taste:

  1. The mesh manages multiple computers — full control, through modules installed to nodes.
  2. Mesh state lives in a database: which modules on which nodes, logs, configuration.
  3. Configuration has several touchpoints — tool surface, web interface, others — all hosted by the mesh itself.
  4. Connectivity is core: every node reachable from every other over a shared overlay, some nodes publicly exposed, firewalls configured.
  5. The mesh hosts applications — and requires some of them itself. This is the circularity.
  6. Arch Linux only for now; ideally any device, including phones, on lighter terms.
  7. The end goal is to operate an IT company on it — development, design, deployment, full circle, self-hosted. Personal cloud infrastructure.
  8. Agents make it self-improving and self-healing.
  9. It is end-to-end testable on one machine (ADR 0016).

Status

A first skeleton exists, with four design moves that the current shape does not have. It is active because two of them are unproven and one contradicts a record that is already accepted.

Finding worth stating up front: ADR 0015 names nine bounded contexts and none of them owns connectivity — no overlay, no resolution, no firewall, no ingress. Requirement 4 has no home in the accepted decomposition, while research 005 found reachability to be the only part of the catalogue where modules genuinely change together under one intent. The skeleton adds it.

Open questions

Question Why it is open
Does the record — the event log contexts integrate through — belong to the substrate or the control plane? It is infrastructure by shape and domain by content. Placing it wrong reintroduces a circularity.
One repository per tier, or per context? Already open from ADR 0015 as "catalogue destination — one repository or many". The skeleton assumes per tier and does not settle it.
Does an unprivileged node earn a place in the inventory, or only a presence? Decides whether "node" means one thing or two.
Does absorbing overlay, filtering, packages, supervision and the container runtime make the host too large? It is the skeleton's biggest unproven claim. A binary whose whole argument is that it has no dependencies now carries six concerns.
Four substrate services or five? The identity provider passes the tier test only if the control plane delegates authentication rather than doing it natively.
Does feature survive? The skeleton splits it in two and argues the conflation is what makes the delivery pipeline hard to reason about. Unproven.