The mesh runs its own registry, certifies its own names, and computes its own filtering
Issue 003 is answered in both halves: manifests are parsed strictly, and a module says what it listens on and from where rather than carrying a key nothing reads. The design records what was built and how each part is checked. Issue 013 is new, found by reading while writing the first module that has both a computed file and a service that needs it. The file arrived second. It failed, then the next reconcile fixed it, which is why nothing caught it.
This commit is contained in:
@@ -4,7 +4,9 @@ status: designed
|
||||
code:
|
||||
- mesh-control internal/builder
|
||||
- mesh-control internal/catalogue/build.go
|
||||
updated: 2026-08-30
|
||||
- mesh-control internal/inventory/secrets.go
|
||||
- mesh-control cmd/mesh-builder
|
||||
updated: 2026-08-31
|
||||
decisions:
|
||||
- 02-DECISIONS/0009-modules-and-the-graph.md
|
||||
- 02-DECISIONS/0010-delivery.md
|
||||
@@ -108,6 +110,34 @@ Three properties of the builder that are decisions:
|
||||
is not running, and those want completely different responses — the same rule the host follows
|
||||
about a service that does not exist
|
||||
|
||||
### And it is a module the mesh assigns
|
||||
|
||||
*2026-08-31. Written after `builder issue --node`, which is the part that makes the sentence
|
||||
"holding its own credential" true rather than aspirational.*
|
||||
|
||||
A build machine is a machine that runs the builder, and there is exactly one honest way to say
|
||||
which machines those are: **assign it**. So the builder is a module like any other — an image, a
|
||||
container, a working directory, and a claim so a machine does not end up running two.
|
||||
|
||||
The one thing that could not be a module in the ordinary way is the credential. It is not
|
||||
generated, because the broker has to have been told about it, and it is not written in a manifest,
|
||||
because a manifest is public and the same file goes to every machine that ever runs it. So the
|
||||
mesh **creates the account, seals the URL to the machine that will use it, and discards the
|
||||
plaintext** — the "given, not generated" case above, and its first user.
|
||||
|
||||
Nothing is printed. A credential shown on a terminal is a credential in a scrollback buffer, and
|
||||
the copy that matters would then exist in two places, one of which nobody is guarding.
|
||||
|
||||
**What this replaces:** a builder started by hand with whatever credential was to hand, which in
|
||||
practice meant the broker's administrative account. *A program documented as holding its own
|
||||
credential and given somebody else's is worse than one with no story at all* — the documentation
|
||||
is what stops anybody checking.
|
||||
|
||||
*Checked in the lab by assigning it and then asking the mesh to build a module: the credential
|
||||
file arrives readable only by that machine, names the scoped account rather than the broker's own,
|
||||
and the build completes — which is the only proof the credential authenticates, because a
|
||||
container that is up holding a credential it cannot use looks identical from outside.*
|
||||
|
||||
## What is kept
|
||||
|
||||
**Every result, including the failures.** A failed build that leaves no trace is indistinguishable
|
||||
@@ -167,6 +197,35 @@ Remade when the machine's sealing key changes. **Declared and not made is refuse
|
||||
module whose own credential is silently absent starts, fails to authenticate, and the reason is
|
||||
three layers from the machine reporting it.
|
||||
|
||||
### Some of them the mesh cannot make
|
||||
|
||||
*2026-08-31, from making the builder a module — the first thing to hold one.*
|
||||
|
||||
A generated secret is the mesh's, and remaking it costs nothing: **nothing else ever knew the old
|
||||
one.** That is the assumption the paragraph above rests on, and it is not true of every secret a
|
||||
module needs.
|
||||
|
||||
A broker account's password exists because **the broker was told about it**. A licence key exists
|
||||
because somebody bought it. The mesh's job with these is to carry the value to the machine that
|
||||
will use it and then be unable to read it — the same sealing, from the other direction: **given,
|
||||
not generated.**
|
||||
|
||||
Treating the two alike is wrong in exactly one place, and it is the place nobody looks. When a
|
||||
machine rejoins it has a new sealing key, and everything sealed to the old one is remade. Remaking
|
||||
a *given* secret puts thirty-two random bytes where a working credential was, and every visible
|
||||
signal says it worked: the mesh sealed a secret, the machine applied it, the file is there with
|
||||
the right permissions. What fails is a program authenticating to something else, hours later,
|
||||
with an error that names neither the mesh nor the secret.
|
||||
|
||||
So **where the value came from is recorded, and a given secret is never regenerated.** A rejoined
|
||||
machine asking for one is refused, naming the remedy — issue it again — because the remedy is a
|
||||
command somebody runs and no amount of pushing will produce a password the broker has never heard
|
||||
of.
|
||||
|
||||
*Checked by taking a given secret, changing the machine's sealing key, and asserting the mesh
|
||||
refuses rather than answers; and by asserting that two ordinary pushes hand back the same value,
|
||||
without which the refusal would be a secret that never survives at all.*
|
||||
|
||||
## What one assignment gets you
|
||||
|
||||
A database module, written to see whether it could be:
|
||||
@@ -203,3 +262,22 @@ access, or are not build output. None of that describes a digest-pinned archive,
|
||||
second service for one kind of immutable blob is two things to run, two to back up, and two ways
|
||||
for an artifact to be missing. **Overturnable without touching anything else**: a manifest carries
|
||||
a URL and a digest, and neither says what served it.
|
||||
|
||||
### And the mesh runs it
|
||||
|
||||
*2026-08-31.* Which registry is a **provision**, mesh-scoped: a build machine requires
|
||||
`artifact-store` and is told where it is, the same way an application is told where its database
|
||||
is. Nothing is configured with an address.
|
||||
|
||||
This closes the last thing the mesh depended on and did not run. The registry a bootstrap pulls
|
||||
from belongs to whoever raised the machine; from the moment the mesh has one of its own, an
|
||||
artifact's home is somewhere the mesh can move, replace and back up.
|
||||
|
||||
**The chicken and egg is the bootstrap's, resolved the same way.** A registry module is an
|
||||
`upstream` artifact — mirrored from a registry that already exists into the one being started. The
|
||||
first copy comes from outside, exactly once, and every copy after it is the mesh's.
|
||||
|
||||
*Checked in the lab by assigning it and then asking for `/v2/` — on the machine, and from a second
|
||||
machine across the private network, because a mesh-scoped provision that only answers locally is
|
||||
not one. A container that is running is not a registry that replies, and this project has paid for
|
||||
that distinction once already.*
|
||||
|
||||
Reference in New Issue
Block a user