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.
127 lines
6.9 KiB
Markdown
127 lines
6.9 KiB
Markdown
---
|
|
layer: as-is
|
|
status: implemented
|
|
code: [hal]
|
|
updated: 2026-08-23
|
|
decisions:
|
|
- 02-DECISIONS/0044-modules-and-the-graph.md
|
|
- 02-DECISIONS/0010-applications-live-in-their-own-repository.md
|
|
- 02-DECISIONS/0044-modules-and-the-graph.md
|
|
---
|
|
|
|
# The catalogue, and what its shape says
|
|
|
|
The catalogue holds **124 modules**. Thirty-three belong to the mesh's own domain; the other
|
|
ninety-one run *on* the mesh rather than being *of* it
|
|
([ADR 0015](../../02-DECISIONS/0015-mesh-brokers-nodes-host-agents-think.md)).
|
|
|
|
The count is not the finding. The **shape** is.
|
|
|
|
## How it is organised today
|
|
|
|
By namespace, and the namespace records origin rather than purpose:
|
|
|
|
- **The mesh's own namespace** holds the platform: the runtime and its daemons, the shared
|
|
library, delivery, provisioning, configuration synchronisation, knowledge, identity, the
|
|
board, developer tooling, and node presentation.
|
|
- **A second namespace** holds the work domain — tasks, workflows, agents, meetings — split
|
|
across a handful of packages that share one schema.
|
|
- **Everything else sits flat at the top level**, one directory per piece of software.
|
|
|
|
## What the flat level actually contains
|
|
|
|
Grouped by what they are *for* — a grouping the catalogue itself does not express:
|
|
|
|
| Purpose | Roughly |
|
|
|---|---|
|
|
| Data and storage services the mesh provisions against | Relational and document databases, a cache, an object store, a package registry, a time-series store |
|
|
| Messaging and identity | A message broker, an identity provider |
|
|
| Reachability | A VPN, a firewall, an intrusion filter, an SSH daemon, a resolver, a certificate authority, a reverse proxy, network equipment control |
|
|
| Forge and container plumbing | Forge integrations, an image registry, container lifecycle and retention |
|
|
| Media libraries | Acquisition, organisation, playback, transcoding, streaming |
|
|
| Workstation and desktop | Browser, file manager, monitors, session management, audio, package management, runtime managers |
|
|
| Hardware-specific support | Power and firmware control for particular hardware, filesystem management |
|
|
| Collaboration and productivity | File sync, office tooling, boards, automation, chat and messaging bridges, mail, analytics, dashboards, home automation, issue trackers and wikis |
|
|
| Third-party organisation integrations | Systems belonging to organisations outside the mesh |
|
|
|
|
Every row is several modules, and **no row is a thing the mesh can see**. Four modules
|
|
together constitute "how a node is reachable", and they have no relationship the mesh can
|
|
assign, version, reason about or replace as one unit. A change to how the mesh handles
|
|
connectivity is made four times.
|
|
|
|
## What the shape records
|
|
|
|
**The catalogue's shape records what was installed, not what anything is for.** One module is
|
|
the unit of one piece of software, because that is the only granularity the module system
|
|
offers.
|
|
|
|
This is the same failure [ADR 0015](../../02-DECISIONS/0015-mesh-brokers-nodes-host-agents-think.md)
|
|
names for the platform core — *boundaries drawn by deployment accident rather than by domain* —
|
|
appearing outside it, at four times the scale. The core is being recomposed; the flat level is
|
|
addressed in principle by
|
|
[ADR 0044](../../02-DECISIONS/0044-modules-and-the-graph.md), which
|
|
deliberately does not yet settle the domain list.
|
|
|
|
## Where the shape came from
|
|
|
|
The catalogue's shape is not arbitrary and it is not a series of mistakes. **This repository
|
|
began as a dotfiles repository**, and most of what looks inexplicable is inherited from that
|
|
directly.
|
|
|
|
The evidence is in the first two days of history: *adopt desktop dotfiles and scripts from the
|
|
original dotfiles repository*; *per-node dotfile overrides*; *service symlinking, node
|
|
`.dfignore`, headless server support* — all on 2026-02-24 and 2026-02-25, before anything
|
|
resembling a mesh existed. Forty-five commits mention dotfiles.
|
|
|
|
Read that way, several things stop being puzzles:
|
|
|
|
| Feature of today's shape | Dotfiles ancestor |
|
|
|---|---|
|
|
| One flat directory per piece of software | Exactly how a dotfiles repository is organised |
|
|
| **Linking rather than copying** as a stated design principle | How every dotfiles manager works — the whole category is built on it |
|
|
| **Adoption** — taking over a machine that already exists, with its own configuration | The core dotfiles verb, and the reason a machine could be brought in at all |
|
|
| **Per-node overrides** | Per-host dotfile overrides, generalised into per-node module settings |
|
|
| Desktop and workstation modules — browser, file manager, editors, session, audio, personal scripts | Dotfiles content that became "modules" when modules became the only unit |
|
|
| An ignore file controlling what is placed on a machine | A dotfiles manager's ignore file |
|
|
|
|
The generalisation from *place files on my machines* to *manage a mesh of nodes* was the right
|
|
move and it worked. What it did not do is revisit the assumptions underneath, because they were
|
|
never stated as assumptions — they were just how the thing already worked.
|
|
|
|
**This is the most useful single fact for anyone changing the catalogue**, and it is why the
|
|
linking principle in particular reads as a deliberate architectural choice when it is an
|
|
inheritance. See [ADR 0018](../../02-DECISIONS/0018-the-mesh-creates-no-symlinks.md), whose case
|
|
this strengthens: the argument for links was never made *for a mesh*.
|
|
|
|
It also explains the measurement in
|
|
[research 005](../../01-RESEARCH/005-domain-grouping/analysis.md). Fifty modules that never
|
|
change alongside anything are not fifty missing domains — many are dotfiles-era entries for one
|
|
piece of software, which never shared a domain because they never had one.
|
|
|
|
## Two properties worth keeping
|
|
|
|
Whatever replaces the shape, two things about it are right.
|
|
|
|
**Uniformity.** A media server and the mesh's own coordinator are installed, provisioned,
|
|
delivered and verified by identical machinery. The mesh's own components hold no privilege —
|
|
which is what makes dogfooding structural rather than a discipline, and what makes moving a
|
|
module out of the repository safe.
|
|
|
|
**Placement is already decided.** A standalone application belongs in its own repository
|
|
([ADR 0010](../../02-DECISIONS/0010-applications-live-in-their-own-repository.md)), and reviewers reject
|
|
it in the monorepo. The catalogue's flat level is not a dumping ground by policy; it is one by
|
|
history.
|
|
|
|
## Known inconsistencies in the catalogue itself
|
|
|
|
Recorded because a reader will meet them:
|
|
|
|
- A documented requirement that every capability-exposing module declare the core runtime as a
|
|
dependency is met by **zero** modules.
|
|
- A firewall-scoping key is declared by five manifests and read by none
|
|
([`04-ISSUES/003`](../../04-ISSUES/003-firewall-scope-is-read-by-no-code/00-report.md)).
|
|
- A connections block in the manifest is metadata: it describes a module's reachability and
|
|
wires nothing.
|
|
- At least one module deliberately runs outside the standard per-module supervision, for
|
|
reasons recorded in the operational memory. The standard path is not universal.
|