Files
hq/01-RESEARCH/007-provisioning-as-the-core/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

3.2 KiB

status, initiated, touches, became
status initiated touches became
active 2026-08-23
03-DESIGN/00-as-is/03-provisioning.md
02-DECISIONS/0005-capabilities-are-provisioned-on-declaration.md
01-RESEARCH/006-mesh-from-scratch/code-skeleton.md

007 — Provisioning as the mesh's core mechanism

What is being investigated

Provisioning is the mechanism the whole mesh rests on: a module declares what it needs, and the mesh makes it exist, generates the credential, records the grant, and puts the values where the module will read them. ADR 0005 calls it the mesh's core concern rather than its plumbing.

Research 006 then asks it to carry more: the control plane becomes a consumer with its own requirements — a source of record, an image registry, a package registry — satisfied by the same mechanism. That generalisation is only safe if the mechanism is sound, and the as-is record says it is not, in named ways.

Why now

Four weaknesses are already documented in 03-DESIGN/00-as-is/03-provisioning.md, each observed rather than theorised:

  • Rotation has no fan-out. A shared credential can be rotated without telling the peers holding the old one. This has locked the mesh out of its own broker.
  • A grant is not a check. The record says a resource was provisioned. Nothing verifies it still exists, still has that credential, or is reachable from where the consumer runs.
  • A frozen password outlives its generation. A generated secret written once diverges from a persistent data directory initialised earlier, and presents as an authentication error.
  • No requirements is indistinguishable from provisioning that did not run. A module that declares nothing skips the stage, which is correct, and looks identical to failure.

Generalising a mechanism with these properties to the control plane's own dependencies would make each of them fatal rather than annoying.

The questions

Question Why it matters
What does a grant mean, exactly — a record that a resource was created, or a claim about the world that is continuously reconciled? The difference between the current model and one where "provisioned" is checkable. Almost every weakness above is a symptom of the first answer.
How is a credential rotated with fan-out to every holder? The mechanism grants easily and regrants not at all. This is the most damaging gap and it has taken the mesh down.
Can the control plane hold requirements, and what satisfies them before anything is installed? The generalisation research 006 needs. Ties directly to the self-hosting transition.
What happens when a requirement cannot be satisfied — no provider, provider on an unreachable node, provider not yet installed? Today this is silent or a stall. It should be a stated, visible state.
Does a requirement belong to a module or to one of its parts? Research 006 splits feature into artifact and part. A part-scoped requirement means a database is not provisioned where the part that needs it is not installed.