# What a module can be Every kind of thing the mesh has to install, run, own or know about, before deciding what a manifest says. Written to be argued with: a case here that turns out not to exist should be struck, and one that is missing is a hole in whatever schema follows. The hard cases are at the end, and they are the point. ## The ordinary cases **1 — A supervised service.** A container the mesh runs and keeps running. Nobody starts it; it is simply up. *A relational store, a message broker, an object store, a dashboard.* **2 — A system package with configuration.** Not a container. Installed into the machine, configured through files, run by the service manager. *A firewall, a resolver, an overlay.* Note: [ADR 0037](../../02-DECISIONS/0037-the-host-applies-it-does-not-decide.md) says applying these is the host's job — so what the module contributes is the *deciding*, not the doing. **3 — An application a person launches.** Installed on a node, started by a human, running only while they use it. *An editor, a chat client, a file manager, a terminal.* **4 — A command-line tool.** Installed, on the path, run when invoked. No service, no window. *A formatter, a query client, a backup utility.* **5 — A library.** Never runs at all. Consumed at build time by other modules. *An SDK.* **6 — A one-shot task.** Runs once, changes something, exits. *A schema migration, a data import, a seed.* **7 — A scheduled task.** Runs repeatedly on a timer, exits each time. *A backup, a prune, a report.* **8 — An adapter.** Exists to make several unlike things look alike behind one name. *A model provider behind an assistant interface.* **9 — A standalone application in its own repository.** Same shape as any of the above; the difference is only where its source lives ([ADR 0010](../../02-DECISIONS/0010-applications-live-in-their-own-repository.md)). Worth listing because a schema that assumes a monorepo path would exclude it. ## The cases that break a naive schema **10 — Something that is a service *and* an application.** A git forge is consumed by other modules as a remote and a registry, *and* operated by a person through a web interface. A web analytics service grants a tracking identity *and* is a dashboard somebody reads. Neither is a service-or-application choice; both are true simultaneously. **11 — Something that provides to others *and* consumes from others.** The store provides databases and needs a filesystem. The forge provides a registry and needs a database. Provider and consumer are not kinds of module; they are ends of edges. **12 — Something the mesh installs that then becomes a node capability.** The container runtime is installed *by* the mesh, and once it works, the node **provides** `container-runtime` to everything else. So a module can change what its node provides. The node's provides-list is therefore partly derived from what is installed on it, not only detected from what was already there — and the two have to agree. **13 — Something that must be adopted rather than installed.** The machine already has the package manager, the container runtime, possibly the version control system, each with configuration somebody chose. The module does not install it; it takes it over ([research 012](../012-the-minimum-viable-node/00-overview.md)). **14 — Something that is a set, not a thing.** *Core infrastructure* is not installable — it is a name for the concrete modules a working node needs. Whether that is a module whose only content is `requires`, or a query over the graph, or a pinned list outside the catalogue, is undecided and is one of the sharper questions here. **15 — Something with one instance for the whole mesh.** There is one mesh database, not one per node. Assigning it to two nodes is not redundancy, it is two meshes. Contrast with a terminal, where per-node is the only sensible reading. **16 — Something that may be installed several times over.** Two terminals coexist happily. Two things wanting port 443 do not. Two message brokers might be fine or might be a split brain, and nothing in *provides* and *requires* distinguishes those. **17 — Something that is not software at all.** A firewall policy. A DNS record. A certificate. It owns no binary, runs nothing, and is entirely *desired state* — which is the one case that fits the host's declaration model exactly and fits an installable-package model not at all. **18 — An agent.** The mesh's own premise is that agents are participants. An agent has an identity, a licence, a node it runs on, and work it does. Whether that is a module, a record in the control plane, or something else is not obvious, and getting it wrong shapes everything about how agents are assigned. **19 — The host itself.** Tier 0 installs everything else and is installed by hand. It is not a module, and a schema that cannot say so has a bootstrap problem hiding in it. **20 — Something the mesh depends on and does not control.** A domain registrar, an upstream resolver, a certificate authority, an electricity supply. Almost certainly not modules — but the mesh's health depends on them, and they are the reason a node can be perfectly configured and still not work. ## What varies across the cases The list above matters less than this. These are the axes a manifest has to express, and each one is a question the schema must answer or deliberately refuse. | Axis | Range | Sharpest case | |---|---|---| | **Does it run?** | supervised · launched by a person · once · on a timer · never | 5, 6, 7, 17 | | **Who starts it?** | the mesh · a human · nothing | 1 vs 3 | | **Where does it come from?** | container image · system package · our source · already on the machine | 12, 13 | | **Does it provide to other modules?** | a resource · an abstract name · nothing | 8, 11 | | **Does it hold state?** | yes, and it matters where · no | 1 vs 3 | | **How many instances?** | one per mesh · one per node · many per node | 15, 16 | | **Can two coexist?** | yes · no · only with different settings | 16 | | **Is it installed or adopted?** | installed · adopted · either, depending on the machine | 13 | | **Does installing it change what the node provides?** | yes · no | 12 | **Two of these are not in any current thinking**, and both come from the hard cases: *how many instances* (15) and *can two coexist* (16). `excludes` covers part of the second and nothing covers the first. ## Questions the cases raise - **Is "runs" a property or a kind?** The axes suggest a property — one schema, with a field saying how it runs, `never` included. The alternative is several kinds of module with different schemas, which is the taxonomy [research 011](00-overview.md) already rejected once for services and applications. - **Is an agent a module?** (18) If yes, the schema carries identity and licensing. If no, the mesh has two catalogues. - **Is core infrastructure a module?** (14) A module whose only content is `requires` is either elegant or a category pretending to be a thing — the same trap `database` was. - **What names one-per-mesh?** (15) Nothing in provides, requires or excludes says it, and getting it wrong means two of something that must be one. - **Where does a policy live?** (17) Pure desired state fits the host's declaration exactly. Whether it is a module at all, or something the control plane derives and no catalogue entry exists for, is open.