Research 011 — the module graph
The proposal to split modules into provisioning services and applications was worked through and abandoned, for a reason worth keeping: it cannot be filed consistently. A git forge is consumed as a service and operated through a web interface; an analytics service grants tracking identity and is a dashboard. The operator's correction is the sharper form — what runs on the machine is a supervised container, not something a user started. That is a fact about HOW a thing runs, not about what kind of thing it is. So it is a facet, and 0002 survives: everything is a module. What the catalogue is missing is not a taxonomy but a graph. Grouping asserts relationships; a graph records them. Five declarations, of which two exist: requires/provides a resource (yes), requires/excludes another module (no), requires a node capability (no). Plus interface modules that carry no implementation, with adapters providing them. Recorded because it matters: this is a package manager's model, and pacman already has all of it — depends, conflicts, and provides as virtual packages, which is exactly the interface/adapter idea. Arriving there independently is evidence for the shape. It is also a warning about what not to reimplement. Working position on capabilities, to be tested: intrinsic ones (hardware, architecture, network position) are detected and never installed, and a module requiring one it lacks is impossible rather than unresolved. Provided ones (a display server, a container runtime) are not a separate kind of thing — they are modules that provide a capability, so "may the mesh install a capability" is not policy, it is dependency resolution. Issue 007 then bears directly: an installed package is not a capability. Also captured: the operator's assessment that the machinery around a module — scheduled tasks, hooks, migrations, config and env — is worth keeping, seeds are not, and the integration is wrong enough to need a major refactor. Research 005 found supporting evidence from another direction, that the densest apparent coupling in the catalogue is manifest boilerplate churn. The first open question is the one that decides whether this is progress: what does the graph DELETE? If modules gain declarations and lose nothing, it is motion.
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
---
|
||||
status: active
|
||||
initiated: 2026-08-25
|
||||
touches:
|
||||
- 02-DECISIONS/0002-everything-is-a-module.md
|
||||
- 02-DECISIONS/0017-modules-outside-the-core-are-grouped-by-domain.md
|
||||
- 02-DECISIONS/0036-a-node-is-a-managed-machine.md
|
||||
- 03-DESIGN/00-as-is/02-modules-and-manifests.md
|
||||
- 03-DESIGN/00-as-is/10-module-catalogue.md
|
||||
- 04-ISSUES/007-an-installed-package-is-not-a-capability/00-report.md
|
||||
---
|
||||
|
||||
# 011 — The module graph
|
||||
|
||||
## What is being investigated
|
||||
|
||||
Whether the catalogue's missing structure is a **graph** — modules declaring what they need,
|
||||
what they offer, and what they exclude — and what that replaces.
|
||||
|
||||
[ADR 0017](../../02-DECISIONS/0017-modules-outside-the-core-are-grouped-by-domain.md) proposes
|
||||
grouping modules by domain. [Research 005](../005-domain-grouping/analysis.md) measured that
|
||||
proposal and found its evidence holds in exactly one place — reachability — which
|
||||
[ADR 0037](../../02-DECISIONS/0037-the-host-applies-it-does-not-decide.md) has since absorbed
|
||||
into the host. The measured case for domain grouping has therefore been consumed by a decision
|
||||
taken for unrelated reasons, and what remains is fifty modules that co-change with nothing.
|
||||
|
||||
That leaves the original complaint unanswered: the catalogue records **what was installed**
|
||||
rather than **what anything is for**, and nothing in the system can see a relationship between
|
||||
two modules. Grouping asserts relationships. A graph records them.
|
||||
|
||||
## Why now
|
||||
|
||||
A proposal to split modules into *provisioning services* and *applications* was worked through
|
||||
and abandoned in favour of one concept with facets, for a reason worth keeping:
|
||||
|
||||
- The split cannot be filed consistently. A git forge is consumed as a service *and* operated
|
||||
through a web interface. An analytics service grants tracking identity *and* is a dashboard
|
||||
somebody reads. An identity provider grants authentication *and* has an admin console.
|
||||
- The operator's correction is the sharper form: **what runs on the machine is a supervised
|
||||
container, not something a user started.** That is a fact about *how a thing runs*, not about
|
||||
what kind of thing it is — so it is a facet, not a taxonomy.
|
||||
|
||||
Filing decisions that follow from nothing are the disease research 005 measured. A second
|
||||
taxonomy would reproduce it.
|
||||
|
||||
So [ADR 0002](../../02-DECISIONS/0002-everything-is-a-module.md) survives, and the question
|
||||
becomes what a module must be able to **declare**.
|
||||
|
||||
## The shape being investigated
|
||||
|
||||
Five declarations, of which two exist today.
|
||||
|
||||
| Declaration | Today | Notes |
|
||||
|---|---|---|
|
||||
| **requires a resource** — a database, a bucket | yes | provisioning, [ADR 0005](../../02-DECISIONS/0005-capabilities-are-provisioned-on-declaration.md) |
|
||||
| **provides a resource** | yes | as above |
|
||||
| **requires another module** | **no** | the dependency edge — the graph's substance |
|
||||
| **excludes another module** | **no** | installing A makes B unavailable |
|
||||
| **requires a node capability** | **no** | a graphical session, a container runtime, an architecture |
|
||||
|
||||
And one structural idea on top: **an interface module carries no implementation.** Adapters
|
||||
provide it. An assistant interface with several model-provider adapters; a terminal interface
|
||||
with several terminal adapters. A dependent names the interface and never an implementation.
|
||||
|
||||
**Prior art to measure against, not invent past.** This is a package manager's model, and the
|
||||
platform's own package manager already has all of it: `depends` is the dependency edge,
|
||||
`conflicts` is exclusion, and `provides` is the interface — several packages provide one
|
||||
virtual name, and a dependent names the virtual one. That the design arrived at the same shape
|
||||
independently is evidence for it. It is also a warning: dependency resolution, version
|
||||
constraints, conflict handling and rollback are a long-solved and easily-botched problem, and
|
||||
the effort should establish what to **delegate** rather than reimplement.
|
||||
|
||||
## Capabilities, and what may be installed
|
||||
|
||||
The operator's formulation: *system specs are capabilities, and capabilities unlock installable
|
||||
modules — you cannot install a graphical application on a node with no display server.*
|
||||
|
||||
The question that follows is whether the mesh may install a capability. The effort's working
|
||||
position, to be tested:
|
||||
|
||||
- **Intrinsic capabilities** — hardware, architecture, network position — are facts about a
|
||||
machine. They are detected, never installed, and a module requiring one it does not have is
|
||||
not unresolved but **impossible** on that node.
|
||||
- **Provided capabilities** — a display server, a container runtime — are not a separate kind
|
||||
of thing at all. They are modules that provide a capability, and requiring one is an ordinary
|
||||
edge the graph resolves by installing it.
|
||||
|
||||
If that holds, "may the mesh install a capability" is not a policy question. It is dependency
|
||||
resolution, and the only genuinely new thing is detection.
|
||||
|
||||
Which is where [issue 007](../../04-ISSUES/007-an-installed-package-is-not-a-capability/00-report.md)
|
||||
bears directly: *an installed package is not a capability*. A provided capability is not real
|
||||
because a package is present — it is real when it is present, running and working, and the
|
||||
difference is exactly the class of fault this repository keeps recording.
|
||||
|
||||
## What it touches beyond the catalogue
|
||||
|
||||
The operator's assessment is that the machinery around a module is wanted and its integration
|
||||
is not: **scheduled tasks, hooks, migrations, configuration and environment settings are worth
|
||||
keeping; seeds are not; and the current integration is wrong enough to need a major refactor.**
|
||||
|
||||
That is a claim to test rather than adopt. Research 005 already found supporting evidence from
|
||||
a different direction — that the densest apparent coupling in the catalogue is manifest
|
||||
boilerplate churn, cross-cutting changes to the machinery applied N times — which is what an
|
||||
integration being wrong looks like from the outside.
|
||||
|
||||
## Open questions
|
||||
|
||||
| Question | Why it is open |
|
||||
|---|---|
|
||||
| What does the graph **delete**? | If modules gain declarations and lose nothing, this is motion rather than progress. The effort has not finished until it names what stops existing. |
|
||||
| Where does resolution happen — mesh or platform package manager? | The mesh must model mesh-level edges. Whether it also resolves operating-system packages, or delegates, decides whether a solver has to be written. |
|
||||
| Is an interface a module, or a name? | Arch makes it a name that packages claim. Making it a module gives it a manifest, an owner and a place to document the contract — and a thing with no implementation to install. |
|
||||
| What does an exclusion mean for something already installed? | Refuse the install, or make the conflict visible and let it be decided. The second is a policy surface; the first is a package manager. |
|
||||
| Does node adoption scan for capabilities, applications, or both? | The operator proposes scanning an adopted node and enabling what it finds. Under the working position above, the scan is for capabilities — but a machine with a terminal already installed is also a module already satisfied, and whether that is adoption or drift is undecided. |
|
||||
| One installation image, or several? | Proposed: pre-built images carrying different capability sets, so a machine is adopted quickly. Several images bake capability sets at image time, which is the filing problem in a new form and reintroduces what detection exists to avoid. One image carrying the host and nothing else is [ADR 0038](../../02-DECISIONS/0038-a-node-joins-by-linking-first.md)'s *one binary installed by hand*, automated. The effort should settle which. |
|
||||
| What happens to domain grouping? | [ADR 0017](../../02-DECISIONS/0017-modules-outside-the-core-are-grouped-by-domain.md) is still `proposed`. If the graph is the answer, 0017 is superseded rather than narrowed — its text is never edited. |
|
||||
Reference in New Issue
Block a user