--- layer: as-is status: implemented code: [hal] updated: 2026-08-23 decisions: - 02-DECISIONS/0002-everything-is-a-module.md - 02-DECISIONS/0010-applications-live-in-their-own-repository.md - 02-DECISIONS/0017-modules-outside-the-core-are-grouped-by-domain.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 0017](../../02-DECISIONS/0017-modules-outside-the-core-are-grouped-by-domain.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.